/// <summary> /// Creates a new <see cref="ABSaveIdentifiedType"/> with all the information. /// </summary> public unsafe ABSaveIdentifiedType(short key, string value, Type type) { // Set the key/value. Key = key; Value = value; // Set the type. Type = type; // Create the "WrittenKey". var bytes = ABSaveUtils.ConvertNumberToByteArray(key, TypeCode.Int16); WrittenKey = new char[2]; // Add the bytes to the "WrittenKey" as characters. fixed(byte *fixedBytePointer = bytes) fixed(char *fixedCharPointer = WrittenKey) { // Create non-fixed pointers for each array. var charPointer = fixedCharPointer; var bytePointer = fixedBytePointer; // And, finally, copy them. for (int i = 0; i < bytes.Length; i++) { *(charPointer++) = (char)*(bytePointer++); } } }
void SerializeItemNoSetup(object obj, MapItemInfo info, ref BitTarget header, bool skipHeader) { Converter item = info.Converter; ABSaveUtils.WaitUntilNotGenerating(item); SerializeConverter(obj, info.Converter, ref header, skipHeader); }
object DeserializeItemNoSetup(MapItemInfo info, bool skipHeader) { Converter item = info.Converter; ABSaveUtils.WaitUntilNotGenerating(item); return(DeserializeConverter(info.Converter, skipHeader)); }
public static string WriteDotAndInt32(int num, bool writeToSB, StringBuilder sb) { string ret = ""; ret += WriteCharacter('.', writeToSB, sb); ret += WriteByteArray(ABSaveUtils.ConvertNumberToByteArray(num, TypeCode.Int32), writeToSB, sb); return(ret); }
byte[] GetStringBufferFor(int length) { if (_stringBuffer == null || _stringBuffer.Length < length) { return(_stringBuffer = ABSaveUtils.CreateUninitializedArray <byte>(length)); } return(_stringBuffer); }
/// <summary> /// Adds a dictionary item to a certain dictionary with a type and all the keys/values along with it. /// </summary> public void AddItem(Type type, ref List <object> addTo) { // Get all the fields/properties in the type. var variables = ABSaveUtils.GetFieldsAndPropertiesWithTypes(type); // Now, add them to the main dictionary. addTo.Add(new ABSaveParserItem <T, object, object, object>(variables)); // Also, add a new item to "CurrentItem" for this object. CurrentItem.Add(0); }
/// <summary> /// Finishes an item by actually creating a final instance out of it. /// </summary> public void FinishObject() { // Create the object based on the data we've collected in the CurrentObjects. var obj = ABSaveUtils.CreateInstance(CurrentObjects.Last().GetObjectType(), Settings, CurrentObjects.Last().ObjectItems); // Remove the last object from the CurrentObjects - since we're done with it now. CurrentObjects.RemoveAt(CurrentObjects.Count - 1); // Remove the last item index from the CurrentItem - since we're done with that now as well. CurrentItem.RemoveAt(CurrentItem.Count - 1); // Now, if we've gotten rid of ALL the CurrentObjects, place the object we just made in the final "Result". if (CurrentObjects.Count == 0) { Result = obj; return; } // If it isn't the last one, we need to put the final object where it's meant to go, which is just where the "CurrentItem" is NOW, because we've removed the last one from it. CurrentObjects.Last().ObjectItems.Items[CurrentItem.Last()] = obj; }
/// <summary> /// Writes a number, and either returns the result or writes it to a StringBuilder. /// </summary> /// <param name="str">The number to write.</param> /// <param name="useSB">Whether we are writing to a StringBuilder or not.</param> /// <param name="numType">The type that the number is.</param> /// <param name="sb">The StringBuilder to write to - if we're writing to one at all.</param> /// <returns>If <paramref name="useSB"/> is false, this method will return the result as a string.</returns> public static string WriteNumerical(dynamic num, TypeCode numType, bool writeLengthBytes = true, bool useSB = false, StringBuilder sb = null) { // NOTE: WE DON'T NEED THE "Next Instruction" CHARACTER BECAUSE \A AND \B ARE ACTUALLY ESCAPED! // Create a variable to store what we'll return. var ret = ""; // Write the number as a byte array. byte[] numberBytes = ABSaveUtils.ConvertNumberToByteArray(num, numType); // Next, work out how many of those bytes actually contain something (we don't want to waste space on trailing "\0"s) numberBytes = RemoveTrailingZeroBytesInByteArray(numberBytes); // Then, if we're going to write the "length bytes", then do it. var lengthBytes = WriteNumericalLengthBytes(writeLengthBytes, numberBytes); // Write out those "length bytes" now. ret += WriteByteArray(lengthBytes, useSB, sb); // Write the actual number - as a byte array. ret += WriteByteArray(numberBytes, useSB, sb); // Now, "ret" would be empty if we were using a StringBuilder, however, if we weren't... It will have the correct string in it so return it. return(ret); }
/// <summary> /// Figures out what a string is and how to deserialize it. This does not deserialize objects, arrays or dictionaries, however. /// </summary> /// <param name="str">The string to deserialize.</param> /// <param name="objType">The type of the object to deserialize to.</param> /// <param name="determinedType">The primitive that the object has been determined as.</param> /// <param name="manuallyParse">Whether a parser using this should manually parse the object or not.</param> /// <param name="settings">The settings for how to handle certain parts.</param> /// <param name="location">OPTIONAL: This is used to add a location to the error from the <paramref name="settings"/></param> /// <returns>The deserialized object - can be null if it needs to be manually parsed.</returns> public static object Deserialize(string str, Type objType, ABSaveSettings settings, out ABSavePrimitiveType determinedType, out bool manuallyParse, int location = 0) { // Set the "determinedType" to Unknown for now, and, manuallyParse to false. determinedType = ABSavePrimitiveType.Unknown; manuallyParse = false; // Get a type code. var tCode = Type.GetTypeCode(objType); // Now, go through what it could be and convert it. if (objType == typeof(string)) { determinedType = ABSavePrimitiveType.String; return(str); } // Check if it's a number. else if (ABSaveUtils.IsNumericType(tCode)) { determinedType = ABSavePrimitiveType.Number; return(DeserializeNumber(str, objType, settings, location)); } // Check if it's an array - if so, all we can do is set the "determinedType" to "array" since this method doesn't deal with that. else if (ABSaveUtils.IsArray(objType)) { manuallyParse = true; determinedType = ABSavePrimitiveType.Array; } // Check if it's a dictionary - if so, all we can do is set the "determinedType" to "dictionary" since this method doesn't deal with that. else if (ABSaveUtils.IsDictionary(objType)) { manuallyParse = true; determinedType = ABSavePrimitiveType.Dictionary; } // Check if it's a boolean - if so, we can get the result out of that using "DeserializeBool" else if (objType == typeof(bool)) { determinedType = ABSavePrimitiveType.Boolean; return(DeserializeBool(str, settings, location)); } // Check if it's a DateTime - if so, we can get the result out of that using "DeserializeDateTime" else if (objType == typeof(DateTime)) { determinedType = ABSavePrimitiveType.DateTime; return(DeserializeDateTime(str, settings, location)); } // Check if it's a Type - if so, we can get the result using "Type.GetType()" else if (objType == typeof(Type)) { determinedType = ABSavePrimitiveType.Type; return(Type.GetType(str)); } // If it wasn't any of the above - it's probably an object, now, we've been given a string which is actually the type name of it (unless the ABSave is incorrect). else { // Mark it as an object. determinedType = ABSavePrimitiveType.Object; // We're going to try and find a TypeConverter. But if we can't find one - we'll just return the correct type based on the TypeName we were given. TypeConverter typeConv = TypeDescriptor.GetConverter(objType); // Check if the type converter can actually convert it FROM a string, if it can, use it. if (typeConv.CanConvertFrom(typeof(string))) { return(typeConv.ConvertFrom(str)); } // However, otherwise, since we know what the type is - we'll return that, and let the parser manually parse it. else { manuallyParse = true; return(Type.GetType(str)); } } // If we got here it was probably manually making the parser do the rest to return null. return(null); }