You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2017/04/16 22:32:09 UTC
[18/72] [abbrv] [partial] flex-blazeds git commit: - Major code scrub
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/amf/Amf3Input.java
----------------------------------------------------------------------
diff --git a/core/src/flex/messaging/io/amf/Amf3Input.java b/core/src/flex/messaging/io/amf/Amf3Input.java
deleted file mode 100644
index 0e62b88..0000000
--- a/core/src/flex/messaging/io/amf/Amf3Input.java
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.io.amf;
-
-import java.io.ByteArrayOutputStream;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import flex.messaging.io.PropertyProxy;
-import flex.messaging.io.SerializationContext;
-import flex.messaging.io.SerializationException;
-import flex.messaging.io.UnknownTypeException;
-import flex.messaging.io.amf.AmfTrace.VectorType;
-import flex.messaging.util.ClassUtil;
-import flex.messaging.util.Trace;
-
-/**
- * Reads AMF 3 formatted data stream.
- * <p>
- * This class intends to matches the Flash Player 8 C++ code
- * in avmglue/DataIO.cpp
- * </p>
- *
- *
- */
-public class Amf3Input extends AbstractAmfInput implements Amf3Types
-{
- /**
- *
- */
- protected List objectTable;
-
- /**
- *
- */
- protected List stringTable;
-
- /**
- *
- */
- protected List traitsTable;
-
- public Amf3Input(SerializationContext context)
- {
- super(context);
-
- stringTable = new ArrayList(64);
- objectTable = new ArrayList(64);
- traitsTable = new ArrayList(10);
- }
-
- /**
- * Reset should be called before reading a top level object,
- * such as a new header or a new body.
- */
- @Override
- public void reset()
- {
- super.reset();
- stringTable.clear();
- objectTable.clear();
- traitsTable.clear();
- }
-
- public Object saveObjectTable()
- {
- Object table = objectTable;
- objectTable = new ArrayList(64);
- return table;
- }
-
- public void restoreObjectTable(Object table)
- {
- objectTable = (ArrayList) table;
- }
-
- public Object saveTraitsTable()
- {
- Object table = traitsTable;
- traitsTable = new ArrayList(10);
- return table;
- }
-
- public void restoreTraitsTable(Object table)
- {
- traitsTable = (ArrayList) table;
- }
-
- public Object saveStringTable()
- {
- Object table = stringTable;
- stringTable = new ArrayList(64);
- return table;
- }
-
- public void restoreStringTable(Object table)
- {
- stringTable = (ArrayList) table;
- }
-
- /**
- * Public entry point to read a top level AMF Object, such as
- * a header value or a message body.
- * @return Object the object read
- * @throws ClassNotFoundException, IOException when reading object process failed
- */
- public Object readObject() throws ClassNotFoundException, IOException
- {
- int type = in.readByte();
- Object value = readObjectValue(type);
- return value;
- }
-
- /**
- *
- */
- protected Object readObjectValue(int type) throws ClassNotFoundException, IOException
- {
- Object value = null;
-
- switch (type)
- {
- case kStringType:
- ClassUtil.validateCreation(String.class);
-
- value = readString();
- if (isDebug)
- trace.writeString((String)value);
- break;
-
- case kObjectType:
- value = readScriptObject();
- break;
-
- case kArrayType:
- value = readArray();
- break;
-
- case kFalseType:
- ClassUtil.validateCreation(Boolean.class);
-
- value = Boolean.FALSE;
-
- if (isDebug)
- trace.write(value);
- break;
-
- case kTrueType:
- ClassUtil.validateCreation(Boolean.class);
-
- value = Boolean.TRUE;
-
- if (isDebug)
- trace.write(value);
- break;
-
- case kIntegerType:
- ClassUtil.validateCreation(Integer.class);
-
- int i = readUInt29();
- // Symmetric with writing an integer to fix sign bits for negative values...
- i = (i << 3) >> 3;
- value = new Integer(i);
-
- if (isDebug)
- trace.write(value);
- break;
-
- case kDoubleType:
- value = Double.valueOf(readDouble());
- break;
-
- case kUndefinedType:
- if (isDebug)
- trace.writeUndefined();
- break;
-
- case kNullType:
- if (isDebug)
- trace.writeNull();
- break;
-
- case kXMLType:
- case kAvmPlusXmlType:
- value = readXml();
- break;
-
- case kDateType:
- value = readDate();
- break;
-
- case kByteArrayType:
- value = readByteArray();
- break;
-
- case kDictionaryType:
- value = readDictionary();
- break;
-
- case kTypedVectorInt:
- case kTypedVectorUint:
- case kTypedVectorDouble:
- case kTypedVectorObject:
- value = readTypedVector(type);
- break;
- default:
- // Unknown object type tag {type}
- UnknownTypeException ex = new UnknownTypeException();
- ex.setMessage(10301, new Object[]{new Integer(type)});
- throw ex;
- }
-
- return value;
- }
-
- /** {@inheritDoc} */
- @Override
- public double readDouble() throws IOException
- {
- ClassUtil.validateCreation(Double.class);
-
- double d = super.readDouble();
- if (isDebug)
- trace.write(d);
- return d;
- }
-
- /**
- *
- */
- protected String readString() throws IOException
- {
- int ref = readUInt29();
- if ((ref & 1) == 0) // This is a reference
- return getStringReference(ref >> 1);
-
- int len = (ref >> 1); // Read the string in
-
- // writeString() special cases the empty string
- // to avoid creating a reference.
- if (0 == len)
- return EMPTY_STRING;
-
- String str = readUTF(len);
-
- stringTable.add(str); // Remember String
-
- return str;
- }
-
- /**
- * Deserialize the bits of a date-time value w/o a prefixing type byte.
- */
- protected Date readDate() throws IOException
- {
- ClassUtil.validateCreation(Date.class);
-
- int ref = readUInt29();
- if ((ref & 1) == 0) // This is a reference
- return (Date)getObjectReference(ref >> 1);
-
- long time = (long)in.readDouble();
-
- Date d = new Date(time);
-
- objectTable.add(d); //Remember Date
-
- if (isDebug)
- trace.write(d);
-
- return d;
- }
-
- protected Object readDictionary() throws IOException, ClassNotFoundException
- {
- int ref = readUInt29();
-
- if ((ref & 1) == 0) // This is a reference.
- return getObjectReference(ref >> 1);
-
- readBoolean(); // usingWeakTypes - irrelevant in Java.
- int len = (ref >> 1);
-
- Dictionary dictionary = (Hashtable)ClassUtil.createDefaultInstance(Hashtable.class, null, true /*validate*/);
-
- objectTable.add(dictionary); // Remember the object.
-
- if (isDebug)
- trace.startAMFDictionary(objectTable.size() - 1);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug) trace.startDictionaryElement();
- Object key = readObjectOneLevelDown(true);
-
- if (isDebug) trace.addDictionaryEquals();
- Object value = readObjectOneLevelDown(true);
- ClassUtil.validateAssignment(dictionary, key != null? key.toString() : null, value);
- dictionary.put(key, value);
- }
-
- if (isDebug)
- trace.endAMFDictionary();
-
- return dictionary;
- }
-
- protected Object readTypedVector(int type) throws IOException, ClassNotFoundException
- {
- int ref = readUInt29();
-
- if ((ref & 1) == 0) // This is a reference.
- return getObjectReference(ref >> 1);
-
- int len = (ref >> 1);
- boolean fixed = readBoolean();
-
- Object vector = null;
- switch (type)
- {
- case kTypedVectorInt:
- vector = readTypedIntVector(len, fixed);
- break;
- case kTypedVectorUint:
- vector = readTypedUintVector(len, fixed);
- break;
- case kTypedVectorDouble:
- vector = readTypedDoubleVector(len, fixed);
- break;
- case kTypedVectorObject:
- vector = readTypedObjectVector(len, fixed);
- break;
- default:
- // Unknown object type tag {type}
- UnknownTypeException ex = new UnknownTypeException();
- ex.setMessage(10301, new Object[]{Integer.valueOf(type)});
- throw ex;
- }
- return vector;
- }
-
- @SuppressWarnings("unchecked")
- protected Object readTypedIntVector(int len, boolean fixed) throws IOException
- {
- // Don't instantiate Array right away with the supplied size if it is more
- // than INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered.
- boolean useListTemporarily = false;
-
- Object vector;
- if (fixed)
- {
- useListTemporarily = len > INITIAL_COLLECTION_CAPACITY;
- if (useListTemporarily)
- {
- ClassUtil.validateCreation(ArrayList.class);
- vector = new ArrayList<Integer>(INITIAL_COLLECTION_CAPACITY);
- }
- else
- {
- ClassUtil.validateCreation(Integer[].class);
- vector = new Integer[len];
- }
- }
- else
- {
- ClassUtil.validateCreation(ArrayList.class);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- vector = new ArrayList<Integer>(initialCapacity);
- }
-
- int objectId = rememberObject(vector);
-
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.INT);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- ClassUtil.validateCreation(Integer.class);
- int value = readInt();
-
- if (isDebug)
- trace.write(value);
-
- Integer item = Integer.valueOf(value);
-
- ClassUtil.validateAssignment(vector, i, item);
- if (vector instanceof Integer[])
- Array.set(vector, i, item);
- else
- ((List<Integer>)vector).add(item);
- }
-
- if (useListTemporarily)
- {
- vector = ((ArrayList<Integer>)vector).toArray();
- objectTable.set(objectId, vector);
- }
-
- if (isDebug)
- trace.endAMFVector();
-
- return vector;
- }
-
- @SuppressWarnings("unchecked")
- protected Object readTypedUintVector(int len, boolean fixed) throws IOException
- {
- // Don't instantiate Array right away with the supplied size if it is more
- // than INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered.
- boolean useListTemporarily = false;
-
- Object vector;
- if (fixed)
- {
- useListTemporarily = len > INITIAL_COLLECTION_CAPACITY;
- if (useListTemporarily)
- {
- ClassUtil.validateCreation(ArrayList.class);
- vector = new ArrayList<Long>(INITIAL_COLLECTION_CAPACITY);
- }
- else
- {
- ClassUtil.validateCreation(Long[].class);
- vector = new Long[len];
- }
- }
- else
- {
- ClassUtil.validateCreation(ArrayList.class);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- vector = new ArrayList<Long>(initialCapacity);
- }
-
- int objectId = rememberObject(vector);
-
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.UINT);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- ClassUtil.validateCreation(Long.class);
-
- long value = (long) (in.readByte() & 0xFF) << 24L;
- value += (long) (in.readByte() & 0xFF) << 16L;
- value += (long) (in.readByte() & 0xFF) << 8L;
- value += (in.readByte() & 0xFF);
-
- if (isDebug)
- trace.write(value);
-
- Long item = Long.valueOf(value);
-
- ClassUtil.validateAssignment(vector, i, item);
- if (vector instanceof Long[])
- Array.set(vector, i, item);
- else
- ((List<Long>)vector).add(item);
- }
-
- if (useListTemporarily)
- {
- vector = ((ArrayList<Long>)vector).toArray();
- objectTable.set(objectId, vector);
- }
-
- if (isDebug)
- trace.endAMFVector();
-
- return vector;
- }
-
- @SuppressWarnings("unchecked")
- protected Object readTypedDoubleVector(int len, boolean fixed) throws IOException
- {
- // Don't instantiate Array right away with the supplied size if it is more
- // than INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered.
- boolean useListTemporarily = false;
-
- Object vector;
- if (fixed)
- {
- useListTemporarily = len > INITIAL_COLLECTION_CAPACITY;
- if (useListTemporarily)
- {
- ClassUtil.validateCreation(ArrayList.class);
- vector = new ArrayList<Double>(INITIAL_COLLECTION_CAPACITY);
- }
- else
- {
- ClassUtil.validateCreation(Double[].class);
- vector = new Double[len];
- }
- }
- else
- {
- ClassUtil.validateCreation(ArrayList.class);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- vector = new ArrayList<Double>(initialCapacity);
- }
-
- int objectId = rememberObject(vector);
-
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.DOUBLE);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Double item = Double.valueOf(readDouble());
-
- ClassUtil.validateAssignment(vector, i, item);
- if (vector instanceof Double[])
- Array.set(vector, i, item);
- else
- ((List<Double>)vector).add(item);
- }
-
- if (useListTemporarily)
- {
- vector = ((ArrayList<Double>)vector).toArray();
- objectTable.set(objectId, vector);
- }
-
- if (isDebug)
- trace.endAMFVector();
-
- return vector;
- }
-
- @SuppressWarnings("unchecked")
- protected Object readTypedObjectVector(int len, boolean fixed) throws IOException, ClassNotFoundException
- {
- // TODO - Class name is always empty for some reason, need to figure out if this is expected.
- String className = readString();
- if (className == null || className.length() == 0 || className.equals(EMPTY_STRING))
- className = Object.class.getName();
-
- // Don't instantiate Array right away with the supplied size if it is more
- // than INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered.
- boolean useListTemporarily = false;
-
- Object vector;
- if (fixed)
- {
- useListTemporarily = len > INITIAL_COLLECTION_CAPACITY;
- if (useListTemporarily)
- {
- ClassUtil.validateCreation(ArrayList.class);
- vector = new ArrayList<Object>(INITIAL_COLLECTION_CAPACITY);
- }
- else
- {
- ClassUtil.validateCreation(Object[].class);
- vector = new Object[len];
- }
- }
- else
- {
- ClassUtil.validateCreation(ArrayList.class);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- vector = new ArrayList<Object>(initialCapacity);
- }
-
- int objectId = rememberObject(vector);
-
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.OBJECT);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
- Object item = readObjectOneLevelDown(true);
- ClassUtil.validateAssignment(vector, i, item);
- if (vector instanceof Object[])
- Array.set(vector, i, item);
- else
- ((List<Object>)vector).add(item);
- }
-
- if (useListTemporarily)
- {
- vector = ((ArrayList<Object>)vector).toArray();
- objectTable.set(objectId, vector);
- }
-
- if (isDebug)
- trace.endAMFVector();
-
- return vector;
- }
-
- /**
- *
- */
- protected Object readArray() throws ClassNotFoundException, IOException
- {
- int ref = readUInt29();
-
- if ((ref & 1) == 0) // This is a reference.
- return getObjectReference(ref >> 1);
-
- int len = (ref >> 1);
- Object array = null;
-
- // First, look for any string based keys. If any non-ordinal indices were used,
- // or if the Array is sparse, we represent the structure as a Map.
- Map map = null;
- for (; ;)
- {
- String name = readString();
- if (name == null || name.length() == 0)
- break;
-
- if (map == null)
- {
- map = (HashMap)ClassUtil.createDefaultInstance(HashMap.class, null, true /*validate*/);
- array = map;
-
- //Remember Object
- objectTable.add(array);
-
- if (isDebug)
- trace.startECMAArray(objectTable.size() - 1);
- }
-
- if (isDebug)
- trace.namedElement(name);
- Object value = readObjectOneLevelDown(true);
- ClassUtil.validateAssignment(map, name, value);
- map.put(name, value);
- }
-
- // If we didn't find any string based keys, we have a dense Array, so we
- // represent the structure as a List.
- if (map == null)
- {
- // Don't instantiate List/Array right away with the supplied size if it is more than
- // INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered. This at least
- // requires the user to pass in the actual objects for the List/Array to grow beyond.
- boolean useListTemporarily = false;
-
- // Legacy Flex 1.5 behavior was to return a java.util.Collection for Array
- if (context.legacyCollection || len > INITIAL_COLLECTION_CAPACITY)
- {
- useListTemporarily = !context.legacyCollection;
- ClassUtil.validateCreation(ArrayList.class);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- array = new ArrayList(initialCapacity);
- }
- // Flex 2+ behavior is to return Object[] for AS3 Array
- else
- {
- ClassUtil.validateCreation(Object[].class);
- array = new Object[len];
- }
- int objectId = rememberObject(array); // Remember the List/Object[].
-
- if (isDebug)
- trace.startAMFArray(objectTable.size() - 1);
-
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
- Object item = readObjectOneLevelDown(true);
- ClassUtil.validateAssignment(array, i, item);
- if (array instanceof ArrayList)
- ((ArrayList)array).add(item);
- else
- Array.set(array, i, item);
- }
-
- if (useListTemporarily)
- {
- array = ((ArrayList)array).toArray();
- objectTable.set(objectId, array);
- }
- }
- else
- {
- for (int i = 0; i < len; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
- Object item = readObjectOneLevelDown(true);
- String key = Integer.toString(i);
- ClassUtil.validateAssignment(map, key, item);
- map.put(key, item);
- }
- }
-
- if (isDebug)
- trace.endAMFArray();
-
- return array;
- }
-
- /**
- *
- */
- protected Object readScriptObject() throws ClassNotFoundException, IOException
- {
- int ref = readUInt29();
-
- if ((ref & 1) == 0)
- return getObjectReference(ref >> 1);
-
- TraitsInfo ti = readTraits(ref);
- String className = ti.getClassName();
- boolean externalizable = ti.isExternalizable();
-
- // Prepare the parameters for createObjectInstance(). Use an array as a holder
- // to simulate two 'by-reference' parameters className and (initially null) proxy
- Object[] params = new Object[] {className, null};
- Object object = createObjectInstance(params);
-
- // Retrieve any changes to the className and the proxy parameters
- className = (String)params[0];
- PropertyProxy proxy = (PropertyProxy)params[1];
-
- // Remember our instance in the object table
- int objectId = rememberObject(object);
-
- if (externalizable)
- {
- readExternalizable(className, object);
- }
- else
- {
- if (isDebug)
- {
- trace.startAMFObject(className, objectTable.size() - 1);
- }
-
- boolean isCollectionClass = isCollectionClass(object);
- int len = ti.getProperties().size();
-
- for (int i = 0; i < len; i++)
- {
- String propName = ti.getProperty(i);
-
- if (isDebug)
- trace.namedElement(propName);
- Object value = readObjectOneLevelDown(isCollectionClass);
- proxy.setValue(object, propName, value);
- }
-
- if (ti.isDynamic())
- {
- for (; ;)
- {
- String name = readString();
- if (name == null || name.length() == 0) break;
-
- if (isDebug)
- trace.namedElement(name);
- Object value = readObjectOneLevelDown(isCollectionClass);
- proxy.setValue(object, name, value);
- }
- }
- }
-
- if (isDebug)
- trace.endAMFObject();
-
- // This lets the BeanProxy substitute a new instance into the BeanProxy
- // at the end of the serialization. You might for example create a Map, store up
- // the properties, then construct the instance based on that. Note that this does
- // not support recursive references to the parent object however.
- Object newObj = proxy.instanceComplete(object);
-
- // TODO: It is possible we gave out references to the
- // temporary object. it would be possible to warn users about
- // that problem by tracking if we read any references to this object
- // in the readObject call above.
- if (newObj != object)
- {
- objectTable.set(objectId, newObj);
- object = newObj;
- }
-
- return object;
- }
-
- /**
- *
- */
- protected void readExternalizable(String className, Object object) throws ClassNotFoundException, IOException
- {
- if (object instanceof Externalizable)
- {
- ClassUtil.validateCreation(Externalizable.class);
-
- if (isDebug)
- trace.startExternalizableObject(className, objectTable.size() - 1);
-
- ((Externalizable)object).readExternal(this);
- }
- else
- {
- //Class '{className}' must implement java.io.Externalizable to receive client IExternalizable instances.
- SerializationException ex = new SerializationException();
- ex.setMessage(10305, new Object[] {object.getClass().getName()});
- throw ex;
- }
- }
-
- /**
- *
- */
- protected byte[] readByteArray() throws IOException
- {
- ClassUtil.validateCreation(byte[].class);
-
- int ref = readUInt29();
- if ((ref & 1) == 0)
- return (byte[])getObjectReference(ref >> 1);
-
- int len = (ref >> 1);
- int initialCapacity = len < INITIAL_COLLECTION_CAPACITY? len : INITIAL_COLLECTION_CAPACITY;
- ByteArrayOutputStream outStream = new ByteArrayOutputStream(initialCapacity);
- for (int i = 0; i < len; i++)
- outStream.write(in.read());
-
- byte[] ba = outStream.toByteArray();
- objectTable.add(ba);
-
- if (isDebug)
- trace.startByteArray(objectTable.size() - 1, len);
-
- return ba;
- }
-
- /**
- *
- */
- protected TraitsInfo readTraits(int ref) throws IOException
- {
- if ((ref & 3) == 1) // This is a reference
- return getTraitReference(ref >> 2);
-
- boolean externalizable = ((ref & 4) == 4);
- boolean dynamic = ((ref & 8) == 8);
- int count = (ref >> 4); /* uint29 */
- String className = readString();
-
- TraitsInfo ti = new TraitsInfo(className, dynamic, externalizable, count);
-
- // Remember Trait Info
- traitsTable.add(ti);
-
- for (int i = 0; i < count; i++)
- {
- String propName = readString();
- ti.addProperty(propName);
- }
-
- return ti;
- }
-
- /**
- *
- */
- protected String readUTF(int utflen) throws IOException
- {
- checkUTFLength(utflen);
- // We should just read the bytes into a buffer
- byte[] bytearr = new byte[utflen];
-
- in.readFully(bytearr, 0, utflen);
- // It is UTF-8 encoding, directly use new String(bytes, "utf-8");
- String s = new String(bytearr, "utf-8");
- return s;
- }
-
- /**
- * AMF 3 represents smaller integers with fewer bytes using the most
- * significant bit of each byte. The worst case uses 32-bits
- * to represent a 29-bit number, which is what we would have
- * done with no compression.
- * <pre>
- * 0x00000000 - 0x0000007F : 0xxxxxxx
- * 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx
- * 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx
- * 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx
- * 0x40000000 - 0xFFFFFFFF : throw range exception
- * </pre>
- *
- * @return A int capable of holding an unsigned 29 bit integer.
- * @throws IOException
- *
- */
- protected int readUInt29() throws IOException
- {
- int value;
-
- // Each byte must be treated as unsigned
- int b = in.readByte() & 0xFF;
-
- if (b < 128)
- return b;
-
- value = (b & 0x7F) << 7;
- b = in.readByte() & 0xFF;
-
- if (b < 128)
- return (value | b);
-
- value = (value | (b & 0x7F)) << 7;
- b = in.readByte() & 0xFF;
-
- if (b < 128)
- return (value | b);
-
- value = (value | (b & 0x7F)) << 8;
- b = in.readByte() & 0xFF;
-
- return (value | b);
- }
-
- /**
- *
- */
- protected Object readXml() throws IOException
- {
- String xml = null;
-
- int ref = readUInt29();
-
- if ((ref & 1) == 0)
- {
- // This is a reference
- xml = (String)getObjectReference(ref >> 1);
- }
- else
- {
- // Read the string in
- int len = (ref >> 1);
-
- // writeString() special case the empty string
- // for speed. Do add a reference
- if (0 == len)
- xml = (String)ClassUtil.createDefaultInstance(String.class, null);
- else
- xml = readUTF(len);
-
- //Remember Object
- objectTable.add(xml);
-
- if (isDebug)
- trace.write(xml);
- }
-
- return stringToDocument(xml);
- }
-
- /**
- *
- */
- protected Object getObjectReference(int ref)
- {
- if (isDebug)
- trace.writeRef(ref);
-
- return objectTable.get(ref);
- }
-
- /**
- *
- */
- protected String getStringReference(int ref)
- {
- String str = (String)stringTable.get(ref);
-
- if (Trace.amf && isDebug)
- trace.writeStringRef(ref);
-
- return str;
- }
-
- /**
- *
- */
- protected TraitsInfo getTraitReference(int ref)
- {
- if (Trace.amf && isDebug)
- trace.writeTraitsInfoRef(ref);
-
- return (TraitsInfo)traitsTable.get(ref);
- }
-
- /**
- * Remember a deserialized object so that you can use it later through a reference.
- */
- protected int rememberObject(Object obj)
- {
- int id = objectTable.size();
- objectTable.add(obj);
- return id;
- }
-
-
- protected Object readObjectOneLevelDown(boolean nestCollectionLevelDown) throws ClassNotFoundException, IOException
- {
- increaseNestObjectLevel();
- if (nestCollectionLevelDown)
- increaseNestCollectionLevel();
- Object value = readObject();
- decreaseNestObjectLevel();
- if (nestCollectionLevelDown)
- decreaseNestCollectionLevel();
- return value;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/amf/Amf3Output.java
----------------------------------------------------------------------
diff --git a/core/src/flex/messaging/io/amf/Amf3Output.java b/core/src/flex/messaging/io/amf/Amf3Output.java
deleted file mode 100644
index 7919530..0000000
--- a/core/src/flex/messaging/io/amf/Amf3Output.java
+++ /dev/null
@@ -1,1376 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.io.amf;
-
-import flex.messaging.MessageException;
-import flex.messaging.io.ArrayCollection;
-import flex.messaging.io.BeanProxy;
-import flex.messaging.io.PagedRowSet;
-import flex.messaging.io.PropertyProxy;
-import flex.messaging.io.PropertyProxyRegistry;
-import flex.messaging.io.SerializationContext;
-import flex.messaging.io.SerializationDescriptor;
-import flex.messaging.io.StatusInfoProxy;
-import flex.messaging.io.amf.AmfTrace.VectorType;
-import flex.messaging.util.Trace;
-import org.w3c.dom.Document;
-
-import javax.sql.RowSet;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Serializes data to an output stream using the new
- * AMF 3 format.
- * <p>
- * This class intends to match the Flash Player 8 C++ code
- * in avmglue/DataIO.cpp
- * </p>
- *
- *
- */
-public class Amf3Output extends AbstractAmfOutput implements Amf3Types
-{
- /**
- *
- */
- protected IdentityHashMap<Object, Integer> objectTable;
-
- /**
- *
- */
- protected HashMap<TraitsInfo, Integer> traitsTable;
-
- /**
- *
- */
- protected HashMap<String, Integer> stringTable;
-
- public Amf3Output(SerializationContext context)
- {
- super(context);
- context.supportDatesByReference = true;
- }
-
- public void reset()
- {
- super.reset();
- if (objectTable != null)
- objectTable.clear();
- if (traitsTable != null)
- traitsTable.clear();
- if (stringTable != null)
- stringTable.clear();
- }
-
- //
- // java.io.ObjectOutput IMPLEMENTATIONS
- //
-
- /**
- * Serialize an Object using AMF 3.
- * @param o the object to write
- * @throws IOException if the write failed
- */
- public void writeObject(Object o) throws IOException
- {
- if (o == null)
- {
- writeAMFNull();
- return;
- }
-
- if (!context.legacyExternalizable && o instanceof Externalizable)
- {
- writeCustomObject(o);
- }
- else if (o instanceof String || o instanceof Character)
- {
- String s = o.toString();
- writeAMFString(s);
- }
- else if (o instanceof Number)
- {
- if (o instanceof Integer || o instanceof Short || o instanceof Byte)
- {
- int i = ((Number)o).intValue();
- writeAMFInt(i);
- }
- else if (!context.legacyBigNumbers &&
- (o instanceof BigInteger || o instanceof BigDecimal))
- {
- // Using double to write big numbers such as BigInteger or
- // BigDecimal can result in information loss so we write
- // them as String by default...
- writeAMFString(o.toString());
- }
- else
- {
- double d = ((Number)o).doubleValue();
- writeAMFDouble(d);
- }
- }
- else if (o instanceof Boolean)
- {
- writeAMFBoolean(((Boolean)o).booleanValue());
- }
- // We have a complex type...
- else if (o instanceof Date)
- {
- writeAMFDate((Date)o);
- }
- else if (o instanceof Calendar)
- {
- writeAMFDate(((Calendar)o).getTime());
- }
- else if (o instanceof Document)
- {
- if (context.legacyXMLDocument)
- out.write(kXMLType); // Legacy flash.xml.XMLDocument Type
- else
- out.write(kAvmPlusXmlType); // New E4X XML Type
- if (!byReference(o))
- {
- String xml = documentToString(o);
- if (isDebug)
- trace.write(xml);
-
- writeAMFUTF(xml);
- }
- }
- // If there is a proxy for this,write it as a custom object so the default
- // behavior can be overriden.
- else if (o instanceof Enum && PropertyProxyRegistry.getRegistry().getProxy(o.getClass()) == null)
- {
- Enum<?> enumValue = (Enum<?>)o;
- writeAMFString(enumValue.name());
- }
- else
- {
- // We have an Object or Array type...
- Class cls = o.getClass();
-
- if (context.legacyMap && o instanceof Map && !(o instanceof ASObject))
- {
- writeMapAsECMAArray((Map)o);
- }
- else if (!context.legacyDictionary && o instanceof Dictionary)
- {
- writeDictionary((Dictionary)o);
- }
- else if (o instanceof Collection)
- {
- if (o instanceof List && context.preferVectors)
- writeListAsTypedVector((List)o);
- else if (context.legacyCollection)
- writeCollection((Collection)o, null);
- else
- writeArrayCollection((Collection)o, null);
- }
- else if (cls.isArray())
- {
- Class<?> componentType = cls.getComponentType();
- // Convert to vector if requested, except for character and byte arrays
- if (context.preferVectors &&
- !(componentType.equals(Byte.class) || componentType.equals(byte.class))&&
- !(componentType.equals(Character.class) || componentType.equals(char.class)))
- writeArrayAsTypedVector(o, componentType);
- else
- writeAMFArray(o, componentType);
- }
- else
- {
- //Special Case: wrap RowSet in PageableRowSet for Serialization
- if (o instanceof RowSet)
- {
- o = new PagedRowSet((RowSet)o, Integer.MAX_VALUE, false);
- }
- else if (context.legacyThrowable && o instanceof Throwable)
- {
- o = new StatusInfoProxy((Throwable)o);
- }
-
- writeCustomObject(o);
- }
- }
- }
-
- public void writeObjectTraits(TraitsInfo ti) throws IOException
- {
- String className = ti.getClassName();
-
- if (isDebug)
- {
- if (ti.isExternalizable())
- trace.startExternalizableObject(className, getObjectTableSize());
- else
- trace.startAMFObject(className, getObjectTableSize());
- }
-
- if (!byReference(ti))
- {
- int count = 0;
- List propertyNames = null;
- boolean externalizable = ti.isExternalizable();
-
- if (!externalizable)
- {
- propertyNames = ti.getProperties();
- if (propertyNames != null)
- count = propertyNames.size();
- }
-
- boolean dynamic = ti.isDynamic();
-
- writeUInt29(3 | (externalizable ? 4 : 0) | (dynamic ? 8 : 0) | (count << 4));
- writeStringWithoutType(className);
-
- if (!externalizable && propertyNames != null)
- {
- for (int i = 0; i < count; i++)
- {
- String propName = ti.getProperty(i);
- writeStringWithoutType(propName);
- }
- }
- }
- }
-
- public void writeObjectProperty(String name, Object value) throws IOException
- {
- if (isDebug)
- trace.namedElement(name);
- increaseNestObjectLevel();
- writeObject(value);
- decreaseNestObjectLevel();
- }
-
- public void writeObjectEnd() throws IOException
- {
- // No action required for AMF 3
-
- if (isDebug)
- trace.endAMFObject();
- }
-
- //
- // AMF SPECIFIC SERIALIZATION IMPLEMENTATIONS
- //
-
- /**
- *
- */
- protected void writeAMFBoolean(boolean b) throws IOException
- {
- if (isDebug)
- trace.write(b);
-
- if (b)
- out.write(kTrueType);
- else
- out.write(kFalseType);
- }
-
- /**
- *
- */
- protected void writeAMFDate(Date d) throws IOException
- {
- out.write(kDateType);
-
- if (!byReference(d))
- {
- if (isDebug)
- trace.write(d);
-
- //Write out an invalid reference
- writeUInt29(1);
-
- // Write the time as 64bit value in ms
- out.writeDouble((double)d.getTime());
- }
- }
-
- /**
- *
- */
- protected void writeAMFDouble(double d) throws IOException
- {
- if (isDebug)
- trace.write(d);
-
- out.write(kDoubleType);
- out.writeDouble(d);
- }
-
- /**
- *
- */
- protected void writeAMFInt(int i) throws IOException
- {
- if (i >= INT28_MIN_VALUE && i <= INT28_MAX_VALUE)
- {
- if (isDebug)
- trace.write(i);
-
- // We have to be careful when the MSB is set, as (value >> 3) will sign extend.
- // We know there are only 29-bits of precision, so truncate. This requires
- // similar care when reading an integer.
- //i = ((i >> 3) & UINT29_MASK);
- i = i & UINT29_MASK; // Mask is 2^29 - 1
- out.write(kIntegerType);
- writeUInt29(i);
- }
- else
- {
- // Promote large int to a double
- writeAMFDouble(i);
- }
- }
-
- protected void writeDictionary(Dictionary dictionary) throws IOException
- {
- out.write(kDictionaryType);
-
- if (byReference(dictionary))
- return;
-
- writeUInt29((dictionary.size() << 1) | 1);
- writeAMFBoolean(false /*usingWeakKeys*/);
-
- if (isDebug) trace.startAMFDictionary(objectTable.size() - 1);
-
- Enumeration keys = dictionary.keys();
- while (keys.hasMoreElements())
- {
- if (isDebug) trace.startDictionaryElement();
- Object key = keys.nextElement();
- increaseNestObjectLevel();
- writeObject(key);
- decreaseNestObjectLevel();
- if (isDebug) trace.addDictionaryEquals();
- Object value = dictionary.get(key);
- increaseNestObjectLevel();
- writeObject(value);
- decreaseNestObjectLevel();
- }
-
- if (isDebug)
- trace.endAMFDictionary();
- }
-
- protected void writeArrayAsTypedVector(Object array, Class<?> componentType) throws IOException
- {
- int vecType = kTypedVectorObject;
- if (componentType.isPrimitive())
- {
- if (int.class.equals(componentType))
- vecType = kTypedVectorInt;
- else if (double.class.equals(componentType))
- vecType = kTypedVectorDouble;
- }
- else
- {
- if (Integer.class.equals(componentType))
- vecType = kTypedVectorInt;
- else if (Double.class.equals(componentType))
- vecType = kTypedVectorDouble;
- }
-
- out.write(vecType);
-
- if (byReference(array))
- return;
-
- int length = Array.getLength(array);
- writeUInt29((length << 1) | 1);
- writeBoolean(true /*fixed*/);
-
- switch (vecType)
- {
- case kTypedVectorInt:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.INT);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = Array.get(array, i);
- int value = ((Integer)element).intValue();
-
- if (isDebug)
- trace.write(value);
-
- writeInt(value);
- }
- break;
- case kTypedVectorDouble:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.DOUBLE);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = Array.get(array, i);
- double value = ((Double)element).doubleValue();
-
- if (isDebug)
- trace.write(value);
-
- writeDouble(value);
- }
- break;
- case kTypedVectorObject:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.OBJECT);
-
- // TODO - I don't think this className is used properly on the client currently.
- String className = componentType.getName();
- writeStringWithoutType(className);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = Array.get(array, i);
- increaseNestObjectLevel();
- writeObject(element);
- decreaseNestObjectLevel();
- }
- break;
- default:
- break;
- }
-
- if (isDebug)
- trace.endAMFVector();
- }
-
- protected void writeListAsTypedVector(List list) throws IOException
- {
- // Peek at the first three elements of the list to figure out what type
- // of Vector it should be sent as.
- int vecType = -1;
- Class<?> initialElementClass = null;
- int peekSize = Math.min(list.size(), 3);
- for (int i = 0; i < peekSize; i++)
- {
- Object element = list.get(i);
- if (i == 0)
- {
- initialElementClass = element != null? element.getClass() : null;
- }
- else
- {
- Class<?> currentElementClass = element != null? element.getClass() : null;
- if (initialElementClass != currentElementClass)
- {
- vecType = kTypedVectorObject;
- break;
- }
- }
- }
-
- if (vecType == -1)
- {
- if (initialElementClass == Integer.class)
- vecType = kTypedVectorInt;
- else if (initialElementClass == Double.class)
- vecType = kTypedVectorDouble;
- else
- vecType = kTypedVectorObject;
-
- }
-
- out.write(vecType);
-
- if (byReference(list))
- return;
-
- int length = list.size();
- writeUInt29((length << 1) | 1);
- writeBoolean(false /*fixed*/);
-
- switch (vecType)
- {
- case kTypedVectorInt:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.INT);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = list.get(i);
- int value = ((Integer)element).intValue();
-
- if (isDebug)
- trace.write(value);
-
- writeInt(value);
- }
- break;
- case kTypedVectorDouble:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.DOUBLE);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = list.get(i);
- double value = ((Double)element).doubleValue();
-
- if (isDebug)
- trace.write(value);
-
- writeDouble(value);
- }
- break;
- case kTypedVectorObject:
- if (isDebug)
- trace.startAMFVector(objectTable.size() - 1, VectorType.OBJECT);
-
- // TODO - I don't think this className is used properly on the client currently.
- String className = initialElementClass != null? initialElementClass.getName() : "";
- writeStringWithoutType(className);
-
- for (int i = 0; i < length; i++)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object element = list.get(i);
- increaseNestObjectLevel();
- writeObject(element);
- decreaseNestObjectLevel();
- }
- break;
- default:
- break;
- }
-
- if (isDebug)
- trace.endAMFVector();
- }
-
- /**
- *
- */
- protected void writeMapAsECMAArray(Map map) throws IOException
- {
- out.write(kArrayType);
-
- if (!byReference(map))
- {
- if (isDebug)
- trace.startECMAArray(getObjectTableSize());
-
- writeUInt29((0 << 1) | 1);
-
- Iterator it = map.keySet().iterator();
- while (it.hasNext())
- {
- Object key = it.next();
- if (key != null)
- {
- String propName = key.toString();
- writeStringWithoutType(propName);
-
- if (isDebug)
- trace.namedElement(propName);
-
- increaseNestObjectLevel();
- writeObject(map.get(key));
- decreaseNestObjectLevel();
- }
- }
-
- writeStringWithoutType(EMPTY_STRING);
-
- if (isDebug)
- trace.endAMFArray();
- }
- }
-
- /**
- *
- */
- protected void writeAMFNull() throws IOException
- {
- if (isDebug)
- trace.writeNull();
-
- out.write(kNullType);
- }
-
- /**
- *
- */
- protected void writeAMFString(String s) throws IOException
- {
- out.write(kStringType);
- writeStringWithoutType(s);
-
- if (isDebug)
- {
- trace.writeString(s);
- }
- }
-
- /**
- *
- */
- protected void writeStringWithoutType(String s) throws IOException
- {
- if (s.length() == 0)
- {
- // don't create a reference for the empty string,
- // as it's represented by the one byte value 1
- // len = 0, ((len << 1) | 1).
- writeUInt29(1);
- return;
- }
-
- if (!byReference(s))
- {
- writeAMFUTF(s);
- return;
- }
- }
-
- /**
- *
- */
- protected void writeAMFArray(Object o, Class componentType) throws IOException
- {
- if (componentType.isPrimitive())
- {
- writePrimitiveArray(o);
- }
- else if (componentType.equals(Byte.class))
- {
- writeAMFByteArray((Byte[])o);
- }
- else if (componentType.equals(Character.class))
- {
- writeCharArrayAsString((Character[])o);
- }
- else
- {
- writeObjectArray((Object[])o, null);
- }
- }
-
- /**
- *
- */
- protected void writeArrayCollection(Collection col, SerializationDescriptor desc) throws IOException
- {
- out.write(kObjectType);
-
- if (!byReference(col))
- {
- ArrayCollection ac;
-
- if (col instanceof ArrayCollection)
- {
- ac = (ArrayCollection)col;
- // TODO: QUESTION: Pete, ignoring the descriptor here... not sure if
- // we should modify the user's AC as that could cause corruption?
- }
- else
- {
- // Wrap any Collection in an ArrayCollection
- ac = new ArrayCollection(col);
- if (desc != null)
- ac.setDescriptor(desc);
- }
-
- // Then wrap ArrayCollection in PropertyProxy for bean-like serialization
- PropertyProxy proxy = PropertyProxyRegistry.getProxy(ac);
- writePropertyProxy(proxy, ac);
- }
- }
-
- /**
- *
- */
- protected void writeCustomObject(Object o) throws IOException
- {
- PropertyProxy proxy = null;
-
- if (o instanceof PropertyProxy)
- {
- proxy = (PropertyProxy)o;
- o = proxy.getDefaultInstance();
-
- // The proxy may wrap a null default instance, if so, short circuit here.
- if (o == null)
- {
- writeAMFNull();
- return;
- }
-
- // HACK: Short circuit and unwrap if PropertyProxy is wrapping an Array
- // or Collection or Map with legacyMap as true since we don't yet have
- // the ability to proxy multiple AMF types. We write an AMF Array directly
- // instead of an AMF Object...
- else if (o instanceof Collection)
- {
- if (context.legacyCollection)
- writeCollection((Collection)o, proxy.getDescriptor());
- else
- writeArrayCollection((Collection)o, proxy.getDescriptor());
- return;
- }
- else if (o.getClass().isArray())
- {
- writeObjectArray((Object[])o, proxy.getDescriptor());
- return;
- }
- else if (context.legacyMap && o instanceof Map && !(o instanceof ASObject))
- {
- writeMapAsECMAArray((Map)o);
- return;
- }
- }
-
- out.write(kObjectType);
-
- if (!byReference(o))
- {
- if (proxy == null)
- {
- proxy = PropertyProxyRegistry.getProxyAndRegister(o);
- }
-
- writePropertyProxy(proxy, o);
- }
- }
-
- /**
- *
- */
- protected void writePropertyProxy(PropertyProxy proxy, Object instance) throws IOException
- {
- /*
- * At this point we substitute the instance we want to serialize.
- */
- Object newInst = proxy.getInstanceToSerialize(instance);
- if (newInst != instance)
- {
- // We can't use writeAMFNull here I think since we already added this object
- // to the object table on the server side. The player won't have any way
- // of knowing we have this reference mapped to null.
- if (newInst == null)
- throw new MessageException("PropertyProxy.getInstanceToSerialize class: " + proxy.getClass() + " returned null for instance class: " + instance.getClass().getName());
-
- // Grab a new proxy if necessary for the new instance
- proxy = PropertyProxyRegistry.getProxyAndRegister(newInst);
- instance = newInst;
- }
-
- List propertyNames = null;
- boolean externalizable = proxy.isExternalizable(instance);
-
- if (!externalizable)
- {
- propertyNames = proxy.getPropertyNames(instance);
- // filter write-only properties
- if (proxy instanceof BeanProxy)
- {
- BeanProxy bp = (BeanProxy)proxy;
- if (propertyNames != null && !propertyNames.isEmpty())
- {
- List<String> propertiesToRemove = null;
- for (int i = 0; i < propertyNames.size(); i++)
- {
- String propName = (String)propertyNames.get(i);
- if (bp.isWriteOnly(instance, propName))
- {
- if (propertiesToRemove == null)
- propertiesToRemove = new ArrayList<String>();
- propertiesToRemove.add(propName);
- }
- }
- if (propertiesToRemove != null)
- propertyNames.removeAll(propertiesToRemove);
- }
- }
- }
-
-
- TraitsInfo ti = new TraitsInfo(proxy.getAlias(instance), proxy.isDynamic(), externalizable, propertyNames);
- writeObjectTraits(ti);
-
- if (externalizable)
- {
- // Call user defined serialization
- ((Externalizable)instance).writeExternal(this);
- }
- else if (propertyNames != null && !propertyNames.isEmpty())
- {
- for (int i = 0; i < propertyNames.size(); i++)
- {
- String propName = (String)propertyNames.get(i);
- Object value = proxy.getValue(instance, propName);
- writeObjectProperty(propName, value);
- }
- }
-
- writeObjectEnd();
- }
-
-
- /**
- * Serialize an array of primitives.
- * <p>
- * Primitives include the following:
- * boolean, char, double, float, long, int, short, byte
- * </p>
- *
- * @param obj An array of primitives
- *
- */
- protected void writePrimitiveArray(Object obj) throws IOException
- {
- Class aType = obj.getClass().getComponentType();
-
- if (aType.equals(Character.TYPE))
- {
- //Treat char[] as a String
- char[] c = (char[])obj;
- writeCharArrayAsString(c);
- }
- else if (aType.equals(Byte.TYPE))
- {
- writeAMFByteArray((byte[])obj);
- }
- else
- {
- out.write(kArrayType);
-
- if (!byReference(obj))
- {
- if (aType.equals(Boolean.TYPE))
- {
- boolean[] b = (boolean[])obj;
-
- // Write out an invalid reference, storing the length in the unused 28-bits.
- writeUInt29((b.length << 1) | 1);
-
- // Send an empty string to imply no named keys
- writeStringWithoutType(EMPTY_STRING);
-
- if (isDebug)
- {
- trace.startAMFArray(getObjectTableSize());
-
- for (int i = 0; i < b.length; i++)
- {
- trace.arrayElement(i);
- writeAMFBoolean(b[i]);
- }
-
- trace.endAMFArray();
- }
- else
- {
- for (int i = 0; i < b.length; i++)
- {
- writeAMFBoolean(b[i]);
- }
- }
- }
- else if (aType.equals(Integer.TYPE) || aType.equals(Short.TYPE))
- {
- //We have a primitive number, either an int or short
- //We write all of these as Integers...
- int length = Array.getLength(obj);
-
- // Write out an invalid reference, storing the length in the unused 28-bits.
- writeUInt29((length << 1) | 1);
- // Send an empty string to imply no named keys
- writeStringWithoutType(EMPTY_STRING);
-
- if (isDebug)
- {
- trace.startAMFArray(getObjectTableSize());
-
- for (int i = 0; i < length; i++)
- {
- trace.arrayElement(i);
- int v = Array.getInt(obj, i);
- writeAMFInt(v);
- }
-
- trace.endAMFArray();
- }
- else
- {
- for (int i = 0; i < length; i++)
- {
- int v = Array.getInt(obj, i);
- writeAMFInt(v);
- }
- }
- }
- else
- {
- //We have a primitive number, either a double, float, or long
- //We write all of these as doubles...
- int length = Array.getLength(obj);
-
- // Write out an invalid reference, storing the length in the unused 28-bits.
- writeUInt29((length << 1) | 1);
- // Send an empty string to imply no named keys
- writeStringWithoutType(EMPTY_STRING);
-
- if (isDebug)
- {
- trace.startAMFArray(getObjectTableSize());
-
- for (int i = 0; i < length; i++)
- {
- trace.arrayElement(i);
- double v = Array.getDouble(obj, i);
- writeAMFDouble(v);
- }
-
- trace.endAMFArray();
- }
- else
- {
- for (int i = 0; i < length; i++)
- {
- double v = Array.getDouble(obj, i);
- writeAMFDouble(v);
- }
- }
- }
- }
- }
- }
-
- /**
- *
- */
- protected void writeAMFByteArray(byte[] ba) throws IOException
- {
- out.write(kByteArrayType);
-
- if (!byReference(ba))
- {
- int length = ba.length;
-
- // Write out an invalid reference, storing the length in the unused 28-bits.
- writeUInt29((length << 1) | 1);
-
- if (isDebug)
- {
- trace.startByteArray(getObjectTableSize(), length);
- }
-
- out.write(ba, 0, length);
- }
- }
-
- /**
- *
- */
- protected void writeAMFByteArray(Byte[] ba) throws IOException
- {
- out.write(kByteArrayType);
-
- if (!byReference(ba))
- {
- int length = ba.length;
-
- // Write out an invalid reference, storing the length in the unused 28-bits.
- writeUInt29((length << 1) | 1);
-
- if (isDebug)
- {
- trace.startByteArray(getObjectTableSize(), length);
- }
-
- for (int i = 0; i < ba.length; i++)
- {
- Byte b = ba[i];
- if (b == null)
- out.write(0);
- else
- out.write(b.byteValue());
- }
- }
- }
-
- /**
- *
- */
- protected void writeCharArrayAsString(Character[] ca) throws IOException
- {
- int length = ca.length;
- char[] chars = new char[length];
-
- for (int i = 0; i < length; i++)
- {
- Character c = ca[i];
- if (c == null)
- chars[i] = 0;
- else
- chars[i] = ca[i].charValue();
- }
- writeCharArrayAsString(chars);
- }
-
- /**
- *
- */
- protected void writeCharArrayAsString(char[] ca) throws IOException
- {
- String str = new String(ca);
- writeAMFString(str);
- }
-
- /**
- *
- */
- protected void writeObjectArray(Object[] values, SerializationDescriptor descriptor) throws IOException
- {
- out.write(kArrayType);
-
- if (!byReference(values))
- {
- if (isDebug)
- trace.startAMFArray(getObjectTableSize());
-
- writeUInt29((values.length << 1) | 1);
-
- // Send an empty string to imply no named keys
- writeStringWithoutType(EMPTY_STRING);
-
- for (int i = 0; i < values.length; ++i)
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object item = values[i];
- if (item != null && descriptor != null && !(item instanceof String)
- && !(item instanceof Number) && !(item instanceof Boolean)
- && !(item instanceof Character))
- {
- PropertyProxy proxy = PropertyProxyRegistry.getProxy(item);
- proxy = (PropertyProxy)proxy.clone();
- proxy.setDescriptor(descriptor);
- proxy.setDefaultInstance(item);
- item = proxy;
- }
- increaseNestObjectLevel();
- writeObject(item);
- decreaseNestObjectLevel();
- }
-
- if (isDebug)
- trace.endAMFArray();
- }
- }
-
- /**
- *
- */
- protected void writeCollection(Collection c, SerializationDescriptor descriptor) throws IOException
- {
- out.write(kArrayType);
-
- // Note: We process Collections independently of Object[]
- // as we want the reference to be based on the actual
- // Collection.
- if (!byReference(c))
- {
- if (isDebug)
- trace.startAMFArray(getObjectTableSize());
-
- writeUInt29((c.size() << 1) | 1);
-
- // Send an empty string to imply no named keys
- writeStringWithoutType(EMPTY_STRING);
-
- Iterator it = c.iterator();
- int i = 0;
- while (it.hasNext())
- {
- if (isDebug)
- trace.arrayElement(i);
-
- Object item = it.next();
-
- if (item != null && descriptor != null && !(item instanceof String)
- && !(item instanceof Number) && !(item instanceof Boolean)
- && !(item instanceof Character))
- {
- PropertyProxy proxy = PropertyProxyRegistry.getProxy(item);
- proxy = (PropertyProxy)proxy.clone();
- proxy.setDescriptor(descriptor);
- proxy.setDefaultInstance(item);
- item = proxy;
- }
- increaseNestObjectLevel();
- writeObject(item);
- decreaseNestObjectLevel();
-
- i++;
- }
-
- if (isDebug)
- trace.endAMFArray();
- }
- }
-
- /**
- *
- */
- protected void writeUInt29(int ref) throws IOException
- {
- // Represent smaller integers with fewer bytes using the most
- // significant bit of each byte. The worst case uses 32-bits
- // to represent a 29-bit number, which is what we would have
- // done with no compression.
-
- // 0x00000000 - 0x0000007F : 0xxxxxxx
- // 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx
- // 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx
- // 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx
- // 0x40000000 - 0xFFFFFFFF : throw range exception
- if (ref < 0x80)
- {
- // 0x00000000 - 0x0000007F : 0xxxxxxx
- out.writeByte(ref);
- }
- else if (ref < 0x4000)
- {
- // 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx
- out.writeByte(((ref >> 7) & 0x7F) | 0x80);
- out.writeByte(ref & 0x7F);
-
- }
- else if (ref < 0x200000)
- {
- // 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx
- out.writeByte(((ref >> 14) & 0x7F) | 0x80);
- out.writeByte(((ref >> 7) & 0x7F) | 0x80);
- out.writeByte(ref & 0x7F);
-
- }
- else if (ref < 0x40000000)
- {
- // 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx
- out.writeByte(((ref >> 22) & 0x7F) | 0x80);
- out.writeByte(((ref >> 15) & 0x7F) | 0x80);
- out.writeByte(((ref >> 8) & 0x7F) | 0x80);
- out.writeByte(ref & 0xFF);
-
- }
- else
- {
- // 0x40000000 - 0xFFFFFFFF : throw range exception
- throw new MessageException("Integer out of range: " + ref);
- }
- }
-
- /**
- *
- */
- public void writeAMFUTF(String s) throws IOException
- {
- int strlen = s.length();
- int utflen = 0;
- int c, count = 0;
-
- char[] charr = getTempCharArray(strlen);
- s.getChars(0, strlen, charr, 0);
-
- for (int i = 0; i < strlen; i++)
- {
- c = charr[i];
- if (c <= 0x007F)
- {
- utflen++;
- }
- else if (c > 0x07FF)
- {
- utflen += 3;
- }
- else
- {
- utflen += 2;
- }
- }
-
- writeUInt29((utflen << 1) | 1);
-
- byte[] bytearr = getTempByteArray(utflen);
-
- for (int i = 0; i < strlen; i++)
- {
- c = charr[i];
- if (c <= 0x007F)
- {
- bytearr[count++] = (byte)c;
- }
- else if (c > 0x07FF)
- {
- bytearr[count++] = (byte)(0xE0 | ((c >> 12) & 0x0F));
- bytearr[count++] = (byte)(0x80 | ((c >> 6) & 0x3F));
- bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F));
- }
- else
- {
- bytearr[count++] = (byte)(0xC0 | ((c >> 6) & 0x1F));
- bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F));
- }
- }
- out.write(bytearr, 0, utflen);
- }
-
- /**
- * Attempts to serialize the object as a reference.
- * If the object cannot be serialized as a reference, it is stored
- * in the reference collection for potential future encounter.
- *
- * @return Success/failure indicator as to whether the object could be
- * serialized as a reference.
- *
- */
- protected boolean byReference(Object o) throws IOException
- {
- if (objectTable != null && objectTable.containsKey(o))
- {
- try
- {
- int refNum = objectTable.get(o).intValue();
-
- if (isDebug)
- trace.writeRef(refNum);
-
- writeUInt29(refNum << 1);
-
- return true;
- }
- catch (ClassCastException e)
- {
- throw new IOException("Object reference is not an Integer");
- }
- }
-
- if (objectTable == null)
- objectTable = new IdentityHashMap<Object, Integer>(64);
- objectTable.put(o, Integer.valueOf(objectTable.size()));
- return false;
- }
-
- /**
- *
- */
- public void addObjectReference(Object o) throws IOException
- {
- byReference(o);
- }
-
- /**
- *
- */
- protected boolean byReference(String s) throws IOException
- {
- if (stringTable != null && stringTable.containsKey(s))
- {
- try
- {
- int refNum = stringTable.get(s).intValue();
-
- writeUInt29(refNum << 1);
-
- if (isDebug && Trace.amf)
- trace.writeStringRef(refNum);
- return true;
- }
- catch (ClassCastException e)
- {
- throw new IOException("String reference is not an Integer");
- }
- }
- if (stringTable == null)
- stringTable = new HashMap<String, Integer>(64);
- stringTable.put(s, Integer.valueOf(stringTable.size()));
- return false;
- }
-
- /**
- *
- */
- protected boolean byReference(TraitsInfo ti) throws IOException
- {
- if (traitsTable != null && traitsTable.containsKey(ti))
- {
- try
- {
- int refNum = traitsTable.get(ti).intValue();
-
- writeUInt29((refNum << 2) | 1);
-
- if (isDebug && Trace.amf)
- trace.writeTraitsInfoRef(refNum);
- return true;
- }
- catch (ClassCastException e)
- {
- throw new IOException("TraitsInfo reference is not an Integer");
- }
- }
- if (traitsTable == null)
- traitsTable = new HashMap<TraitsInfo, Integer>(10);
- traitsTable.put(ti, Integer.valueOf(traitsTable.size()));
- return false;
- }
-
- protected int getObjectTableSize()
- {
- return objectTable != null? objectTable.size() - 1 : 0;
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/amf/Amf3Types.java
----------------------------------------------------------------------
diff --git a/core/src/flex/messaging/io/amf/Amf3Types.java b/core/src/flex/messaging/io/amf/Amf3Types.java
deleted file mode 100644
index 72e1b82..0000000
--- a/core/src/flex/messaging/io/amf/Amf3Types.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.io.amf;
-
-/**
- * AMF3 type markers and constants for AVM+ Serialization.
- *
- * @see flex.messaging.io.amf.AmfTypes for AMF 0 Type Markers.
- */
-public interface Amf3Types
-{
- // AMF marker constants
- int kUndefinedType = 0;
- int kNullType = 1;
- int kFalseType = 2;
- int kTrueType = 3;
- int kIntegerType = 4;
- int kDoubleType = 5;
- int kStringType = 6;
- int kXMLType = 7;
- int kDateType = 8;
- int kArrayType = 9;
- int kObjectType = 10;
- int kAvmPlusXmlType = 11;
- int kByteArrayType = 12;
- int kTypedVectorInt = 13;
- int kTypedVectorUint= 14;
- int kTypedVectorDouble = 15;
- int kTypedVectorObject = 16;
- int kDictionaryType = 17;
-
- String EMPTY_STRING = "";
-
- /**
- * Internal use only.
- *
- */
- int UINT29_MASK = 0x1FFFFFFF; // 2^29 - 1
-
- /**
- * The maximum value for an <code>int</code> that will avoid promotion to an
- * ActionScript Number when sent via AMF 3 is 2<sup>28</sup> - 1, or <code>0x0FFFFFFF</code>.
- */
- int INT28_MAX_VALUE = 0x0FFFFFFF; // 2^28 - 1
-
- /**
- * The minimum value for an <code>int</code> that will avoid promotion to an
- * ActionScript Number when sent via AMF 3 is -2<sup>28</sup> or <code>0xF0000000</code>.
- */
- int INT28_MIN_VALUE = 0xF0000000; // -2^28 in 2^29 scheme
-}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/core/src/flex/messaging/io/amf/AmfIO.java
----------------------------------------------------------------------
diff --git a/core/src/flex/messaging/io/amf/AmfIO.java b/core/src/flex/messaging/io/amf/AmfIO.java
deleted file mode 100644
index 6336a4d..0000000
--- a/core/src/flex/messaging/io/amf/AmfIO.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package flex.messaging.io.amf;
-
-import flex.messaging.MessageException;
-import flex.messaging.io.AbstractProxy;
-import flex.messaging.io.SerializationContext;
-import flex.messaging.io.SerializationException;
-import flex.messaging.io.TypeMarshallingContext;
-
-/**
- * Base class for Amf I/O.
- *
- */
-abstract class AmfIO
-{
- protected final SerializationContext context;
- /*
- * DEBUG LOGGING.
- */
- protected boolean isDebug;
- protected AmfTrace trace;
-
- // Nest object level, how deep the object graph is right now
- private int nestObjectLevel;
- // Nest collection level, how deep the collection nest is right now, for example 3 dimensional matrix will reach level of 3
- private int nestCollectionLevel;
-
-
- /*
- * OPTIMIZATION.
- */
- private char[] tempCharArray = null;
- private byte[] tempByteArray = null;
-
- AmfIO(SerializationContext context)
- {
- this.context = context;
- nestObjectLevel = 0;
- nestCollectionLevel = 0;
- }
-
- /**
- * Turns on "trace" debugging for AMF responses.
- * @param trace the trace object
- */
- public void setDebugTrace(AmfTrace trace)
- {
- this.trace = trace;
- isDebug = this.trace != null;
- }
-
- /**
- * Clear all object reference information so that the instance
- * can be used to deserialize another data structure.
- *
- * Reset should be called before reading a top level object,
- * such as a new header or a new body.
- */
- public void reset()
- {
- nestObjectLevel = 0;
- nestCollectionLevel = 0;
- TypeMarshallingContext marshallingContext = TypeMarshallingContext.getTypeMarshallingContext();
- marshallingContext.reset();
- }
-
- /**
- * Returns an existing array with a length of at least the specified
- * capacity. This method is for optimization only. Do not use the array
- * outside the context of this method and do not call this method again
- * while the array is being used.
- * @param capacity minimum length
- * @return a character array
- */
- final char[] getTempCharArray(int capacity)
- {
- char[] result = this.tempCharArray;
- if ((result == null) || (result.length < capacity))
- {
- result = new char[capacity * 2];
- tempCharArray = result;
- }
- return result;
- }
-
- /**
- * Returns an existing array with a length of at least the specified
- * capacity. This method is for optimization only. Do not use the array
- * outside the context of this method and do not call this method again
- * while the array is being used.
- * @param capacity minimum length
- * @return a byte array
- */
- final byte[] getTempByteArray(int capacity)
- {
- byte[] result = this.tempByteArray;
- if ((result == null) || (result.length < capacity))
- {
- result = new byte[capacity * 2];
- tempByteArray = result;
- }
- return result;
- }
-
- protected void increaseNestObjectLevel()
- {
- nestObjectLevel++;
-
- if (nestObjectLevel > context.maxObjectNestLevel)
- {
- SerializationException se = new SerializationException();
- se.setMessage(10315, new Object[] {context.maxObjectNestLevel});
- throw se;
- }
- }
-
- protected void decreaseNestObjectLevel()
- {
- nestObjectLevel--;
- }
-
- protected void increaseNestCollectionLevel()
- {
- nestCollectionLevel++;
- if (nestCollectionLevel > context.maxCollectionNestLevel)
- {
- SerializationException se = new SerializationException();
- se.setMessage(10316, new Object[] {context.maxCollectionNestLevel});
- throw se;
- }
- }
-
- protected void decreaseNestCollectionLevel()
- {
- nestCollectionLevel--;
- }
-
- public static boolean isCollectionClass(Object object)
- {
- if (object == null)
- return false;
- Class clazz = object.getClass();
- if (clazz.isArray())
- return true;
- if (java.util.Collection.class.isAssignableFrom(clazz))
- return true;
- if (java.util.Map.class.isAssignableFrom(clazz))
- return true;
- if (flex.messaging.io.ArrayCollection.class.equals(clazz))
- return true;
- return flex.messaging.io.ArrayList.class.equals(clazz);
- }
-}