public void Update(byte[] buffer, int offset, int count) { CheckDebug.NotNull(buffer); var s1 = checksum & 0xFFFF; var s2 = (checksum >> 16) & 0xFFFF; var index = offset; while (count > 0) { var k = count < NMax ? count : NMax; count -= k; for (var i = 0; i < k; i++) { s1 += buffer[index++]; s2 += s1; } s1 = s1 % Modulo; s2 = s1 % Modulo; } checksum = (s2 << 16) | s1; }
void WriteVector <T>( Marker marker, bool isObjectVector, bool isFixedLength, IList items, Action <T> write) { CheckDebug.NotNull(items); WriteMarker(marker); if (ObjectReferenceAddOrWrite(items)) { return; } WriteInlineHeaderValue(items.Count); b.WriteBoolean(isFixedLength); UnmarkedWriteString(isObjectVector ? "*" : "", isString: true); foreach (var item in items) { write((T)item); } }
public static Socket FastSocket(Socket socket) { CheckDebug.NotNull(socket); socket.NoDelay = true; if (IsWindows) { unchecked { try { // defined in `mstcpip.h` const int SIO_LOOPBACK_FAST_PATH = (int)0x98000010; socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue: Yes, optionOutValue: null); } catch (Exception e) { Kon.DebugException(e); } } } return(socket); }
void WriteAsObject(AsObject value) { CheckDebug.NotNull(value); ReferenceAdd(value); if (string.IsNullOrEmpty(value.TypeName)) { WriteMarker(Marker.Object); } else { WriteMarker(Marker.TypedObject); b.WriteUtfPrefixed(value.TypeName); } foreach (var property in value) { b.WriteUtfPrefixed(property.Key); WriteItem(property.Value); } // object end is marked with a zero-length field name, and an end of object marker. b.WriteUInt16(0); WriteMarker(Marker.ObjectEnd); }
void WriteXElement(XElement value) { CheckDebug.NotNull(value); ReferenceAdd(value); UnmarkedWriteLongString( value.ToString(SaveOptions.DisableFormatting)); }
public static async Task <byte[]> ReadBytesAsync(this Stream stream, int count) { CheckDebug.NotNull(stream); var buffer = new byte[count]; await stream.ReadBytesAsync(buffer, 0, count); return(buffer); }
public static byte[] ReadBytes(this Stream stream, int count) { CheckDebug.NotNull(stream); var buffer = new byte[count]; stream.ReadBytes(buffer, 0, count); return(buffer); }
void UnmarkedWriteLongString(string value) { CheckDebug.NotNull(value); var utf8 = Encoding.UTF8.GetBytes(value); WriteMarker(Marker.LongString); b.WriteUInt32((uint)utf8.Length); b.WriteBytes(utf8); }
void WriteArray(IEnumerable enumerable, int length) { CheckDebug.NotNull(enumerable); ReferenceAdd(enumerable); b.WriteInt32(length); foreach (var element in enumerable) { WriteItem(element); } }
public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { CheckDebug.NotNull(buffer); if (!hasRead) { hasRead = true; VerifyZlibHeader(await stream.ReadBytesAsync(2)); } return(await base.ReadAsync(buffer, offset, count, cancellationToken)); }
public override void Write(byte[] buffer, int offset, int count) { CheckDebug.NotNull(buffer); if (!hasWritten) { hasWritten = true; stream.Write(ZlibHeader, 0, ZlibHeader.Length); } base.Write(buffer, offset, count); adler32.Update(buffer, offset, count); }
void WriteByteArray(ArraySegment <byte> value) { CheckDebug.NotNull(value); WriteMarker(Marker.ByteArray); if (ObjectReferenceAddOrWrite(value)) { return; } // inline-header-value: array length WriteInlineHeaderValue(value.Count); b.WriteBytes(value.Array, value.Offset, value.Count); }
void WriteXDocument(XDocument value) { CheckDebug.NotNull(value); WriteMarker(Marker.Xml); if (ObjectReferenceAddOrWrite(value)) { return; } UnmarkedWriteString( value.ToString(SaveOptions.DisableFormatting) ?? "", isString: false); }
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { CheckDebug.NotNull(buffer); if (!hasWritten) { hasWritten = true; await stream.WriteAsync(ZlibHeader, 0, ZlibHeader.Length, cancellationToken); } await base.WriteAsync(buffer, offset, count, cancellationToken); adler32.Update(buffer, offset, count); }
public override int Read(byte[] buffer, int offset, int count) { CheckDebug.NotNull(buffer); // the zlib format is specified by rfc 1950. Zlib also uses deflate, plus 2 or 6 header bytes, and a 4 byte checksum at the end. // the first 2 bytes indicate the compression method and flags. if the dictionary flag is set, then 4 additional bytes will follow. // preset dictionaries aren't very common and we don't support them. if (!hasRead) { hasRead = true; VerifyZlibHeader(stream.ReadBytes(2)); } return(base.Read(buffer, offset, count)); }
void WriteAssociativeArray(IDictionary <string, object> dictionary) { CheckDebug.NotNull(dictionary); ReferenceAdd(dictionary); WriteMarker(Marker.EcmaArray); b.WriteInt32(dictionary.Count); foreach (var(key, value) in dictionary) { b.WriteUtfPrefixed(key); WriteItem(value); } // object end is marked with a zero-length field name, and an end of object marker. b.WriteUInt16(0); WriteMarker(Marker.ObjectEnd); }
void WriteArray(IEnumerable enumerable, int length) { CheckDebug.NotNull(enumerable); WriteMarker(Marker.Array); if (ObjectReferenceAddOrWrite(enumerable)) { return; } WriteInlineHeaderValue(length); // empty key signifies end of associative section UnmarkedWriteString("", isString: true); foreach (var element in enumerable) { WriteItem(element); } }
void WriteTypedObject(object value) { CheckDebug.NotNull(value); ReferenceAdd(value); var klass = context.GetClassInfo(value); WriteMarker(Marker.TypedObject); b.WriteUtfPrefixed(klass.Name); foreach (var member in klass.Members) { b.WriteUtfPrefixed(member.Name); WriteItem(member.GetValue(value)); } // object end is marked with a zero-length field name, and an end of object marker. b.WriteUInt16(0); WriteMarker(Marker.ObjectEnd); }
void UnmarkedWriteString(string value, bool isString) { CheckDebug.NotNull(value); if (value == "") { // spec: empty strings are never sent by reference WriteInlineHeaderValue(0); return; } if (isString ? ReferenceListAddOrWriteInternal(refStrings, value) : ReferenceListAddOrWriteInternal(refObjects, value)) { return; } var bytes = Encoding.UTF8.GetBytes(value); WriteInlineHeaderValue(bytes.Length); b.WriteBytes(bytes); }
void WriteDictionary(IDictionary value) { CheckDebug.NotNull(value); WriteMarker(Marker.Dictionary); if (ObjectReferenceAddOrWrite(value)) { return; } WriteInlineHeaderValue(value.Count); // true: weakly referenced entries // false: strongly referenced entries b.WriteBoolean(false); foreach (DictionaryEntry entry in value) { WriteItem(entry.Key); WriteItem(entry.Value); } }
void WriteAssociativeArray(IDictionary <string, object> dictionary) { CheckDebug.NotNull(dictionary); WriteMarker(Marker.Array); if (ObjectReferenceAddOrWrite(dictionary)) { return; } // inline-header-value: number of dense items - zero for an associative array WriteInlineHeaderValue(0); foreach (var(key, value) in dictionary) { UnmarkedWriteString(key, isString: true); WriteItem(value); } // empty key signifies end of associative section UnmarkedWriteString("", isString: true); }
// writes a string, either as a short or long strong depending on length. void WriteVariantString(string value) { CheckDebug.NotNull(value); var utf8 = Encoding.UTF8.GetBytes(value); var length = utf8.Length; if (length < ushort.MaxValue) { // unsigned 16-bit length WriteMarker(Marker.String); b.WriteUInt16((ushort)utf8.Length); b.WriteBytes(utf8); } else { // unsigned 32-bit length WriteMarker(Marker.LongString); b.WriteUInt32((uint)utf8.Length); b.WriteBytes(utf8); } }
public static async Task ReadBytesAsync(this Stream stream, byte[] buffer, int index, int count) { CheckDebug.NotNull(stream, buffer); var read = 0; while (count > 0) { var n = await stream.ReadAsync(buffer, read, count); if (n == 0) { break; } read += n; count -= n; } if (count != 0) { throw new EndOfStreamException(); } }
void WriteObject(object obj) { CheckDebug.NotNull(obj); WriteMarker(Marker.Object); if (ObjectReferenceAddOrWrite(obj)) { return; } var info = context.GetClassInfo(obj); if (refClasses.Add(info, out var index)) { // http://download.macromedia.com/pub/labs/amf/amf3_spec_121207.pdf // """ // The first (low) bit is a flag with value 1. The second bit is a flag // (representing whether a trait reference follows) with value 0 to imply that // this objects traits are being sent by reference. The remaining 1 to 27 // significant bits are used to encode a trait reference index (an integer). // -- AMF3 specification, 3.12 Object type // """ // <u27=trait-reference-index> <0=trait-reference> <1=object-inline> WriteInlineHeaderValue(index << 1); } else { // write the class definition // we can use the same format to serialize normal and extern classes, for simplicity's sake. // normal: <u25=member-count> <u1=dynamic> <0=externalizable> <1=trait-inline> <1=object-inline> // externalizable: <u25=insignificant> <u1=insignificant> <1=externalizable> <1=trait-inline> <1=object-inline> var header = info.Members.Length; header = (header << 1) | (info.IsDynamic ? 1 : 0); header = (header << 1) | (info.IsExternalizable ? 1 : 0); header = (header << 1) | 1; // the final shift is done here. WriteInlineHeaderValue(header); // write the type name UnmarkedWriteString(info.Name, isString: true); // then, write the actual object value if (info.IsExternalizable) { if (!(obj is IExternalizable externalizable)) { throw new ArgumentException($"{obj.GetType().FullName} ({info.Name}) is marked as externalizable but does not implement IExternalizable"); } externalizable.WriteExternal(new DataOutput(writer)); } else { foreach (var member in info.Members) { UnmarkedWriteString(member.Name, isString: true); } foreach (var member in info.Members) { WriteItem(member.GetValue(obj)); } if (info.IsDynamic) { if (!(obj is IDictionary <string, object> dictionary)) { throw new ArgumentException($"{obj.GetType()} is marked as dynamic but does not implement IDictionary"); } foreach (var(key, value) in dictionary) { UnmarkedWriteString(key, isString: true); WriteItem(value); } UnmarkedWriteString(string.Empty, isString: true); } } } }
public static void Write(this Stream stream, byte[] buffer) => stream.Write(CheckDebug.NotNull(buffer), 0, buffer.Length);
public static Task WriteAsync(this Stream stream, byte[] buffer) => stream.WriteAsync(CheckDebug.NotNull(buffer), 0, buffer.Length);
public static Task WriteAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken) => stream.WriteAsync(CheckDebug.NotNull(buffer), 0, buffer.Length, cancellationToken);
public void Update(byte[] buffer) { CheckDebug.NotNull(buffer); Update(buffer, 0, buffer.Length); }