mercurial/pathencode.c
author Matt Mackall <mpm@selenic.com>
Wed, 30 Sep 2015 15:43:49 -0500
changeset 26421 4b0fc75f9403
parent 26050 822f46b80fa9
child 27342 673ba59669b5
permissions -rw-r--r--
urls: bulk-change primary website URLs
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   159
	if (PyString_AsStringAndSize(pathobj, &path, &len) == -1) {
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   171
	newobj = PyString_FromStringAndSize(NULL, newlen);
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) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   174
		PyString_GET_SIZE(newobj)--;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   175
		_encodedir(PyString_AS_STRING(newobj), newlen, path,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   176
			   len + 1);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   177
	}
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
	return newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   180
}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   181
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   182
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
   183
			  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
   184
			  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
   185
			  int encodedir)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   186
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   187
	enum path_state state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   188
	Py_ssize_t i = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   189
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
	 * 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
   192
	 * 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
   193
	 */
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
	while (i < len) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   196
		switch (state) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   197
		case START:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   198
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   199
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   200
				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
   201
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   202
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   203
				state = LDOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   204
				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
   205
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   206
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   207
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   208
				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
   209
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   210
			case 'a':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   211
				state = A;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   212
				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
   213
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   214
			case 'c':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   215
				state = C;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   216
				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
   217
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   218
			case 'l':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   219
				state = L;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   220
				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
   221
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   222
			case 'n':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   223
				state = N;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   224
				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
   225
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   226
			case 'p':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   227
				state = P;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   228
				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
   229
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   230
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   231
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   232
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   233
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   234
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   235
		case A:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   236
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   237
				state = AU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   238
				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
   239
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   240
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   241
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   242
		case AU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   243
			if (src[i] == 'x') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   244
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   245
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   246
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   247
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   248
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   249
		case THIRD:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   250
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   251
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   252
			case '.':
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 '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   255
				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
   256
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   257
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   258
				i--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   259
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   260
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   261
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   262
		case C:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   263
			if (src[i] == 'o') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   264
				state = CO;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   265
				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
   266
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   267
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   268
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   269
		case CO:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   270
			if (src[i] == 'm') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   271
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   272
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   273
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   274
			else if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   275
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   276
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   277
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   278
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   279
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   280
		case COMLPT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   281
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   282
			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
   283
			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
   284
				state = COMLPTn;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   285
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   286
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   287
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   288
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   289
				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
   290
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   291
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   292
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   293
		case COMLPTn:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   294
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   295
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   296
			case '.':
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 '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   299
				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
   300
				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
   301
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   302
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   303
				memcopy(dest, &destlen, destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   304
					&src[i - 2], 2);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   305
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   306
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   307
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   308
		case L:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   309
			if (src[i] == 'p') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   310
				state = LP;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   311
				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
   312
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   313
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   314
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   315
		case LP:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   316
			if (src[i] == 't') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   317
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   318
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   319
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   320
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   321
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   322
		case N:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   323
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   324
				state = NU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   325
				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
   326
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   327
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   328
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   329
		case NU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   330
			if (src[i] == 'l') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   331
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   332
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   333
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   334
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   335
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   336
		case P:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   337
			if (src[i] == 'r') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   338
				state = PR;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   339
				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
   340
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   341
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   342
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   343
		case PR:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   344
			if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   345
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   346
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   347
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   348
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   349
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   350
		case LDOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   351
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   352
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   353
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   354
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   355
				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
   356
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   357
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   358
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   359
				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
   360
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   361
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   362
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   363
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   364
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   365
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   366
		case DOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   367
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   368
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   369
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   370
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   371
				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
   372
				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
   373
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   374
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   375
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   376
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   377
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   378
				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
   379
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   380
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   381
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   382
				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
   383
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   384
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   385
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   386
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   387
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   388
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   389
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   390
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   391
		case H:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   392
			if (src[i] == 'g') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   393
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   394
				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
   395
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   396
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   397
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   398
		case HGDI:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   399
			if (src[i] == '/') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   400
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   401
				if (encodedir)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   402
					memcopy(dest, &destlen, destsize, ".hg",
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   403
						3);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   404
				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
   405
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   406
			else state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   407
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   408
		case SPACE:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   409
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   410
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   411
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   412
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   413
				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
   414
				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
   415
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   416
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   417
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   418
				charcopy(dest, &destlen, destsize, ' ');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   419
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   420
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   421
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   422
		case DEFAULT:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   423
			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
   424
				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
   425
				if (i == len)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   426
					goto done;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   427
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   428
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   429
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   430
				state = DOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   431
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   432
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   433
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   434
				state = SPACE;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   435
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   436
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   437
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   438
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   439
				charcopy(dest, &destlen, destsize, '/');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   440
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   441
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   442
			default:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   443
				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
   444
					do {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   445
						charcopy(dest, &destlen,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   446
							 destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   447
					} while (i < len &&
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   448
						 inset(onebyte, src[i]));
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   449
				}
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   450
				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
   451
					char c = src[i++];
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   452
					charcopy(dest, &destlen, destsize, '_');
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
						 c == '_' ? '_' : c + 32);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   455
				}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   456
				else
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   457
					escape3(dest, &destlen, destsize,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   458
						src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   459
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   460
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   461
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   462
		}
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
done:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   465
	return destlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   466
}
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
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
   469
			      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
   470
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   471
	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
   472
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   473
	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
   474
		1, 0x2bff3bfa, 0x68000001, 0x2fffffff,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   475
	};
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
	Py_ssize_t destlen = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   478
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   479
	return _encode(twobytes, onebyte, dest, destlen, destsize,
17691
c6c7e466dd3a pathencode: simplify basicencode
Adrian Buehlmann <adrian@cadifra.com>
parents: 17616
diff changeset
   480
		       src, len, 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   481
}
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
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
   484
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   485
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
   486
			       const char *src, Py_ssize_t len)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   487
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   488
	static const uint32_t onebyte[8] = {
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   489
		1, 0x2bfffbfb, 0xe8000001, 0x2fffffff
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   490
	};
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
	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
   493
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   494
	Py_ssize_t i, destlen = 0;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   495
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   496
	for (i = 0; i < len; i++) {
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   497
		if (inset(onebyte, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   498
			charcopy(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   499
		else if (inset(lower, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   500
			charcopy(dest, &destlen, destsize, src[i] + 32);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   501
		else
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   502
			escape3(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   503
	}
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
	return destlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   506
}
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
PyObject *lowerencode(PyObject *self, PyObject *args)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   509
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   510
	char *path;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   511
	Py_ssize_t len, newlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   512
	PyObject *ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   513
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   514
	if (!PyArg_ParseTuple(args, "s#:lowerencode", &path, &len))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   515
		return NULL;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   516
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   517
	newlen = _lowerencode(NULL, 0, path, len);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   518
	ret = PyString_FromStringAndSize(NULL, newlen);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   519
	if (ret)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   520
		newlen = _lowerencode(PyString_AS_STRING(ret), newlen,
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   521
				      path, len);
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   572
	ret = PyString_FromStringAndSize(NULL, destsize);
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   576
	dest = PyString_AS_STRING(ret);
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   642
	PyString_GET_SIZE(ret) = destlen;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   643
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   644
	return ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   645
}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   646
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   647
/*
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   648
 * 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
   649
 * 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
   650
 */
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   651
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
   652
{
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   653
	static PyObject *shafunc;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   654
	PyObject *shaobj, *hashobj;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   655
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   656
	if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   657
		PyObject *util, *name = PyString_FromString("mercurial.util");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   658
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   659
		if (name == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   660
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   661
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   662
		util = PyImport_Import(name);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   663
		Py_DECREF(name);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   664
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   665
		if (util == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   666
			PyErr_SetString(PyExc_ImportError, "mercurial.util");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   667
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   668
		}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   669
		shafunc = PyObject_GetAttrString(util, "sha1");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   670
		Py_DECREF(util);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   671
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   672
		if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   673
			PyErr_SetString(PyExc_AttributeError,
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   674
					"module 'mercurial.util' has no "
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   675
					"attribute 'sha1'");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   676
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   677
		}
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
	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
   681
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   682
	if (shaobj == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   683
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   684
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   685
	hashobj = PyObject_CallMethod(shaobj, "digest", "");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   686
	Py_DECREF(shaobj);
26050
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   687
	if (hashobj == NULL)
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   688
		return -1;
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   689
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   690
	if (!PyString_Check(hashobj) || PyString_GET_SIZE(hashobj) != 20) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   691
		PyErr_SetString(PyExc_TypeError,
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   692
				"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
   693
		Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   694
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   695
	}
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
	memcpy(hash, PyString_AS_STRING(hashobj), 20);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   698
	Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   699
	return 0;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   700
}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   701
19185
8bed40e02c3b pathencode: grow buffers to increase safety margin
Matt Mackall <mpm@selenic.com>
parents: 19051
diff changeset
   702
#define MAXENCODE 4096 * 4
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   703
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   704
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
   705
{
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   706
	char dired[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   707
	char lowered[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   708
	char auxed[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   709
	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
   710
	char sha[20];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   711
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   712
	baselen = (len - 5) * 3;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   713
	if (baselen >= MAXENCODE) {
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   714
		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
   715
		return NULL;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   716
	}
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   717
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   718
	dirlen = _encodedir(dired, baselen, src, len);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   719
	if (sha1hash(sha, dired, dirlen - 1) == -1)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   720
		return NULL;
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   721
	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
   722
	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   723
	return hashmangle(auxed, auxlen, sha);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   724
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   725
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   726
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
   727
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   728
	Py_ssize_t len, newlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   729
	PyObject *pathobj, *newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   730
	char *path;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   731
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   732
	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
   733
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   734
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   735
	if (PyString_AsStringAndSize(pathobj, &path, &len) == -1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   736
		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
   737
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   738
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   739
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   740
	if (len > maxstorepathlen)
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   741
		newlen = maxstorepathlen + 2;
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   742
	else
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   743
		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
   744
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   745
	if (newlen <= maxstorepathlen + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   746
		if (newlen == len + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   747
			Py_INCREF(pathobj);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   748
			return pathobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   749
		}
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
		newobj = PyString_FromStringAndSize(NULL, newlen);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   752
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   753
		if (newobj) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   754
			PyString_GET_SIZE(newobj)--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   755
			basicencode(PyString_AS_STRING(newobj), newlen, path,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   756
				    len + 1);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   757
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   758
	}
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   759
	else
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   760
		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
   761
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   762
	return newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   763
}