mercurial/cext/pathencode.c
author Pulkit Goyal <7895pulkit@gmail.com>
Fri, 29 Dec 2017 06:32:17 +0530
changeset 35590 aaeba70d5cbe
parent 32372 df448de7cf3b
child 36056 44cb058bc0d3
permissions -rw-r--r--
py3: add 8 new passing tests to the whitelist Differential Revision: https://phab.mercurial-scm.org/D1800
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     1
/*
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     2
 pathencode.c - efficient path name encoding
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     3
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     4
 Copyright 2012 Facebook
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     5
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     6
 This software may be used and distributed according to the terms of
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     7
 the GNU General Public License, incorporated herein by reference.
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     8
*/
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     9
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    10
/*
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    11
 * An implementation of the name encoding scheme used by the fncache
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    12
 * store.  The common case is of a path < 120 bytes long, which is
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    13
 * handled either in a single pass with no allocations or two passes
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    14
 * with a single allocation.  For longer paths, multiple passes are
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    15
 * required.
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    16
 */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    17
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
    18
#define PY_SSIZE_T_CLEAN
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    19
#include <Python.h>
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    20
#include <assert.h>
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    21
#include <ctype.h>
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    22
#include <stdlib.h>
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    23
#include <string.h>
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    24
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    25
#include "util.h"
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    26
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    27
/* state machine for the fast path */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    28
enum path_state {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    29
	START,   /* first byte of a path component */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    30
	A,       /* "AUX" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    31
	AU,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    32
	THIRD,   /* third of a 3-byte sequence, e.g. "AUX", "NUL" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    33
	C,       /* "CON" or "COMn" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    34
	CO,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    35
	COMLPT,  /* "COM" or "LPT" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    36
	COMLPTn,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    37
	L,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    38
	LP,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    39
	N,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    40
	NU,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    41
	P,       /* "PRN" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    42
	PR,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    43
	LDOT,    /* leading '.' */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    44
	DOT,     /* '.' in a non-leading position */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    45
	H,       /* ".h" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    46
	HGDI,    /* ".hg", ".d", or ".i" */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    47
	SPACE,
19051
55c6ab8163ec pathencode: eliminate comma at end of enum list to avoid pedantic warning
Yuya Nishihara <yuya@tcha.org>
parents: 18452
diff changeset
    48
	DEFAULT  /* byte of a path component after the first */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    49
};
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    50
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    51
/* state machine for dir-encoding */
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    52
enum dir_state {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    53
	DDOT,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    54
	DH,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    55
	DHGDI,
19051
55c6ab8163ec pathencode: eliminate comma at end of enum list to avoid pedantic warning
Yuya Nishihara <yuya@tcha.org>
parents: 18452
diff changeset
    56
	DDEFAULT
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    57
};
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    58
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
    59
