Files: 89d4ea002ce8eba46b2a851392339309844af851 / lib / pkt-line.js
3179 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 (options.verbosity >= 2) |
73 | console.error('line', line.toString('ascii')) |
74 | if (!line.length) return cb(true) |
75 | var args = util.split3(line.toString('ascii')) |
76 | var args2 = util.split2(args[2], '\0') |
77 | var caps = args2[1] |
78 | if (caps) { |
79 | if (options.verbosity >= 2) |
80 | console.error('update capabilities:', caps) |
81 | if (options.onCaps) |
82 | options.onCaps(caps.split(' ')) |
83 | } |
84 | cb(null, { |
85 | old: rev(args[0]), |
86 | new: rev(args[1]), |
87 | name: args2[0] |
88 | }) |
89 | }) |
90 | } |
91 | |
92 | function havesWants(onEnd) { |
93 | return function readWant(abort, cb) { |
94 | readPackLineStr(abort, function (end, line) { |
95 | if (end) return abortCb(cb, end, onEnd) |
96 | if (options.verbosity >= 2) |
97 | console.error('line', line) |
98 | if (line === 'done') return abortCb(cb, true, onEnd) |
99 | if (line.length === 0) return cb(null, {type: 'flush-pkt'}) |
100 | var args = util.split3(line) |
101 | var caps = args[2] |
102 | if (caps) { |
103 | if (options.verbosity >= 2) |
104 | console.error('want capabilities:', caps) |
105 | if (options.onCaps) |
106 | options.onCaps(caps) |
107 | } |
108 | cb(null, { |
109 | type: args[0], |
110 | hash: args[1], |
111 | }) |
112 | }) |
113 | } |
114 | } |
115 | |
116 | b.pktLines = readPackLine |
117 | b.updates = readUpdate |
118 | b.wants = b.haves = havesWants |
119 | |
120 | return b |
121 | } |
122 | |
123 | exports.encode = pktLineEncode |
124 | exports.decode = pktLineDecode |
125 |
Built with git-ssb-web