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 25 26#include "crc.h" 27 28 29uint64_t 30crc_reverse_init(crcInfoPtr crc) 31{ 32 dispatch_once(&crc->table_init, ^{ 33 gen_std_crc_table(crc); 34 }); 35 return crc->descriptor->def.parms.initial_value; 36} 37 38static inline uint8_t 39crc_table_value8(uint8_t *table, uint8_t p, uint8_t crc) { 40 return table[(crc ^ p) & 0xff] ^ (crc >> 8); 41} 42 43static inline uint16_t 44crc_table_value16(uint16_t *table, uint8_t p, uint16_t crc) { 45 return table[(crc ^ p) & 0xff] ^ (crc >> 8); 46} 47 48static inline uint32_t 49crc_table_value32(uint32_t *table, uint8_t p, uint32_t crc) { 50 return table[(crc ^ p) & 0xff] ^ (crc >> 8); 51} 52 53static inline uint64_t 54crc_table_value64(uint64_t *table, uint8_t p, uint64_t crc) { 55 return table[(crc ^ p) & 0xffLL] ^ (crc >> 8); 56} 57 58uint64_t 59crc_reverse_update(crcInfoPtr crc, uint8_t *p, size_t len, uint64_t current) 60{ 61 while (len--) { 62 switch (crc->descriptor->def.parms.width) { 63 case 1: current = crc_table_value8(crc->table.bytes, *p, (uint8_t) current); break; 64 case 2: current = crc_table_value16(crc->table.b16, *p, (uint16_t) current); break; 65 case 4: current = crc_table_value32(crc->table.b32, *p, (uint32_t) current); break; 66 case 8: current = crc_table_value64(crc->table.b64, *p, current); break; 67 } 68 } 69 return current; 70} 71 72 73uint64_t 74crc_reverse_final(crcInfoPtr crc, uint64_t current) 75{ 76 return current ^ crc->descriptor->def.parms.final_xor; 77} 78 79uint64_t 80crc_reverse_oneshot(crcInfoPtr crc, uint8_t *p, size_t len) 81{ 82 dispatch_once(&crc->table_init, ^{ 83 gen_std_crc_table(crc); 84 }); 85 uint64_t current = crc->descriptor->def.parms.initial_value; 86 while (len--) { 87 switch (crc->descriptor->def.parms.width) { 88 case 1: current = crc_table_value8(crc->table.bytes, *p, (uint8_t) current); break; 89 case 2: current = crc_table_value16(crc->table.b16, *p, (uint16_t) current); break; 90 case 4: current = crc_table_value32(crc->table.b32, *p, (uint32_t) current); break; 91 case 8: current = crc_table_value64(crc->table.b64, *p, current); break; 92 } 93 p++; 94 } 95 return current ^ crc->descriptor->def.parms.final_xor; 96} 97