Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"maxlen" : false, // {int} Max number of characters per line

// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"asi" : true, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : true, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
Expand Down
138 changes: 62 additions & 76 deletions lib/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ function InputStream(buf, withType) {
this.in = ByteBuffer.wrap(buf);
this._refs = [];
this._readHeader();
};
}

InputStream.addObject = function (classname, convertor) {
// convertor must impl `readObject(io, obj, withType)` or `writeObject(io, obj, withType)`
if (typeof convertor.readObject !== 'function' && typeof convertor.writeObject !== 'function') {
throw new Error('Convertor must implement readObject() or writeObject()');
}
objects[classname] = convertor;
};
}

InputStream.read = InputStream.readObject = function (buf, withType) {
return new InputStream(buf, withType)._readContent();
};
}

var proto = InputStream.prototype;

Expand All @@ -51,7 +51,7 @@ proto.read = proto.readObject = proto._readContent = function () {
debug('> _readContent');

var la = this.lookAhead();
if (la === undefined) return;
if (la === undefined) { return }

if (la === cons.TC_BLOCKDATA) {
return this._readBlockDataShort();
Expand All @@ -60,19 +60,19 @@ proto.read = proto.readObject = proto._readContent = function () {
} else {
return this._readObject();
}
};
}

proto._readBlockDataShort = function() {
// blockdatashort:
// TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
throw new Error('Not implement _readBlockDataShort()');
};
}

proto._readBlockDataLong = function() {
// blockdatalong:
// TC_BLOCKDATALONG (int)<size> (byte)[size]
throw new Error('Not implement _readBlockDataLong()');
};
}

proto._readObject = function () {
// object:
Expand Down Expand Up @@ -124,7 +124,7 @@ proto._readObject = function () {
} else {
throw new Error('Illegal lookahead: 0x' + la.toString(16));
}
};
}

proto._readNewObject = function () {
// newObject:
Expand All @@ -141,14 +141,14 @@ proto._readNewObject = function () {
var ret = normalize(obj, this.withType);
debug('<< _readNewObject | obj = %j', ret);
return ret;
};
}


proto._readNewClass = function() {
// newClass:
// TC_CLASS classDesc newHandle
throw new Error('Not implement _readNewClass()');
};
}

proto._readNewArray = function () {
// newArray:
Expand All @@ -165,7 +165,7 @@ proto._readNewArray = function () {

debug('<< _readNewArray | obj = %j', obj);
return this.withType ? obj : obj.$;
};
}

proto._readNewString = function () {
// newString:
Expand All @@ -176,7 +176,7 @@ proto._readNewString = function () {
this._newHandle(str);
debug('< _readNewString | str = %s', str);
return str;
};
}

proto._readNewEnum = function () {
// newEnum:
Expand Down Expand Up @@ -211,7 +211,7 @@ proto._readNewClassDesc = function () {
} else {
throw new Error('Illegal lookahead: 0x' + la.toString(16));
}
};
}


proto._readNonProxyDesc = function() {
Expand Down Expand Up @@ -242,7 +242,7 @@ proto._readPrevObject = function () {
var obj = this._refs[id - cons.baseWireHandle];
debug('< _readRrevObject | id = %d, obj = %j', id, obj);
return obj;
};
}

proto._readNull = function() {
this.in.get();
Expand Down Expand Up @@ -282,12 +282,12 @@ proto._readClassDesc = function () {
} else {
throw new Error('Illegal lookahead: 0x' + la.toString(16));
}
};
}

proto._newHandle = function (o) {
debug('> _newHandle | index = %d, obj = %j', this._refs.length, o);
this._refs.push(o);
};
}

proto._readClassData = function (obj) {
// classdata:
Expand All @@ -306,12 +306,17 @@ proto._readClassData = function (obj) {

if (flags & cons.SC_SERIALIZABLE) {
if (flags & cons.SC_WRITE_METHOD) {
debug('>> _readClassData | production: wrclass objectAnnotation')
//this._readNowrclass(obj);
this._readObjectAnnotation(obj);
debug('>> _readClassData | production: wrclass objectAnnotation');

var name = obj.$class.name;
objects[name].readObject(this, obj);

// TC_ENDBLOCKDATA
assert.equal(this.in.get(), cons.TC_ENDBLOCKDATA,
'SC_WRITE_METHOD object should end with TC_ENDBLOCKDATA');

} else {
debug('>> _readClassData | production: nowrclass')
debug('>> _readClassData | production: nowrclass');
this._readNowrclass(obj);
}
} else if (flags & cons.SC_EXTERNALIZABLE) {
Expand All @@ -320,70 +325,51 @@ proto._readClassData = function (obj) {
this._readObjectAnnotation(obj);

} else {
debug('>> _readClassData | production: externalContents')
debug('>> _readClassData | production: externalContents');
this._readExternalContents();
}
} else {
throw new Error('Illegal _readClassData')
throw new Error('Illegal _readClassData');
}
};
}


