version bump 1.0.0: running hash
This commit is contained in:
parent
b692b3f7df
commit
318cb4ebd4
@ -10,13 +10,18 @@
|
||||
.*/perf/.*
|
||||
|
||||
.*/demo/browser.js
|
||||
.*/shim.js
|
||||
|
||||
[include]
|
||||
adler32.flow.js
|
||||
.*/bin/.*.njs
|
||||
.*/demo/browser.flow.js
|
||||
|
||||
[libs]
|
||||
bits/10_types.js
|
||||
misc/flow.js
|
||||
misc/flowdeps.js
|
||||
|
||||
[options]
|
||||
module.file_ext=.js
|
||||
module.file_ext=.njs
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ test_files/*.py
|
||||
test_files/*.js
|
||||
test_files/baseline*
|
||||
misc/coverage.html
|
||||
ctest/sauce*
|
||||
|
7
Makefile
7
Makefile
@ -2,6 +2,7 @@ LIB=adler32
|
||||
REQS=
|
||||
ADDONS=
|
||||
AUXTARGETS=demo/browser.js
|
||||
CMDS=bin/adler32.njs
|
||||
HTMLLINT=index.html
|
||||
|
||||
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
||||
@ -31,12 +32,13 @@ clean: clean-baseline ## Remove targets and build artifacts
|
||||
|
||||
.PHONY: test mocha
|
||||
test mocha: test.js $(TARGET) baseline ## Run test suite
|
||||
mocha -R spec -t 20000
|
||||
mocha -R spec -t 30000
|
||||
|
||||
.PHONY: ctest
|
||||
ctest: ## Build browser test (into ctest/ subdirectory)
|
||||
cat misc/*.js > ctest/fixtures.js
|
||||
cp -f test.js ctest/test.js
|
||||
cp -f shim.js ctest/shim.js
|
||||
cp -f $(TARGET) ctest/
|
||||
|
||||
.PHONY: ctestserv
|
||||
@ -56,6 +58,7 @@ clean-baseline: ## Remove test baselines
|
||||
.PHONY: lint
|
||||
lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
|
||||
@jshint --show-non-errors $(TARGET) $(AUXTARGETS)
|
||||
@jshint --show-non-errors $(CMDS)
|
||||
@jshint --show-non-errors package.json
|
||||
@jshint --show-non-errors --extract=always $(HTMLLINT)
|
||||
@jscs $(TARGET) $(AUXTARGETS)
|
||||
@ -68,7 +71,7 @@ flow: lint ## Run flow checker
|
||||
cov: misc/coverage.html ## Run coverage test
|
||||
|
||||
misc/coverage.html: $(TARGET) test.js
|
||||
mocha --require blanket -R html-cov -t 20000 > $@
|
||||
mocha --require blanket -R html-cov -t 30000 > $@
|
||||
|
||||
.PHONY: coveralls
|
||||
coveralls: ## Coverage Test + Send to coveralls.io
|
||||
|
64
README.md
64
README.md
@ -1,32 +1,63 @@
|
||||
# adler32
|
||||
|
||||
Signed ADLER-32 algorithm implementation in JS (for the browser and nodejs).
|
||||
Emphasis on correctness and performance.
|
||||
Emphasis on correctness, performance, and IE6+ support.
|
||||
|
||||
## Installation
|
||||
|
||||
With [npm](https://www.npmjs.org/package/adler-32):
|
||||
|
||||
npm install adler-32
|
||||
```bash
|
||||
$ npm install adler-32
|
||||
```
|
||||
|
||||
In the browser:
|
||||
|
||||
<script lang="javascript" src="adler32.js"></script>
|
||||
```html
|
||||
<script lang="javascript" src="adler32.js"></script>
|
||||
```
|
||||
|
||||
The browser exposes a variable ADLER32
|
||||
The browser exposes a variable `ADLER32`.
|
||||
|
||||
When installed globally, npm installs a script `adler32` that computes the
|
||||
checksum for a specified file or standard input.
|
||||
|
||||
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_ADLER`.
|
||||
|
||||
## Usage
|
||||
|
||||
- `ADLER32.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 an argument representing data and an
|
||||
optional second argument representing the starting "seed" (for running hash).
|
||||
|
||||
- `ADLER32.bstr(binary string)` interprets the argument as a binary string where
|
||||
the `i`-th byte is `str.charCodeAt(i)`
|
||||
The return value is a signed 32-bit integer.
|
||||
|
||||
- `ADLER32.str(string)` interprets the argument as a standard JS string
|
||||
- `ADLER32.buf(byte array or buffer[, seed])` assumes the argument is a sequence
|
||||
of 8-bit unsigned integers (e.g. nodejs `Buffer` or simple array of ints).
|
||||
|
||||
- `ADLER32.bstr(binary string[, seed])` assumes the argument as a binary string
|
||||
where byte `i` is the low byte of the UCS-2 char: `str.charCodeAt(i) & 0xFF`
|
||||
|
||||
- `ADLER32.str(string)` assumes the argument as a standard JS string and
|
||||
calculates the hash of the UTF-8 encoding.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
// var ADLER32 = require('adler-32'); // uncomment if in node
|
||||
ADLER32.str("SheetJS") // 176947863
|
||||
ADLER32.bstr("SheetJS") // 176947863
|
||||
ADLER32.buf([ 83, 104, 101, 101, 116, 74, 83 ]) // 176947863
|
||||
|
||||
adler32 = ADLER32.buf([83, 104]) // 17825980 "Sh"
|
||||
adler32 = ADLER32.str("eet", adler32) // 95486458 "Sheet"
|
||||
ADLER32.bstr("JS", adler32) // 176947863 "SheetJS"
|
||||
|
||||
[ADLER32.str("\u2603"), ADLER32.str("\u0003")] // [ 73138686, 262148 ]
|
||||
[ADLER32.bstr("\u2603"), ADLER32.bstr("\u0003")] // [ 262148, 262148 ]
|
||||
[ADLER32.buf([0x2603]), ADLER32.buf([0x0003])] // [ 262148, 262148 ]
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
@ -39,7 +70,7 @@ To update the browser artifacts, run `make ctest`.
|
||||
|
||||
To generate the bits file, use the `adler32` function from python zlib:
|
||||
|
||||
```
|
||||
```python
|
||||
>>> from zlib import adler32
|
||||
>>> x="foo bar baz٪☃🍣"
|
||||
>>> adler32(x)
|
||||
@ -52,7 +83,7 @@ To generate the bits file, use the `adler32` function from python zlib:
|
||||
|
||||
The included `adler32.njs` script can process files or stdin:
|
||||
|
||||
```
|
||||
```bash
|
||||
$ echo "this is a test" > t.txt
|
||||
$ bin/adler32.njs t.txt
|
||||
726861088
|
||||
@ -60,7 +91,7 @@ $ bin/adler32.njs t.txt
|
||||
|
||||
For comparison, the included `adler32.py` script uses python zlib:
|
||||
|
||||
```
|
||||
```bash
|
||||
$ bin/adler32.py t.txt
|
||||
726861088
|
||||
```
|
||||
@ -70,8 +101,6 @@ $ bin/adler32.py t.txt
|
||||
`make perf` will run algorithmic performance tests (which should justify certain
|
||||
decisions in the code).
|
||||
|
||||
[js-crc](http://git.io/crc32) has more performance notes
|
||||
|
||||
Bit twiddling is much faster than taking the mod on Safari and older Firefoxes.
|
||||
Instead of taking the literal mod 65521, it is faster to keep it in the integers
|
||||
by bit-shifting: `65536 ~ 15 mod 65521` so for nonnegative integer `a`:
|
||||
@ -87,7 +116,7 @@ The mod is taken at the very end, since the intermediate result may exceed 65521
|
||||
|
||||
The magic numbers were chosen so as to not overflow a 31-bit integer:
|
||||
|
||||
```
|
||||
```mathematica
|
||||
F[n_] := Reduce[x*(x + 1)*n/2 + (x + 1)*(65521) < (2^31 - 1) && x > 0, x, Integers]
|
||||
F[255] (* bstr: x \[Element] Integers && 1 <= x <= 3854 *)
|
||||
F[127] (* ascii: x \[Element] Integers && 1 <= x <= 5321 *)
|
||||
@ -102,9 +131,10 @@ granted by the Apache 2.0 license are reserved by the Original Author.
|
||||
|
||||
## Badges
|
||||
|
||||
[![Sauce Test Status](https://saucelabs.com/browser-matrix/adler32.svg)](https://saucelabs.com/u/adler32)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-adler32.svg?branch=master)](https://travis-ci.org/SheetJS/js-adler32)
|
||||
|
||||
[![Coverage Status](https://coveralls.io/repos/SheetJS/js-adler32/badge.png?branch=master)](https://coveralls.io/r/SheetJS/js-adler32?branch=master)
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-adler32/master.svg)](https://coveralls.io/r/SheetJS/js-adler32?branch=master)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-adler32?pixel)](https://github.com/SheetJS/js-adler32)
|
||||
|
||||
|
@ -23,22 +23,20 @@ var ADLER32;
|
||||
}
|
||||
/*jshint ignore:end */
|
||||
}(function(ADLER32) {
|
||||
ADLER32.version = '0.4.0';
|
||||
ADLER32.version = '1.0.0';
|
||||
/*::
|
||||
type ADLER32Type = number;
|
||||
type ABuf = Array<number> | Buffer;
|
||||
*/
|
||||
/*# consult README.md for the magic number */
|
||||
/*# charCodeAt is the best approach for binary strings */
|
||||
/*global Buffer */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr));
|
||||
function adler32_bstr(bstr/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += bstr.charCodeAt(i);
|
||||
a += bstr.charCodeAt(i)&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -47,12 +45,13 @@ function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ {
|
||||
function adler32_buf(buf/*:ABuf*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = buf.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = (seed >>> 16) & 0xFFFF; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += buf[i];
|
||||
a += buf[i]&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -62,8 +61,9 @@ function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ {
|
||||
}
|
||||
|
||||
/*# much much faster to intertwine utf8 and adler */
|
||||
function adler32_str(str/*:string*/)/*:ADLER32Type*/ {
|
||||
function adler32_str(str/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = str.length, M = 0, c = 0, d = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
@ -88,7 +88,7 @@ function adler32_str(str/*:string*/)/*:ADLER32Type*/ {
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
b = (15*(b>>>16)+(b&65535));
|
||||
}
|
||||
return (b << 16) | a;
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
|
20
adler32.js
20
adler32.js
@ -21,16 +21,14 @@ var ADLER32;
|
||||
}
|
||||
/*jshint ignore:end */
|
||||
}(function(ADLER32) {
|
||||
ADLER32.version = '0.4.0';
|
||||
/*global Buffer */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr));
|
||||
ADLER32.version = '1.0.0';
|
||||
function adler32_bstr(bstr, seed) {
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += bstr.charCodeAt(i);
|
||||
a += bstr.charCodeAt(i)&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -39,12 +37,13 @@ function adler32_bstr(bstr) {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_buf(buf) {
|
||||
function adler32_buf(buf, seed) {
|
||||
var a = 1, b = 0, L = buf.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = (seed >>> 16) & 0xFFFF; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += buf[i];
|
||||
a += buf[i]&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -53,8 +52,9 @@ function adler32_buf(buf) {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_str(str) {
|
||||
function adler32_str(str, seed) {
|
||||
var a = 1, b = 0, L = str.length, M = 0, c = 0, d = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
@ -79,7 +79,7 @@ function adler32_str(str) {
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
b = (15*(b>>>16)+(b&65535));
|
||||
}
|
||||
return (b << 16) | a;
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
|
@ -2,36 +2,77 @@
|
||||
/* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
|
||||
var X;
|
||||
var X/*:ADLER32Module*/;
|
||||
try { X = require('../'); } catch(e) { X = require('adler-32'); }
|
||||
|
||||
function help()/*:number*/ {
|
||||
[
|
||||
"usage: adler32 [options] [filename]",
|
||||
"",
|
||||
"Options:",
|
||||
" -h, --help output usage information",
|
||||
" -V, --version output the version number",
|
||||
" -S, --seed=<n> use integer seed as starting value (default 1)",
|
||||
" -H, --hex-seed=<h> use hex seed as starting value (default 1)",
|
||||
" -d, --signed print result with format `%d` (default)",
|
||||
" -u, --unsigned print result with format `%u`",
|
||||
" -x, --hex print result with format `%0.8x`",
|
||||
" -X, --HEX print result with format `%0.8X`",
|
||||
" -F, --format=<s> use specified printf format",
|
||||
"",
|
||||
"Set filename = '-' or pipe data into adler32 to read from stdin",
|
||||
"Default output mode is signed (-d)",
|
||||
""
|
||||
].forEach(function(l) { console.log(l); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
function version()/*:number*/ { console.log(X.version); return 0; }
|
||||
|
||||
var fs = require('fs');
|
||||
require('exit-on-epipe');
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
function die(msg/*:string*/, ec/*:?number*/)/*:void*/ { console.error(msg); process.exit(ec || 0); }
|
||||
|
||||
var filename;
|
||||
if(args[0]) filename = args[0];
|
||||
var args/*:Array<string>*/ = process.argv.slice(2);
|
||||
var filename/*:string*/ = "";
|
||||
var fmt/*:string*/ = "";
|
||||
var seed = 1, r = 10;
|
||||
|
||||
for(var i = 0; i < args.length; ++i) {
|
||||
var arg = args[i];
|
||||
if(arg.charCodeAt(0) != 45) { if(filename === "") filename = arg; continue; }
|
||||
var m = arg.indexOf("=") == -1 ? arg : arg.substr(0, arg.indexOf("="));
|
||||
switch(m) {
|
||||
case "-": filename = "-"; break;
|
||||
|
||||
case "--help": case "-h": process.exit(help()); break;
|
||||
case "--version": case "-V": process.exit(version()); break;
|
||||
|
||||
case "--signed": case "-d": fmt = "%d"; break;
|
||||
case "--unsigned": case "-u": fmt = "%u"; break;
|
||||
case "--hex": case "-x": fmt = "%0.8x"; break;
|
||||
case "--HEX": case "-X": fmt = "%0.8X"; break;
|
||||
case "--format": case "-F":
|
||||
fmt = ((m!=arg) ? arg.substr(m.length+1) : args[++i])||""; break;
|
||||
|
||||
case "--hex-seed": case "-H": r = 16;
|
||||
/* falls through */
|
||||
case "--seed": case "-S":
|
||||
seed=parseInt((m!=arg) ? arg.substr(m.length+1) : args[++i], r)||1; break;
|
||||
|
||||
default: die("adler32: unrecognized option `" + arg + "'", 22);
|
||||
}
|
||||
}
|
||||
|
||||
if(!process.stdin.isTTY) filename = filename || "-";
|
||||
if(filename.length===0) die("adler32: must specify a filename ('-' for stdin)",1);
|
||||
|
||||
if(!filename) {
|
||||
console.error("adler32: must specify a filename ('-' for stdin)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if(filename === "-h" || filename === "--help") {
|
||||
console.log("usage: " + process.argv[0] + " [filename]");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if(filename !== "-" && !fs.existsSync(filename)) {
|
||||
console.error("adler32: " + filename + ": No such file or directory");
|
||||
process.exit(2);
|
||||
function process_data(data/*:Buffer*/) {
|
||||
var out/*:ADLER32Type*/ = X.buf(data, seed);
|
||||
return console.log(fmt === "" ? out : require("printj").sprintf(fmt, out));
|
||||
}
|
||||
|
||||
if(filename === "-") process.stdin.pipe(require('concat-stream')(process_data));
|
||||
else process_data(fs.readFileSync(filename));
|
||||
|
||||
function process_data(data) {
|
||||
console.log(X.buf(data));
|
||||
}
|
||||
else if(fs.existsSync(filename)) process_data(fs.readFileSync(filename));
|
||||
else die("adler32: " + filename + ": No such file or directory", 2);
|
||||
|
@ -1 +1 @@
|
||||
ADLER32.version = '0.4.0';
|
||||
ADLER32.version = '1.0.0';
|
||||
|
@ -1,14 +1,12 @@
|
||||
/*# consult README.md for the magic number */
|
||||
/*# charCodeAt is the best approach for binary strings */
|
||||
/*global Buffer */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr));
|
||||
function adler32_bstr(bstr/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += bstr.charCodeAt(i);
|
||||
a += bstr.charCodeAt(i)&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -17,12 +15,13 @@ function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ {
|
||||
function adler32_buf(buf/*:ABuf*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = buf.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = (seed >>> 16) & 0xFFFF; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += buf[i];
|
||||
a += buf[i]&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -32,8 +31,9 @@ function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ {
|
||||
}
|
||||
|
||||
/*# much much faster to intertwine utf8 and adler */
|
||||
function adler32_str(str/*:string*/)/*:ADLER32Type*/ {
|
||||
function adler32_str(str/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ {
|
||||
var a = 1, b = 0, L = str.length, M = 0, c = 0, d = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
@ -58,5 +58,5 @@ function adler32_str(str/*:string*/)/*:ADLER32Type*/ {
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
b = (15*(b>>>16)+(b&65535));
|
||||
}
|
||||
return (b << 16) | a;
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
@ -21,16 +21,14 @@ var ADLER32;
|
||||
}
|
||||
/*jshint ignore:end */
|
||||
}(function(ADLER32) {
|
||||
ADLER32.version = '0.4.0';
|
||||
/*global Buffer */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr));
|
||||
ADLER32.version = '1.0.0';
|
||||
function adler32_bstr(bstr, seed) {
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += bstr.charCodeAt(i);
|
||||
a += bstr.charCodeAt(i)&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -39,12 +37,13 @@ function adler32_bstr(bstr) {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_buf(buf) {
|
||||
function adler32_buf(buf, seed) {
|
||||
var a = 1, b = 0, L = buf.length, M = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = (seed >>> 16) & 0xFFFF; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
a += buf[i];
|
||||
a += buf[i]&0xFF;
|
||||
b += a;
|
||||
}
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
@ -53,8 +52,9 @@ function adler32_buf(buf) {
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
|
||||
function adler32_str(str) {
|
||||
function adler32_str(str, seed) {
|
||||
var a = 1, b = 0, L = str.length, M = 0, c = 0, d = 0;
|
||||
if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; }
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
@ -79,7 +79,7 @@ function adler32_str(str) {
|
||||
a = (15*(a>>>16)+(a&65535));
|
||||
b = (15*(b>>>16)+(b&65535));
|
||||
}
|
||||
return (b << 16) | a;
|
||||
return ((b%65521) << 16) | (a%65521);
|
||||
}
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
|
@ -1,2 +1,2 @@
|
||||
var assert = {};
|
||||
assert.equal = function(x,y) { if(x !== y) throw x + " !== " + y; };
|
||||
assert.equal = function(x,y) { if(x !== y) throw new Error(x + " !== " + y); };
|
||||
|
@ -1,9 +1,21 @@
|
||||
var o = "foo bar baz٪☃🍣";
|
||||
var m = "foobar"; for(var i = 0; i != 11; ++i) m+=m;
|
||||
var m1 = m + m, m2 = m1 + m1, m3 = m2 + m2, m4 = m3 + m3;
|
||||
var M1 = m + "𝑹" + m, M2 = M1 + "𝐀" + M1, M3 = M2 + "𝓜" + M2, M4 = M3 + "𝙖" + M3;
|
||||
var bits = [
|
||||
[ "Wikipedia", 300286872, 1 ],
|
||||
[ "foo bar baz", 398066679, 1 ],
|
||||
[ "foo bar baz٪", 570688890 ],
|
||||
[ "foo bar baz٪☃", 919275383 ],
|
||||
[ m, -747910882, 1 ],
|
||||
[ m1, 1286443594, 1],
|
||||
[ m2, 812328098, 1 ],
|
||||
[ m3, -1124316861, 1 ],
|
||||
[ m4, -357657979, 1 ],
|
||||
[ M1, -792947423 ],
|
||||
[ M2, -1841877779 ],
|
||||
[ M3, 869751957 ],
|
||||
[ M4, -1344947227 ],
|
||||
[ o, 1543572022 ],
|
||||
[ o+o, -2076896149 ],
|
||||
[ o+o+o, 2023497376 ]
|
||||
@ -14,8 +26,21 @@ type ArrayLike = any;
|
||||
type Stringifier = {(d:ArrayLike):string};
|
||||
|
||||
declare class ADLER32Module {
|
||||
bstr(s:string):ADLER32Type;
|
||||
buf(b:ABuf):ADLER32Type;
|
||||
str(s:string):ADLER32Type;
|
||||
bstr(s:string, seed:?ADLER32Type):ADLER32Type;
|
||||
buf(b:ABuf, seed:?ADLER32Type):ADLER32Type;
|
||||
str(s:string, seed:?ADLER32Type):ADLER32Type;
|
||||
version:string;
|
||||
};
|
||||
*/
|
||||
/*::
|
||||
type _CB = {(data:Buffer):void;};
|
||||
declare module 'concat-stream' {declare function exports(f:_CB):stream$Duplex;};
|
||||
declare module 'exit-on-epipe' {};
|
||||
|
||||
declare module 'adler-32' { declare var exports:ADLER32Module; };
|
||||
declare module '../' { declare var exports:ADLER32Module; };
|
||||
|
||||
declare module 'printj' {
|
||||
declare function sprintf(fmt:string, ...args:any):string;
|
||||
};
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script src="shim.js"></script>
|
||||
<script src="adler32.js"></script>
|
||||
<script src="fakeassert.js"></script>
|
||||
<script src="mocha.js"></script>
|
||||
|
237
ctest/shim.js
Normal file
237
ctest/shim.js
Normal file
@ -0,0 +1,237 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||
if (!Object.keys) {
|
||||
Object.keys = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length;
|
||||
|
||||
return function (obj) {
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) result.push(prop);
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i=0; i < dontEnumsLength; i++) {
|
||||
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
if (!Array.prototype.filter)
|
||||
{
|
||||
Array.prototype.filter = function(fun /*, thisp */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this == null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
{
|
||||
var val = t[i]; // in case fun mutates this
|
||||
if (fun.call(thisp, val, i, t))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
|
||||
if (!Array.prototype.forEach)
|
||||
{
|
||||
Array.prototype.forEach = function(fun /*, thisArg */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
fun.call(thisArg, t[i], i, t);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.com/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(" this is null or not defined");
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError(callback + " is not a function");
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (thisArg) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
||||
// the standard built-in constructor with that name and len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while(k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
||||
kValue = O[ k ];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
||||
// with T as the this value and argument list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[ k ] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (searchElement, fromIndex) {
|
||||
if ( this === undefined || this === null ) {
|
||||
throw new TypeError( '"this" is null or not defined' );
|
||||
}
|
||||
|
||||
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
|
||||
|
||||
fromIndex = +fromIndex || 0;
|
||||
|
||||
if (Math.abs(fromIndex) === Infinity) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
|
||||
if (fromIndex < 0) {
|
||||
fromIndex += length;
|
||||
if (fromIndex < 0) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (;fromIndex < length; fromIndex++) {
|
||||
if (this[fromIndex] === searchElement) {
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
||||
|
||||
if (! Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ttaubert/node-arraybuffer-slice
|
||||
// (c) 2013 Tim Taubert <tim@timtaubert.de>
|
||||
// arraybuffer-slice may be freely distributed under the MIT license.
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
ArrayBuffer.prototype.slice = function (begin, end) {
|
||||
begin = (begin|0) || 0;
|
||||
var num = this.byteLength;
|
||||
end = end === (void 0) ? num : (end|0);
|
||||
|
||||
// Handle negative values.
|
||||
if (begin < 0) begin += num;
|
||||
if (end < 0) end += num;
|
||||
|
||||
if (num === 0 || begin >= num || begin >= end) {
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var length = Math.min(num - begin, end - begin);
|
||||
var target = new ArrayBuffer(length);
|
||||
var targetArray = new Uint8Array(target);
|
||||
targetArray.set(new Uint8Array(this, begin, length));
|
||||
return target;
|
||||
};
|
||||
}
|
@ -9,14 +9,41 @@ if(typeof require !== 'undefined') {
|
||||
|
||||
function readlines(f) { return fs.readFileSync(f, "ascii").split("\n"); }
|
||||
|
||||
function msieversion()
|
||||
{
|
||||
if(typeof window == 'undefined') return Infinity;
|
||||
if(typeof window.navigator == 'undefined') return Infinity;
|
||||
var ua = window.navigator.userAgent
|
||||
var msie = ua.indexOf ( "MSIE " )
|
||||
if(msie < 0) return Infinity;
|
||||
return parseInt (ua.substring (msie+5, ua.indexOf (".", msie )));
|
||||
}
|
||||
|
||||
describe('adler32 bits', function() {
|
||||
bits.forEach(function(i) {
|
||||
var msg = i[0], l = i[0].length, L = i[1]|0;
|
||||
if(l > 20) msg = i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5);
|
||||
if(l > 100 && msieversion() < 9) return;
|
||||
if(l > 20000 && typeof Buffer === 'undefined') return;
|
||||
it(msg, function() {
|
||||
if(i[2] === 1) assert.equal(X.bstr(i[0]), L);
|
||||
assert.equal(X.str(i[0]), i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') assert.equal(X.buf(new Buffer(i[0])), L);
|
||||
var len = i[0].length, step = len < 20000 ? 1 : len < 50000 ? Math.ceil(len / 20000) : Math.ceil(len / 2000);
|
||||
for(var x = 0; x < len; x += step) {
|
||||
if(i[0].charCodeAt(x) >= 0xD800 && i[0].charCodeAt(x) < 0xE000) continue;
|
||||
if(i[2] === 1) {
|
||||
var bstradl = X.bstr(i[0].substr(x), X.bstr(i[0].substr(0, x)));
|
||||
assert.equal(bstradl, L);
|
||||
}
|
||||
var stradl = X.str(i[0].substr(x), X.str(i[0].substr(0, x)));
|
||||
assert.equal(stradl, i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var buf = new Buffer(i[0]);
|
||||
var bufadl = X.buf(buf.slice(x), X.buf(buf.slice(0, x)));
|
||||
assert.equal(bufadl, L);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -34,9 +61,9 @@ if(typeof require !== 'undefined') describe("unicode", function() {
|
||||
if(c.charCodeAt(0) >= 0xD800 && c.charCodeAt(0) < 0xE000) continue;
|
||||
var cc = corpus[ucidx], dd = X.str(c);
|
||||
assert.equal(dd, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + dd);
|
||||
var ee = X.buf(new Buffer(c, "utf8"));
|
||||
assert.equal(ee, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ee);
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var ee = X.buf(new Buffer(c, "utf8"));
|
||||
assert.equal(ee, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ee);
|
||||
var ff = X.bstr(String.fromCharCode.apply(null, new Buffer(c, "utf8")));
|
||||
assert.equal(ff, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ff);
|
||||
}
|
||||
|
@ -26,10 +26,10 @@ function make_chunk_buf_to_str(BType/*:function*/)/*:Stringifier*/ {
|
||||
};
|
||||
}
|
||||
/*# buffer to binary string */
|
||||
var bstrify/*:Stringifier*/ = make_chunk_buf_to_str(Uint8Array);
|
||||
var bstrify/*:Stringifier*/ = make_chunk_buf_to_str(typeof Uint8Array !== 'undefined' ? Uint8Array : Array);
|
||||
|
||||
/*# readAsBinaryString support */
|
||||
var rABS/*:boolean*/ = is_defined(FileReader, ['prototype', 'readAsBinaryString']);
|
||||
var rABS/*:boolean*/ = typeof FileReader !== 'undefined' && is_defined(FileReader, ['prototype', 'readAsBinaryString']);
|
||||
var userABS/*:HTMLInputElement*/ = (document.getElementsByName("userabs")[0]/*:any*/);
|
||||
if(!rABS) {
|
||||
userABS.disabled = true;
|
||||
@ -37,7 +37,7 @@ if(!rABS) {
|
||||
}
|
||||
|
||||
/*## Process Result */
|
||||
/*:: declare class HTMLPreElement extends HTMLElement { innerText:string; } */
|
||||
/*:: declare class HTMLPreElement extends HTMLElement { innerText?:string; } */
|
||||
function process_value(val/*:ADLER32Type*/) {
|
||||
var output = [];
|
||||
output[0] = "Signed : " + val;
|
||||
|
@ -15,7 +15,6 @@ function is_defined(val, keys) {
|
||||
return keys.length === 0 || is_defined(val[keys[0]], keys.slice(1));
|
||||
}
|
||||
|
||||
|
||||
function make_chunk_buf_to_str(BType) {
|
||||
return function(data) {
|
||||
var o = "", l = 0, w = 10240, L = data.byteLength/w;
|
||||
@ -24,18 +23,15 @@ function make_chunk_buf_to_str(BType) {
|
||||
return o;
|
||||
};
|
||||
}
|
||||
var bstrify = make_chunk_buf_to_str(typeof Uint8Array !== 'undefined' ? Uint8Array : Array);
|
||||
|
||||
var bstrify = make_chunk_buf_to_str(Uint8Array);
|
||||
|
||||
|
||||
var rABS = is_defined(FileReader, ['prototype', 'readAsBinaryString']);
|
||||
var rABS = typeof FileReader !== 'undefined' && is_defined(FileReader, ['prototype', 'readAsBinaryString']);
|
||||
var userABS = (document.getElementsByName("userabs")[0]);
|
||||
if(!rABS) {
|
||||
userABS.disabled = true;
|
||||
userABS.checked = false;
|
||||
}
|
||||
|
||||
|
||||
function process_value(val) {
|
||||
var output = [];
|
||||
output[0] = "Signed : " + val;
|
||||
@ -49,7 +45,6 @@ function process_value(val) {
|
||||
console_log("output", new Date());
|
||||
}
|
||||
|
||||
|
||||
var dotxt = (document.getElementById('dotext'));
|
||||
dotxt.onclick = function() {
|
||||
var txt=(document.getElementById('rawdata'));
|
||||
@ -58,8 +53,6 @@ dotxt.onclick = function() {
|
||||
process_value(wb);
|
||||
};
|
||||
|
||||
|
||||
|
||||
var readcb = function(e) {
|
||||
console_log("onload", new Date(), rABS, false);
|
||||
var target = (e.target);
|
||||
@ -68,7 +61,6 @@ var readcb = function(e) {
|
||||
process_value(val);
|
||||
};
|
||||
|
||||
|
||||
var handle_file = function(e) {
|
||||
rABS = userABS.checked;
|
||||
var otarget = (e.target);
|
||||
@ -85,7 +77,6 @@ var handle_file = function(e) {
|
||||
var xlf = (document.getElementById('xlf'));
|
||||
if(xlf.addEventListener) xlf.addEventListener('change', handle_file, false);
|
||||
|
||||
|
||||
var handle_drop = (function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
@ -34,6 +34,7 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
|
||||
<pre id="out">.</pre>
|
||||
<br />
|
||||
<script type="text/javascript">/* jshint browser: true */</script>
|
||||
<script src="shim.js"></script>
|
||||
<script src="adler32.js"></script>
|
||||
<script src="demo/browser.flow.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
12
misc/bits.js
12
misc/bits.js
@ -1,9 +1,21 @@
|
||||
var o = "foo bar baz٪☃🍣";
|
||||
var m = "foobar"; for(var i = 0; i != 11; ++i) m+=m;
|
||||
var m1 = m + m, m2 = m1 + m1, m3 = m2 + m2, m4 = m3 + m3;
|
||||
var M1 = m + "𝑹" + m, M2 = M1 + "𝐀" + M1, M3 = M2 + "𝓜" + M2, M4 = M3 + "𝙖" + M3;
|
||||
var bits = [
|
||||
[ "Wikipedia", 300286872, 1 ],
|
||||
[ "foo bar baz", 398066679, 1 ],
|
||||
[ "foo bar baz٪", 570688890 ],
|
||||
[ "foo bar baz٪☃", 919275383 ],
|
||||
[ m, -747910882, 1 ],
|
||||
[ m1, 1286443594, 1],
|
||||
[ m2, 812328098, 1 ],
|
||||
[ m3, -1124316861, 1 ],
|
||||
[ m4, -357657979, 1 ],
|
||||
[ M1, -792947423 ],
|
||||
[ M2, -1841877779 ],
|
||||
[ M3, 869751957 ],
|
||||
[ M4, -1344947227 ],
|
||||
[ o, 1543572022 ],
|
||||
[ o+o, -2076896149 ],
|
||||
[ o+o+o, 2023497376 ]
|
||||
|
@ -3,8 +3,9 @@ type ArrayLike = any;
|
||||
type Stringifier = {(d:ArrayLike):string};
|
||||
|
||||
declare class ADLER32Module {
|
||||
bstr(s:string):ADLER32Type;
|
||||
buf(b:ABuf):ADLER32Type;
|
||||
str(s:string):ADLER32Type;
|
||||
bstr(s:string, seed:?ADLER32Type):ADLER32Type;
|
||||
buf(b:ABuf, seed:?ADLER32Type):ADLER32Type;
|
||||
str(s:string, seed:?ADLER32Type):ADLER32Type;
|
||||
version:string;
|
||||
};
|
||||
*/
|
||||
|
12
misc/flowdeps.js
Normal file
12
misc/flowdeps.js
Normal file
@ -0,0 +1,12 @@
|
||||
/*::
|
||||
type _CB = {(data:Buffer):void;};
|
||||
declare module 'concat-stream' {declare function exports(f:_CB):stream$Duplex;};
|
||||
declare module 'exit-on-epipe' {};
|
||||
|
||||
declare module 'adler-32' { declare var exports:ADLER32Module; };
|
||||
declare module '../' { declare var exports:ADLER32Module; };
|
||||
|
||||
declare module 'printj' {
|
||||
declare function sprintf(fmt:string, ...args:any):string;
|
||||
};
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# make_unicode_crc.py -- generate baselines for tests
|
||||
# make_unicode_adler.py -- generate baselines for tests
|
||||
# Copyright (C) 2016-present SheetJS
|
||||
|
||||
from zlib import adler32
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "adler-32",
|
||||
"version": "0.4.0",
|
||||
"version": "1.0.0",
|
||||
"author": "sheetjs",
|
||||
"description": "Pure-JS ADLER-32",
|
||||
"keywords": [ "adler32", "checksum" ],
|
||||
@ -10,11 +10,11 @@
|
||||
"main": "./adler32",
|
||||
"dependencies": {
|
||||
"concat-stream":"",
|
||||
"printj":"",
|
||||
"exit-on-epipe":""
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha":"",
|
||||
"xlsjs":"",
|
||||
"codepage":""
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-adler32.git" },
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* bm.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* bm.js (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
var Benchmark = require('benchmark');
|
||||
var c = require('ansi')(process.stdout);
|
||||
|
||||
|
32
perf/bstr.js
32
perf/bstr.js
@ -1,3 +1,6 @@
|
||||
var old = require('adler-32').bstr;
|
||||
var cur = require('../').bstr;
|
||||
|
||||
function sheetjs1(bstr) {
|
||||
var a = 1, b = 0, L = bstr.length;
|
||||
for(var i = 0; i < L;) {
|
||||
@ -10,7 +13,7 @@ function sheetjs1(bstr) {
|
||||
}
|
||||
|
||||
function sheetjs2(bstr) {
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850)+i;
|
||||
for(;i<M;i++) {
|
||||
@ -24,7 +27,7 @@ function sheetjs2(bstr) {
|
||||
}
|
||||
|
||||
function sheetjs3(bstr) {
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
var a = 1, b = 0, L = bstr.length, M = 0;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 5552);
|
||||
for(;M>0;--M) {
|
||||
@ -37,28 +40,31 @@ function sheetjs3(bstr) {
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
var w = 6;
|
||||
var foobar = [255,255,255,255,255,255].map(function(x) { return String.fromCharCode(x); }).join("");
|
||||
foobar += foobar;
|
||||
foobar += foobar;
|
||||
foobar += foobar;
|
||||
foobar += foobar;
|
||||
foobar += foobar;
|
||||
foobar += foobar;
|
||||
for(var ff = 0; ff < w; ++ff) foobar += foobar;
|
||||
foobar.charCodeAt(0);
|
||||
var m = 2048;
|
||||
|
||||
var assert = require('assert');
|
||||
var BM = require('./bm');
|
||||
for(var i = 0; i != 14; ++i) {
|
||||
for(var i = 0; i != 6; ++i) foobar += foobar;
|
||||
for(var i = 6; i != 14; ++i) {
|
||||
foobar += foobar;
|
||||
foobar.charCodeAt(0);
|
||||
assert.equal(sheetjs1(foobar), sheetjs3(foobar));
|
||||
assert.equal(sheetjs1(foobar), sheetjs2(foobar));
|
||||
//for(var j = 0; j != 200; ++j) assert.equal(sheetjs2(foobar), sheetjs3(foobar));
|
||||
var suite = new BM('binary string (' + foobar.length + ')');
|
||||
|
||||
var res = old(foobar);
|
||||
assert.equal(res, cur(foobar));
|
||||
assert.equal(res, sheetjs1(foobar));
|
||||
assert.equal(res, sheetjs2(foobar));
|
||||
assert.equal(res, sheetjs3(foobar));
|
||||
|
||||
var suite = new BM('binary string (' + foobar.length + ')');
|
||||
if(i<3) suite.add('sheetjs 1', function() { for(var j = 0; j != m; ++j) sheetjs1(foobar); });
|
||||
suite.add('sheetjs 2', function() { for(var j = 0; j != m; ++j) sheetjs2(foobar); });
|
||||
suite.add('sheetjs 3', function() { for(var j = 0; j != m; ++j) sheetjs3(foobar); });
|
||||
suite.add('last vers', function() { for(var j = 0; j != m; ++j) old(foobar); });
|
||||
suite.add('current v', function() { for(var j = 0; j != m; ++j) cur(foobar); });
|
||||
suite.run();
|
||||
m>>>=1; if(m < 10) m = 10;
|
||||
}
|
||||
|
42
perf/utf8.js
42
perf/utf8.js
@ -1,7 +1,8 @@
|
||||
var table = require('../').table;
|
||||
var old = require('adler-32').str;
|
||||
var cur = require('../').str;
|
||||
|
||||
function sheetjs1(utf8) {
|
||||
var buf = Buffer(utf8);
|
||||
var buf = new Buffer(utf8);
|
||||
var a = 1, b = 0, L = buf.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
@ -12,7 +13,7 @@ function sheetjs1(utf8) {
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
function sheetjs2(utf8) {
|
||||
@ -21,37 +22,42 @@ function sheetjs2(utf8) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
c = utf8.charCodeAt(i++);
|
||||
if(c < 0x80) { a += c; b += a; --M; }
|
||||
else if(c < 0x800) {
|
||||
a += 192|((c>>6)&31); b += a; --M;
|
||||
a += 128|(c&63); b += a; --M;
|
||||
if(c < 0x80) {
|
||||
a += c; b += a; --M;
|
||||
} else if(c < 0x800) {
|
||||
a += 192|((c>>6)&31); b += a; --M;
|
||||
a += 128|(c&63); b += a; --M;
|
||||
} else if(c >= 0xD800 && c < 0xE000) {
|
||||
c = (c&1023)+64; d = utf8.charCodeAt(i++) & 1023;
|
||||
a += 240|((c>>8)&7); b += a; --M;
|
||||
a += 128|((c>>2)&63); b += a; --M;
|
||||
a += 128|((d>>6)&15)|(c&3); b += a; --M;
|
||||
a += 128|(d&63); b += a; --M;
|
||||
a += 240|((c>>8)&7); b += a; --M;
|
||||
a += 128|((c>>2)&63); b += a; --M;
|
||||
a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M;
|
||||
a += 128|(d&63); b += a; --M;
|
||||
} else {
|
||||
a += 224|((c>>12)&15); b += a; --M;
|
||||
a += 128|((c>>6)&63); b += a; --M;
|
||||
a += 128|(c&63); b += a; --M;
|
||||
a += 224|((c>>12)&15); b += a; --M;
|
||||
a += 128|((c>>6)&63); b += a; --M;
|
||||
a += 128|(c&63); b += a; --M;
|
||||
}
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
var foobar = "foo bar baz٪☃🍣";
|
||||
for(var i = 0; i != 11; ++i) foobar += " " + foobar;
|
||||
var assert = require('assert');
|
||||
sheetjs1(foobar); sheetjs2(foobar);
|
||||
assert.equal(sheetjs1(foobar), sheetjs2(foobar));
|
||||
|
||||
var res = old(foobar);
|
||||
assert.equal(res, cur(foobar));
|
||||
assert.equal(res, sheetjs1(foobar));
|
||||
assert.equal(res, sheetjs2(foobar));
|
||||
|
||||
var BM = require('./bm');
|
||||
var suite = new BM('unicode string');
|
||||
|
||||
suite.add('sheetjs 1', function() { for(var j = 0; j != 1000; ++j) sheetjs1(foobar); });
|
||||
suite.add('sheetjs 2', function() { for(var j = 0; j != 1000; ++j) sheetjs2(foobar); });
|
||||
suite.add('last vers', function() { for(var j = 0; j != 1000; ++j) old(foobar); });
|
||||
suite.add('current v', function() { for(var j = 0; j != 1000; ++j) cur(foobar); });
|
||||
suite.run();
|
||||
|
237
shim.js
Normal file
237
shim.js
Normal file
@ -0,0 +1,237 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||
if (!Object.keys) {
|
||||
Object.keys = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length;
|
||||
|
||||
return function (obj) {
|
||||
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) result.push(prop);
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i=0; i < dontEnumsLength; i++) {
|
||||
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
if (!Array.prototype.filter)
|
||||
{
|
||||
Array.prototype.filter = function(fun /*, thisp */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this == null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
{
|
||||
var val = t[i]; // in case fun mutates this
|
||||
if (fun.call(thisp, val, i, t))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
|
||||
if (!Array.prototype.forEach)
|
||||
{
|
||||
Array.prototype.forEach = function(fun /*, thisArg */)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (i in t)
|
||||
fun.call(thisArg, t[i], i, t);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.com/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(" this is null or not defined");
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError(callback + " is not a function");
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (thisArg) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
||||
// the standard built-in constructor with that name and len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while(k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
||||
kValue = O[ k ];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
||||
// with T as the this value and argument list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[ k ] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (searchElement, fromIndex) {
|
||||
if ( this === undefined || this === null ) {
|
||||
throw new TypeError( '"this" is null or not defined' );
|
||||
}
|
||||
|
||||
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
|
||||
|
||||
fromIndex = +fromIndex || 0;
|
||||
|
||||
if (Math.abs(fromIndex) === Infinity) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
|
||||
if (fromIndex < 0) {
|
||||
fromIndex += length;
|
||||
if (fromIndex < 0) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (;fromIndex < length; fromIndex++) {
|
||||
if (this[fromIndex] === searchElement) {
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
||||
|
||||
if (! Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ttaubert/node-arraybuffer-slice
|
||||
// (c) 2013 Tim Taubert <tim@timtaubert.de>
|
||||
// arraybuffer-slice may be freely distributed under the MIT license.
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
ArrayBuffer.prototype.slice = function (begin, end) {
|
||||
begin = (begin|0) || 0;
|
||||
var num = this.byteLength;
|
||||
end = end === (void 0) ? num : (end|0);
|
||||
|
||||
// Handle negative values.
|
||||
if (begin < 0) begin += num;
|
||||
if (end < 0) end += num;
|
||||
|
||||
if (num === 0 || begin >= num || begin >= end) {
|
||||
return new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var length = Math.min(num - begin, end - begin);
|
||||
var target = new ArrayBuffer(length);
|
||||
var targetArray = new Uint8Array(target);
|
||||
targetArray.set(new Uint8Array(this, begin, length));
|
||||
return target;
|
||||
};
|
||||
}
|
31
test.js
31
test.js
@ -9,14 +9,41 @@ if(typeof require !== 'undefined') {
|
||||
|
||||
function readlines(f) { return fs.readFileSync(f, "ascii").split("\n"); }
|
||||
|
||||
function msieversion()
|
||||
{
|
||||
if(typeof window == 'undefined') return Infinity;
|
||||
if(typeof window.navigator == 'undefined') return Infinity;
|
||||
var ua = window.navigator.userAgent
|
||||
var msie = ua.indexOf ( "MSIE " )
|
||||
if(msie < 0) return Infinity;
|
||||
return parseInt (ua.substring (msie+5, ua.indexOf (".", msie )));
|
||||
}
|
||||
|
||||
describe('adler32 bits', function() {
|
||||
bits.forEach(function(i) {
|
||||
var msg = i[0], l = i[0].length, L = i[1]|0;
|
||||
if(l > 20) msg = i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5);
|
||||
if(l > 100 && msieversion() < 9) return;
|
||||
if(l > 20000 && typeof Buffer === 'undefined') return;
|
||||
it(msg, function() {
|
||||
if(i[2] === 1) assert.equal(X.bstr(i[0]), L);
|
||||
assert.equal(X.str(i[0]), i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') assert.equal(X.buf(new Buffer(i[0])), L);
|
||||
var len = i[0].length, step = len < 20000 ? 1 : len < 50000 ? Math.ceil(len / 20000) : Math.ceil(len / 2000);
|
||||
for(var x = 0; x < len; x += step) {
|
||||
if(i[0].charCodeAt(x) >= 0xD800 && i[0].charCodeAt(x) < 0xE000) continue;
|
||||
if(i[2] === 1) {
|
||||
var bstradl = X.bstr(i[0].substr(x), X.bstr(i[0].substr(0, x)));
|
||||
assert.equal(bstradl, L);
|
||||
}
|
||||
var stradl = X.str(i[0].substr(x), X.str(i[0].substr(0, x)));
|
||||
assert.equal(stradl, i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var buf = new Buffer(i[0]);
|
||||
var bufadl = X.buf(buf.slice(x), X.buf(buf.slice(0, x)));
|
||||
assert.equal(bufadl, L);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -34,9 +61,9 @@ if(typeof require !== 'undefined') describe("unicode", function() {
|
||||
if(c.charCodeAt(0) >= 0xD800 && c.charCodeAt(0) < 0xE000) continue;
|
||||
var cc = corpus[ucidx], dd = X.str(c);
|
||||
assert.equal(dd, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + dd);
|
||||
var ee = X.buf(new Buffer(c, "utf8"));
|
||||
assert.equal(ee, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ee);
|
||||
if(typeof Buffer !== 'undefined') {
|
||||
var ee = X.buf(new Buffer(c, "utf8"));
|
||||
assert.equal(ee, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ee);
|
||||
var ff = X.bstr(String.fromCharCode.apply(null, new Buffer(c, "utf8")));
|
||||
assert.equal(ff, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ff);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user