diff options
Diffstat (limited to 'js/src/Ice/BasicStream.js')
-rw-r--r-- | js/src/Ice/BasicStream.js | 4957 |
1 files changed, 2479 insertions, 2478 deletions
diff --git a/js/src/Ice/BasicStream.js b/js/src/Ice/BasicStream.js index d0bdb325076..5699993d6af 100644 --- a/js/src/Ice/BasicStream.js +++ b/js/src/Ice/BasicStream.js @@ -7,2955 +7,2956 @@ // // ********************************************************************** -(function(global){ - require("Ice/Class"); - require("Ice/Debug"); - require("Ice/ExUtil"); - require("Ice/FormatType"); - require("Ice/HashMap"); - require("Ice/Object"); - require("Ice/OptionalFormat"); - require("Ice/Protocol"); - require("Ice/TraceUtil"); - require("Ice/Buffer"); - require("Ice/Exception"); - require("Ice/LocalException"); - require("Ice/Version"); - require("Ice/CompactIdRegistry"); - require("Ice/ArrayUtil"); - require("Ice/UnknownSlicedObject"); - - var Ice = global.Ice || {}; - - var Debug = Ice.Debug; - var ExUtil = Ice.ExUtil; - var FormatType = Ice.FormatType; - var HashMap = Ice.HashMap; - var IceObject = Ice.Object; - var OptionalFormat = Ice.OptionalFormat; - var Protocol = Ice.Protocol; - var TraceUtil = Ice.TraceUtil; - var ArrayUtil = Ice.ArrayUtil; - var SlicedData = Ice.SlicedData; - - var SliceType = {}; - SliceType.NoSlice = 0; - SliceType.ObjectSlice = 1; - SliceType.ExceptionSlice = 2; - - var OPTIONAL_END_MARKER = 0xFF; - var FLAG_HAS_TYPE_ID_STRING = (1<<0); - var FLAG_HAS_TYPE_ID_INDEX = (1<<1); - var FLAG_HAS_TYPE_ID_COMPACT = (1<<1 | 1<<0); - var FLAG_HAS_OPTIONAL_MEMBERS = (1<<2); - var FLAG_HAS_INDIRECTION_TABLE = (1<<3); - var FLAG_HAS_SLICE_SIZE = (1<<4); - var FLAG_IS_LAST_SLICE = (1<<5); - - var IndirectPatchEntry = function(index, patcher) - { - this.index = index; - this.patcher = patcher; - }; - - var Class = Ice.Class; - - var EncapsDecoder = Class({ - __init__: function(stream, encaps, sliceObjects, f) - { - this._stream = stream; - this._encaps = encaps; - this._sliceObjects = sliceObjects; - this._servantFactoryManager = f; - this._patchMap = null; // Lazy initialized, HashMap<int, Patcher[] >() - this._unmarshaledMap = new HashMap(); // HashMap<int, Ice.Object>() - this._typeIdMap = null; // Lazy initialized, HashMap<int, String> - this._typeIdIndex = 0; - this._objectList = null; // Lazy initialized. Ice.Object[] - }, - readOpt: function() - { - return false; - }, - readPendingObjects: function() - { - }, - readTypeId: function(isIndex) +var Ice = require("../Ice/ModuleRegistry").Ice; +var __M = Ice.__M; +__M.require(module, "Ice", + [ + "../Ice/Class", + "../Ice/Debug", + "../Ice/ExUtil", + "../Ice/FormatType", + "../Ice/HashMap", + "../Ice/Object", + "../Ice/OptionalFormat", + "../Ice/Protocol", + "../Ice/TraceUtil", + "../Ice/Buffer", + "../Ice/Exception", + "../Ice/LocalException", + "../Ice/Version", + "../Ice/CompactIdRegistry", + "../Ice/ArrayUtil", + "../Ice/UnknownSlicedObject" + ]); + +var Debug = Ice.Debug; +var ExUtil = Ice.ExUtil; +var FormatType = Ice.FormatType; +var HashMap = Ice.HashMap; +var IceObject = Ice.Object; +var OptionalFormat = Ice.OptionalFormat; +var Protocol = Ice.Protocol; +var TraceUtil = Ice.TraceUtil; +var ArrayUtil = Ice.ArrayUtil; +var SlicedData = Ice.SlicedData; + +var SliceType = {}; +SliceType.NoSlice = 0; +SliceType.ObjectSlice = 1; +SliceType.ExceptionSlice = 2; + +var OPTIONAL_END_MARKER = 0xFF; +var FLAG_HAS_TYPE_ID_STRING = (1<<0); +var FLAG_HAS_TYPE_ID_INDEX = (1<<1); +var FLAG_HAS_TYPE_ID_COMPACT = (1<<1 | 1<<0); +var FLAG_HAS_OPTIONAL_MEMBERS = (1<<2); +var FLAG_HAS_INDIRECTION_TABLE = (1<<3); +var FLAG_HAS_SLICE_SIZE = (1<<4); +var FLAG_IS_LAST_SLICE = (1<<5); + +var IndirectPatchEntry = function(index, patcher) +{ + this.index = index; + this.patcher = patcher; +}; + +var Class = Ice.Class; + +var EncapsDecoder = Class({ + __init__: function(stream, encaps, sliceObjects, f) + { + this._stream = stream; + this._encaps = encaps; + this._sliceObjects = sliceObjects; + this._servantFactoryManager = f; + this._patchMap = null; // Lazy initialized, HashMap<int, Patcher[] >() + this._unmarshaledMap = new HashMap(); // HashMap<int, Ice.Object>() + this._typeIdMap = null; // Lazy initialized, HashMap<int, String> + this._typeIdIndex = 0; + this._objectList = null; // Lazy initialized. Ice.Object[] + }, + readOpt: function() + { + return false; + }, + readPendingObjects: function() + { + }, + readTypeId: function(isIndex) + { + var typeId, index; + if(this._typeIdMap === null) // Lazy initialization { - var typeId, index; - if(this._typeIdMap === null) // Lazy initialization - { - this._typeIdMap = new HashMap(); // Map<int, String>(); - } + this._typeIdMap = new HashMap(); // Map<int, String>(); + } - if(isIndex) - { - index = this._stream.readSize(); - typeId = this._typeIdMap.get(index); - if(typeId === undefined) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - } - else + if(isIndex) + { + index = this._stream.readSize(); + typeId = this._typeIdMap.get(index); + if(typeId === undefined) { - typeId = this._stream.readString(); - this._typeIdMap.set(++this._typeIdIndex, typeId); + throw new Ice.UnmarshalOutOfBoundsException(); } - return typeId; - }, - newInstance: function(typeId) + } + else { - // - // Try to find a factory registered for the specific type. - // - var userFactory = this._servantFactoryManager.find(typeId); - var v = null; - + typeId = this._stream.readString(); + this._typeIdMap.set(++this._typeIdIndex, typeId); + } + return typeId; + }, + newInstance: function(typeId) + { + // + // Try to find a factory registered for the specific type. + // + var userFactory = this._servantFactoryManager.find(typeId); + var v = null; + + if(userFactory !== undefined) + { + v = userFactory.create(typeId); + } + + // + // If that fails, invoke the default factory if one has been + // registered. + // + if(v === null || v === undefined) + { + userFactory = this._servantFactoryManager.find(""); if(userFactory !== undefined) { v = userFactory.create(typeId); } - - // - // If that fails, invoke the default factory if one has been - // registered. - // - if(v === null || v === undefined) - { - userFactory = this._servantFactoryManager.find(""); - if(userFactory !== undefined) - { - v = userFactory.create(typeId); - } - } - - // - // Last chance: try to instantiate the class dynamically. - // - if(v === null || v === undefined) - { - v = this._stream.createObject(typeId); - } + } + + // + // Last chance: try to instantiate the class dynamically. + // + if(v === null || v === undefined) + { + v = this._stream.createObject(typeId); + } - return v; - }, - addPatchEntry: function(index, patcher) + return v; + }, + addPatchEntry: function(index, patcher) + { + Debug.assert(index > 0); + // + // Check if already un-marshalled the object. If that's the case, + // just patch the object smart pointer and we're done. + // + var obj = this._unmarshaledMap.get(index); + if(obj !== undefined && obj !== null) { - Debug.assert(index > 0); - // - // Check if already un-marshalled the object. If that's the case, - // just patch the object smart pointer and we're done. - // - var obj = this._unmarshaledMap.get(index); - if(obj !== undefined && obj !== null) - { - patcher.call(null, obj); - return; - } + patcher.call(null, obj); + return; + } - if(this._patchMap === null) // Lazy initialization - { - this._patchMap = new HashMap(); // HashMap<Integer, Patcher[] >(); - } + if(this._patchMap === null) // Lazy initialization + { + this._patchMap = new HashMap(); // HashMap<Integer, Patcher[] >(); + } + // + // Add patch entry if the object isn't un-marshalled yet, + // the smart pointer will be patched when the instance is + // un-marshalled. + // + var l = this._patchMap.get(index); + if(l === undefined) + { // - // Add patch entry if the object isn't un-marshalled yet, - // the smart pointer will be patched when the instance is - // un-marshalled. + // We have no outstanding instances to be patched for this + // index, so make a new entry in the patch map. // - var l = this._patchMap.get(index); - if(l === undefined) - { - // - // We have no outstanding instances to be patched for this - // index, so make a new entry in the patch map. - // - l = []; // Patcher[]; - this._patchMap.set(index, l); - } + l = []; // Patcher[]; + this._patchMap.set(index, l); + } - // - // Append a patch entry for this instance. - // - l.push(patcher); - }, - unmarshal: function(index, v) + // + // Append a patch entry for this instance. + // + l.push(patcher); + }, + unmarshal: function(index, v) + { + var i, length, l; + // + // Add the object to the map of un-marshalled objects, this must + // be done before reading the objects (for circular references). + // + this._unmarshaledMap.set(index, v); + + // + // Read the object. + // + v.__read(this._stream); + if(this._patchMap !== null) { - var i, length, l; // - // Add the object to the map of un-marshalled objects, this must - // be done before reading the objects (for circular references). + // Patch all instances now that the object is un-marshalled. // - this._unmarshaledMap.set(index, v); - - // - // Read the object. - // - v.__read(this._stream); - if(this._patchMap !== null) + l = this._patchMap.get(index); + if(l !== undefined) { + Debug.assert(l.length > 0); // - // Patch all instances now that the object is un-marshalled. + // Patch all pointers that refer to the instance. // - l = this._patchMap.get(index); - if(l !== undefined) - { - Debug.assert(l.length > 0); - // - // Patch all pointers that refer to the instance. - // - for(i = 0, length = l.length; i < length; ++i) - { - l[i](v); - } - // - // Clear out the patch map for that index -- there is nothing left - // to patch for that index for the time being. - // - this._patchMap.delete(index); - } - } - - if((this._patchMap === null || this._patchMap.size === 0) && this._objectList === null) - { - try - { - v.ice_postUnmarshal(); - } - catch(ex) + for(i = 0, length = l.length; i < length; ++i) { - this._stream.instance.initializationData().logger.warning("exception raised by ice_postUnmarshal:\n" + - ExUtil.toString(ex)); - } - } - else - { - if(this._objectList === null) // Lazy initialization - { - this._objectList = []; // Ice.Object[] - } - this._objectList.push(v); - - if(this._patchMap === null || this._patchMap.size === 0) - { - // - // Iterate over the object list and invoke ice_postUnmarshal on - // each object. We must do this after all objects have been - // unmarshaled in order to ensure that any object data members - // have been properly patched. - // - for(i = 0, length = this._objectList.length; i < length; i++) - { - try - { - this._objectList[i].ice_postUnmarshal(); - } - catch(ex) - { - this._stream.instance.initializationData().logger.warning( - "exception raised by ice_postUnmarshal:\n" + ExUtil.toString(ex)); - } - } - this._objectList = []; + l[i](v); } + // + // Clear out the patch map for that index -- there is nothing left + // to patch for that index for the time being. + // + this._patchMap.delete(index); } } - }); - - var EncapsDecoder10 = Class(EncapsDecoder, { - __init__: function(stream, encaps, sliceObjects, f) - { - EncapsDecoder.call(this, stream, encaps, sliceObjects, f); - this._sliceType = SliceType.NoSlice; - }, - readObject: function(patcher) + + if((this._patchMap === null || this._patchMap.size === 0) && this._objectList === null) { - Debug.assert(patcher !== null); - - // - // Object references are encoded as a negative integer in 1.0. - // - var index = this._stream.readInt(); - if(index > 0) + try { - throw new Ice.MarshalException("invalid object id"); + v.ice_postUnmarshal(); } - index = -index; - - if(index === 0) + catch(ex) { - patcher.call(null, null); + this._stream.instance.initializationData().logger.warning("exception raised by ice_postUnmarshal:\n" + + ExUtil.toString(ex)); } - else + } + else + { + if(this._objectList === null) // Lazy initialization { - this.addPatchEntry(index, patcher); + this._objectList = []; // Ice.Object[] } - }, - throwException: function() - { - Debug.assert(this._sliceType === SliceType.NoSlice); - - // - // User exception with the 1.0 encoding start with a boolean flag - // that indicates whether or not the exception has classes. - // - // This allows reading the pending objects even if some part of - // the exception was sliced. - // - var usesClasses = this._stream.readBool(); - this._sliceType = SliceType.ExceptionSlice; - this._skipFirstSlice = false; - - // - // Read the first slice header. - // - this.startSlice(); - var mostDerivedId = this._typeId; - while(true) + this._objectList.push(v); + + if(this._patchMap === null || this._patchMap.size === 0) { - var userEx = this._stream.createUserException(this._typeId); - // - // We found the exception. + // Iterate over the object list and invoke ice_postUnmarshal on + // each object. We must do this after all objects have been + // unmarshaled in order to ensure that any object data members + // have been properly patched. // - if(userEx !== null) + for(i = 0, length = this._objectList.length; i < length; i++) { - userEx.__read(this._stream); - if(usesClasses) + try { - this.readPendingObjects(); + this._objectList[i].ice_postUnmarshal(); } - throw userEx; - - // Never reached. - } - - // - // Slice off what we don't understand. - // - this.skipSlice(); - try - { - this.startSlice(); - } - catch(ex) - { - // - // An oversight in the 1.0 encoding means there is no marker to indicate - // the last slice of an exception. As a result, we just try to read the - // next type ID, which raises UnmarshalOutOfBoundsException when the - // input buffer underflows. - // - // Set the reason member to a more helpful message. - // - if(ex instanceof Ice.UnmarshalOutOfBoundsException) + catch(ex) { - ex.reason = "unknown exception type `" + mostDerivedId + "'"; + this._stream.instance.initializationData().logger.warning( + "exception raised by ice_postUnmarshal:\n" + ExUtil.toString(ex)); } - throw ex; } + this._objectList = []; } - }, - startInstance: function(sliceType) + } + } +}); + +var EncapsDecoder10 = Class(EncapsDecoder, { + __init__: function(stream, encaps, sliceObjects, f) + { + EncapsDecoder.call(this, stream, encaps, sliceObjects, f); + this._sliceType = SliceType.NoSlice; + }, + readObject: function(patcher) + { + Debug.assert(patcher !== null); + + // + // Object references are encoded as a negative integer in 1.0. + // + var index = this._stream.readInt(); + if(index > 0) { - Debug.assert(this._sliceType === sliceType); - this._skipFirstSlice = true; - }, - endInstance: function(/*preserve*/) + throw new Ice.MarshalException("invalid object id"); + } + index = -index; + + if(index === 0) + { + patcher.call(null, null); + } + else { - var sz; + this.addPatchEntry(index, patcher); + } + }, + throwException: function() + { + Debug.assert(this._sliceType === SliceType.NoSlice); + + // + // User exception with the 1.0 encoding start with a boolean flag + // that indicates whether or not the exception has classes. + // + // This allows reading the pending objects even if some part of + // the exception was sliced. + // + var usesClasses = this._stream.readBool(); + this._sliceType = SliceType.ExceptionSlice; + this._skipFirstSlice = false; + + // + // Read the first slice header. + // + this.startSlice(); + var mostDerivedId = this._typeId; + while(true) + { + var userEx = this._stream.createUserException(this._typeId); + // - // Read the Ice::Object slice. + // We found the exception. // - if(this._sliceType === SliceType.ObjectSlice) + if(userEx !== null) { - this.startSlice(); - sz = this._stream.readSize(); // For compatibility with the old AFM. - if(sz !== 0) + userEx.__read(this._stream); + if(usesClasses) { - throw new Ice.MarshalException("invalid Object slice"); + this.readPendingObjects(); } - this.endSlice(); - } + throw userEx; - this._sliceType = SliceType.NoSlice; - return null; - }, - startSlice: function() - { - var isIndex; - // - // If first slice, don't read the header, it was already read in - // readInstance or throwException to find the factory. - // - if(this._skipFirstSlice) - { - this._skipFirstSlice = false; - return this._typeId; + // Never reached. } // - // For objects, first read the type ID boolean which indicates - // whether or not the type ID is encoded as a string or as an - // index. For exceptions, the type ID is always encoded as a - // string. + // Slice off what we don't understand. // - if(this._sliceType === SliceType.ObjectSlice) // For exceptions, the type ID is always encoded as a string + this.skipSlice(); + try { - isIndex = this._stream.readBool(); - this._typeId = this.readTypeId(isIndex); + this.startSlice(); } - else + catch(ex) { - this._typeId = this._stream.readString(); + // + // An oversight in the 1.0 encoding means there is no marker to indicate + // the last slice of an exception. As a result, we just try to read the + // next type ID, which raises UnmarshalOutOfBoundsException when the + // input buffer underflows. + // + // Set the reason member to a more helpful message. + // + if(ex instanceof Ice.UnmarshalOutOfBoundsException) + { + ex.reason = "unknown exception type `" + mostDerivedId + "'"; + } + throw ex; } - - this._sliceSize = this._stream.readInt(); - if(this._sliceSize < 4) + } + }, + startInstance: function(sliceType) + { + Debug.assert(this._sliceType === sliceType); + this._skipFirstSlice = true; + }, + endInstance: function(/*preserve*/) + { + var sz; + // + // Read the Ice::Object slice. + // + if(this._sliceType === SliceType.ObjectSlice) + { + this.startSlice(); + sz = this._stream.readSize(); // For compatibility with the old AFM. + if(sz !== 0) { - throw new Ice.UnmarshalOutOfBoundsException(); + throw new Ice.MarshalException("invalid Object slice"); } + this.endSlice(); + } + this._sliceType = SliceType.NoSlice; + return null; + }, + startSlice: function() + { + var isIndex; + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if(this._skipFirstSlice) + { + this._skipFirstSlice = false; return this._typeId; - }, - endSlice: function() + } + + // + // For objects, first read the type ID boolean which indicates + // whether or not the type ID is encoded as a string or as an + // index. For exceptions, the type ID is always encoded as a + // string. + // + if(this._sliceType === SliceType.ObjectSlice) // For exceptions, the type ID is always encoded as a string { - }, - skipSlice: function() + isIndex = this._stream.readBool(); + this._typeId = this.readTypeId(isIndex); + } + else { - if(this._stream.instance.traceLevels().slicing > 0) - { - var logger = this._stream.instance.initializationData().logger; - if(this._sliceType === SliceType.ObjectSlice) - { - TraceUtil.traceSlicing("object", this._typeId, this._stream.instance.traceLevels().slicingCat, logger); - } - else - { - TraceUtil.traceSlicing("exception", this._typeId, this._stream.instance.traceLevels().slicingCat, logger); - } - } - Debug.assert(this._sliceSize >= 4); - this._stream.skip(this._sliceSize - 4); - }, - readPendingObjects: function() + this._typeId = this._stream.readString(); + } + + this._sliceSize = this._stream.readInt(); + if(this._sliceSize < 4) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + + return this._typeId; + }, + endSlice: function() + { + }, + skipSlice: function() + { + if(this._stream.instance.traceLevels().slicing > 0) { - var k, num; - do + var logger = this._stream.instance.initializationData().logger; + if(this._sliceType === SliceType.ObjectSlice) { - num = this._stream.readSize(); - for(k = num; k > 0; --k) - { - this.readInstance(); - } + TraceUtil.traceSlicing("object", this._typeId, this._stream.instance.traceLevels().slicingCat, logger); } - while(num > 0); - - if(this._patchMap !== null && this._patchMap.size !== 0) + else { - // - // If any entries remain in the patch map, the sender has sent an index for an object, but failed - // to supply the object. - // - throw new Ice.MarshalException("index for class received, but no instance"); + TraceUtil.traceSlicing("exception", this._typeId, this._stream.instance.traceLevels().slicingCat, logger); } - }, - readInstance: function() + } + Debug.assert(this._sliceSize >= 4); + this._stream.skip(this._sliceSize - 4); + }, + readPendingObjects: function() + { + var k, num; + do { - var index = this._stream.readInt(), - mostDerivedId, - v = null; - - if(index <= 0) + num = this._stream.readSize(); + for(k = num; k > 0; --k) { - throw new Ice.MarshalException("invalid object id"); + this.readInstance(); } + } + while(num > 0); - this._sliceType = SliceType.ObjectSlice; - this._skipFirstSlice = false; + if(this._patchMap !== null && this._patchMap.size !== 0) + { + // + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. + // + throw new Ice.MarshalException("index for class received, but no instance"); + } + }, + readInstance: function() + { + var index = this._stream.readInt(), + mostDerivedId, + v = null; + + if(index <= 0) + { + throw new Ice.MarshalException("invalid object id"); + } + + this._sliceType = SliceType.ObjectSlice; + this._skipFirstSlice = false; + // + // Read the first slice header. + // + this.startSlice(); + mostDerivedId = this._typeId; + while(true) + { // - // Read the first slice header. + // For the 1.0 encoding, the type ID for the base Object class + // marks the last slice. // - this.startSlice(); - mostDerivedId = this._typeId; - while(true) + if(this._typeId == IceObject.ice_staticId()) { - // - // For the 1.0 encoding, the type ID for the base Object class - // marks the last slice. - // - if(this._typeId == IceObject.ice_staticId()) - { - throw new Ice.NoObjectFactoryException("", mostDerivedId); - } + throw new Ice.NoObjectFactoryException("", mostDerivedId); + } - v = this.newInstance(this._typeId); + v = this.newInstance(this._typeId); - // - // We found a factory, we get out of this loop. - // - if(v) - { - break; - } - - // - // If object slicing is disabled, stop un-marshalling. - // - if(!this._sliceObjects) - { - throw new Ice.NoObjectFactoryException("object slicing is disabled", this._typeId); - } + // + // We found a factory, we get out of this loop. + // + if(v) + { + break; + } - // - // Slice off what we don't understand. - // - this.skipSlice(); - this.startSlice(); // Read next Slice header for next iteration. + // + // If object slicing is disabled, stop un-marshalling. + // + if(!this._sliceObjects) + { + throw new Ice.NoObjectFactoryException("object slicing is disabled", this._typeId); } // - // Un-marshal the object and add-it to the map of un-marshaled objects. + // Slice off what we don't understand. // - this.unmarshal(index, v); + this.skipSlice(); + this.startSlice(); // Read next Slice header for next iteration. } - }); - var EncapsDecoder11 = Class(EncapsDecoder, { - __init__: function(stream, encaps, sliceObjects, f) + // + // Un-marshal the object and add-it to the map of un-marshaled objects. + // + this.unmarshal(index, v); + } +}); + +var EncapsDecoder11 = Class(EncapsDecoder, { + __init__: function(stream, encaps, sliceObjects, f) + { + EncapsDecoder.call(this, stream, encaps, sliceObjects, f); + this._current = null; + this._objectIdIndex = 1; + }, + readObject: function(patcher) + { + Debug.assert(patcher !== undefined); + var index = this._stream.readSize(); + + if(index < 0) { - EncapsDecoder.call(this, stream, encaps, sliceObjects, f); - this._current = null; - this._objectIdIndex = 1; - }, - readObject: function(patcher) + throw new Ice.MarshalException("invalid object id"); + } + + if(index === 0) { - Debug.assert(patcher !== undefined); - var index = this._stream.readSize(); - - if(index < 0) - { - throw new Ice.MarshalException("invalid object id"); - } - - if(index === 0) + if(patcher !== null) { - if(patcher !== null) - { - patcher.call(null, null); - } + patcher.call(null, null); } - else if(this._current !== null && (this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) + } + else if(this._current !== null && (this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) + { + // + // When reading an object within a slice and there's an + // indirect object table, always read an indirect reference + // that points to an object from the indirect object table + // marshaled at the end of the Slice. + // + // Maintain a list of indirect references. Note that the + // indirect index starts at 1, so we decrement it by one to + // derive an index into the indirection table that we'll read + // at the end of the slice. + // + if(patcher !== null) { - // - // When reading an object within a slice and there's an - // indirect object table, always read an indirect reference - // that points to an object from the indirect object table - // marshaled at the end of the Slice. - // - // Maintain a list of indirect references. Note that the - // indirect index starts at 1, so we decrement it by one to - // derive an index into the indirection table that we'll read - // at the end of the slice. - // - if(patcher !== null) + if(this._current.indirectPatchList === null) // Lazy initialization { - if(this._current.indirectPatchList === null) // Lazy initialization - { - this._current.indirectPatchList = []; // IndirectPatchEntry[] - } - var e = new IndirectPatchEntry(); - e.index = index - 1; - e.patcher = patcher; - this._current.indirectPatchList.push(e); + this._current.indirectPatchList = []; // IndirectPatchEntry[] } + var e = new IndirectPatchEntry(); + e.index = index - 1; + e.patcher = patcher; + this._current.indirectPatchList.push(e); } - else - { - this.readInstance(index, patcher); - } - }, - throwException: function() + } + else { - Debug.assert(this._current === null); - this.push(SliceType.ExceptionSlice); + this.readInstance(index, patcher); + } + }, + throwException: function() + { + Debug.assert(this._current === null); + this.push(SliceType.ExceptionSlice); + + // + // Read the first slice header. + // + this.startSlice(); + var mostDerivedId = this._current.typeId; + while(true) + { + + var userEx = this._stream.createUserException(this._current.typeId); // - // Read the first slice header. + // We found the exception. // - this.startSlice(); - var mostDerivedId = this._current.typeId; - while(true) + if(userEx !== null) { - - var userEx = this._stream.createUserException(this._current.typeId); - - // - // We found the exception. - // - if(userEx !== null) - { - userEx.__read(this._stream); - throw userEx; + userEx.__read(this._stream); + throw userEx; - // Never reached. - } + // Never reached. + } - // - // Slice off what we don't understand. - // - this.skipSlice(); + // + // Slice off what we don't understand. + // + this.skipSlice(); - if((this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0) + if((this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0) + { + if(mostDerivedId.indexOf("::") === 0) { - if(mostDerivedId.indexOf("::") === 0) - { - throw new Ice.UnknownUserException(mostDerivedId.substr(2)); - } - throw new Ice.UnknownUserException(mostDerivedId); + throw new Ice.UnknownUserException(mostDerivedId.substr(2)); } - - this.startSlice(); + throw new Ice.UnknownUserException(mostDerivedId); } - }, - startInstance: function(sliceType) + + this.startSlice(); + } + }, + startInstance: function(sliceType) + { + Debug.assert(sliceType !== undefined); + Debug.assert(this._current.sliceType !== null && this._current.sliceType === sliceType); + this._current.skipFirstSlice = true; + }, + endInstance: function(preserve) + { + var slicedData = null; + if(preserve) { - Debug.assert(sliceType !== undefined); - Debug.assert(this._current.sliceType !== null && this._current.sliceType === sliceType); - this._current.skipFirstSlice = true; - }, - endInstance: function(preserve) + slicedData = this.readSlicedData(); + } + if(this._current.slices !== null) { - var slicedData = null; - if(preserve) - { - slicedData = this.readSlicedData(); - } - if(this._current.slices !== null) - { - this._current.slices.length = 0; // Clear the array. - this._current.indirectionTables.length = 0; // Clear the array. - } - this._current = this._current.previous; - return slicedData; - }, - startSlice: function() + this._current.slices.length = 0; // Clear the array. + this._current.indirectionTables.length = 0; // Clear the array. + } + this._current = this._current.previous; + return slicedData; + }, + startSlice: function() + { + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if(this._current.skipFirstSlice) { - // - // If first slice, don't read the header, it was already read in - // readInstance or throwException to find the factory. - // - if(this._current.skipFirstSlice) - { - this._current.skipFirstSlice = false; - return this._current.typeId; - } + this._current.skipFirstSlice = false; + return this._current.typeId; + } - this._current.sliceFlags = this._stream.readByte(); + this._current.sliceFlags = this._stream.readByte(); - // - // Read the type ID, for object slices the type ID is encoded as a - // string or as an index, for exceptions it's always encoded as a - // string. - // - if(this._current.sliceType === SliceType.ObjectSlice) + // + // Read the type ID, for object slices the type ID is encoded as a + // string or as an index, for exceptions it's always encoded as a + // string. + // + if(this._current.sliceType === SliceType.ObjectSlice) + { + if((this._current.sliceFlags & FLAG_HAS_TYPE_ID_COMPACT) === FLAG_HAS_TYPE_ID_COMPACT) // Must be checked 1st! { - if((this._current.sliceFlags & FLAG_HAS_TYPE_ID_COMPACT) === FLAG_HAS_TYPE_ID_COMPACT) // Must be checked 1st! - { - this._current.typeId = ""; - this._current.compactId = this._stream.readSize(); - } - else if((this._current.sliceFlags & (FLAG_HAS_TYPE_ID_INDEX | FLAG_HAS_TYPE_ID_STRING)) !== 0) - { - this._current.typeId = this.readTypeId((this._current.sliceFlags & FLAG_HAS_TYPE_ID_INDEX) !== 0); - this._current.compactId = -1; - } - else - { - // Only the most derived slice encodes the type ID for the compact format. - this._current.typeId = ""; - this._current.compactId = -1; - } + this._current.typeId = ""; + this._current.compactId = this._stream.readSize(); + } + else if((this._current.sliceFlags & (FLAG_HAS_TYPE_ID_INDEX | FLAG_HAS_TYPE_ID_STRING)) !== 0) + { + this._current.typeId = this.readTypeId((this._current.sliceFlags & FLAG_HAS_TYPE_ID_INDEX) !== 0); + this._current.compactId = -1; } else { - this._current.typeId = this._stream.readString(); + // Only the most derived slice encodes the type ID for the compact format. + this._current.typeId = ""; this._current.compactId = -1; } + } + else + { + this._current.typeId = this._stream.readString(); + this._current.compactId = -1; + } + + // + // Read the slice size if necessary. + // + if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + { + this._current.sliceSize = this._stream.readInt(); + if(this._current.sliceSize < 4) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + } + else + { + this._current.sliceSize = 0; + } + return this._current.typeId; + }, + endSlice: function() + { + var e, + i, + indirectionTable = [], + length; + + if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) + { + this._stream.skipOpts(); + } + // + // Read the indirection table if one is present and transform the + // indirect patch list into patch entries with direct references. + // + if((this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) + { // - // Read the slice size if necessary. + // The table is written as a sequence<size> to conserve space. // - if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + length = this._stream.readAndCheckSeqSize(1); + for(i = 0; i < length; ++i) { - this._current.sliceSize = this._stream.readInt(); - if(this._current.sliceSize < 4) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + indirectionTable[i] = this.readInstance(this._stream.readSize(), null); } - else + + // + // Sanity checks. If there are optional members, it's possible + // that not all object references were read if they are from + // unknown optional data members. + // + if(indirectionTable.length === 0) { - this._current.sliceSize = 0; + throw new Ice.MarshalException("empty indirection table"); } - return this._current.typeId; - }, - endSlice: function() - { - var e, - i, - indirectionTable = [], - length; - - if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) + if((this._current.indirectPatchList === null || this._current.indirectPatchList.length === 0) && + (this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) === 0) { - this._stream.skipOpts(); + throw new Ice.MarshalException("no references to indirection table"); } // - // Read the indirection table if one is present and transform the - // indirect patch list into patch entries with direct references. + // Convert indirect references into direct references. // - if((this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) + if(this._current.indirectPatchList !== null) { - // - // The table is written as a sequence<size> to conserve space. - // - length = this._stream.readAndCheckSeqSize(1); - for(i = 0; i < length; ++i) - { - indirectionTable[i] = this.readInstance(this._stream.readSize(), null); - } - - // - // Sanity checks. If there are optional members, it's possible - // that not all object references were read if they are from - // unknown optional data members. - // - if(indirectionTable.length === 0) + for(i = 0, length = this._current.indirectPatchList.length; i < length; ++i) { - throw new Ice.MarshalException("empty indirection table"); - } - if((this._current.indirectPatchList === null || this._current.indirectPatchList.length === 0) && - (this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) === 0) - { - throw new Ice.MarshalException("no references to indirection table"); - } - - // - // Convert indirect references into direct references. - // - if(this._current.indirectPatchList !== null) - { - for(i = 0, length = this._current.indirectPatchList.length; i < length; ++i) + e = this._current.indirectPatchList[i]; + Debug.assert(e.index >= 0); + if(e.index >= indirectionTable.length) { - e = this._current.indirectPatchList[i]; - Debug.assert(e.index >= 0); - if(e.index >= indirectionTable.length) - { - throw new Ice.MarshalException("indirection out of range"); - } - this.addPatchEntry(indirectionTable[e.index], e.patcher); + throw new Ice.MarshalException("indirection out of range"); } - this._current.indirectPatchList.length = 0; + this.addPatchEntry(indirectionTable[e.index], e.patcher); } + this._current.indirectPatchList.length = 0; } - }, - skipSlice: function() + } + }, + skipSlice: function() + { + if(this._stream.instance.traceLevels().slicing > 0) { - if(this._stream.instance.traceLevels().slicing > 0) - { - var logger = this._stream.instance.initializationData().logger; - var slicingCat = this._stream.instance.traceLevels().slicingCat; - if(this._current.sliceType === SliceType.ExceptionSlice) - { - TraceUtil.traceSlicing("exception", this._current.typeId, slicingCat, logger); - } - else - { - TraceUtil.traceSlicing("object", this._current.typeId, slicingCat, logger); - } - } - - var start = this._stream.pos; - - if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + var logger = this._stream.instance.initializationData().logger; + var slicingCat = this._stream.instance.traceLevels().slicingCat; + if(this._current.sliceType === SliceType.ExceptionSlice) { - Debug.assert(this._current.sliceSize >= 4); - this._stream.skip(this._current.sliceSize - 4); + TraceUtil.traceSlicing("exception", this._current.typeId, slicingCat, logger); } else { - if(this._current.sliceType === SliceType.ObjectSlice) - { - throw new Ice.NoObjectFactoryException( - "compact format prevents slicing (the sender should use the sliced format instead)", - this._current.typeId); - } - - if(this._current.typeId.indexOf("::") === 0) - { - throw new Ice.UnknownUserException(this._current.typeId.substring(2)); - } - - throw new Ice.UnknownUserException(this._current.typeId); + TraceUtil.traceSlicing("object", this._current.typeId, slicingCat, logger); } + } - // - // Preserve this slice. - // - var info = new Ice.SliceInfo(); - info.typeId = this._current.typeId; - info.compactId = this._current.compactId; - info.hasOptionalMembers = (this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0; - info.isLastSlice = (this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0; - - var b = this._stream._buf; - var end = b.position; - var dataEnd = end; - if(info.hasOptionalMembers) + var start = this._stream.pos; + + if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + { + Debug.assert(this._current.sliceSize >= 4); + this._stream.skip(this._current.sliceSize - 4); + } + else + { + if(this._current.sliceType === SliceType.ObjectSlice) { - // - // Don't include the optional member end marker. It will be re-written by - // endSlice when the sliced data is re-written. - // - --dataEnd; + throw new Ice.NoObjectFactoryException( + "compact format prevents slicing (the sender should use the sliced format instead)", + this._current.typeId); } - b.position = start; - info.bytes = b.getArray(dataEnd - start); - b.position = end; - - if(this._current.slices === null) // Lazy initialization + if(this._current.typeId.indexOf("::") === 0) { - this._current.slices = []; // Ice.SliceInfo[] - this._current.indirectionTables = []; // int[] + throw new Ice.UnknownUserException(this._current.typeId.substring(2)); } + throw new Ice.UnknownUserException(this._current.typeId); + } + + // + // Preserve this slice. + // + var info = new Ice.SliceInfo(); + info.typeId = this._current.typeId; + info.compactId = this._current.compactId; + info.hasOptionalMembers = (this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0; + info.isLastSlice = (this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0; + + var b = this._stream._buf; + var end = b.position; + var dataEnd = end; + if(info.hasOptionalMembers) + { // - // Read the indirect object table. We read the instances or their - // IDs if the instance is a reference to an already un-marhsaled - // object. - // - // The SliceInfo object sequence is initialized only if - // readSlicedData is called. + // Don't include the optional member end marker. It will be re-written by + // endSlice when the sliced data is re-written. // + --dataEnd; + } + + b.position = start; + info.bytes = b.getArray(dataEnd - start); + b.position = end; - if((this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) - { - var length = this._stream.readAndCheckSeqSize(1); - var indirectionTable = []; - for(var i = 0; i < length; ++i) - { - indirectionTable[i] = this.readInstance(this._stream.readSize(), null); - } - this._current.indirectionTables.push(indirectionTable); - } - else - { - this._current.indirectionTables.push(null); - } - this._current.slices.push(info); - }, - readOpt: function(readTag, expectedFormat) + if(this._current.slices === null) // Lazy initialization { - if(this._current === null) - { - return this._stream.readOptImpl(readTag, expectedFormat); - } - - if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) + this._current.slices = []; // Ice.SliceInfo[] + this._current.indirectionTables = []; // int[] + } + + // + // Read the indirect object table. We read the instances or their + // IDs if the instance is a reference to an already un-marhsaled + // object. + // + // The SliceInfo object sequence is initialized only if + // readSlicedData is called. + // + + if((this._current.sliceFlags & FLAG_HAS_INDIRECTION_TABLE) !== 0) + { + var length = this._stream.readAndCheckSeqSize(1); + var indirectionTable = []; + for(var i = 0; i < length; ++i) { - return this._stream.readOptImpl(readTag, expectedFormat); + indirectionTable[i] = this.readInstance(this._stream.readSize(), null); } - return false; - }, - readInstance: function(index, patcher) + this._current.indirectionTables.push(indirectionTable); + } + else { - Debug.assert(index > 0); - - var mostDerivedId, - v = null; - - if(index > 1) + this._current.indirectionTables.push(null); + } + this._current.slices.push(info); + }, + readOpt: function(readTag, expectedFormat) + { + if(this._current === null) + { + return this._stream.readOptImpl(readTag, expectedFormat); + } + + if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) + { + return this._stream.readOptImpl(readTag, expectedFormat); + } + return false; + }, + readInstance: function(index, patcher) + { + Debug.assert(index > 0); + + var mostDerivedId, + v = null; + + if(index > 1) + { + if(patcher !== null) { - if(patcher !== null) - { - this.addPatchEntry(index, patcher); - } - return index; + this.addPatchEntry(index, patcher); } + return index; + } - this.push(SliceType.ObjectSlice); + this.push(SliceType.ObjectSlice); - // - // Get the object ID before we start reading slices. If some - // slices are skiped, the indirect object table are still read and - // might read other objects. - // - index = ++this._objectIdIndex; + // + // Get the object ID before we start reading slices. If some + // slices are skiped, the indirect object table are still read and + // might read other objects. + // + index = ++this._objectIdIndex; - // - // Read the first slice header. - // - this.startSlice(); - mostDerivedId = this._current.typeId; - while(true) + // + // Read the first slice header. + // + this.startSlice(); + mostDerivedId = this._current.typeId; + while(true) + { + if(this._current.compactId >= 0) { - if(this._current.compactId >= 0) - { - // - // Translate a compact (numeric) type ID into a string type ID. - // - this._current.typeId = ""; - if(this._current.typeId.length === 0) - { - this._current.typeId = this._stream.getTypeId(this._current.compactId); - } - } - - if(this._current.typeId.length > 0) - { - v = this.newInstance(this._current.typeId); - // - // We found a factory, we get out of this loop. - // - if(v !== null && v !== undefined) - { - break; - } - } - // - // If object slicing is disabled, stop un-marshalling. + // Translate a compact (numeric) type ID into a string type ID. // - if(!this._sliceObjects) + this._current.typeId = ""; + if(this._current.typeId.length === 0) { - throw new Ice.NoObjectFactoryException("object slicing is disabled", this._current.typeId); + this._current.typeId = this._stream.getTypeId(this._current.compactId); } - - // - // Slice off what we don't understand. - // - this.skipSlice(); + } + + if(this._current.typeId.length > 0) + { + v = this.newInstance(this._current.typeId); // - // If this is the last slice, keep the object as an opaque - // UnknownSlicedData object. + // We found a factory, we get out of this loop. // - if((this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0) + if(v !== null && v !== undefined) { - v = new Ice.UnknownSlicedObject(mostDerivedId); break; } - - this.startSlice(); // Read next Slice header for next iteration. } // - // Un-marshal the object + // If object slicing is disabled, stop un-marshalling. // - this.unmarshal(index, v); - if(this._current === null && this._patchMap !== null && this._patchMap.size !== 0) + if(!this._sliceObjects) { - // - // If any entries remain in the patch map, the sender has sent an index for an object, but failed - // to supply the object. - // - throw new Ice.MarshalException("index for class received, but no instance"); + throw new Ice.NoObjectFactoryException("object slicing is disabled", this._current.typeId); } - if(patcher !== null) + // + // Slice off what we don't understand. + // + this.skipSlice(); + // + // If this is the last slice, keep the object as an opaque + // UnknownSlicedData object. + // + if((this._current.sliceFlags & FLAG_IS_LAST_SLICE) !== 0) { - patcher.call(null, v); + v = new Ice.UnknownSlicedObject(mostDerivedId); + break; } - return index; - }, - readSlicedData: function() + + this.startSlice(); // Read next Slice header for next iteration. + } + + // + // Un-marshal the object + // + this.unmarshal(index, v); + if(this._current === null && this._patchMap !== null && this._patchMap.size !== 0) { - var i, ii, table, info, j, jj; - - if(this._current.slices === null) // No preserved slices. - { - return null; - } // - // The _indirectionTables member holds the indirection table for each slice - // in _slices. + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. // - Debug.assert(this._current.slices.length === this._current.indirectionTables.length); - for(i = 0, ii = this._current.slices.length; i < ii; ++i) - { - // - // We use the "objects" list in SliceInfo to hold references - // to the target objects. Note that the objects might not have - // been read yet in the case of a circular reference to an - // enclosing object. - // - table = this._current.indirectionTables[i]; - info = this._current.slices[i]; - info.objects = []; - jj = table ? table.length : 0; - for(j = 0; j < jj; ++j) - { - this.addPatchEntry(table[j], sequencePatcher(info.objects, j, IceObject)); - } - } - return new SlicedData(ArrayUtil.clone(this._current.slices)); - }, - push: function(sliceType) + throw new Ice.MarshalException("index for class received, but no instance"); + } + + if(patcher !== null) { - if(this._current === null) - { - this._current = new EncapsDecoder11.InstanceData(null); - } - else + patcher.call(null, v); + } + return index; + }, + readSlicedData: function() + { + var i, ii, table, info, j, jj; + + if(this._current.slices === null) // No preserved slices. + { + return null; + } + // + // The _indirectionTables member holds the indirection table for each slice + // in _slices. + // + Debug.assert(this._current.slices.length === this._current.indirectionTables.length); + for(i = 0, ii = this._current.slices.length; i < ii; ++i) + { + // + // We use the "objects" list in SliceInfo to hold references + // to the target objects. Note that the objects might not have + // been read yet in the case of a circular reference to an + // enclosing object. + // + table = this._current.indirectionTables[i]; + info = this._current.slices[i]; + info.objects = []; + jj = table ? table.length : 0; + for(j = 0; j < jj; ++j) { - this._current = !this._current.next ? new EncapsDecoder11.InstanceData(this._current) : this._current.next; + this.addPatchEntry(table[j], sequencePatcher(info.objects, j, IceObject)); } - this._current.sliceType = sliceType; - this._current.skipFirstSlice = false; } - }); - - EncapsDecoder11.InstanceData = function(previous) + return new SlicedData(ArrayUtil.clone(this._current.slices)); + }, + push: function(sliceType) { - if(previous !== null) + if(this._current === null) { - previous.next = this; + this._current = new EncapsDecoder11.InstanceData(null); } - this.previous = previous; - this.next = null; + else + { + this._current = !this._current.next ? new EncapsDecoder11.InstanceData(this._current) : this._current.next; + } + this._current.sliceType = sliceType; + this._current.skipFirstSlice = false; + } +}); + +EncapsDecoder11.InstanceData = function(previous) +{ + if(previous !== null) + { + previous.next = this; + } + this.previous = previous; + this.next = null; - // Instance attributes - this.sliceType = null; - this.skipFirstSlice = false; - this.slices = null; // Preserved slices. Ice.SliceInfo[] - this.indirectionTables = null; // int[] - - // Slice attributes - this.sliceFlags = 0; - this.sliceSize = 0; - this.typeId = null; - this.compactId = 0; - this.indirectPatchList = null; // Lazy initialized, IndirectPatchEntry[] - }; + // Instance attributes + this.sliceType = null; + this.skipFirstSlice = false; + this.slices = null; // Preserved slices. Ice.SliceInfo[] + this.indirectionTables = null; // int[] - var sequencePatcher = function(seq, index, T){ - return function(v) - { - if(v !== null && !(v instanceof T)) - { - ExUtil.throwUOE(T.ice_staticId(), v); - } - seq[index] = v; - }; - }; + // Slice attributes + this.sliceFlags = 0; + this.sliceSize = 0; + this.typeId = null; + this.compactId = 0; + this.indirectPatchList = null; // Lazy initialized, IndirectPatchEntry[] +}; - var EncapsEncoder = Class({ - __init__: function(stream, encaps) - { - this._stream = stream; - this._encaps = encaps; - this._marshaledMap = new HashMap(); // HashMap<Ice.Object, int>; - this._typeIdMap = null; // Lazy initialized. HashMap<String, int> - this._typeIdIndex = 0; - }, - writeOpt: function() - { - return false; - }, - writePendingObjects: function() +var sequencePatcher = function(seq, index, T){ + return function(v) { - return undefined; - }, - registerTypeId: function(typeId) - { - if(this._typeIdMap === null) // Lazy initialization + if(v !== null && !(v instanceof T)) { - this._typeIdMap = new HashMap(); // HashMap<String, int> + ExUtil.throwUOE(T.ice_staticId(), v); } + seq[index] = v; + }; +}; - var p = this._typeIdMap.get(typeId); - if(p !== undefined) - { - return p; - } - this._typeIdMap.set(typeId, ++this._typeIdIndex); - return -1; +var EncapsEncoder = Class({ + __init__: function(stream, encaps) + { + this._stream = stream; + this._encaps = encaps; + this._marshaledMap = new HashMap(); // HashMap<Ice.Object, int>; + this._typeIdMap = null; // Lazy initialized. HashMap<String, int> + this._typeIdIndex = 0; + }, + writeOpt: function() + { + return false; + }, + writePendingObjects: function() + { + return undefined; + }, + registerTypeId: function(typeId) + { + if(this._typeIdMap === null) // Lazy initialization + { + this._typeIdMap = new HashMap(); // HashMap<String, int> } - }); - - var EncapsEncoder10 = Class(EncapsEncoder, { - __init__: function(stream, encaps) - { - EncapsEncoder.call(this, stream, encaps); - // Instance attributes - this._sliceType = SliceType.NoSlice; - this._writeSlice = 0; // Position of the slice data members - // Encapsulation attributes for object marshalling. - this._objectIdIndex = 0; - this._toBeMarshaledMap = new HashMap(); // HashMap<Ice.Object, Integer>(); - }, - writeObject: function(v) - { - Debug.assert(v !== undefined); - // - // Object references are encoded as a negative integer in 1.0. - // - if(v !== null) - { - this._stream.writeInt(-this.registerObject(v)); - } - else - { - this._stream.writeInt(0); - } - }, - writeUserException: function(v) + + var p = this._typeIdMap.get(typeId); + if(p !== undefined) { - Debug.assert(v !== null && v !== undefined); - // - // User exception with the 1.0 encoding start with a boolean - // flag that indicates whether or not the exception uses - // classes. - // - // This allows reading the pending objects even if some part of - // the exception was sliced. - // - var usesClasses = v.__usesClasses(); - this._stream.writeBool(usesClasses); - v.__write(this._stream); - if(usesClasses) - { - this.writePendingObjects(); - } - }, - startInstance: function(sliceType) + return p; + } + this._typeIdMap.set(typeId, ++this._typeIdIndex); + return -1; + } +}); + +var EncapsEncoder10 = Class(EncapsEncoder, { + __init__: function(stream, encaps) + { + EncapsEncoder.call(this, stream, encaps); + // Instance attributes + this._sliceType = SliceType.NoSlice; + this._writeSlice = 0; // Position of the slice data members + // Encapsulation attributes for object marshalling. + this._objectIdIndex = 0; + this._toBeMarshaledMap = new HashMap(); // HashMap<Ice.Object, Integer>(); + }, + writeObject: function(v) + { + Debug.assert(v !== undefined); + // + // Object references are encoded as a negative integer in 1.0. + // + if(v !== null) { - this._sliceType = sliceType; - }, - endInstance: function() + this._stream.writeInt(-this.registerObject(v)); + } + else { - if(this._sliceType === SliceType.ObjectSlice) - { - // - // Write the Object slice. - // - this.startSlice(IceObject.ice_staticId(), -1, true); - this._stream.writeSize(0); // For compatibility with the old AFM. - this.endSlice(); - } - this._sliceType = SliceType.NoSlice; - }, - startSlice: function(typeId) + this._stream.writeInt(0); + } + }, + writeUserException: function(v) + { + Debug.assert(v !== null && v !== undefined); + // + // User exception with the 1.0 encoding start with a boolean + // flag that indicates whether or not the exception uses + // classes. + // + // This allows reading the pending objects even if some part of + // the exception was sliced. + // + var usesClasses = v.__usesClasses(); + this._stream.writeBool(usesClasses); + v.__write(this._stream); + if(usesClasses) + { + this.writePendingObjects(); + } + }, + startInstance: function(sliceType) + { + this._sliceType = sliceType; + }, + endInstance: function() + { + if(this._sliceType === SliceType.ObjectSlice) { // - // For object slices, encode a boolean to indicate how the type ID - // is encoded and the type ID either as a string or index. For - // exception slices, always encode the type ID as a string. + // Write the Object slice. // - if(this._sliceType === SliceType.ObjectSlice) + this.startSlice(IceObject.ice_staticId(), -1, true); + this._stream.writeSize(0); // For compatibility with the old AFM. + this.endSlice(); + } + this._sliceType = SliceType.NoSlice; + }, + startSlice: function(typeId) + { + // + // For object slices, encode a boolean to indicate how the type ID + // is encoded and the type ID either as a string or index. For + // exception slices, always encode the type ID as a string. + // + if(this._sliceType === SliceType.ObjectSlice) + { + var index = this.registerTypeId(typeId); + if(index < 0) { - var index = this.registerTypeId(typeId); - if(index < 0) - { - this._stream.writeBool(false); - this._stream.writeString(typeId); - } - else - { - this._stream.writeBool(true); - this._stream.writeSize(index); - } + this._stream.writeBool(false); + this._stream.writeString(typeId); } else { - this._stream.writeString(typeId); + this._stream.writeBool(true); + this._stream.writeSize(index); } + } + else + { + this._stream.writeString(typeId); + } - this._stream.writeInt(0); // Placeholder for the slice length. + this._stream.writeInt(0); // Placeholder for the slice length. - this._writeSlice = this._stream.pos; - }, - endSlice: function() - { - // - // Write the slice length. - // - var sz = this._stream.pos - this._writeSlice + 4; - this._stream.rewriteInt(sz, this._writeSlice - 4); - }, - writePendingObjects: function() - { - var self = this, - writeCB = function(key, value) + this._writeSlice = this._stream.pos; + }, + endSlice: function() + { + // + // Write the slice length. + // + var sz = this._stream.pos - this._writeSlice + 4; + this._stream.rewriteInt(sz, this._writeSlice - 4); + }, + writePendingObjects: function() + { + var self = this, + writeCB = function(key, value) + { + // + // Ask the instance to marshal itself. Any new class + // instances that are triggered by the classes marshaled + // are added to toBeMarshaledMap. + // + self._stream.writeInt(value); + + try { - // - // Ask the instance to marshal itself. Any new class - // instances that are triggered by the classes marshaled - // are added to toBeMarshaledMap. - // - self._stream.writeInt(value); - - try - { - key.ice_preMarshal(); - } - catch(ex) - { - self._stream.instance.initializationData().logger.warning( - "exception raised by ice_preMarshal:\n" + ExUtil.toString(ex)); - } - - key.__write(self._stream); - }, - savedMap; - - while(this._toBeMarshaledMap.size > 0) - { - // - // Consider the to be marshalled objects as marshalled now, - // this is necessary to avoid adding again the "to be - // marshalled objects" into _toBeMarshaledMap while writing - // objects. - // - this._marshaledMap.merge(this._toBeMarshaledMap); + key.ice_preMarshal(); + } + catch(ex) + { + self._stream.instance.initializationData().logger.warning( + "exception raised by ice_preMarshal:\n" + ExUtil.toString(ex)); + } - savedMap = this._toBeMarshaledMap; - this._toBeMarshaledMap = new HashMap(); // HashMap<Ice.Object, int>(); - this._stream.writeSize(savedMap.size); - savedMap.forEach(writeCB); - } - this._stream.writeSize(0); // Zero marker indicates end of sequence of sequences of instances. - }, - registerObject: function(v) + key.__write(self._stream); + }, + savedMap; + + while(this._toBeMarshaledMap.size > 0) { - Debug.assert(v !== null); - // - // Look for this instance in the to-be-marshaled map. + // Consider the to be marshalled objects as marshalled now, + // this is necessary to avoid adding again the "to be + // marshalled objects" into _toBeMarshaledMap while writing + // objects. // - var p = this._toBeMarshaledMap.get(v); - if(p !== undefined) - { - return p; - } + this._marshaledMap.merge(this._toBeMarshaledMap); - // - // Didn't find it, try the marshaled map next. - // - p = this._marshaledMap.get(v); - if(p !== undefined) - { - return p; - } + savedMap = this._toBeMarshaledMap; + this._toBeMarshaledMap = new HashMap(); // HashMap<Ice.Object, int>(); + this._stream.writeSize(savedMap.size); + savedMap.forEach(writeCB); + } + this._stream.writeSize(0); // Zero marker indicates end of sequence of sequences of instances. + }, + registerObject: function(v) + { + Debug.assert(v !== null); - // - // We haven't seen this instance previously, create a new - // index, and insert it into the to-be-marshaled map. - // - this._toBeMarshaledMap.set(v, ++this._objectIdIndex); - return this._objectIdIndex; + // + // Look for this instance in the to-be-marshaled map. + // + var p = this._toBeMarshaledMap.get(v); + if(p !== undefined) + { + return p; } - }); - - var EncapsEncoder11 = Class(EncapsEncoder, { - __init__: function(stream, encaps) + + // + // Didn't find it, try the marshaled map next. + // + p = this._marshaledMap.get(v); + if(p !== undefined) + { + return p; + } + + // + // We haven't seen this instance previously, create a new + // index, and insert it into the to-be-marshaled map. + // + this._toBeMarshaledMap.set(v, ++this._objectIdIndex); + return this._objectIdIndex; + } +}); + +var EncapsEncoder11 = Class(EncapsEncoder, { + __init__: function(stream, encaps) + { + EncapsEncoder.call(this, stream, encaps); + this._current = null; + this._objectIdIndex = 1; + }, + writeObject: function(v) + { + Debug.assert(v !== undefined); + var index, idx; + if(v === null) { - EncapsEncoder.call(this, stream, encaps); - this._current = null; - this._objectIdIndex = 1; - }, - writeObject: function(v) + this._stream.writeSize(0); + } + else if(this._current !== null && this._encaps.format === FormatType.SlicedFormat) { - Debug.assert(v !== undefined); - var index, idx; - if(v === null) + if(this._current.indirectionTable === null) // Lazy initialization { - this._stream.writeSize(0); + this._current.indirectionTable = []; // Ice.Object[] + this._current.indirectionMap = new HashMap(); // HashMap<Ice.Object, int> } - else if(this._current !== null && this._encaps.format === FormatType.SlicedFormat) - { - if(this._current.indirectionTable === null) // Lazy initialization - { - this._current.indirectionTable = []; // Ice.Object[] - this._current.indirectionMap = new HashMap(); // HashMap<Ice.Object, int> - } - // - // If writting an object within a slice and using the sliced - // format, write an index from the object indirection - // table. The indirect object table is encoded at the end of - // each slice and is always read (even if the Slice is - // unknown). - // - index = this._current.indirectionMap.get(v); - if(index === undefined) - { - this._current.indirectionTable.push(v); - idx = this._current.indirectionTable.length; // Position + 1 (0 is reserved for nil) - this._current.indirectionMap.set(v, idx); - this._stream.writeSize(idx); - } - else - { - this._stream.writeSize(index); - } + // + // If writting an object within a slice and using the sliced + // format, write an index from the object indirection + // table. The indirect object table is encoded at the end of + // each slice and is always read (even if the Slice is + // unknown). + // + index = this._current.indirectionMap.get(v); + if(index === undefined) + { + this._current.indirectionTable.push(v); + idx = this._current.indirectionTable.length; // Position + 1 (0 is reserved for nil) + this._current.indirectionMap.set(v, idx); + this._stream.writeSize(idx); } else { - this.writeInstance(v); // Write the instance or a reference if already marshaled. + this._stream.writeSize(index); } - }, - writePendingObjects: function() + } + else { - return undefined; - }, - writeUserException: function(v) + this.writeInstance(v); // Write the instance or a reference if already marshaled. + } + }, + writePendingObjects: function() + { + return undefined; + }, + writeUserException: function(v) + { + Debug.assert(v !== null && v !== undefined); + v.__write(this._stream); + }, + startInstance: function(sliceType, data) + { + if(this._current === null) { - Debug.assert(v !== null && v !== undefined); - v.__write(this._stream); - }, - startInstance: function(sliceType, data) + this._current = new EncapsEncoder11.InstanceData(null); + } + else { - if(this._current === null) - { - this._current = new EncapsEncoder11.InstanceData(null); - } - else - { - this._current = (this._current.next === null) ? new EncapsEncoder11.InstanceData(this._current) : this._current.next; - } - this._current.sliceType = sliceType; - this._current.firstSlice = true; + this._current = (this._current.next === null) ? new EncapsEncoder11.InstanceData(this._current) : this._current.next; + } + this._current.sliceType = sliceType; + this._current.firstSlice = true; - if(data !== null && data !== undefined) - { - this.writeSlicedData(data); - } - }, - endInstance: function() + if(data !== null && data !== undefined) { - this._current = this._current.previous; - }, - startSlice: function(typeId, compactId, last) - { - Debug.assert((this._current.indirectionTable === null || this._current.indirectionTable.length === 0) && - (this._current.indirectionMap === null || this._current.indirectionMap.size === 0)); + this.writeSlicedData(data); + } + }, + endInstance: function() + { + this._current = this._current.previous; + }, + startSlice: function(typeId, compactId, last) + { + Debug.assert((this._current.indirectionTable === null || this._current.indirectionTable.length === 0) && + (this._current.indirectionMap === null || this._current.indirectionMap.size === 0)); - this._current.sliceFlagsPos = this._stream.pos; + this._current.sliceFlagsPos = this._stream.pos; - this._current.sliceFlags = 0; - if(this._encaps.format === FormatType.SlicedFormat) - { - this._current.sliceFlags |= FLAG_HAS_SLICE_SIZE; // Encode the slice size if using the sliced format. - } - if(last) - { - this._current.sliceFlags |= FLAG_IS_LAST_SLICE; // This is the last slice. - } + this._current.sliceFlags = 0; + if(this._encaps.format === FormatType.SlicedFormat) + { + this._current.sliceFlags |= FLAG_HAS_SLICE_SIZE; // Encode the slice size if using the sliced format. + } + if(last) + { + this._current.sliceFlags |= FLAG_IS_LAST_SLICE; // This is the last slice. + } - this._stream.writeByte(0); // Placeholder for the slice flags + this._stream.writeByte(0); // Placeholder for the slice flags + // + // For object slices, encode the flag and the type ID either as a + // string or index. For exception slices, always encode the type + // ID a string. + // + if(this._current.sliceType === SliceType.ObjectSlice) + { // - // For object slices, encode the flag and the type ID either as a - // string or index. For exception slices, always encode the type - // ID a string. - // - if(this._current.sliceType === SliceType.ObjectSlice) + // Encode the type ID (only in the first slice for the compact + // encoding). + // + if(this._encaps.format === FormatType.SlicedFormat || this._current.firstSlice) { - // - // Encode the type ID (only in the first slice for the compact - // encoding). - // - if(this._encaps.format === FormatType.SlicedFormat || this._current.firstSlice) + if(compactId >= 0) { - if(compactId >= 0) + this._current.sliceFlags |= FLAG_HAS_TYPE_ID_COMPACT; + this._stream.writeSize(compactId); + } + else + { + var index = this.registerTypeId(typeId); + if(index < 0) { - this._current.sliceFlags |= FLAG_HAS_TYPE_ID_COMPACT; - this._stream.writeSize(compactId); + this._current.sliceFlags |= FLAG_HAS_TYPE_ID_STRING; + this._stream.writeString(typeId); } else { - var index = this.registerTypeId(typeId); - if(index < 0) - { - this._current.sliceFlags |= FLAG_HAS_TYPE_ID_STRING; - this._stream.writeString(typeId); - } - else - { - this._current.sliceFlags |= FLAG_HAS_TYPE_ID_INDEX; - this._stream.writeSize(index); - } + this._current.sliceFlags |= FLAG_HAS_TYPE_ID_INDEX; + this._stream.writeSize(index); } } } - else - { - this._stream.writeString(typeId); - } + } + else + { + this._stream.writeString(typeId); + } - if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) - { - this._stream.writeInt(0); // Placeholder for the slice length. - } + if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + { + this._stream.writeInt(0); // Placeholder for the slice length. + } - this._current.writeSlice = this._stream.pos; - this._current.firstSlice = false; - }, - endSlice: function() + this._current.writeSlice = this._stream.pos; + this._current.firstSlice = false; + }, + endSlice: function() + { + var sz, i, length; + + // + // Write the optional member end marker if some optional members + // were encoded. Note that the optional members are encoded before + // the indirection table and are included in the slice size. + // + if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) { - var sz, i, length; - - // - // Write the optional member end marker if some optional members - // were encoded. Note that the optional members are encoded before - // the indirection table and are included in the slice size. - // - if((this._current.sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) !== 0) - { - this._stream.writeByte(OPTIONAL_END_MARKER); - } + this._stream.writeByte(OPTIONAL_END_MARKER); + } - // - // Write the slice length if necessary. - // - if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) - { - sz = this._stream.pos - this._current.writeSlice + 4; - this._stream.rewriteInt(sz, this._current.writeSlice - 4); - } + // + // Write the slice length if necessary. + // + if((this._current.sliceFlags & FLAG_HAS_SLICE_SIZE) !== 0) + { + sz = this._stream.pos - this._current.writeSlice + 4; + this._stream.rewriteInt(sz, this._current.writeSlice - 4); + } + + // + // Only write the indirection table if it contains entries. + // + if(this._current.indirectionTable !== null && this._current.indirectionTable.length !== 0) + { + Debug.assert(this._encaps.format === FormatType.SlicedFormat); + this._current.sliceFlags |= FLAG_HAS_INDIRECTION_TABLE; // - // Only write the indirection table if it contains entries. + // Write the indirection object table. // - if(this._current.indirectionTable !== null && this._current.indirectionTable.length !== 0) + this._stream.writeSize(this._current.indirectionTable.length); + for(i = 0, length = this._current.indirectionTable.length; i < length; ++i) { - Debug.assert(this._encaps.format === FormatType.SlicedFormat); - this._current.sliceFlags |= FLAG_HAS_INDIRECTION_TABLE; - - // - // Write the indirection object table. - // - this._stream.writeSize(this._current.indirectionTable.length); - for(i = 0, length = this._current.indirectionTable.length; i < length; ++i) - { - this.writeInstance(this._current.indirectionTable[i]); - } - this._current.indirectionTable.length = 0; // Faster way to clean array in JavaScript - this._current.indirectionMap.clear(); + this.writeInstance(this._current.indirectionTable[i]); } + this._current.indirectionTable.length = 0; // Faster way to clean array in JavaScript + this._current.indirectionMap.clear(); + } - // - // Finally, update the slice flags. - // - this._stream.rewriteByte(this._current.sliceFlags, this._current.sliceFlagsPos); - }, - writeOpt: function(tag, format) + // + // Finally, update the slice flags. + // + this._stream.rewriteByte(this._current.sliceFlags, this._current.sliceFlagsPos); + }, + writeOpt: function(tag, format) + { + if(this._current === null) { - if(this._current === null) - { - return this._stream.writeOptImpl(tag, format); - } - - if(this._stream.writeOptImpl(tag, format)) - { - this._current.sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; - return true; - } - - return false; - }, - writeSlicedData: function(slicedData) + return this._stream.writeOptImpl(tag, format); + } + + if(this._stream.writeOptImpl(tag, format)) { - Debug.assert(slicedData !== null && slicedData !== undefined); + this._current.sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + return true; + } + + return false; + }, + writeSlicedData: function(slicedData) + { + Debug.assert(slicedData !== null && slicedData !== undefined); + + // + // We only remarshal preserved slices if we are using the sliced + // format. Otherwise, we ignore the preserved slices, which + // essentially "slices" the object into the most-derived type + // known by the sender. + // + if(this._encaps.format !== FormatType.SlicedFormat) + { + return; + } + + var i, ii, info, + j, jj; + for(i = 0, ii = slicedData.slices.length; i < ii; ++i) + { + info = slicedData.slices[i]; + this.startSlice(info.typeId, info.compactId, info.isLastSlice); + // - // We only remarshal preserved slices if we are using the sliced - // format. Otherwise, we ignore the preserved slices, which - // essentially "slices" the object into the most-derived type - // known by the sender. + // Write the bytes associated with this slice. // - if(this._encaps.format !== FormatType.SlicedFormat) + this._stream.writeBlob(info.bytes); + + if(info.hasOptionalMembers) { - return; + this._current.sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; } - var i, ii, info, - j, jj; - - for(i = 0, ii = slicedData.slices.length; i < ii; ++i) + // + // Make sure to also re-write the object indirection table. + // + if(info.objects !== null && info.objects.length > 0) { - info = slicedData.slices[i]; - this.startSlice(info.typeId, info.compactId, info.isLastSlice); - - // - // Write the bytes associated with this slice. - // - this._stream.writeBlob(info.bytes); - - if(info.hasOptionalMembers) + if(this._current.indirectionTable === null) // Lazy initialization { - this._current.sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + this._current.indirectionTable = []; // Ice.Object[] + this._current.indirectionMap = new HashMap(); // HashMap<Ice.Object, int> } - - // - // Make sure to also re-write the object indirection table. - // - if(info.objects !== null && info.objects.length > 0) + + for(j = 0, jj = info.objects.length; j < jj; ++j) { - if(this._current.indirectionTable === null) // Lazy initialization - { - this._current.indirectionTable = []; // Ice.Object[] - this._current.indirectionMap = new HashMap(); // HashMap<Ice.Object, int> - } - - for(j = 0, jj = info.objects.length; j < jj; ++j) - { - this._current.indirectionTable.push(info.objects[j]); - } + this._current.indirectionTable.push(info.objects[j]); } - - this.endSlice(); } - }, - writeInstance: function(v) + + this.endSlice(); + } + }, + writeInstance: function(v) + { + Debug.assert(v !== null && v !== undefined); + + // + // If the instance was already marshaled, just write it's ID. + // + var p = this._marshaledMap.get(v); + if(p !== undefined) { - Debug.assert(v !== null && v !== undefined); + this._stream.writeSize(p); + return; + } - // - // If the instance was already marshaled, just write it's ID. - // - var p = this._marshaledMap.get(v); - if(p !== undefined) - { - this._stream.writeSize(p); - return; - } + // + // We haven't seen this instance previously, create a new ID, + // insert it into the marshaled map, and write the instance. + // + this._marshaledMap.set(v, ++this._objectIdIndex); - // - // We haven't seen this instance previously, create a new ID, - // insert it into the marshaled map, and write the instance. - // - this._marshaledMap.set(v, ++this._objectIdIndex); + try + { + v.ice_preMarshal(); + } + catch(ex) + { + this._stream.instance.initializationData().logger.warning("exception raised by ice_preMarshal:\n" + + ExUtil.toString(ex)); + } - try - { - v.ice_preMarshal(); - } - catch(ex) - { - this._stream.instance.initializationData().logger.warning("exception raised by ice_preMarshal:\n" + - ExUtil.toString(ex)); - } + this._stream.writeSize(1); // Object instance marker. + v.__write(this._stream); + } +}); - this._stream.writeSize(1); // Object instance marker. - v.__write(this._stream); - } - }); +EncapsEncoder11.InstanceData = function(previous) +{ + Debug.assert(previous !== undefined); + if(previous !== null) + { + previous.next = this; + } + this.previous = previous; + this.next = null; - EncapsEncoder11.InstanceData = function(previous) + // Instance attributes + this.sliceType = null; + this.firstSlice = false; + + // Slice attributes + this.sliceFlags = 0; + this.writeSlice = 0; // Position of the slice data members + this.sliceFlagsPos = 0; // Position of the slice flags + this.indirectionTable = null; // Ice.Object[] + this.indirectionMap = null; // HashMap<Ice.Object, int> +}; + +var ReadEncaps = Class({ + __init__: function() { - Debug.assert(previous !== undefined); - if(previous !== null) - { - previous.next = this; - } - this.previous = previous; + this.start = 0; + this.sz = 0; + this.encoding = null; + this.encoding_1_0 = false; + this.decoder = null; this.next = null; - - // Instance attributes - this.sliceType = null; - this.firstSlice = false; - - // Slice attributes - this.sliceFlags = 0; - this.writeSlice = 0; // Position of the slice data members - this.sliceFlagsPos = 0; // Position of the slice flags - this.indirectionTable = null; // Ice.Object[] - this.indirectionMap = null; // HashMap<Ice.Object, int> - }; + }, + reset: function() + { + this.decoder = null; + }, + setEncoding: function(encoding) + { + this.encoding = encoding; + this.encoding_1_0 = encoding.equals(Ice.Encoding_1_0); + } +}); - var ReadEncaps = Class({ - __init__: function() - { - this.start = 0; - this.sz = 0; - this.encoding = null; - this.encoding_1_0 = false; - this.decoder = null; - this.next = null; - }, - reset: function() - { - this.decoder = null; - }, - setEncoding: function(encoding) +var WriteEncaps = Class({ + __init__: function() + { + this.start = 0; + this.format = FormatType.DefaultFormat; + this.encoding = null; + this.encoding_1_0 = false; + this.encoder = null; + this.next = null; + }, + reset: function() + { + this.encoder = null; + }, + setEncoding: function(encoding) + { + this.encoding = encoding; + this.encoding_1_0 = encoding.equals(Ice.Encoding_1_0); + } +}); + +var BasicStream = Class({ + __init__: function(instance, encoding, unlimited, data) + { + this._instance = instance; + this._closure = null; + this._encoding = encoding; + + this._readEncapsStack = null; + this._writeEncapsStack = null; + this._readEncapsCache = null; + this._writeEncapsCache = null; + + this._sliceObjects = true; + + this._messageSizeMax = this._instance.messageSizeMax(); // Cached for efficiency. + this._unlimited = unlimited !== undefined ? unlimited : false; + + this._startSeq = -1; + this._sizePos = -1; + + if(data !== undefined) { - this.encoding = encoding; - this.encoding_1_0 = encoding.equals(Ice.Encoding_1_0); + this._buf = new Ice.Buffer(data); } - }); - - var WriteEncaps = Class({ - __init__: function() + else { - this.start = 0; - this.format = FormatType.DefaultFormat; - this.encoding = null; - this.encoding_1_0 = false; - this.encoder = null; - this.next = null; - }, - reset: function() - { - this.encoder = null; - }, - setEncoding: function(encoding) - { - this.encoding = encoding; - this.encoding_1_0 = encoding.equals(Ice.Encoding_1_0); + this._buf = new Ice.Buffer(); } - }); - - var BasicStream = Class({ - __init__: function(instance, encoding, unlimited, data) + }, + // + // This function allows this object to be reused, rather than + // reallocated. + // + reset: function() + { + this._buf.reset(); + this.clear(); + }, + clear: function() + { + if(this._readEncapsStack !== null) { - this._instance = instance; - this._closure = null; - this._encoding = encoding; - + Debug.assert(this._readEncapsStack.next); + this._readEncapsStack.next = this._readEncapsCache; + this._readEncapsCache = this._readEncapsStack; + this._readEncapsCache.reset(); this._readEncapsStack = null; + } + + if(this._writeEncapsStack !== null) + { + Debug.assert(this._writeEncapsStack.next); + this._writeEncapsStack.next = this._writeEncapsCache; + this._writeEncapsCache = this._writeEncapsStack; + this._writeEncapsCache.reset(); this._writeEncapsStack = null; - this._readEncapsCache = null; - this._writeEncapsCache = null; + } + this._startSeq = -1; + this._sliceObjects = true; + }, + swap: function(other) + { + Debug.assert(this._instance === other._instance); + + var tmpBuf, tmpClosure, tmpUnlimited, tmpStartSeq, tmpMinSeqSize, tmpSizePos; - this._sliceObjects = true; + tmpBuf = other._buf; + other._buf = this._buf; + this._buf = tmpBuf; - this._messageSizeMax = this._instance.messageSizeMax(); // Cached for efficiency. - this._unlimited = unlimited !== undefined ? unlimited : false; + tmpClosure = other._closure; + other._closure = this._closure; + this._closure = tmpClosure; - this._startSeq = -1; - this._sizePos = -1; - - if(data !== undefined) - { - this._buf = new Ice.Buffer(data); - } - else - { - this._buf = new Ice.Buffer(); - } - }, // - // This function allows this object to be reused, rather than - // reallocated. + // Swap is never called for BasicStreams that have encapsulations being read/write. However, + // encapsulations might still be set in case marshalling or un-marshalling failed. We just + // reset the encapsulations if there are still some set. + // + this.resetEncaps(); + other.resetEncaps(); + + tmpUnlimited = other._unlimited; + other._unlimited = this._unlimited; + this._unlimited = tmpUnlimited; + + tmpStartSeq = other._startSeq; + other._startSeq = this._startSeq; + this._startSeq = tmpStartSeq; + + tmpMinSeqSize = other._minSeqSize; + other._minSeqSize = this._minSeqSize; + this._minSeqSize = tmpMinSeqSize; + + tmpSizePos = other._sizePos; + other._sizePos = this._sizePos; + this._sizePos = tmpSizePos; + }, + resetEncaps: function() + { + this._readEncapsStack = null; + this._writeEncapsStack = null; + }, + resize: function(sz) + { + // + // Check memory limit if stream is not unlimited. // - reset: function() + if(!this._unlimited && sz > this._messageSizeMax) { - this._buf.reset(); - this.clear(); - }, - clear: function() + ExUtil.throwMemoryLimitException(sz, this._messageSizeMax); + } + + this._buf.resize(sz); + this._buf.position = sz; + }, + prepareWrite: function() + { + this._buf.position = 0; + return this._buf; + }, + startWriteObject: function(data) + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.startInstance(SliceType.ObjectSlice, data); + }, + endWriteObject: function() + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.endInstance(); + }, + startReadObject: function() + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + this._readEncapsStack.decoder.startInstance(SliceType.ObjectSlice); + }, + endReadObject: function(preserve) + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + return this._readEncapsStack.decoder.endInstance(preserve); + }, + startWriteException: function(data) + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.startInstance(SliceType.ExceptionSlice, data); + }, + endWriteException: function() + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.endInstance(); + }, + startReadException: function() + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + this._readEncapsStack.decoder.startInstance(SliceType.ExceptionSlice); + }, + endReadException: function(preserve) + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + return this._readEncapsStack.decoder.endInstance(preserve); + }, + startWriteEncaps: function(encoding, format) + { + // + // If no encoding version is specified, use the current write + // encapsulation encoding version if there's a current write + // encapsulation, otherwise, use the stream encoding version. + // + + if(encoding === undefined) { - if(this._readEncapsStack !== null) + if(this._writeEncapsStack !== null) { - Debug.assert(this._readEncapsStack.next); - this._readEncapsStack.next = this._readEncapsCache; - this._readEncapsCache = this._readEncapsStack; - this._readEncapsCache.reset(); - this._readEncapsStack = null; + encoding = this._writeEncapsStack.encoding; + format = this._writeEncapsStack.format; } - - if(this._writeEncapsStack !== null) + else { - Debug.assert(this._writeEncapsStack.next); - this._writeEncapsStack.next = this._writeEncapsCache; - this._writeEncapsCache = this._writeEncapsStack; - this._writeEncapsCache.reset(); - this._writeEncapsStack = null; + encoding = this._encoding; + format = FormatType.DefaultFormat; } - this._startSeq = -1; - this._sliceObjects = true; - }, - swap: function(other) - { - Debug.assert(this._instance === other._instance); - - var tmpBuf, tmpClosure, tmpUnlimited, tmpStartSeq, tmpMinSeqSize, tmpSizePos; - - tmpBuf = other._buf; - other._buf = this._buf; - this._buf = tmpBuf; - - tmpClosure = other._closure; - other._closure = this._closure; - this._closure = tmpClosure; - - // - // Swap is never called for BasicStreams that have encapsulations being read/write. However, - // encapsulations might still be set in case marshalling or un-marshalling failed. We just - // reset the encapsulations if there are still some set. - // - this.resetEncaps(); - other.resetEncaps(); - - tmpUnlimited = other._unlimited; - other._unlimited = this._unlimited; - this._unlimited = tmpUnlimited; - - tmpStartSeq = other._startSeq; - other._startSeq = this._startSeq; - this._startSeq = tmpStartSeq; + } - tmpMinSeqSize = other._minSeqSize; - other._minSeqSize = this._minSeqSize; - this._minSeqSize = tmpMinSeqSize; + Protocol.checkSupportedEncoding(encoding); - tmpSizePos = other._sizePos; - other._sizePos = this._sizePos; - this._sizePos = tmpSizePos; - }, - resetEncaps: function() + var curr = this._writeEncapsCache; + if(curr !== null) { - this._readEncapsStack = null; - this._writeEncapsStack = null; - }, - resize: function(sz) + curr.reset(); + this._writeEncapsCache = this._writeEncapsCache.next; + } + else { - // - // Check memory limit if stream is not unlimited. - // - if(!this._unlimited && sz > this._messageSizeMax) - { - ExUtil.throwMemoryLimitException(sz, this._messageSizeMax); - } + curr = new WriteEncaps(); + } + curr.next = this._writeEncapsStack; + this._writeEncapsStack = curr; - this._buf.resize(sz); - this._buf.position = sz; - }, - prepareWrite: function() - { - this._buf.position = 0; - return this._buf; - }, - startWriteObject: function(data) - { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.startInstance(SliceType.ObjectSlice, data); - }, - endWriteObject: function() - { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.endInstance(); - }, - startReadObject: function() - { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - this._readEncapsStack.decoder.startInstance(SliceType.ObjectSlice); - }, - endReadObject: function(preserve) - { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - return this._readEncapsStack.decoder.endInstance(preserve); - }, - startWriteException: function(data) - { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.startInstance(SliceType.ExceptionSlice, data); - }, - endWriteException: function() + this._writeEncapsStack.format = format; + this._writeEncapsStack.setEncoding(encoding); + this._writeEncapsStack.start = this._buf.limit; + + this.writeInt(0); // Placeholder for the encapsulation length. + this._writeEncapsStack.encoding.__write(this); + }, + endWriteEncaps: function() + { + Debug.assert(this._writeEncapsStack); + + // Size includes size and version. + var start = this._writeEncapsStack.start; + + var sz = this._buf.limit - start; + this._buf.putIntAt(start, sz); + + var curr = this._writeEncapsStack; + this._writeEncapsStack = curr.next; + curr.next = this._writeEncapsCache; + this._writeEncapsCache = curr; + this._writeEncapsCache.reset(); + }, + endWriteEncapsChecked: function() // Used by public stream API. + { + if(this._writeEncapsStack === null) { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.endInstance(); - }, - startReadException: function() + throw new Ice.EncapsulationException("not in an encapsulation"); + } + this.endWriteEncaps(); + }, + writeEmptyEncaps: function(encoding) + { + Protocol.checkSupportedEncoding(encoding); + this.writeInt(6); // Size + encoding.__write(this); + }, + writeEncaps: function(v) + { + if(v.length < 6) { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - this._readEncapsStack.decoder.startInstance(SliceType.ExceptionSlice); - }, - endReadException: function(preserve) + throw new Ice.EncapsulationException(); + } + this.expand(v.length); + this._buf.putArray(v); + }, + getWriteEncoding: function() + { + return this._writeEncapsStack !== null ? this._writeEncapsStack.encoding : this._encoding; + }, + startReadEncaps: function() + { + var curr = this._readEncapsCache; + if(curr !== null) { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - return this._readEncapsStack.decoder.endInstance(preserve); - }, - startWriteEncaps: function(encoding, format) + curr.reset(); + this._readEncapsCache = this._readEncapsCache.next; + } + else { - // - // If no encoding version is specified, use the current write - // encapsulation encoding version if there's a current write - // encapsulation, otherwise, use the stream encoding version. - // - - if(encoding === undefined) - { - if(this._writeEncapsStack !== null) - { - encoding = this._writeEncapsStack.encoding; - format = this._writeEncapsStack.format; - } - else - { - encoding = this._encoding; - format = FormatType.DefaultFormat; - } - } - - Protocol.checkSupportedEncoding(encoding); - - var curr = this._writeEncapsCache; - if(curr !== null) - { - curr.reset(); - this._writeEncapsCache = this._writeEncapsCache.next; - } - else - { - curr = new WriteEncaps(); - } - curr.next = this._writeEncapsStack; - this._writeEncapsStack = curr; + curr = new ReadEncaps(); + } + curr.next = this._readEncapsStack; + this._readEncapsStack = curr; - this._writeEncapsStack.format = format; - this._writeEncapsStack.setEncoding(encoding); - this._writeEncapsStack.start = this._buf.limit; + this._readEncapsStack.start = this._buf.position; - this.writeInt(0); // Placeholder for the encapsulation length. - this._writeEncapsStack.encoding.__write(this); - }, - endWriteEncaps: function() + // + // I don't use readSize() and writeSize() for encapsulations, + // because when creating an encapsulation, I must know in advance + // how many bytes the size information will require in the data + // stream. If I use an Int, it is always 4 bytes. For + // readSize()/writeSize(), it could be 1 or 5 bytes. + // + var sz = this.readInt(); + if(sz < 6) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } + if(sz - 4 > this._buf.remaining) { - Debug.assert(this._writeEncapsStack); + throw new Ice.UnmarshalOutOfBoundsException(); + } + this._readEncapsStack.sz = sz; - // Size includes size and version. - var start = this._writeEncapsStack.start; - - var sz = this._buf.limit - start; - this._buf.putIntAt(start, sz); + var encoding = new Ice.EncodingVersion(); + encoding.__read(this); + Protocol.checkSupportedEncoding(encoding); // Make sure the encoding is supported. + this._readEncapsStack.setEncoding(encoding); - var curr = this._writeEncapsStack; - this._writeEncapsStack = curr.next; - curr.next = this._writeEncapsCache; - this._writeEncapsCache = curr; - this._writeEncapsCache.reset(); - }, - endWriteEncapsChecked: function() // Used by public stream API. - { - if(this._writeEncapsStack === null) - { - throw new Ice.EncapsulationException("not in an encapsulation"); - } - this.endWriteEncaps(); - }, - writeEmptyEncaps: function(encoding) - { - Protocol.checkSupportedEncoding(encoding); - this.writeInt(6); // Size - encoding.__write(this); - }, - writeEncaps: function(v) + return encoding; + }, + endReadEncaps: function() + { + Debug.assert(this._readEncapsStack !== null); + + if(!this._readEncapsStack.encoding_1_0) { - if(v.length < 6) + this.skipOpts(); + if(this._buf.position !== this._readEncapsStack.start + this._readEncapsStack.sz) { throw new Ice.EncapsulationException(); } - this.expand(v.length); - this._buf.putArray(v); - }, - getWriteEncoding: function() - { - return this._writeEncapsStack !== null ? this._writeEncapsStack.encoding : this._encoding; - }, - startReadEncaps: function() + } + else if(this._buf.position !== this._readEncapsStack.start + this._readEncapsStack.sz) { - var curr = this._readEncapsCache; - if(curr !== null) - { - curr.reset(); - this._readEncapsCache = this._readEncapsCache.next; - } - else + if(this._buf.position + 1 !== this._readEncapsStack.start + this._readEncapsStack.sz) { - curr = new ReadEncaps(); + throw new Ice.EncapsulationException(); } - curr.next = this._readEncapsStack; - this._readEncapsStack = curr; - - this._readEncapsStack.start = this._buf.position; - + // - // I don't use readSize() and writeSize() for encapsulations, - // because when creating an encapsulation, I must know in advance - // how many bytes the size information will require in the data - // stream. If I use an Int, it is always 4 bytes. For - // readSize()/writeSize(), it could be 1 or 5 bytes. + // Ice version < 3.3 had a bug where user exceptions with + // class members could be encoded with a trailing byte + // when dispatched with AMD. So we tolerate an extra byte + // in the encapsulation. // - var sz = this.readInt(); - if(sz < 6) + + try { - throw new Ice.UnmarshalOutOfBoundsException(); + this._buf.get(); } - if(sz - 4 > this._buf.remaining) + catch(ex) { throw new Ice.UnmarshalOutOfBoundsException(); } - this._readEncapsStack.sz = sz; - - var encoding = new Ice.EncodingVersion(); - encoding.__read(this); - Protocol.checkSupportedEncoding(encoding); // Make sure the encoding is supported. - this._readEncapsStack.setEncoding(encoding); + } - return encoding; - }, - endReadEncaps: function() + var curr = this._readEncapsStack; + this._readEncapsStack = curr.next; + curr.next = this._readEncapsCache; + this._readEncapsCache = curr; + this._readEncapsCache.reset(); + }, + skipEmptyEncaps: function(encoding) + { + Debug.assert(encoding !== undefined); + var sz = this.readInt(); + if(sz !== 6) { - Debug.assert(this._readEncapsStack !== null); - - if(!this._readEncapsStack.encoding_1_0) - { - this.skipOpts(); - if(this._buf.position !== this._readEncapsStack.start + this._readEncapsStack.sz) - { - throw new Ice.EncapsulationException(); - } - } - else if(this._buf.position !== this._readEncapsStack.start + this._readEncapsStack.sz) - { - if(this._buf.position + 1 !== this._readEncapsStack.start + this._readEncapsStack.sz) - { - throw new Ice.EncapsulationException(); - } - - // - // Ice version < 3.3 had a bug where user exceptions with - // class members could be encoded with a trailing byte - // when dispatched with AMD. So we tolerate an extra byte - // in the encapsulation. - // - - try - { - this._buf.get(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - } + throw new Ice.EncapsulationException(); + } - var curr = this._readEncapsStack; - this._readEncapsStack = curr.next; - curr.next = this._readEncapsCache; - this._readEncapsCache = curr; - this._readEncapsCache.reset(); - }, - skipEmptyEncaps: function(encoding) + var pos = this._buf.position; + if(pos + 2 > this._buf.limit) { - Debug.assert(encoding !== undefined); - var sz = this.readInt(); - if(sz !== 6) - { - throw new Ice.EncapsulationException(); - } - - var pos = this._buf.position; - if(pos + 2 > this._buf.limit) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + throw new Ice.UnmarshalOutOfBoundsException(); + } - if(encoding !== null) - { - encoding.__read(this); - } - else - { - this._buf.position = pos + 2; - } - }, - endReadEncapsChecked: function() // Used by public stream API. + if(encoding !== null) { - if(this._readEncapsStack === null) - { - throw new Ice.EncapsulationException("not in an encapsulation"); - } - this.endReadEncaps(); - }, - readEncaps: function(encoding) + encoding.__read(this); + } + else { - Debug.assert(encoding !== undefined); - var sz = this.readInt(); - if(sz < 6) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + this._buf.position = pos + 2; + } + }, + endReadEncapsChecked: function() // Used by public stream API. + { + if(this._readEncapsStack === null) + { + throw new Ice.EncapsulationException("not in an encapsulation"); + } + this.endReadEncaps(); + }, + readEncaps: function(encoding) + { + Debug.assert(encoding !== undefined); + var sz = this.readInt(); + if(sz < 6) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } - if(sz - 4 > this._buf.remaining) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + if(sz - 4 > this._buf.remaining) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } - if(encoding !== null) - { - encoding.__read(this); - this._buf.position = this._buf.position - 6; - } - else - { - this._buf.position = this._buf.position - 4; - } + if(encoding !== null) + { + encoding.__read(this); + this._buf.position = this._buf.position - 6; + } + else + { + this._buf.position = this._buf.position - 4; + } - try - { - return this._buf.getArray(sz); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - getReadEncoding: function() + try { - return this._readEncapsStack !== null ? this._readEncapsStack.encoding : this._encoding; - }, - getReadEncapsSize: function() + return this._buf.getArray(sz); + } + catch(ex) { - Debug.assert(this._readEncapsStack !== null); - return this._readEncapsStack.sz - 6; - }, - skipEncaps: function() + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + getReadEncoding: function() + { + return this._readEncapsStack !== null ? this._readEncapsStack.encoding : this._encoding; + }, + getReadEncapsSize: function() + { + Debug.assert(this._readEncapsStack !== null); + return this._readEncapsStack.sz - 6; + }, + skipEncaps: function() + { + var sz = this.readInt(); + if(sz < 6) { - var sz = this.readInt(); - if(sz < 6) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - var encoding = new Ice.EncodingVersion(); - encoding.__read(this); - try - { - this._buf.position = this._buf.position + sz - 6; - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - return encoding; - }, - startWriteSlice: function(typeId, compactId, last) + throw new Ice.UnmarshalOutOfBoundsException(); + } + var encoding = new Ice.EncodingVersion(); + encoding.__read(this); + try { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.startSlice(typeId, compactId, last); - }, - endWriteSlice: function() + this._buf.position = this._buf.position + sz - 6; + } + catch(ex) { - Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); - this._writeEncapsStack.encoder.endSlice(); - }, - startReadSlice: function() // Returns type ID of next slice + throw new Ice.UnmarshalOutOfBoundsException(); + } + return encoding; + }, + startWriteSlice: function(typeId, compactId, last) + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.startSlice(typeId, compactId, last); + }, + endWriteSlice: function() + { + Debug.assert(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null); + this._writeEncapsStack.encoder.endSlice(); + }, + startReadSlice: function() // Returns type ID of next slice + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + return this._readEncapsStack.decoder.startSlice(); + }, + endReadSlice: function() + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + this._readEncapsStack.decoder.endSlice(); + }, + skipSlice: function() + { + Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); + this._readEncapsStack.decoder.skipSlice(); + }, + readPendingObjects: function() + { + if(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null) { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - return this._readEncapsStack.decoder.startSlice(); - }, - endReadSlice: function() + this._readEncapsStack.decoder.readPendingObjects(); + } + else if((this._readEncapsStack !== null && this._readEncapsStack.encoding_1_0) || + (this._readEncapsStack === null && this._encoding.equals(Ice.Encoding_1_0))) { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - this._readEncapsStack.decoder.endSlice(); - }, - skipSlice: function() + // + // If using the 1.0 encoding and no objects were read, we + // still read an empty sequence of pending objects if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no objects + // are written we do marshal an empty sequence if marshaled + // data types use classes. + // + this.skipSize(); + } + }, + writePendingObjects: function() + { + if(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null) { - Debug.assert(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null); - this._readEncapsStack.decoder.skipSlice(); - }, - readPendingObjects: function() + this._writeEncapsStack.encoder.writePendingObjects(); + } + else if((this._writeEncapsStack !== null && this._writeEncapsStack.encoding_1_0) || + (this._writeEncapsStack === null && this._encoding.equals(Ice.Encoding_1_0))) { - if(this._readEncapsStack !== null && this._readEncapsStack.decoder !== null) - { - this._readEncapsStack.decoder.readPendingObjects(); - } - else if((this._readEncapsStack !== null && this._readEncapsStack.encoding_1_0) || - (this._readEncapsStack === null && this._encoding.equals(Ice.Encoding_1_0))) - { - // - // If using the 1.0 encoding and no objects were read, we - // still read an empty sequence of pending objects if - // requested (i.e.: if this is called). - // - // This is required by the 1.0 encoding, even if no objects - // are written we do marshal an empty sequence if marshaled - // data types use classes. - // - this.skipSize(); - } - }, - writePendingObjects: function() + // + // If using the 1.0 encoding and no objects were written, we + // still write an empty sequence for pending objects if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no objects + // are written we do marshal an empty sequence if marshaled + // data types use classes. + // + this.writeSize(0); + } + }, + writeSize: function(v) + { + if(v > 254) { - if(this._writeEncapsStack !== null && this._writeEncapsStack.encoder !== null) - { - this._writeEncapsStack.encoder.writePendingObjects(); - } - else if((this._writeEncapsStack !== null && this._writeEncapsStack.encoding_1_0) || - (this._writeEncapsStack === null && this._encoding.equals(Ice.Encoding_1_0))) - { - // - // If using the 1.0 encoding and no objects were written, we - // still write an empty sequence for pending objects if - // requested (i.e.: if this is called). - // - // This is required by the 1.0 encoding, even if no objects - // are written we do marshal an empty sequence if marshaled - // data types use classes. - // - this.writeSize(0); - } - }, - writeSize: function(v) + this.expand(5); + this._buf.put(255); + this._buf.putInt(v); + } + else { - if(v > 254) - { - this.expand(5); - this._buf.put(255); - this._buf.putInt(v); - } - else - { - this.expand(1); - this._buf.put(v); - } - }, - readSize: function() + this.expand(1); + this._buf.put(v); + } + }, + readSize: function() + { + try { - try + var b = this._buf.get(); + if(b === 255) { - var b = this._buf.get(); - if(b === 255) + var v = this._buf.getInt(); + if(v < 0) { - var v = this._buf.getInt(); - if(v < 0) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - return v; + throw new Ice.UnmarshalOutOfBoundsException(); } - return b; - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); + return v; } - }, - readAndCheckSeqSize: function(minSize) + return b; + } + catch(ex) { - var sz = this.readSize(); + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + readAndCheckSeqSize: function(minSize) + { + var sz = this.readSize(); - if(sz === 0) - { - return sz; - } + if(sz === 0) + { + return sz; + } - // - // The _startSeq variable points to the start of the sequence for which - // we expect to read at least _minSeqSize bytes from the stream. - // - // If not initialized or if we already read more data than _minSeqSize, - // we reset _startSeq and _minSeqSize for this sequence (possibly a - // top-level sequence or enclosed sequence it doesn't really matter). - // - // Otherwise, we are reading an enclosed sequence and we have to bump - // _minSeqSize by the minimum size that this sequence will require on - // the stream. - // - // The goal of this check is to ensure that when we start un-marshalling - // a new sequence, we check the minimal size of this new sequence against - // the estimated remaining buffer size. This estimatation is based on - // the minimum size of the enclosing sequences, it's _minSeqSize. - // - if(this._startSeq === -1 || this._buf.position > (this._startSeq + this._minSeqSize)) - { - this._startSeq = this._buf.position; - this._minSeqSize = sz * minSize; - } - else - { - this._minSeqSize += sz * minSize; - } + // + // The _startSeq variable points to the start of the sequence for which + // we expect to read at least _minSeqSize bytes from the stream. + // + // If not initialized or if we already read more data than _minSeqSize, + // we reset _startSeq and _minSeqSize for this sequence (possibly a + // top-level sequence or enclosed sequence it doesn't really matter). + // + // Otherwise, we are reading an enclosed sequence and we have to bump + // _minSeqSize by the minimum size that this sequence will require on + // the stream. + // + // The goal of this check is to ensure that when we start un-marshalling + // a new sequence, we check the minimal size of this new sequence against + // the estimated remaining buffer size. This estimatation is based on + // the minimum size of the enclosing sequences, it's _minSeqSize. + // + if(this._startSeq === -1 || this._buf.position > (this._startSeq + this._minSeqSize)) + { + this._startSeq = this._buf.position; + this._minSeqSize = sz * minSize; + } + else + { + this._minSeqSize += sz * minSize; + } - // - // If there isn't enough data to read on the stream for the sequence (and - // possibly enclosed sequences), something is wrong with the marshalled - // data: it's claiming having more data that what is possible to read. - // - if(this._startSeq + this._minSeqSize > this._buf.limit) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + // + // If there isn't enough data to read on the stream for the sequence (and + // possibly enclosed sequences), something is wrong with the marshalled + // data: it's claiming having more data that what is possible to read. + // + if(this._startSeq + this._minSeqSize > this._buf.limit) + { + throw new Ice.UnmarshalOutOfBoundsException(); + } - return sz; - }, - startSize: function() + return sz; + }, + startSize: function() + { + var pos = this._buf.position; + this.writeInt(0); // Placeholder for 32-bit size + return pos; + }, + endSize: function(pos) + { + Debug.assert(pos >= 0); + this.rewriteInt(this._buf.position - pos - 4, pos); + }, + writeBlob: function(v) + { + if(v === null) { - var pos = this._buf.position; - this.writeInt(0); // Placeholder for 32-bit size - return pos; - }, - endSize: function(pos) + return; + } + this.expand(v.length); + this._buf.putArray(v); + }, + readBlob: function(sz) + { + if(this._buf.remaining < sz) { - Debug.assert(pos >= 0); - this.rewriteInt(this._buf.position - pos - 4, pos); - }, - writeBlob: function(v) + throw new Ice.UnmarshalOutOfBoundsException(); + } + try { - if(v === null) - { - return; - } - this.expand(v.length); - this._buf.putArray(v); - }, - readBlob: function(sz) + return this._buf.getArray(sz); + } + catch(ex) { - if(this._buf.remaining < sz) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - try - { - return this._buf.getArray(sz); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - // Read/write format and tag for optionals - writeOpt: function(tag, format) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + // Read/write format and tag for optionals + writeOpt: function(tag, format) + { + Debug.assert(this._writeEncapsStack !== null); + if(this._writeEncapsStack.encoder !== null) { - Debug.assert(this._writeEncapsStack !== null); - if(this._writeEncapsStack.encoder !== null) - { - return this._writeEncapsStack.encoder.writeOpt(tag, format); - } - return this.writeOptImpl(tag, format); - }, - readOpt: function(tag, expectedFormat) + return this._writeEncapsStack.encoder.writeOpt(tag, format); + } + return this.writeOptImpl(tag, format); + }, + readOpt: function(tag, expectedFormat) + { + Debug.assert(this._readEncapsStack !== null); + if(this._readEncapsStack.decoder !== null) { - Debug.assert(this._readEncapsStack !== null); - if(this._readEncapsStack.decoder !== null) - { - return this._readEncapsStack.decoder.readOpt(tag, expectedFormat); - } - return this.readOptImpl(tag, expectedFormat); - }, - writeOptValue: function(tag, format, write, v) + return this._readEncapsStack.decoder.readOpt(tag, expectedFormat); + } + return this.readOptImpl(tag, expectedFormat); + }, + writeOptValue: function(tag, format, write, v) + { + if(v !== undefined) { - if(v !== undefined) + if(this.writeOpt(tag, format)) { - if(this.writeOpt(tag, format)) - { - write.call(this, v); - } + write.call(this, v); } - }, - readOptValue: function(tag, format, read) + } + }, + readOptValue: function(tag, format, read) + { + if(this.readOpt(tag, format)) { - if(this.readOpt(tag, format)) - { - return read.call(this); - } - else - { - return undefined; - } - }, - writeByte: function(v) + return read.call(this); + } + else { - this.expand(1); - this._buf.put(v); - }, - rewriteByte: function(v, dest) + return undefined; + } + }, + writeByte: function(v) + { + this.expand(1); + this._buf.put(v); + }, + rewriteByte: function(v, dest) + { + this._buf.putAt(dest, v); + }, + readByte: function() + { + try { - this._buf.putAt(dest, v); - }, - readByte: function() + return this._buf.get(); + } + catch(ex) { - try - { - return this._buf.get(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeByteSeq: function(v) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeByteSeq: function(v) + { + if(v === null || v.length === 0) { - if(v === null || v.length === 0) - { - this.writeSize(0); - } - else - { - this.writeSize(v.length); - this.expand(v.length); - this._buf.putArray(v); - } - }, - readByteSeq: function() + this.writeSize(0); + } + else { - return this._buf.getArray(this.readAndCheckSeqSize(1)); - }, - writeBool: function(v) + this.writeSize(v.length); + this.expand(v.length); + this._buf.putArray(v); + } + }, + readByteSeq: function() + { + return this._buf.getArray(this.readAndCheckSeqSize(1)); + }, + writeBool: function(v) + { + this.expand(1); + this._buf.put(v ? 1 : 0); + }, + rewriteBool: function(v, dest) + { + this._buf.putAt(dest, v ? 1 : 0); + }, + readBool: function() + { + try { - this.expand(1); - this._buf.put(v ? 1 : 0); - }, - rewriteBool: function(v, dest) + return this._buf.get() === 1; + } + catch(ex) { - this._buf.putAt(dest, v ? 1 : 0); - }, - readBool: function() + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeShort: function(v) + { + this.expand(2); + this._buf.putShort(v); + }, + readShort: function() + { + try { - try - { - return this._buf.get() === 1; - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeShort: function(v) + return this._buf.getShort(); + } + catch(ex) { - this.expand(2); - this._buf.putShort(v); - }, - readShort: function() + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeInt: function(v) + { + this.expand(4); + this._buf.putInt(v); + }, + rewriteInt: function(v, dest) + { + this._buf.putIntAt(dest, v); + }, + readInt: function() + { + try { - try - { - return this._buf.getShort(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeInt: function(v) + return this._buf.getInt(); + } + catch(ex) { - this.expand(4); - this._buf.putInt(v); - }, - rewriteInt: function(v, dest) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeLong: function(v) + { + this.expand(8); + this._buf.putLong(v); + }, + readLong: function() + { + try { - this._buf.putIntAt(dest, v); - }, - readInt: function() + return this._buf.getLong(); + } + catch(ex) { - try - { - return this._buf.getInt(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeLong: function(v) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeFloat: function(v) + { + this.expand(4); + this._buf.putFloat(v); + }, + readFloat: function() + { + try { - this.expand(8); - this._buf.putLong(v); - }, - readLong: function() + return this._buf.getFloat(); + } + catch(ex) { - try - { - return this._buf.getLong(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeFloat: function(v) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeDouble: function(v) + { + this.expand(8); + this._buf.putDouble(v); + }, + readDouble: function() + { + try { - this.expand(4); - this._buf.putFloat(v); - }, - readFloat: function() + return this._buf.getDouble(); + } + catch(ex) { - try - { - return this._buf.getFloat(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeDouble: function(v) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeString: function(v) + { + if(v === null || v.length === 0) { - this.expand(8); - this._buf.putDouble(v); - }, - readDouble: function() + this.writeSize(0); + } + else { - try - { - return this._buf.getDouble(); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeString: function(v) + this._buf.writeString(this, v); + } + }, + readString: function() + { + var len = this.readSize(); + if(len === 0) { - if(v === null || v.length === 0) - { - this.writeSize(0); - } - else - { - this._buf.writeString(this, v); - } - }, - readString: function() + return ""; + } + // + // Check the buffer has enough bytes to read. + // + if(this._buf.remaining < len) { - var len = this.readSize(); - if(len === 0) - { - return ""; - } - // - // Check the buffer has enough bytes to read. - // - if(this._buf.remaining < len) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } + throw new Ice.UnmarshalOutOfBoundsException(); + } - try - { - return this._buf.getString(len); - } - catch(ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - }, - writeProxy: function(v) + try { - this._instance.proxyFactory().proxyToStream(v, this); - }, - writeOptProxy: function(tag, v) - { - if(v !== undefined) - { - if(this.writeOpt(tag, OptionalFormat.FSize)) - { - var pos = this.startSize(); - this.writeProxy(v); - this.endSize(pos); - } - } - }, - readProxy: function(type) + return this._buf.getString(len); + } + catch(ex) { - return this._instance.proxyFactory().streamToProxy(this, type); - }, - readOptProxy: function(tag, type) + throw new Ice.UnmarshalOutOfBoundsException(); + } + }, + writeProxy: function(v) + { + this._instance.proxyFactory().proxyToStream(v, this); + }, + writeOptProxy: function(tag, v) + { + if(v !== undefined) { - if(this.readOpt(tag, OptionalFormat.FSize)) + if(this.writeOpt(tag, OptionalFormat.FSize)) { - this.skip(4); - return this.readProxy(type); + var pos = this.startSize(); + this.writeProxy(v); + this.endSize(pos); } - else - { - return undefined; - } - }, - writeEnum: function(v) + } + }, + readProxy: function(type) + { + return this._instance.proxyFactory().streamToProxy(this, type); + }, + readOptProxy: function(tag, type) + { + if(this.readOpt(tag, OptionalFormat.FSize)) { - if(this.isWriteEncoding_1_0()) - { - if(v.maxValue < 127) - { - this.writeByte(v.value); - } - else if(v.maxValue < 32767) - { - this.writeShort(v.value); - } - else - { - this.writeInt(v.value); - } - } - else - { - this.writeSize(v.value); - } - }, - readEnum: function(T) + this.skip(4); + return this.readProxy(type); + } + else { - var v; - if(this.getReadEncoding().equals(Ice.Encoding_1_0)) - { - if(T.maxValue < 127) - { - v = this.readByte(); - } - else if(T.maxValue < 32767) - { - v = this.readShort(); - } - else - { - v = this.readInt(); - } - } - else - { - v = this.readSize(); - } - - var e = T.valueOf(v); - if(e === undefined) + return undefined; + } + }, + writeEnum: function(v) + { + if(this.isWriteEncoding_1_0()) + { + if(v.maxValue < 127) { - throw new Ice.MarshalException("enumerator value " + v + " is out of range"); + this.writeByte(v.value); } - return e; - }, - readOptEnum: function(tag, T) - { - if(this.readOpt(tag, OptionalFormat.Size)) + else if(v.maxValue < 32767) { - return this.readEnum(T); + this.writeShort(v.value); } else { - return undefined; + this.writeInt(v.value); } - }, - writeObject: function(v) + } + else { - this.initWriteEncaps(); - this._writeEncapsStack.encoder.writeObject(v); - }, - writeOptObject: function(tag, v) + this.writeSize(v.value); + } + }, + readEnum: function(T) + { + var v; + if(this.getReadEncoding().equals(Ice.Encoding_1_0)) { - if(v !== undefined) + if(T.maxValue < 127) { - if(this.writeOpt(tag, OptionalFormat.Class)) - { - this.writeObject(v); - } + v = this.readByte(); } - }, - readObject: function(patcher, T) - { - this.initReadEncaps(); - // - // BUGFIX: - // With Chrome linux the invokation of readObject on the decoder some times - // calls BasicStream.readObject with the decoder object as this param. - // Use call instead of directly invoke the method to workaround this bug. - // - this._readEncapsStack.decoder.readObject.call( - this._readEncapsStack.decoder, - function(obj){ - if(obj !== null && !(obj.ice_instanceof(T))) - { - ExUtil.throwUOE(T.ice_staticId(), obj); - } - patcher(obj); - }); - }, - readOptObject: function(tag, patcher, T) - { - if(this.readOpt(tag, OptionalFormat.Class)) + else if(T.maxValue < 32767) { - this.readObject(patcher, T); + v = this.readShort(); } else { - patcher(undefined); + v = this.readInt(); } - }, - writeUserException: function(e) + } + else { - this.initWriteEncaps(); - this._writeEncapsStack.encoder.writeUserException(e); - }, - throwException: function() + v = this.readSize(); + } + + var e = T.valueOf(v); + if(e === undefined) { - this.initReadEncaps(); - this._readEncapsStack.decoder.throwException(); - }, - sliceObjects: function(b) + throw new Ice.MarshalException("enumerator value " + v + " is out of range"); + } + return e; + }, + readOptEnum: function(tag, T) + { + if(this.readOpt(tag, OptionalFormat.Size)) { - this._sliceObjects = b; - }, - readOptImpl: function(readTag, expectedFormat) + return this.readEnum(T); + } + else { - var b, v, format, tag, offset; - - if(this.isReadEncoding_1_0()) + return undefined; + } + }, + writeObject: function(v) + { + this.initWriteEncaps(); + this._writeEncapsStack.encoder.writeObject(v); + }, + writeOptObject: function(tag, v) + { + if(v !== undefined) + { + if(this.writeOpt(tag, OptionalFormat.Class)) { - return false; // Optional members aren't supported with the 1.0 encoding. + this.writeObject(v); } - - while(true) - { - if(this._buf.position >= this._readEncapsStack.start + this._readEncapsStack.sz) + } + }, + readObject: function(patcher, T) + { + this.initReadEncaps(); + // + // BUGFIX: + // With Chrome linux the invokation of readObject on the decoder some times + // calls BasicStream.readObject with the decoder object as this param. + // Use call instead of directly invoke the method to workaround this bug. + // + this._readEncapsStack.decoder.readObject.call( + this._readEncapsStack.decoder, + function(obj){ + if(obj !== null && !(obj.ice_instanceof(T))) { - return false; // End of encapsulation also indicates end of optionals. + ExUtil.throwUOE(T.ice_staticId(), obj); } + patcher(obj); + }); + }, + readOptObject: function(tag, patcher, T) + { + if(this.readOpt(tag, OptionalFormat.Class)) + { + this.readObject(patcher, T); + } + else + { + patcher(undefined); + } + }, + writeUserException: function(e) + { + this.initWriteEncaps(); + this._writeEncapsStack.encoder.writeUserException(e); + }, + throwException: function() + { + this.initReadEncaps(); + this._readEncapsStack.decoder.throwException(); + }, + sliceObjects: function(b) + { + this._sliceObjects = b; + }, + readOptImpl: function(readTag, expectedFormat) + { + var b, v, format, tag, offset; - v = this.readByte(); + if(this.isReadEncoding_1_0()) + { + return false; // Optional members aren't supported with the 1.0 encoding. + } - if(v === OPTIONAL_END_MARKER) - { - this._buf.position -= 1; // Rewind. - return false; - } + while(true) + { + if(this._buf.position >= this._readEncapsStack.start + this._readEncapsStack.sz) + { + return false; // End of encapsulation also indicates end of optionals. + } - format = OptionalFormat.valueOf(v & 0x07); // First 3 bits. - tag = v >> 3; - if(tag === 30) - { - tag = this.readSize(); - } + v = this.readByte(); - if(tag > readTag) - { - offset = tag < 30 ? 1 : (tag < 255 ? 2 : 6); // Rewind - this._buf.position -= offset; - return false; // No optional data members with the requested tag. - } - - if(tag < readTag) - { - this.skipOpt(format); // Skip optional data members - } - else - { - if(format !== expectedFormat) - { - throw new Ice.MarshalException("invalid optional data member `" + tag + "': unexpected format"); - } - return true; - } - } - }, - writeOptImpl: function(tag, format) - { - if(this.isWriteEncoding_1_0()) + if(v === OPTIONAL_END_MARKER) { - return false; // Optional members aren't supported with the 1.0 encoding. + this._buf.position -= 1; // Rewind. + return false; } - var v = format.value; - if(tag < 30) + format = OptionalFormat.valueOf(v & 0x07); // First 3 bits. + tag = v >> 3; + if(tag === 30) { - v |= tag << 3; - this.writeByte(v); + tag = this.readSize(); } - else + + if(tag > readTag) { - v |= 0x0F0; // tag = 30 - this.writeByte(v); - this.writeSize(tag); + offset = tag < 30 ? 1 : (tag < 255 ? 2 : 6); // Rewind + this._buf.position -= offset; + return false; // No optional data members with the requested tag. } - return true; - }, - skipOpt: function(format) - { - switch(format) + + if(tag < readTag) { - case OptionalFormat.F1: - this.skip(1); - break; - case OptionalFormat.F2: - this.skip(2); - break; - case OptionalFormat.F4: - this.skip(4); - break; - case OptionalFormat.F8: - this.skip(8); - break; - case OptionalFormat.Size: - this.skipSize(); - break; - case OptionalFormat.VSize: - this.skip(this.readSize()); - break; - case OptionalFormat.FSize: - this.skip(this.readInt()); - break; - case OptionalFormat.Class: - this.readObject(null, Ice.Object); - break; + this.skipOpt(format); // Skip optional data members } - }, - skipOpts: function() - { - var b, v, format; - // - // Skip remaining un-read optional members. - // - while(true) + else { - if(this._buf.position >= this._readEncapsStack.start + this._readEncapsStack.sz) - { - return; // End of encapsulation also indicates end of optionals. - } - - b = this.readByte(); - v = b < 0 ? b + 256 : b; - if(v === OPTIONAL_END_MARKER) + if(format !== expectedFormat) { - return; + throw new Ice.MarshalException("invalid optional data member `" + tag + "': unexpected format"); } - - format = OptionalFormat.valueOf(v & 0x07); // Read first 3 bits. - if((v >> 3) === 30) - { - this.skipSize(); - } - this.skipOpt(format); + return true; } - }, - skip: function(size) + } + }, + writeOptImpl: function(tag, format) + { + if(this.isWriteEncoding_1_0()) { - if(size > this._buf.remaining) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - this._buf.position += size; - }, - skipSize: function() + return false; // Optional members aren't supported with the 1.0 encoding. + } + + var v = format.value; + if(tag < 30) { - var b = this.readByte(); - if(b === 255) - { - this.skip(4); - } - }, - isEmpty: function() + v |= tag << 3; + this.writeByte(v); + } + else { - return this._buf.empty(); - }, - expand: function(n) + v |= 0x0F0; // tag = 30 + this.writeByte(v); + this.writeSize(tag); + } + return true; + }, + skipOpt: function(format) + { + switch(format) + { + case OptionalFormat.F1: + this.skip(1); + break; + case OptionalFormat.F2: + this.skip(2); + break; + case OptionalFormat.F4: + this.skip(4); + break; + case OptionalFormat.F8: + this.skip(8); + break; + case OptionalFormat.Size: + this.skipSize(); + break; + case OptionalFormat.VSize: + this.skip(this.readSize()); + break; + case OptionalFormat.FSize: + this.skip(this.readInt()); + break; + case OptionalFormat.Class: + this.readObject(null, Ice.Object); + break; + } + }, + skipOpts: function() + { + var b, v, format; + // + // Skip remaining un-read optional members. + // + while(true) { - if(!this._unlimited && this._buf && this._buf.position + n > this._messageSizeMax) + if(this._buf.position >= this._readEncapsStack.start + this._readEncapsStack.sz) { - ExUtil.throwMemoryLimitException(this._buf.position + n, this._messageSizeMax); + return; // End of encapsulation also indicates end of optionals. } - this._buf.expand(n); - }, - createObject: function(id) - { - var obj = null, Class; - try + + b = this.readByte(); + v = b < 0 ? b + 256 : b; + if(v === OPTIONAL_END_MARKER) { - var typeId = id.length > 2 ? id.substr(2).replace(/::/g, ".") : ""; - /*jshint -W061 */ - Class = eval(typeId); - /*jshint +W061 */ - if(Class !== undefined) - { - obj = new Class(); - } + return; } - catch(ex) + + format = OptionalFormat.valueOf(v & 0x07); // Read first 3 bits. + if((v >> 3) === 30) { - throw new Ice.NoObjectFactoryException("no object factory", id, ex); + this.skipSize(); } - - return obj; - }, - getTypeId: function(compactId) + this.skipOpt(format); + } + }, + skip: function(size) + { + if(size > this._buf.remaining) { - var typeId = Ice.CompactIdRegistry.get(compactId); - return typeId === undefined ? "" : typeId; - }, - isReadEncoding_1_0: function() + throw new Ice.UnmarshalOutOfBoundsException(); + } + this._buf.position += size; + }, + skipSize: function() + { + var b = this.readByte(); + if(b === 255) { - return this._readEncapsStack !== null ? this._readEncapsStack.encoding_1_0 : this._encoding.equals(Ice.Encoding_1_0); - }, - isWriteEncoding_1_0: function() + this.skip(4); + } + }, + isEmpty: function() + { + return this._buf.empty(); + }, + expand: function(n) + { + if(!this._unlimited && this._buf && this._buf.position + n > this._messageSizeMax) { - return this._writeEncapsStack ? this._writeEncapsStack.encoding_1_0 : this._encoding.equals(Ice.Encoding_1_0); - }, - initReadEncaps: function() + ExUtil.throwMemoryLimitException(this._buf.position + n, this._messageSizeMax); + } + this._buf.expand(n); + }, + createObject: function(id) + { + var obj = null, Class; + try { - if(this._readEncapsStack === null) // Lazy initialization + var typeId = id.length > 2 ? id.substr(2).replace(/::/g, ".") : ""; + /*jshint -W061 */ + Class = __M.type(typeId); + /*jshint +W061 */ + if(Class !== undefined) { - this._readEncapsStack = this._readEncapsCache; - if(this._readEncapsStack !== null) - { - this._readEncapsCache = this._readEncapsCache.next; - } - else - { - this._readEncapsStack = new ReadEncaps(); - } - this._readEncapsStack.setEncoding(this._encoding); - this._readEncapsStack.sz = this._buf.limit; + obj = new Class(); } + } + catch(ex) + { + throw new Ice.NoObjectFactoryException("no object factory", id, ex); + } - if(this._readEncapsStack.decoder === null) // Lazy initialization. + return obj; + }, + getTypeId: function(compactId) + { + var typeId = Ice.CompactIdRegistry.get(compactId); + return typeId === undefined ? "" : typeId; + }, + isReadEncoding_1_0: function() + { + return this._readEncapsStack !== null ? this._readEncapsStack.encoding_1_0 : this._encoding.equals(Ice.Encoding_1_0); + }, + isWriteEncoding_1_0: function() + { + return this._writeEncapsStack ? this._writeEncapsStack.encoding_1_0 : this._encoding.equals(Ice.Encoding_1_0); + }, + initReadEncaps: function() + { + if(this._readEncapsStack === null) // Lazy initialization + { + this._readEncapsStack = this._readEncapsCache; + if(this._readEncapsStack !== null) { - var factoryManager = this._instance.servantFactoryManager(); - if(this._readEncapsStack.encoding_1_0) - { - this._readEncapsStack.decoder = new EncapsDecoder10(this, this._readEncapsStack, this._sliceObjects, factoryManager); - } - else - { - this._readEncapsStack.decoder = new EncapsDecoder11(this, this._readEncapsStack, this._sliceObjects, factoryManager); - } + this._readEncapsCache = this._readEncapsCache.next; } - }, - initWriteEncaps: function() - { - if(!this._writeEncapsStack) // Lazy initialization + else { - this._writeEncapsStack = this._writeEncapsCache; - if(this._writeEncapsStack) - { - this._writeEncapsCache = this._writeEncapsCache.next; - } - else - { - this._writeEncapsStack = new WriteEncaps(); - } - this._writeEncapsStack.setEncoding(this._encoding); + this._readEncapsStack = new ReadEncaps(); } + this._readEncapsStack.setEncoding(this._encoding); + this._readEncapsStack.sz = this._buf.limit; + } - if(this._writeEncapsStack.format === FormatType.DefaultFormat) + if(this._readEncapsStack.decoder === null) // Lazy initialization. + { + var factoryManager = this._instance.servantFactoryManager(); + if(this._readEncapsStack.encoding_1_0) { - this._writeEncapsStack.format = this._instance.defaultsAndOverrides().defaultFormat; + this._readEncapsStack.decoder = new EncapsDecoder10(this, this._readEncapsStack, this._sliceObjects, factoryManager); } - - if(!this._writeEncapsStack.encoder) // Lazy initialization. + else { - if(this._writeEncapsStack.encoding_1_0) - { - this._writeEncapsStack.encoder = new EncapsEncoder10(this, this._writeEncapsStack); - } - else - { - this._writeEncapsStack.encoder = new EncapsEncoder11(this, this._writeEncapsStack); - } + this._readEncapsStack.decoder = new EncapsDecoder11(this, this._readEncapsStack, this._sliceObjects, factoryManager); } - }, - createUserException: function(id) + } + }, + initWriteEncaps: function() + { + if(!this._writeEncapsStack) // Lazy initialization { - var userEx = null, Class; - - try + this._writeEncapsStack = this._writeEncapsCache; + if(this._writeEncapsStack) { - var typeId = id.length > 2 ? id.substr(2).replace(/::/g, ".") : ""; - /*jshint -W061 */ - Class = eval(typeId); - /*jshint +W061 */ - if(Class !== undefined) - { - userEx = new Class(); - } + this._writeEncapsCache = this._writeEncapsCache.next; } - catch(ex) + else { - throw new Ice.MarshalException(ex); + this._writeEncapsStack = new WriteEncaps(); } - - return userEx; + this._writeEncapsStack.setEncoding(this._encoding); } - }); - - var defineProperty = Object.defineProperty; - - defineProperty(BasicStream.prototype, "pos", { - get: function() { return this._buf.position; }, - set: function(n) { this._buf.position = n; } - }); - - defineProperty(BasicStream.prototype, "size", { - get: function() { return this._buf.limit; } - }); - - defineProperty(BasicStream.prototype, "instance", { - get: function() { return this._instance; } - }); - defineProperty(BasicStream.prototype, "closure", { - get: function() { return this._type; }, - set: function(type) { this._type = type; } - }); + if(this._writeEncapsStack.format === FormatType.DefaultFormat) + { + this._writeEncapsStack.format = this._instance.defaultsAndOverrides().defaultFormat; + } - defineProperty(BasicStream.prototype, "buffer", { - get: function() { return this._buf; } - }); - - var defineBuiltinHelper = function(write, read, sz, format) + if(!this._writeEncapsStack.encoder) // Lazy initialization. + { + if(this._writeEncapsStack.encoding_1_0) + { + this._writeEncapsStack.encoder = new EncapsEncoder10(this, this._writeEncapsStack); + } + else + { + this._writeEncapsStack.encoder = new EncapsEncoder11(this, this._writeEncapsStack); + } + } + }, + createUserException: function(id) { - var helper = { - write: function(os, v) { return write.call(os, v); }, - read: function(is) { return read.call(is); }, - writeOpt: function(os, tag, v) { os.writeOptValue(tag, format, write, v); }, - readOpt: function(is, tag) { return is.readOptValue(tag, format, read); }, - }; - defineProperty(helper, "minWireSize", { - get: function() { return sz; } - }); - return helper; - }; + var userEx = null, Class; - var stream = BasicStream.prototype; - Ice.ByteHelper = defineBuiltinHelper(stream.writeByte, stream.readByte, 1, Ice.OptionalFormat.F1); - Ice.BoolHelper = defineBuiltinHelper(stream.writeBool, stream.readBool, 1, Ice.OptionalFormat.F1); - Ice.ShortHelper = defineBuiltinHelper(stream.writeShort, stream.readShort, 2, Ice.OptionalFormat.F2); - Ice.IntHelper = defineBuiltinHelper(stream.writeInt, stream.readInt, 4, Ice.OptionalFormat.F4); - Ice.LongHelper = defineBuiltinHelper(stream.writeLong, stream.readLong, 8, Ice.OptionalFormat.F8); - Ice.FloatHelper = defineBuiltinHelper(stream.writeFloat, stream.readFloat, 4, Ice.OptionalFormat.F4); - Ice.DoubleHelper = defineBuiltinHelper(stream.writeDouble, stream.readDouble, 8, Ice.OptionalFormat.F8); - Ice.StringHelper = defineBuiltinHelper(stream.writeString, stream.readString, 1, Ice.OptionalFormat.VSize); - - Ice.ObjectHelper = { - write: function(os, v) - { - os.writeObject(v); - }, - read: function(is) - { - var o; - is.readObject(function(v) { o = v; }, Ice.Object); - return o; - }, - writeOpt: function(os, tag, v) - { - os.writeOptValue(tag, Ice.OptionalFormat.Class, stream.writeObject, v); - }, - readOpt: function(is, tag) - { - var o; - is.readOptObject(tag, function(v) { o = v; }, Ice.Object); - return o; - }, + try + { + var typeId = id.length > 2 ? id.substr(2).replace(/::/g, ".") : ""; + /*jshint -W061 */ + Class = __M.type(typeId); + /*jshint +W061 */ + if(Class !== undefined) + { + userEx = new Class(); + } + } + catch(ex) + { + throw new Ice.MarshalException(ex); + } + + return userEx; + } +}); + +var defineProperty = Object.defineProperty; + +defineProperty(BasicStream.prototype, "pos", { + get: function() { return this._buf.position; }, + set: function(n) { this._buf.position = n; } +}); + +defineProperty(BasicStream.prototype, "size", { + get: function() { return this._buf.limit; } +}); + +defineProperty(BasicStream.prototype, "instance", { + get: function() { return this._instance; } +}); + +defineProperty(BasicStream.prototype, "closure", { + get: function() { return this._type; }, + set: function(type) { this._type = type; } +}); + +defineProperty(BasicStream.prototype, "buffer", { + get: function() { return this._buf; } +}); + +var defineBuiltinHelper = function(write, read, sz, format) +{ + var helper = { + write: function(os, v) { return write.call(os, v); }, + read: function(is) { return read.call(is); }, + writeOpt: function(os, tag, v) { os.writeOptValue(tag, format, write, v); }, + readOpt: function(is, tag) { return is.readOptValue(tag, format, read); }, }; - - defineProperty(Ice.ObjectHelper, "minWireSize", { - get: function() { return 1; } + defineProperty(helper, "minWireSize", { + get: function() { return sz; } }); - - Ice.BasicStream = BasicStream; - global.Ice = Ice; -}(typeof (global) === "undefined" ? window : global)); + return helper; +}; + +var stream = BasicStream.prototype; +Ice.ByteHelper = defineBuiltinHelper(stream.writeByte, stream.readByte, 1, Ice.OptionalFormat.F1); +Ice.BoolHelper = defineBuiltinHelper(stream.writeBool, stream.readBool, 1, Ice.OptionalFormat.F1); +Ice.ShortHelper = defineBuiltinHelper(stream.writeShort, stream.readShort, 2, Ice.OptionalFormat.F2); +Ice.IntHelper = defineBuiltinHelper(stream.writeInt, stream.readInt, 4, Ice.OptionalFormat.F4); +Ice.LongHelper = defineBuiltinHelper(stream.writeLong, stream.readLong, 8, Ice.OptionalFormat.F8); +Ice.FloatHelper = defineBuiltinHelper(stream.writeFloat, stream.readFloat, 4, Ice.OptionalFormat.F4); +Ice.DoubleHelper = defineBuiltinHelper(stream.writeDouble, stream.readDouble, 8, Ice.OptionalFormat.F8); +Ice.StringHelper = defineBuiltinHelper(stream.writeString, stream.readString, 1, Ice.OptionalFormat.VSize); + +Ice.ObjectHelper = { + write: function(os, v) + { + os.writeObject(v); + }, + read: function(is) + { + var o; + is.readObject(function(v) { o = v; }, Ice.Object); + return o; + }, + writeOpt: function(os, tag, v) + { + os.writeOptValue(tag, Ice.OptionalFormat.Class, stream.writeObject, v); + }, + readOpt: function(is, tag) + { + var o; + is.readOptObject(tag, function(v) { o = v; }, Ice.Object); + return o; + }, +}; + +defineProperty(Ice.ObjectHelper, "minWireSize", { + get: function() { return 1; } +}); + +Ice.BasicStream = BasicStream; +module.exports.Ice = Ice; |