public void TestBuilderAdd() { var builder1 = new BinaryCodeBuilder( new byte[] { 100, 255 } ); var builder2 = new BinaryCodeBuilder(); var bytes = new byte[] { 100, 255, 201 }; builder1.AppendBit(1); builder1.AppendBit(0); builder1.AppendBit(0); builder1.AppendBit(1); builder1.AppendBit(0); builder2.Append(builder1); builder2.AppendBit(0); builder2.AppendBit(1); builder2.AppendBit(1); var storedBytes2 = builder2.ToBytes(); for (int i = 0; i < bytes.Length; i++) { Assert.AreEqual(bytes[i], storedBytes2[i]); } }
protected BinaryCodeBuilder EncodeLength(uint length) { byte lengthSizeInBytes = GetNumberOfBytesToStoreLength(length); BinaryCodeBuilder builder = new BinaryCodeBuilder(); builder.AppendBit((byte)(lengthSizeInBytes % 2)); builder.AppendBit((byte)((lengthSizeInBytes / 2) % 2)); // Minimum length is 1 byte so we start counting that value with 0, meaning 0 represents 1, 1 represents 2 etc. byte[] lengthBytes = BitConverter.GetBytes(length); for (int i = 0; i <= lengthSizeInBytes; i++) { builder.AppendByte(lengthBytes[i]); } return(builder); }
public void TestBitsAdd() { var builder1 = new BinaryCodeBuilder(); var builder2 = new BinaryCodeBuilder(); var bytes = new byte[] { 100, 255, 24 }; var bits = new byte[] { 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 }; for (int i = 0; i < bits.Length; i++) { builder1.AppendBit(bits[i]); } builder2.AppendBits(bits); var storedBytes1 = builder1.ToBytes(); var storedBytes2 = builder2.ToBytes(); for (int i = 0; i < bytes.Length; i++) { Assert.AreEqual(bytes[i], storedBytes1[i]); Assert.AreEqual(bytes[i], storedBytes2[i]); } }
protected virtual IEnumerable <byte> ComplexTypeEncoder(object o) { bool firstLevelEncoding = false; if (_encodedComplexObjects == null) { firstLevelEncoding = true; _encodedComplexObjects = new List <object>(); } if (_encodedComplexObjects.Contains(o)) { // Infinite encoding loop detected throw new InfiniteEncodingLoopException(o, "Infinite encoding loop detected"); } _encodedComplexObjects.Add(o); // Remember we already encoded this one object in particular List <byte> result = new List <byte>(); Type t = o.GetType(); // Original type accessable fields (all fields apart from private fields in base types as these are not inherited) var hierarchyFieldInfos = new List <FieldInfo[]>(); hierarchyFieldInfos.Add(t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)); Type inherited = t.BaseType; // Base types non-public fields (later restricted to private fields only) while (inherited != null && inherited != typeof(object)) { hierarchyFieldInfos.Add(inherited.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)); inherited = inherited.BaseType; } int hierarchyDescentCounter = 0; // How many times to go up the class parent hierarchy to get access to currently encoded private fields bool originalType = true; // whether we are currently encoding fields accessable from the object type, not parent types object currentlyEncodedObject; BinaryCodeBuilder encodedAsBuilder; BinaryCodeBuilder builder = new BinaryCodeBuilder(); foreach (var fieldArr in hierarchyFieldInfos) { foreach (var field in fieldArr) { if (field.IsPrivate || originalType) { if (hierarchyDescentCounter > 0) { for (int i = 0; i < hierarchyDescentCounter; i++) { builder.AppendBit(1); } hierarchyDescentCounter = 0; } builder.AppendBit(0); // 0 indicates end of going up the class hierarchy byte[] bytes = EncodeFieldName(field.Name); builder.Append(EncodeLength((uint)bytes.Length)); builder.AppendBytes(bytes); currentlyEncodedObject = field.GetValue(o); encodedAsBuilder = Encode(currentlyEncodedObject); builder.Append(encodedAsBuilder); } } hierarchyDescentCounter++; originalType = false; } if (firstLevelEncoding) { _encodedComplexObjects.Clear(); _encodedComplexObjects = null; } return(builder); }