Skip to content

Commit 7d23427

Browse files
committed
Get unpack working
1 parent 7b5157f commit 7d23427

9 files changed

+264
-47
lines changed

Diff for: lib/apply-delta.js

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// This is Chris Dickinson's code
22

33
var binary = require('bodec')
4-
// , Decoder = require('varint/decode.js')
5-
// , vi = new Decoder
4+
, vi = new Decoder
65

76
// we use writeUint[8|32][LE|BE] instead of indexing
87
// into buffers so that we get buffer-browserify compat.
@@ -11,7 +10,6 @@ var OFFSET_BUFFER = binary.create(4)
1110

1211
module.exports = apply_delta;
1312
function apply_delta(delta, target) {
14-
throw "TODO: fix me"
1513
var base_size_info = {size: null, buffer: null}
1614
, resized_size_info = {size: null, buffer: null}
1715
, output_buffer
@@ -107,3 +105,34 @@ function delta_header(buf, output) {
107105
output.buffer = binary.slice(buf, idx)
108106

109107
}
108+
109+
var MSB = 0x80
110+
, REST = 0x7F
111+
112+
function Decoder() {
113+
this.accum = []
114+
}
115+
Decoder.prototype.write = write;
116+
117+
function write(byte) {
118+
var msb = byte & MSB
119+
, accum = this.accum
120+
, len
121+
, out
122+
123+
accum[accum.length] = byte & REST
124+
if(msb) {
125+
return
126+
}
127+
128+
len = accum.length
129+
out = 0
130+
131+
for(var i = 0; i < len; ++i) {
132+
out |= accum[i] << (7 * i)
133+
}
134+
135+
accum.length = 0
136+
this.ondata(out)
137+
return
138+
}

Diff for: lib/decoders.js

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
var indexOf = require('./indexof.js');
2+
var parseOct = require('./parseoct.js');
3+
var parseAscii = require('./parseascii.js');
4+
var parseToHex = require('./parsetohex.js');
5+
6+
exports.commit = function decodeCommit(body) {
7+
var i = 0;
8+
var start;
9+
var key;
10+
var parents = [];
11+
var commit = {
12+
tree: "",
13+
parents: parents,
14+
author: "",
15+
committer: "",
16+
message: ""
17+
};
18+
while (body[i] !== 0x0a) {
19+
start = i;
20+
i = indexOf(body, 0x20, start);
21+
if (i < 0) throw new SyntaxError("Missing space");
22+
key = parseAscii(body, start, i++);
23+
start = i;
24+
i = indexOf(body, 0x0a, start);
25+
if (i < 0) throw new SyntaxError("Missing linefeed");
26+
var value = parseAscii(body, start, i++);
27+
if (key === "parent") {
28+
parents.push(value);
29+
}
30+
else {
31+
if (key === "author" || key === "committer") {
32+
value = decodePerson(value);
33+
}
34+
commit[key] = value;
35+
}
36+
}
37+
i++;
38+
commit.message = parseAscii(body, i, body.length);
39+
return commit;
40+
};
41+
42+
exports.tag = function decodeTag(body) {
43+
var i = 0;
44+
var start;
45+
var key;
46+
var tag = {};
47+
while (body[i] !== 0x0a) {
48+
start = i;
49+
i = indexOf(body, 0x20, start);
50+
if (i < 0) throw new SyntaxError("Missing space");
51+
key = parseAscii(body, start, i++);
52+
start = i;
53+
i = indexOf(body, 0x0a, start);
54+
if (i < 0) throw new SyntaxError("Missing linefeed");
55+
var value = parseAscii(body, start, i++);
56+
if (key === "tagger") value = decodePerson(value);
57+
tag[key] = value;
58+
}
59+
i++;
60+
tag.message = parseAscii(body, i, body.length);
61+
return tag;
62+
};
63+
64+
exports.tree = function decodeTree(body) {
65+
var i = 0;
66+
var length = body.length;
67+
var start;
68+
var mode;
69+
var name;
70+
var hash;
71+
var tree = {};
72+
while (i < length) {
73+
start = i;
74+
i = indexOf(body, 0x20, start);
75+
if (i < 0) throw new SyntaxError("Missing space");
76+
mode = parseOct(body, start, i++);
77+
start = i;
78+
i = indexOf(body, 0x00, start);
79+
name = parseAscii(body, start, i++);
80+
hash = parseToHex(body, i, i += 20);
81+
tree[name] = {
82+
mode: mode,
83+
hash: hash
84+
};
85+
}
86+
return tree;
87+
};
88+
89+
exports.blob = function decodeBlob(body) {
90+
return body;
91+
};
92+
93+
function decodePerson(string) {
94+
var match = string.match(/^([^<]*) <([^>]*)> ([^ ]*) (.*)$/);
95+
if (!match) throw new Error("Improperly formatted person string");
96+
var sec = parseInt(match[3], 10);
97+
var date = new Date(sec * 1000);
98+
date.timeZoneoffset = parseInt(match[4], 10) / 100 * -60;
99+
return {
100+
name: match[1],
101+
email: match[2],
102+
date: date
103+
};
104+
}

Diff for: lib/inflate-stream.js

+55-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,54 @@
1-
// Taken from chrisdickinson/inflate's min.js
2-
// Modified to use bodec and inlined in js-git
3-
// Original code under MIT License
4-
// Copyright Chris Diskinson <[email protected]>
1+
var binary = require('bodec');
52

6-
module.exports = inflate
3+
// Wrapper for proposed new API to inflate:
4+
//
5+
// var inf = inflate();
6+
// inf.write(byte) -> more - Write a byte to inflate's state-machine.
7+
// Returns true if more data is expected.
8+
// inf.recycle() - Reset the internal state machine.
9+
// inf.flush() -> data - Flush the output as a binary buffer.
10+
//
11+
// This is quite slow, but could be made fast if baked into inflate itself.
12+
module.exports = function () {
13+
var push = inflate(onEmit, onUnused);
14+
var more = true;
15+
var chunks = [];
16+
var b = binary.create(1);
717

8-
var binary = require('bodec')
18+
return { write: write, recycle: recycle, flush: flush };
19+
20+
function write(byte) {
21+
b[0] = byte;
22+
push(null, b);
23+
return more;
24+
}
25+
26+
function recycle() {
27+
push.recycle();
28+
more = true;
29+
}
30+
31+
function flush() {
32+
var buffer = binary.join(chunks);
33+
chunks.length = 0;
34+
return buffer;
35+
}
36+
37+
function onEmit(err, item) {
38+
if (err) throw err;
39+
if (item === undefined) {
40+
// console.log("onEnd");
41+
more = false;
42+
return;
43+
}
44+
chunks.push(item);
45+
}
46+
47+
function onUnused(chunks) {
48+
// console.log("onUnused", chunks);
49+
more = false;
50+
}
51+
};
952

1053
var MAXBITS = 15
1154
, MAXLCODES = 286
@@ -86,7 +129,7 @@ function inflate(emit, on_unused) {
86129
output_one_offs = 0
87130
become(noop, {}, noop)
88131
start_stream_header()
89-
return stream
132+
// return stream
90133
}
91134

92135
var bytes_need = 0
@@ -596,9 +639,11 @@ function inflate(emit, on_unused) {
596639
output_idx = 0
597640
ended = true
598641
emit()
599-
return
642+
// return
643+
}
644+
else {
645+
last = result
600646
}
601-
last = result
602647
}
603648

