mercurial/cext/pathencode.c
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 25 Sep 2020 14:54:43 +0200
changeset 45639 7a757e893532
parent 41336 763b45bc4483
child 46374 e92ca942ddca
permissions -rw-r--r--
copies: no longer change the sidedata flag With the new sidedata storage that include data about all file changes, every revision has one, so the sidedata flag is not longer a good way to spot changeset with copy information. So we drop this check to simplify the code We optimisation itself provided an interesting speedup, so we will likely reintroduce something similar, with a dedicated flag, in the future. Differential Revision: https://phab.mercurial-scm.org/D9116
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++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   129
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   130
				state = DDEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   131
			}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   132
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   133
		case DHGDI:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   134
			if (src[i] == '/') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   135
				memcopy(dest, &destlen, destsize, ".hg", 3);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   136
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   137
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   138
			state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   139
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   140
		case DDEFAULT:
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   141
			if (src[i] == '.') {
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   142
				state = DDOT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   143
			}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   144
			charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   145
			break;
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
	}
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
	return destlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   150
}
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
PyObject *encodedir(PyObject *self, PyObject *args)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   153
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   154
	Py_ssize_t len, newlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   155
	PyObject *pathobj, *newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   156
	char *path;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   157
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   158
	if (!PyArg_ParseTuple(args, "O:encodedir", &pathobj)) {
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   159
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   160
	}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   161
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   162
	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
   163
		PyErr_SetString(PyExc_TypeError, "expected a string");
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   164
		return NULL;
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   167
	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
   168
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   169
	if (newlen == len + 1) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   170
		Py_INCREF(pathobj);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   171
		return pathobj;
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
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   174
	newobj = PyBytes_FromStringAndSize(NULL, newlen);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   175
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   176
	if (newobj) {
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   177
		assert(PyBytes_Check(newobj));
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   178
		Py_SIZE(newobj)--;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   179
		_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
   180
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   181
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   182
	return newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   183
}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   184
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   185
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
   186
                          char *dest, Py_ssize_t destlen, size_t destsize,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   187
                          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
   188
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   189
	enum path_state state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   190
	Py_ssize_t i = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   191
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   192
	/*
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   193
	 * 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
   194
	 * 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
   195
	 */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   196
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   197
	while (i < len) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   198
		switch (state) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   199
		case START:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   200
			switch (src[i]) {
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
				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
   203
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   204
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   205
				state = LDOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   206
				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
   207
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   208
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   209
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   210
				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
   211
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   212
			case 'a':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   213
				state = A;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   214
				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
   215
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   216
			case 'c':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   217
				state = C;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   218
				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
   219
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   220
			case 'l':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   221
				state = L;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   222
				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
   223
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   224
			case 'n':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   225
				state = N;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   226
				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
   227
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   228
			case 'p':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   229
				state = P;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   230
				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
   231
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   232
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   233
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   234
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   235
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   236
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   237
		case A:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   238
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   239
				state = AU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   240
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   241
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   242
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   243
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   244
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   245
		case AU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   246
			if (src[i] == 'x') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   247
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   248
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   249
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   250
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   251
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   252
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   253
		case THIRD:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   254
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   255
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   256
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   257
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   258
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   259
				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
   260
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   261
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   262
				i--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   263
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   264
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   265
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   266
		case C:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   267
			if (src[i] == 'o') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   268
				state = CO;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   269
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   270
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   271
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   272
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   273
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   274
		case CO:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   275
			if (src[i] == 'm') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   276
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   277
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   278
			} 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
   279
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   280
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   281
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   282
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   283
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   284
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   285
		case COMLPT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   286
			switch (src[i]) {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   287
			case '1':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   288
			case '2':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   289
			case '3':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   290
			case '4':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   291
			case '5':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   292
			case '6':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   293
			case '7':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   294
			case '8':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   295
			case '9':
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   296
				state = COMLPTn;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   297
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   298
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   299
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   300
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   301
				charcopy(dest, &destlen, destsize, src[i - 1]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   302
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   303
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   304
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   305
		case COMLPTn:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   306
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   307
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   308
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   309
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   310
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   311
				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
   312
				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
   313
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   314
			default:
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   315
				memcopy(dest, &destlen, destsize, &src[i - 2],
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   316
				        2);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   317
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   318
			}
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 L:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   321
			if (src[i] == 'p') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   322
				state = LP;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   323
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   324
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   325
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   326
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   327
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   328
		case LP:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   329
			if (src[i] == 't') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   330
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   331
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   332
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   333
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   334
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   335
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   336
		case N:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   337
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   338
				state = NU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   339
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   340
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   341
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   342
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   343
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   344
		case NU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   345
			if (src[i] == 'l') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   346
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   347
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   348
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   349
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   350
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   351
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   352
		case P:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   353
			if (src[i] == 'r') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   354
				state = PR;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   355
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   356
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   357
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   358
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   359
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   360
		case PR:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   361
			if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   362
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   363
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   364
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   365
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   366
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   367
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   368
		case LDOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   369
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   370
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   371
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   372
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   373
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   374
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   375
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   376
				state = H;
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
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   380
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   381
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   382
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   383
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   384
		case DOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   385
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   386
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   387
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   388
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   389
				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
   390
				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
   391
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   392
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   393
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   394
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   395
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   396
				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
   397
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   398
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   399
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   400
				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
   401
				i++;
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
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   404
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   405
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   406
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   407
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   408
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   409
		case H:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   410
			if (src[i] == 'g') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   411
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   412
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   413
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   414
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   415
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   416
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   417
		case HGDI:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   418
			if (src[i] == '/') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   419
				state = START;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   420
				if (encodedir) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   421
					memcopy(dest, &destlen, destsize, ".hg",
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   422
					        3);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   423
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   424
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   425
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   426
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   427
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   428
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   429
		case SPACE:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   430
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   431
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   432
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   433
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   434
				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
   435
				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
   436
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   437
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   438
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   439
				charcopy(dest, &destlen, destsize, ' ');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   440
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   441
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   442
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   443
		case DEFAULT:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   444
			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
   445
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   446
				if (i == len) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   447
					goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   448
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   449
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   450
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   451
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   452
				state = DOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   453
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   454
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   455
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   456
				state = SPACE;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   457
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   458
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   459
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   460
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   461
				charcopy(dest, &destlen, destsize, '/');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   462
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   463
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   464
			default:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   465
				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
   466
					do {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   467
						charcopy(dest, &destlen,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   468
						         destsize, src[i++]);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   469
					} while (i < len &&
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   470
					         inset(onebyte, src[i]));
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   471
				} 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
   472
					char c = src[i++];
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   473
					charcopy(dest, &destlen, destsize, '_');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   474
					charcopy(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   475
					         c == '_' ? '_' : c + 32);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   476
				} else {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   477
					escape3(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   478
					        src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   479
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   480
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   481
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   482
			break;
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
done:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   486
	return destlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   487
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   488
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   489
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
   490
                              Py_ssize_t len)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   491
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   492
	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
   493
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   494
	static const uint32_t onebyte[8] = {
38702
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   495
	    1,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   496
	    0x2bff3bfa,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   497
	    0x68000001,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   498
	    0x2fffffff,
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   499
	};
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   500
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   501
	Py_ssize_t destlen = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   502
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   503
	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
   504
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   505
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   506
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
   507
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   508
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
   509
                               Py_ssize_t len)
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   510
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   511
	static const uint32_t onebyte[8] = {1, 0x2bfffbfb, 0xe8000001,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   512
	                                    0x2fffffff};
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   513
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   514
	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
   515
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   516
	Py_ssize_t i, destlen = 0;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   517
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   518
	for (i = 0; i < len; i++) {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   519
		if (inset(onebyte, src[i])) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   520
			charcopy(dest, &destlen, destsize, src[i]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   521
		} else if (inset(lower, src[i])) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   522
			charcopy(dest, &destlen, destsize, src[i] + 32);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   523
		} else {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   524
			escape3(dest, &destlen, destsize, src[i]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   525
		}
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   526
	}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   527
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   528
	return destlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   529
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   530
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   531
PyObject *lowerencode(PyObject *self, PyObject *args)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   532
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   533
	char *path;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   534
	Py_ssize_t len, newlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   535
	PyObject *ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   536
