mercurial/cext/pathencode.c
author Raphaël Gomès <rgomes@octobus.net>
Tue, 05 Apr 2022 17:11:36 +0200
branchstable
changeset 49006 5bd6bcd31dd1
parent 48330 e35807332598
child 48821 b0dd39b91e7a
permissions -rw-r--r--
relnotes: add notes for 6.1.1 This also fixes the header for 6.1 from 6.1rc0
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>
46374
e92ca942ddca cext: add Python 3.10 support
Victor Stinner <vstinner@python.org>
parents: 41336
diff changeset
    24
#include "pythoncapi_compat.h"
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    25
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    26
#include "util.h"
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    27
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    28
/* 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
    29
enum path_state {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    30
	START, /* first byte of a path component */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    31
	A,     /* "AUX" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    32
	AU,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    33
	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
    34
	C,     /* "CON" or "COMn" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    35
	CO,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    36
	COMLPT, /* "COM" or "LPT" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    37
	COMLPTn,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    38
	L,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    39
	LP,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    40
	N,
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    41
	NU,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    42
	P, /* "PRN" */
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    43
	PR,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    44
	LDOT, /* leading '.' */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    45
	DOT,  /* '.' in a non-leading position */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    46
	H,    /* ".h" */
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    47
	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
    48
	SPACE,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    49
	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
    50
};
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    51
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    52
/* state machine for dir-encoding */
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    53
enum dir_state {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    54
	DDOT,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    55
	DH,
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    56
	DHGDI,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
    57
	DDEFAULT,
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    58
};
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    59
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
    60
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
    61
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    62
	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
    63
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    64
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    65
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
    66
                            char c)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    67
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    68
	if (dest) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    69
		assert(*destlen < destsize);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    70
		dest[*destlen] = c;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    71
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    72
	(*destlen)++;
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    75
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
    76
                           const void *src, Py_ssize_t len)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    77
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    78
	if (dest) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    79
		assert(*destlen + len < destsize);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    80
		memcpy((void *)&dest[*destlen], src, len);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    81
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    82
	*destlen += len;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    83
}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    84
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    85
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
    86
                             uint8_t c)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    87
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    88
	static const char hexdigit[] = "0123456789abcdef";
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    89
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 >> 4]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    91
	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
    92
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    93
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    94
/* 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
    95
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
    96
                           char c)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    97
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    98
	charcopy(dest, destlen, destsize, '~');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
    99
	hexencode(dest, destlen, destsize, c);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   100
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   101
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   102
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
   103
                             Py_ssize_t len)
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   104
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   105
	enum dir_state state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   106
	Py_ssize_t i = 0, destlen = 0;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   107
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   108
	while (i < len) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   109
		switch (state) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   110
		case DDOT:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   111
			switch (src[i]) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   112
			case 'd':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   113
			case 'i':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   114
				state = DHGDI;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   115
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   116
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   117
			case 'h':
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   118
				state = DH;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   119
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   120
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   121
			default:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   122
				state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   123
				break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   124
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   125
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   126
		case DH:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   127
			if (src[i] == 'g') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   128
				state = DHGDI;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   129
				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
   130
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   131
				state = DDEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   132
			}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   133
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   134
		case DHGDI:
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   135
			if (src[i] == '/') {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   136
				memcopy(dest, &destlen, destsize, ".hg", 3);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   137
				charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   138
			}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   139
			state = DDEFAULT;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   140
			break;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   141
		case DDEFAULT:
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   142
			if (src[i] == '.') {
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   143
				state = DDOT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   144
			}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   145
			charcopy(dest, &destlen, destsize, src[i++]);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   146
			break;
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   150
	return destlen;
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   153
PyObject *encodedir(PyObject *self, PyObject *args)
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   154
{
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   155
	Py_ssize_t len, newlen;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   156
	PyObject *pathobj, *newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   157
	char *path;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   158
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   159
	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
   160
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   161
	}
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   162
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   163
	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
   164
		PyErr_SetString(PyExc_TypeError, "expected a string");
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   165
		return NULL;
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
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   168
	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
   169
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   170
	if (newlen == len + 1) {
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   171
		Py_INCREF(pathobj);
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   172
		return pathobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   173
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   174
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   175
	newobj = PyBytes_FromStringAndSize(NULL, newlen);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   176
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   177
	if (newobj) {
30102
a8c948ee3668 pathencode: use Py_SIZE directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30099
diff changeset
   178
		assert(PyBytes_Check(newobj));
48330
e35807332598 cext: fix Python 3.11 compatibility - Py_SIZE is not an lvalue (issue6610)
Mads Kiilerich <mads@kiilerich.com>
parents: 46374
diff changeset
   179
		Py_SET_SIZE(newobj, Py_SIZE(newobj) - 1);
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   180
		_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
   181
	}
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   182
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   183
	return newobj;
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   184
}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   185
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   186
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
   187
                          char *dest, Py_ssize_t destlen, size_t destsize,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   188
                          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
   189
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   190
	enum path_state state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   191
	Py_ssize_t i = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   192
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   193
	/*
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   194
	 * 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
   195
	 * 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
   196
	 */
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   197
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   198
	while (i < len) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   199
		switch (state) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   200
		case START:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   201
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   202
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   203
				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
   204
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   205
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   206
				state = LDOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   207
				escape3(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   208
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   209
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   210
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   211
				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
   212
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   213
			case 'a':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   214
				state = A;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   215
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   216
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   217
			case 'c':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   218
				state = C;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   219
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   220
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   221
			case 'l':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   222
				state = L;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   223
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   224
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   225
			case 'n':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   226
				state = N;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   227
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   228
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   229
			case 'p':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   230
				state = P;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   231
				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
   232
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   233
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   234
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   235
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   236
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   237
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   238
		case A:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   239
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   240
				state = AU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   241
				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
   242
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   243
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   244
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   245
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   246
		case AU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   247
			if (src[i] == 'x') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   248
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   249
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   250
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   251
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   252
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   253
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   254
		case THIRD:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   255
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   256
			switch (src[i]) {
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 '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   259
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   260
				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
   261
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   262
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   263
				i--;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   264
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   265
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   266
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   267
		case C:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   268
			if (src[i] == 'o') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   269
				state = CO;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   270
				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
   271
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   272
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   273
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   274
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   275
		case CO:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   276
			if (src[i] == 'm') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   277
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   278
				i++;
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   279
			} 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
   280
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   281
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   282
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   283
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   284
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   285
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   286
		case COMLPT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   287
			switch (src[i]) {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   288
			case '1':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   289
			case '2':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   290
			case '3':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   291
			case '4':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   292
			case '5':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   293
			case '6':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   294
			case '7':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   295
			case '8':
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   296
			case '9':
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   297
				state = COMLPTn;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   298
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   299
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   300
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   301
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   302
				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
   303
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   304
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   305
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   306
		case COMLPTn:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   307
			state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   308
			switch (src[i]) {
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 '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   311
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   312
				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
   313
				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
   314
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   315
			default:
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   316
				memcopy(dest, &destlen, destsize, &src[i - 2],
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   317
				        2);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   318
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   319
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   320
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   321
		case L:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   322
			if (src[i] == 'p') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   323
				state = LP;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   324
				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
   325
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   326
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   327
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   328
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   329
		case LP:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   330
			if (src[i] == 't') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   331
				state = COMLPT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   332
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   333
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   334
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   335
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   336
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   337
		case N:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   338
			if (src[i] == 'u') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   339
				state = NU;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   340
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   341
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   342
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   343
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   344
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   345
		case NU:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   346
			if (src[i] == 'l') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   347
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   348
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   349
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   350
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   351
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   352
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   353
		case P:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   354
			if (src[i] == 'r') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   355
				state = PR;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   356
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   357
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   358
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   359
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   360
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   361
		case PR:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   362
			if (src[i] == 'n') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   363
				state = THIRD;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   364
				i++;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   365
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   366
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   367
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   368
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   369
		case LDOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   370
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   371
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   372
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   373
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   374
				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
   375
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   376
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   377
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   378
				charcopy(dest, &destlen, destsize, src[i++]);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   379
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   380
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   381
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   382
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   383
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   384
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   385
		case DOT:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   386
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   387
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   388
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   389
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   390
				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
   391
				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
   392
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   393
			case 'd':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   394
			case 'i':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   395
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   396
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   397
				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
   398
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   399
			case 'h':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   400
				state = H;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   401
				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
   402
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   403
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   404
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   405
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   406
				charcopy(dest, &destlen, destsize, '.');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   407
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   408
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   409
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   410
		case H:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   411
			if (src[i] == 'g') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   412
				state = HGDI;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   413
				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
   414
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   415
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   416
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   417
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   418
		case HGDI:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   419
			if (src[i] == '/') {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   420
				state = START;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   421
				if (encodedir) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   422
					memcopy(dest, &destlen, destsize, ".hg",
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   423
					        3);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   424
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   425
				charcopy(dest, &destlen, destsize, src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   426
			} else {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   427
				state = DEFAULT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   428
			}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   429
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   430
		case SPACE:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   431
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   432
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   433
			case '\0':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   434
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   435
				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
   436
				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
   437
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   438
			default:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   439
				state = DEFAULT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   440
				charcopy(dest, &destlen, destsize, ' ');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   441
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   442
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   443
			break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   444
		case DEFAULT:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   445
			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
   446
				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
   447
				if (i == len) {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   448
					goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   449
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   450
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   451
			switch (src[i]) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   452
			case '.':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   453
				state = DOT;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   454
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   455
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   456
			case ' ':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   457
				state = SPACE;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   458
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   459
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   460
			case '/':
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   461
				state = START;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   462
				charcopy(dest, &destlen, destsize, '/');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   463
				i++;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   464
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   465
			default:
17699
0696b1793f4b pathencode: change isset name to avoid name collision
André Sintzoff <andre.sintzoff@gmail.com>
parents: 17692
diff changeset
   466
				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
   467
					do {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   468
						charcopy(dest, &destlen,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   469
						         destsize, src[i++]);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   470
					} while (i < len &&
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   471
					         inset(onebyte, src[i]));
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   472
				} 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
   473
					char c = src[i++];
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   474
					charcopy(dest, &destlen, destsize, '_');
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   475
					charcopy(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   476
					         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
   477
				} else {
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   478
					escape3(dest, &destlen, destsize,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   479
					        src[i++]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   480
				}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   481
				break;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   482
			}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   483
			break;
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
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   486
done:
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   487
	return destlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   488
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   489
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   490
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
   491
                              Py_ssize_t len)
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   492
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   493
	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
   494
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   495
	static const uint32_t onebyte[8] = {
38702
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   496
	    1,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   497
	    0x2bff3bfa,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   498
	    0x68000001,
992e108212a9 cext: reformat with clang-format 6.0
Yuya Nishihara <yuya@tcha.org>
parents: 38113
diff changeset
   499
	    0x2fffffff,
17616
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
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   502
	Py_ssize_t destlen = 0;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   503
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   504
	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
   505
}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   506
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   507
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
   508
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   509
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
   510
                               Py_ssize_t len)
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   511
{
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   512
	static const uint32_t onebyte[8] = {1, 0x2bfffbfb, 0xe8000001,
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   513
	                                    0x2fffffff};
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   514
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   515
	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
   516
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   517
	Py_ssize_t i, destlen = 0;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   518
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   519
	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
   520
		if (inset(onebyte, src[i])) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   521
			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
   522
		} else if (inset(lower, src[i])) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   523
			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
   524
		} else {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   525
			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
   526
		}
18430
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
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   529
	return destlen;
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
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   532
PyObject *lowerencode(PyObject *self, PyObject *args)
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   533
{
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   534
	char *path;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   535
	Py_ssize_t len, newlen;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   536
	PyObject *ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   537
36620
186c6df3a373 py3: bulk-replace 'const char*' format specifier passed to PyArg_ParseTuple*()
Yuya Nishihara <yuya@tcha.org>
parents: 36056
diff changeset
   538
	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
   539
	                      &path, &len)) {
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   540
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   541
	}
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   542
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   543
	newlen = _lowerencode(NULL, 0, path, len);
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   544
	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
   545
	if (ret) {
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   546
		_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
   547
	}
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   548
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   549
	return ret;
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   550
}
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17699
diff changeset
   551
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   552
/* See store.py:_auxencode for a description. */
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   553
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
   554
                            Py_ssize_t len)
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   555
{
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   556
	static const uint32_t twobytes[8];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   557
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   558
	static const uint32_t onebyte[8] = {
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   559
	    ~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
   560
	};
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   561
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   562
	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
   563
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   564
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   565
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
   566
{
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 dirprefixlen = 8;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   568
	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
   569
	char *dest;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   570
	PyObject *ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   571
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   572
	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
   573
	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
   574
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   575
	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
   576
		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
   577
			lastdot = lastslash;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   578
		}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   579
		lastslash--;
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   582
#if 0
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   583
	/* 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
   584
           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
   585
           violate this rule.  */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   586
	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
   587
		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
   588
				"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
   589
		return NULL;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   590
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   591
#endif
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   592
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   593
	/* 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
   594
	   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
   595
	destsize = 120;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   596
	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
   597
		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
   598
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   599
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   600
	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
   601
	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
   602
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   603
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   604
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   605
	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
   606
	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
   607
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   608
	/* 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
   609
	   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
   610
	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
   611
		if (src[i] == '/') {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   612
			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
   613
			/* 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
   614
			   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
   615
			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
   616
				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
   617
				/* 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
   618
				 * beginning */
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   619
			}
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   620
			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
   621
				break;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   622
			}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   623
			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
   624
			p = -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   625
		} 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
   626
			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
   627
		}
