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]);
            }
        }
        public virtual BinaryCodeBuilder Encode(object o, ConverterCategory converterCategory = ConverterCategory.ANY, BinaryCodeBuilder builder = null)
        {
            if (builder == null)
            {
                builder = new BinaryCodeBuilder();
            }

            BinaryEncoderData  encoderData   = GetSpecificEncoder(o, converterCategory);
            IEnumerable <byte> encodedObject = null;

            if (encoderData.ConverterType == ConverterType.NULL)
            {
                builder.AppendBit(0);
                builder.AppendBit(0);

                return(builder);
            }
            else if (encoderData.ConverterType == ConverterType.EXCLUSIVE)
            {
                encodedObject = encoderData.Encoder.Invoke(o);
                builder.AppendBit(0);
                builder.AppendBit(1);
                byte[] typeBytes = EncodeType(o.GetType());
                builder.Append(EncodeLength((uint)typeBytes.Length));
                builder.AppendBytes(typeBytes);
            }
            else
            {
                encodedObject = encoderData.Encoder.Invoke(o);
                builder.AppendBit(1);

                if (encoderData.ConverterType == ConverterType.INCLUSIVE_SERIALIZABLE)
                {
                    // Inclusive serializable, no need to encode type
                    builder.AppendBit(0);
                }
                else
                {
                    // Inclusive primitive, no need to encode type
                    builder.AppendBit(1);
                }
            }

            uint length = (uint)encodedObject.Count();

            builder.Append(EncodeLength(length));

            builder.AppendBytes(encodedObject);

            return(builder);
        }
        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);
        }
Esempio n. 4
0
        static void Main(string[] args)
        {
            var storer = new BinaryCodeBuilder();

            var a = new byte[] {
                0, 1, 1, 0, 0
            };
            var b = new byte[] {
                1, 1, 1, 0, 1
            };
            var c = new byte[] {
                0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1
            };

            storer.AppendBits(a);
            storer.AppendBits(b);
            storer.AppendBits(c);

            storer.Print();
        }
        public void TestBytesAdd()
        {
            var builder1 = new BinaryCodeBuilder();
            var builder2 = new BinaryCodeBuilder();

            var bytes = new byte[] { 100, 140, 255, 0, 24 };

            for (int i = 0; i < bytes.Length; i++)
            {
                builder1.AppendByte(bytes[i]);
            }
            builder2.AppendBytes(bytes);

            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);
        }