static inline int inset(const uint32_t bitset[], char c)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    60
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    61
	return bitset[((uint8_t)c) >> 5] & (1 << (((uint8_t)c) & 31));
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    62
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    63
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    64
static inline void charcopy(char *dest, Py_ssize_t *destlen, size_t destsize,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    65
                            char c)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    66
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    67
	if (dest) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    68
		assert(*destlen < destsize);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    69
		dest[*destlen] = c;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    70
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    71
	(*destlen)++;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    72
}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    73
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    74
static inline void memcopy(char *dest, Py_ssize_t *destlen, size_t destsize,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    75
                           const void *src, Py_ssize_t len)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    76
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    77
	if (dest) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    78
		assert(*destlen + len < destsize);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    79
		memcpy((void *)&dest[*destlen], src, len);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    80
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    81
	*destlen += len;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    82
}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    83
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    84
static inline void hexencode(char *dest, Py_ssize_t *destlen, size_t destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    85
			     uint8_t c)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    86
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    87
	static const char hexdigit[] = "0123456789abcdef";
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    88
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    89
	charcopy(dest, destlen, destsize, hexdigit[c >> 4]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    90
	charcopy(dest, destlen, destsize, hexdigit[c & 15]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    91
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    92
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    93
/* 3-byte escape: tilde followed by two hex digits */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    94
static inline void escape3(char *dest, Py_ssize_t *destlen, size_t destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    95
			   char c)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    96
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    97
	charcopy(dest, destlen, destsize, '~');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    98
	hexencode(dest, destlen, destsize, c);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    99
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   100
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   101
static Py_ssize_t _encodedir(char *dest, size_t destsize,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   102
                             const char *src, Py_ssize_t len)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   103
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   104
	enum dir_state state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   105
	Py_ssize_t i = 0, destlen = 0;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   106
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   107
	while (i < len) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   108
		switch (state) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   109
		case DDOT:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   110
			switch (src[i]) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   111
			case 'd':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   112
			case 'i':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   113
				state = DHGDI;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   114
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   115
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   116
			case 'h':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   117
				state = DH;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   118
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   119
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   120
			default:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   121
				state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   122
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   123
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   124
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   125
		case DH:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   126
			if (src[i] == 'g') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   127
				state = DHGDI;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   128
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   129
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   130
			else state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   131
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   132
		case DHGDI:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   133
			if (src[i] == '/') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   134
				memcopy(dest, &destlen, destsize, ".hg", 3);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   135
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   136
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   137
			state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   138
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   139
		case DDEFAULT:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   140
			if (src[i] == '.')
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   141
				state = DDOT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   142
			charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   143
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   144
		}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   145
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   146
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   147
	return destlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   148
}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   149
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   150
PyObject *encodedir(PyObject *self, PyObject *args)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   151
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   152
	Py_ssize_t len, newlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   153
	PyObject *pathobj, *newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   154
	char *path;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   155
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   156
	if (!PyArg_ParseTuple(args, "O:encodedir", &pathobj))
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   157
		return NULL;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   158
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   159
	if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   160
		PyErr_SetString(PyExc_TypeError, "expected a string");
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   161
		return NULL;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   162
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   163
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   164
	newlen = len ? _encodedir(NULL, 0, path, len + 1) : 1;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   165
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   166
	if (newlen == len + 1) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   167
		Py_INCREF(pathobj);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   168
		return pathobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   169
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   170
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   171
	newobj = PyBytes_FromStringAndSize(NULL, newlen);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   172
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   173
	if (newobj) {
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   174
		assert(PyBytes_Check(newobj));
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   175
		Py_SIZE(newobj)--;
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   176
		_encodedir(PyBytes_AS_STRING(newobj), newlen, path,
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   177
			   len + 1);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   178
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   179
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   180
	return newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   181
}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   182
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   183
static Py_ssize_t _encode(const uint32_t twobytes[8], const uint32_t onebyte[8],
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   184
			  char *dest, Py_ssize_t destlen, size_t destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   185
			  const char *src, Py_ssize_t len,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   186
			  int encodedir)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   187
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   188
	enum path_state state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   189
	Py_ssize_t i = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   190
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   191
	/*
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   192
	 * Python strings end with a zero byte, which we use as a
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   193
	 * terminal token as they are not valid inside path names.
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   194
	 */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   195
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   196
	while (i < len) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   197
		switch (state) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   198
		case START:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   199
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   200
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   201
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   202
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   203
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   204
				state = LDOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   205
				escape3(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   206
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   207
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   208
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   209
				escape3(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   210
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   211
			case 'a':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   212
				state = A;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   213
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   214
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   215
			case 'c':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   216
				state = C;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   217
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   218
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   219
			case 'l':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   220
				state = L;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   221
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   222
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   223
			case 'n':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   224
				state = N;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   225
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   226
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   227
			case 'p':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   228
				state = P;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   229
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   230
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   231
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   232
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   233
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   234
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   235
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   236
		case A:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   237
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   238
				state = AU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   239
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   240
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   241
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   242
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   243
		case AU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   244
			if (src[i] == 'x') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   245
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   246
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   247
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   248
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   249
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   250
		case THIRD:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   251
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   252
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   253
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   254
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   255
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   256
				escape3(dest, &destlen, destsize, src[i - 1]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   257
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   258
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   259
				i--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   260
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   261
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   262
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   263
		case C:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   264
			if (src[i] == 'o') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   265
				state = CO;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   266
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   267
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   268
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   269
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   270
		case CO:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   271
			if (src[i] == 'm') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   272
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   273
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   274
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   275
			else if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   276
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   277
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   278
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   279
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   280
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   281
		case COMLPT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   282
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   283
			case '1': case '2': case '3': case '4': case '5':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   284
			case '6': case '7': case '8': case '9':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   285
				state = COMLPTn;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   286
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   287
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   288
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   289
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   290
				charcopy(dest, &destlen, destsize, src[i - 1]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   291
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   292
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   293
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   294
		case COMLPTn:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   295
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   296
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   297
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   298
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   299
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   300
				escape3(dest, &destlen, destsize, src[i - 2]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   301
				charcopy(dest, &destlen, destsize, src[i - 1]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   302
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   303
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   304
				memcopy(dest, &destlen, destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   305
					&src[i - 2], 2);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   306
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   307
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   308
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   309
		case L:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   310
			if (src[i] == 'p') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   311
				state = LP;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   312
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   313
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   314
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   315
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   316
		case LP:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   317
			if (src[i] == 't') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   318
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   319
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   320
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   321
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   322
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   323
		case N:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   324
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   325
				state = NU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   326
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   327
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   328
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   329
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   330
		case NU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   331
			if (src[i] == 'l') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   332
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   333
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   334
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   335
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   336
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   337
		case P:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   338
			if (src[i] == 'r') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   339
				state = PR;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   340
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   341
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   342
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   343
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   344
		case PR:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   345
			if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   346
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   347
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   348
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   349
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   350
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   351
		case LDOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   352
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   353
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   354
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   355
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   356
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   357
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   358
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   359
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   360
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   361
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   362
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   363
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   364
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   365
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   366
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   367
		case DOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   368
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   369
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   370
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   371
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   372
				memcopy(dest, &destlen, destsize, "~2e", 3);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   373
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   374
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   375
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   376
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   377
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   378
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   379
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   380
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   381
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   382
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   383
				memcopy(dest, &destlen, destsize, ".h", 2);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   384
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   385
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   386
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   387
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   388
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   389
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   390
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   391
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   392
		case H:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   393
			if (src[i] == 'g') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   394
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   395
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   396
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   397
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   398
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   399
		case HGDI:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   400
			if (src[i] == '/') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   401
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   402
				if (encodedir)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   403
					memcopy(dest, &destlen, destsize, ".hg",
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   404
						3);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   405
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   406
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   407
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   408
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   409
		case SPACE:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   410
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   411
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   412
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   413
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   414
				memcopy(dest, &destlen, destsize, "~20", 3);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   415
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   416
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   417
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   418
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   419
				charcopy(dest, &destlen, destsize, ' ');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   420
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   421
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   422
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   423
		case DEFAULT:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   424
			while (inset(onebyte, src[i])) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   425
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   426
				if (i == len)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   427
					goto done;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   428
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   429
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   430
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   431
				state = DOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   432
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   433
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   434
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   435
				state = SPACE;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   436
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   437
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   438
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   439
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   440
				charcopy(dest, &destlen, destsize, '/');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   441
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   442
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   443
			default:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   444
				if (inset(onebyte, src[i])) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   445
					do {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   446
						charcopy(dest, &destlen,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   447
							 destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   448
					} while (i < len &&
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   449
						 inset(onebyte, src[i]));
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   450
				}
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   451
				else if (inset(twobytes, src[i])) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   452
					char c = src[i++];
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   453
					charcopy(dest, &destlen, destsize, '_');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   454
					charcopy(dest, &destlen, destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   455
						 c == '_' ? '_' : c + 32);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   456
				}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   457
				else
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   458
					escape3(dest, &destlen, destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   459
						src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   460
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   461
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   462
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   463
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   464
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   465
done:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   466
	return destlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   467
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   468
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   469
static Py_ssize_t basicencode(char *dest, size_t destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   470
			      const char *src, Py_ssize_t len)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   471
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   472
	static const uint32_t twobytes[8] = { 0, 0, 0x87fffffe };
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   473
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   474
	static const uint32_t onebyte[8] = {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   475
		1, 0x2bff3bfa, 0x68000001, 0x2fffffff,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   476
	};
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   477
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   478
	Py_ssize_t destlen = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   479
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   480
	return _encode(twobytes, onebyte, dest, destlen, destsize,
17691
c6c7e466dd3a pathencode: simplify basicencode
Adrian Buehlmann <adrian@cadifra.com>
parents: 17616
diff changeset
   481
		       src, len, 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   482
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   483
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   484
static const Py_ssize_t maxstorepathlen = 120;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   485
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   486
static Py_ssize_t _lowerencode(char *dest, size_t destsize,
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   487
			       const char *src, Py_ssize_t len)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   488
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   489
	static const uint32_t onebyte[8] = {
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   490
		1, 0x2bfffbfb, 0xe8000001, 0x2fffffff
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   491
	};
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   492
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   493
	static const uint32_t lower[8] = { 0, 0, 0x7fffffe };
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   494
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   495
	Py_ssize_t i, destlen = 0;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   496
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   497
	for (i = 0; i < len; i++) {
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   498
		if (inset(onebyte, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   499
			charcopy(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   500
		else if (inset(lower, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   501
			charcopy(dest, &destlen, destsize, src[i] + 32);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   502
		else
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   503
			escape3(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   504
	}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   505
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   506
	return destlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   507
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   508
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   509
PyObject *lowerencode(PyObject *self, PyObject *args)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   510
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   511
	char *path;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   512
	Py_ssize_t len, newlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   513
	PyObject *ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   514
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   515
	if (!PyArg_ParseTuple(args, "s#:lowerencode", &path, &len))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   516
		return NULL;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   517
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   518
	newlen = _lowerencode(NULL, 0, path, len);
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   519
	ret = PyBytes_FromStringAndSize(NULL, newlen);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   520
	if (ret)
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   521
		_lowerencode(PyBytes_AS_STRING(ret), newlen, path, len);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   522
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   523
	return ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   524
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   525
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   526
/* See store.py:_auxencode for a description. */
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   527
static Py_ssize_t auxencode(char *dest, size_t destsize,
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   528
			    const char *src, Py_ssize_t len)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   529
{
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   530
	static const uint32_t twobytes[8];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   531
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   532
	static const uint32_t onebyte[8] = {
20535
5f683209f5b6 pathencode: eliminate signed integer warnings
Danek Duvall <danek.duvall@oracle.com>
parents: 19317
diff changeset
   533
		~0U, 0xffff3ffe, ~0U, ~0U, ~0U, ~0U, ~0U, ~0U,
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   534
	};
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   535
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   536
	return _encode(twobytes, onebyte, dest, 0, destsize, src, len, 0);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   537
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   538
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   539
static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20])
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   540
{
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   541
	static const Py_ssize_t dirprefixlen = 8;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   542
	static const Py_ssize_t maxshortdirslen = 68;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   543
	char *dest;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   544
	PyObject *ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   545
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   546
	Py_ssize_t i, d, p, lastslash = len - 1, lastdot = -1;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   547
	Py_ssize_t destsize, destlen = 0, slop, used;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   548
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   549
	while (lastslash >= 0 && src[lastslash] != '/') {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   550
		if (src[lastslash] == '.' && lastdot == -1)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   551
			lastdot = lastslash;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   552
		lastslash--;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   553
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   554
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   555
#if 0
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   556
	/* All paths should end in a suffix of ".i" or ".d".
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   557
           Unfortunately, the file names in test-hybridencode.py
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   558
           violate this rule.  */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   559
	if (lastdot != len - 3) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   560
		PyErr_SetString(PyExc_ValueError,
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   561
				"suffix missing or wrong length");
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   562
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   563
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   564
#endif
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   565
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   566
	/* If src contains a suffix, we will append it to the end of
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   567
	   the new string, so make room. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   568
	destsize = 120;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   569
	if (lastdot >= 0)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   570
		destsize += len - lastdot - 1;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   571
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   572
	ret = PyBytes_FromStringAndSize(NULL, destsize);
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   573
	if (ret == NULL)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   574
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   575
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   576
	dest = PyBytes_AS_STRING(ret);
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   577
	memcopy(dest, &destlen, destsize, "dh/", 3);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   578
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   579
	/* Copy up to dirprefixlen bytes of each path component, up to
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   580
	   a limit of maxshortdirslen bytes. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   581
	for (i = d = p = 0; i < lastslash; i++, p++) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   582
		if (src[i] == '/') {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   583
			char d = dest[destlen - 1];
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   584
			/* After truncation, a directory name may end
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   585
			   in a space or dot, which are unportable. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   586
			if (d == '.' || d == ' ')
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   587
				dest[destlen - 1] = '_';
19317
66da6e9feacd pathencode: fix hashmangle short dir limit (issue3958)
Siddharth Agarwal <sid0@fb.com>
parents: 19185
diff changeset
   588
			/* The + 3 is to account for "dh/" in the beginning */
66da6e9feacd pathencode: fix hashmangle short dir limit (issue3958)
Siddharth Agarwal <sid0@fb.com>
parents: 19185
diff changeset
   589
			if (destlen > maxshortdirslen + 3)
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   590
				break;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   591
			charcopy(dest, &destlen, destsize, src[i]);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   592
			p = -1;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   593
		}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   594
		else if (p < dirprefixlen)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   595
			charcopy(dest, &destlen, destsize, src[i]);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   596
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   597
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   598
	/* Rewind to just before the last slash copied. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   599
	if (destlen > maxshortdirslen + 3)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   600
		do {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   601
			destlen--;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   602
		} while (destlen > 0 && dest[destlen] != '/');
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   603
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   604
	if (destlen > 3) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   605
		if (lastslash > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   606
			char d = dest[destlen - 1];
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   607
			/* The last directory component may be
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   608
			   truncated, so make it safe. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   609
			if (d == '.' || d == ' ')
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   610
				dest[destlen - 1] = '_';
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   611
		}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   612
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   613
		charcopy(dest, &destlen, destsize, '/');
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   614
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   615
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   616
	/* Add a prefix of the original file's name. Its length
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   617
	   depends on the number of bytes left after accounting for
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   618
	   hash and suffix. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   619
	used = destlen + 40;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   620
	if (lastdot >= 0)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   621
		used += len - lastdot - 1;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   622
	slop = maxstorepathlen - used;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   623
	if (slop > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   624
		Py_ssize_t basenamelen =
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   625
			lastslash >= 0 ? len - lastslash - 2 : len - 1;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   626
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   627
		if (basenamelen > slop)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   628
			basenamelen = slop;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   629
		if (basenamelen > 0)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   630
			memcopy(dest, &destlen, destsize, &src[lastslash + 1],
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   631
				basenamelen);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   632
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   633
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   634
	/* Add hash and suffix. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   635
	for (i = 0; i < 20; i++)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   636
		hexencode(dest, &destlen, destsize, sha[i]);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   637
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   638
	if (lastdot >= 0)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   639
		memcopy(dest, &destlen, destsize, &src[lastdot],
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   640
			len - lastdot - 1);
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   641
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   642
	assert(PyBytes_Check(ret));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   643
	Py_SIZE(ret) = destlen;
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   644
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   645
	return ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   646
}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   647
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   648
/*
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   649
 * Avoiding a trip through Python would improve performance by 50%,
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   650
 * but we don't encounter enough long names to be worth the code.
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   651
 */
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   652
static int sha1hash(char hash[20], const char *str, Py_ssize_t len)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   653
{
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   654
	static PyObject *shafunc;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   655
	PyObject *shaobj, *hashobj;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   656
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   657
	if (shafunc == NULL) {
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   658
		PyObject *hashlib, *name = PyBytes_FromString("hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   659
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   660
		if (name == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   661
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   662
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   663
		hashlib = PyImport_Import(name);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   664
		Py_DECREF(name);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   665
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   666
		if (hashlib == NULL) {
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   667
			PyErr_SetString(PyExc_ImportError, "hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   668
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   669
		}
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   670
		shafunc = PyObject_GetAttrString(hashlib, "sha1");
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   671
		Py_DECREF(hashlib);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   672
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   673
		if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   674
			PyErr_SetString(PyExc_AttributeError,
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   675
					"module 'hashlib' has no "
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   676
					"attribute 'sha1'");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   677
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   678
		}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   679
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   680
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   681
	shaobj = PyObject_CallFunction(shafunc, "s#", str, len);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   682
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   683
	if (shaobj == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   684
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   685
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   686
	hashobj = PyObject_CallMethod(shaobj, "digest", "");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   687
	Py_DECREF(shaobj);
26050
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   688
	if (hashobj == NULL)
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   689
		return -1;
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   690
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   691
	if (!PyBytes_Check(hashobj) || PyBytes_GET_SIZE(hashobj) != 20) {
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   692
		PyErr_SetString(PyExc_TypeError,
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   693
				"result of digest is not a 20-byte hash");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   694
		Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   695
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   696
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   697
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   698
	memcpy(hash, PyBytes_AS_STRING(hashobj), 20);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   699
	Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   700
	return 0;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   701
}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   702
19185
8bed40e02c3b pathencode: grow buffers to increase safety margin
Matt Mackall <mpm@selenic.com>
parents: 19051
diff changeset
   703
#define MAXENCODE 4096 * 4
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   704
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   705
static PyObject *hashencode(const char *src, Py_ssize_t len)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   706
{
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   707
	char dired[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   708
	char lowered[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   709
	char auxed[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   710
	Py_ssize_t dirlen, lowerlen, auxlen, baselen;
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   711
	char sha[20];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   712
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   713
	baselen = (len - 5) * 3;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   714
	if (baselen >= MAXENCODE) {
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   715
		PyErr_SetString(PyExc_ValueError, "string too long");
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   716
		return NULL;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   717
	}
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   718
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   719
	dirlen = _encodedir(dired, baselen, src, len);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   720
	if (sha1hash(sha, dired, dirlen - 1) == -1)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   721
		return NULL;
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   722
	lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   723
	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   724
	return hashmangle(auxed, auxlen, sha);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   725
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   726
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   727
PyObject *pathencode(PyObject *self, PyObject *args)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   728
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   729
	Py_ssize_t len, newlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   730
	PyObject *pathobj, *newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   731
	char *path;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   732
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   733
	if (!PyArg_ParseTuple(args, "O:pathencode", &pathobj))
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   734
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   735
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   736
	if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   737
		PyErr_SetString(PyExc_TypeError, "expected a string");
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   738
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   739
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   740
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   741
	if (len > maxstorepathlen)
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   742
		newlen = maxstorepathlen + 2;
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   743
	else
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   744
		newlen = len ? basicencode(NULL, 0, path, len + 1) : 1;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   745
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   746
	if (newlen <= maxstorepathlen + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   747
		if (newlen == len + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   748
			Py_INCREF(pathobj);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   749
			return pathobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   750
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   751
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   752
		newobj = PyBytes_FromStringAndSize(NULL, newlen);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   753
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   754
		if (newobj) {
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   755
			assert(PyBytes_Check(newobj));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   756
			Py_SIZE(newobj)--;
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   757
			basicencode(PyBytes_AS_STRING(newobj), newlen, path,
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   758
				    len + 1);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   759
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   760
	}
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   761
	else
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   762
		newobj = hashencode(path, len + 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   763
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   764
	return newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   765
}