diff --git a/crc32.d b/crc32.d index 60fa4a88a..cbd2e0e0f 100644 --- a/crc32.d +++ b/crc32.d @@ -14,6 +14,8 @@ // CRC-32 calculation module crc32; +pragma(msg, "The 'crc32' module has been scheduled for deprecation. Please use 'std.hash.crc32' instead."); + private immutable uint[256] crc32_table = [ 0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535, diff --git a/posix.mak b/posix.mak index 7efbf6eb2..93e979590 100644 --- a/posix.mak +++ b/posix.mak @@ -54,7 +54,7 @@ DOCSRC = ../d-programming-language.org WEBSITE_DIR = ../web DOC_OUTPUT_DIR = $(WEBSITE_DIR)/phobos-prerelease BIGDOC_OUTPUT_DIR = /tmp -SRC_DOCUMENTABLES = index.d $(addsuffix .d,$(STD_MODULES) $(STD_NET_MODULES) $(EXTRA_DOCUMENTABLES)) +SRC_DOCUMENTABLES = index.d $(addsuffix .d,$(STD_MODULES) $(STD_NET_MODULES) $(STD_HASH_MODULES) $(EXTRA_DOCUMENTABLES)) STDDOC = $(DOCSRC)/std.ddoc BIGSTDDOC = $(DOCSRC)/std_consolidated.ddoc DDOCFLAGS=-m$(MODEL) -d -c -o- -version=StdDdoc -I$(DRUNTIME_PATH)/import $(DMDEXTRAFLAGS) @@ -162,6 +162,8 @@ STD_MODULES = $(addprefix std/, algorithm array ascii base64 bigint \ STD_NET_MODULES = $(addprefix std/net/, isemail curl) +STD_HASH_MODULES = $(addprefix std/hash/, crc32) + # OS-specific D modules EXTRA_MODULES_LINUX := $(addprefix std/c/linux/, linux socket) EXTRA_MODULES_OSX := $(addprefix std/c/osx/, socket) @@ -184,7 +186,7 @@ EXTRA_MODULES += $(EXTRA_DOCUMENTABLES) $(addprefix \ processinit uni uni_tab) # Aggregate all D modules relevant to this build -D_MODULES = crc32 $(STD_MODULES) $(EXTRA_MODULES) $(STD_NET_MODULES) +D_MODULES = $(STD_MODULES) $(EXTRA_MODULES) $(STD_NET_MODULES) $(STD_HASH_MODULES) # Add the .d suffix to the module names D_FILES = $(addsuffix .d,$(D_MODULES)) # Aggregate all D modules over all OSs (this is for the zip file) diff --git a/std/hash/crc32.d b/std/hash/crc32.d new file mode 100644 index 000000000..58f503f7b --- /dev/null +++ b/std/hash/crc32.d @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001, 2002 + * Pavel "EvilOne" Minayev + * Copyright (c) 2012 + * Alex Rønne Petersen + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Author makes no representations about + * the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + */ + +/** +Cyclic Redundancy Check (32-bit) implementation. + +Macros: + +WIKI = StdHashCRC32 + +Copyright: Copyright Pavel "EvilOne" Minayev 2001, 2002. Copyright Alex Rønne Petersen 2012. +License: + +Permission to use, copy, modify, distribute and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation. Author makes no representations about +the suitability of this software for any purpose. It is provided +"as is" without express or implied warranty. + +Authors: Pavel "EvilOne" Minayev, Alex Rønne Petersen +Source: $(PHOBOSSRC std/hash/_crc32.d) +*/ + +// CRC-32 calculation +module std.hash.crc32; + +import std.range; + +@safe: + +private immutable uint[256] crc32_table = +[ + 0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535, + 0x9e6495a3,0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd, + 0xe7b82d07,0x90bf1d91,0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,0x1adad47d, + 0x6ddde4eb,0xf4d4b551,0x83d385c7,0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec, + 0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,0x3b6e20c8,0x4c69105e,0xd56041e4, + 0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,0x35b5a8fa,0x42b2986c, + 0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,0x26d930ac, + 0x51de003a,0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f, + 0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,0x2f6f7c87,0x58684c11,0xc1611dab, + 0xb6662d3d,0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,0x71b18589,0x06b6b51f, + 0x9fbfe4a5,0xe8b8d433,0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb, + 0x086d3d2d,0x91646c97,0xe6635c01,0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e, + 0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,0x65b0d9c6,0x12b7e950,0x8bbeb8ea, + 0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,0x4db26158,0x3ab551ce, + 0xa3bc0074,0xd4bb30e2,0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,0x4369e96a, + 0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9, + 0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409, + 0xce61e49f,0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81, + 0xb7bd5c3b,0xc0ba6cad,0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,0xead54739, + 0x9dd277af,0x04db2615,0x73dc1683,0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8, + 0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,0xf00f9344,0x8708a3d2,0x1e01f268, + 0x6906c2fe,0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,0xfed41b76,0x89d32be0, + 0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,0xd6d6a3e8, + 0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b, + 0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef, + 0x4669be79,0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,0xcc0c7795,0xbb0b4703, + 0x220216b9,0x5505262f,0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7, + 0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a, + 0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,0x95bf4a82,0xe2b87a14,0x7bb12bae, + 0x0cb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,0x86d3d2d4,0xf1d4e242, + 0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,0x88085ae6, + 0xff0f6a70,0x66063bca,0x11010b5c,0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45, + 0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7,0x4969474d, + 0x3e6e77db,0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5, + 0x47b2cf7f,0x30b5ffe9,0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605, + 0xcdd70693,0x54de5729,0x23d967bf,0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94, + 0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d +]; + +/** + * The initial value of a CRC32 computation. + */ +enum uint crc32Init = uint.max; + +/** + * Updates a given CRC32 value with the given byte value. + * + * Params: + * crc = The current CRC32 value. + * val = The value to add to the CRC32 computation. + */ +uint updateCRC32(T)(uint crc, T val) pure nothrow +if (is(T == ubyte) || is(T == byte)) +{ + return crc32_table[cast(ubyte)crc ^ cast(ubyte)val] ^ (crc >> 8); +} + +/** + * Computes the CRC32 value of a given range of bytes. + * + * Params: + * range = The range to compute a CRC32 value for. + */ +uint rangeToCRC32(R)(in R range) pure nothrow +if (isInputRange!R && (is(ElementType!R == byte) || is(ElementType!R == ubyte))) +{ + uint crc = crc32Init; + + foreach (val; range) + crc = updateCRC32!(ElementType!R)(crc, val); + + return crc; +} + +unittest +{ + ubyte[] bytes1 = [1, 2, 3]; + byte[] bytes2 = [1, 2, 3]; + + rangeToCRC32(bytes1); // ensure that we can call with ubyte[] + rangeToCRC32(bytes2); // ensure that we can call with byte[] +} diff --git a/std/stream.d b/std/stream.d index 4d51ef1a1..c763cfb43 100644 --- a/std/stream.d +++ b/std/stream.d @@ -385,7 +385,7 @@ interface OutputStream { // not really abstract, but its instances will do nothing useful class Stream : InputStream, OutputStream { - private import std.string, crc32, std.c.stdlib, std.c.stdio; + private import std.string, std.hash.crc32, std.c.stdlib, std.c.stdio; // stream abilities bool readable = false; /// Indicates whether this stream can be read from. @@ -1344,14 +1344,14 @@ class Stream : InputStream, OutputStream { { ulong pos = position; scope(exit) position(pos); - uint crc = init_crc32(); + uint crc = crc32Init; position(0); ulong len = size; for (ulong i = 0; i < len; i++) { ubyte c; read(c); - crc = update_crc32(c, crc); + crc = updateCRC32(crc, c); } return crc; } diff --git a/unittest.d b/unittest.d index 7d170e706..65ddb6dd2 100644 --- a/unittest.d +++ b/unittest.d @@ -18,6 +18,7 @@ public import std.compiler; public import std.concurrency; public import std.conv; public import std.cpuid; +public import std.hash.crc32; public import std.cstream; public import std.ctype; public import std.datetime; diff --git a/win32.mak b/win32.mak index 5e2f0fa71..87adc746e 100644 --- a/win32.mak +++ b/win32.mak @@ -132,7 +132,7 @@ SRC_STD_REST= std\variant.d \ SRC_STD_ALL= $(SRC_STD_1_HEAVY) $(SRC_STD_2_HEAVY) $(SRC_STD_3) $(SRC_STD_REST) -SRC= unittest.d crc32.d index.d +SRC= unittest.d index.d SRC_STD= std\zlib.d std\zip.d std\stdint.d std\container.d std\conv.d std\utf.d std\uri.d \ std\math.d std\string.d std\path.d std\datetime.d \ @@ -177,15 +177,17 @@ SRC_STD_INTERNAL= std\internal\processinit.d std\internal\uni.d std\internal\uni SRC_STD_INTERNAL_MATH= std\internal\math\biguintcore.d \ std\internal\math\biguintnoasm.d std\internal\math\biguintx86.d \ - std\internal\math\gammafunction.d std\internal\math\errorfunction.d + std\internal\math\gammafunction.d std\internal\math\errorfunction.d SRC_STD_INTERNAL_WINDOWS= std\internal\windows\advapi32.d +SRC_STD_HASH= std\hash\crc32.d + SRC_ETC= SRC_ETC_C= etc\c\zlib.d etc\c\curl.d etc\c\sqlite3.d -SRC_TO_COMPILE_NOT_STD= crc32.d \ +SRC_TO_COMPILE_NOT_STD= \ $(SRC_STD_NET) \ $(SRC_STD_C) \ $(SRC_STD_WIN) \ @@ -193,6 +195,7 @@ SRC_TO_COMPILE_NOT_STD= crc32.d \ $(SRC_STD_INTERNAL) \ $(SRC_STD_INTERNAL_MATH) \ $(SRC_STD_INTERNAL_WINDOWS) \ + $(SRC_STD_HASH) \ $(SRC_ETC) \ $(SRC_ETC_C) @@ -267,6 +270,7 @@ DOCS= $(DOC)\object.html \ $(DOC)\std_container.html \ $(DOC)\std_conv.html \ $(DOC)\std_cpuid.html \ + $(DOC)\std_hash_crc32.html \ $(DOC)\std_cstream.html \ $(DOC)\std_ctype.html \ $(DOC)\std_csv.html \ @@ -610,6 +614,9 @@ $(DOC)\std_zlib.html : $(STDDOC) std\zlib.d $(DOC)\std_net_isemail.html : $(STDDOC) std\net\isemail.d $(DMD) -c -o- $(DDOCFLAGS) -Df$(DOC)\std_net_isemail.html $(STDDOC) std\net\isemail.d +$(DOC)\std_hash_crc32.html : $(STDDOC) std\hash\crc32.d + $(DMD) -c -o- $(DDOCFLAGS) -Df$(DOC)\std_hash_crc32.html $(STDDOC) std\hash\crc32.d + $(DOC)\std_net_curl.html : $(STDDOC) std\net\curl.d $(DMD) -c -o- $(DDOCFLAGS) -Df$(DOC)\std_net_curl.html $(STDDOC) std\net\curl.d @@ -667,7 +674,7 @@ $(DOC)\etc_c_zlib.html : $(STDDOC) etc\c\zlib.d zip : win32.mak posix.mak $(STDDOC) $(SRC) \ $(SRC_STD) $(SRC_STD_C) $(SRC_STD_WIN) \ $(SRC_STD_C_WIN) $(SRC_STD_C_LINUX) $(SRC_STD_C_OSX) $(SRC_STD_C_FREEBSD) \ - $(SRC_ETC) $(SRC_ETC_C) $(SRC_ZLIB) $(SRC_STD_NET) \ + $(SRC_ETC) $(SRC_ETC_C) $(SRC_ZLIB) $(SRC_STD_NET) $(SRC_STD_HASH) \ $(SRC_STD_INTERNAL) $(SRC_STD_INTERNAL_MATH) $(SRC_STD_INTERNAL_WINDOWS) del phobos.zip zip32 -u phobos win32.mak posix.mak $(STDDOC) @@ -682,6 +689,7 @@ zip : win32.mak posix.mak $(STDDOC) $(SRC) \ zip32 -u phobos $(SRC_STD_INTERNAL) zip32 -u phobos $(SRC_STD_INTERNAL_MATH) zip32 -u phobos $(SRC_STD_INTERNAL_WINDOWS) + zip32 -u phobos $(SRC_STD_HASH) zip32 -u phobos $(SRC_ETC) $(SRC_ETC_C) zip32 -u phobos $(SRC_ZLIB) zip32 -u phobos $(SRC_STD_NET) @@ -714,6 +722,7 @@ install: $(CP) $(SRC_STD_INTERNAL) $(DIR)\src\phobos\std\internal\ $(CP) $(SRC_STD_INTERNAL_MATH) $(DIR)\src\phobos\std\internal\math\ $(CP) $(SRC_STD_INTERNAL_WINDOWS) $(DIR)\src\phobos\std\internal\windows\ + $(CP) $(SRC_STD_HASH) $(DIR)\src\phobos\std\hash\ #$(CP) $(SRC_ETC) $(DIR)\src\phobos\etc\ $(CP) $(SRC_ETC_C) $(DIR)\src\phobos\etc\c\ $(CP) $(SRC_ZLIB) $(DIR)\src\phobos\etc\c\zlib\ @@ -733,6 +742,7 @@ svn: $(CP) $(SRC_STD_INTERNAL) $(SVN)\std\internal\ $(CP) $(SRC_STD_INTERNAL_MATH) $(SVN)\std\internal\math\ $(CP) $(SRC_STD_INTERNAL_WINDOWS) $(SVN)\std\internal\windows\ + $(CP) $(STC_STD_HASH) $(SVN)\std\hash\ #$(CP) $(SRC_ETC) $(SVN)\etc\ $(CP) $(SRC_ETC_C) $(SVN)\etc\c\ $(CP) $(SRC_ZLIB) $(SVN)\etc\c\zlib\