604649
function bits() {
@@ -720,7 +765,7 @@ function inflate(emit, on_unused) {
720765
output_idx &= WINDOW_MINUS_ONE
721766
}
722767

723-
emit(binary.fromArray(vals))
768+
emit(null, binary.fromArray(vals))
724769
}
725770
}
726771

Diff for: lib/pack-codec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var inflate = require('./inflate.js');
1+
var inflate = require('./inflate-stream.js');
22
var deflate = require('./deflate.js');
33
var sha1 = require('git-sha1');
44
var binary = require('bodec');

Diff for: lib/parseoct.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = function parseOct(buffer, start, end) {
2+
var val = 0;
3+
while (start < end) {
4+
val = (val << 3) + buffer[start++] - 0x30;
5+
}
6+
return val;
7+
};

Diff for: lib/parsetohex.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var chars = "0123456789abcdef";
2+
3+
module.exports = function parseToHex(buffer, start, end) {
4+
var val = "";
5+
while (start < end) {
6+
var byte = buffer[start++];
7+
val += chars[byte >> 4] + chars[byte & 0xf];
8+
}
9+
return val;
10+
};

Diff for: lib/xhr-node.js

+6-12
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ module.exports = function (root, accessToken) {
4444
body = Buffer.concat(body).toString();
4545
console.log(method, url, res.statusCode);
4646
console.log("Rate limit %s/%s left", res.headers['x-ratelimit-remaining'], res.headers['x-ratelimit-limit']);
47-
if (res.statusCode >= 400 && res.statusCode < 500) return callback();
48-
else if (res.statusCode === 200 && method === "GET" && /\/refs\//.test(url)) {
47+
if (res.statusCode === 200 && method === "GET" && /\/refs\//.test(url)) {
4948
cache[url] = {
5049
body: body,
5150
etag: res.headers.etag
@@ -55,21 +54,16 @@ module.exports = function (root, accessToken) {
5554
body = cache[url].body;
5655
res.statusCode = 200;
5756
}
58-
else if (res.statusCode < 200 || res.statusCode >= 300) {
59-
return callback(new Error("Invalid HTTP response: " + res.statusCode));
60-
}
61-
62-
var response = {message:body};
63-
if (body){
64-
try { response = JSON.parse(body); }
65-
catch (err) {}
66-
}
67-
6857
// Fake parts of the xhr object using node APIs
6958
var xhr = {
7059
status: res.statusCode,
7160
statusText: res.statusCode + " " + statusCodes[res.statusCode]
7261
};
62+
var response = {message:body};
63+
if (body){
64+
try { response = JSON.parse(body); }
65+
catch (err) {}
66+
}
7367
return callback(null, xhr, response);
7468
});
7569
});

0 commit comments

Comments
 (0)