18432
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   630
	/* 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
   631
	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
   632
		do {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   633
			destlen--;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   634
		} 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
   635
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   636
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   637
	if (destlen > 3) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   638
		if (lastslash > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   639
			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
   640
			/* 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
   641
			   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
   642
			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
   643
				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
   644
			}
18432
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   647
		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
   648
	}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   649
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   650
	/* 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
   651
	   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
   652
	   hash and suffix. */
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   653
	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
   654
	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
   655
		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
   656
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   657
	slop = maxstorepathlen - used;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   658
	if (slop > 0) {
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   659
		Py_ssize_t basenamelen =
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   660
		    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
   661
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   662
		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
   663
			basenamelen = slop;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   664
		}
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   665
		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
   666
			memcopy(dest, &destlen, destsize, &src[lastslash + 1],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   667
			        basenamelen);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   668
		}
18432
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
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   671
	/* 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
   672
	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
   673
		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
   674
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   675
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   676
	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
   677
		memcopy(dest, &destlen, destsize, &src[lastdot],
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   678
		        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
   679
	}
18432
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   680
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   681
	assert(PyBytes_Check(ret));
46374
e92ca942ddca cext: add Python 3.10 support
Victor Stinner <vstinner@python.org>
parents: 41336
diff changeset
   682
	Py_SET_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
   683
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   684
	return ret;
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   685
}
39954be8ece7 pathencode: implement the "mangling" part of hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18431
diff changeset
   686
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   687
/*
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   688
 * 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
   689
 * 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
   690
 */
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   691
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
   692
{
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   693
	static PyObject *shafunc;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   694
	PyObject *shaobj, *hashobj;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   695
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   696
	if (shafunc == NULL) {
38113
f7a0398996ad pathencode: remove unused variable
Augie Fackler <augie@google.com>
parents: 38056
diff changeset
   697
		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
   698
		if (hashlib == NULL) {
38056
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   699
			PyErr_SetString(PyExc_ImportError,
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   700
			                "pathencode failed to find hashlib");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   701
			return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   702
		}
29340
ae92c3eee88e pathencode: use hashlib.sha1 directly instead of indirecting through util
Augie Fackler <raf@durin42.com>
parents: 27342
diff changeset
   703
		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
   704
		Py_DECREF(hashlib);
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   705
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   706
		if (shafunc == NULL) {
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   707
			PyErr_SetString(PyExc_AttributeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   708
			                "module 'hashlib' has no "
38056
9aaa74f9eb87 pathencode: improve error messages slightly
Augie Fackler <augie@google.com>
parents: 38055
diff changeset
   709
			                "attribute 'sha1' in pathencode");
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   710
			return -1;
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
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   713
38055
4fccc73ce2f6 pathencode: hashlib.sha1() takes bytes not str on Python 3
Augie Fackler <augie@google.com>
parents: 38054
diff changeset
   714
	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
   715
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   716
	if (shaobj == NULL) {
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   717
		return -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   718
	}
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   719
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   720
	hashobj = PyObject_CallMethod(shaobj, "digest", "");
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   721
	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
   722
	if (hashobj == NULL) {
26050
822f46b80fa9 pathencode: check result of .digest() method in sha1hash
Augie Fackler <augie@google.com>
parents: 20535
diff changeset
   723
		return -1;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   724
	}
18431
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   725
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   726
	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
   727
		PyErr_SetString(PyExc_TypeError,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   728
		                "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
   729
		Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   730
		return -1;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   731
	}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   732
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   733
	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
   734
	Py_DECREF(hashobj);
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   735
	return 0;
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   736
}
3aa9b2136593 pathencode: add a SHA-1 hash function
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   737
19185
8bed40e02c3b pathencode: grow buffers to increase safety margin
Matt Mackall <mpm@selenic.com>
parents: 19051
diff changeset
   738
#define MAXENCODE 4096 * 4
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   739
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   740
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
   741
{
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   742
	char dired[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   743
	char lowered[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   744
	char auxed[MAXENCODE];
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   745
	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
   746
	char sha[20];
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   747
18452
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   748
	baselen = (len - 5) * 3;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   749
	if (baselen >= MAXENCODE) {
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   750
		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
   751
		return NULL;
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   752
	}
8bd338c7c4c9 pathencode: don't use alloca() for safety/portability
Matt Mackall <mpm@selenic.com>
parents: 18434
diff changeset
   753
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   754
	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
   755
	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
   756
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   757
	}
18433
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   758
	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
   759
	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   760
	return hashmangle(auxed, auxlen, sha);
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   761
}
79f4a2a8f248 pathencode: implement hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18432
diff changeset
   762
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   763
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
   764
{
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   765
	Py_ssize_t len, newlen;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   766
	PyObject *pathobj, *newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   767
	char *path;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   768
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   769
	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
   770
		return NULL;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   771
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   772
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   773
	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
   774
		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
   775
		return NULL;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   776
	}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   777
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   778
	if (len > maxstorepathlen) {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   779
		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
   780
	} else {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   781
		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
   782
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   783
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   784
	if (newlen <= maxstorepathlen + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   785
		if (newlen == len + 1) {
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   786
			Py_INCREF(pathobj);
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   787
			return pathobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   788
		}
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   789
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   790
		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
   791
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   792
		if (newobj) {
30163
f5607b6253da pathencode: use assert() for PyBytes_Check()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30102
diff changeset
   793
			assert(PyBytes_Check(newobj));
48330
e35807332598 cext: fix Python 3.11 compatibility - Py_SIZE is not an lvalue (issue6610)
Mads Kiilerich <mads@kiilerich.com>
parents: 46374
diff changeset
   794
			Py_SET_SIZE(newobj, Py_SIZE(newobj) - 1);
30099
e60de7fcad29 pathencode: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29340
diff changeset
   795
			basicencode(PyBytes_AS_STRING(newobj), newlen, path,
36056
44cb058bc0d3 pathencode: allow clang-format oversight
Augie Fackler <augie@google.com>
parents: 32372
diff changeset
   796
			            len + 1);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   797
		}
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 38702
diff changeset
   798
	} else {
18434
3807ec0c6bba pathencode: implement both basic and hashed encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18433
diff changeset
   799
		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
   800
	}
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   801
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   802
	return newobj;
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
   803
}