version bump 1.0.0: running hash

This commit is contained in:
SheetJS 2016-10-12 21:23:45 -04:00
parent b692b3f7df
commit 318cb4ebd4
28 changed files with 804 additions and 141 deletions

View File

@ -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
View File

@ -3,3 +3,4 @@ test_files/*.py
test_files/*.js
test_files/baseline*
misc/coverage.html
ctest/sauce*

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -1 +1 @@
ADLER32.version = '0.4.0';
ADLER32.version = '1.0.0';

View File

@ -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);
}

View File

@ -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;

View File

@ -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); };

View File

@ -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;
};
*/

View File

@ -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
View 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;
};
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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">

View File

@ -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 ]

View File

@ -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
View 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;
};
*/

View File

@ -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

View File

@ -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" },

View File

@ -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);

View File

@ -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;
}

View File

@ -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
View 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
View File

@ -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);
}