/// <summary> /// deconstructs objects that inhert ISerializable /// </summary> /// <returns></returns> private static BinaryBuilder SeriObjDeconstructor(ISerializable obj) { SerializationInfo info = new SerializationInfo(obj.GetType(), new FormatterConverter()); StreamingContext context = new StreamingContext(StreamingContextStates.All); obj.GetObjectData(info, context); var node = info.GetEnumerator(); BinaryBuilder byteBuilder = new BinaryBuilder(); byteBuilder.Append(serializerEntry); ///Object Type Change byteBuilder.Append(info.ObjectType.AssemblyQualifiedName); byteBuilder.Append(equals); ///Object Type Change while (node.MoveNext()) { //bytebuilder adds to itself the new byte arrays, no need to assign byteBuilder.Append(startClass + node.Name + typeEntry + node.ObjectType.ToString() + equals + Deconstruction(node.Value) + endClass); //stringBuilder.Append(startClass + node.Name + typeEntry + node.ObjectType + equals + Deconstruct(node.Value) + endClass); } byteBuilder.Append(serializerExit); return(byteBuilder); }
private static BinaryBuilder ListObjDeconstructor(IList list) { BinaryBuilder objGraph = new BinaryBuilder(); //TODO: ADD A WAY TO COUNT MEMEBERS AND AVOID NULL sends //THIS IS A BIG NONO (spent too much on to find these issue) //IF ANOTHER UNSOLVALBE ISSUE RAISES LISTS ARE YOUR FIRST WARNING if (list.GetType().IsArray) { //if (list is List<byte>) // return ((List<byte>)list).ToArray(); objGraph.Append(list.Count.ToString()); if (list is byte[]) { objGraph.Append(startEnum); objGraph.Append((byte[])list); objGraph.Append(endEnum); return(objGraph); } } objGraph.Append(startEnum); foreach (var member in list) { if (member == null) //Don't add to the list, { //objGraph.Append(nullObj + betweenEnum); //No sending nulls continue; } objGraph.Append(Deconstruction(member) + endClass); //between Enum is like endclass } objGraph.Append(endEnum); return(objGraph); }
/// <summary> /// This method will get the dataInfo and rescue the required section /// from the beginning of the dataInfo string until it encounters the given operation /// </summary> /// <param name="dataInfo">The operation</param> /// <param name="syntax">Object graph</param> /// <returns>The required section</returns> private static BinaryBuilder GetSection(ref byte[] dataInfo, byte[] syntax, ref int location) { BinaryBuilder sectionByte = new BinaryBuilder(); for (int i = location; i < dataInfo.Length; i++) { if (CheckHitOperator(dataInfo, syntax, ref location)) //when the program gets to "=" it continues { break; } sectionByte.Append(dataInfo[i]); location += 1; } location += syntax.Length; return(sectionByte); }
private static BinaryBuilder Deconstruction(object obj) { if (obj == null) { return(nullObj); } if (obj.GetType().IsPrimitive || obj is string) { return(BinaryBuilder.PrimitiveToByte(obj)); } if (!obj.GetType().IsSerializable) //PROTECTION { return(new byte[0]); //don't touch the field, CONSIDER: throwing an error } else if (obj is ISerializable) { return(SeriObjDeconstructor((ISerializable)obj)); } if (obj is IList) //string is also an enum but will never reach here thanks to the primitive check { return(ListObjDeconstructor((IList)obj)); } var fields = obj.GetType().GetFields(bindingFlags); BinaryBuilder objGraph = new BinaryBuilder(); #region SpecialCases /*Special cases so far: * 1. Object is null (Done) * 2. Object points to itself in an infnite loop (Done) * 3. backingField (Done) * 4. Object is an enum/list/array (Done) */ #endregion foreach (var field in fields) { //the field is a field class, the fieldValue is the value of this field (the actual object) //for examle field is "int num = 5" and the field value is the 5 if (field.IsNotSerialized) //PROTECTION { continue; //Don't touch the object, was meant to not be serialized } object fieldValue = field.GetValue(obj); if (fieldValue == null) //No sending nulls { continue; //Null object, ignore. spares the text in the writing } if (fieldValue == obj) { throw new StackOverflowException("An object points to itself"); //Will cause an infinite loop, so just throw it } //BACKING FIELDS ARE IGNORED BECAUSE THE PROPERTIES LINE SAVES THEM INSTEAD //one of the few compiler generated attributes is backing fields //backing field is a proprty with a get and set only, which has a hidden field behind it //instead we save this field in the properties if (Attribute.GetCustomAttribute(field, typeof(CompilerGeneratedAttribute)) == null) //this line checks for backing field { objGraph.Append(startClass + field.Name + equals + Deconstruction(fieldValue) + endClass); } else { objGraph.Append(startClass + GetNameOfBackingField(field.Name) + equals + Deconstruction(fieldValue) + endClass); } } return(objGraph); }