mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-09-22 03:52:21 -04:00
Initial tests, inside an Eclipse project (just to use its HTML/JS
editor)
This commit is contained in:
parent
f09b07b1d2
commit
d770179818
29
evopedia-html5/.project
Normal file
29
evopedia-html5/.project
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>evopedia-html5</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
12
evopedia-html5/.settings/.jsdtscope
Normal file
12
evopedia-html5/.settings/.jsdtscope
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="WebContent"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
|
||||
<attributes>
|
||||
<attribute name="hide" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||
<classpathentry kind="output" path=""/>
|
||||
</classpath>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="evopedia-html5">
|
||||
<wb-resource deploy-path="/" source-path="/WebContent"/>
|
||||
<property name="context-root" value="evopedia-html5"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web"/>
|
||||
<fixed facet="wst.web"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
<installed facet="wst.web" version="1.0"/>
|
||||
</faceted-project>
|
@ -0,0 +1 @@
|
||||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
@ -0,0 +1 @@
|
||||
Window
|
250
evopedia-html5/WebContent/bzip2-antimatter15.js
Normal file
250
evopedia-html5/WebContent/bzip2-antimatter15.js
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
bzip2.js - a small bzip2 decompression implementation
|
||||
|
||||
Copyright 2011 by antimatter15 (antimatter15@gmail.com)
|
||||
|
||||
Based on micro-bunzip by Rob Landley (rob@landley.net).
|
||||
|
||||
Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
|
||||
which also acknowledges contributions by Mike Burrows, David Wheeler,
|
||||
Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
|
||||
Robert Sedgewick, and Jon L. Bentley.
|
||||
|
||||
I hereby release this code under the GNU Library General Public License
|
||||
(LGPL) version 2, available at http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
var bzip2 = {};
|
||||
|
||||
bzip2.array = function(bytes){
|
||||
var bit = 0, byte = 0;
|
||||
var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ];
|
||||
return function(n){
|
||||
var result = 0;
|
||||
while(n > 0){
|
||||
var left = 8 - bit;
|
||||
if(n >= left){
|
||||
result <<= left;
|
||||
result |= (BITMASK[left] & bytes[byte++]);
|
||||
bit = 0;
|
||||
n -= left;
|
||||
}else{
|
||||
result <<= n;
|
||||
result |= ((bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit));
|
||||
bit += n;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
bzip2.simple = function(bits){
|
||||
var size = bzip2.header(bits);
|
||||
var all = '', chunk = '';
|
||||
do{
|
||||
all += chunk;
|
||||
chunk = bzip2.decompress(bits, size);
|
||||
}while(chunk != -1);
|
||||
return all;
|
||||
}
|
||||
|
||||
bzip2.header = function(bits){
|
||||
if(bits(8*3) != 4348520) throw "No magic number found";
|
||||
var i = bits(8) - 48;
|
||||
if(i < 1 || i > 9) throw "Not a BZIP archive";
|
||||
return i;
|
||||
};
|
||||
|
||||
|
||||
//takes a function for reading the block data (starting with 0x314159265359)
|
||||
//a block size (0-9) (optional, defaults to 9)
|
||||
//a length at which to stop decompressing and return the output
|
||||
bzip2.decompress = function(bits, size, len){
|
||||
var MAX_HUFCODE_BITS = 20;
|
||||
var MAX_SYMBOLS = 258;
|
||||
var SYMBOL_RUNA = 0;
|
||||
var SYMBOL_RUNB = 1;
|
||||
var GROUP_SIZE = 50;
|
||||
|
||||
var bufsize = 100000 * size;
|
||||
for(var h = '', i = 0; i < 6; i++) h += bits(8).toString(16);
|
||||
if(h == "177245385090") return -1; //last block
|
||||
if(h != "314159265359") throw "eek not valid bzip data";
|
||||
bits(32); //ignore CRC codes
|
||||
if(bits(1)) throw "unsupported obsolete version";
|
||||
var origPtr = bits(24);
|
||||
if(origPtr > bufsize) throw "Initial position larger than buffer size";
|
||||
var t = bits(16);
|
||||
var symToByte = new Uint8Array(256),
|
||||
symTotal = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if(t & (1 << (15 - i))) {
|
||||
var k = bits(16);
|
||||
for(j = 0; j < 16; j++){
|
||||
if(k & (1 << (15 - j))){
|
||||
symToByte[symTotal++] = (16 * i) + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var groupCount = bits(3);
|
||||
if(groupCount < 2 || groupCount > 6) throw "another error";
|
||||
var nSelectors = bits(15);
|
||||
if(nSelectors == 0) throw "meh";
|
||||
var mtfSymbol = []; //TODO: possibly replace JS array with typed arrays
|
||||
for(var i = 0; i < groupCount; i++) mtfSymbol[i] = i;
|
||||
var selectors = new Uint8Array(32768);
|
||||
|
||||
for(var i = 0; i < nSelectors; i++){
|
||||
for(var j = 0; bits(1); j++) if(j >= groupCount) throw "whoops another error";
|
||||
var uc = mtfSymbol[j];
|
||||
mtfSymbol.splice(j, 1); //this is a probably inefficient MTF transform
|
||||
mtfSymbol.splice(0, 0, uc);
|
||||
selectors[i] = uc;
|
||||
}
|
||||
|
||||
var symCount = symTotal + 2;
|
||||
var groups = [];
|
||||
for(var j = 0; j < groupCount; j++){
|
||||
var length = new Uint8Array(MAX_SYMBOLS),
|
||||
temp = new Uint8Array(MAX_HUFCODE_BITS+1);
|
||||
t = bits(5); //lengths
|
||||
for(var i = 0; i < symCount; i++){
|
||||
while(true){
|
||||
if (t < 1 || t > MAX_HUFCODE_BITS) throw "I gave up a while ago on writing error messages";
|
||||
if(!bits(1)) break;
|
||||
if(!bits(1)) t++;
|
||||
else t--;
|
||||
}
|
||||
length[i] = t;
|
||||
}
|
||||
var minLen, maxLen;
|
||||
minLen = maxLen = length[0];
|
||||
for(var i = 1; i < symCount; i++){
|
||||
if(length[i] > maxLen) maxLen = length[i];
|
||||
else if(length[i] < minLen) minLen = length[i];
|
||||
}
|
||||
var hufGroup;
|
||||
hufGroup = groups[j] = {};
|
||||
hufGroup.permute = new Uint32Array(MAX_SYMBOLS);
|
||||
hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 1);
|
||||
hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1);
|
||||
hufGroup.minLen = minLen;
|
||||
hufGroup.maxLen = maxLen;
|
||||
var base = hufGroup.base.subarray(1);
|
||||
var limit = hufGroup.limit.subarray(1);
|
||||
var pp = 0;
|
||||
for(var i = minLen; i <= maxLen; i++)
|
||||
for(var t = 0; t < symCount; t++)
|
||||
if(length[t] == i) hufGroup.permute[pp++] = t;
|
||||
for(i = minLen; i <= maxLen; i++) temp[i] = limit[i] = 0;
|
||||
for(i = 0; i < symCount; i++) temp[length[i]]++;
|
||||
pp = t = 0;
|
||||
for(i = minLen; i < maxLen; i++) {
|
||||
pp += temp[i];
|
||||
limit[i] = pp - 1;
|
||||
pp <<= 1;
|
||||
base[i+1] = pp - (t += temp[i]);
|
||||
}
|
||||
limit[maxLen]=pp+temp[maxLen]-1;
|
||||
base[minLen]=0;
|
||||
}
|
||||
var byteCount = new Uint32Array(256);
|
||||
for(var i = 0; i < 256; i++) mtfSymbol[i] = i;
|
||||
var runPos, count, symCount, selector;
|
||||
runPos = count = symCount = selector = 0;
|
||||
var buf = new Uint32Array(bufsize);
|
||||
while(true){
|
||||
if(!(symCount--)){
|
||||
symCount = GROUP_SIZE - 1;
|
||||
if(selector >= nSelectors) throw "meow i'm a kitty, that's an error";
|
||||
hufGroup = groups[selectors[selector++]];
|
||||
base = hufGroup.base.subarray(1);
|
||||
limit = hufGroup.limit.subarray(1);
|
||||
}
|
||||
i = hufGroup.minLen;
|
||||
j = bits(i);
|
||||
while(true){
|
||||
if(i > hufGroup.maxLen) throw "rawr i'm a dinosaur";
|
||||
if(j <= limit[i]) break;
|
||||
i++;
|
||||
j = (j << 1) | bits(1);
|
||||
}
|
||||
j -= base[i];
|
||||
if(j < 0 || j >= MAX_SYMBOLS) throw "moo i'm a cow";
|
||||
var nextSym = hufGroup.permute[j];
|
||||
if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) {
|
||||
if(!runPos){
|
||||
runPos = 1;
|
||||
t = 0;
|
||||
}
|
||||
if(nextSym == SYMBOL_RUNA) t += runPos;
|
||||
else t += 2 * runPos;
|
||||
runPos <<= 1;
|
||||
continue;
|
||||
}
|
||||
if(runPos){
|
||||
runPos = 0;
|
||||
if(count + t >= bufsize) throw "Boom.";
|
||||
uc = symToByte[mtfSymbol[0]];
|
||||
byteCount[uc] += t;
|
||||
while(t--) buf[count++] = uc;
|
||||
}
|
||||
if(nextSym > symTotal) break;
|
||||
if(count >= bufsize) throw "I can't think of anything. Error";
|
||||
i = nextSym -1;
|
||||
uc = mtfSymbol[i];
|
||||
mtfSymbol.splice(i, 1);
|
||||
mtfSymbol.splice(0, 0, uc);
|
||||
uc = symToByte[uc];
|
||||
byteCount[uc]++;
|
||||
buf[count++] = uc;
|
||||
}
|
||||
if(origPtr < 0 || origPtr >= count) throw "I'm a monkey and I'm throwing something at someone, namely you";
|
||||
var j = 0;
|
||||
for(var i = 0; i < 256; i++){
|
||||
k = j + byteCount[i];
|
||||
byteCount[i] = j;
|
||||
j = k;
|
||||
}
|
||||
for(var i = 0; i < count; i++){
|
||||
uc = buf[i] & 0xff;
|
||||
buf[byteCount[uc]] |= (i << 8);
|
||||
byteCount[uc]++;
|
||||
}
|
||||
var pos = 0, current = 0, run = 0;
|
||||
if(count) {
|
||||
pos = buf[origPtr];
|
||||
current = (pos & 0xff);
|
||||
pos >>= 8;
|
||||
run = -1;
|
||||
}
|
||||
count = count;
|
||||
var output = '';
|
||||
var copies, previous, outbyte;
|
||||
if(!len) len = Infinity;
|
||||
while(count){
|
||||
count--;
|
||||
previous = current;
|
||||
pos = buf[pos];
|
||||
current = pos & 0xff;
|
||||
pos >>= 8;
|
||||
if(run++ == 3){
|
||||
copies = current;
|
||||
outbyte = previous;
|
||||
current = -1;
|
||||
}else{
|
||||
copies = 1;
|
||||
outbyte = current;
|
||||
}
|
||||
while(copies--){
|
||||
output += (String.fromCharCode(outbyte));
|
||||
if(!--len) return output;
|
||||
}
|
||||
if(current != previous) run = 0;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
328
evopedia-html5/WebContent/bzip2-killiroid.js
Normal file
328
evopedia-html5/WebContent/bzip2-killiroid.js
Normal file
@ -0,0 +1,328 @@
|
||||
/**
|
||||
* this is a port of pyflate
|
||||
* @url http://www.paul.sladen.org/projects/pyflate/
|
||||
* @author kirilloid
|
||||
* @license CC-SA 3.0
|
||||
* @usage ArchUtils.bz2.decode(str)
|
||||
* @example ArchUtils.bz2.decode(
|
||||
* "BZh91AY&SYN\xEC\xE86\0\0\2Q\x80\0\x10@\0\6D\x90\x80 " +
|
||||
* "\x001\6LA\1\xA7\xA9\xA5\x80\xBB\x941\xF8\xBB\x92)\xC2\x84\x82wgA\xB0"
|
||||
* ) == "hello world\n";
|
||||
*/
|
||||
|
||||
var ArchUtils = (function(){
|
||||
'use strict';
|
||||
|
||||
// python functions eliminated, Gonzalo
|
||||
|
||||
/**
|
||||
* bwt_reverse code from wikipedia (slightly modified)
|
||||
* @url http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform
|
||||
* @license: CC-SA 3.0
|
||||
*/
|
||||
|
||||
function bwt_reverse(src, primary) {
|
||||
var len = src.length;
|
||||
if (primary >= len) throw RangeError("Out of bound");
|
||||
if (primary < 0) throw RangeError("Out of bound");
|
||||
|
||||
//only used on arrays, optimized, Gonzalo
|
||||
var A = src;
|
||||
src = src.join('');
|
||||
A.sort();
|
||||
|
||||
var start = {};
|
||||
for (var i = len-1; i >= 0; i--) start[A[i]] = i;
|
||||
|
||||
var links = [];
|
||||
for (i = 0; i < len; i++) links.push(start[src[i]]++);
|
||||
|
||||
var i, first = A[i = primary], ret = [];
|
||||
|
||||
for (var j = 1; j < len; j++) {
|
||||
ret.push(A[i = links[i]]);
|
||||
}
|
||||
return first + ret.reverse().join('');
|
||||
}
|
||||
|
||||
//move_to_front is always used to store reslt in array, optimized, Gonzalo
|
||||
function move_to_front_and_store(a, c, buff) {
|
||||
var v = a[c];
|
||||
for (var i = c; i > 0; a[i] = a[--i]);
|
||||
buff.push(a[0] = v);
|
||||
}
|
||||
|
||||
// BitfieldBase never used directly, optimized, Gonzalo
|
||||
/**
|
||||
* @class RBitfield
|
||||
* right-sided bitfield for reading bits in byte from right to left
|
||||
*/
|
||||
var RBitfield = function() {
|
||||
this.init = function(x) {
|
||||
this.masks = [];
|
||||
for (var i = 0; i < 31; i++) this.masks[i] = (1 << i) - 1;
|
||||
this.masks[31] = -0x80000000;
|
||||
//eliminated support for RBitfield.init( RBitfield ), never used, Gonzalo
|
||||
this.f = x;
|
||||
this.bits = 0;
|
||||
this.bitfield = 0x0;
|
||||
this.count = 0;
|
||||
}
|
||||
//_read not used, optimized, Gonzalo
|
||||
//readByte inlined, Gonzalo
|
||||
//needbits inlined, Gonzalo
|
||||
//align inlined, Gonzalo
|
||||
//toskip inlined, Gonzalo
|
||||
// this.dropbytes not used, eliminated, Gonzalo
|
||||
// this.tell not used, eliminated, Gonzalo
|
||||
// since js truncate args to int32 with bit operators
|
||||
// we need to specific processing for n >= 32 bits reading
|
||||
// separate function is created for optimization purposes
|
||||
//readbits2 always called ith constants >=32, check removed, Gonzalo
|
||||
this.readbits2 = function readbits2(n) {
|
||||
//only for n>=32!!!, check removed
|
||||
var n2 = n >> 1;
|
||||
return this.readbits(n2) * (1 << n2) + this.readbits(n - n2);
|
||||
}
|
||||
this.readbits = function readbits(n) {
|
||||
//if (n > this.bits) this.needbits(n);
|
||||
// INLINED: needbits, readByte
|
||||
while (this.bits < n) {
|
||||
this.bitfield = (this.bitfield << 8) + this.f.charCodeAt(this.count++);
|
||||
this.bits += 8;
|
||||
}
|
||||
var m = this.masks[n];
|
||||
var r = (this.bitfield >> (this.bits - n)) & m;
|
||||
this.bits -= n;
|
||||
this.bitfield &= ~(m << this.bits);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class HuffmanLength
|
||||
* utility class, used for comparison of huffman codes
|
||||
*/
|
||||
var HuffmanLength = function(code, bits) {
|
||||
this.code = code;
|
||||
this.bits = bits;
|
||||
this.symbol = undefined;
|
||||
} //cropped unused functions and needless checks, Gonzalo
|
||||
|
||||
//class HuffmanTable never used directly..., optimized, Gonzalo
|
||||
|
||||
/**
|
||||
* @class OrderedHuffmanTable
|
||||
* utility class for working with huffman table
|
||||
*/
|
||||
var OrderedHuffmanTable = function() {
|
||||
this.process = function(lengths) {
|
||||
var len = lengths.length;
|
||||
var z = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
z.push([i, lengths[i]]);
|
||||
}
|
||||
z.push([len, -1]);
|
||||
|
||||
var l = [];
|
||||
var b = z[0];
|
||||
var start = b[0], bits = b[1];
|
||||
for (var p = 1; p < z.length; p++) {
|
||||
var finish = z[p][0], endbits = z[p][1];
|
||||
if (bits)
|
||||
for (var code = start; code < finish; code++)
|
||||
l.push(new HuffmanLength(code, bits));
|
||||
start = finish;
|
||||
bits = endbits;
|
||||
if (endbits == -1) break;
|
||||
}
|
||||
l.sort(function (a, b) { //function cmpHuffmanTable(a, b), can be anonymous, optimized, Gonzalo
|
||||
return (a.bits - b.bits) || (a.code - b.code);
|
||||
});
|
||||
this.table = l;
|
||||
|
||||
//inlined populate_huffman_symbols, Gonzalo
|
||||
var temp_bits = 0;
|
||||
var symbol = -1;
|
||||
// faht = Fast Access Huffman Table
|
||||
this.faht = [];
|
||||
var cb = null;
|
||||
for (var i = 0; i < this.table.length; i++) {
|
||||
var x = this.table[i];
|
||||
symbol += 1;
|
||||
if (x.bits != temp_bits ) {
|
||||
symbol <<= x.bits - temp_bits ;
|
||||
cb = this.faht[temp_bits = x.bits] = {};
|
||||
}
|
||||
cb[x.symbol = symbol] = x;
|
||||
}
|
||||
|
||||
//inlined min_max_bits
|
||||
|
||||
this.min_bits = 16;
|
||||
this.max_bits = -1;
|
||||
this.table.forEach(function(x){
|
||||
if (x.bits < this.min_bits) this.min_bits = x.bits;
|
||||
if (x.bits > this.max_bits) this.max_bits = x.bits;
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
|
||||
return ({ bz2: { decode: function(input) { //eliminated unused unpackSize, Gonzalo
|
||||
var b = new RBitfield();
|
||||
b.init(input);
|
||||
b.readbits(16);
|
||||
var method = b.readbits(8);
|
||||
if (method != 104) { //char 'h'
|
||||
throw "Unknown (not type 'h'uffman Bzip2) compression method";
|
||||
}
|
||||
|
||||
var blocksize = b.readbits(8);
|
||||
if ( 49 <= blocksize && blocksize <= 57) { //char '1' && char '9'
|
||||
blocksize -= 48; //char 0
|
||||
} else {
|
||||
throw "Unknown (not size '1'-'9') Bzip2 blocksize";
|
||||
}
|
||||
|
||||
function getUsedCharTable(b) {
|
||||
var a = [];
|
||||
var used_groups = b.readbits(16);
|
||||
for (var m1 = 1 << 15; m1 > 0; m1 >>= 1) {
|
||||
if (!(used_groups & m1)) {
|
||||
for (var i = 0; i < 16; i++) a.push(false);
|
||||
continue;
|
||||
}
|
||||
var used_chars = b.readbits(16);
|
||||
for (var m2 = 1 << 15; m2 > 0; m2 >>= 1) {
|
||||
a.push( Boolean(used_chars & m2) );
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var out = [];
|
||||
|
||||
function main_loop() { while (true) {
|
||||
var blocktype = b.readbits2(48);
|
||||
var crc = b.readbits2(32);
|
||||
if (blocktype == 0x314159265359) { // (pi)
|
||||
if (b.readbits(1)) throw "Bzip2 randomised support not implemented";
|
||||
var pointer = b.readbits(24);
|
||||
var used = getUsedCharTable(b);
|
||||
|
||||
var huffman_groups = b.readbits(3);
|
||||
if (2 > huffman_groups || huffman_groups > 6)
|
||||
throw RangeError("Bzip2: Number of Huffman groups not in range 2..6");
|
||||
var mtf = [0,1,2,3,4,5,6].slice(0,huffman_groups); //eliminate use of range, Gonzalo
|
||||
var selectors_list = [];
|
||||
for (var i = 0, selectors_used = b.readbits(15); i < selectors_used; i++) {
|
||||
// zero-terminated bit runs (0..62) of MTF'ed huffman table
|
||||
var c = 0;
|
||||
while (b.readbits(1)) {
|
||||
if (c++ >= huffman_groups)
|
||||
throw RangeError("More than max ("+huffman_groups+") groups");
|
||||
}
|
||||
move_to_front_and_store(mtf, c, selectors_list); //optimized to single function, Gonzalo
|
||||
}
|
||||
var groups_lengths = [];
|
||||
|
||||
// INLINE: sum used only once, Gonzalo
|
||||
var symbols_in_use = used.reduce( function(a, b) {return a + b}, 0 ) + 2; //sum(used) + 2 // remember RUN[AB] RLE symbols
|
||||
|
||||
for (var j = 0; j < huffman_groups; j++) {
|
||||
var length = b.readbits(5);
|
||||
var lengths = [];
|
||||
for (var i = 0; i < symbols_in_use; i++) {
|
||||
if (length < 0 || length > 20)
|
||||
throw RangeError("Bzip2 Huffman length code outside range 0..20");
|
||||
while (b.readbits(1)) length -= (b.readbits(1) * 2) - 1;
|
||||
lengths.push(length);
|
||||
}
|
||||
groups_lengths.push(lengths);
|
||||
}
|
||||
var tables = [];
|
||||
for (var g = 0; g < groups_lengths.length; g++) {
|
||||
var codes = new OrderedHuffmanTable();
|
||||
codes.process(groups_lengths[g]); //consolidated function calls
|
||||
tables.push(codes);
|
||||
}
|
||||
var favourites = [];
|
||||
for (var c = used.length - 1; c >= 0; c--) {
|
||||
if (used[c]) favourites.push(String.fromCharCode(c)); //inlined chr, used once, Gonzalo
|
||||
}
|
||||
favourites.reverse();
|
||||
var selector_pointer = 0;
|
||||
var decoded = 0;
|
||||
var t;
|
||||
|
||||
// Main Huffman loop
|
||||
var repeat = 0;
|
||||
var repeat_power = 0;
|
||||
var buffer = [], r;
|
||||
|
||||
while (true) {
|
||||
if (--decoded <= 0) {
|
||||
decoded = 50;
|
||||
if (selector_pointer <= selectors_list.length)
|
||||
t = tables[selectors_list[selector_pointer++]];
|
||||
}
|
||||
|
||||
// INLINED: find_next_symbol
|
||||
for (var bb in t.faht) {
|
||||
if (b.bits < bb) {
|
||||
b.bitfield = (b.bitfield << 8) + b.f.charCodeAt(b.count++);
|
||||
b.bits += 8;
|
||||
}
|
||||
if (r = t.faht[bb][ b.bitfield >> (b.bits - bb) ]) {
|
||||
b.bitfield &= b.masks[b.bits -= bb];
|
||||
r = r.code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 <= r && r <= 1) {
|
||||
if (repeat == 0) repeat_power = 1;
|
||||
repeat += repeat_power << r;
|
||||
repeat_power <<= 1;
|
||||
continue;
|
||||
} else {
|
||||
var v = favourites[0];
|
||||
for ( ; repeat > 0; repeat--) buffer.push(v);
|
||||
}
|
||||
if (r == symbols_in_use - 1) { // eof symbol
|
||||
break;
|
||||
} else {
|
||||
move_to_front_and_store(favourites,r-1,buffer); //Uninlined, size efficiency, Gonzalo
|
||||
}
|
||||
}
|
||||
var nt = bwt_reverse(buffer, pointer);
|
||||
var done = [];
|
||||
var i = 0;
|
||||
var len = nt.length;
|
||||
// RLE decoding
|
||||
while (i < len) {
|
||||
var c = nt.charCodeAt(i);
|
||||
if ((i < len - 4)
|
||||
&& nt.charCodeAt(i+1) == c
|
||||
&& nt.charCodeAt(i+2) == c
|
||||
&& nt.charCodeAt(i+3) == c) {
|
||||
var c = nt.charAt(i);
|
||||
var rep = nt.charCodeAt(i+4)+4;
|
||||
for (; rep > 0; rep--) done.push(c);
|
||||
i += 5;
|
||||
} else {
|
||||
done.push(nt[i++]);
|
||||
}
|
||||
}
|
||||
out.push(done.join(''));
|
||||
} else if (blocktype == 0x177245385090) { // sqrt(pi)
|
||||
b.readbits(b.bits & 0x7); //align
|
||||
break;
|
||||
} else {
|
||||
throw "Illegal Bzip2 blocktype = 0x" + blocktype.toString(16);
|
||||
}
|
||||
} }
|
||||
main_loop();
|
||||
return out.join('');
|
||||
} } });
|
||||
})();
|
32
evopedia-html5/WebContent/evopedia.html
Normal file
32
evopedia-html5/WebContent/evopedia.html
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
|
||||
<title>Evopedia HTML5</title>
|
||||
<script type="text/javascript" src="bzip2-antimatter15.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Evopedia</h1>
|
||||
<br/>
|
||||
Blockstart : <input type="text" id="blockstart" value="0" />
|
||||
<br/>
|
||||
Blockoffset : <input type="text" id="blockoffset" value="0" />
|
||||
<br/>
|
||||
Length : <input type="text" id="length" value="8866" />
|
||||
<br/>
|
||||
<div id="openLocalFiles" style="visibility:hidden">
|
||||
Please pick the file wikipedia_00.dat from the wikipedia_small_2010-08-14 dump :<br>
|
||||
<input type="file" id="files" name="file" />
|
||||
</div>
|
||||
<br/>
|
||||
<input type="button" id="read" value="Read from dump" onclick="readArticleFromHtmlForm(file)" />
|
||||
<br/>
|
||||
<div id="articleContent"> </div>
|
||||
<hr/>
|
||||
<pre id="rawArticleContent"> </pre>
|
||||
|
||||
<script type="text/javascript" src="evopedia.js"></script>
|
||||
</body>
|
||||
</html>
|
88
evopedia-html5/WebContent/evopedia.js
Normal file
88
evopedia-html5/WebContent/evopedia.js
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
var file=document.getElementById('files').files[0];
|
||||
|
||||
var storage = navigator.getDeviceStorage('music');
|
||||
//alert(storage);
|
||||
|
||||
if (!storage) {
|
||||
//alert("no device storage available");
|
||||
document.getElementById('openLocalFiles').style.visibility="visible";
|
||||
document.getElementById('files').addEventListener('change', handleFileSelect, false);
|
||||
document.getElementById('files').addEventListener('load', handleFileSelect, false);
|
||||
}
|
||||
else {
|
||||
var filerequest = storage.get('wikipedia_small_2010-08-14/wikipedia_00.dat');
|
||||
//alert(filerequest);
|
||||
filerequest.onsuccess = function() {
|
||||
file = filerequest.result;
|
||||
//alert(file);
|
||||
//readArticleFromHtmlForm(file);
|
||||
};
|
||||
filerequest.onerror = function() {
|
||||
alert("error reading file");
|
||||
};
|
||||
}
|
||||
|
||||
function readArticleFromHtmlForm(file) {
|
||||
if (file) {
|
||||
var blockstart = document.getElementById('blockstart').value;
|
||||
var blockoffset = document.getElementById('blockoffset').value;
|
||||
var length = document.getElementById('length').value;
|
||||
readArticleFromOffset(file, blockstart, blockoffset, length);
|
||||
}
|
||||
else {
|
||||
alert("File not set");
|
||||
}
|
||||
}
|
||||
|
||||
function readArticleFromOffset(file, blockstart, blockoffset, length) {
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onerror = errorHandler;
|
||||
reader.onabort = function(e) {
|
||||
alert('File read cancelled');
|
||||
};
|
||||
reader.onload = function(e) {
|
||||
var compressedArticles = e.target.result;
|
||||
//var htmlArticle = compressedArticles;
|
||||
//alert(typeof compressedArticles);
|
||||
//var htmlArticle = ArchUtils.bz2.decode(compressedArticles);
|
||||
// TODO : should be improved by uncompressing the content chunk by chunk,
|
||||
// until the length is reached, instead of uncompressing everything
|
||||
var htmlArticles = bzip2.simple(bzip2.array(new Uint8Array(compressedArticles)));
|
||||
var htmlArticle = htmlArticles.substring(blockoffset,length);
|
||||
// Decode UTF-8 encoding
|
||||
htmlArticle = decodeURIComponent(escape(htmlArticle));
|
||||
|
||||
document.getElementById('articleContent').innerHTML = htmlArticle;
|
||||
// For testing purpose
|
||||
document.getElementById('rawArticleContent').innerHTML = htmlArticle.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||||
};
|
||||
|
||||
//var blob = file;
|
||||
// TODO : should be improved by reading the file chunks by chunks until the article is found,
|
||||
// instead of reading the whole file starting at blockstart
|
||||
var blob = file.slice(blockstart);
|
||||
|
||||
// Read in the image file as a binary string.
|
||||
reader.readAsArrayBuffer(blob);
|
||||
}
|
||||
|
||||
function errorHandler(evt) {
|
||||
switch(evt.target.error.code) {
|
||||
case evt.target.error.NOT_FOUND_ERR:
|
||||
alert('File Not Found!');
|
||||
break;
|
||||
case evt.target.error.NOT_READABLE_ERR:
|
||||
alert('File is not readable');
|
||||
break;
|
||||
case evt.target.error.ABORT_ERR:
|
||||
break; // noop
|
||||
default:
|
||||
alert('An error occurred reading this file.');
|
||||
};
|
||||
}
|
||||
|
||||
function handleFileSelect(evt) {
|
||||
file = evt.target.files[0];
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user