summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2012-06-01 15:18:35 -0700
committerMark Spruiell <mes@zeroc.com>2012-06-01 15:18:35 -0700
commitf8f74e93981c92113c486b6c5b2752de36e95752 (patch)
tree85ba37ff9eed6bf417ad3ab1c3343415c7f9c421 /java/src
parentremoving hasObjects/clearObjects from SlicedData (diff)
downloadice-f8f74e93981c92113c486b6c5b2752de36e95752.tar.bz2
ice-f8f74e93981c92113c486b6c5b2752de36e95752.tar.xz
ice-f8f74e93981c92113c486b6c5b2752de36e95752.zip
Java port
Diffstat (limited to 'java/src')
-rw-r--r--java/src/Ice/AsyncResult.java2
-rw-r--r--java/src/Ice/FormatType.java29
-rw-r--r--java/src/Ice/InputStream.java49
-rw-r--r--java/src/Ice/InputStreamI.java71
-rw-r--r--java/src/Ice/Object.java6
-rw-r--r--java/src/Ice/ObjectImpl.java55
-rw-r--r--java/src/Ice/ObjectReader.java6
-rw-r--r--java/src/Ice/OutputStream.java45
-rw-r--r--java/src/Ice/OutputStreamI.java36
-rw-r--r--java/src/Ice/SliceInfo.java31
-rw-r--r--java/src/Ice/SlicedData.java26
-rw-r--r--java/src/Ice/UserException.java16
-rw-r--r--java/src/Ice/UserExceptionReader.java58
-rw-r--r--java/src/Ice/UserExceptionReaderFactory.java27
-rw-r--r--java/src/Ice/UserExceptionWriter.java15
-rw-r--r--java/src/IceInternal/BasicStream.java2348
-rw-r--r--java/src/IceInternal/DefaultsAndOverrides.java4
-rw-r--r--java/src/IceInternal/Outgoing.java2
-rw-r--r--java/src/IceInternal/UserExceptionFactory.java2
19 files changed, 2021 insertions, 807 deletions
diff --git a/java/src/Ice/AsyncResult.java b/java/src/Ice/AsyncResult.java
index ac7c21b95fb..8450ccf1ffa 100644
--- a/java/src/Ice/AsyncResult.java
+++ b/java/src/Ice/AsyncResult.java
@@ -234,7 +234,7 @@ public class AsyncResult
try
{
_is.startReadEncaps();
- _is.throwException();
+ _is.throwException(null);
}
catch(UserException ex)
{
diff --git a/java/src/Ice/FormatType.java b/java/src/Ice/FormatType.java
new file mode 100644
index 00000000000..067228c10b5
--- /dev/null
+++ b/java/src/Ice/FormatType.java
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Ice;
+
+/**
+ * This enumeration describes the possible formats for classes and exceptions.
+ **/
+public enum FormatType
+{
+ /**
+ * Indicates that no preference was specified.
+ **/
+ DefaultFormat,
+ /**
+ * A minimal format that eliminates the possibility for slicing unrecognized types.
+ **/
+ CompactFormat,
+ /**
+ * Allow slicing and preserve slices for unknown types.
+ **/
+ SlicedFormat
+}
diff --git a/java/src/Ice/InputStream.java b/java/src/Ice/InputStream.java
index aff945a49b6..d7194e757f1 100644
--- a/java/src/Ice/InputStream.java
+++ b/java/src/Ice/InputStream.java
@@ -189,21 +189,48 @@ public interface InputStream
void readObject(ReadObjectCallback cb);
/**
- * Extracts a Slice type ID from the stream.
+ * Extracts a user exception from the stream and throws it.
+ **/
+ void throwException() throws UserException;
+
+ /**
+ * Extracts a user exception from the stream and throws it, using the supplied
+ * factory to instantiate a UserExceptionReader.
*
- * @return The extracted type ID.
+ * @param factory A factory that creates UserExceptionReader instances.
**/
- String readTypeId();
+ void throwException(UserExceptionReaderFactory factory) throws UserException;
/**
- * Extracts a user exception from the stream and throws it.
+ * Marks the start of an Ice object.
**/
- void throwException() throws UserException;
+ void startObject();
+
+ /**
+ * Marks the end of an Ice object.
+ *
+ * @return A SlicedData object containing the preserved slices for unknown types.
+ **/
+ SlicedData endObject(boolean preserve);
+
+ /**
+ * Marks the start of a user exception.
+ **/
+ void startException();
+
+ /**
+ * Marks the end of a user exception.
+ *
+ * @return A SlicedData object containing the preserved slices for unknown types.
+ **/
+ SlicedData endException(boolean preserve);
/**
* Reads the start of an object or exception slice.
+ *
+ * @return The Slice type ID for this slice.
**/
- void startSlice();
+ String startSlice();
/**
* Indicates that the end of an object or exception slice has been reached.
@@ -223,6 +250,11 @@ public interface InputStream
Ice.EncodingVersion startEncapsulation();
/**
+ * Indicates that the end of an encapsulation has been reached.
+ **/
+ void endEncapsulation();
+
+ /**
* Skips over an encapsulation.
*
* @return The encapsulation encoding version.
@@ -230,11 +262,6 @@ public interface InputStream
Ice.EncodingVersion skipEncapsulation();
/**
- * Indicates that the end of an encapsulation has been reached.
- **/
- void endEncapsulation();
-
- /**
* Indicates that unmarshaling is complete, except for any Slice objects. The application must call this method
* only if the stream actually contains Slice objects. Calling <code>readPendingObjects</code> triggers the
* calls to {@link ReadObjectCallback#invoke} that inform the application that unmarshaling of a Slice
diff --git a/java/src/Ice/InputStreamI.java b/java/src/Ice/InputStreamI.java
index 41d4b9600ca..06d1d216a31 100644
--- a/java/src/Ice/InputStreamI.java
+++ b/java/src/Ice/InputStreamI.java
@@ -186,23 +186,70 @@ public class InputStreamI implements InputStream
_is.readObject(new Patcher(cb));
}
- public String
- readTypeId()
+ public void
+ throwException()
+ throws UserException
{
- return _is.readTypeId();
+ _is.throwException(null);
+ }
+
+ private static class UserExceptionFactoryI implements IceInternal.UserExceptionFactory
+ {
+ UserExceptionFactoryI(UserExceptionReaderFactory factory)
+ {
+ _factory = factory;
+ }
+
+ public void
+ createAndThrow(String id)
+ throws UserException
+ {
+ _factory.createAndThrow(id);
+ }
+
+ public void
+ destroy()
+ {
+ }
+
+ private UserExceptionReaderFactory _factory;
}
public void
- throwException()
+ throwException(UserExceptionReaderFactory factory)
throws UserException
{
- _is.throwException();
+ _is.throwException(new UserExceptionFactoryI(factory));
}
public void
+ startObject()
+ {
+ _is.startReadObject();
+ }
+
+ public SlicedData
+ endObject(boolean preserve)
+ {
+ return _is.endReadObject(preserve);
+ }
+
+ public void
+ startException()
+ {
+ _is.startReadException();
+ }
+
+ public SlicedData
+ endException(boolean preserve)
+ {
+ return _is.endReadException(preserve);
+ }
+
+ public String
startSlice()
{
- _is.startReadSlice();
+ return _is.startReadSlice();
}
public void
@@ -223,18 +270,18 @@ public class InputStreamI implements InputStream
return _is.startReadEncaps();
}
- public Ice.EncodingVersion
- skipEncapsulation()
- {
- return _is.skipEncaps();
- }
-
public void
endEncapsulation()
{
_is.endReadEncapsChecked();
}
+ public Ice.EncodingVersion
+ skipEncapsulation()
+ {
+ return _is.skipEncaps();
+ }
+
public void
readPendingObjects()
{
diff --git a/java/src/Ice/Object.java b/java/src/Ice/Object.java
index 8fdee7ddbdd..70461f26b86 100644
--- a/java/src/Ice/Object.java
+++ b/java/src/Ice/Object.java
@@ -163,8 +163,10 @@ public interface Object
DispatchStatus __collocDispatch(IceInternal.Direct request);
void __write(IceInternal.BasicStream __os);
- void __read(IceInternal.BasicStream __is, boolean __rid);
+ void __writeImpl(IceInternal.BasicStream __os);
+ void __read(IceInternal.BasicStream __is);
+ void __readImpl(IceInternal.BasicStream __is);
void __write(OutputStream __outS);
- void __read(InputStream __inS, boolean __rid);
+ void __read(InputStream __inS);
}
diff --git a/java/src/Ice/ObjectImpl.java b/java/src/Ice/ObjectImpl.java
index 8e53c69c532..6d2352d6075 100644
--- a/java/src/Ice/ObjectImpl.java
+++ b/java/src/Ice/ObjectImpl.java
@@ -352,70 +352,41 @@ public abstract class ObjectImpl implements Object, java.lang.Cloneable, java.io
assert(false);
throw new Ice.OperationNotExistException(current.id, current.facet, current.operation);
}
-
+
public DispatchStatus
__collocDispatch(IceInternal.Direct request)
{
return request.run(this);
}
-
public void
__write(IceInternal.BasicStream __os)
{
- __os.writeTypeId(ice_staticId());
- __os.startWriteSlice();
- __os.writeSize(0); // For compatibility with the old AFM.
- __os.endWriteSlice();
}
public void
- __read(IceInternal.BasicStream __is, boolean __rid)
+ __writeImpl(IceInternal.BasicStream __os)
{
- if(__rid)
- {
- __is.readTypeId();
- }
-
- __is.startReadSlice();
+ }
- // For compatibility with the old AFM.
- int sz = __is.readSize();
- if(sz != 0)
- {
- throw new MarshalException();
- }
+ public void
+ __read(IceInternal.BasicStream __is)
+ {
+ }
- __is.endReadSlice();
+ public void
+ __readImpl(IceInternal.BasicStream __is)
+ {
}
public void
__write(Ice.OutputStream __outS)
{
- __outS.writeTypeId(ice_staticId());
- __outS.startSlice();
- __outS.writeSize(0); // For compatibility with the old AFM.
- __outS.endSlice();
}
public void
- __read(Ice.InputStream __inS, boolean __rid)
+ __read(Ice.InputStream __inS)
{
- if(__rid)
- {
- __inS.readTypeId();
- }
-
- __inS.startSlice();
-
- // For compatibility with the old AFM.
- int sz = __inS.readSize();
- if(sz != 0)
- {
- throw new MarshalException();
- }
-
- __inS.endSlice();
}
private static String
@@ -443,11 +414,11 @@ public abstract class ObjectImpl implements Object, java.lang.Cloneable, java.io
{
if(expected != received)
{
- if(expected == Ice.OperationMode.Idempotent
+ if(expected == Ice.OperationMode.Idempotent
&& received == Ice.OperationMode.Nonmutating)
{
//
- // Fine: typically an old client still using the
+ // Fine: typically an old client still using the
// deprecated nonmutating keyword
//
}
diff --git a/java/src/Ice/ObjectReader.java b/java/src/Ice/ObjectReader.java
index e5ffb26ad11..498042c51c7 100644
--- a/java/src/Ice/ObjectReader.java
+++ b/java/src/Ice/ObjectReader.java
@@ -23,7 +23,7 @@ public abstract class ObjectReader extends ObjectImpl
* by the unmarshaling code in case the type ID has already been read as part
* of other unmarshaling activities.
**/
- public abstract void read(InputStream in, boolean rid);
+ public abstract void read(InputStream in);
public void
__write(IceInternal.BasicStream os)
@@ -32,9 +32,9 @@ public abstract class ObjectReader extends ObjectImpl
}
public void
- __read(IceInternal.BasicStream is, boolean rid)
+ __read(IceInternal.BasicStream is)
{
InputStream stream = (InputStream)is.closure();
- read(stream, rid);
+ read(stream);
}
}
diff --git a/java/src/Ice/OutputStream.java b/java/src/Ice/OutputStream.java
index 8ed1d4f105e..e86c20983a7 100644
--- a/java/src/Ice/OutputStream.java
+++ b/java/src/Ice/OutputStream.java
@@ -175,26 +175,53 @@ public interface OutputStream
void writeObject(Ice.Object v);
/**
- * Writes a Slice type ID to the stream.
+ * Writes a user exception to the stream.
*
- * @param id The Slice type ID to write.
+ * @param id The user exception to write.
**/
- void writeTypeId(String id);
+ void writeException(UserException ex);
/**
- * Writes a user exception to the stream.
+ * Select the format to be used for classes and exceptions.
*
- * @param id The user exception to write.
+ * @param format Specify the compact or sliced format.
**/
- void writeException(UserException ex);
+ void format(FormatType format);
/**
- * Writes the start of a slice to the stream.
+ * Marks the start of an Ice object.
+ *
+ * @param slicedData Preserved slices for this object, or null.
+ **/
+ void startObject(SlicedData slicedData);
+
+ /**
+ * Marks the end of an Ice object.
+ **/
+ void endObject();
+
+ /**
+ * Marks the start of a user exception.
+ *
+ * @param slicedData Preserved slices for this exception, or null.
+ **/
+ void startException(SlicedData slicedData);
+
+ /**
+ * Marks the end of a user exception.
+ **/
+ void endException();
+
+ /**
+ * Marks the start of a new slice for an Ice object or user exception.
+ *
+ * @param typeId The Slice type ID corresponding to this slice.
+ * @param last True if this is the last slice, false otherwise.
**/
- void startSlice();
+ void startSlice(String typeId, boolean last);
/**
- * Ends the previous slice.
+ * Marks the end of a slice for an Ice object or user exception.
**/
void endSlice();
diff --git a/java/src/Ice/OutputStreamI.java b/java/src/Ice/OutputStreamI.java
index df38a394b14..21a1d177c84 100644
--- a/java/src/Ice/OutputStreamI.java
+++ b/java/src/Ice/OutputStreamI.java
@@ -160,21 +160,45 @@ public class OutputStreamI implements OutputStream
}
public void
- writeTypeId(String id)
+ writeException(UserException v)
{
- _os.writeTypeId(id);
+ _os.writeUserException(v);
}
public void
- writeException(UserException v)
+ format(FormatType format)
{
- _os.writeUserException(v);
+ _os.format(format);
+ }
+
+ public void
+ startObject(SlicedData slicedData)
+ {
+ _os.startWriteObject(slicedData);
+ }
+
+ public void
+ endObject()
+ {
+ _os.endWriteObject();
+ }
+
+ public void
+ startException(SlicedData slicedData)
+ {
+ _os.startWriteException(slicedData);
+ }
+
+ public void
+ endException()
+ {
+ _os.endWriteException();
}
public void
- startSlice()
+ startSlice(String typeId, boolean last)
{
- _os.startWriteSlice();
+ _os.startWriteSlice(typeId, last);
}
public void
diff --git a/java/src/Ice/SliceInfo.java b/java/src/Ice/SliceInfo.java
new file mode 100644
index 00000000000..3f3494aa920
--- /dev/null
+++ b/java/src/Ice/SliceInfo.java
@@ -0,0 +1,31 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Ice;
+
+/**
+ * SliceInfo encapsulates the details of a slice for an unknown class or exception type.
+ **/
+public class SliceInfo
+{
+ /**
+ * The Slice type ID for this slice.
+ **/
+ public String typeId;
+
+ /**
+ * The encoded bytes for this slice, including the leading size integer.
+ **/
+ public byte[] bytes;
+
+ /**
+ * The Ice objects referenced by this slice.
+ **/
+ public Ice.Object[] objects;
+}
diff --git a/java/src/Ice/SlicedData.java b/java/src/Ice/SlicedData.java
new file mode 100644
index 00000000000..964866e7d42
--- /dev/null
+++ b/java/src/Ice/SlicedData.java
@@ -0,0 +1,26 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Ice;
+
+/**
+ * SlicedData holds the slices of unknown class or exception types.
+ **/
+public class SlicedData
+{
+ public SlicedData(SliceInfo[] slices)
+ {
+ this.slices = slices;
+ }
+
+ /**
+ * The details of each slice, in order of most-derived to least-derived.
+ **/
+ public SliceInfo[] slices;
+}
diff --git a/java/src/Ice/UserException.java b/java/src/Ice/UserException.java
index 7372560c5de..6beea1ed671 100644
--- a/java/src/Ice/UserException.java
+++ b/java/src/Ice/UserException.java
@@ -73,7 +73,13 @@ public abstract class UserException extends Exception implements Cloneable
__write(IceInternal.BasicStream __os);
public abstract void
- __read(IceInternal.BasicStream __is, boolean __rid);
+ __writeImpl(IceInternal.BasicStream __os);
+
+ public abstract void
+ __read(IceInternal.BasicStream __is);
+
+ public abstract void
+ __readImpl(IceInternal.BasicStream __is);
public void
__write(Ice.OutputStream __outS)
@@ -82,14 +88,8 @@ public abstract class UserException extends Exception implements Cloneable
}
public void
- __read(Ice.InputStream __inS, boolean __rid)
+ __read(Ice.InputStream __inS)
{
assert(false);
}
-
- public boolean
- __usesClasses()
- {
- return false;
- }
}
diff --git a/java/src/Ice/UserExceptionReader.java b/java/src/Ice/UserExceptionReader.java
new file mode 100644
index 00000000000..375756b7228
--- /dev/null
+++ b/java/src/Ice/UserExceptionReader.java
@@ -0,0 +1,58 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Ice;
+
+/**
+ * Allows a Dynamic Ice application to instantiate a user exception and
+ * intercept its unmarshaling.
+ *
+ * @see InputStream
+ **/
+public abstract class UserExceptionReader extends UserException
+{
+ /**
+ * Creates a reader for the given communicator.
+ **/
+ public UserExceptionReader(Communicator communicator)
+ {
+ _communicator = communicator;
+ }
+
+ /**
+ * Unmarshal an exception from an output stream.
+ *
+ * @param in The input stream.
+ **/
+ public abstract void read(Ice.InputStream is);
+
+ public void __write(IceInternal.BasicStream os)
+ {
+ assert(false);
+ }
+
+ public void __read(IceInternal.BasicStream is)
+ {
+ InputStream stream = (InputStream)is.closure();
+ assert(stream != null);
+ read(stream);
+ }
+
+ public void __write(Ice.OutputStream os)
+ {
+ assert(false);
+ }
+
+ public void __read(Ice.InputStream is)
+ {
+ read(is);
+ }
+
+ protected Communicator _communicator;
+}
diff --git a/java/src/Ice/UserExceptionReaderFactory.java b/java/src/Ice/UserExceptionReaderFactory.java
new file mode 100644
index 00000000000..376b013c144
--- /dev/null
+++ b/java/src/Ice/UserExceptionReaderFactory.java
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Ice;
+
+/**
+ * Creates a UserExceptionReader for extracting a user exception
+ * from an input stream.
+ *
+ * @see InputStream
+ **/
+public interface UserExceptionReaderFactory
+{
+ /**
+ * Creates and throws a UserExceptionReader instance.
+ *
+ * @param typeId The Slice type ID of the user exception to be instantiated.
+ **/
+ void createAndThrow(String typeId)
+ throws UserExceptionReader;
+}
diff --git a/java/src/Ice/UserExceptionWriter.java b/java/src/Ice/UserExceptionWriter.java
index 053eab8b612..04f33c60aee 100644
--- a/java/src/Ice/UserExceptionWriter.java
+++ b/java/src/Ice/UserExceptionWriter.java
@@ -33,15 +33,6 @@ public abstract class UserExceptionWriter extends UserException
public abstract void
write(Ice.OutputStream os);
- /**
- * Indicates whether the encapsulated exception contains one or more
- * data members that are instances of Slice classes.
- *
- * @return True if the exception contains classes, or false otherwise.
- **/
- public abstract boolean
- usesClasses();
-
public void
__write(IceInternal.BasicStream os)
{
@@ -71,11 +62,5 @@ public abstract class UserExceptionWriter extends UserException
assert(false);
}
- public boolean
- __usesClasses()
- {
- return usesClasses();
- }
-
protected Communicator _communicator;
}
diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java
index 28491f89959..3e881b87919 100644
--- a/java/src/IceInternal/BasicStream.java
+++ b/java/src/IceInternal/BasicStream.java
@@ -33,24 +33,22 @@ public class BasicStream
initialize(Instance instance, Ice.EncodingVersion encoding, boolean unlimited, boolean direct)
{
_instance = instance;
- _encoding = encoding;
_buf = new Buffer(_instance.messageSizeMax(), direct);
_closure = null;
+ _encoding = encoding;
_unlimited = unlimited;
_readEncapsStack = null;
_writeEncapsStack = null;
_readEncapsCache = null;
_writeEncapsCache = null;
-
- _traceSlicing = -1;
_sliceObjects = true;
_messageSizeMax = _instance.messageSizeMax(); // Cached for efficiency.
_startSeq = -1;
- _objectList = null;
+ _format = _instance.defaultsAndOverrides().defaultFormat;
}
//
@@ -87,11 +85,6 @@ public class BasicStream
_startSeq = -1;
- if(_objectList != null)
- {
- _objectList.clear();
- }
-
_sliceObjects = true;
}
@@ -120,37 +113,25 @@ public class BasicStream
{
assert(_instance == other._instance);
- Object tmpClosure = other._closure;
- other._closure = _closure;
- _closure = tmpClosure;
-
Buffer tmpBuf = other._buf;
other._buf = _buf;
_buf = tmpBuf;
- ReadEncaps tmpRead = other._readEncapsStack;
- other._readEncapsStack = _readEncapsStack;
- _readEncapsStack = tmpRead;
-
- tmpRead = other._readEncapsCache;
- other._readEncapsCache = _readEncapsCache;
- _readEncapsCache = tmpRead;
-
- WriteEncaps tmpWrite = other._writeEncapsStack;
- other._writeEncapsStack = _writeEncapsStack;
- _writeEncapsStack = tmpWrite;
-
- tmpWrite = other._writeEncapsCache;
- other._writeEncapsCache = _writeEncapsCache;
- _writeEncapsCache = tmpWrite;
+ Object tmpClosure = other._closure;
+ other._closure = _closure;
+ _closure = tmpClosure;
- int tmpReadSlice = other._readSlice;
- other._readSlice = _readSlice;
- _readSlice = tmpReadSlice;
+ //
+ // Swap is never called for BasicStreams that have encapsulations being read/write.
+ //
+ assert(_readEncapsStack == null);
+ assert(_writeEncapsStack == null);
+ assert(other._readEncapsStack == null);
+ assert(other._writeEncapsStack == null);
- int tmpWriteSlice = other._writeSlice;
- other._writeSlice = _writeSlice;
- _writeSlice = tmpWriteSlice;
+ boolean tmpUnlimited = other._unlimited;
+ other._unlimited = _unlimited;
+ _unlimited = tmpUnlimited;
int tmpStartSeq = other._startSeq;
other._startSeq = _startSeq;
@@ -160,13 +141,9 @@ public class BasicStream
other._minSeqSize = _minSeqSize;
_minSeqSize = tmpMinSeqSize;
- java.util.ArrayList<Ice.Object> tmpObjectList = other._objectList;
- other._objectList = _objectList;
- _objectList = tmpObjectList;
-
- boolean tmpUnlimited = other._unlimited;
- other._unlimited = _unlimited;
- _unlimited = tmpUnlimited;
+ Ice.FormatType tmpFormat = other._format;
+ other._format = _format;
+ _format = tmpFormat;
}
public void
@@ -199,6 +176,71 @@ public class BasicStream
}
public void
+ format(Ice.FormatType format)
+ {
+ if(format != Ice.FormatType.DefaultFormat)
+ {
+ _format = format;
+ }
+ }
+
+ public void
+ startWriteObject(Ice.SlicedData data)
+ {
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.startObject(data);
+ }
+
+ public void
+ endWriteObject()
+ {
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.endObject();
+ }
+
+ public void
+ startReadObject()
+ {
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ _readEncapsStack.decoder.startObject();
+ }
+
+ public Ice.SlicedData
+ endReadObject(boolean preserve)
+ {
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ return _readEncapsStack.decoder.endObject(preserve);
+ }
+
+ public void
+ startWriteException(Ice.SlicedData data)
+ {
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.startException(data);
+ }
+
+ public void
+ endWriteException()
+ {
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.endException();
+ }
+
+ public void
+ startReadException()
+ {
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ _readEncapsStack.decoder.startException();
+ }
+
+ public Ice.SlicedData
+ endReadException(boolean preserve)
+ {
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ return _readEncapsStack.decoder.endException(preserve);
+ }
+
+ public void
startWriteEncaps()
{
//
@@ -206,7 +248,7 @@ public class BasicStream
// encapsulation encoding version if there's a current write
// encapsulation, otherwise, use the stream encoding version.
//
-
+
if(_writeEncapsStack != null)
{
startWriteEncaps(_writeEncapsStack.encoding);
@@ -221,21 +263,20 @@ public class BasicStream
startWriteEncaps(Ice.EncodingVersion encoding)
{
Protocol.checkSupportedEncoding(encoding);
-
+
+ WriteEncaps curr = _writeEncapsCache;
+ if(curr != null)
{
- WriteEncaps curr = _writeEncapsCache;
- if(curr != null)
- {
- curr.reset();
- _writeEncapsCache = _writeEncapsCache.next;
- }
- else
- {
- curr = new WriteEncaps();
- }
- curr.next = _writeEncapsStack;
- _writeEncapsStack = curr;
+ curr.reset();
+ _writeEncapsCache = _writeEncapsCache.next;
}
+ else
+ {
+ curr = new WriteEncaps();
+ }
+ curr.next = _writeEncapsStack;
+ _writeEncapsStack = curr;
+
_writeEncapsStack.encoding = encoding;
_writeEncapsStack.start = _buf.size();
@@ -247,6 +288,12 @@ public class BasicStream
endWriteEncaps()
{
assert(_writeEncapsStack != null);
+
+ if(_writeEncapsStack.encoder != null)
+ {
+ _writeEncapsStack.encoder.writePendingObjects();
+ }
+
int start = _writeEncapsStack.start;
int sz = _buf.size() - start; // Size includes size and version.
_buf.b.putInt(start, sz);
@@ -265,7 +312,6 @@ public class BasicStream
{
throw new Ice.EncapsulationException("not in an encapsulation");
}
-
endWriteEncaps();
}
@@ -277,7 +323,7 @@ public class BasicStream
encoding.__write(this);
}
- public void
+ public void
writeEncaps(byte[] v)
{
if(v.length < 6)
@@ -288,7 +334,7 @@ public class BasicStream
_buf.b.put(v);
}
- public Ice.EncodingVersion
+ public Ice.EncodingVersion
getWriteEncoding()
{
return _writeEncapsStack != null ? _writeEncapsStack.encoding : _encoding;
@@ -297,36 +343,34 @@ public class BasicStream
public Ice.EncodingVersion
startReadEncaps()
{
+ ReadEncaps curr = _readEncapsCache;
+ if(curr != null)
{
- ReadEncaps curr = _readEncapsCache;
- if(curr != null)
- {
- curr.reset();
- _readEncapsCache = _readEncapsCache.next;
- }
- else
- {
- curr = new ReadEncaps();
- }
- curr.next = _readEncapsStack;
- _readEncapsStack = curr;
+ curr.reset();
+ _readEncapsCache = _readEncapsCache.next;
}
+ else
+ {
+ curr = new ReadEncaps();
+ }
+ curr.next = _readEncapsStack;
+ _readEncapsStack = curr;
_readEncapsStack.start = _buf.b.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
+ // 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.
//
+ //
int sz = readInt();
if(sz < 6)
{
throw new Ice.UnmarshalOutOfBoundsException();
}
-
if(sz - 4 > _buf.b.remaining())
{
throw new Ice.UnmarshalOutOfBoundsException();
@@ -343,6 +387,12 @@ public class BasicStream
endReadEncaps()
{
assert(_readEncapsStack != null);
+
+ if(_readEncapsStack.decoder != null)
+ {
+ _readEncapsStack.decoder.readPendingObjects();
+ }
+
if(_buf.b.position() != _readEncapsStack.start + _readEncapsStack.sz)
{
if(_buf.b.position() + 1 != _readEncapsStack.start + _readEncapsStack.sz)
@@ -377,14 +427,15 @@ public class BasicStream
skipEmptyEncaps(Ice.EncodingVersion encoding)
{
int sz = readInt();
- if(sz < 6)
+ if(sz != 6)
{
- throw new Ice.UnmarshalOutOfBoundsException();
+ throw new Ice.EncapsulationException();
}
- if(sz != 6)
+ final int pos = _buf.b.position();
+ if(pos + 2 > _buf.size())
{
- throw new Ice.EncapsulationException();
+ throw new Ice.UnmarshalOutOfBoundsException();
}
if(encoding != null)
@@ -393,7 +444,7 @@ public class BasicStream
}
else
{
- _buf.b.position(_buf.b.position() + 2);
+ _buf.b.position(pos + 2);
}
}
@@ -404,11 +455,10 @@ public class BasicStream
{
throw new Ice.EncapsulationException("not in an encapsulation");
}
-
endReadEncaps();
}
- public byte[]
+ public byte[]
readEncaps(Ice.EncodingVersion encoding)
{
int sz = readInt();
@@ -421,13 +471,13 @@ public class BasicStream
{
throw new Ice.UnmarshalOutOfBoundsException();
}
-
+
if(encoding != null)
{
encoding.__read(this);
_buf.b.position(_buf.b.position() - 6);
}
- else
+ else
{
_buf.b.position(_buf.b.position() - 4);
}
@@ -444,8 +494,8 @@ public class BasicStream
}
}
- public Ice.EncodingVersion
- getReadEncoding()
+ public Ice.EncodingVersion
+ getReadEncoding()
{
return _readEncapsStack != null ? _readEncapsStack.encoding : _encoding;
}
@@ -479,101 +529,56 @@ public class BasicStream
}
public void
- startWriteSlice()
+ startWriteSlice(String typeId, boolean last)
{
- writeInt(0); // Placeholder for the slice length.
- _writeSlice = _buf.size();
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.startSlice(typeId, last);
}
- public void
+ public void
endWriteSlice()
{
- final int sz = _buf.size() - _writeSlice + 4;
- _buf.b.putInt(_writeSlice - 4, sz);
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.endSlice();
}
- public void
- startReadSlice()
+ public String
+ startReadSlice() // Returns type ID of next slice
{
- int sz = readInt();
- if(sz < 4)
- {
- throw new Ice.UnmarshalOutOfBoundsException();
- }
- _readSlice = _buf.b.position();
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ return _readEncapsStack.decoder.startSlice();
}
- public void
+ public void
endReadSlice()
{
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ _readEncapsStack.decoder.endSlice();
}
- public void
+ public void
skipSlice()
{
- int sz = readInt();
- if(sz < 4)
- {
- throw new Ice.UnmarshalOutOfBoundsException();
- }
- try
- {
- _buf.b.position(_buf.b.position() + sz - 4);
- }
- catch(IllegalArgumentException ex)
- {
- throw new Ice.UnmarshalOutOfBoundsException();
- }
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ _readEncapsStack.decoder.skipSlice();
}
- public int
- readAndCheckSeqSize(int minSize)
+ public void
+ readPendingObjects()
{
- int sz = readSize();
-
- if(sz == 0)
- {
- return 0;
- }
-
- //
- // 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(_startSeq == -1 || _buf.b.position() > (_startSeq + _minSeqSize))
- {
- _startSeq = _buf.b.position();
- _minSeqSize = sz * minSize;
- }
- else
+ if(_readEncapsStack != null && _readEncapsStack.decoder != null)
{
- _minSeqSize += sz * minSize;
+ _readEncapsStack.decoder.readPendingObjects();
}
-
- //
- // 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(_startSeq + _minSeqSize > _buf.size())
+ }
+
+ public void
+ writePendingObjects()
+ {
+ if(_writeEncapsStack != null && _writeEncapsStack.encoder != null)
{
- throw new Ice.UnmarshalOutOfBoundsException();
+ _writeEncapsStack.encoder.writePendingObjects();
}
-
- return sz;
}
public void
@@ -592,6 +597,16 @@ public class BasicStream
}
}
+ public void
+ writeSizeSeq(java.util.List<Integer> v)
+ {
+ writeSize(v.size());
+ for(Integer n : v)
+ {
+ writeSize(n);
+ }
+ }
+
public int
readSize()
{
@@ -618,62 +633,71 @@ public class BasicStream
}
}
- public void
- writeTypeId(String id)
+ public int[]
+ readSizeSeq()
{
- if(_writeEncapsStack == null || _writeEncapsStack.typeIdMap == null)
- {
- //
- // writeObject() must be called first.
- //
- throw new Ice.MarshalException("type ids require an encapsulation");
- }
+ int sz = readSize();
+ int[] v = new int[sz];
- Integer index = _writeEncapsStack.typeIdMap.get(id);
- if(index != null)
- {
- writeBool(true);
- writeSize(index.intValue());
- }
- else
+ if(sz > 0)
{
- index = Integer.valueOf(++_writeEncapsStack.typeIdIndex);
- _writeEncapsStack.typeIdMap.put(id, index);
- writeBool(false);
- writeString(id);
+ for(int n = 0; n < sz; ++n)
+ {
+ v[n] = readSize();
+ }
}
+
+ return v;
}
- public String
- readTypeId()
+ public int
+ readAndCheckSeqSize(int minSize)
{
- if(_readEncapsStack == null || _readEncapsStack.typeIdMap == null)
+ int sz = readSize();
+
+ if(sz == 0)
{
- //
- // readObject() must be called first.
- //
- throw new Ice.MarshalException("type ids require an encapsulation");
+ return 0;
}
- String id;
- Integer index;
- final boolean isIndex = readBool();
- if(isIndex)
+ //
+ // 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(_startSeq == -1 || _buf.b.position() > (_startSeq + _minSeqSize))
{
- index = Integer.valueOf(readSize());
- id = _readEncapsStack.typeIdMap.get(index);
- if(id == null)
- {
- throw new Ice.UnmarshalOutOfBoundsException();
- }
+ _startSeq = _buf.b.position();
+ _minSeqSize = sz * minSize;
}
else
{
- id = readString();
- index = Integer.valueOf(++_readEncapsStack.typeIdIndex);
- _readEncapsStack.typeIdMap.put(index, id);
+ _minSeqSize += sz * minSize;
}
- return id;
+
+ //
+ // 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(_startSeq + _minSeqSize > _buf.size())
+ {
+ throw new Ice.UnmarshalOutOfBoundsException();
+ }
+
+ return sz;
}
public void
@@ -718,6 +742,20 @@ public class BasicStream
}
public void
+ writeOpt(int tag, int type)
+ {
+ assert(_writeEncapsStack != null && _writeEncapsStack.encoder != null);
+ _writeEncapsStack.encoder.writeOpt(tag, type);
+ }
+
+ public boolean
+ readOpt(int tag, int expectedType)
+ {
+ assert(_readEncapsStack != null && _readEncapsStack.decoder != null);
+ return _readEncapsStack.decoder.readOpt(tag, expectedType);
+ }
+
+ public void
writeByte(byte v)
{
expand(1);
@@ -735,6 +773,12 @@ public class BasicStream
}
public void
+ writeByteAt(byte v, int dest)
+ {
+ _buf.b.put(dest, v);
+ }
+
+ public void
writeByteSeq(byte[] v)
{
if(v == null)
@@ -839,6 +883,12 @@ public class BasicStream
}
public void
+ writeBoolAt(boolean v, int dest)
+ {
+ _buf.b.put(dest, v ? (byte)1 : (byte)0);
+ }
+
+ public void
writeBoolSeq(boolean[] v)
{
if(v == null)
@@ -982,6 +1032,12 @@ public class BasicStream
}
public void
+ writeIntAt(int v, int dest)
+ {
+ _buf.b.putInt(dest, v);
+ }
+
+ public void
writeIntSeq(int[] v)
{
if(v == null)
@@ -1299,7 +1355,6 @@ public class BasicStream
}
else
{
-
//
// Check the buffer has enough bytes to read.
//
@@ -1394,391 +1449,31 @@ public class BasicStream
public void
writeObject(Ice.Object v)
{
- if(_writeEncapsStack == null) // Lazy initialization
- {
- _writeEncapsStack = _writeEncapsCache;
- if(_writeEncapsStack != null)
- {
- _writeEncapsCache = _writeEncapsCache.next;
- }
- else
- {
- _writeEncapsStack = new WriteEncaps();
- }
- }
-
- if(_writeEncapsStack.toBeMarshaledMap == null) // Lazy initialization
- {
- _writeEncapsStack.toBeMarshaledMap = new java.util.IdentityHashMap<Ice.Object, Integer>();
- _writeEncapsStack.marshaledMap = new java.util.IdentityHashMap<Ice.Object, Integer>();
- _writeEncapsStack.typeIdMap = new java.util.TreeMap<String, Integer>();
- }
- if(v != null)
- {
- //
- // Look for this instance in the to-be-marshaled map.
- //
- Integer p = _writeEncapsStack.toBeMarshaledMap.get(v);
- if(p == null)
- {
- //
- // Didn't find it, try the marshaled map next.
- //
- Integer q = _writeEncapsStack.marshaledMap.get(v);
- if(q == null)
- {
- //
- // We haven't seen this instance previously,
- // create a new index, and insert it into the
- // to-be-marshaled map.
- //
- q = Integer.valueOf(++_writeEncapsStack.writeIndex);
- _writeEncapsStack.toBeMarshaledMap.put(v, q);
- }
- p = q;
- }
- writeInt(-p.intValue());
- }
- else
- {
- writeInt(0); // Write null reference
- }
+ initWriteEncaps();
+ _writeEncapsStack.encoder.writeObject(v);
}
public void
readObject(Patcher patcher)
{
- Ice.Object v = null;
-
- if(_readEncapsStack == null) // Lazy initialization
- {
- _readEncapsStack = _readEncapsCache;
- if(_readEncapsStack != null)
- {
- _readEncapsCache = _readEncapsCache.next;
- }
- else
- {
- _readEncapsStack = new ReadEncaps();
- }
- }
-
- if(_readEncapsStack.patchMap == null) // Lazy initialization
- {
- _readEncapsStack.patchMap = new java.util.TreeMap<Integer, java.util.LinkedList<Patcher> >();
- _readEncapsStack.unmarshaledMap = new java.util.TreeMap<Integer, Ice.Object>();
- _readEncapsStack.typeIdMap = new java.util.TreeMap<Integer, String>();
- }
-
- int index = readInt();
-
- if(patcher != null)
- {
- if(index == 0)
- {
- patcher.patch(null);
- return;
- }
-
- if(index < 0)
- {
- Integer i = Integer.valueOf(-index);
- java.util.LinkedList<Patcher> patchlist = _readEncapsStack.patchMap.get(i);
- if(patchlist == null)
- {
- //
- // We have no outstanding instances to be patched for
- // this index, so make a new entry in the patch map.
- //
- patchlist = new java.util.LinkedList<Patcher>();
- _readEncapsStack.patchMap.put(i, patchlist);
- }
- //
- // Append a patcher for this instance and see if we can
- // patch the instance. (The instance may have been
- // unmarshaled previously.)
- //
- patchlist.add(patcher);
- patchReferences(null, i);
- return;
- }
- }
- if(index < 0)
- {
- throw new Ice.MarshalException("Invalid class instance index");
- }
-
- String mostDerivedId = readTypeId();
- String id = mostDerivedId;
-
- while(true)
- {
- //
- // If we slice all the way down to Ice::Object, we throw
- // because Ice::Object is abstract.
- //
- if(id.equals(Ice.ObjectImpl.ice_staticId()))
- {
- throw new Ice.NoObjectFactoryException("", mostDerivedId);
- }
-
- //
- // Try to find a factory registered for the specific type.
- //
- Ice.ObjectFactory userFactory = _instance.servantFactoryManager().find(id);
- if(userFactory != null)
- {
- v = userFactory.create(id);
- }
-
- //
- // If that fails, invoke the default factory if one has
- // been registered.
- //
- if(v == null)
- {
- userFactory = _instance.servantFactoryManager().find("");
- if(userFactory != null)
- {
- v = userFactory.create(id);
- }
- }
-
- //
- // Last chance: check the table of static factories (i.e.,
- // automatically generated factories for concrete
- // classes).
- //
- if(v == null)
- {
- userFactory = loadObjectFactory(id);
- if(userFactory != null)
- {
- v = userFactory.create(id);
- }
- }
-
- if(v == null)
- {
- if(_sliceObjects)
- {
- //
- // Performance sensitive, so we use lazy
- // initialization for tracing.
- //
- if(_traceSlicing == -1)
- {
- _traceSlicing = _instance.traceLevels().slicing;
- _slicingCat = _instance.traceLevels().slicingCat;
- }
- if(_traceSlicing > 0)
- {
- TraceUtil.traceSlicing("class", id, _slicingCat, _instance.initializationData().logger);
- }
- skipSlice(); // Slice off this derived part -- we don't understand it.
- id = readTypeId(); // Read next id for next iteration.
- continue;
- }
- else
- {
- Ice.NoObjectFactoryException ex = new Ice.NoObjectFactoryException();
- ex.type = id;
- throw ex;
- }
- }
-
- Integer i = Integer.valueOf(index);
- _readEncapsStack.unmarshaledMap.put(i, v);
-
- //
- // Record each object instance so that readPendingObjects
- // can invoke ice_postUnmarshal after all objects have
- // been unmarshaled.
- //
- if(_objectList == null)
- {
- _objectList = new java.util.ArrayList<Ice.Object>();
- }
- _objectList.add(v);
-
- v.__read(this, false);
- patchReferences(i, null);
- return;
- }
+ assert(patcher != null);
+ initReadEncaps();
+ _readEncapsStack.decoder.readObject(patcher);
}
public void
- writeUserException(Ice.UserException v)
+ writeUserException(Ice.UserException e)
{
- writeBool(v.__usesClasses());
- v.__write(this);
- if(v.__usesClasses())
- {
- writePendingObjects();
- }
+ initWriteEncaps();
+ _writeEncapsStack.encoder.writeUserException(e);
}
public void
- throwException()
+ throwException(UserExceptionFactory factory)
throws Ice.UserException
{
- boolean usesClasses = readBool();
-
- String id = readString();
- final String origId = id;
-
- for(;;)
- {
- //
- // Look for a factory for this ID.
- //
- UserExceptionFactory factory = getUserExceptionFactory(id);
-
- if(factory != null)
- {
- //
- // Got factory -- get the factory to instantiate the
- // exception, initialize the exception members, and
- // throw the exception.
- //
- try
- {
- factory.createAndThrow();
- }
- catch(Ice.UserException ex)
- {
- ex.__read(this, false);
- if(usesClasses)
- {
- readPendingObjects();
- }
- throw ex;
- }
- }
- else
- {
- //
- // Performance sensitive, so we use lazy
- // initialization for tracing.
- //
- if(_traceSlicing == -1)
- {
- _traceSlicing = _instance.traceLevels().slicing;
- _slicingCat = _instance.traceLevels().slicingCat;
- }
- if(_traceSlicing > 0)
- {
- TraceUtil.traceSlicing("exception", id, _slicingCat, _instance.initializationData().logger);
- }
-
- skipSlice(); // Slice off what we don't understand.
-
- try
- {
- id = readString(); // Read type id for next slice.
- }
- catch(Ice.UnmarshalOutOfBoundsException ex)
- {
- //
- // When readString raises this exception it means we've seen the last slice,
- // so we set the reason member to a more helpful message.
- //
- throw new Ice.UnmarshalOutOfBoundsException("unknown exception type `" + origId + "'", ex);
- }
- }
- }
-
- //
- // The only way out of the loop above is to find an exception
- // for which the receiver has a factory. If this does not
- // happen, sender and receiver disagree about the Slice
- // definitions they use. In that case, the receiver will
- // eventually fail to read another type ID and throw a
- // MarshalException.
- //
- }
-
- public void
- writePendingObjects()
- {
- if(_writeEncapsStack != null && _writeEncapsStack.toBeMarshaledMap != null)
- {
- while(_writeEncapsStack.toBeMarshaledMap.size() > 0)
- {
- java.util.IdentityHashMap<Ice.Object, Integer> savedMap =
- new java.util.IdentityHashMap<Ice.Object, Integer>(_writeEncapsStack.toBeMarshaledMap);
- writeSize(savedMap.size());
- for(java.util.Map.Entry<Ice.Object, Integer> p : savedMap.entrySet())
- {
- //
- // Add an instance from the old to-be-marshaled
- // map to the marshaled map and then ask the
- // instance to marshal itself. Any new class
- // instances that are triggered by the classes
- // marshaled are added to toBeMarshaledMap.
- //
- _writeEncapsStack.marshaledMap.put(p.getKey(), p.getValue());
- writeInstance(p.getKey(), p.getValue());
- }
-
- //
- // We have marshaled all the instances for this pass,
- // substract what we have marshaled from the
- // toBeMarshaledMap.
- //
- for(Ice.Object p : savedMap.keySet())
- {
- _writeEncapsStack.toBeMarshaledMap.remove(p);
- }
- }
- }
- writeSize(0); // Zero marker indicates end of sequence of sequences of instances.
- }
-
- public void
- readPendingObjects()
- {
- int num;
- do
- {
- num = readSize();
- for(int k = num; k > 0; --k)
- {
- readObject(null);
- }
- }
- while(num > 0);
-
- if(_readEncapsStack != null && _readEncapsStack.patchMap != null && _readEncapsStack.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");
- }
-
- //
- // Iterate over unmarshaledMap and invoke ice_postUnmarshal on
- // each object. We must do this after all objects in this
- // encapsulation have been unmarshaled in order to ensure that
- // any object data members have been properly patched.
- //
- if(_objectList != null)
- {
- for(Ice.Object obj : _objectList)
- {
- try
- {
- obj.ice_postUnmarshal();
- }
- catch(java.lang.Exception ex)
- {
- String s = "exception raised by ice_postUnmarshal:\n" + Ex.toString(ex);
- _instance.initializationData().logger.warning("exception raised by ice_postUnmarshal:\n");
- }
- }
- }
+ initReadEncaps();
+ _readEncapsStack.decoder.throwException(factory);
}
public void
@@ -1787,89 +1482,6 @@ public class BasicStream
_sliceObjects = b;
}
- void
- writeInstance(Ice.Object v, Integer index)
- {
- writeInt(index.intValue());
- try
- {
- v.ice_preMarshal();
- }
- catch(java.lang.Exception ex)
- {
- String s = "exception raised by ice_preUnmarshal:\n" + Ex.toString(ex);
- _instance.initializationData().logger.warning("exception raised by ice_preUnmarshal:\n");
- }
- v.__write(this);
- }
-
- void
- patchReferences(Integer instanceIndex, Integer patchIndex)
- {
- //
- // Called whenever we have unmarshaled a new instance or an
- // index. The instanceIndex is the index of the instance just
- // unmarshaled and patchIndex is the index just
- // unmarshaled. (Exactly one of the two parameters must be
- // null.) Patch any pointers in the patch map with the new
- // address.
- //
- assert((instanceIndex != null && patchIndex == null) || (instanceIndex == null && patchIndex != null));
-
- java.util.LinkedList<Patcher> patchlist;
- Ice.Object v;
- if(instanceIndex != null)
- {
- //
- // We have just unmarshaled an instance -- check if
- // something needs patching for that instance.
- //
- patchlist = _readEncapsStack.patchMap.get(instanceIndex);
- if(patchlist == null)
- {
- return; // We don't have anything to patch for the instance just unmarshaled
- }
- v = _readEncapsStack.unmarshaledMap.get(instanceIndex);
- patchIndex = instanceIndex;
- }
- else
- {
- //
- // We have just unmarshaled an index -- check if we have
- // unmarshaled the instance for that index yet.
- //
- v = _readEncapsStack.unmarshaledMap.get(patchIndex);
- if(v == null)
- {
- return; // We haven't unmarshaled the instance for this index yet
- }
- patchlist = _readEncapsStack.patchMap.get(patchIndex);
- }
- assert(patchlist != null && patchlist.size() > 0);
- assert(v != null);
-
- //
- // Patch all references that refer to the instance.
- //
- for(Patcher p : patchlist)
- {
- try
- {
- p.patch(v);
- }
- catch(ClassCastException ex)
- {
- throw new Ice.NoObjectFactoryException("no object factory", p.type(), ex);
- }
- }
-
- //
- // Clear out the patch map for that index -- there is nothing
- // left to patch for that index for the time being.
- //
- _readEncapsStack.patchMap.remove(patchIndex);
- }
-
public int
pos()
{
@@ -2216,7 +1828,7 @@ public class BasicStream
}
public void
- createAndThrow()
+ createAndThrow(String typeId)
throws Ice.UserException
{
try
@@ -2353,8 +1965,8 @@ public class BasicStream
// are not Java keywords, but are in this list to prevent illegal code being generated if
// someone defines Slice operations with that name.
//
- final String[] keywordList =
- {
+ final String[] keywordList =
+ {
"abstract", "assert", "boolean", "break", "byte", "case", "catch",
"char", "checkedCast", "class", "clone", "const", "continue", "default", "do",
"double", "else", "enum", "equals", "extends", "false", "final", "finalize",
@@ -2405,66 +2017,1367 @@ public class BasicStream
return buf.toString();
}
+ //
+ // Optional data member type.
+ //
+ private static final int MemberTypeF1 = 0;
+ private static final int MemberTypeF2 = 1;
+ private static final int MemberTypeF4 = 2;
+ private static final int MemberTypeF8 = 3;
+ private static final int MemberTypeVSize = 4;
+ private static final int MemberTypeFSize = 5;
+ private static final int MemberTypeReserved = 6;
+ private static final int MemberTypeEndMarker = 7;
+
private Instance _instance;
private Buffer _buf;
private Object _closure;
private byte[] _stringBytes; // Reusable array for reading strings.
private char[] _stringChars; // Reusable array for reading strings.
- private static final class ReadEncaps
+ private enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }
+
+ private static final class EncapsDecoder
{
- int start;
- int sz;
+ EncapsDecoder(BasicStream stream, ReadEncaps encaps, boolean sliceObjects)
+ {
+ _stream = stream;
+ _encaps = encaps;
+ _sliceObjects = sliceObjects;
+ _traceSlicing = -1;
+ _sliceType = SliceType.NoSlice;
+ _usesClasses = false;
+ _typeIdIndex = 0;
+ _slices = new java.util.ArrayList<Ice.SliceInfo>();
+ _indirectionTables = new java.util.ArrayList<int[]>();
+ _indirectPatchList = new java.util.ArrayList<IndirectPatchEntry>();
+ _patchMap = new java.util.TreeMap<Integer, java.util.LinkedList<Patcher> >();
+ _unmarshaledMap = new java.util.TreeMap<Integer, Ice.Object>();
+ _typeIdMap = new java.util.TreeMap<Integer, String>();
+ }
- // byte encodingMajor; // Currently unused
- // byte encodingMinor; // Currently unused
+ void readObject(Patcher patcher)
+ {
+ int index = 0;
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ //
+ // Object references are encoded as a negative integer in 1.0.
+ //
+ index = _stream.readInt();
+ _usesClasses = true;
+ if(index > 0)
+ {
+ throw new Ice.MarshalException("invalid object id");
+ }
+ index = -index;
+ }
+ else
+ {
+ //
+ // Later versions use a size.
+ //
+ index = _stream.readSize();
+ if(index < 0)
+ {
+ throw new Ice.MarshalException("invalid object id");
+ }
+ }
- java.util.TreeMap<Integer, java.util.LinkedList<Patcher> > patchMap;
- java.util.TreeMap<Integer, Ice.Object> unmarshaledMap;
- int typeIdIndex;
- java.util.TreeMap<Integer, String> typeIdMap;
- Ice.EncodingVersion encoding = new Ice.EncodingVersion();
- ReadEncaps next;
+ if(index == 0)
+ {
+ patcher.patch(null);
+ }
+ else if(_sliceType != SliceType.NoSlice && (_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0)
+ {
+ //
+ // 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.
+ //
+ IndirectPatchEntry e = new IndirectPatchEntry();
+ e.index = index - 1;
+ e.patcher = patcher;
+ _indirectPatchList.add(e);
+ }
+ else
+ {
+ addPatchEntry(index, patcher);
+ }
+ }
- void
- reset()
+ void throwException(UserExceptionFactory factory)
+ throws Ice.UserException
{
- if(patchMap != null)
+ assert(_sliceType == SliceType.NoSlice);
+
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
{
- patchMap.clear();
- unmarshaledMap.clear();
- typeIdIndex = 0;
- typeIdMap.clear();
+ //
+ // 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 the exception was sliced. With encoding > 1.0, we
+ // don't need this, each slice indirect patch table indicates
+ // the presence of objects.
+ //
+ boolean usesClasses = _stream.readBool();
+ _usesClasses |= usesClasses;
+ }
+
+ _sliceType = SliceType.ExceptionSlice;
+ _skipFirstSlice = false;
+
+ //
+ // Read the first slice header.
+ //
+ startSlice();
+ final String mostDerivedId = _typeId;
+ UserExceptionFactory exceptionFactory = factory;
+ while(true)
+ {
+ //
+ // Look for a factory for this ID.
+ //
+ if(exceptionFactory == null)
+ {
+ exceptionFactory = _stream.getUserExceptionFactory(_typeId);
+ }
+
+ //
+ // We found a factory, we get out of this loop.
+ //
+ if(exceptionFactory != null)
+ {
+ //
+ // Got factory -- ask the factory to instantiate the
+ // exception, initialize the exception members, and throw
+ // the exception.
+ //
+ try
+ {
+ exceptionFactory.createAndThrow(_typeId);
+ }
+ catch(Ice.UserException ex)
+ {
+ ex.__read(_stream);
+ readPendingObjects();
+ throw ex;
+
+ // Never reached.
+ }
+ }
+
+ //
+ // Performance sensitive, so we use lazy initialization
+ // for tracing.
+ //
+ if(_traceSlicing == -1)
+ {
+ _traceSlicing = _stream.instance().traceLevels().slicing;
+ _slicingCat = _stream.instance().traceLevels().slicingCat;
+ }
+ if(_traceSlicing > 0)
+ {
+ TraceUtil.traceSlicing("exception", _typeId, _slicingCat,
+ _stream.instance().initializationData().logger);
+ }
+
+ if((_sliceFlags & FLAG_IS_LAST_SLICE) != 0)
+ {
+ // TODO: Consider adding a new exception, such as NoExceptionFactory?
+ throw new Ice.UnmarshalOutOfBoundsException("unknown exception type `" + mostDerivedId + "'");
+ }
+
+ skipSlice(); // Slice off what we don't understand.
+ try
+ {
+ startSlice();
+ }
+ catch(Ice.UnmarshalOutOfBoundsException 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.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ // Set the reason member to a more helpful message.
+ ex.reason = "unknown exception type `" + mostDerivedId + "'";
+ }
+ throw ex;
+ }
}
}
+
+ void startObject()
+ {
+ assert(_sliceType == SliceType.ObjectSlice);
+ _skipFirstSlice = true;
+ }
+
+ Ice.SlicedData endObject(boolean preserve)
+ {
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ //
+ // Read the Ice::Object slice.
+ //
+ startSlice();
+
+ //
+ // For compatibility with the old AFM.
+ //
+ int sz = _stream.readSize();
+ if(sz != 0)
+ {
+ throw new Ice.MarshalException("invalid Object slice");
+ }
+
+ endSlice();
+ }
+
+ _sliceType = SliceType.NoSlice;
+ Ice.SlicedData slicedData = null;
+ if(preserve)
+ {
+ slicedData = readSlicedData();
+ }
+ _slices.clear();
+ _indirectionTables.clear();
+ return slicedData;
+ }
+
+ void startException()
+ {
+ assert(_sliceType == SliceType.ExceptionSlice);
+ _skipFirstSlice = true;
+ }
+
+ Ice.SlicedData endException(boolean preserve)
+ {
+ _sliceType = SliceType.NoSlice;
+ Ice.SlicedData slicedData = null;
+ if(preserve)
+ {
+ slicedData = readSlicedData();
+ }
+ _slices.clear();
+ _indirectionTables.clear();
+ return slicedData;
+ }
+
+ String startSlice()
+ {
+ //
+ // If first slice, don't read the header, it was already read in
+ // readInstance or throwException to find the factory.
+ //
+ if(_skipFirstSlice)
+ {
+ _skipFirstSlice = false;
+ return _typeId;
+ }
+
+ //
+ // Read the slice flags. For the 1.0 encoding there's no flag but
+ // just a boolean for object slices. The boolean indicates whether
+ // or not the type ID is encoded as a string or as an index.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _sliceFlags = FLAG_HAS_SLICE_SIZE;
+ if(_sliceType == SliceType.ObjectSlice) // For exceptions, the type ID is always encoded as a string
+ {
+ boolean isIndex = _stream.readBool();
+ _sliceFlags |= isIndex ? FLAG_HAS_TYPE_ID_INDEX : FLAG_HAS_TYPE_ID_STRING;
+ }
+ }
+ else
+ {
+ _sliceFlags = _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(_sliceType == SliceType.ObjectSlice)
+ {
+ if((_sliceFlags & FLAG_HAS_TYPE_ID_INDEX) != 0)
+ {
+ int index = _stream.readSize();
+ _typeId = _typeIdMap.get(index);
+ if(_typeId == null)
+ {
+ throw new Ice.UnmarshalOutOfBoundsException();
+ }
+ }
+ else if((_sliceFlags & FLAG_HAS_TYPE_ID_STRING) != 0)
+ {
+ _typeId = _stream.readString();
+ _typeIdMap.put(++_typeIdIndex, _typeId);
+ }
+ else
+ {
+ // Only the most derived slice encodes the type ID for the
+ // compact format.
+ _typeId = "";
+ }
+ }
+ else
+ {
+ _typeId = _stream.readString();
+ }
+
+ //
+ // Read the slice size if necessary.
+ //
+ if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0)
+ {
+ _sliceSize = _stream.readInt();
+ if(_sliceSize < 4)
+ {
+ throw new Ice.UnmarshalOutOfBoundsException();
+ }
+ }
+ else
+ {
+ _sliceSize = 0;
+ }
+
+ //
+ // Reset the indirect patch list for this new slice.
+ //
+ _indirectPatchList.clear();
+ return _typeId;
+ }
+
+ void endSlice()
+ {
+ if((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0)
+ {
+ //
+ // Read remaining un-read optional members.
+ //
+ byte v;
+ do
+ {
+ v = _stream.readByte();
+ }
+ while(skipOpt(v & 0x07));
+ }
+
+ //
+ // Read the indirection table if one is present and transform the
+ // indirect patch list into patch entries with direct references.
+ //
+ if((_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0)
+ {
+ //
+ // The table is written as a sequence<size> to conserve space.
+ //
+ int[] indirectionTable = _stream.readSizeSeq();
+
+ //
+ // Sanity checks.
+ //
+ if(indirectionTable.length == 0 && !_indirectPatchList.isEmpty())
+ {
+ throw new Ice.MarshalException("empty indirection table");
+ }
+ else if(indirectionTable.length > 0 && _indirectPatchList.isEmpty())
+ {
+ throw new Ice.MarshalException("no references to indirection table");
+ }
+
+ //
+ // Convert indirect references into direct references.
+ //
+ for(IndirectPatchEntry e : _indirectPatchList)
+ {
+ assert(e.index >= 0);
+ if(e.index >= indirectionTable.length)
+ {
+ throw new Ice.MarshalException("indirection out of range");
+ }
+ final int id = indirectionTable[e.index];
+ if(id <= 0)
+ {
+ //
+ // Entries in the table must be positive, just like a regular object reference.
+ //
+ throw new Ice.MarshalException("invalid id in object indirection table");
+ }
+ addPatchEntry(id, e.patcher);
+ }
+ }
+ }
+
+ void skipSlice()
+ {
+ int start = _stream.pos();
+
+ if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0)
+ {
+ assert(_sliceSize >= 4);
+ _stream.pos(start + _sliceSize - 4);
+ if((start + _sliceSize - 4) > _stream.size())
+ {
+ throw new Ice.UnmarshalOutOfBoundsException();
+ }
+ }
+ else
+ {
+ throw new Ice.MarshalException("compact format prevents slicing");
+ }
+
+ if(!_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ //
+ // Preserve this slice.
+ //
+ Ice.SliceInfo info = new Ice.SliceInfo();
+ info.typeId = _typeId;
+ java.nio.ByteBuffer b = _stream.getBuffer().b;
+ final int end = b.position();
+ info.bytes = new byte[end - start];
+ b.position(start);
+ b.get(info.bytes);
+ _slices.add(info);
+
+ if((_sliceFlags & FLAG_HAS_INDIRECTION_TABLE) != 0)
+ {
+ //
+ // Read the indirection table, which is written as a sequence<size> to conserve space.
+ //
+ _indirectionTables.add(_stream.readSizeSeq());
+ }
+ else
+ {
+ _indirectionTables.add(new int[0]);
+ }
+ }
+ }
+
+ boolean readOpt(int readTag, int expectedType)
+ {
+ assert(_sliceType != SliceType.NoSlice);
+ if((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) == 0)
+ {
+ return false; // No optional data members
+ }
+
+ int tag;
+ int type;
+ do
+ {
+ byte v = _stream.readByte();
+
+ type = v & 0x07; // Read first 3 bits.
+ tag = (int)(v >> 3);
+ if(tag == 31)
+ {
+ tag = _stream.readSize();
+ }
+ }
+ while(tag < readTag && skipOpt(type)); // Skip optional data members with lower tag values.
+
+ if(type == MemberTypeEndMarker)
+ {
+ //
+ // Clear the optional members flag since we've reach the end. We clear
+ // the flag to prevent endSlice to skip un-read optional members and
+ // to prevent other optional members from being read.
+ //
+ _sliceFlags &= ~FLAG_HAS_OPTIONAL_MEMBERS;
+ return false;
+ }
+ else if(tag > readTag)
+ {
+ //
+ // Rewind the stream so that we correctly read the next
+ // optional data member tag & type.
+ //
+ int pos = _stream.pos();
+ pos -= tag < 31 ? 1 : (tag < 255 ? 2 : 6);
+ _stream.pos(pos);
+ return false; // No optional data members with the requested tag.
+ }
+
+ assert(readTag == tag);
+ if(type != expectedType)
+ {
+ throw new Ice.MarshalException("invalid optional data member `" + tag + "' in `" + _typeId +
+ "': unexpected type");
+ }
+
+ //
+ // We have an optional data member with the requested tag and
+ // type.
+ //
+ return true;
+ }
+
+ void readPendingObjects()
+ {
+ //
+ // With the 1.0 encoding, only read pending objects if nil or
+ // non-nil references were read (_usesClasses == true). Otherwise,
+ // read pending objects only if some non-nil references were read.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ if(!_usesClasses)
+ {
+ return;
+ }
+ _usesClasses = false;
+ }
+ else if(_patchMap.isEmpty())
+ {
+ return;
+ }
+
+ int num;
+ java.util.ArrayList<Ice.Object> objectList = new java.util.ArrayList<Ice.Object>();
+ do
+ {
+ num = _stream.readSize();
+ for(int k = num; k > 0; --k)
+ {
+ objectList.add(readInstance());
+ }
+ }
+ while(num > 0);
+
+ if(!_patchMap.isEmpty())
+ {
+ //
+ // 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");
+ }
+
+ //
+ // 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(Ice.Object p : objectList)
+ {
+ try
+ {
+ p.ice_postUnmarshal();
+ }
+ catch(java.lang.Exception ex)
+ {
+ String s = "exception raised by ice_postUnmarshal:\n" + Ex.toString(ex);
+ _stream.instance().initializationData().logger.warning("exception raised by ice_postUnmarshal:\n");
+ }
+ }
+ }
+
+ private Ice.Object readInstance()
+ {
+ int index;
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ index = _stream.readInt();
+ }
+ else
+ {
+ index = _stream.readSize();
+ }
+
+ Ice.Object v = null;
+ if(index <= 0)
+ {
+ throw new Ice.MarshalException("invalid object id");
+ }
+
+ _sliceType = SliceType.ObjectSlice;
+ _skipFirstSlice = false;
+
+ //
+ // Read the first slice header.
+ //
+ startSlice();
+ final String mostDerivedId = _typeId;
+ ObjectFactoryManager servantFactoryManager = _stream.instance().servantFactoryManager();
+ while(true)
+ {
+ //
+ // For the 1.0 encoding, the type ID for the base Object class marks
+ // the last slice. For later encodings, an empty type ID means the
+ // class was marshaled in the compact format and therefore cannot be
+ // sliced.
+ //
+ if(_typeId.length() == 0 || _typeId.equals(Ice.ObjectImpl.ice_staticId()))
+ {
+ throw new Ice.NoObjectFactoryException("", mostDerivedId);
+ }
+
+ //
+ // Try to find a factory registered for the specific type.
+ //
+ Ice.ObjectFactory userFactory = servantFactoryManager.find(_typeId);
+ if(userFactory != null)
+ {
+ v = userFactory.create(_typeId);
+ }
+
+ //
+ // If that fails, invoke the default factory if one has been
+ // registered.
+ //
+ if(v == null)
+ {
+ userFactory = servantFactoryManager.find("");
+ if(userFactory != null)
+ {
+ v = userFactory.create(_typeId);
+ }
+ }
+
+ //
+ // Last chance: check the table of static factories (i.e.,
+ // automatically generated factories for concrete classes).
+ //
+ if(v == null)
+ {
+ userFactory = _stream.loadObjectFactory(_typeId);
+ if(userFactory != null)
+ {
+ v = userFactory.create(_typeId);
+ assert(v != null);
+ }
+ }
+
+ //
+ // We found a factory, we get out of this loop.
+ //
+ if(v != null)
+ {
+ break;
+ }
+
+ //
+ // If object slicing is disabled, or if the flags indicate that this is the
+ // last slice (for encodings >= 1.1), we raise NoObjectFactoryException.
+ //
+ if(!_sliceObjects)
+ {
+ throw new Ice.NoObjectFactoryException("object slicing is disabled", _typeId);
+ }
+ else if((_sliceFlags & FLAG_IS_LAST_SLICE) != 0)
+ {
+ throw new Ice.NoObjectFactoryException("", _typeId);
+ }
+
+ //
+ // Performance sensitive, so we use lazy initialization for tracing.
+ //
+ if(_traceSlicing == -1)
+ {
+ _traceSlicing = _stream.instance().traceLevels().slicing;
+ _slicingCat = _stream.instance().traceLevels().slicingCat;
+ }
+ if(_traceSlicing > 0)
+ {
+ TraceUtil.traceSlicing("class", _typeId, _slicingCat,
+ _stream.instance().initializationData().logger);
+ }
+
+ skipSlice(); // Slice off what we don't understand.
+ startSlice(); // Read next Slice header for next iteration.
+ }
+
+ //
+ // Add the object to the map of un-marshalled objects, this must
+ // be done before reading the objects (for circular references).
+ //
+ _unmarshaledMap.put(index, v);
+
+ //
+ // Read the object.
+ //
+ v.__read(_stream);
+
+ //
+ // Patch all instances now that the object is un-marshalled.
+ //
+ java.util.LinkedList<Patcher> l = _patchMap.get(index);
+ if(l != null)
+ {
+ assert(l.size() > 0);
+
+ //
+ // Patch all pointers that refer to the instance.
+ //
+ for(Patcher p : l)
+ {
+ p.patch(v);
+ }
+
+ //
+ // Clear out the patch map for that index -- there is nothing left
+ // to patch for that index for the time being.
+ //
+ _patchMap.remove(index);
+ }
+
+ return v;
+ }
+
+ private void addPatchEntry(int index, Patcher patcher)
+ {
+ 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.
+ //
+ Ice.Object obj = _unmarshaledMap.get(index);
+ if(obj != null)
+ {
+ patcher.patch(obj);
+ return;
+ }
+
+ //
+ // Add patch entry if the object isn't un-marshalled yet, the
+ // smart pointer will be patched when the instance is
+ // un-marshalled.
+ //
+
+ java.util.LinkedList<Patcher> l = _patchMap.get(index);
+ if(l == null)
+ {
+ //
+ // We have no outstanding instances to be patched for this
+ // index, so make a new entry in the patch map.
+ //
+ l = new java.util.LinkedList<Patcher>();
+ _patchMap.put(index, l);
+ }
+
+ //
+ // Append a patch entry for this instance.
+ //
+ l.add(patcher);
+ }
+
+ private Ice.SlicedData readSlicedData()
+ {
+ if(_slices.isEmpty()) // No preserved slices.
+ {
+ return null;
+ }
+
+ //
+ // The _indirectionTables member holds the indirection table for each slice
+ // in _slices.
+ //
+ assert(_slices.size() == _indirectionTables.size());
+
+ for(int n = 0; n < _slices.size(); ++n)
+ {
+ //
+ // We use the "objects" list in SliceInfo to hold references to the target
+ // objects. Note however that we may not have actually read these objects
+ // yet, so they need to be treated just like we had read the object references
+ // directly (i.e., we add them to the patch list).
+ //
+ // Another important note: the SlicedData object that we return here must
+ // not be destroyed before readPendingObjects is called, otherwise the
+ // patch references will refer to invalid addresses.
+ //
+ final int[] table = _indirectionTables.get(n);
+ Ice.SliceInfo info = _slices.get(n);
+ info.objects = new Ice.Object[table.length];
+ for(int j = 0; j < table.length; ++j)
+ {
+ if(table[j] <= 0)
+ {
+ throw new Ice.MarshalException("invalid id in object indirection table");
+ }
+ SequencePatcher patcher = new SequencePatcher(info.objects, Ice.Object.class,
+ Ice.ObjectImpl.ice_staticId(), j);
+ addPatchEntry(table[j], patcher);
+ }
+ }
+
+ Ice.SliceInfo[] arr = new Ice.SliceInfo[_slices.size()];
+ _slices.toArray(arr);
+ return new Ice.SlicedData(arr);
+ }
+
+ private boolean skipOpt(int type)
+ {
+ int sz;
+ switch(type)
+ {
+ case MemberTypeF1:
+ {
+ sz = 1;
+ break;
+ }
+ case MemberTypeF2:
+ {
+ sz = 2;
+ break;
+ }
+ case MemberTypeF4:
+ {
+ sz = 4;
+ break;
+ }
+ case MemberTypeF8:
+ {
+ sz = 8;
+ break;
+ }
+ case MemberTypeVSize:
+ {
+ sz = _stream.readSize();
+ break;
+ }
+ case MemberTypeFSize:
+ {
+ sz = _stream.readInt();
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+
+ int pos = _stream.pos();
+ if(pos + sz > _stream.size())
+ {
+ throw new Ice.UnmarshalOutOfBoundsException();
+ }
+ _stream.pos(pos + sz);
+ return true;
+ }
+
+ private final BasicStream _stream;
+ private final ReadEncaps _encaps;
+ private final boolean _sliceObjects;
+
+ private int _traceSlicing;
+ private String _slicingCat;
+
+ // Object/exception attributes
+ private SliceType _sliceType;
+ private boolean _skipFirstSlice;
+ private java.util.ArrayList<Ice.SliceInfo> _slices; // Preserved slices.
+ private java.util.ArrayList<int[]> _indirectionTables;
+ private boolean _usesClasses;
+
+ // Slice attributes
+ private byte _sliceFlags;
+ private int _sliceSize;
+ private String _typeId;
+
+ private static final class IndirectPatchEntry
+ {
+ int index;
+ Patcher patcher;
+ }
+ private java.util.ArrayList<IndirectPatchEntry> _indirectPatchList;
+
+ // Encapsulation attributes for object un-marshalling
+ private java.util.TreeMap<Integer, java.util.LinkedList<Patcher> > _patchMap;
+ private java.util.TreeMap<Integer, Ice.Object> _unmarshaledMap;
+ private java.util.TreeMap<Integer, String> _typeIdMap;
+ private int _typeIdIndex;
}
- private static final class WriteEncaps
+ private static final class EncapsEncoder
{
- int start;
+ EncapsEncoder(BasicStream stream, WriteEncaps encaps, Ice.FormatType format)
+ {
+ _stream = stream;
+ _encaps = encaps;
+ _format = format;
+ _sliceType = SliceType.NoSlice;
+ _usesClasses = false;
+ _objectIdIndex = 0;
+ _typeIdIndex = 0;
+ _indirectionTable = new java.util.ArrayList<Integer>();
+ _indirectionMap = new java.util.TreeMap<Integer, Integer>();
+ _toBeMarshaledMap = new java.util.IdentityHashMap<Ice.Object, Integer>();
+ _marshaledMap = new java.util.IdentityHashMap<Ice.Object, Integer>();
+ _typeIdMap = new java.util.TreeMap<String, Integer>();
+ }
- int writeIndex;
- java.util.IdentityHashMap<Ice.Object, Integer> toBeMarshaledMap;
- java.util.IdentityHashMap<Ice.Object, Integer> marshaledMap;
- int typeIdIndex;
- java.util.TreeMap<String, Integer> typeIdMap;
- Ice.EncodingVersion encoding = new Ice.EncodingVersion();
- WriteEncaps next;
+ void writeObject(Ice.Object v)
+ {
+ if(v != null)
+ {
+ //
+ // Register the object.
+ //
+ int index = registerObject(v);
- void
- reset()
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ //
+ // Object references are encoded as a negative integer in 1.0.
+ //
+ _stream.writeInt(-index);
+ _usesClasses = true;
+ }
+ else if(_sliceType != SliceType.NoSlice && _format == Ice.FormatType.SlicedFormat)
+ {
+ //
+ // An object reference that appears inside a slice of an
+ // object or exception encoded as a positive non-zero
+ // index into a per-slice indirection table.
+ //
+ // We use _indirectionMap to keep track of the object
+ // references in the current slice; it maps the object
+ // reference to the position in the indirection list. Note
+ // that the position is offset by one (e.g., the first
+ // position = 1).
+ //
+ Integer p = _indirectionMap.get(index);
+ if(p == null)
+ {
+ _indirectionTable.add(index);
+ int sz = _indirectionTable.size(); // Position + 1
+ _indirectionMap.put(index, sz);
+ _stream.writeSize(sz);
+ }
+ else
+ {
+ _stream.writeSize(p.intValue());
+ }
+ }
+ else
+ {
+ _stream.writeSize(index);
+ }
+ }
+ else
+ {
+ //
+ // Write nil reference.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _stream.writeInt(0);
+ _usesClasses = true;
+ }
+ else
+ {
+ _stream.writeSize(0);
+ }
+ }
+ }
+
+ void writeUserException(Ice.UserException v)
{
- if(toBeMarshaledMap != null)
+ v.__write(_stream);
+ writePendingObjects();
+ }
+
+ void startObject(Ice.SlicedData data)
+ {
+ _sliceType = SliceType.ObjectSlice;
+ _firstSlice = true;
+ if(data != null)
{
- writeIndex = 0;
- toBeMarshaledMap.clear();
- marshaledMap.clear();
- typeIdIndex = 0;
- typeIdMap.clear();
+ writeSlicedData(data);
+ }
+ }
+
+ void endObject()
+ {
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ //
+ // Write the Object slice.
+ //
+ startSlice(Ice.ObjectImpl.ice_staticId(), true);
+ _stream.writeSize(0); // For compatibility with the old AFM.
+ endSlice();
}
+ _sliceType = SliceType.NoSlice;
}
+
+ void startException(Ice.SlicedData data)
+ {
+ _sliceType = SliceType.ExceptionSlice;
+ _firstSlice = true;
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _usesClassesPos = _stream.pos();
+ _stream.writeBool(false); // Placeholder for usesClasses boolean
+ }
+ if(data != null)
+ {
+ writeSlicedData(data);
+ }
+ }
+
+ void endException()
+ {
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _stream.writeBoolAt(_usesClasses, _usesClassesPos);
+ }
+ _sliceType = SliceType.NoSlice;
+ }
+
+ void startSlice(String typeId, boolean last)
+ {
+ assert(_indirectionTable.isEmpty() && _indirectionMap.isEmpty());
+ _sliceFlags = (byte)0;
+ _sliceFlagsPos = _stream.pos();
+
+ //
+ // Encode the slice size for the old encoding and if using the
+ // sliced format.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0) || _format == Ice.FormatType.SlicedFormat)
+ {
+ _sliceFlags |= FLAG_HAS_SLICE_SIZE;
+ }
+
+ //
+ // This is the last slice.
+ //
+ if(last)
+ {
+ _sliceFlags |= FLAG_IS_LAST_SLICE;
+ }
+
+ //
+ // For object slices, encode the flag and the type ID either as a
+ // string or index. For exception slices, don't encode slice flags
+ // for the old encoding and always encode the type ID a string.
+ //
+ if(_sliceType == SliceType.ObjectSlice)
+ {
+ _stream.writeByte((byte)0); // Placeholder for the slice flags
+
+ //
+ // Encode the type ID (only in the first slice for the compact
+ // encoding).
+ //
+ if(_format == Ice.FormatType.SlicedFormat || _encaps.encoding.equals(Ice.Util.Encoding_1_0) ||
+ _firstSlice)
+ {
+ //
+ // If the type ID has already been seen, write the index
+ // of the type ID, otherwise allocate a new type ID and
+ // write the string.
+ //
+ Integer p = _typeIdMap.get(typeId);
+ if(p != null)
+ {
+ _sliceFlags |= FLAG_HAS_TYPE_ID_INDEX;
+ _stream.writeSize(p.intValue());
+ }
+ else
+ {
+ _sliceFlags |= FLAG_HAS_TYPE_ID_STRING;
+ _typeIdMap.put(typeId, ++_typeIdIndex);
+ _stream.writeString(typeId);
+ }
+ }
+ }
+ else
+ {
+ if(!_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _stream.writeByte((byte)0); // Placeholder for the slice flags
+ }
+ _stream.writeString(typeId);
+ }
+
+ if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0)
+ {
+ _stream.writeInt(0); // Placeholder for the slice length.
+ }
+
+ _writeSlice = _stream.pos();
+ _firstSlice = false;
+ }
+
+ void endSlice()
+ {
+ //
+ // 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((_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) != 0)
+ {
+ _stream.writeByte((byte)MemberTypeEndMarker);
+ }
+
+ //
+ // Write the slice length if necessary.
+ //
+ if((_sliceFlags & FLAG_HAS_SLICE_SIZE) != 0)
+ {
+ final int sz = _stream.pos() - _writeSlice + 4;
+ _stream.writeIntAt(sz, _writeSlice - 4);
+ }
+
+ //
+ // Only write the indirection table if it contains entries.
+ //
+ if(!_indirectionTable.isEmpty())
+ {
+ assert(_format == Ice.FormatType.SlicedFormat);
+ _sliceFlags |= FLAG_HAS_INDIRECTION_TABLE;
+
+ //
+ // Write the indirection table as a sequence<size> to conserve space.
+ //
+ _stream.writeSizeSeq(_indirectionTable);
+
+ _indirectionTable.clear();
+ _indirectionMap.clear();
+ }
+
+ //
+ // Finally, update the slice flags.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ if(_sliceType == SliceType.ObjectSlice) // No flags for 1.0 exception slices.
+ {
+ _stream.writeBoolAt((_sliceFlags & FLAG_HAS_TYPE_ID_INDEX) != 0, _sliceFlagsPos);
+ }
+ }
+ else
+ {
+ _stream.writeByteAt(_sliceFlags, _sliceFlagsPos);
+ }
+ }
+
+ void writeOpt(int tag, int type)
+ {
+ assert(_sliceType != SliceType.NoSlice);
+ _sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS;
+ byte v = (byte)type;
+ if(tag < 31)
+ {
+ v |= (byte)(tag << 3);
+ }
+ else
+ {
+ v |= (byte)0x0F8; // tag = 31
+ _stream.writeSize(tag);
+ }
+ }
+
+ void writePendingObjects()
+ {
+ //
+ // With the 1.0 encoding, only write pending objects if nil or
+ // non-nil references were written (_usesClasses =
+ // true). Otherwise, write pending objects only if some non-nil
+ // references were written.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ if(!_usesClasses)
+ {
+ return;
+ }
+ _usesClasses = false;
+ }
+ else if(_toBeMarshaledMap.isEmpty())
+ {
+ return;
+ }
+
+ while(_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.
+ //
+ _marshaledMap.putAll(_toBeMarshaledMap);
+
+ java.util.IdentityHashMap<Ice.Object, Integer> savedMap = _toBeMarshaledMap;
+ _toBeMarshaledMap = new java.util.IdentityHashMap<Ice.Object, Integer>();
+ _stream.writeSize(savedMap.size());
+ for(java.util.Map.Entry<Ice.Object, Integer> p : savedMap.entrySet())
+ {
+ //
+ // Ask the instance to marshal itself. Any new class
+ // instances that are triggered by the classes marshaled
+ // are added to toBeMarshaledMap.
+ //
+ if(_encaps.encoding.equals(Ice.Util.Encoding_1_0))
+ {
+ _stream.writeInt(p.getValue().intValue());
+ }
+ else
+ {
+ _stream.writeSize(p.getValue().intValue());
+ }
+
+ try
+ {
+ p.getKey().ice_preMarshal();
+ }
+ catch(java.lang.Exception ex)
+ {
+ String s = "exception raised by ice_preUnmarshal:\n" + Ex.toString(ex);
+ _stream.instance().initializationData().logger.warning(
+ "exception raised by ice_preUnmarshal:\n");
+ }
+
+ p.getKey().__write(_stream);
+ }
+ }
+ _stream.writeSize(0); // Zero marker indicates end of sequence of sequences of instances.
+ }
+
+ private void writeSlicedData(Ice.SlicedData slicedData)
+ {
+ assert(slicedData != null);
+
+ //
+ // We only remarshal preserved slices if the target encoding is > 1.0 and 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(_encaps.encoding.equals(Ice.Util.Encoding_1_0) || _format != Ice.FormatType.SlicedFormat)
+ {
+ return;
+ }
+
+ for(int n = 0; n < slicedData.slices.length; ++n)
+ {
+ Ice.SliceInfo info = slicedData.slices[n];
+ startSlice(info.typeId, false); // last = false, sliced data never contains the last slice.
+
+ //
+ // Write the bytes associated with this slice.
+ //
+ _stream.writeBlob(info.bytes);
+
+ //
+ // Assemble and write the indirection table. The table must have the same order
+ // as the list of objects.
+ //
+ for(int j = 0; j < info.objects.length; ++j)
+ {
+ _indirectionTable.add(registerObject(info.objects[j]));
+ }
+
+ endSlice();
+ }
+ }
+
+ private int registerObject(Ice.Object v)
+ {
+ //
+ // Look for this instance in the to-be-marshaled map.
+ //
+ Integer p = _toBeMarshaledMap.get(v);
+ if(p != null)
+ {
+ return p.intValue();
+ }
+
+ //
+ // Didn't find it, try the marshaled map next.
+ //
+ p = _marshaledMap.get(v);
+ if(p != null)
+ {
+ return p.intValue();
+ }
+
+ //
+ // We haven't seen this instance previously, create a new
+ // index, and insert it into the to-be-marshaled map.
+ //
+ _toBeMarshaledMap.put(v, ++_objectIdIndex);
+ return _objectIdIndex;
+ }
+
+ private final BasicStream _stream;
+ private final WriteEncaps _encaps;
+ private final Ice.FormatType _format;
+
+ // Object/exception attributes
+ private SliceType _sliceType;
+ private boolean _firstSlice;
+ private boolean _usesClasses;
+ private int _usesClassesPos;
+
+ // Slice attributes
+ private byte _sliceFlags;
+ private int _writeSlice; // Position of the slice data members
+ private int _sliceFlagsPos; // Position of the slice flags
+ private java.util.ArrayList<Integer> _indirectionTable;
+ private java.util.TreeMap<Integer, Integer> _indirectionMap;
+
+ // Encapsulation attributes for object marshalling.
+ private int _objectIdIndex;
+ private java.util.IdentityHashMap<Ice.Object, Integer> _toBeMarshaledMap;
+ private java.util.IdentityHashMap<Ice.Object, Integer> _marshaledMap;
+ private java.util.TreeMap<String, Integer> _typeIdMap;
+ private int _typeIdIndex;
+ }
+
+ private static final class ReadEncaps
+ {
+ void reset()
+ {
+ decoder = null;
+ }
+
+ int start;
+ int sz;
+ Ice.EncodingVersion encoding = new Ice.EncodingVersion();
+
+ EncapsDecoder decoder;
+
+ ReadEncaps next;
+ }
+
+ private static final class WriteEncaps
+ {
+ void reset()
+ {
+ encoder = null;
+ }
+
+ int start;
+ Ice.EncodingVersion encoding = new Ice.EncodingVersion();
+
+ EncapsEncoder encoder;
+
+ WriteEncaps next;
}
+ //
+ // The encoding version to use when there's no encapsulation to
+ // read from or write to. This is for example used to read message
+ // headers or when the user is using the streaming API with no
+ // encapsulation.
+ //
private Ice.EncodingVersion _encoding;
private ReadEncaps _readEncapsStack;
@@ -2472,11 +3385,47 @@ public class BasicStream
private ReadEncaps _readEncapsCache;
private WriteEncaps _writeEncapsCache;
- private int _readSlice;
- private int _writeSlice;
+ private void initReadEncaps()
+ {
+ if(_readEncapsStack == null) // Lazy initialization
+ {
+ _readEncapsStack = _readEncapsCache;
+ if(_readEncapsStack != null)
+ {
+ _readEncapsCache = _readEncapsCache.next;
+ }
+ else
+ {
+ _readEncapsStack = new ReadEncaps();
+ }
+ }
+
+ if(_readEncapsStack.decoder == null) // Lazy initialization.
+ {
+ _readEncapsStack.decoder = new EncapsDecoder(this, _readEncapsStack, _sliceObjects);
+ }
+ }
+
+ private void initWriteEncaps()
+ {
+ if(_writeEncapsStack == null) // Lazy initialization
+ {
+ _writeEncapsStack = _writeEncapsCache;
+ if(_writeEncapsStack != null)
+ {
+ _writeEncapsCache = _writeEncapsCache.next;
+ }
+ else
+ {
+ _writeEncapsStack = new WriteEncaps();
+ }
+ }
- private int _traceSlicing;
- private String _slicingCat;
+ if(_writeEncapsStack.encoder == null) // Lazy initialization.
+ {
+ _writeEncapsStack.encoder = new EncapsEncoder(this, _writeEncapsStack, _format);
+ }
+ }
private boolean _sliceObjects;
@@ -2486,7 +3435,14 @@ public class BasicStream
private int _startSeq;
private int _minSeqSize;
- private java.util.ArrayList<Ice.Object> _objectList;
+ private Ice.FormatType _format;
+
+ private static final byte FLAG_HAS_TYPE_ID_STRING = (byte)(1<<0);
+ private static final byte FLAG_HAS_TYPE_ID_INDEX = (byte)(1<<1);
+ private static final byte FLAG_HAS_OPTIONAL_MEMBERS = (byte)(1<<2);
+ private static final byte FLAG_HAS_INDIRECTION_TABLE = (byte)(1<<3);
+ private static final byte FLAG_HAS_SLICE_SIZE = (byte)(1<<4);
+ private static final byte FLAG_IS_LAST_SLICE = (byte)(1<<5);
private static java.util.HashMap<String, UserExceptionFactory> _exceptionFactories =
new java.util.HashMap<String, UserExceptionFactory>();
diff --git a/java/src/IceInternal/DefaultsAndOverrides.java b/java/src/IceInternal/DefaultsAndOverrides.java
index ecc80d17df8..273ac999ab4 100644
--- a/java/src/IceInternal/DefaultsAndOverrides.java
+++ b/java/src/IceInternal/DefaultsAndOverrides.java
@@ -120,6 +120,9 @@ public final class DefaultsAndOverrides
Ice.Util.encodingVersionToString(Protocol.currentEncoding));
defaultEncoding = Ice.Util.stringToEncodingVersion(value);
Protocol.checkSupportedEncoding(defaultEncoding);
+
+ boolean slicedFormat = properties.getPropertyAsIntWithDefault("Ice.Default.SlicedFormat", 0) > 0;
+ defaultFormat = slicedFormat ? Ice.FormatType.SlicedFormat : Ice.FormatType.CompactFormat;
}
final public String defaultHost;
@@ -129,6 +132,7 @@ public final class DefaultsAndOverrides
final public int defaultLocatorCacheTimeout;
final public boolean defaultPreferSecure;
final public Ice.EncodingVersion defaultEncoding;
+ final public Ice.FormatType defaultFormat;
final public boolean overrideTimeout;
final public int overrideTimeoutValue;
diff --git a/java/src/IceInternal/Outgoing.java b/java/src/IceInternal/Outgoing.java
index dc611e91fc5..c7ace46eb31 100644
--- a/java/src/IceInternal/Outgoing.java
+++ b/java/src/IceInternal/Outgoing.java
@@ -501,7 +501,7 @@ public final class Outgoing implements OutgoingMessageCallback
try
{
_is.startReadEncaps();
- _is.throwException();
+ _is.throwException(null);
}
catch(Ice.UserException ex)
{
diff --git a/java/src/IceInternal/UserExceptionFactory.java b/java/src/IceInternal/UserExceptionFactory.java
index 924afd8e721..78da26417b7 100644
--- a/java/src/IceInternal/UserExceptionFactory.java
+++ b/java/src/IceInternal/UserExceptionFactory.java
@@ -11,7 +11,7 @@ package IceInternal;
public interface UserExceptionFactory
{
- void createAndThrow()
+ void createAndThrow(String typeId)
throws Ice.UserException;
void destroy();