36620
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36056
diff changeset
   537
	if (!PyArg_ParseTuple(args, PY23("s#:lowerencode", "y#:lowerencode"),
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   538
	                      &path, &len)) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   539
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   540
	}
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   541
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   542
	newlen = _lowerencode(NULL, 0, path, len);
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   543
	ret = PyBytes_FromStringAndSize(NULL, newlen);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   544
	if (ret) {
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   545
		_lowerencode(PyBytes_AS_STRING(ret), newlen, path, len);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   546
	}
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   547
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   548
	return ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   549
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   550
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   551
/* See store.py:_auxencode for a description. */
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   552
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
   553
                            Py_ssize_t len)
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   554
{
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   555
	static const uint32_t twobytes[8];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   556
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   557
	static const uint32_t onebyte[8] = {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   558
	    ~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
   559
	};
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   560
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   561
	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
   562
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   563
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   564
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
   565
{
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   566
	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
   567
	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
   568
	char *dest;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   569
	PyObject *ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   570
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   571
	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
   572
	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
   573
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   574
	while (lastslash >= 0 && src[lastslash] != '/') {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   575
		if (src[lastslash] == '.' && lastdot == -1) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   576
			lastdot = lastslash;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   577
		}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   578
		lastslash--;
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   581
#if 0
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   582
	/* 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
   583
           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
   584
           violate this rule.  */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   585
	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
   586
		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
   587
				"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
   588
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   589
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   590
#endif
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   591
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   592
	/* 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
   593
	   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
   594
	destsize = 120;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   595
	if (lastdot >= 0) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   596
		destsize += len - lastdot - 1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   597
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   598
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   599
	ret = PyBytes_FromStringAndSize(NULL, destsize);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   600
	if (ret == NULL) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   601
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   602
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   603
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   604
	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
   605
	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
   606
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   607
	/* 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
   608
	   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
   609
	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
   610
		if (src[i] == '/') {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   611
			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
   612
			/* 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
   613
			   in a space or dot, which are unportable. */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   614
			if (d == '.' || d == ' ') {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   615
				dest[destlen - 1] = '_';
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   616
				/* The + 3 is to account for "dh/" in the
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   617
				 * beginning */
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   618
			}
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   619
			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
   620
				break;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   621
			}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   622
			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
   623
			p = -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   624
		} 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
   625
			charcopy(dest, &destlen, destsize, src[i]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   626
		}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   627
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   628
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   629
	/* Rewind to just before the last slash copied. */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   630
	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
   631
		do {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   632
			destlen--;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   633
		} while (destlen > 0 && dest[destlen] != '/');
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   634
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   635
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   636
	if (destlen > 3) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   637
		if (lastslash > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   638
			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
   639
			/* 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
   640
			   truncated, so make it safe. */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   641
			if (d == '.' || d == ' ') {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   642
				dest[destlen - 1] = '_';
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   643
			}
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   646
		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
   647
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   648
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   649
	/* 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
   650
	   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
   651
	   hash and suffix. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   652
	used = destlen + 40;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   653
	if (lastdot >= 0) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   654
		used += len - lastdot - 1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   655
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   656
	slop = maxstorepathlen - used;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   657
	if (slop > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   658
		Py_ssize_t basenamelen =
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   659
		    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
   660
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   661
		if (basenamelen > slop) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   662
			basenamelen = slop;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   663
		}
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   664
		if (basenamelen > 0) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   665
			memcopy(dest, &destlen, destsize, &src[lastslash + 1],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   666
			        basenamelen);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   667
		}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   668
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   669
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   670
	/* Add hash and suffix. */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   671
	for (i = 0; i < 20; i++) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   672
		hexencode(dest, &destlen, destsize, sha[i]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   673
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   674
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   675
	if (lastdot >= 0) {
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   676
		memcopy(dest, &destlen, destsize, &src[lastdot],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   677
		        len - lastdot - 1);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   678
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   679
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   680
	assert(PyBytes_Check(ret));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   681
	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
   682
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   683
	return ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   684
}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   685
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   686
/*
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   687
 * 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
   688
 * 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
   689
 */
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   690
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
   691
{
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   692
	static PyObject *shafunc;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   693
	PyObject *shaobj, *hashobj;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   694
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   695
	if (shafunc == NULL) {
38113
f7a0398996ad pathencode: remove unused variable
Augie Fackler <augie@google.com>
parents: 38056
diff changeset
   696
		PyObject *hashlib = PyImport_ImportModule("hashlib");
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   697
		if (hashlib == NULL) {
38056
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   698
			PyErr_SetString(PyExc_ImportError,
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   699
			                "pathencode failed to find hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   700
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   701
		}
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   702
		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
   703
		Py_DECREF(hashlib);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   704
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   705
		if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   706
			PyErr_SetString(PyExc_AttributeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   707
			                "module 'hashlib' has no "
38056
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   708
			                "attribute 'sha1' in pathencode");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   709
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   710
		}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   711
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   712
38055
4fccc73ce2f6 pathencode: hashlib.sha1() takes bytes not str on Python 3
Augie Fackler <augie@google.com>
parents: 38054
diff changeset
   713
	shaobj = PyObject_CallFunction(shafunc, PY23("s#", "y#"), str, len);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   714
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   715
	if (shaobj == NULL) {
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   716
		return -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   717
	}
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   718
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   719
	hashobj = PyObject_CallMethod(shaobj, "digest", "");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   720
	Py_DECREF(shaobj);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   721
	if (hashobj == NULL) {
26050
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   722
		return -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   723
	}
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   724
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   725
	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
   726
		PyErr_SetString(PyExc_TypeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   727
		                "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
   728
		Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   729
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   730
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   731
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   732
	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
   733
	Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   734
	return 0;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   735
}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   736
19185
8bed40e02c3b pathencode: grow buffers to increase safety margin
Matt Mackall <mpm@selenic.com>
parents: 19051
diff changeset
   737
#define MAXENCODE 4096 * 4
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   738
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   739
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
   740
{
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   741
	char dired[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   742
	char lowered[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   743
	char auxed[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   744
	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
   745
	char sha[20];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   746
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   747
	baselen = (len - 5) * 3;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   748
	if (baselen >= MAXENCODE) {
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   749
		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
   750
		return NULL;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   751
	}
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   752
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   753
	dirlen = _encodedir(dired, baselen, src, len);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   754
	if (sha1hash(sha, dired, dirlen - 1) == -1) {
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   755
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   756
	}
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   757
	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
   758
	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   759
	return hashmangle(auxed, auxlen, sha);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   760
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   761
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   762
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
   763
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   764
	Py_ssize_t len, newlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   765
	PyObject *pathobj, *newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   766
	char *path;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   767
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   768
	if (!PyArg_ParseTuple(args, "O:pathencode", &pathobj)) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   769
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   770
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   771
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   772
	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
   773
		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
   774
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   775
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   776
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   777
	if (len > maxstorepathlen) {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   778
		newlen = maxstorepathlen + 2;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   779
	} else {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   780
		newlen = len ? basicencode(NULL, 0, path, len + 1) : 1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   781
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   782
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   783
	if (newlen <= maxstorepathlen + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   784
		if (newlen == len + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   785
			Py_INCREF(pathobj);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   786
			return pathobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   787
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   788
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   789
		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
   790
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   791
		if (newobj) {
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   792
			assert(PyBytes_Check(newobj));
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   793
			Py_SIZE(newobj)--;
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   794
			basicencode(PyBytes_AS_STRING(newobj), newlen, path,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   795
			            len + 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   796
		}
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   797
	} else {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   798
		newobj = hashencode(path, len + 1);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   799
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   800
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   801
	return newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   802
}