/// <summary> /// Read a date. /// </summary> /// <remarks> /// Type declaration: /// <c>U29D-value = U29 (The first (low) bit is a flag with value 1. /// The remaining bits are not used). /// date-time = DOUBLE (A 64-bit integer value transported as a double). /// date-type = date-marker (U29O-ref | (U29D-value date-time))</c> /// </remarks> private static void ReadDate(AmfContext context, AmfStreamReader reader, XmlWriter output = null) { int index, reference; if (ReadReference(context, reader, out index, out reference)) { if (output != null) WriteReference(index, output); return; } context.References.Track(); //Dates are represented as an Unix time stamp, but in milliseconds var milliseconds = reader.ReadDouble(); var value = milliseconds.ToString(); if (output != null) { output.WriteStartElement(AmfxContent.Date); output.WriteValue(value); output.WriteEndElement(); } }
/// <summary> /// Read a value of a given type from current reader's position. /// </summary> /// <remarks> /// Current reader position must be just after a value type marker of a type to read. /// </remarks> /// <param name="context">AMF decoding context.</param> /// <param name="reader">AMF stream reader.</param> /// <param name="type">Type of the value to read.</param> /// <param name="output">AMFX output.</param> /// <exception cref="NotSupportedException">AMF type is not supported.</exception> /// <exception cref="FormatException">Unknown data format.</exception> /// <exception cref="SerializationException">Error during deserialization.</exception> private void ReadValue(AmfContext context, AmfStreamReader reader, Amf0TypeMarker type, XmlWriter output = null) { switch (type) { case Amf0TypeMarker.Null: case Amf0TypeMarker.Undefined: break; case Amf0TypeMarker.Boolean: reader.ReadBoolean(); break; case Amf0TypeMarker.Number: reader.ReadDouble(); break; case Amf0TypeMarker.String: ReadString(reader, output); break; case Amf0TypeMarker.LongString: ReadLongString(reader, output); break; case Amf0TypeMarker.Date: ReadDate(reader, output); break; case Amf0TypeMarker.XmlDocument: ReadXml(reader, output); break; case Amf0TypeMarker.Reference: ReadReference(context, reader, output); break; case Amf0TypeMarker.Object: ReadObject(context, reader, output); break; case Amf0TypeMarker.TypedObject: ReadObject(context, reader, output, true); break; case Amf0TypeMarker.EcmaArray: ReadEcmaArray(context, reader, output); break; case Amf0TypeMarker.StrictArray: ReadStrictArray(context, reader, output); break; case Amf0TypeMarker.MovieClip: case Amf0TypeMarker.RecordSet: case Amf0TypeMarker.Unsupported: throw new NotSupportedException(string.Format(Errors.Amf0Deserializer_ReadValue_UnsupportedType, type)); default: throw new FormatException(string.Format(Errors.Amf0Decoder_ReadValue_UnknownType, (byte)type)); } if (output != null) output.Flush(); }
/// <summary> /// Read a double. /// </summary> private static void ReadDouble(AmfStreamReader reader, XmlWriter output = null) { var value = reader.ReadDouble(); if (output != null) { if (value <= MinInt29Value || value >= MaxInt29Value && Math.Abs(value - Math.Round(value)) < MinDoublePrecision) { var integer = Convert.ToInt32(value); output.WriteStartElement(AmfxContent.Integer); output.WriteValue(integer); } else { output.WriteStartElement(AmfxContent.Double); output.WriteValue(value); } output.WriteEndElement(); } }
/// <summary> /// Read a date. /// </summary> /// <remarks> /// Type declaration: /// <c>time-zone = S16 /// date-type = date-marker DOUBLE time-zone</c> /// </remarks> private static void ReadDate(AmfStreamReader reader, XmlWriter output = null) { //Dates are represented as an Unix time stamp, but in milliseconds var milliseconds = reader.ReadDouble(); //Value indicates a timezone, but it should not be used reader.ReadInt16(); if (output != null) { output.WriteStartElement(AmfxContent.Date); var result = milliseconds.ToString(); output.WriteValue(result); output.WriteEndElement(); } }