/// <summary> /// Serializes the supplied object Graph to the underlying stream. /// </summary> public void Serialize(object GraphRoot) { General.ContractRequiresNotNull(GraphRoot); if (GraphRoot.GetType().IsValueType) { throw new UsageAnomaly("Object to serialize must be a class instance."); } // Initialize detected types this.DetectedTypes.Clear(); this.DetectedTypes.Add(typeof(object), new FieldInfo[] {}); // For null references // Initialize writer this.TorrentWriter = new BinaryWriter(this.Torrent, Encoding.Unicode); // Write Header this.TorrentWriter.Write(BytesHandling.FusionateByteArrays(SERIALIZATION_HEADER_CODE, FORMAT_VERSION, FORMAT_KIND_BINARY)); // Travel Graph and Write Content this.GenerateObjectBlock(GraphRoot); // Write Trailer this.TorrentWriter.Write(BytesHandling.FusionateByteArrays(SERIALIZATION_TRAILER_CODE)); }
// --------------------------------------------------------------------------------------------------------------------------------------------------------- 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); }
// --------------------------------------------------------------------------------------------------------------------------------------------------------- public byte[] GenerateNonObjectDataBlock(Type DataType, object SourceObject) { byte[] Data = null; if (DataType == typeof(byte[])) { Data = BytesHandling.FusionateByteArrays(true, (byte[])SourceObject); } else if (DataType == typeof(string)) { Data = BytesHandling.FusionateByteArrays(true, BytesHandling.StringToBytesUnicode((string)SourceObject)); } else if (DataType == typeof(decimal)) { var Parts = decimal.GetBits((decimal)SourceObject).Select(intval => BitConverter.GetBytes(intval)).ToArray(); Data = BytesHandling.FusionateByteArrays(true, Parts); } else if (DataType.IsValueType) { Data = BytesHandling.GetBytesFromFixedLengthTypeObject(SourceObject, true); } return(Data); }
/// <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); }
//------------------------------------------------------------------------------------------ /// <summary> /// Converts a License Document (XML) into a Key Code (Base64 compressed text) /// </summary> // IMPORTANT: This must be equivalent to that in the website public static string LicenseDocumentToKeyCode(string Document) { var DocBytes = Document.StringToBytes(); var DocCompressed = BytesHandling.Compress(DocBytes); var KeyCode = Convert.ToBase64String(DocCompressed).Intercalate(50, Environment.NewLine); return(KeyCode); }
/// <summary> /// Converts a Key Code (Base64 compressed text) into a License Document (XML) /// </summary> public static string LicenseKeyCodeToDocument(string KeyCode) { if (KeyCode.IsAbsent()) { return(""); } var KeyCodeCompressed = Convert.FromBase64String(KeyCode.RemoveNewLines("").Replace(" ", "")); if (KeyCodeCompressed.Length < 1) { throw new Exception("Compressed key-code is corrupt."); } var DocBytes = BytesHandling.Decompress(KeyCodeCompressed); var Document = DocBytes.BytesToString(); return(Document); }
// --------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Generates an object field as bytes-array, and returns it. /// </summary> protected byte[] GenerateObjectFieldBlock(Type ContainerObjectType, FieldInfo SourceField, object SourceObject) { byte[] Result = null; var DataType = SourceField.FieldType; var FieldId = BitConverter.GetBytes(Array.IndexOf <FieldInfo>(DetectedTypes[ContainerObjectType], SourceField)); byte[] Data = null; Data = GenerateNonObjectDataBlock(DataType, SourceObject); if (Data == null) { var ObjectTypeIdAndInstanceId = GenerateObjectBlock(SourceObject); if (ObjectTypeIdAndInstanceId != null) { Data = BitConverter.GetBytes(ObjectTypeIdAndInstanceId.Item2); // Only get the instance-id } } Result = BytesHandling.FusionateByteArrays(BLOCK_FLD_VAL.IntoArray(), FieldId, Data); return(Result); }
// ------------------------------------------------------------------------------------------- /// <summary> /// Returns this Source object in its Base-64 representation, optionally inserting line-breaks every 76 chars. /// </summary> public static string ToBase64(object Source, bool InsertLineBreaks = false) { var Bytes = Source as byte[]; if (Bytes == null) { var Text = Source as string; if (Text != null) { Bytes = Text.StringToBytesUnicode(); } else { var Image = Source as System.Windows.Media.ImageSource; if (Image != null) { Bytes = Instrumind.Common.Visualization.Display.ToBytes(Image); } else { Bytes = BytesHandling.SerializeToBytes(Source); } } } if (Bytes == null) { return(null); } var Result = Convert.ToBase64String(Bytes, (InsertLineBreaks ? Base64FormattingOptions.InsertLineBreaks : Base64FormattingOptions.None)); return(Result); }
// ------------------------------------------------------------------------------------------- /// <summary> /// Gives, in a target byte array, another one readed from a stream, until consume a number of bytes or before some marks conformed by only one byte. /// Return the index of the found mark or -1 if the consumable bytes limit was reached. /// </summary> private static int CaptureSegmentWithSimpleStreamReader(ref byte[] TargetSegment, BinaryReader TorrentReader, int BytesNumberLimit, params byte[][] LimitMarks) { int CaptureEndingCause = -1; int MarksCount = LimitMarks.GetLength(0); int Ind = 0; int Pos = 0; int ConsumedBytesCount = 0; bool FoundedMark = false; byte Atom = 0; SimpleList <byte[]> Parts = new SimpleList <byte[]>(); byte[] Part = new byte[0]; int PartBytesCount = 0; Parts.Add(Part); try { while (ConsumedBytesCount < BytesNumberLimit) { Atom = TorrentReader.ReadByte(); ConsumedBytesCount++; FoundedMark = false; for (Ind = 0; Ind < MarksCount; Ind++) { if (Atom == LimitMarks[Ind][0]) { FoundedMark = true; CaptureEndingCause = Ind; break; } } if (FoundedMark) { break; } if (PartBytesCount == BLOCK_SIZE_TINY) { Part = new byte[BLOCK_SIZE_TINY]; PartBytesCount = 0; Parts.Add(Part); } Part[PartBytesCount] = Atom; PartBytesCount++; } throw new UsageAnomaly("Stream has been readed/consumed until reach the " + BytesNumberLimit.ToString() + " bytes limit.", new DataWagon("ConsumedBytesCount", ConsumedBytesCount)); } #pragma warning disable 168 catch (EndOfStreamException Anomaly) { // The possible end of the stream is expected. }; #pragma warning restore 168 TargetSegment = new byte[(BLOCK_SIZE_TINY * (Parts.Count - 1)) + PartBytesCount]; Ind = 0; Pos = 0; foreach (byte[] Fragment in Parts) { Ind++; CopyByteArray(TargetSegment, (Ind < Parts.Count ? Fragment : BytesHandling.ExtractSegment(Fragment, 0, PartBytesCount)), Pos, (byte)0, false); Pos += BLOCK_SIZE_TINY; } return(CaptureEndingCause); }