Skip to content
This repository has been archived by the owner on Sep 13, 2022. It is now read-only.

Commit

Permalink
Yay
Browse files Browse the repository at this point in the history
  • Loading branch information
augustl committed Jan 31, 2010
0 parents commit eac6d9c
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 0 deletions.
20 changes: 20 additions & 0 deletions LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2010 August Lilleaas

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 changes: 23 additions & 0 deletions README.textile
@@ -0,0 +1,23 @@
h2. JSUnzip

A javascript library for unzipping files.

{{{
var myZip = ... // Get it with an XHR request, HTML5 files, etc.
var unzipper = new JSUnzip(myZip);
unzipper.readEntries();

// unzipper.entries is an array of JSUnzip.ZipEntry objects, one
// for each file in the zip.
var e = unzipper.entries[0];
e.fileName;
e.data; // raw unextracted data
}}}

The test suite runs on Chrome 4, FireFox 3.6, IE7, Opera 10 and Safari 4.0.4.

Very alpha, is among other things not yet able to inflate deflated (uncompress compressed) files.

h2. About

Written by August Lilleaas <august.lilleaas@gmail.com>. Licensed under the MIT license.
11 changes: 11 additions & 0 deletions Rakefile
@@ -0,0 +1,11 @@
namespace :jstestdriver do
desc "Starts a local server"
task :server do
exec("jstestdriver --port 4224")
end

desc "Runs the tests"
task :run do
exec("jstestdriver --tests all --config test/jsTestDriver.conf --reset")
end
end
143 changes: 143 additions & 0 deletions lib/js_unzip.js
@@ -0,0 +1,143 @@
(function (GLOBAL) {
var JSUnzip = function (fileContents) {
this.fileContents = new JSUnzip.BigEndianBinaryStream(fileContents);
}
GLOBAL.JSUnzip = JSUnzip;
JSUnzip.MAGIC_NUMBER = 0x04034b50;

JSUnzip.prototype = {
readEntries: function () {
if (!this.isZipFile()) {
throw new Error("File is not a Zip file.");
}

this.entries = [];
var e = new JSUnzip.ZipEntry(this.fileContents);
while (e.data) {
this.entries.push(e);
e = new JSUnzip.ZipEntry(this.fileContents);
}
},

isZipFile: function () {
return this.fileContents.getByteRangeAsNumber(0, 4) === JSUnzip.MAGIC_NUMBER;
}
}

JSUnzip.ZipEntry = function (binaryStream) {
this.signature = binaryStream.getNextBytesAsNumber(4);
if (this.signature !== JSUnzip.MAGIC_NUMBER) {
return;
}

this.versionNeeded = binaryStream.getNextBytesAsNumber(2);
this.bitFlag = binaryStream.getNextBytesAsNumber(2);
this.compressionMethod = binaryStream.getNextBytesAsNumber(2);
this.timeBlob = binaryStream.getNextBytesAsNumber(4);

if (this.isEncrypted() ||
this.isUsingUtf8() ||
this.isUsingBit3TrailingDataDescriptor()) {
return;
}

this.crc32 = binaryStream.getNextBytesAsNumber(4);
this.compressedSize = binaryStream.getNextBytesAsNumber(4);
this.uncompressedSize = binaryStream.getNextBytesAsNumber(4);

if (this.isUsingZip64()) {
return;
}

this.fileNameLength = binaryStream.getNextBytesAsNumber(2);
this.extraFieldLength = binaryStream.getNextBytesAsNumber(2);

this.fileName = binaryStream.getNextBytesAsString(this.fileNameLength);
this.extra = binaryStream.getNextBytesAsString(this.extraFieldLength);
this.data = binaryStream.getNextBytesAsString(this.compressedSize);
}

JSUnzip.ZipEntry.prototype = {
extract: function () {
if (this.compressionMethod === 0) {
this.extractedData = this.data;
} else if (this.compressionMethod == 8) {
// TODO: Write JSInflater :)
var inflater = new JSInflater(this.data);
inflater.inflate();
this.extractedData = inflater.data;
}
},

isEncrypted: function () {
return (this.bitFlag & 0x01) === 0x01;
},

isUsingUtf8: function () {
return (this.bitFlag & 0x0800) === 0x0800;
},

isUsingBit3TrailingDataDescriptor: function () {
return (this.bitFlag & 0x0008) === 0x0008;
},

isUsingZip64: function () {
this.compressedSize === 0xFFFFFFFF ||
this.uncompressedSize === 0xFFFFFFFF;
}
}

JSUnzip.BigEndianBinaryStream = function (stream) {
this.stream = stream;
this.resetByteIndex();
}

JSUnzip.BigEndianBinaryStream.prototype = {
// The index of the current byte, used when we step through the byte
// with getNextBytesAs*.
resetByteIndex: function () {
this.currentByteIndex = 0;
},

// TODO: Other similar JS libs does charCodeAt(index) & 0xff. Grok
// why, and do that here if neccesary. So far, I've never gotten a
// char code higher than 255.
getByteAt: function (index) {
return this.stream.charCodeAt(index);
},

getNextBytesAsNumber: function (steps) {
var res = this.getByteRangeAsNumber(this.currentByteIndex, steps);
this.currentByteIndex += steps;
return res;
},

getNextBytesAsString: function (steps) {
var res = this.getByteRangeAsString(this.currentByteIndex, steps);
this.currentByteIndex += steps;
return res;
},

// Big endian, so we're going backwards.
getByteRangeAsNumber: function (index, steps) {
var result = 0;
var i = index + steps - 1;
while (i >= index) {
result = (result << 8) + this.getByteAt(i);
i--;
}
return result;
},

getByteRangeAsString: function (index, steps) {
var result = "";
var max = index + steps;
var i = index;
while (i < max) {
result += String.fromCharCode(this.getByteAt(i));
i++;
}
return result;
}
}
}(this));
5 changes: 5 additions & 0 deletions test/jsTestDriver.conf
@@ -0,0 +1,5 @@
server: http://localhost:4224

load:
- ../lib/js_unzip.js
- tests/*_test.js
6 changes: 6 additions & 0 deletions test/tests/deflate_test.js
@@ -0,0 +1,6 @@
TestCase("DeflateTest", {
"test it": function () {
var deflated = "";
// var deflater = new JSUnzip.Deflate(deflated);
}
})
58 changes: 58 additions & 0 deletions test/tests/jszip_test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit eac6d9c

Please sign in to comment.