1/*
2 * Copyright (c) 2012 Apple, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef CommonNumerics_crc_h
25#define CommonNumerics_crc_h
26
27#include <stdint.h>
28#include <stddef.h>
29#include <dispatch/dispatch.h>
30#include <dispatch/queue.h>
31
32
33#define MASK08 0x00000000000000ffLL
34#define MASK16 0x000000000000ffffLL
35#define MASK32 0x00000000ffffffffLL
36#define MASK64 0xffffffffffffffffLL
37
38
39
40#define WEAK_CHECK_INPUT "123456789"
41
42// Utility Functions
43
44uint8_t reflect_byte(uint8_t b);
45uint64_t reflect(uint64_t w, size_t bits);
46uint64_t reverse_poly(uint64_t poly, size_t width);
47
48typedef uint64_t (*cccrc_setup_p)(void);
49typedef uint64_t (*cccrc_update_p)(size_t len, const void *in, uint64_t crc);
50typedef uint64_t (*cccrc_final_p)(size_t length, uint64_t crc);
51typedef uint64_t (*cccrc_oneshot_p)(size_t len, const void *in);
52
53#define NO_REFLECT_REVERSE 0
54#define REFLECT_IN 1
55#define REVERSE_OUT 2
56#define REFLECT_REVERSE 3
57
58typedef struct crcModelParms_t {
59    int width; // width in bytes
60    int reflect_reverse;
61    uint64_t mask;
62    uint64_t poly;
63    uint64_t initial_value;
64    uint64_t final_xor;
65    uint64_t weak_check;
66} crcModelParms;
67
68typedef struct crcFuncs_t {
69    cccrc_setup_p setup;
70    cccrc_update_p update;
71    cccrc_final_p final;
72    cccrc_oneshot_p oneshot;
73} crcFuncs;
74
75enum crcType_t {
76    model = 0,
77    functions = 1,
78};
79typedef uint32_t crcType;
80
81typedef struct crcDescriptor_t {
82    const char *name;
83    const crcType defType;
84    union ddef {
85        crcModelParms parms;
86        crcFuncs funcs;
87    } def;
88} crcDescriptor;
89
90typedef const crcDescriptor *crcDescriptorPtr;
91
92typedef struct crcInfo_t {
93    dispatch_once_t table_init;
94    crcDescriptorPtr descriptor;
95    size_t size;
96    union {
97        uint8_t *bytes;
98        uint16_t *b16;
99        uint32_t *b32;
100        uint64_t *b64;
101    } table;
102} crcInfo, *crcInfoPtr;
103
104
105int gen_std_crc_table(crcInfoPtr crc);
106void dump_crc_table(crcInfoPtr crc);
107uint64_t crc_normal_init(crcInfoPtr crc);
108uint64_t crc_normal_update(crcInfoPtr crc, uint8_t *p, size_t len, uint64_t current);
109uint64_t crc_normal_final(crcInfoPtr crc, uint64_t current);
110uint64_t crc_normal_oneshot(crcInfoPtr crc, uint8_t *p, size_t len);
111
112uint64_t crc_reverse_init(crcInfoPtr crc);
113uint64_t crc_reverse_update(crcInfoPtr crc, uint8_t *p, size_t len, uint64_t current);
114uint64_t crc_reverse_final(crcInfoPtr crc, uint64_t current);
115uint64_t crc_reverse_oneshot(crcInfoPtr crc, uint8_t *p, size_t len);
116
117static inline uint64_t descmaskfunc(crcDescriptorPtr descriptor) {
118    switch(descriptor->def.parms.width) {
119        case 1: return MASK08;
120        case 2: return MASK16;
121        case 4: return MASK32;
122        case 8: return MASK64;
123    }
124    return 0;
125}
126
127const crcDescriptor crc8;
128const crcDescriptor crc8_icode;
129const crcDescriptor crc8_itu;
130const crcDescriptor crc8_rohc;
131const crcDescriptor crc8_wcdma;
132const crcDescriptor crc16;
133const crcDescriptor crc16_ccitt_true;
134const crcDescriptor crc16_ccitt_false;
135const crcDescriptor crc16_usb;
136const crcDescriptor crc16_xmodem;
137const crcDescriptor crc16_dect_r;
138const crcDescriptor crc16_dect_x;
139const crcDescriptor crc16_icode;
140const crcDescriptor crc16_verifone;
141const crcDescriptor crc16_a;
142const crcDescriptor crc16_b;
143const crcDescriptor crc32;
144const crcDescriptor crc32_castagnoli;
145const crcDescriptor crc32_bzip2;
146const crcDescriptor crc32_mpeg_2;
147const crcDescriptor crc32_posix;
148const crcDescriptor crc32_xfer;
149const crcDescriptor adler32;
150const crcDescriptor crc64_ecma_182;
151
152#endif
153