pull-git-remote-helper
Version:
use pull-streams to make gitremote-helpers(1)
122 lines (110 loc) • 2.96 kB
JavaScript
var buffered = require('pull-buffered')
var util = require('./util')
function rev(str) {
return str === '0000000000000000000000000000000000000000' ? null : str
}
// from pull-stream/source.js
function abortCb(cb, abort, onAbort) {
cb(abort)
onAbort && onAbort(abort === true ? null: abort)
return
}
function pktLineEncode(read) {
var ended
return function (end, cb) {
if (ended) return cb(ended)
read(end, function (end, data) {
if (ended = end) {
cb(end)
} else {
if (data)
data += '\n'
else
data = ''
var len = data ? data.length + 4 : 0
var hexLen = ('000' + len.toString(16)).substr(-4)
var pkt = hexLen + data
// console.error('>', JSON.stringify(pkt))
cb(end, pkt)
}
})
}
}
function pktLineDecode(read, options) {
var b = buffered(read)
var readPrefix = b.chunks(4)
var ended
function readPackLine(abort, cb) {
if (ended) return cb(ended)
readPrefix(abort, function (end, buf) {
if (ended = end) return cb(end)
var len = parseInt(buf, 16)
if (!len)
return cb(null, new Buffer(''))
b.chunks(len - 4)(null, function (end, buf) {
if (ended = end) return cb(end)
cb(end, buf)
})
})
}
function readPackLineStr(abort, cb) {
if (ended) return cb(ended)
readPackLine(abort, function (end, buf) {
if (ended = end) return cb(end)
// trim newline
var len = buf.length
if (buf[len - 1] == 0xa)
len--
var line = buf.toString('ascii', 0, len)
cb(null, line)
})
}
function readUpdate(abort, cb) {
readPackLine(abort, function (end, line) {
if (end) return cb(end)
if (!line.length) return cb(true)
var args = util.split3(line.toString('ascii'))
var args2 = util.split2(args[2], '\0')
var caps = args2[1]
if (caps) {
if (options.onCaps) {
var capsSet = {}
caps.split(' ').forEach(function (cap) {
capsSet[cap] = true
})
options.onCaps(capsSet)
}
}
cb(null, {
old: rev(args[0]),
new: rev(args[1]),
name: args2[0]
})
})
}
function havesWants(onEnd) {
return function readWant(abort, cb) {
readPackLineStr(abort, function (end, line) {
if (end) return abortCb(cb, end, onEnd)
if (line === 'done') return abortCb(cb, true, onEnd)
if (line.length === 0) return cb(null, {type: 'flush-pkt'})
var args = util.split3(line)
var caps = args[2]
if (caps) {
if (options.onCaps)
options.onCaps(caps)
}
cb(null, {
type: args[0],
hash: args[1],
})
})
}
}
b.pktLines = readPackLine
b.updates = readUpdate
b.wants = b.haves = havesWants
return b
}
exports.encode = pktLineEncode
exports.decode = pktLineDecode