Files: 9f6b7a97b920fe19a6c5b5cde35a13230b4e1b9a / lib / pkt-line.js
2962 bytesRaw
1 | var buffered = require('pull-buffered') |
2 | var util = require('./util') |
3 | |
4 | function rev(str) { |
5 | return str === '0000000000000000000000000000000000000000' ? null : str |
6 | } |
7 | |
8 | // from pull-stream/source.js |
9 | function abortCb(cb, abort, onAbort) { |
10 | cb(abort) |
11 | onAbort && onAbort(abort === true ? null: abort) |
12 | return |
13 | } |
14 | |
15 | function pktLineEncode(read) { |
16 | var ended |
17 | return function (end, cb) { |
18 | if (ended) return cb(ended) |
19 | read(end, function (end, data) { |
20 | if (ended = end) { |
21 | cb(end) |
22 | } else { |
23 | if (data) |
24 | data += '\n' |
25 | else |
26 | data = '' |
27 | var len = data ? data.length + 4 : 0 |
28 | var hexLen = ('000' + len.toString(16)).substr(-4) |
29 | var pkt = hexLen + data |
30 | // console.error('>', JSON.stringify(pkt)) |
31 | cb(end, pkt) |
32 | } |
33 | }) |
34 | } |
35 | } |
36 | |
37 | function pktLineDecode(read, options) { |
38 | var b = buffered(read) |
39 | var readPrefix = b.chunks(4) |
40 | var ended |
41 | |
42 | function readPackLine(abort, cb) { |
43 | if (ended) return cb(ended) |
44 | readPrefix(abort, function (end, buf) { |
45 | if (ended = end) return cb(end) |
46 | var len = parseInt(buf, 16) |
47 | if (!len) |
48 | return cb(null, new Buffer('')) |
49 | b.chunks(len - 4)(null, function (end, buf) { |
50 | if (ended = end) return cb(end) |
51 | cb(end, buf) |
52 | }) |
53 | }) |
54 | } |
55 | |
56 | function readPackLineStr(abort, cb) { |
57 | if (ended) return cb(ended) |
58 | readPackLine(abort, function (end, buf) { |
59 | if (ended = end) return cb(end) |
60 | // trim newline |
61 | var len = buf.length |
62 | if (buf[len - 1] == 0xa) |
63 | len-- |
64 | var line = buf.toString('ascii', 0, len) |
65 | cb(null, line) |
66 | }) |
67 | } |
68 | |
69 | function readUpdate(abort, cb) { |
70 | readPackLine(abort, function (end, line) { |
71 | if (end) return cb(end) |
72 | if (!line.length) return cb(true) |
73 | var args = util.split3(line.toString('ascii')) |
74 | var args2 = util.split2(args[2], '\0') |
75 | var caps = args2[1] |
76 | if (caps) { |
77 | if (options.onCaps) { |
78 | var capsSet = {} |
79 | caps.split(' ').forEach(function (cap) { |
80 | capsSet[cap] = true |
81 | }) |
82 | options.onCaps(capsSet) |
83 | } |
84 | } |
85 | cb(null, { |
86 | old: rev(args[0]), |
87 | new: rev(args[1]), |
88 | name: args2[0] |
89 | }) |
90 | }) |
91 | } |
92 | |
93 | function havesWants(onEnd) { |
94 | return function readWant(abort, cb) { |
95 | readPackLineStr(abort, function (end, line) { |
96 | if (end) return abortCb(cb, end, onEnd) |
97 | if (line === 'done') return abortCb(cb, true, onEnd) |
98 | if (line.length === 0) return cb(null, {type: 'flush-pkt'}) |
99 | var args = util.split3(line) |
100 | var caps = args[2] |
101 | if (caps) { |
102 | if (options.onCaps) |
103 | options.onCaps(caps) |
104 | } |
105 | cb(null, { |
106 | type: args[0], |
107 | hash: args[1], |
108 | }) |
109 | }) |
110 | } |
111 | } |
112 | |
113 | b.pktLines = readPackLine |
114 | b.updates = readUpdate |
115 | b.wants = b.haves = havesWants |
116 | |
117 | return b |
118 | } |
119 | |
120 | exports.encode = pktLineEncode |
121 | exports.decode = pktLineDecode |
122 |
Built with git-ssb-web