/// <summary> /// Serializes an object. The object could be anything. /// </summary> /// <param name="obj">The object to serialize</param> /// <param name="useSB">Whether this will write to a string builder (if true), or return a string (if false).</param> /// <param name="sb">The StringBuilder to write to - if <paramref name="useSB"/> is true.</param> /// <param name="determinedType">The primitive type which has been decided for it.</param> /// <param name="writeNextInstructionSymbol">Whether it will write \u0001 on the start - usually false if it is serializing the first object in a class.</param> /// <param name="dnWriteEndLevel">"Do Not Write End Level Symbol" - Marks whether to NOT write \u0005 (if true), commonly used for the last object of all.</param> /// <returns>If <paramref name="useSB"/> is false, this method will return the result as a string.</returns> public static string Serialize(dynamic obj, ABSaveType type, ABSaveSettings settings, out ABSavePrimitiveType determinedType, bool useSB = false, StringBuilder sb = null, bool writeNextInstructionSymbol = true, bool dnWriteEndLevel = false) { // This will be what to return if useSB is false. string ret; // For now, make it so we output "unknown". determinedType = ABSavePrimitiveType.Unknown; // Check if the object is null... or an IntPtr, write the null symbol - otherwise, we could get a StackOverflowException. if (obj == null || obj is IntPtr || obj is UIntPtr) { return(ABSaveWriter.WriteNullItem(useSB, sb)); } // Remember what type the object is - as well as the TypeCode. Type objType = obj.GetType(); var tCode = Type.GetTypeCode(obj.GetType()); // If the object is a string - write it as a string. if (tCode == TypeCode.String) { ret = ABSaveWriter.WriteString(obj, writeNextInstructionSymbol, useSB, sb); determinedType = ABSavePrimitiveType.String; } // If the object is a number - write it as a number. else if (IsNumericType(tCode)) { ret = ABSaveWriter.WriteNumerical(obj, tCode, true, useSB, sb); determinedType = ABSavePrimitiveType.Number; } // If the object is an array - serialize it as an array. else if (IsArray(objType)) { ret = SerializeArray(obj, objType, type, settings, useSB, sb, dnWriteEndLevel); determinedType = ABSavePrimitiveType.Array; } // If the object is a dictionary - serialize it as a dictionary. else if (IsDictionary(objType)) { ret = SerializeDictionary(obj, type, settings, useSB, sb, dnWriteEndLevel); determinedType = ABSavePrimitiveType.Dictionary; } // If the object is a boolean - serialize it as a boolean. else if (tCode == TypeCode.Boolean) { ret = SerializeBool(obj, writeNextInstructionSymbol, useSB, sb); determinedType = ABSavePrimitiveType.Boolean; } // If the object is a DateTime - serialize it as a DateTime. else if (tCode == TypeCode.DateTime) { ret = SerializeDateTime(obj, useSB, sb); determinedType = ABSavePrimitiveType.DateTime; } // If it's a type, just write it out using the ABSaveWriter (for some reason there is no TypeConverter built-in for a type!) else if (obj is Type) { ret = SerializeType(obj, useSB, sb); determinedType = ABSavePrimitiveType.Type; } // Otherwise, we'll attempt to find a built-in type converter (to a string) else { // Mark it as an object. determinedType = ABSavePrimitiveType.Object; // Attempt to get a converter for it. var canBeTypeConverted = false; var typeConv = TypeDescriptor.GetConverter(objType); // Check if the type converter can actually convert it to a string. if (typeConv.IsValid(obj)) { if (typeConv.CanConvertTo(typeof(string))) { canBeTypeConverted = true; } } // If it can be type converted, convert it using that, and then write it as a string. if (canBeTypeConverted) { ret = ABSaveWriter.WriteString(typeConv.ConvertToString(obj), writeNextInstructionSymbol, useSB, sb); } // Otherwise, if it can't be type converted... Manually convert it. else { ret = SerializeObject(obj, type, objType, settings, writeNextInstructionSymbol, useSB, sb, dnWriteEndLevel); } } // Return the result from this. return(ret); }
/// <summary> /// Serializes a DateTime - using the number of ticks on a DateTime. /// </summary> /// <param name="obj"></param> /// <param name="writeNextInstructionSymbol">Whether it will write \u0001 on the start - usually false if it is serializing the first object in a class.</param> /// <param name="useSB">Whether this will write to a string builder (if true), or return a string (if false).</param> /// <param name="sb">The StringBuilder to write to - if <paramref name="useSB"/> is true.</param> /// <returns>If <paramref name="useSB"/> is false, this method will return the result as a string.</returns> public static string SerializeDateTime(DateTime obj, bool useSB = false, StringBuilder sb = null) { // Write the ticks, we're using "WriteNumerical" because the ticks are a long. return(ABSaveWriter.WriteNumerical(obj.Ticks, TypeCode.Int64, true, useSB, sb)); }