Initial commit
This commit is contained in:
commit
a7891dc881
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
misc/coverage.html
|
||||
misc/*/
|
6
.jscs.json
Normal file
6
.jscs.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"disallowTrailingComma": true
|
||||
}
|
||||
|
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- "npm install -g mocha"
|
||||
- "npm install blanket"
|
||||
- "npm install coveralls mocha-lcov-reporter"
|
||||
after_success:
|
||||
- "make coveralls-spin"
|
14
LICENSE
Normal file
14
LICENSE
Normal file
@ -0,0 +1,14 @@
|
||||
Copyright (C) 2014 SheetJS
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
53
Makefile
Normal file
53
Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
LIB=adler32
|
||||
DEPS=$(sort $(wildcard bits/*.js))
|
||||
TARGET=$(LIB).js
|
||||
|
||||
$(TARGET): $(DEPS)
|
||||
cat $^ | tr -d '\15\32' > $@
|
||||
cp -f $@ ctest/
|
||||
|
||||
bits/01_version.js: package.json
|
||||
echo "ADLER32.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARGET)
|
||||
|
||||
.PHONY: test mocha
|
||||
test mocha: test.js
|
||||
mocha -R spec
|
||||
|
||||
.PHONY: ctest
|
||||
ctest:
|
||||
cat misc/*.js > ctest/fixtures.js
|
||||
cp -f test.js ctest/test.js
|
||||
cp -f $(TARGET) ctest/
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(TARGET)
|
||||
jshint --show-non-errors $(TARGET)
|
||||
jscs $(TARGET)
|
||||
|
||||
.PHONY: cov cov-spin
|
||||
cov: misc/coverage.html
|
||||
cov-spin:
|
||||
make cov & bash misc/spin.sh $$!
|
||||
|
||||
COVFMT=$(patsubst %,cov_%,$(FMT))
|
||||
.PHONY: $(COVFMT)
|
||||
$(COVFMT): cov_%:
|
||||
FMTS=$* make cov
|
||||
|
||||
misc/coverage.html: $(TARGET) test.js
|
||||
mocha --require blanket -R html-cov > $@
|
||||
|
||||
.PHONY: coveralls coveralls-spin
|
||||
coveralls:
|
||||
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
|
||||
|
||||
coveralls-spin:
|
||||
make coveralls & bash misc/spin.sh $$!
|
||||
|
||||
.PHONY: perf
|
||||
perf:
|
||||
bash perf/perf.sh
|
76
README.md
Normal file
76
README.md
Normal file
@ -0,0 +1,76 @@
|
||||
# adler32
|
||||
|
||||
Signed ADLER-32 algorithm implementation in JS (for the browser and nodejs).
|
||||
Emphasis on correctness and performance.
|
||||
|
||||
## Installation
|
||||
|
||||
In [nodejs](https://www.npmjs.org/package/adler-32):
|
||||
|
||||
npm install adler-32
|
||||
|
||||
In the browser:
|
||||
|
||||
<script lang="javascript" src="adler32.js"></script>
|
||||
|
||||
The browser exposes a variable ADLER32
|
||||
|
||||
## 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)
|
||||
|
||||
- `ADLER32.bstr(binary string)` interprets the argument as a binary string where
|
||||
the `i`-th byte is `str.charCodeAt(i)`
|
||||
|
||||
- `ADLER32.str(string)` interprets the argument as a standard JS string
|
||||
|
||||
## Testing
|
||||
|
||||
`make test` will run the nodejs-based test. To run the in-browser tests, run a
|
||||
local server and go to the `ctest` directory. To update the browser artifacts,
|
||||
run `make ctest`.
|
||||
|
||||
To generate the bits file, use the `adler32` function from python zlib:
|
||||
|
||||
```
|
||||
>>> from zlib import adler32
|
||||
>>> x="foo bar baz٪☃🍣"
|
||||
>>> adler32(x)
|
||||
1543572022
|
||||
>>> adler32(x+x)
|
||||
-2076896149
|
||||
>>> adler32(x+x+x)
|
||||
2023497376
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
`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
|
||||
|
||||
## Magic Number
|
||||
|
||||
The magic numbers were chosen so as to not overflow a 31-bit integer:
|
||||
|
||||
```
|
||||
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 *)
|
||||
```
|
||||
|
||||
Subtract up to 4 elements for the unicode case.
|
||||
|
||||
## License
|
||||
|
||||
Please consult the attached LICENSE file for details. All rights not explicitly
|
||||
granted by the Apache 2.0 license are reserved by the Original Author.
|
||||
|
||||
[![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)
|
||||
|
||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/8827aa40b3fdbca7c7ad0f51c68b3379 "githalytics.com")](http://githalytics.com/SheetJS/js-adler32)
|
||||
|
69
adler32.js
Normal file
69
adler32.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
var ADLER32 = {};
|
||||
(function(ADLER32) {
|
||||
ADLER32.version = '0.2.0';
|
||||
/* consult README.md for the magic number */
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr));
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += bstr.charCodeAt(i++);
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
function adler32_buf(buf) {
|
||||
var a = 1, b = 0, L = buf.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += buf[i++];
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
/* much much faster to intertwine utf8 and adler */
|
||||
function adler32_str(str) {
|
||||
var a = 1, b = 0, L = str.length, M, c, d;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
c = str.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;
|
||||
} else if(c >= 0xD800 && c < 0xE000) {
|
||||
c = (c&1023)+64; d = str.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;
|
||||
} 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 %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
ADLER32.str = adler32_str;
|
||||
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32);
|
4
bits/00_header.js
Normal file
4
bits/00_header.js
Normal file
@ -0,0 +1,4 @@
|
||||
/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
var ADLER32 = {};
|
||||
(function(ADLER32) {
|
1
bits/01_version.js
Normal file
1
bits/01_version.js
Normal file
@ -0,0 +1 @@
|
||||
ADLER32.version = '0.2.0';
|
60
bits/40_adler.js
Normal file
60
bits/40_adler.js
Normal file
@ -0,0 +1,60 @@
|
||||
/* consult README.md for the magic number */
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr));
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += bstr.charCodeAt(i++);
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
function adler32_buf(buf) {
|
||||
var a = 1, b = 0, L = buf.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += buf[i++];
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
/* much much faster to intertwine utf8 and adler */
|
||||
function adler32_str(str) {
|
||||
var a = 1, b = 0, L = str.length, M, c, d;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
c = str.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;
|
||||
} else if(c >= 0xD800 && c < 0xE000) {
|
||||
c = (c&1023)+64; d = str.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;
|
||||
} 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 %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
3
bits/90_exports.js
Normal file
3
bits/90_exports.js
Normal file
@ -0,0 +1,3 @@
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
ADLER32.str = adler32_str;
|
1
bits/99_footer.js
Normal file
1
bits/99_footer.js
Normal file
@ -0,0 +1 @@
|
||||
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32);
|
69
ctest/adler32.js
Normal file
69
ctest/adler32.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
var ADLER32 = {};
|
||||
(function(ADLER32) {
|
||||
ADLER32.version = '0.2.0';
|
||||
/* consult README.md for the magic number */
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function adler32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr));
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += bstr.charCodeAt(i++);
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
function adler32_buf(buf) {
|
||||
var a = 1, b = 0, L = buf.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += buf[i++];
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
/* much much faster to intertwine utf8 and adler */
|
||||
function adler32_str(str) {
|
||||
var a = 1, b = 0, L = str.length, M, c, d;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3850);
|
||||
while(M>0) {
|
||||
c = str.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;
|
||||
} else if(c >= 0xD800 && c < 0xE000) {
|
||||
c = (c&1023)+64; d = str.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;
|
||||
} 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 %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
ADLER32.bstr = adler32_bstr;
|
||||
ADLER32.buf = adler32_buf;
|
||||
ADLER32.str = adler32_str;
|
||||
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32);
|
2
ctest/fakeassert.js
Normal file
2
ctest/fakeassert.js
Normal file
@ -0,0 +1,2 @@
|
||||
var assert = {};
|
||||
assert.equal = function(x,y) { if(x !== y) throw x + " !== " + y; };
|
11
ctest/fixtures.js
Normal file
11
ctest/fixtures.js
Normal file
@ -0,0 +1,11 @@
|
||||
var o = "foo bar baz٪☃🍣";
|
||||
var bits = [
|
||||
[ "Wikipedia", 300286872, 1 ],
|
||||
[ "foo bar baz", 398066679, 1 ],
|
||||
[ "foo bar baz٪", 570688890 ],
|
||||
[ "foo bar baz٪☃", 919275383],
|
||||
[ "foo bar baz٪☃🍣", 1543572022],
|
||||
[ o+o, -2076896149 ],
|
||||
[ o+o+o, 2023497376 ]
|
||||
];
|
||||
if(typeof module !== "undefined") module.exports = bits;
|
21
ctest/index.html
Normal file
21
ctest/index.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Mocha</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="mocha.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script src="adler32.js"></script>
|
||||
<script src="fakeassert.js"></script>
|
||||
<script src="mocha.js"></script>
|
||||
<script src="fixtures.js"></script>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script src="test.js"></script>
|
||||
<script>
|
||||
mocha.run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
270
ctest/mocha.css
Normal file
270
ctest/mocha.css
Normal file
@ -0,0 +1,270 @@
|
||||
@charset "utf-8";
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#mocha {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
margin: 60px 50px;
|
||||
}
|
||||
|
||||
#mocha ul,
|
||||
#mocha li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#mocha ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#mocha h1,
|
||||
#mocha h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mocha h1 {
|
||||
margin-top: 15px;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
#mocha h1 a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#mocha .suite .suite h1 {
|
||||
margin-top: 0;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
#mocha .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mocha .suite {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test {
|
||||
margin-left: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#mocha .test.pending:hover h2::after {
|
||||
content: '(pending)';
|
||||
font-family: arial, sans-serif;
|
||||
}
|
||||
|
||||
#mocha .test.pass.medium .duration {
|
||||
background: #c09853;
|
||||
}
|
||||
|
||||
#mocha .test.pass.slow .duration {
|
||||
background: #b94a48;
|
||||
}
|
||||
|
||||
#mocha .test.pass::before {
|
||||
content: '✓';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #00d6b2;
|
||||
}
|
||||
|
||||
#mocha .test.pass .duration {
|
||||
font-size: 9px;
|
||||
margin-left: 5px;
|
||||
padding: 2px 5px;
|
||||
color: #fff;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#mocha .test.pass.fast .duration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha .test.pending {
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.pending::before {
|
||||
content: '◦';
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.fail {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test.fail pre {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha .test.fail::before {
|
||||
content: '✖';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre.error {
|
||||
color: #c00;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* (1): approximate for browsers not supporting calc
|
||||
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
|
||||
* ^^ seriously
|
||||
*/
|
||||
#mocha .test pre {
|
||||
display: block;
|
||||
float: left;
|
||||
clear: left;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
max-width: 85%; /*(1)*/
|
||||
max-width: calc(100% - 42px); /*(2)*/
|
||||
word-wrap: break-word;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
-moz-border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 3px #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#mocha .test h2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mocha .test a.replay {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 0;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
background: #eee;
|
||||
font-size: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
-webkit-transition: opacity 200ms;
|
||||
-moz-transition: opacity 200ms;
|
||||
transition: opacity 200ms;
|
||||
opacity: 0.3;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha .test:hover a.replay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#mocha-report.pass .test.fail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.fail .test.pass {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.pending .test.pass,
|
||||
#mocha-report.pending .test.fail {
|
||||
display: none;
|
||||
}
|
||||
#mocha-report.pending .test.pass.pending {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#mocha-error {
|
||||
color: #c00;
|
||||
font-size: 1.5em;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#mocha-stats {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: #888;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#mocha-stats .progress {
|
||||
float: right;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#mocha-stats em {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha-stats a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha-stats a:hover {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#mocha-stats li {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
list-style: none;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
#mocha-stats canvas {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#mocha code .comment { color: #ddd; }
|
||||
#mocha code .init { color: #2f6fad; }
|
||||
#mocha code .string { color: #5890ad; }
|
||||
#mocha code .keyword { color: #8a6343; }
|
||||
#mocha code .number { color: #2f6fad; }
|
||||
|
||||
@media screen and (max-device-width: 480px) {
|
||||
#mocha {
|
||||
margin: 60px 0px;
|
||||
}
|
||||
|
||||
#mocha #stats {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
5842
ctest/mocha.js
Normal file
5842
ctest/mocha.js
Normal file
File diff suppressed because it is too large
Load Diff
21
ctest/test.js
Normal file
21
ctest/test.js
Normal file
@ -0,0 +1,21 @@
|
||||
/* vim: set ts=2: */
|
||||
var X;
|
||||
if(typeof require !== 'undefined') {
|
||||
assert = require('assert');
|
||||
describe('source',function(){it('should load',function(){X=require('./');});});
|
||||
bits = require('./misc/bits.js');
|
||||
} else { X = ADLER32; }
|
||||
|
||||
describe('adler32 bits', function() {
|
||||
bits.forEach(function(i) {
|
||||
var l = i[0].length;
|
||||
var msg = i[0];
|
||||
if(l > 20) i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5);
|
||||
it(msg, function() {
|
||||
if(i[2] === 1) assert.equal(X.bstr(i[0]), i[1]|0);
|
||||
assert.equal(X.str(i[0]), i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') assert.equal(X.buf(new Buffer(i[0])), i[1]|0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
11
misc/bits.js
Normal file
11
misc/bits.js
Normal file
@ -0,0 +1,11 @@
|
||||
var o = "foo bar baz٪☃🍣";
|
||||
var bits = [
|
||||
[ "Wikipedia", 300286872, 1 ],
|
||||
[ "foo bar baz", 398066679, 1 ],
|
||||
[ "foo bar baz٪", 570688890 ],
|
||||
[ "foo bar baz٪☃", 919275383],
|
||||
[ "foo bar baz٪☃🍣", 1543572022],
|
||||
[ o+o, -2076896149 ],
|
||||
[ o+o+o, 2023497376 ]
|
||||
];
|
||||
if(typeof module !== "undefined") module.exports = bits;
|
14
misc/spin.sh
Executable file
14
misc/spin.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# spin.sh -- show a spinner (for coverage test)
|
||||
# Copyright (C) 2014 SheetJS
|
||||
|
||||
wpid=$1
|
||||
delay=1
|
||||
str="|/-\\"
|
||||
while [ $(ps -a|awk '$1=='$wpid' {print $1}') ]; do
|
||||
t=${str#?}
|
||||
printf " [%c]" "$str"
|
||||
str=$t${str%"$t"}
|
||||
sleep $delay
|
||||
printf "\b\b\b\b"
|
||||
done
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"private":"true",
|
||||
"name": "adler-32",
|
||||
"version": "0.2.0",
|
||||
"author": "sheetjs",
|
||||
"description": "Pure-JS ADLER-32",
|
||||
"keywords": [ "adler32", "checksum" ],
|
||||
"main": "./adler32",
|
||||
"devDependencies": {
|
||||
"mocha":"",
|
||||
"xlsjs":"",
|
||||
"uglify-js":"",
|
||||
"codepage":""
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-adler32.git" },
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make test"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
"pattern": "adler32.js"
|
||||
}
|
||||
},
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-adler32/issues" },
|
||||
"license": "Apache-2.0",
|
||||
"engines": { "node": ">=0.8" }
|
||||
}
|
35
perf/bm.js
Normal file
35
perf/bm.js
Normal file
@ -0,0 +1,35 @@
|
||||
/* bm.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
var Benchmark = require('benchmark');
|
||||
var c = require('ansi')(process.stdout);
|
||||
|
||||
function test_end() { c.horizontalAbsolute(0).write("✓"); c.write('\n'); }
|
||||
|
||||
function suite_end() { console.log('Fastest is ' + this.filter('fastest').pluck('name')); }
|
||||
|
||||
function test_cycle(e) { c.horizontalAbsolute(0); c.eraseLine(); c.write("→ "+e.target); }
|
||||
|
||||
function BM(name) {
|
||||
if(!(this instanceof BM)) return new BM(name);
|
||||
console.log("--- " + name + " ---");
|
||||
this.suite = new Benchmark.Suite(name, { onComplete: suite_end });
|
||||
this.suites = [];
|
||||
this.maxlen = 0;
|
||||
}
|
||||
|
||||
BM.prototype.run = function() {
|
||||
var maxlen = this.maxlen, ss = this.suite;
|
||||
this.suites.forEach(function(s) { ss.add(s[0] + new Array(maxlen-s[0].length+1).join(" "), s[1]); });
|
||||
if(this.suites.length > 0) this.suite.run();
|
||||
};
|
||||
|
||||
BM.prototype.add = function(msg, test) {
|
||||
this.suites.push([msg, {
|
||||
onCycle: test_cycle,
|
||||
onComplete: test_end,
|
||||
defer: false,
|
||||
fn: test
|
||||
}]);
|
||||
this.maxlen = Math.max(this.maxlen, msg.length);
|
||||
};
|
||||
|
||||
module.exports = BM;
|
38
perf/bstr.js
Normal file
38
perf/bstr.js
Normal file
@ -0,0 +1,38 @@
|
||||
var table = require('../').table;
|
||||
|
||||
function sheetjs1(bstr) {
|
||||
var a = 1, b = 0, L = bstr.length;
|
||||
for(var i = 0; i < L;) {
|
||||
a += bstr.charCodeAt(i++);
|
||||
a %= 65521;
|
||||
b += a;
|
||||
b %= 65521;
|
||||
}
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
function sheetjs2(bstr) {
|
||||
var a = 1, b = 0, L = bstr.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += bstr.charCodeAt(i++);
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
var foobar = "foobarbazqux";
|
||||
for(var i = 0; i != 11; ++i) foobar += " " + foobar;
|
||||
var assert = require('assert');
|
||||
assert.equal(sheetjs1(foobar), sheetjs2(foobar));
|
||||
|
||||
var BM = require('./bm');
|
||||
var suite = new BM('binary 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.run();
|
5
perf/perf.sh
Executable file
5
perf/perf.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
node perf/bstr.js
|
||||
node perf/utf8.js
|
||||
|
57
perf/utf8.js
Normal file
57
perf/utf8.js
Normal file
@ -0,0 +1,57 @@
|
||||
var table = require('../').table;
|
||||
|
||||
function sheetjs1(utf8) {
|
||||
var buf = Buffer(utf8);
|
||||
var a = 1, b = 0, L = buf.length, M;
|
||||
for(var i = 0; i < L;) {
|
||||
M = Math.min(L-i, 3854);
|
||||
for(;M>0;--M) {
|
||||
a += buf[i++];
|
||||
b += a;
|
||||
}
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | a);
|
||||
}
|
||||
|
||||
function sheetjs2(utf8) {
|
||||
var a = 1, b = 0, L = utf8.length, M, c, d;
|
||||
for(var i = 0; i < L;) {
|
||||
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;
|
||||
} 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;
|
||||
} 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 %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return b > 32767 ? (((b - 65536) * 65536) | a) : ((b * 65536) | 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 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.run();
|
21
test.js
Normal file
21
test.js
Normal file
@ -0,0 +1,21 @@
|
||||
/* vim: set ts=2: */
|
||||
var X;
|
||||
if(typeof require !== 'undefined') {
|
||||
assert = require('assert');
|
||||
describe('source',function(){it('should load',function(){X=require('./');});});
|
||||
bits = require('./misc/bits.js');
|
||||
} else { X = ADLER32; }
|
||||
|
||||
describe('adler32 bits', function() {
|
||||
bits.forEach(function(i) {
|
||||
var l = i[0].length;
|
||||
var msg = i[0];
|
||||
if(l > 20) i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5);
|
||||
it(msg, function() {
|
||||
if(i[2] === 1) assert.equal(X.bstr(i[0]), i[1]|0);
|
||||
assert.equal(X.str(i[0]), i[1]|0);
|
||||
if(typeof Buffer !== 'undefined') assert.equal(X.buf(new Buffer(i[0])), i[1]|0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user