feat: 초기 프로젝트 설정 및 룰.md 파일 추가
This commit is contained in:
326
api.hyungi.net/node_modules/js-git/lib/pack-codec.js
generated
vendored
Normal file
326
api.hyungi.net/node_modules/js-git/lib/pack-codec.js
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
var inflateStream = require('./inflate-stream.js');
|
||||
var inflate = require('./inflate.js');
|
||||
var deflate = require('./deflate.js');
|
||||
var sha1 = require('git-sha1');
|
||||
var bodec = require('bodec');
|
||||
|
||||
var typeToNum = {
|
||||
commit: 1,
|
||||
tree: 2,
|
||||
blob: 3,
|
||||
tag: 4,
|
||||
"ofs-delta": 6,
|
||||
"ref-delta": 7
|
||||
};
|
||||
var numToType = {};
|
||||
for (var type in typeToNum) {
|
||||
var num = typeToNum[type];
|
||||
numToType[num] = type;
|
||||
}
|
||||
exports.parseEntry = parseEntry;
|
||||
function parseEntry(chunk) {
|
||||
var offset = 0;
|
||||
var byte = chunk[offset++];
|
||||
var type = numToType[(byte >> 4) & 0x7];
|
||||
var size = byte & 0xf;
|
||||
var left = 4;
|
||||
while (byte & 0x80) {
|
||||
byte = chunk[offset++];
|
||||
size |= (byte & 0x7f) << left;
|
||||
left += 7;
|
||||
}
|
||||
size = size >>> 0;
|
||||
var ref;
|
||||
if (type === "ref-delta") {
|
||||
ref = bodec.toHex(bodec.slice(chunk, offset, offset += 20));
|
||||
}
|
||||
else if (type === "ofs-delta") {
|
||||
byte = chunk[offset++];
|
||||
ref = byte & 0x7f;
|
||||
while (byte & 0x80) {
|
||||
byte = chunk[offset++];
|
||||
ref = ((ref + 1) << 7) | (byte & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
var body = inflate(bodec.slice(chunk, offset));
|
||||
if (body.length !== size) {
|
||||
throw new Error("Size mismatch");
|
||||
}
|
||||
var result = {
|
||||
type: type,
|
||||
body: body
|
||||
};
|
||||
if (typeof ref !== "undefined") {
|
||||
result.ref = ref;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
exports.decodePack = decodePack;
|
||||
function decodePack(emit) {
|
||||
|
||||
var state = $pack;
|
||||
var sha1sum = sha1();
|
||||
var inf = inflateStream();
|
||||
|
||||
var offset = 0;
|
||||
var position = 0;
|
||||
var version = 0x4b434150; // PACK reversed
|
||||
var num = 0;
|
||||
var type = 0;
|
||||
var length = 0;
|
||||
var ref = null;
|
||||
var checksum = "";
|
||||
var start = 0;
|
||||
var parts = [];
|
||||
|
||||
|
||||
return function (chunk) {
|
||||
if (chunk === undefined) {
|
||||
if (num || checksum.length < 40) throw new Error("Unexpected end of input stream");
|
||||
return emit();
|
||||
}
|
||||
|
||||
for (var i = 0, l = chunk.length; i < l; i++) {
|
||||
// console.log([state, i, chunk[i].toString(16)]);
|
||||
if (!state) throw new Error("Unexpected extra bytes: " + bodec.slice(chunk, i));
|
||||
state = state(chunk[i], i, chunk);
|
||||
position++;
|
||||
}
|
||||
if (!state) return;
|
||||
if (state !== $checksum) sha1sum.update(chunk);
|
||||
var buff = inf.flush();
|
||||
if (buff.length) {
|
||||
parts.push(buff);
|
||||
}
|
||||
};
|
||||
|
||||
// The first four bytes in a packfile are the bytes 'PACK'
|
||||
function $pack(byte) {
|
||||
if ((version & 0xff) === byte) {
|
||||
version >>>= 8;
|
||||
return version ? $pack : $version;
|
||||
}
|
||||
throw new Error("Invalid packfile header");
|
||||
}
|
||||
|
||||
// The version is stored as an unsigned 32 integer in network byte order.
|
||||
// It must be version 2 or 3.
|
||||
function $version(byte) {
|
||||
version = (version << 8) | byte;
|
||||
if (++offset < 4) return $version;
|
||||
if (version >= 2 && version <= 3) {
|
||||
offset = 0;
|
||||
return $num;
|
||||
}
|
||||
throw new Error("Invalid version number " + num);
|
||||
}
|
||||
|
||||
// The number of objects in this packfile is also stored as an unsigned 32 bit int.
|
||||
function $num(byte) {
|
||||
num = (num << 8) | byte;
|
||||
if (++offset < 4) return $num;
|
||||
offset = 0;
|
||||
emit({version: version, num: num});
|
||||
return $header;
|
||||
}
|
||||
|
||||
// n-byte type and length (3-bit type, (n-1)*7+4-bit length)
|
||||
// CTTTSSSS
|
||||
// C is continue bit, TTT is type, S+ is length
|
||||
function $header(byte) {
|
||||
if (start === 0) start = position;
|
||||
type = byte >> 4 & 0x07;
|
||||
length = byte & 0x0f;
|
||||
if (byte & 0x80) {
|
||||
offset = 4;
|
||||
return $header2;
|
||||
}
|
||||
return afterHeader();
|
||||
}
|
||||
|
||||
// Second state in the same header parsing.
|
||||
// CSSSSSSS*
|
||||
function $header2(byte) {
|
||||
length |= (byte & 0x7f) << offset;
|
||||
if (byte & 0x80) {
|
||||
offset += 7;
|
||||
return $header2;
|
||||
}
|
||||
return afterHeader();
|
||||
}
|
||||
|
||||
// Common helper for finishing tiny and normal headers.
|
||||
function afterHeader() {
|
||||
offset = 0;
|
||||
if (type === 6) {
|
||||
ref = 0;
|
||||
return $ofsDelta;
|
||||
}
|
||||
if (type === 7) {
|
||||
ref = "";
|
||||
return $refDelta;
|
||||
}
|
||||
// console.log({type: type,length: length})
|
||||
return $body;
|
||||
}
|
||||
|
||||
// Big-endian modified base 128 number encoded ref offset
|
||||
function $ofsDelta(byte) {
|
||||
ref = byte & 0x7f;
|
||||
if (byte & 0x80) return $ofsDelta2;
|
||||
return $body;
|
||||
}
|
||||
|
||||
function $ofsDelta2(byte) {
|
||||
ref = ((ref + 1) << 7) | (byte & 0x7f);
|
||||
if (byte & 0x80) return $ofsDelta2;
|
||||
return $body;
|
||||
}
|
||||
|
||||
// 20 byte raw sha1 hash for ref
|
||||
function $refDelta(byte) {
|
||||
ref += toHex(byte);
|
||||
if (++offset < 20) return $refDelta;
|
||||
return $body;
|
||||
}
|
||||
|
||||
// Common helper for generating 2-character hex numbers
|
||||
function toHex(num) {
|
||||
return num < 0x10 ? "0" + num.toString(16) : num.toString(16);
|
||||
}
|
||||
|
||||
// Common helper for emitting all three object shapes
|
||||
function emitObject() {
|
||||
var body = bodec.join(parts);
|
||||
if (body.length !== length) {
|
||||
throw new Error("Body length mismatch");
|
||||
}
|
||||
var item = {
|
||||
type: numToType[type],
|
||||
size: length,
|
||||
body: body,
|
||||
offset: start
|
||||
};
|
||||
if (ref) item.ref = ref;
|
||||
parts.length = 0;
|
||||
start = 0;
|
||||
offset = 0;
|
||||
type = 0;
|
||||
length = 0;
|
||||
ref = null;
|
||||
emit(item);
|
||||
}
|
||||
|
||||
// Feed the deflated code to the inflate engine
|
||||
function $body(byte, i, chunk) {
|
||||
if (inf.write(byte)) return $body;
|
||||
var buf = inf.flush();
|
||||
if (buf.length !== length) throw new Error("Length mismatch, expected " + length + " got " + buf.length);
|
||||
inf.recycle();
|
||||
if (buf.length) {
|
||||
parts.push(buf);
|
||||
}
|
||||
emitObject();
|
||||
// If this was all the objects, start calculating the sha1sum
|
||||
if (--num) return $header;
|
||||
sha1sum.update(bodec.slice(chunk, 0, i + 1));
|
||||
return $checksum;
|
||||
}
|
||||
|
||||
// 20 byte checksum
|
||||
function $checksum(byte) {
|
||||
checksum += toHex(byte);
|
||||
if (++offset < 20) return $checksum;
|
||||
var actual = sha1sum.digest();
|
||||
if (checksum !== actual) throw new Error("Checksum mismatch: " + actual + " != " + checksum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
exports.encodePack = encodePack;
|
||||
function encodePack(emit) {
|
||||
var sha1sum = sha1();
|
||||
var left;
|
||||
return function (item) {
|
||||
if (item === undefined) {
|
||||
if (left !== 0) throw new Error("Some items were missing");
|
||||
return emit();
|
||||
}
|
||||
if (typeof item.num === "number") {
|
||||
if (left !== undefined) throw new Error("Header already sent");
|
||||
left = item.num;
|
||||
write(packHeader(item.num));
|
||||
}
|
||||
else if (typeof item.type === "string" && bodec.isBinary(item.body)) {
|
||||
// The header must be sent before items.
|
||||
if (typeof left !== "number") throw new Error("Headers not sent yet");
|
||||
|
||||
// Make sure we haven't sent all the items already
|
||||
if (!left) throw new Error("All items already sent");
|
||||
|
||||
// Send the item in packstream format
|
||||
write(packFrame(item));
|
||||
|
||||
// Send the checksum after the last item
|
||||
if (!--left) {
|
||||
emit(bodec.fromHex(sha1sum.digest()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Invalid item");
|
||||
}
|
||||
};
|
||||
function write(chunk) {
|
||||
sha1sum.update(chunk);
|
||||
emit(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
function packHeader(length) {
|
||||
return bodec.fromArray([
|
||||
0x50, 0x41, 0x43, 0x4b, // PACK
|
||||
0, 0, 0, 2, // version 2
|
||||
length >> 24, // Num of objects
|
||||
(length >> 16) & 0xff,
|
||||
(length >> 8) & 0xff,
|
||||
length & 0xff
|
||||
]);
|
||||
}
|
||||
|
||||
function packFrame(item) {
|
||||
var length = item.body.length;
|
||||
|
||||
// write TYPE_AND_BASE128_SIZE
|
||||
var head = [(typeToNum[item.type] << 4) | (length & 0xf)];
|
||||
var i = 0;
|
||||
length >>= 4;
|
||||
while (length) {
|
||||
head[i++] |= 0x80;
|
||||
head[i] = length & 0x7f;
|
||||
length >>= 7;
|
||||
}
|
||||
|
||||
if (typeof item.ref === "number") {
|
||||
// write BIG_ENDIAN_MODIFIED_BASE_128_NUMBER
|
||||
var offset = item.ref;
|
||||
// Calculate how many digits we need in base 128 and move the pointer
|
||||
i += Math.floor(Math.log(offset) / Math.log(0x80)) + 1;
|
||||
// Write the last digit
|
||||
head[i] = offset & 0x7f;
|
||||
// Then write the rest
|
||||
while (offset >>= 7) {
|
||||
head[--i] = 0x80 | (--offset & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
var parts = [bodec.fromArray(head)];
|
||||
if (typeof item.ref === "string") {
|
||||
parts.push(bodec.fromHex(item.ref));
|
||||
}
|
||||
parts.push(deflate(item.body));
|
||||
return bodec.join(parts);
|
||||
}
|
||||
Reference in New Issue
Block a user