Line data Source code
1 : /* contrib/ltree/crc32.c */
2 :
3 : /*
4 : * Implements CRC-32, as used in ltree.
5 : *
6 : * Note that the CRC is used in the on-disk format of GiST indexes, so we
7 : * must stay backwards-compatible!
8 : */
9 :
10 : #include "postgres.h"
11 : #include "ltree.h"
12 :
13 : #include "crc32.h"
14 : #include "utils/pg_crc.h"
15 : #ifdef LOWER_NODE
16 : #include "utils/pg_locale.h"
17 : #endif
18 :
19 : #ifdef LOWER_NODE
20 :
21 : unsigned int
22 156802 : ltree_crc32_sz(const char *buf, int size)
23 : {
24 : pg_crc32 crc;
25 156802 : const char *p = buf;
26 156802 : const char *end = buf + size;
27 : static pg_locale_t locale = NULL;
28 :
29 156802 : if (!locale)
30 1 : locale = pg_database_locale();
31 :
32 156802 : INIT_TRADITIONAL_CRC32(crc);
33 376366 : while (size > 0)
34 : {
35 : char foldstr[UNICODE_CASEMAP_BUFSZ];
36 219564 : int srclen = pg_mblen_range(p, end);
37 : size_t foldlen;
38 :
39 : /* fold one codepoint at a time */
40 219564 : foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen,
41 : locale);
42 :
43 439128 : COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen);
44 :
45 219564 : size -= srclen;
46 219564 : p += srclen;
47 : }
48 156802 : FIN_TRADITIONAL_CRC32(crc);
49 156802 : return (unsigned int) crc;
50 : }
51 :
52 : #else
53 :
54 : unsigned int
55 : ltree_crc32_sz(const char *buf, int size)
56 : {
57 : pg_crc32 crc;
58 : const char *p = buf;
59 :
60 : INIT_TRADITIONAL_CRC32(crc);
61 : while (size > 0)
62 : {
63 : COMP_TRADITIONAL_CRC32(crc, p, 1);
64 : size--;
65 : p++;
66 : }
67 : FIN_TRADITIONAL_CRC32(crc);
68 : return (unsigned int) crc;
69 : }
70 :
71 : #endif /* !LOWER_NODE */
|