forked from swank-js/swank-js
-
Notifications
You must be signed in to change notification settings - Fork 4
/
swank-protocol.js
88 lines (77 loc) · 3.11 KB
/
swank-protocol.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// -*- mode: js2; js-run: "swank-protocol-tests.js" -*-
//
// Copyright (c) 2010 Ivan Shvedunov. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var readFromString = require("./lisp").readFromString;
const HEADER_LEN = 6;
const DUMMY_HEADER = "000000";
const MAX_MESSAGE_SIZE = 10 * 1024 * 1024;
function SwankParser (onMessage) {
this.onMessage = onMessage;
this.resetBuffer();
};
// FIXME: proper error handling (handle both packet parsing and reader errors)
SwankParser.prototype.resetBuffer = function resetBuffer (len, handler) {
len = len || HEADER_LEN;
this.needChars = len;
this.handleData = handler || this.handleHeader;
this.stash = new Buffer(len);
this.pos = 0;
};
SwankParser.prototype.execute = function execute (buffer) {
var offset = 0;
while (offset < buffer.length)
offset += this.handleContent(buffer, offset);
};
SwankParser.prototype.handleContent = function handleContent (buffer, offset) {
var newPos = Math.min(this.needChars, this.pos + buffer.length - offset);
var bytesToCopy = newPos - this.pos;
buffer.copy(this.stash, this.pos, offset, offset + bytesToCopy);
this.pos = newPos;
if (this.pos == this.needChars)
this.handleData();
return bytesToCopy; // stashLen + newPos - stashLen
};
SwankParser.prototype.handleHeader = function handleHeader () {
var count = parseInt(this.stash.toString(), 16) || 0;
if (count > 0 && count < MAX_MESSAGE_SIZE)
this.resetBuffer(count, this.handleMessage);
else
this.resetBuffer();
};
SwankParser.prototype.handleMessage = function handleMessage (str) {
this.onMessage(readFromString(this.stash.toString())); // FIXME: handle errors
this.resetBuffer();
};
function buildMessage (obj) {
var str = obj.toString();
var lenStr = "" + Buffer.byteLength(str).toString(16);
while (lenStr.length < HEADER_LEN)
lenStr = "0" + lenStr;
return lenStr + str;
};
exports.SwankParser = SwankParser;
exports.buildMessage = buildMessage;