mercurial/cext/pathencode.c
author Augie Fackler <augie@google.com>
Fri, 13 Apr 2018 18:28:58 -0400
changeset 37670 719b8cb22936
parent 36620 186c6df3a373
child 38054 92ac9cf78dba
permissions -rw-r--r--
localrepo: add some overlooked strkwargs love for py3 Differential Revision: https://phab.mercurial-scm.org/D3337
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 {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    29
	START, /* first byte of a path component */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    30
	A,     /* "AUX" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    31
	AU,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    32
	THIRD, /* third of a 3-byte sequence, e.g. "AUX", "NUL" */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    33
	C,     /* "CON" or "COMn" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    34
	CO,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    35
	COMLPT, /* "COM" or "LPT" */
17616
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,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    41
	P, /* "PRN" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    42
	PR,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    43
	LDOT, /* leading '.' */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    44
	DOT,  /* '.' in a non-leading position */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    45
	H,    /* ".h" */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    46
	HGDI, /* ".hg", ".d", or ".i" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    47
	SPACE,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
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,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
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,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    85
                             uint8_t c)
17616
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,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    95
                           char c)
17616
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
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   101
static Py_ssize_t _encodedir(char *dest, size_t destsize, const char *src,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   102
                             Py_ssize_t len)
17606
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++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   129
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   130
				state = DDEFAULT;
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   131
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   132
		case DHGDI:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   133
			if (src[i] == '/') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   134
				memcopy(dest, &destlen, destsize, ".hg", 3);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   135
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   136
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   137
			state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   138
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   139
		case DDEFAULT:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   140
			if (src[i] == '.')
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   141
				state = DDOT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   142
			charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   143
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   144
		}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   145
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   146
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   147
	return destlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   148
}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   149
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   150
PyObject *encodedir(PyObject *self, PyObject *args)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   151
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   152
	Py_ssize_t len, newlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   153
	PyObject *pathobj, *newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   154
	char *path;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   155
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   156
	if (!PyArg_ParseTuple(args, "O:encodedir", &pathobj))
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   157
		return NULL;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   158
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   159
	if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   160
		PyErr_SetString(PyExc_TypeError, "expected a string");
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   161
		return NULL;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   162
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   163
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   164
	newlen = len ? _encodedir(NULL, 0, path, len + 1) : 1;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   165
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   166
	if (newlen == len + 1) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   167
		Py_INCREF(pathobj);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   168
		return pathobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   169
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   170
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   171
	newobj = PyBytes_FromStringAndSize(NULL, newlen);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   172
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   173
	if (newobj) {
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   174
		assert(PyBytes_Check(newobj));
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   175
		Py_SIZE(newobj)--;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   176
		_encodedir(PyBytes_AS_STRING(newobj), newlen, path, len + 1);
17606
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],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   183
                          char *dest, Py_ssize_t destlen, size_t destsize,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   184
                          const char *src, Py_ssize_t len, int encodedir)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   185
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   186
	enum path_state state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   187
	Py_ssize_t i = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   188
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
	 * 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
   191
	 * 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
   192
	 */
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
	while (i < len) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   195
		switch (state) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   196
		case START:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   197
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   198
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   199
				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
   200
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   201
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   202
				state = LDOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   203
				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
   204
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   205
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   206
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   207
				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
   208
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   209
			case 'a':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   210
				state = A;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   211
				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
   212
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   213
			case 'c':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   214
				state = C;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   215
				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
   216
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   217
			case 'l':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   218
				state = L;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   219
				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
   220
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   221
			case 'n':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   222
				state = N;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   223
				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
   224
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   225
			case 'p':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   226
				state = P;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   227
				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
   228
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   229
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   230
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   231
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   232
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   233
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   234
		case A:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   235
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   236
				state = AU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   237
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   238
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   239
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   240
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   241
		case AU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   242
			if (src[i] == 'x') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   243
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   244
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   245
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   246
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   247
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   248
		case THIRD:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   249
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   250
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   251
			case '.':
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 '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   254
				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
   255
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   256
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   257
				i--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   258
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   259
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   260
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   261
		case C:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   262
			if (src[i] == 'o') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   263
				state = CO;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   264
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   265
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   266
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   267
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   268
		case CO:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   269
			if (src[i] == 'm') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   270
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   271
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   272
			} else if (src[i] == 'n') {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   273
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   274
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   275
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   276
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   277
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   278
		case COMLPT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   279
			switch (src[i]) {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   280
			case '1':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   281
			case '2':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   282
			case '3':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   283
			case '4':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   284
			case '5':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   285
			case '6':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   286
			case '7':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   287
			case '8':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   288
			case '9':
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   289
				state = COMLPTn;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   290
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   291
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   292
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   293
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   294
				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
   295
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   296
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   297
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   298
		case COMLPTn:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   299
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   300
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   301
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   302
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   303
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   304
				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
   305
				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
   306
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   307
			default:
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   308
				memcopy(dest, &destlen, destsize, &src[i - 2],
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   309
				        2);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   310
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   311
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   312
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   313
		case L:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   314
			if (src[i] == 'p') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   315
				state = LP;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   316
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   317
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   318
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   319
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   320
		case LP:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   321
			if (src[i] == 't') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   322
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   323
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   324
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   325
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   326
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   327
		case N:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   328
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   329
				state = NU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   330
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   331
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   332
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   333
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   334
		case NU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   335
			if (src[i] == 'l') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   336
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   337
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   338
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   339
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   340
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   341
		case P:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   342
			if (src[i] == 'r') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   343
				state = PR;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   344
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   345
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   346
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   347
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   348
		case PR:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   349
			if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   350
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   351
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   352
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   353
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   354
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   355
		case LDOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   356
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   357
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   358
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   359
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   360
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   361
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   362
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   363
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   364
				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
   365
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   366
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   367
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   368
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   369
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   370
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   371
		case DOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   372
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   373
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   374
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   375
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   376
				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
   377
				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
   378
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   379
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   380
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   381
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   382
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   383
				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
   384
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   385
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   386
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   387
				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
   388
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   389
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   390
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   391
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   392
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   393
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   394
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   395
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   396
		case H:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   397
			if (src[i] == 'g') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   398
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   399
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   400
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   401
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   402
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   403
		case HGDI:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   404
			if (src[i] == '/') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   405
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   406
				if (encodedir)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   407
					memcopy(dest, &destlen, destsize, ".hg",
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   408
					        3);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   409
				charcopy(dest, &destlen, destsize, src[i++]);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   410
			} else
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   411
				state = DEFAULT;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   412
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   413
		case SPACE:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   414
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   415
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   416
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   417
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   418
				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
   419
				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
   420
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   421
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   422
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   423
				charcopy(dest, &destlen, destsize, ' ');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   424
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   425
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   426
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   427
		case DEFAULT:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   428
			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
   429
				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
   430
				if (i == len)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   431
					goto done;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   432
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   433
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   434
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   435
				state = DOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   436
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   437
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   438
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   439
				state = SPACE;
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
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   443
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   444
				charcopy(dest, &destlen, destsize, '/');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   445
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   446
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   447
			default:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   448
				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
   449
					do {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   450
						charcopy(dest, &destlen,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   451
						         destsize, src[i++]);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   452
					} while (i < len &&
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   453
					         inset(onebyte, src[i]));
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   454
				} 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
   455
					char c = src[i++];
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   456
					charcopy(dest, &destlen, destsize, '_');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   457
					charcopy(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   458
					         c == '_' ? '_' : c + 32);
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   459
				} else
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   460
					escape3(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   461
					        src[i++]);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   462
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   463
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   464
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   465
		}
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
done:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   468
	return destlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   469
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   470
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   471
static Py_ssize_t basicencode(char *dest, size_t destsize, const char *src,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   472
                              Py_ssize_t len)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   473
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   474
	static const uint32_t twobytes[8] = {0, 0, 0x87fffffe};
