Ejemplo n.º 1
0
        /// <summary>
        /// Generates a collection item as bytes-array, and returns it.
        /// </summary>
        protected byte[] GenerateCollectionItemBlock(object SourceObject)
        {
            byte[] Result = null;

            int TypeId   = -1;
            var DataType = (SourceObject == null ? typeof(object) : SourceObject.GetType());

            byte[] Data = null;

            Data = GenerateNonObjectDataBlock(DataType, SourceObject);
            if (Data == null)
            {
                var ObjectTypeIdAndInstanceId = GenerateObjectBlock(SourceObject);
                if (ObjectTypeIdAndInstanceId != null)
                {
                    TypeId = ObjectTypeIdAndInstanceId.Item1;
                    Data   = BitConverter.GetBytes(ObjectTypeIdAndInstanceId.Item2); // Only get the instance-id
                }
            }
            else
            {
                TypeId = DetectedTypes.IndexOfKey(DataType);
            }

            if (Data != null && TypeId < 0)
            {
                throw new InternalAnomaly("Type should be already registered: " + DataType.Name);
            }

            Result = BytesHandling.FusionateByteArrays(BLOCK_COL_ITM.IntoArray(),
                                                       (TypeId < 0 ? new byte[0] : BitConverter.GetBytes(TypeId)),
                                                       Data);
            return(Result);
        }
Ejemplo n.º 2
0
        // ---------------------------------------------------------------------------------------------------------------------------------------------------------
        protected FieldInfo[] RegisterType(Type InsType)
        {
            FieldInfo[] Fields = null;

            if (DetectedTypes.AddNew(InsType, null))
            {
                Fields = InsType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
                         .Where(fld => !fld.Attributes.HasFlag(FieldAttributes.NotSerialized) &&
                                fld.FieldType.BaseType != typeof(MulticastDelegate) &&
                                fld.FieldType.BaseType != typeof(Delegate)).ToArray();
                DetectedTypes[InsType] = Fields;

                var TypeDeclaration = InsType.Namespace + "." + InsType.Name + TYPEDEC_SEPARATOR +
                                      Fields.GetConcatenation(fld => fld.Name.CutBetween("<", ">k__BackingField", true)
                                                              + MEMBER_TYPIFICATION_CODE + fld.FieldType.Name,
                                                              MEMBERS_SEPARATOR);

                var Block = BytesHandling.FusionateByteArrays(BLOCK_TYP_DECL.IntoArray(), TypeDeclaration.StringToBytes().PreppendLength());

                this.TorrentWriter.Write(Block);
            }
            else
            {
                Fields = DetectedTypes[InsType];
            }

            return(Fields);
        }
Ejemplo n.º 3
0
        // ---------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Generates an object-block.
        /// Returns type-id and object-id to be used as reference data.
        /// </summary>
        protected Tuple <int, int> GenerateObjectBlock(object Instance)
        {
            if (Instance == null)
            {
                return(null);
            }

            var InsType = Instance.GetType();

            // If already traveled, just return id.
            var InstanceId = TravelTrace.IndexOf(Instance);

            if (InstanceId >= 0)
            {
                return(Tuple.Create(InsType == null ? -1 : DetectedTypes.IndexOfKey(InsType), InstanceId));
            }

            InstanceId = TravelTrace.Count + 1;
            TravelTrace.Add(Instance);

            var ContainedFields = RegisterType(InsType);
            var TypeId          = this.DetectedTypes.IndexOfKey(InsType);

            var BlocksToWrite = new List <byte[]>();

            if (typeof(IEnumerable).IsAssignableFrom(InsType))
            {
                var Items      = ((IEnumerable)Instance).Cast <object>();
                var ItemsCount = Items.Count(item =>
                {
                    if (item != null)
                    {
                        RegisterType(item.GetType());           // Detect new types
                    }
                    return(true);                               // include all, even empties
                });

                this.TorrentWriter.Write(BLOCK_OBJ_COL);
                //- BlocksToWrite.Add(BLOCK_OBJ_COL.IntoArray());

                this.TorrentWriter.Write(ItemsCount);
                //- BlocksToWrite.Add(BitConverter.GetBytes(ItemsCount));

                foreach (var Item in Items)
                {
                    var ItemBlock = GenerateCollectionItemBlock(Item);
                    this.TorrentWriter.Write(ItemBlock);
                    //- BlocksToWrite.Add(ItemBlock);
                }
            }
            else
            {
                this.TorrentWriter.Write(BLOCK_OBJ_INS);
                //- BlocksToWrite.Add(BLOCK_OBJ_INS.IntoArray());

                this.TorrentWriter.Write(BitConverter.GetBytes(TypeId));
                //- BlocksToWrite.Add(BitConverter.GetBytes(TypeId));

                foreach (var Field in ContainedFields)
                {
                    var Value            = Field.GetValue(Instance);
                    var DefaultTypeValue = InsType.GetDefaultValue();

                    if (Value == DefaultTypeValue)
                    {
                        continue;
                    }

                    var FieldBlock = GenerateObjectFieldBlock(InsType, Field, Value);
                    this.TorrentWriter.Write(FieldBlock);
                    //- BlocksToWrite.Add(FieldBlock);
                }
            }

            /*- // Now, after the object-graph tree has been traveled, proceed to write
             * foreach (var Block in BlocksToWrite)
             *  this.TorrentWriter.Write(Block); */

            return(Tuple.Create(DetectedTypes.IndexOfKey(Instance.GetType()), InstanceId));
        }