proto._readNowrclass = function (obj) {
// nowrclass:
// values // fields in order of class descriptor
debug('> _readNowrclass');
this.defaultReadFields(obj);
};
this._defaultReadFields(obj);
}


proto.defaultReadFields = function(obj) {
debug('> defaultReadFields');
proto._defaultReadFields = function(obj) {
debug('> _defaultReadFields');
var $fields = concatFields(obj.$class);
for (var i = 0; i < $fields.length; i++) {
var field = $fields[i];
var val = this._readFieldValue(field);
obj.$[field.name] = val;
}
}

// try to detect TC_BLOCKDATA
var type = this.in.get(this.in.position());
if (type === cons.TC_BLOCKDATA) {
this.in.skip(1);
var size = this.in.get();
}
};

proto.defaultReadObject = function(obj) {
this._defaultReadFields(obj);
}


proto.readBlockHeader = function(len) {
this.in.skip(2);
}


proto._readObjectAnnotation = function (obj) {
// objectAnnotation:
// endBlockData
// contents endBlockData // contents written by writeObject
// // or writeExternal PROTOCOL_VERSION_2.
debug('> _readObjectAnnotation');
var type = this.in.get(this.in.position());
if (type === cons.TC_BLOCKDATA) {
// TC_BLOCKDATA
this.in.skip(1);

// blockdata:
// blockdatashort
// blockdatalong
// blockdatashort:
// TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
// blockdatalong:
// TC_BLOCKDATALONG (int)<size> (byte)[size]
var size = this.in.get();
debug('TC_BLOCKDATA start, size = %d bytes', size);
}

var name = obj.$class.name;
objects[name].readObject(this, obj);

// TC_ENDBLOCKDATA
assert.equal(this.in.get(), cons.TC_ENDBLOCKDATA,
'SC_WRITE_METHOD object should end with TC_ENDBLOCKDATA');
};
throw new Error('Not implement _readObjectAnnotation()');
}

proto._readExternalContents = function() {
// externalContents: // externalContent written by
Expand All @@ -406,7 +392,7 @@ proto._readArrayItems = function (obj) {

debug('< _readArrayItems | size = %d, arr = %j', size, obj.$);
return obj;
};
}


proto._readFieldValue = function (field) {
Expand Down Expand Up @@ -454,14 +440,14 @@ proto._readFieldValue = function (field) {
default:
throw new Error('Illegal field type: ' + JSON.stringify(field));
}
};
}

proto._readClassDescFlags = function () {
// classDescFlags:
// (byte) // Defined in Terminal Symbols and
// // Constants
return this.readByte();
};
}

proto._readFields = function () {
// fields:
Expand All @@ -474,7 +460,7 @@ proto._readFields = function () {
}
debug('< _readFields | count = %d, fieldsDesc = %j', count, fieldsDesc);
return fieldsDesc;
};
}

proto._readClassAnnotation = function () {
// classAnnotation:
Expand All @@ -486,15 +472,15 @@ proto._readClassAnnotation = function () {
} else {
throw new Error('Illegal type: 0x' + type.toString(16));
}
};
}

proto._readSuperClassDesc = function () {
// superClassDesc:
// classDesc
var superClass = this._readClassDesc();
debug('< _readSuperClassDesc | desc = %j', superClass);
return superClass;
};
}

proto._readClassDescInfo = function () {
// classDescInfo:
Expand All @@ -508,7 +494,7 @@ proto._readClassDescInfo = function () {

debug('< _readClassDescInfo | obj = %j', obj);
return obj
};
}


proto._readFieldDesc = function () {
Expand Down Expand Up @@ -540,7 +526,7 @@ proto._readFieldDesc = function () {

debug('<< _readFieldDesc | desc = %j', desc);
return desc;
};
}

proto._readUTFString = function (isLong) {
// Note that the symbol (utf) is used to designate a string written using 2-byte length information,
Expand All @@ -562,31 +548,31 @@ proto._readHeader = function () {
err.name = 'InvaildStreamHeaderError';
throw err;
}
};
}

proto.lookAhead = function() {
return this.in.get(this.in.position());
};
}

proto.readBytes = function (size) {
return this.in.read(size);
};
}

proto.readInt = function () {
return this.in.getUInt();
};
}

proto.readByte = function () {
return this.in.get();
};
}

proto.readShort = function () {
return this.in.getUInt16();
};
}

proto.readLong = function () {
return this.in.getLong();
};
}


function concatFields(classDesc) {
Expand All @@ -595,16 +581,16 @@ function concatFields(classDesc) {
} else {
return concatFields(classDesc.superClass).concat(classDesc.fields);
}
};
}


function normalize(obj, withType) {
if (withType || !obj || obj.$ === undefined) return obj;
if (withType || !obj || obj.$ === undefined) { return obj }

var $class = obj.$class;
var $fields = concatFields($class);
var isPrimitive = !!($class.name.indexOf('java.lang.') === 0
&& $fields.length === 1
&& $fields[0].name === 'value');
return isPrimitive ? obj.$.value : ('_$' in obj ? obj._$ : obj.$);
};
}
Loading