public static string ArrayToDescriptor(Array array, Type type, VarIntStr typeHandle) { if (array.LongLength>MAX_ELM_COUNT) throw new SlimSerializationException(StringConsts.SLIM_ARRAYS_OVER_MAX_ELM_ERROR.Args(array.LongLength, MAX_ELM_COUNT)); if (type==typeof(object[]))//special case for object[], because this type is very often used in Glue and other places return "$2|"+array.Length.ToString(); var th = typeHandle.StringValue ?? ( typeHandle.IntValue < TypeRegistry.STR_HNDL_POOL.Length ? TypeRegistry.STR_HNDL_POOL[typeHandle.IntValue] : '$'+typeHandle.IntValue.ToString() ); var ar = array.Rank; if (ar>MAX_DIM_COUNT) throw new SlimSerializationException(StringConsts.SLIM_ARRAYS_OVER_MAX_DIMS_ERROR.Args(ar, MAX_DIM_COUNT)); var descr = new StringBuilder(); descr.Append( th ); descr.Append('|');//separator char for(int i=0; i<ar; i++) { descr.Append(array.GetLowerBound(i)); descr.Append('~'); descr.Append(array.GetUpperBound(i)); if (i<ar-1) descr.Append(','); } return descr.ToString(); }
/// <summary> /// Emits MetaHandle that contains type handle for reference handle only when this referenced is added to pool for the first time. /// Emits inlined string for strings and inlined value types for boxed objects. /// Emits additional array dimensions info for array refernces who's types are emitted for the first time /// </summary> public MetaHandle GetHandle(object reference, TypeRegistry treg, SlimFormat format, out Type type) { Debug.Assert(m_Mode == SerializationOperation.Serializing, "GetHandle() called while deserializing", DebugAction.Throw); if (reference == null) { type = null; return(new MetaHandle(0)); } type = reference.GetType(); if (type == typeof(string)) { return(MetaHandle.InlineString(reference as string)); } if (reference is Type) { var thandle = treg.GetTypeHandle(reference as Type); return(MetaHandle.InlineTypeValue(thandle)); } if (type.IsValueType) { var vth = treg.GetTypeHandle(type); return(MetaHandle.InlineValueType(vth)); } bool added; uint handle = (uint)getIndex(reference, out added); if (added) { var th = treg.GetTypeHandle(type); if (format.IsRefTypeSupported(type))//20150305 Refhandle inline { return(MetaHandle.InlineRefType(th)); } if (type.IsArray)//write array header like so: "System.int[,]|0~10,0~12" or "$3|0~10,0~12" { //DKh 20130712 Removed repetitive code that was refactored into Arrays class var arr = (Array)reference; th = new VarIntStr(Arrays.ArrayToDescriptor(arr, type, th)); } return(new MetaHandle(handle, th)); } return(new MetaHandle(handle)); }
public static string ArrayToDescriptor(Array array, Type type, VarIntStr typeHandle) { if (array.LongLength > MAX_ELM_COUNT) { throw new SlimSerializationException(StringConsts.SLIM_ARRAYS_OVER_MAX_ELM_ERROR.Args(array.LongLength, MAX_ELM_COUNT)); } if (type == typeof(object[]))//special case for object[], because this type is very often used in Glue and other places { return("$2|" + array.Length.ToString()); } var th = typeHandle.StringValue ?? (typeHandle.IntValue < TypeRegistry.STR_HNDL_POOL.Length ? TypeRegistry.STR_HNDL_POOL[typeHandle.IntValue] : '$' + typeHandle.IntValue.ToString() ); var ar = array.Rank; if (ar > MAX_DIM_COUNT) { throw new SlimSerializationException(StringConsts.SLIM_ARRAYS_OVER_MAX_DIMS_ERROR.Args(ar, MAX_DIM_COUNT)); } var descr = new StringBuilder(); descr.Append(th); descr.Append('|'); //separator char for (int i = 0; i < ar; i++) { descr.Append(array.GetLowerBound(i)); descr.Append('~'); descr.Append(array.GetUpperBound(i)); if (i < ar - 1) { descr.Append(','); } } return(descr.ToString()); }
/// <summary> /// Returns type by handle i.e. VarIntStr(1) or VarIntStr("full name"). Throws in case of error /// </summary> public Type this[VarIntStr handle] { get { try { if (IsNullHandle(handle)) { return(typeof(object)); } if (handle.StringValue == null) { var idx = (int)handle.IntValue; if (idx < m_List.Count) { return(m_List[idx]); } throw new Exception(); } Type result; if (!s_Types.TryGetValue(handle.StringValue, out result)) { result = Type.GetType(handle.StringValue, true); var dict = new Dictionary <string, Type>(s_Types, StringComparer.Ordinal); dict[handle.StringValue] = result; System.Threading.Thread.MemoryBarrier(); s_Types = dict;//atomic } bool added; getTypeIndex(result, out added); return(result); } catch { throw new SlimInvalidTypeHandleException("TypeRegistry[handle] is invalid: " + handle.ToString()); } } }
public void Serialize(SlimWriter writer, TypeRegistry registry, RefPool refs, object instance, StreamingContext streamingContext, Type valueType = null) { Type type = valueType; VarIntStr typeHandle = new VarIntStr(0); if (type == null) { if (instance == null) { writer.Write(TypeRegistry.NULL_HANDLE);//object type null return; } type = instance.GetType(); //Write type name. Full or compressed. Full Type names are assembly-qualified strings, compressed are string in form of // $<name_table_index> i.e. $1 <--- get string[1] typeHandle = registry.GetTypeHandle(type); writer.Write(typeHandle); } //we get here if we have a boxed value of directly-handled type var wa = Format.GetWriteActionForType(type) ?? Format.GetWriteActionForRefType(type);//20150503 DKh fixed root byte[] slow if (wa != null) { wa(writer, instance); return; } TypeDescriptor td = getTypeDescriptorCachedOrMake(type); if (td.IsArray) //need to write array dimensions { writer.Write(Arrays.ArrayToDescriptor((Array)instance, type, typeHandle)); } td.SerializeInstance(writer, registry, refs, instance, streamingContext); }
/// <summary> /// Emits MetaHandle that contains type handle for reference handle only when this referenced is added to pool for the first time. /// Emits inlined string for strings and inlined value types for boxed objects. /// Emits additional array dimensions info for array refernces who's types are emitted for the first time /// </summary> public MetaHandle GetHandle(object reference, TypeRegistry treg, SlimFormat format, out Type type) { Debug.Assert(m_Mode == SerializationOperation.Serializing, "GetHandle() called while deserializing", DebugAction.Throw); if (reference==null) { type = null; return new MetaHandle(0); } type = reference.GetType(); if (type == typeof(string)) { return MetaHandle.InlineString(reference as string); } if (reference is Type) { var thandle = treg.GetTypeHandle(reference as Type); return MetaHandle.InlineTypeValue(thandle); } if (type.IsValueType) { var vth = treg.GetTypeHandle(type); return MetaHandle.InlineValueType(vth); } bool added; uint handle = (uint)getIndex(reference, out added); if (added) { var th = treg.GetTypeHandle(type); if (format.IsRefTypeSupported(type))//20150305 Refhandle inline return MetaHandle.InlineRefType(th); if (type.IsArray)//write array header like so: "System.int[,]|0~10,0~12" or "$3|0~10,0~12" { //DKh 20130712 Removed repetitive code that was refactored into Arrays class var arr = (Array)reference; th = new VarIntStr( Arrays.ArrayToDescriptor(arr, type, th) ); } return new MetaHandle(handle, th); } return new MetaHandle(handle); }
public abstract void Write(VarIntStr? value);
public static bool IsNullHandle(VarIntStr handle) { return(handle.IntValue == 0 && IsNullHandle(handle.StringValue)); }
public override void Write(VarIntStr? value) { if (value.HasValue) { this.Write(true); Write(value.Value); return; } this.Write(false); }
public override void Write(VarIntStr value) { this.Write(value.StringValue); if (value.StringValue==null) this.Write(value.IntValue); }