# HG changeset patch # User Bryan O'Sullivan # Date 1355346576 28800 # Node ID 79f4a2a8f248f37fd6926d469eb751c347d23552 # Parent 39954be8ece7fac657d0087b1aa26afd472353a5 pathencode: implement hashed encoding in C This will be used by an upcoming patch. diff -r 39954be8ece7 -r 79f4a2a8f248 mercurial/pathencode.c --- a/mercurial/pathencode.c Wed Dec 12 13:09:35 2012 -0800 +++ b/mercurial/pathencode.c Wed Dec 12 13:09:36 2012 -0800 @@ -523,6 +523,19 @@ return ret; } +/* See store.py:_auxencode for a description. */ +static Py_ssize_t auxencode(char *dest, size_t destsize, + const char *src, Py_ssize_t len) +{ + static const uint32_t twobytes[8]; + + static const uint32_t onebyte[8] = { + ~0, 0xffff3ffe, ~0, ~0, ~0, ~0, ~0, ~0, + }; + + return _encode(twobytes, onebyte, dest, 0, destsize, src, len, 0); +} + static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20]) { static const Py_ssize_t dirprefixlen = 8; @@ -683,6 +696,30 @@ return 0; } +static PyObject *hashencode(const char *src, Py_ssize_t len) +{ + const Py_ssize_t baselen = (len - 5) * 3; +#ifndef _MSC_VER + /* alloca is surprisingly slow, so avoid when possible */ + char dired[baselen]; + char lowered[baselen]; + char auxed[baselen]; +#else + char *dired = alloca(baselen); + char *lowered = alloca(baselen); + char *auxed = alloca(baselen); +#endif + Py_ssize_t dirlen, lowerlen, auxlen; + char sha[20]; + + dirlen = _encodedir(dired, baselen, src, len); + if (sha1hash(sha, dired, dirlen - 1) == -1) + return NULL; + lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5); + auxlen = auxencode(auxed, baselen, lowered, lowerlen); + return hashmangle(auxed, auxlen, sha); +} + /* * We currently implement only basic encoding. *