/// <summary> /// Sets a mapped property or field value using reflection. /// </summary> /// <param name="serializer"></param> /// <param name="instance"></param> /// <param name="propertyOrField"></param> /// <param name="value"></param> private static void SetMappedPropertyOrField(IActionScriptSerializer serializer, object instance, MemberInfo propertyOrField, IASValue value) { try { // Try to set the property. PropertyInfo property = propertyOrField as PropertyInfo; if (property != null) { object propertyValue = serializer.ToNative(value, property.PropertyType); property.SetValue(instance, propertyValue, null); return; } // Oh, it must be a field then. FieldInfo field = (FieldInfo)propertyOrField; object fieldValue = serializer.ToNative(value, field.FieldType); field.SetValue(instance, fieldValue); } catch (Exception ex) { throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture, "Error while setting value of property or field named '{0}' on class '{1}'", propertyOrField.Name, propertyOrField.ReflectedType.FullName), ex); } }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { IDictionary <TKey, TValue> dict = CreateDictionaryInstance(@class.MemberNames.Count); // Add members. int memberIndex = 0; foreach (IASValue memberValue in memberValues) { TKey key = (TKey)Convert.ChangeType(@class.MemberNames[memberIndex], typeof(TKey)); TValue value = (TValue)serializer.ToNative(memberValue, typeof(TValue)); dict.Add(key, value); memberIndex += 1; } // Add dynamic properties. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { TKey key = (TKey)Convert.ChangeType(pair.Key, typeof(TKey)); TValue value = (TValue)serializer.ToNative(pair.Value, typeof(TValue)); dict.Add(key, value); } return(dict); }
private IEnumerable <IASValue> GetMappedMemberValues(IActionScriptSerializer serializer, object instance) { foreach (ActionScriptPropertyMapping mapping in memberPropertyMappings) { yield return(GetMappedPropertyOrField(serializer, instance, mapping.NativePropertyOrField)); } }
/// <summary> /// Sets a mapped property or field value or a dynamic property depending on the mapping. /// </summary> /// <param name="serializer"></param> /// <param name="instance"></param> /// <param name="dynamic"></param> /// <param name="propertyName"></param> /// <param name="value"></param> private void SetMappedMemberOrDynamicProperty(IActionScriptSerializer serializer, object instance, IDynamic dynamic, string propertyName, IASValue value) { // Set the mapped property, if there is one. ActionScriptPropertyMapping propertyMapping; if (propertyMappings.TryGetValue(propertyName, out propertyMapping)) { SetMappedPropertyOrField(serializer, instance, propertyMapping.NativePropertyOrField, value); // If the property is dynamic then also set it as a dynamic property if possible. if (dynamic != null && propertyMapping.IsDynamic) { SetDynamicProperty(dynamic, serializer, propertyName, value); } } else if (dynamic != null) { SetDynamicProperty(dynamic, serializer, propertyName, value); } else { throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture, "Unable to set value for property '{0}' during ActionScript object deserialization because no suitable mapping is defined and type '{1}' is not dynamic.", propertyName, classMapping.NativeType.FullName)); } }
private static IEnumerable <IASValue> GetIndexedValues(IActionScriptSerializer serializer, ICollection <T> collection) { foreach (T element in collection) { yield return(serializer.ToASValue(element)); } }
private static IEnumerable <IASValue> GetIndexedValues(IActionScriptSerializer serializer, T[] array) { foreach (T element in array) { yield return(serializer.ToASValue(element)); } }
void IASValueVisitor.VisitByteArray(IActionScriptSerializer serializer, int length, IEnumerable <ArraySegment <byte> > segments) { if (length > MaxArrayLength) { throw new AMFException(ExceptionPrefix + "Cannot serialize a byte array longer than " + MaxArrayLength + " bytes."); } AddCurrentValueToCache(AMF3ObjectTypeCode.ByteArray); output.WriteByte((byte)AMF3ObjectTypeCode.ByteArray); output.WriteVWInt29(length * 2 + 1); if (length != 0) { int bytesRemaining = length; foreach (ArraySegment <byte> bytes in segments) { if (bytesRemaining < bytes.Count) { throw new AMFException(ExceptionPrefix + "The byte array provided more bytes than were indicated by its length."); } bytesRemaining -= bytes.Count; output.WriteBytes(bytes.Array, bytes.Offset, bytes.Count); } if (bytesRemaining != 0) { throw new AMFException(ExceptionPrefix + "The byte array did not provide as many bytes as were indicated by its length."); } } }
protected override object MapByteArrayToNative(IActionScriptSerializer serializer, Type nativeType, int length, IEnumerable <ArraySegment <byte> > segments) { ICollection <T> collection = CreateCollectionInstance(length); if (typeof(T) == typeof(byte)) { ICollection <byte> byteCollection = (ICollection <byte>)collection; foreach (ArraySegment <byte> segment in segments) { for (int i = 0; i < segment.Count; i++) { byteCollection.Add(segment.Array[i + segment.Offset]); } } } else { foreach (ArraySegment <byte> segment in segments) { for (int i = 0; i < segment.Count; i++) { IASValue byteValue = new ASInt29(segment.Array[i + segment.Offset]); T value = (T)serializer.ToNative(byteValue, typeof(T)); collection.Add(value); } } } return(collection); }
/// <summary> /// Maps a <see cref="ASTypeKind.Object" /> value. /// </summary> /// <remarks> /// The default implementation throws an <see cref="ActionScriptException" />. /// </remarks> /// <param name="serializer">The serializer to use</param> /// <param name="nativeType">The native type to produce</param> /// <param name="class">The class of the object</param> /// <param name="memberValues">The member values of the object in member index order</param> /// <param name="dynamicProperties">The dynamic properties of the object in no particular order</param> /// <param name="externalizableValue">The externalizable value, or null if none</param> protected virtual object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { throw ToNativeNotSupported(ASTypeKind.Object, nativeType); }
/// <summary> /// Converts the ActionScript value to a native value of the specified type. /// </summary> /// <remarks> /// The default implementation visits the <paramref name="asValue"/> and forwards the /// data to one of the specialized MapToXXX methods accordingly. /// </remarks> /// <param name="serializer">The serializer to use</param> /// <param name="asValue">The ActionScript value to convert</param> /// <param name="nativeType">The native type to produce</param> /// <returns>The native value</returns> /// <exception cref="ActionScriptException">Thrown if the mapping is not supported</exception> public virtual object ToNative(IActionScriptSerializer serializer, IASValue asValue, Type nativeType) { Visitor visitor = new Visitor(this, nativeType); asValue.AcceptVisitor(serializer, visitor); return(visitor.Result); }
protected override object MapArrayToNative(IActionScriptSerializer serializer, Type nativeType, int indexedLength, IEnumerable <IASValue> indexedValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties) { IDictionary <TKey, TValue> dict = CreateDictionaryInstance(indexedLength); // Add indexed values. int index = 0; foreach (IASValue indexedValue in indexedValues) { TKey key = (TKey)Convert.ChangeType(index, typeof(TKey)); TValue value = (TValue)serializer.ToNative(indexedValue, typeof(TValue)); dict.Add(key, value); index += 1; } // Add dynamic properties. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { TKey key = (TKey)Convert.ChangeType(pair.Key, typeof(TKey)); TValue value = (TValue)serializer.ToNative(pair.Value, typeof(TValue)); dict.Add(key, value); } return(dict); }
void IASNativeArrayMapper.AcceptVisitor(IActionScriptSerializer serializer, object nativeArray, IASValueVisitor visitor) { // We can assume this isn't a byte array since we checked that earlier. T[] array = (T[])nativeArray; visitor.VisitArray(serializer, array.Length, GetIndexedValues(serializer, array), EmptyDictionary <string, IASValue> .Instance); }
/// <summary> /// Creates an AMF data output writer. /// Initially uses the <see cref="AMFObjectEncoding.AMF0" /> object encoding. /// </summary> /// <param name="stream">The output stream</param> /// <param name="serializer">The ActionScript serializer to use for object serialization</param> public AMFDataOutput(Stream stream, IActionScriptSerializer serializer) { this.stream = stream; this.serializer = serializer; objectEncoding = AMFObjectEncoding.AMF0; utf8Encoding = new UTF8Encoding(false, false); }
public override void SetUp() { base.SetUp(); stream = new MemoryStream(); serializer = Mocks.CreateMock <IActionScriptSerializer>(); input = new AMFDataInput(stream, serializer); }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { ThrowIfNotInitialized(); visitor.VisitObject(serializer, @class, EmptyArray <IASValue> .Instance, EmptyDictionary <string, IASValue> .Instance, externalizableValue); }
void IASValueVisitor.VisitDate(IActionScriptSerializer serializer, double millisecondsSinceEpoch, int timeZoneOffsetMinutes) { AddCurrentValueToCache(AMF3ObjectTypeCode.Date); output.WriteByte((byte)AMF3ObjectTypeCode.Date); output.WriteVWInt29(1); output.WriteDouble(millisecondsSinceEpoch - timeZoneOffsetMinutes * 60000); }
/// <summary> /// Creates an AMF data input reader. /// Initially uses the <see cref="AMFObjectEncoding.AMF0" /> object encoding, /// switches modes automatically if <see cref="AMFObjectEncoding.AMF3" /> data is encountered. /// </summary> /// <param name="stream">The input stream</param> /// <param name="serializer">The ActionScript serializer to use for object serialization</param> public AMFDataInput(Stream stream, IActionScriptSerializer serializer) { this.stream = stream; this.serializer = serializer; objectReader = new AMF0ObjectReader(this); utf8Encoding = new UTF8Encoding(false, false); }
public override void SetUp() { base.SetUp(); stream = new MemoryStream(); serializer = Mocks.CreateMock<IActionScriptSerializer>(); input = new AMFDataInput(stream, serializer); }
protected override object MapStringToNative(IActionScriptSerializer serializer, Type nativeType, string value) { if (value.Length != 1) { throw new ActionScriptException("Cannot map a string with length not equal to 1 to a Char."); } return(value[0]); }
public override void SetUp() { base.SetUp(); ActionScriptMappingTable mappingTable = new ActionScriptMappingTable(); mappingTable.RegisterBuiltInMapperFactories(); serializer = new MappedActionScriptSerializer(mappingTable); }
protected override object MapNumberToNative(IActionScriptSerializer serializer, Type nativeType, double value) { if (Enum.GetUnderlyingType(nativeType) == typeof(UInt64)) { return(Enum.ToObject(nativeType, unchecked ((ulong)value))); // use unsigned long to ensure we don't drop the most significant bit } else { return(Enum.ToObject(nativeType, unchecked ((long)value))); } }
public override IASValue ToASValue(IActionScriptSerializer serializer, object nativeValue) { Int32 value = (Int32)nativeValue; if (value >= ASConstants.Int29MinValue && value <= ASConstants.Int29MaxValue) { return(new ASInt29(value)); } return(new ASNumber(value)); }
public override IASValue ToASValue(IActionScriptSerializer serializer, object nativeValue) { UInt32 value = (UInt32)nativeValue; if (value <= ASConstants.Int29MaxValue) { return(new ASInt29(unchecked ((int)value))); } return(new ASNumber(value)); }
public override IASValue ToASValue(IActionScriptSerializer serializer, object nativeValue) { UInt64 value = (UInt64)nativeValue; if (value <= ASConstants.Int29MaxValue) { return(new ASInt29(unchecked ((int)value))); } return(new ASNumber(value)); // note: loss of precision may occur }
public override IASValue ToASValue(IActionScriptSerializer serializer, object nativeValue) { // Handle byte arrays specially. byte[] bytes = nativeValue as byte[]; if (bytes != null) { return(new ASByteArray(bytes)); } // Handle other types. return(new ASNativeArray(nativeValue, this, false)); }
void IASValueVisitor.VisitString(IActionScriptSerializer serializer, string value) { if (output.IsShortString(value)) { output.WriteByte((byte)AMF0ObjectTypeCode.ShortString); output.WriteShortString(value); } else { output.WriteByte((byte)AMF0ObjectTypeCode.LongString); output.WriteLongString(value); } }
/// <inheritdoc /> public IService GetServiceForMessage(IActionScriptSerializer serializer, IMessage message) { if (serializer == null) { throw new ArgumentNullException("serializer"); } if (message == null) { throw new ArgumentNullException("message"); } return(UncheckedGetServiceForMessage(serializer, message)); }
public override IASValue ToASValue(IActionScriptSerializer serializer, object nativeValue) { // Externalizable classes require less work and we already have a good special // case ASValue implementation to support the AMF deserializer so let's use it. ASClass @class = classMapping.ASClass; if (@class.Layout == ASClassLayout.Externalizable) { return(new ASExternalizableObject(@class, (IExternalizable)nativeValue)); } // Generate the full mapping on demand. return(new ASNativeObject(@class, nativeValue, this)); }
private static void SetDynamicProperty(IDynamic dynamic, IActionScriptSerializer serializer, string propertyName, IASValue value) { try { dynamic.SetDynamicProperty(serializer, propertyName, value); } catch (Exception ex) { throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture, "Error while setting value of dynamic property '{0}' on class '{1}'", propertyName, dynamic.GetType().FullName), ex); } }
private object FromAMF(byte[] bytes) { IActionScriptSerializer serializer = serializerFactory.CreateSerializer(); MemoryStream stream = new MemoryStream(bytes); AMFDataInput dataInput = new AMFDataInput(stream, serializer); dataInput.BeginObjectStream(); IASValue asValue = dataInput.ReadObject(); dataInput.EndObjectStream(); object nativeValue = serializer.ToNative(asValue, null); return(nativeValue); }
private byte[] ToAMF(object nativeValue) { IActionScriptSerializer serializer = serializerFactory.CreateSerializer(); IASValue asValue = serializer.ToASValue(nativeValue); MemoryStream stream = new MemoryStream(); AMFDataOutput dataOutput = new AMFDataOutput(stream, serializer); dataOutput.ObjectEncoding = AMFObjectEncoding.AMF3; dataOutput.BeginObjectStream(); dataOutput.WriteObject(asValue); dataOutput.EndObjectStream(); return(stream.ToArray()); }
void IASValueVisitor.VisitBoolean(IActionScriptSerializer serializer, bool value) { output.WriteByte((byte)AMF0ObjectTypeCode.Boolean); output.WriteBoolean(value); }
private IService UncheckedGetServiceForMessage(IActionScriptSerializer serializer, IMessage message) { IService service; CommandMessage commandMessage = message as CommandMessage; if (commandMessage != null && ! String.IsNullOrEmpty(commandMessage.MessageRefType)) { service = UncheckedGetServiceForMessageClassAlias(commandMessage.MessageRefType); if (service != null) return service; } string classAlias = serializer.GetClassAlias(message.GetType()); service = UncheckedGetServiceForMessageClassAlias(classAlias); return service; }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { visitor.VisitUndefined(serializer); }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { visitor.VisitInt29(serializer, value); }
void IASValueVisitor.VisitNumber(IActionScriptSerializer serializer, double value) { output.WriteByte((byte)AMF3ObjectTypeCode.Number); output.WriteDouble(value); }
void IASValueVisitor.VisitXml(IActionScriptSerializer serializer, string xmlString) { output.WriteByte((byte)AMF3ObjectTypeCode.Xml); WriteStringData(xmlString); }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { int objectReferenceId = AddCurrentValueToCache(AMF3ObjectTypeCode.Object); output.WriteByte((byte)AMF3ObjectTypeCode.Object); // Look for a suitable existing class definition in the cache. int classDefinitionId; if (classDefinitionCache.TryGetValue(@class, out classDefinitionId)) { // Use class definition reference. output.WriteVWInt29(classDefinitionId * 4 + 1); } else { // Include class definition inline and add it to the cache. classDefinitionCache.Add(@class, objectReferenceId); output.WriteVWInt29(@class.MemberNames.Count * 16 + (int)@class.Layout * 4 + 3); WriteStringData(@class.ClassAlias); foreach (string memberName in @class.MemberNames) { if (String.IsNullOrEmpty(memberName)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); WriteStringData(memberName); } } if (@class.Layout == ASClassLayout.Externalizable) { if (externalizableValue == null) throw new AMFException(ExceptionPrefix + "The class layout is Externalizable but the object does not provide an ExternalizableValue."); externalizableValue.WriteExternal(output); } else { // Write the members first as a sequence of values. int memberCount = @class.MemberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); if (@class.Layout == ASClassLayout.Dynamic) { // Write dynamic key/value pairs. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); WriteStringData(pair.Key); WriteObject(pair.Value); } // Terminate with empty string. WriteStringData(""); } } }
void IASValueVisitor.VisitArray(IActionScriptSerializer serializer, int indexedLength, IEnumerable<IASValue> indexedValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties) { AddCurrentValueToCache(AMF3ObjectTypeCode.Array); if (indexedLength > MaxArrayLength) throw new AMFException(ExceptionPrefix + "Cannot serialize an array longer than " + MaxArrayLength + " elements."); output.WriteByte((byte)AMF3ObjectTypeCode.Array); output.WriteVWInt29(indexedLength * 2 + 1); // Write dynamic properties as key/value pairs. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an array with a null or empty string key."); WriteStringData(pair.Key); WriteObject(pair.Value); } // Terminate with empty string. WriteStringData(""); // Write indexed values in sequence. int index = 0; foreach (IASValue element in indexedValues) { if (index == indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is greater than was indicated by its length."); WriteObject(element); index += 1; } if (index != indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is less than was indicated by its length."); }
void IASValueVisitor.VisitByteArray(IActionScriptSerializer serializer, int length, IEnumerable<ArraySegment<byte>> segments) { if (length > MaxArrayLength) throw new AMFException(ExceptionPrefix + "Cannot serialize a byte array longer than " + MaxArrayLength + " bytes."); AddCurrentValueToCache(AMF3ObjectTypeCode.ByteArray); output.WriteByte((byte)AMF3ObjectTypeCode.ByteArray); output.WriteVWInt29(length * 2 + 1); if (length != 0) { int bytesRemaining = length; foreach (ArraySegment<byte> bytes in segments) { if (bytesRemaining < bytes.Count) throw new AMFException(ExceptionPrefix + "The byte array provided more bytes than were indicated by its length."); bytesRemaining -= bytes.Count; output.WriteBytes(bytes.Array, bytes.Offset, bytes.Count); } if (bytesRemaining != 0) throw new AMFException(ExceptionPrefix + "The byte array did not provide as many bytes as were indicated by its length."); } }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { visitor.VisitXml(serializer, XmlString); }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { ThrowIfNotInitialized(); visitor.VisitObject(serializer, @class, EmptyArray<IASValue>.Instance, EmptyDictionary<string, IASValue>.Instance, externalizableValue); }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { AddCurrentValueToCache(); // Externalizable not supported. if (@class.Layout == ASClassLayout.Externalizable) throw new AMFException(ExceptionPrefix + "Externalizable class layout not supported by AMF0."); if (@class.ClassAlias.Length != 0) { // Write class alias for typed object. output.WriteByte((byte)AMF0ObjectTypeCode.TypedObject); output.WriteShortString(@class.ClassAlias); } else { // Write header for untyped object. output.WriteByte((byte)AMF0ObjectTypeCode.Object); } // Write members as key/value pairs. IList<string> memberNames = @class.MemberNames; int memberCount = memberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); string memberName = memberNames[memberIndex]; if (String.IsNullOrEmpty(memberName)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); output.WriteShortString(memberName); WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); // Write dynamic key/value pairs. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); output.WriteShortString(pair.Key); WriteObject(pair.Value); } // Terminate with empty string and end of object marker. output.WriteShortString(""); output.WriteByte((byte)AMF0ObjectTypeCode.EndOfObject); }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { ThrowIfNotInitialized(); visitor.VisitObject(serializer, @class, memberValues, dynamicProperties, null); }
void IASValueVisitor.VisitBoolean(IActionScriptSerializer serializer, bool value) { output.WriteByte(value ? (byte)AMF3ObjectTypeCode.True : (byte)AMF3ObjectTypeCode.False); }
/// <inheritdoc /> public IService GetServiceForMessage(IActionScriptSerializer serializer, IMessage message) { if (serializer == null) throw new ArgumentNullException("serializer"); if (message == null) throw new ArgumentNullException("message"); return UncheckedGetServiceForMessage(serializer, message); }
void IASValueVisitor.VisitUnsupported(IActionScriptSerializer serializer) { throw new AMFException(ExceptionPrefix + "Cannot write an Unsupported value to an AMF3 stream."); }
void IASValueVisitor.VisitUndefined(IActionScriptSerializer serializer) { output.WriteByte((byte)AMF3ObjectTypeCode.Undefined); }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { ThrowIfNotInitialized(); mapper.AcceptVisitor(serializer, nativeArray, visitor); }
void IASValueVisitor.VisitNull(IActionScriptSerializer serializer) { WriteNull(); }
void IASValueVisitor.VisitInt29(IActionScriptSerializer serializer, int value) { output.WriteByte((byte)AMF3ObjectTypeCode.Integer); output.WriteVWInt29(value); }
/// <summary> /// Invokes the method on the visitor that corresponds with the type of the value. /// </summary> /// <param name="serializer">The serializer to use</param> /// <param name="visitor">The visitor</param> public abstract void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor);
void IASValueVisitor.VisitByteArray(IActionScriptSerializer serializer, int length, IEnumerable<ArraySegment<byte>> segments) { // Serialize the value as a plain old array of numbers for AMF0. AddCurrentValueToCache(); output.WriteByte((byte)AMF0ObjectTypeCode.Array); output.WriteInt(length); if (length != 0) { int bytesRemaining = length; foreach (ArraySegment<byte> bytes in segments) { if (bytesRemaining < bytes.Count) throw new AMFException(ExceptionPrefix + "The byte array provided more bytes than were indicated by its length."); bytesRemaining -= bytes.Count; int offset = bytes.Offset; int count = bytes.Count; byte[] array = bytes.Array; while (count-- > 0) WriteNumber(array[offset++]); } if (bytesRemaining != 0) throw new AMFException(ExceptionPrefix + "The byte array did not provide as many bytes as were indicated by its length."); } }
/// <inheritdoc /> public override void AcceptVisitor(IActionScriptSerializer serializer, IASValueVisitor visitor) { ArraySegment<byte>[] segments = new ArraySegment<byte>[] { bytes }; visitor.VisitByteArray(serializer, bytes.Count, segments); }
void IASValueVisitor.VisitArray(IActionScriptSerializer serializer, int indexedLength, IEnumerable<IASValue> indexedValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties) { AddCurrentValueToCache(); IEnumerator<KeyValuePair<string, IASValue>> dynamicPropertyEnumerator = dynamicProperties.GetEnumerator(); if (dynamicPropertyEnumerator.MoveNext()) { // Generate a mixed array. All keys are stored as strings. output.WriteByte((byte)AMF0ObjectTypeCode.MixedArray); output.WriteInt(indexedLength); // Write dynamic properties as key/value pairs. do { KeyValuePair<string, IASValue> pair = dynamicPropertyEnumerator.Current; if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an array with a null or empty string key."); output.WriteShortString(pair.Key); WriteObject(pair.Value); } while (dynamicPropertyEnumerator.MoveNext()); // Write indexed values as key/value pairs. int index = 0; foreach (IASValue element in indexedValues) { if (index == indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is greater than was indicated by its length."); output.WriteShortString(index.ToString(CultureInfo.InvariantCulture)); WriteObject(element); index += 1; } if (index != indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is less than was indicated by its length."); // Terminate with empty string and end of object marker. output.WriteShortString(""); output.WriteByte((byte)AMF0ObjectTypeCode.EndOfObject); } else { // Generate an ordinary array. output.WriteByte((byte)AMF0ObjectTypeCode.Array); output.WriteInt(indexedLength); // Write indexed values as a sequence of objects. int index = 0; foreach (IASValue element in indexedValues) { if (index == indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is greater than was indicated by its length."); WriteObject(element); index += 1; } if (index != indexedLength) throw new AMFException(ExceptionPrefix + "The number of indexed values provided by the array is less than was indicated by its length."); } }
void IASValueVisitor.VisitString(IActionScriptSerializer serializer, string value) { output.WriteByte((byte)AMF3ObjectTypeCode.String); WriteStringData(value); }