config/emacs.d/swank-js/swank-protocol.js
2011-06-26 15:55:20 -07:00

87 lines
3 KiB
JavaScript

// -*- 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.needChars = HEADER_LEN;
this.handleData = this.handleHeader;
this.stash = "";
this.onMessage = onMessage;
};
// FIXME: proper error handling (handle both packet parsing and reader errors)
SwankParser.prototype.execute = function execute (text) {
var offset = 0;
while (offset < text.length)
offset += this.handleContent(text, offset);
};
SwankParser.prototype.handleContent = function handleContent (text, offset) {
var stashLen = this.stash.length;
var avail = Math.min(this.needChars, text.length + stashLen - offset);
var message = this.stash + text.substring(offset, offset + avail - stashLen);
if (avail < this.needChars)
this.stash = message;
else {
this.stash = "";
this.handleData(message);
}
return message.length - stashLen;
};
SwankParser.prototype.handleHeader = function handleHeader (str) {
var count = parseInt(str, 16) || 0;
if (count > 0 && count < MAX_MESSAGE_SIZE) {
this.needChars = count;
this.handleData = this.handleMessage;
} else
this.needChars = HEADER_LEN; // FIXME: handle errors
};
SwankParser.prototype.handleMessage = function handleMessage (str) {
this.onMessage(readFromString(str)); // FIXME: handle errors
this.needChars = HEADER_LEN;
this.handleData = this.handleHeader;
};
function buildMessage (obj) {
var str = obj.toString();
var lenStr = "" + str.length.toString(16);
while (lenStr.length < HEADER_LEN)
lenStr = "0" + lenStr;
return lenStr + str;
};
exports.SwankParser = SwankParser;
exports.buildMessage = buildMessage;