/// <summary> /// Initalizes TypeGo variable /// </summary> /// <param name="typeGoInfo">TypeGo variable to initialize</param> /// <param name="options">Serializer or deserializer options</param> public void Initialize(TypeGoInfo <TObject> typeGoInfo, ITypeOptions options) { TypeGoInfo = typeGoInfo; typeGoInfo.IsNoQuotesValueType = false; var baseType = Nullable.GetUnderlyingType(typeGoInfo.Type); if (baseType == null) { baseType = typeGoInfo.Type; } baseType = ReflectionHelper.GenerateTypeFromInterface(baseType, options); typeGoInfo.DefaultBinaryValue = new byte[] { 0 }; //set delegates to access faster and make it pointer directly usgae typeGoInfo.JsonSerialize = JsonSerialize; //set delegates to access faster and make it pointer directly usage for json deserializer typeGoInfo.JsonDeserialize = JsonDeserialize; //set delegates to access faster and make it pointer directly usage for binary serializer typeGoInfo.BinarySerialize = BinarySerialize; //set delegates to access faster and make it pointer directly usage for binary deserializer typeGoInfo.BinaryDeserialize = BinaryDeserialize; //create instance of object typeGoInfo.CreateInstance = ReflectionHelper.GetActivator <TObject>(baseType); typeGoInfo.SerializeProperties = typeGoInfo.Properties.Values.ToArray(); typeGoInfo.DeserializeProperties = typeGoInfo.Properties.Values.ToArray(); GenerateProperties(); }
/// <summary> /// Initalizes TypeGo variable /// </summary> /// <param name="arrayTypeGoInfo">TypeGo variable to initialize</param> /// <param name="options">Serializer or deserializer options</param> public void Initialize(TypeGoInfo <List <T> > arrayTypeGoInfo, ITypeOptions options) { arrayTypeGoInfo.IsNoQuotesValueType = false; //set the default value of variable arrayTypeGoInfo.DefaultValue = default; if (TryGetValueOfTypeGo(typeof(T), out object result)) { typeGoInfo = (TypeGoInfo <T>)result; } else { typeGoInfo = BaseTypeGoInfo.Generate <T>(Options); } arrayTypeGoInfo.JsonSerialize = JsonSerialize; //set delegates to access faster and make it pointer directly usage for json deserializer arrayTypeGoInfo.JsonDeserialize = JsonDeserialize; //set delegates to access faster and make it pointer directly usage for binary serializer arrayTypeGoInfo.BinarySerialize = BinarySerialize; //set delegates to access faster and make it pointer directly usage for binary deserializer arrayTypeGoInfo.BinaryDeserialize = BinaryDeserialize; //create instance of object //arrayTypeGoInfo.CreateInstance = ReflectionHelper.GetActivator<TObject>(baseType); CastToArray = arrayTypeGoInfo.Cast; }
/// <summary> /// deserialize json /// </summary> /// <param name="typeGo"></param> /// <param name="instance"></param> /// <param name="json">json value</param> /// <param name="createInstance">index of start string</param> /// <returns>value deserialized</returns> internal static ReadOnlySpan <char> Extract(JsonDeserializer deserializer, TypeGoInfo typeGo, ref object instance, Func <object> createInstance, ref JsonSpanReader json) { var character = json.Read(); if (character == JsonConstantsBytes.Quotes) { //if (typeGo.IsNoQuotesValueType) return(json.ExtractString()); //else // return json.ExtractStringQuotes(); } else if (character == JsonConstantsBytes.OpenBraket) { //if (createInstance != null) // instance = createInstance(); ExtractOject(deserializer, typeGo, ref instance, ref json); } else if (character == JsonConstantsBytes.OpenSquareBrackets) { if (instance == null && typeGo.CreateInstance != null) { instance = typeGo.CreateInstance(); } ExtractArray(deserializer, typeGo, ref instance, ref json); } else { if (createInstance != null) { instance = null; } return(json.ExtractValue()); } return(null); }
/// <summary> /// Initalizes TypeGo variable /// </summary> /// <param name="typeGoInfo">TypeGo variable to initialize</param> /// <param name="options">Serializer or deserializer options</param> public void Initialize(TypeGoInfo <byte[]> typeGoInfo, ITypeOptions options) { typeGoInfo.IsNoQuotesValueType = false; //set the default value of variable typeGoInfo.DefaultValue = default; typeGoInfo.JsonSerialize = JsonSerialize; typeGoInfo.JsonDeserialize = JsonDeserialize; //set delegates to access faster and make it pointer directly usage for binary serializer typeGoInfo.BinarySerialize = BinarySerialize; //set delegates to access faster and make it pointer directly usage for binary deserializer typeGoInfo.BinaryDeserialize = BinaryDeserialize; }
internal static T ExtractArray(JsonDeserializer deserializer, TypeGoInfo <T> typeGo, ref JsonSpanReader json) { //typeGo.JsonDeserialize(ref json); //var generic = typeGo.Generics.First(); while (true) { char character = json.Read(); if (character == JsonConstantsString.OpenBraket) { //var obj = ExtractOject(ref deserializer, ref typeGo, ref json); //typeGo.AddArrayValue(arrayInstance, obj); } else if (character == JsonConstantsString.OpenSquareBrackets) { //var obj = ExtractArray(deserializer, generic, ref json); //typeGo.AddArrayValue(arrayInstance, obj); } else if (character == JsonConstantsString.Quotes) { //var value = json.ExtractString(); //typeGo.AddArrayValue(arrayInstance, generic.JsonDeserialize(deserializer, value)); } else if (character == JsonConstantsString.Comma) { continue; } else if (character == JsonConstantsString.CloseSquareBrackets) { break; } else { //bool isClosed = false; //var value = json.ExtractValue(); //if (value[value.Length - 1] == JsonConstantsString.Comma) // value = value.Slice(0, value.Length - 1); //if (value[value.Length - 1] == JsonConstantsString.CloseSquareBrackets) //{ // value = value.Slice(0, value.Length - 1); // isClosed = true; //} //if (generic.JsonDeserialize != null) // typeGo.AddArrayValue(arrayInstance, generic.JsonDeserialize(deserializer, value)); //if (isClosed) // break; } } return(default);
static void ExtractArray(JsonDeserializer deserializer, TypeGoInfo typeGo, ref object instance, ref JsonSpanReader json) { var generic = typeGo.Generics.First(); while (true) { var character = json.Read(); if (character == JsonConstantsBytes.OpenBraket) { object genericInstance = null; ExtractOject(deserializer, generic, ref genericInstance, ref json); typeGo.AddArrayValue(instance, genericInstance); } else if (character == JsonConstantsBytes.OpenSquareBrackets) { object genericInstance = null; ExtractArray(deserializer, generic, ref genericInstance, ref json); typeGo.AddArrayValue(instance, genericInstance); } else if (character == JsonConstantsBytes.Comma) { continue; } else if (character == JsonConstantsBytes.CloseSquareBrackets) { break; } else if (character == JsonConstantsBytes.Quotes) { var value = json.ExtractString(); typeGo.AddArrayValue(instance, generic.JsonDeserialize(deserializer, value)); } else { var value = json.ExtractValue(); if (generic.JsonDeserialize != null) { typeGo.AddArrayValue(instance, generic.JsonDeserialize(deserializer, value)); } } } }
/// <summary> /// Initalizes TypeGo variable /// </summary> /// <param name="typeGoInfo">TypeGo variable to initialize</param> /// <param name="options">Serializer or deserializer options</param> public void Initialize(TypeGoInfo <string> typeGoInfo, ITypeOptions options) { Encoding = options.Encoding; typeGoInfo.IsNoQuotesValueType = false; //set the default value of variable typeGoInfo.DefaultValue = default; //set delegates to access faster and make it pointer directly usage typeGoInfo.JsonSerialize = JsonSerialize; //set delegates to access faster and make it pointer directly usage for json deserializer typeGoInfo.JsonDeserialize = JsonDeserialize; //set delegates to access faster and make it pointer directly usage for binary serializer typeGoInfo.BinarySerialize = BinarySerialize; //set delegates to access faster and make it pointer directly usage for binary deserializer typeGoInfo.BinaryDeserialize = BinaryDeserialize; IsUnixNewLine = Environment.NewLine.Length == 1; }
/// <summary> /// Deserialize json /// </summary> /// <param name="deserializer"></param> /// <param name="typeGo"></param> /// <param name="json">json object to deserialize</param> /// <returns>The deserialized value</returns> internal static T Extract(ref JsonDeserializer deserializer, TypeGoInfo <T> typeGo, ref JsonSpanReader json) { char character = json.Read(); if (character == JsonConstantsString.Quotes) { ReadOnlySpan <char> extract = json.ExtractString(); return(typeGo.JsonDeserialize(ref extract)); } else if (character == JsonConstantsString.OpenBraket) { return(ExtractOject(ref deserializer, ref typeGo, ref json)); } else if (character == JsonConstantsString.OpenSquareBrackets) { return(ExtractArray(deserializer, typeGo, ref json)); } else { ReadOnlySpan <char> value = json.ExtractValue(); return(typeGo.JsonDeserialize(ref value)); } }
/// <summary> /// Get binary model of type /// </summary> /// <typeparam name="T"></typeparam> /// <param name="typeGoInfo"></param> /// <param name="option"></param> /// <param name="generatedModels"></param> /// <returns></returns> internal static BinaryModelInfo GetBinaryModel <T>(TypeGoInfo <T> typeGoInfo, BaseOptionInfo option, Dictionary <Type, BinaryModelInfo> generatedModels) { Type type = typeGoInfo.Type; if (generatedModels.TryGetValue(type, out BinaryModelInfo binaryModel)) { return(binaryModel); } binaryModel = new BinaryModelInfo { Name = type.Name, Namespace = type.Namespace, AssemblyName = System.IO.Path.GetFileName(type.Assembly.Location), Properties = new List <MemberBinaryModelInfo>(), Generics = new List <BinaryModelInfo>() }; generatedModels.Add(type, binaryModel); foreach (Type genericType in type.GetGenericArguments()) { binaryModel.Generics.Add(GetBinaryModel(genericType, option, generatedModels)); } if (typeGoInfo.Variable is ObjectVariable <T> objectVariable) { foreach (BasePropertyGoInfo <T> property in objectVariable.Properties) { MemberBinaryModelInfo propertyResult = property.GetBinaryMember(option, generatedModels); propertyResult.Index = property.Index; binaryModel.Properties.Add(propertyResult); } } return(binaryModel); }
/// <summary> /// extract list of properties from object /// </summary> /// <param name="typeGo"></param> /// <param name="instance"></param> /// <param name="json"></param> /// <param name="indexOf"></param> /// <returns></returns> static void ExtractOject(JsonDeserializer deserializer, TypeGoInfo typeGo, ref object instance, ref JsonSpanReader json) { while (!json.IsFinished) { //read tp uneascape char var character = json.Read(); if (character == JsonConstantsBytes.Comma) { continue; } else if (character == JsonConstantsBytes.CloseBracket) { break; } var key = json.ExtractKey(); //read to uneascape char json.Read(); var propertyname = new string(key.ToArray()); if (typeGo.Properties.TryGetValue(propertyname, out PropertyGoInfo propertyGo)) { if (instance == null && typeGo.CreateInstance != null) { instance = typeGo.CreateInstance(); } object propertyInstance = null; if (propertyGo.TypeGoInfo.CreateInstance != null) { propertyInstance = propertyGo.TypeGoInfo.CreateInstance(); } else { propertyInstance = instance; } var value = Extract(deserializer, propertyGo.TypeGoInfo, ref propertyInstance, propertyGo.TypeGoInfo.CreateInstance, ref json); var deserialize = propertyGo.TypeGoInfo.JsonDeserialize; if (deserialize != null) { propertyGo.JsonSetValue(deserializer, propertyInstance, deserialize(deserializer, value)); } else { propertyGo.JsonSetValue(deserializer, instance, propertyInstance); } } else if (propertyname == JsonConstantsBytes.ValuesRefrencedTypeNameNoQuotes) { Extract(deserializer, typeGo, ref instance, null, ref json); } else if (propertyname == JsonConstantsBytes.RefRefrencedTypeNameNoQuotes) { object propertyInstance = null; var value = Extract(deserializer, null, ref propertyInstance, null, ref json); var type = TypeGoInfo.Generate(typeof(int), deserializer); var result = (int)type.JsonDeserialize(deserializer, value); deserializer.DeSerializedObjects.TryGetValue(result, out instance); } else { Extract(deserializer, propertyGo?.TypeGoInfo, ref instance, null, ref json); } } }
//#region CompileTimeSerialization ///// <summary> ///// The "compile time" serialization is a faster way to serialize data ///// </summary> ///// <typeparam name="T"></typeparam> ///// <param name="data"></param> ///// <returns></returns> //public string SerializeCompile<T>(T data) //{ // Writer = new StringBuilder(256); // //ClearSerializedObjects(); // ReferencedIndex = 0; // if (GetSerializer(out Action<Serializer, StringBuilder, T> serializer, ref data)) // serializer(this, Writer, data); // return Writer.ToString(); //} ///// <summary> ///// Continue serialization in compile time ///// </summary> ///// <typeparam name="T"></typeparam> ///// <param name="data"></param> //public void ContinueSerializeCompile<T>(T data) //{ // if (GetSerializer(out Action<Serializer, StringBuilder, T> serializer, ref data)) // serializer(this, Writer, data); //} ///// <summary> ///// Gets "compile time" serializer to serialize data faster ///// </summary> ///// <typeparam name="T"></typeparam> ///// <param name="serializer"></param> ///// <param name="data"></param> ///// <returns></returns> //internal bool GetSerializer<T>(out Action<Serializer, StringBuilder, T> serializer, ref T data) //{ // serializer = TypeInfo<T>.Serialize; // if (serializer == null) // { // var genericTypeDefinition = typeof(T).GetGenericTypeDefinition(); // if (genericTypeDefinition == typeof(IEnumerable<>)) // { // var type = typeof(IEnumerable<>).MakeGenericType(typeof(T).GetGenericArguments()[0]); // if (TypeManager.CompiledTypes.TryGetValue(type, out CompileTime.TypeInfo typeInfo)) // { // typeInfo.DynamicSerialize(this, Writer, data); // return false; // } // } // throw new Exception($"Type {typeof(T)} not initialized in compile time!"); // } // return true; //} //#endregion /// <summary> /// Serializes an object to a json string /// </summary> /// <param name="typeGoInfo"></param> /// <param name="serializeHandler"></param> /// <param name="data">Object to serialize</param> /// <returns>Json string from serialized object</returns> internal void SerializeObject <T>(TypeGoInfo <T> typeGoInfo, ref JsonSerializeHandler serializeHandler, ref T data) { typeGoInfo.JsonSerialize(ref serializeHandler, ref data); }
/// <summary> /// deserialize json /// </summary> /// <param name="typeGo"></param> /// <param name="instance"></param> /// <param name="json">json value</param> /// <param name="createInstance">index of start string</param> /// <returns>value deserialized</returns> internal static void Extract(TypeGoInfo typeGo, ref object instance, Func <object> createInstance, ref ReadOnlySpan <byte> _buffer) { int startIndex = 0; int endIndex = 0; // StringBuilder stringBuilder = null; int index = -1; int length = _buffer.Length; ExtractEmpty: index++; if (index >= length) { return; } var character = _buffer[index]; if (JsonSpanReader2.SkipValues.Contains(character)) { goto ExtractEmpty; } else { if (character == JsonConstantsBytes.Comma) { goto ExtractEmpty; } else if (character == JsonConstantsBytes.Colon) { goto ExtractEmpty; } else if (character == JsonConstantsBytes.OpenBraket) { goto CreateObject; } else if (character == JsonConstantsBytes.OpenSquareBrackets) { } else if (character == JsonConstantsBytes.Quotes) { goto ExtractString; } else { goto ExtractValue; } } CreateObject: //stackReader = new StackReader(new StringBuilder()) { Parent = stackReader }; if (createInstance != null) { instance = createInstance(); } goto ExtractEmpty; ExtractString: startIndex = index; endIndex = index; //stringBuilder = new StringBuilder(); bool canSkip = false; while (true) { index++; character = _buffer[index]; if (character == JsonConstantsBytes.Quotes) { if (canSkip) { canSkip = false; } else { break; } } else if (character == JsonConstantsBytes.BackSlash) { canSkip = true; } endIndex = index; //stringBuilder.Append((char)character); } goto ExtractEmpty; ExtractValue: startIndex = index; endIndex = index; //stringBuilder = new StringBuilder(); //stringBuilder.Append((char)_buffer[index]); while (true) { index++; character = _buffer[index]; if (character == JsonConstantsBytes.Space || character == JsonConstantsBytes.Comma || character == JsonConstantsBytes.CloseBracket || character == JsonConstantsBytes.CloseSquareBrackets) { break; } else { endIndex = index; } } goto ExtractEmpty; }