comparison mercurial/pathencode.c @ 18433:79f4a2a8f248

pathencode: implement hashed encoding in C This will be used by an upcoming patch.
author Bryan O'Sullivan <bryano@fb.com>
date Wed, 12 Dec 2012 13:09:36 -0800
parents 39954be8ece7
children 3807ec0c6bba
comparison
equal deleted inserted replaced
18432:39954be8ece7 18433:79f4a2a8f248
521 path, len); 521 path, len);
522 522
523 return ret; 523 return ret;
524 } 524 }
525 525
526 /* See store.py:_auxencode for a description. */
527 static Py_ssize_t auxencode(char *dest, size_t destsize,
528 const char *src, Py_ssize_t len)
529 {
530 static const uint32_t twobytes[8];
531
532 static const uint32_t onebyte[8] = {
533 ~0, 0xffff3ffe, ~0, ~0, ~0, ~0, ~0, ~0,
534 };
535
536 return _encode(twobytes, onebyte, dest, 0, destsize, src, len, 0);
537 }
538
526 static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20]) 539 static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20])
527 { 540 {
528 static const Py_ssize_t dirprefixlen = 8; 541 static const Py_ssize_t dirprefixlen = 8;
529 static const Py_ssize_t maxshortdirslen = 68; 542 static const Py_ssize_t maxshortdirslen = 68;
530 char *dest; 543 char *dest;
681 memcpy(hash, PyString_AS_STRING(hashobj), 20); 694 memcpy(hash, PyString_AS_STRING(hashobj), 20);
682 Py_DECREF(hashobj); 695 Py_DECREF(hashobj);
683 return 0; 696 return 0;
684 } 697 }
685 698
699 static PyObject *hashencode(const char *src, Py_ssize_t len)
700 {
701 const Py_ssize_t baselen = (len - 5) * 3;
702 #ifndef _MSC_VER
703 /* alloca is surprisingly slow, so avoid when possible */
704 char dired[baselen];
705 char lowered[baselen];
706 char auxed[baselen];
707 #else
708 char *dired = alloca(baselen);
709 char *lowered = alloca(baselen);
710 char *auxed = alloca(baselen);
711 #endif
712 Py_ssize_t dirlen, lowerlen, auxlen;
713 char sha[20];
714
715 dirlen = _encodedir(dired, baselen, src, len);
716 if (sha1hash(sha, dired, dirlen - 1) == -1)
717 return NULL;
718 lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
719 auxlen = auxencode(auxed, baselen, lowered, lowerlen);
720 return hashmangle(auxed, auxlen, sha);
721 }
722
686 /* 723 /*
687 * We currently implement only basic encoding. 724 * We currently implement only basic encoding.
688 * 725 *
689 * If a name is too long to encode due to Windows path name limits, 726 * If a name is too long to encode due to Windows path name limits,
690 * this function returns None. 727 * this function returns None.