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