17616
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
	static const uint32_t onebyte[8] = {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   477
	    1, 0x2bff3bfa, 0x68000001, 0x2fffffff,
17616
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
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   480
	Py_ssize_t destlen = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   481
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   482
	return _encode(twobytes, onebyte, dest, destlen, destsize, src, len, 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   483
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   484
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   485
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
   486
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   487
static Py_ssize_t _lowerencode(char *dest, size_t destsize, const char *src,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   488
                               Py_ssize_t len)
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   489
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   490
	static const uint32_t onebyte[8] = {1, 0x2bfffbfb, 0xe8000001,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   491
	                                    0x2fffffff};
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   492
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   493
	static const uint32_t lower[8] = {0, 0, 0x7fffffe};
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   494
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   495
	Py_ssize_t i, destlen = 0;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   496
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   497
	for (i = 0; i < len; i++) {
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   498
		if (inset(onebyte, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   499
			charcopy(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   500
		else if (inset(lower, src[i]))
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   501
			charcopy(dest, &destlen, destsize, src[i] + 32);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   502
		else
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   503
			escape3(dest, &destlen, destsize, src[i]);
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   504
	}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   505
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   506
	return destlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   507
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   508
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   509
PyObject *lowerencode(PyObject *self, PyObject *args)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   510
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   511
	char *path;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   512
	Py_ssize_t len, newlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   513
	PyObject *ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   514
36620
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36056
diff changeset
   515
	if (!PyArg_ParseTuple(args, PY23("s#:lowerencode", "y#:lowerencode"),
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36056
diff changeset
   516
	                      &path, &len))
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   517
		return NULL;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   518
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   519
	newlen = _lowerencode(NULL, 0, path, len);
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   520
	ret = PyBytes_FromStringAndSize(NULL, newlen);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   521
	if (ret)
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   522
		_lowerencode(PyBytes_AS_STRING(ret), newlen, path, len);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   523
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   524
	return ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   525
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   526
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   527
/* See store.py:_auxencode for a description. */
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   528
static Py_ssize_t auxencode(char *dest, size_t destsize, const char *src,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   529
                            Py_ssize_t len)
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   530
{
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   531
	static const uint32_t twobytes[8];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   532
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   533
	static const uint32_t onebyte[8] = {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   534
	    ~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
   535
	};
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   536
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   537
	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
   538
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   539
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   540
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
   541
{
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 dirprefixlen = 8;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   543
	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
   544
	char *dest;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   545
	PyObject *ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   546
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 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
   548
	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
   549
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   550
	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
   551
		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
   552
			lastdot = lastslash;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   553
		lastslash--;
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   556
#if 0
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   557
	/* 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
   558
           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
   559
           violate this rule.  */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   560
	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
   561
		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
   562
				"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
   563
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   564
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   565
#endif
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   566
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   567
	/* 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
   568
	   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
   569
	destsize = 120;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   570
	if (lastdot >= 0)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   571
		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
   572
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   573
	ret = PyBytes_FromStringAndSize(NULL, destsize);
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   574
	if (ret == NULL)
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   575
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   576
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   577
	dest = PyBytes_AS_STRING(ret);
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   578
	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
   579
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   580
	/* 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
   581
	   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
   582
	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
   583
		if (src[i] == '/') {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   584
			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
   585
			/* 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
   586
			   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
   587
			if (d == '.' || d == ' ')
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   588
				dest[destlen - 1] = '_';
19317
66da6e9feacd pathencode: fix hashmangle short dir limit (issue3958)
Siddharth Agarwal <sid0@fb.com>
parents: 19185
diff changeset
   589
			/* 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
   590
			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
   591
				break;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   592
			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
   593
			p = -1;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   594
		} else if (p < dirprefixlen)
18432
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 =
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   625
		    lastslash >= 0 ? len - lastslash - 2 : len - 1;
18432
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],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   631
			        basenamelen);
18432
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],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   640
		        len - lastdot - 1);
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   641
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   642
	assert(PyBytes_Check(ret));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   643
	Py_SIZE(ret) = destlen;
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   644
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   645
	return ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   646
}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   647
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   648
/*
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   649
 * Avoiding a trip through Python would improve performance by 50%,
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   650
 * but we don't encounter enough long names to be worth the code.
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   651
 */
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   652
static int sha1hash(char hash[20], const char *str, Py_ssize_t len)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   653
{
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   654
	static PyObject *shafunc;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   655
	PyObject *shaobj, *hashobj;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   656
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   657
	if (shafunc == NULL) {
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   658
		PyObject *hashlib, *name = PyBytes_FromString("hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   659
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   660
		if (name == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   661
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   662
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   663
		hashlib = PyImport_Import(name);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   664
		Py_DECREF(name);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   665
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   666
		if (hashlib == NULL) {
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   667
			PyErr_SetString(PyExc_ImportError, "hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   668
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   669
		}
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   670
		shafunc = PyObject_GetAttrString(hashlib, "sha1");
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   671
		Py_DECREF(hashlib);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   672
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   673
		if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   674
			PyErr_SetString(PyExc_AttributeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   675
			                "module 'hashlib' has no "
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   676
			                "attribute 'sha1'");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   677
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   678
		}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   679
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   680
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   681
	shaobj = PyObject_CallFunction(shafunc, "s#", str, len);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   682
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   683
	if (shaobj == NULL)
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   684
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   685
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   686
	hashobj = PyObject_CallMethod(shaobj, "digest", "");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   687
	Py_DECREF(shaobj);
26050
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   688
	if (hashobj == NULL)
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   689
		return -1;
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   690
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   691
	if (!PyBytes_Check(hashobj) || PyBytes_GET_SIZE(hashobj) != 20) {
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   692
		PyErr_SetString(PyExc_TypeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   693
		                "result of digest is not a 20-byte hash");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   694
		Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   695
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   696
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   697
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   698
	memcpy(hash, PyBytes_AS_STRING(hashobj), 20);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   699
	Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   700
	return 0;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   701
}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   702
19185
8bed40e02c3b pathencode: grow buffers to increase safety margin
Matt Mackall <mpm@selenic.com>
parents: 19051
diff changeset
   703
#define MAXENCODE 4096 * 4
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   704
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   705
static PyObject *hashencode(const char *src, Py_ssize_t len)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   706
{
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   707
	char dired[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   708
	char lowered[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   709
	char auxed[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   710
	Py_ssize_t dirlen, lowerlen, auxlen, baselen;
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   711
	char sha[20];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   712
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   713
	baselen = (len - 5) * 3;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   714
	if (baselen >= MAXENCODE) {
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   715
		PyErr_SetString(PyExc_ValueError, "string too long");
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   716
		return NULL;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   717
	}
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   718
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   719
	dirlen = _encodedir(dired, baselen, src, len);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   720
	if (sha1hash(sha, dired, dirlen - 1) == -1)
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   721
		return NULL;
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   722
	lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   723
	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   724
	return hashmangle(auxed, auxlen, sha);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   725
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   726
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   727
PyObject *pathencode(PyObject *self, PyObject *args)
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   728
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   729
	Py_ssize_t len, newlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   730
	PyObject *pathobj, *newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   731
	char *path;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   732
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   733
	if (!PyArg_ParseTuple(args, "O:pathencode", &pathobj))
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   734
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   735
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   736
	if (PyBytes_AsStringAndSize(pathobj, &path, &len) == -1) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   737
		PyErr_SetString(PyExc_TypeError, "expected a string");
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   738
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   739
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   740
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   741
	if (len > maxstorepathlen)
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   742
		newlen = maxstorepathlen + 2;
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   743
	else
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   744
		newlen = len ? basicencode(NULL, 0, path, len + 1) : 1;
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   745
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   746
	if (newlen <= maxstorepathlen + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   747
		if (newlen == len + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   748
			Py_INCREF(pathobj);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   749
			return pathobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   750
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   751
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   752
		newobj = PyBytes_FromStringAndSize(NULL, newlen);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   753
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   754
		if (newobj) {
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   755
			assert(PyBytes_Check(newobj));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   756
			Py_SIZE(newobj)--;
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   757
			basicencode(PyBytes_AS_STRING(newobj), newlen, path,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   758
			            len + 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   759
		}
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   760
	} else
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   761
		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
   762
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   763
	return newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   764
}