version bump 0.3.0: cleanup and flow

This commit is contained in:
SheetJS 2015-05-06 14:47:18 -07:00
parent 5cc2f712b1
commit 6cdecfeb22
13 changed files with 200 additions and 58 deletions

17
.flowconfig Normal file

@ -0,0 +1,17 @@
[ignore]
.*/node_modules/.*
.*/dist/.*
.*/test.js
.*/crc32.js
.*/bits/.*
.*/ctest/.*
.*/misc/.*
.*/perf/.*
[include]
crc32.flow.js
[libs]
[options]

4
.jshintrc Normal file

@ -0,0 +1,4 @@
{
"bitwise": false,
"curly": false
}

@ -1,10 +1,20 @@
LIB=crc32
REQS=
ADDONS=
AUXTARGETS=
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
DEPS=$(sort $(wildcard bits/*.js))
TARGET=$(LIB).js
$(TARGET): $(DEPS)
.PHONY: all
all: $(TARGET) $(AUXTARGETS)
$(TARGET) $(AUXTARGETS): %.js : %.flow.js
node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^\s*\/\*:[^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*:[^*]*\*\//gm,""))' > $@
$(LIB).flow.js: $(DEPS)
cat $^ | tr -d '\15\32' > $@
cp -f $@ ctest/
bits/01_version.js: package.json
echo "CRC32.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
@ -15,18 +25,23 @@ clean:
.PHONY: test mocha
test mocha: test.js
mocha -R spec
mocha -R spec -t 20000
.PHONY: ctest
ctest:
cat misc/*.js > ctest/fixtures.js
cp -f test.js ctest/test.js
cp -f $(TARGET) ctest/
cp -f $(TARGET) ctest/
.PHONY: lint
lint: $(TARGET)
jshint --show-non-errors $(TARGET)
jscs $(TARGET)
lint: $(TARGET) $(AUXTARGETS)
jshint --show-non-errors $(TARGET) $(AUXTARGETS)
jshint --show-non-errors package.json
jscs $(TARGET) $(AUXTARGETS)
.PHONY: flow
flow: lint
flow check --all --show-all-errors
.PHONY: cov cov-spin
cov: misc/coverage.html
@ -39,11 +54,11 @@ $(COVFMT): cov_%:
FMTS=$* make cov
misc/coverage.html: $(TARGET) test.js
mocha --require blanket -R html-cov > $@
mocha --require blanket -R html-cov -t 20000 > $@
.PHONY: coveralls coveralls-spin
coveralls:
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | ./node_modules/coveralls/bin/coveralls.js
coveralls-spin:
make coveralls & bash misc/spin.sh $$!

@ -5,59 +5,61 @@ Emphasis on correctness and performance.
## Installation
In [nodejs](https://www.npmjs.org/package/crc-32):
With [npm](https://www.npmjs.org/package/crc-32):
npm install crc-32
$ npm install crc-32
In the browser:
<script lang="javascript" src="crc32.js"></script>
<script src="crc32.js"></script>
The browser exposes a variable CRC32
The script will manipulate `module.exports` if available (e.g. in a CommonJS
`require` context). This is not always desirable. To prevent the behavior,
define `DO_NOT_EXPORT_CRC`
## Usage
- `CRC32.buf(byte array or buffer)` assumes the argument is a set of 8 bit
unsigned integers (e.g. nodejs `Buffer` or simple array of ints)
In all cases, the relevant function takes a single argument representing data.
The return value is a signed 32-bit integer.
- `CRC32.buf(byte array or buffer)` assumes the argument is a set of 8-bit
unsigned integers (e.g. nodejs `Buffer` or simple array of ints).
- `CRC32.bstr(binary string)` interprets the argument as a binary string where
the `i`-th byte is `str.charCodeAt(i)`
the `i`-th byte is the low byte of the UCS-2 char: `str.charCodeAt(i) & 0xFF`
- `CRC32.str(string)` interprets the argument as a standard JS string
For example:
```js
> // var CRC32 = require('crc-32'); // uncomment this line if in node
> CRC32.str("SheetJS") // -1647298270
> CRC32.bstr("SheetJS") // -1647298270
> CRC32.buf([ 83, 104, 101, 101, 116, 74, 83 ]) // -1647298270
> [CRC32.str("\u2603"), CRC32.str("\u0003")] // [ -1743909036, 1259060791 ]
> [CRC32.bstr("\u2603"), CRC32.bstr("\u0003")] // [ 1259060791, 1259060791 ]
> [CRC32.buf([0x2603]), CRC32.buf([0x0003])] // [ 1259060791, 1259060791 ]
```
## Testing
`make test` will run the nodejs-based test. To run the in-browser tests, run a
local server and go to the `ctest` directory. To update the browser artifacts,
run `make ctest`.
`make test` will run the node-based tests.
## Performance
`make perf` will run algorithmic performance tests (which should justify certain
decisions in the code).
`make perf-all` compares the performance of various crc-32 algorithms that
implement the correct form (note that the SSE intrinsic is designed for the
CRC32C checksum and uses a different polynomial).
Unexpected code patterns were based on performance testing in node and browser:
- [Loop unrolling helps!](http://jsperf.com/crc32-table/2)
## In the future ...
- Specifying an arbitrary initial CRC value
- Supporting different polynomials (e.g. CRC32C)
To run the in-browser tests, run a local server and go to the `ctest` directory.
To update the browser artifacts, run `make ctest`.
## License
Please consult the attached LICENSE file for details. All rights not explicitly
granted by the Apache 2.0 license are reserved by the Original Author.
## Badges
[![Build Status](https://travis-ci.org/SheetJS/js-crc32.svg?branch=master)](https://travis-ci.org/SheetJS/js-crc32)
[![Coverage Status](https://img.shields.io/coveralls/SheetJS/js-crc32/master.svg)](https://coveralls.io/r/SheetJS/js-crc32?branch=master)
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/ee0e89f8b1d5b861ffbf264b8ce329a6 "githalytics.com")](http://githalytics.com/SheetJS/js-crc32)
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-crc32/master.svg)](https://coveralls.io/r/SheetJS/js-crc32?branch=master)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-crc32?pixel)](https://github.com/SheetJS/js-crc32)

@ -1,4 +1,5 @@
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
var CRC32 = {};
/*:: declare var DO_NOT_EXPORT_CRC: any; */
(function(CRC32) {

@ -1 +1 @@
CRC32.version = '0.2.2';
CRC32.version = '0.3.0';

5
bits/10_types.js Normal file

@ -0,0 +1,5 @@
/*::
type CRC32Type = number;
type ABuf = Array<number> | Buffer;
type CRC32TableType = Array<number> | Int32Array;
*/

@ -1,6 +1,6 @@
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = new Array(256);
function signed_crc_table()/*:CRC32TableType*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
for(var n =0; n != 256; ++n){
c = n;

@ -1,7 +1,7 @@
/* charCodeAt is the best approach for binary strings */
var use_buffer = typeof Buffer !== 'undefined';
function crc32_bstr(bstr) {
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
function crc32_bstr(bstr/*:string*/)/*:CRC32Type*/ {
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
var crc = -1, L = bstr.length - 1;
for(var i = 0; i < L;) {
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
@ -11,7 +11,7 @@ function crc32_bstr(bstr) {
return crc ^ -1;
}
function crc32_buf(buf) {
function crc32_buf(buf/*:ABuf*/)/*:CRC32Type*/ {
if(buf.length > 10000) return crc32_buf_8(buf);
for(var crc = -1, i = 0, L=buf.length-3; i < L;) {
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
@ -23,7 +23,7 @@ function crc32_buf(buf) {
return crc ^ -1;
}
function crc32_buf_8(buf) {
function crc32_buf_8(buf/*:ABuf*/)/*:CRC32Type*/ {
for(var crc = -1, i = 0, L=buf.length-7; i < L;) {
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
@ -39,7 +39,7 @@ function crc32_buf_8(buf) {
}
/* much much faster to intertwine utf8 and crc */
function crc32_str(str) {
function crc32_str(str/*:string*/)/*:CRC32Type*/ {
for(var crc = -1, i = 0, L=str.length, c, d; i < L;) {
c = str.charCodeAt(i++);
if(c < 0x80) {

100
crc32.flow.js Normal file

@ -0,0 +1,100 @@
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
var CRC32 = {};
/*:: declare var DO_NOT_EXPORT_CRC: any; */
(function(CRC32) {
CRC32.version = '0.3.0';
/*::
type CRC32Type = number;
type ABuf = Array<number> | Buffer;
type CRC32TableType = Array<number> | Int32Array;
*/
/* see perf/crc32table.js */
function signed_crc_table()/*:CRC32TableType*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
for(var n =0; n != 256; ++n){
c = n;
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
table[n] = c;
}
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
}
var table = signed_crc_table();
/* charCodeAt is the best approach for binary strings */
var use_buffer = typeof Buffer !== 'undefined';
function crc32_bstr(bstr/*:string*/)/*:CRC32Type*/ {
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
var crc = -1, L = bstr.length - 1;
for(var i = 0; i < L;) {
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
}
if(i === L) crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i)) & 0xFF];
return crc ^ -1;
}
function crc32_buf(buf/*:ABuf*/)/*:CRC32Type*/ {
if(buf.length > 10000) return crc32_buf_8(buf);
for(var crc = -1, i = 0, L=buf.length-3; i < L;) {
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
}
while(i < L+3) crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
return crc ^ -1;
}
function crc32_buf_8(buf/*:ABuf*/)/*:CRC32Type*/ {
for(var crc = -1, i = 0, L=buf.length-7; i < L;) {
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
}
while(i < L+7) crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
return crc ^ -1;
}
/* much much faster to intertwine utf8 and crc */
function crc32_str(str/*:string*/)/*:CRC32Type*/ {
for(var crc = -1, i = 0, L=str.length, c, d; i < L;) {
c = str.charCodeAt(i++);
if(c < 0x80) {
crc = (crc >>> 8) ^ table[(crc ^ c) & 0xFF];
} else if(c < 0x800) {
crc = (crc >>> 8) ^ table[(crc ^ (192|((c>>6)&31))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|(c&63))) & 0xFF];
} else if(c >= 0xD800 && c < 0xE000) {
c = (c&1023)+64; d = str.charCodeAt(i++) & 1023;
crc = (crc >>> 8) ^ table[(crc ^ (240|((c>>8)&7))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|((c>>2)&63))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|((d>>6)&15)|(c&3))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|(d&63))) & 0xFF];
} else {
crc = (crc >>> 8) ^ table[(crc ^ (224|((c>>12)&15))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|((c>>6)&63))) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ (128|(c&63))) & 0xFF];
}
}
return crc ^ -1;
}
CRC32.table = table;
CRC32.bstr = crc32_bstr;
CRC32.buf = crc32_buf;
CRC32.str = crc32_str;
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_CRC === 'undefined' ? exports : CRC32);

@ -2,10 +2,10 @@
/* vim: set ts=2: */
var CRC32 = {};
(function(CRC32) {
CRC32.version = '0.2.2';
CRC32.version = '0.3.0';
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = new Array(256);
var c = 0, table = new Array(256);
for(var n =0; n != 256; ++n){
c = n;
@ -27,7 +27,7 @@ var table = signed_crc_table();
/* charCodeAt is the best approach for binary strings */
var use_buffer = typeof Buffer !== 'undefined';
function crc32_bstr(bstr) {
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
var crc = -1, L = bstr.length - 1;
for(var i = 0; i < L;) {
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);

@ -2,10 +2,10 @@
/* vim: set ts=2: */
var CRC32 = {};
(function(CRC32) {
CRC32.version = '0.2.2';
CRC32.version = '0.3.0';
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = new Array(256);
var c = 0, table = new Array(256);
for(var n =0; n != 256; ++n){
c = n;
@ -27,7 +27,7 @@ var table = signed_crc_table();
/* charCodeAt is the best approach for binary strings */
var use_buffer = typeof Buffer !== 'undefined';
function crc32_bstr(bstr) {
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
var crc = -1, L = bstr.length - 1;
for(var i = 0; i < L;) {
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);

@ -1,15 +1,13 @@
{
"name": "crc-32",
"version": "0.2.2",
"version": "0.3.0",
"author": "sheetjs",
"description": "Pure-JS CRC-32",
"keywords": [ "crc32", "checksum", "crc" ],
"main": "./crc32",
"devDependencies": {
"mocha":"",
"xlsjs":"",
"uglify-js":"",
"codepage":""
"uglify-js":""
},
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-crc32.git" },
"scripts": {