Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_crc.h

Go to the documentation of this file.
00001 /*
00002  * pg_crc.h
00003  *
00004  * PostgreSQL CRC support
00005  *
00006  * See Ross Williams' excellent introduction
00007  * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
00008  * http://www.ross.net/crc/ or several other net sites.
00009  *
00010  * We use a normal (not "reflected", in Williams' terms) CRC, using initial
00011  * all-ones register contents and a final bit inversion.
00012  *
00013  * The 64-bit variant is not used as of PostgreSQL 8.1, but we retain the
00014  * code for possible future use.
00015  *
00016  *
00017  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00018  * Portions Copyright (c) 1994, Regents of the University of California
00019  *
00020  * src/include/utils/pg_crc.h
00021  */
00022 #ifndef PG_CRC_H
00023 #define PG_CRC_H
00024 
00025 /* ugly hack to let this be used in frontend and backend code on Cygwin */
00026 #ifdef FRONTEND
00027 #define CRCDLLIMPORT
00028 #else
00029 #define CRCDLLIMPORT PGDLLIMPORT
00030 #endif
00031 
00032 typedef uint32 pg_crc32;
00033 
00034 /* Initialize a CRC accumulator */
00035 #define INIT_CRC32(crc) ((crc) = 0xFFFFFFFF)
00036 
00037 /* Finish a CRC calculation */
00038 #define FIN_CRC32(crc)  ((crc) ^= 0xFFFFFFFF)
00039 
00040 /* Accumulate some (more) bytes into a CRC */
00041 #define COMP_CRC32(crc, data, len)  \
00042 do { \
00043     const unsigned char *__data = (const unsigned char *) (data); \
00044     uint32      __len = (len); \
00045 \
00046     while (__len-- > 0) \
00047     { \
00048         int     __tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \
00049         (crc) = pg_crc32_table[__tab_index] ^ ((crc) << 8); \
00050     } \
00051 } while (0)
00052 
00053 /* Check for equality of two CRCs */
00054 #define EQ_CRC32(c1,c2)  ((c1) == (c2))
00055 
00056 /* Constant table for CRC calculation */
00057 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
00058 
00059 
00060 #ifdef PROVIDE_64BIT_CRC
00061 
00062 /*
00063  * If we use a 64-bit integer type, then a 64-bit CRC looks just like the
00064  * usual sort of implementation.  However, we can also fake it with two
00065  * 32-bit registers.  Experience has shown that the two-32-bit-registers code
00066  * is as fast as, or even much faster than, the 64-bit code on all but true
00067  * 64-bit machines.  We use SIZEOF_VOID_P to check the native word width.
00068  */
00069 
00070 #if SIZEOF_VOID_P < 8
00071 
00072 /*
00073  * crc0 represents the LSBs of the 64-bit value, crc1 the MSBs.  Note that
00074  * with crc0 placed first, the output of 32-bit and 64-bit implementations
00075  * will be bit-compatible only on little-endian architectures.  If it were
00076  * important to make the two possible implementations bit-compatible on
00077  * all machines, we could do a configure test to decide how to order the
00078  * two fields, but it seems not worth the trouble.
00079  */
00080 typedef struct pg_crc64
00081 {
00082     uint32      crc0;
00083     uint32      crc1;
00084 }   pg_crc64;
00085 
00086 /* Initialize a CRC accumulator */
00087 #define INIT_CRC64(crc) ((crc).crc0 = 0xffffffff, (crc).crc1 = 0xffffffff)
00088 
00089 /* Finish a CRC calculation */
00090 #define FIN_CRC64(crc)  ((crc).crc0 ^= 0xffffffff, (crc).crc1 ^= 0xffffffff)
00091 
00092 /* Accumulate some (more) bytes into a CRC */
00093 #define COMP_CRC64(crc, data, len)  \
00094 do { \
00095     uint32      __crc0 = (crc).crc0; \
00096     uint32      __crc1 = (crc).crc1; \
00097     unsigned char *__data = (unsigned char *) (data); \
00098     uint32      __len = (len); \
00099 \
00100     while (__len-- > 0) \
00101     { \
00102         int     __tab_index = ((int) (__crc1 >> 24) ^ *__data++) & 0xFF; \
00103         __crc1 = pg_crc64_table1[__tab_index] ^ ((__crc1 << 8) | (__crc0 >> 24)); \
00104         __crc0 = pg_crc64_table0[__tab_index] ^ (__crc0 << 8); \
00105     } \
00106     (crc).crc0 = __crc0; \
00107     (crc).crc1 = __crc1; \
00108 } while (0)
00109 
00110 /* Check for equality of two CRCs */
00111 #define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0 && (c1).crc1 == (c2).crc1)
00112 
00113 /* Constant table for CRC calculation */
00114 extern CRCDLLIMPORT const uint32 pg_crc64_table0[];
00115 extern CRCDLLIMPORT const uint32 pg_crc64_table1[];
00116 #else                           /* use int64 implementation */
00117 
00118 typedef struct pg_crc64
00119 {
00120     uint64      crc0;
00121 }   pg_crc64;
00122 
00123 /* Initialize a CRC accumulator */
00124 #define INIT_CRC64(crc) ((crc).crc0 = UINT64CONST(0xffffffffffffffff))
00125 
00126 /* Finish a CRC calculation */
00127 #define FIN_CRC64(crc)  ((crc).crc0 ^= UINT64CONST(0xffffffffffffffff))
00128 
00129 /* Accumulate some (more) bytes into a CRC */
00130 #define COMP_CRC64(crc, data, len)  \
00131 do { \
00132     uint64      __crc0 = (crc).crc0; \
00133     unsigned char *__data = (unsigned char *) (data); \
00134     uint32      __len = (len); \
00135 \
00136     while (__len-- > 0) \
00137     { \
00138         int     __tab_index = ((int) (__crc0 >> 56) ^ *__data++) & 0xFF; \
00139         __crc0 = pg_crc64_table[__tab_index] ^ (__crc0 << 8); \
00140     } \
00141     (crc).crc0 = __crc0; \
00142 } while (0)
00143 
00144 /* Check for equality of two CRCs */
00145 #define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0)
00146 
00147 /* Constant table for CRC calculation */
00148 extern CRCDLLIMPORT const uint64 pg_crc64_table[];
00149 #endif   /* SIZEOF_VOID_P < 8 */
00150 #endif   /* PROVIDE_64BIT_CRC */
00151 
00152 #endif   /* PG_CRC_H */