public void Code(Type t, ref ICountableDict dict) { int count = CodeCount(ref dict, n => (ICountableDict)Activator.CreateInstance(t, n)); if (count < 1) { return; } var keyType = dict.KeyType; var valueType = dict.ValueType; while (count-- > 0) { object key = null; TypeCoder.Read(this, keyType, ref key); object val = null; TypeCoder.Read(this, valueType, ref val); dict.AddObject(key, val); } }
public void Code(Type t, ref IDictionary dict) { int count = CodeCount(ref dict, d => d.Count); if (count < 1) { return; } XElement element; Type[] subTypeArray = t.GetGenericArguments(); var keys = dict.Keys; foreach (object k in keys) { var item = new XElement("item"); m_elementStack.Push(m_element); m_element = item; object key = k; element = new XElement("key"); m_elementStack.Push(m_element); m_element = element; TypeCoder.Write(this, subTypeArray[0], ref key); m_element = m_elementStack.Pop(); AddValue(element); object val = dict[key]; element = new XElement("val"); m_elementStack.Push(m_element); m_element = element; TypeCoder.Write(this, subTypeArray[1], ref val); m_element = m_elementStack.Pop(); AddValue(element); m_element = m_elementStack.Pop(); AddValue(item); } }
public void Code(Type t, ref object o) { TypeCoder.Write(this, t, ref o); }
public void Code(ref object obj) { TypeInfo typeInfo; #region handle null objects if (obj == null) { if (TryGetTypeInfo(typeof(TypeCoder.Null), out typeInfo) && ((typeInfo.Options & TypeInfo.Option.Active) != 0)) { m_writer.Write(typeInfo.Name); return; } else { throw new Exception("cannot encode null object " + "- change by configuring coder with " + "\"coder.Add(TypeCoder.Default.Null);\""); } } #endregion Type type = obj.GetType(); string typeName; TypeInfo.Option typeOptions = TypeInfo.Option.Size | TypeInfo.Option.Version; if (!TypeCoder.IsDirectlyCodeable(type)) { if (HandleRef(ref obj)) { return; } } #region handle modified type names if (TryGetTypeInfo(type, out typeInfo)) { typeName = typeInfo.Name; typeOptions = typeInfo.Options; } else { typeName = type.AssemblyQualifiedName; if ((m_debugMode & CoderDebugMode.ReportQualifiedNames) != 0) { Report.Line("qualified name \"{0}\"", typeName); } } #endregion m_writer.Write(typeName); #region code version placeholder if ((typeOptions & TypeInfo.Option.Version) != 0) { m_versionStack.Push(m_version); m_version = typeInfo != null ? typeInfo.Version : 0; m_writer.Write(m_version); } #endregion #region code size placeholder long size = 0; long sizePosition = 0; long startPosition = 0; if ((typeOptions & TypeInfo.Option.Size) != 0) { sizePosition = m_writer.BaseStream.Position; m_writer.Write(size); startPosition = m_writer.BaseStream.Position; } #endregion #region code fields based on supported interface if (!TypeCoder.WritePrimitive(this, type, ref obj)) { m_typeInfoStack.Push(typeInfo); if ((m_debugMode & CoderDebugMode.ReportObjects) != 0) { Report.Line("{0,-34} 0x{1:x}", typeName, obj.GetHashCode()); } var fcobj = obj as IFieldCodeable; if (fcobj != null) { CodeFields(type, m_version, fcobj); var tmobj = obj as ITypedMap; if (tmobj != null) { CodeFields(type, tmobj); } } else if (typeInfo.ProxyType != null) { CodeFields(type, m_version, typeInfo.Object2ProxyFun(obj)); } else { throw new Exception("uncodeable object of type \"" + typeName + '\"'); } m_typeInfoStack.Pop(); } #endregion #region backpatch size into stream if ((typeOptions & TypeInfo.Option.Size) != 0) { var position = m_writer.BaseStream.Position; size = position - startPosition; m_writer.BaseStream.Position = sizePosition; m_writer.Write(size); m_writer.BaseStream.Position = position; } #endregion #region pop version stack if ((typeOptions & TypeInfo.Option.Version) != 0) { m_version = m_versionStack.Pop(); } #endregion }
public void Code(Type t, ref object o) { TypeCoder.Read(this, t, ref o); }
public void Code(ref object obj) { var typeName = m_reader.ReadString(); TypeInfo newTypeInfo = null; TypeInfo typeInfo; if (TryGetTypeInfo(typeName, out typeInfo)) { if (typeInfo.Type == typeof(TypeCoder.Null)) { if ((typeInfo.Options & TypeInfo.Option.Active) != 0) { obj = null; return; } else { throw new Exception("cannot decode null object " + "- change by configuring coder with " + "\"coder.Add(TypeCoder.Default.Null);\""); } } if (typeInfo.Type == typeof(TypeCoder.Reference)) { if ((typeInfo.Options & TypeInfo.Option.Active) != 0) { if (CoderVersion < 5) { obj = UseRef(m_reader.ReadInt32()); } else { obj = UseRef(m_reader.ReadGuid()); } return; } else { throw new Exception( "cannot decode multiply referenced object " + "- change by configuring coder with " + "\"coder.Add(TypeCoder.Default.Reference);\""); } } } else { typeInfo = new TypeInfo(typeName, Type.GetType(typeName), TypeInfo.Option.Size | TypeInfo.Option.Version); if ((m_debugMode & CoderDebugMode.ReportQualifiedNames) != 0) { Report.Line("qualified name \"{0}\"", typeName); } } if ((typeInfo.Options & TypeInfo.Option.Version) != 0) { m_versionStack.Push(m_version); m_version = m_reader.ReadInt32(); if (m_version < typeInfo.Version) { TypeInfo oldTypeInfo; if (typeInfo.VersionMap.TryGetValue(m_version, out oldTypeInfo)) { newTypeInfo = typeInfo; typeInfo = oldTypeInfo; } } } long end = 0; if ((typeInfo.Options & TypeInfo.Option.Size) != 0) { end = m_reader.ReadInt64() + m_reader.BaseStream.Position; } if (typeInfo.Type != null) { if (!TypeCoder.ReadPrimitive(this, typeInfo.Type, ref obj)) { if ((typeInfo.Options & TypeInfo.Option.Ignore) != 0) { m_reader.BaseStream.Position = end; obj = null; } else { var codedVersion = m_version; m_typeInfoStack.Push(typeInfo); if (typeInfo.Creator != null) { obj = typeInfo.Creator(); } else { obj = FastObjectFactory.ObjectFactory(typeInfo.Type)(); } if ((m_debugMode & CoderDebugMode.ReportObjects) != 0) { Report.Line("{0,-34} 0x{1:x}", typeName, obj.GetHashCode()); } if (m_doRefs) { AddRef(obj); } #region code fields based on supported interface var fcobj = obj as IFieldCodeable; if (fcobj != null) { CodeFields(typeInfo.Type, codedVersion, fcobj); if (typeInfo.ProxyType != null) { obj = typeInfo.Proxy2ObjectFun(fcobj); } else { var tmobj = obj as ITypedMap; if (tmobj != null) { CodeFields(typeInfo.Type, tmobj); } } if ((typeInfo.Options & TypeInfo.Option.Size) != 0) { m_reader.BaseStream.Position = end; } } else { if ((typeInfo.Options & TypeInfo.Option.Size) != 0) { m_reader.BaseStream.Position = end; Report.Warn( "skipping object of uncodeable type \"{0}\"", typeName); obj = null; } else { throw new Exception( "cannot skip uncodeable object of type \"" + typeName + '"'); } } var aobj = obj as IAwakeable; if (aobj != null) { aobj.Awake(codedVersion); // codedVersion } #endregion m_typeInfoStack.Pop(); } } } else { if ((typeInfo.Options & TypeInfo.Option.Size) != 0) { m_reader.BaseStream.Position = end; Report.Warn("skipping object of unknown type " + typeName); obj = null; } else { throw new Exception( "cannot skip object of unknown type \"" + typeName + '"'); } } if ((typeInfo.Options & TypeInfo.Option.Version) != 0) { m_version = m_versionStack.Pop(); if (obj != null && newTypeInfo != null) { var source = new Convertible(typeInfo.Name, obj); var target = new Convertible(newTypeInfo.Name, null); source.ConvertInto(target); obj = target.Data; } } }
public void Code(ref object obj) { TypeInfo typeInfo; if (obj == null) { if (TryGetTypeInfo(typeof(TypeCoder.Null), out typeInfo) && ((typeInfo.Options & TypeInfo.Option.Active) != 0)) { AddValue(new XElement(typeInfo.XmlName)); return; } else { throw new Exception("cannot encode null object " + "- change by configuring coder with " + "\"coder.Add(TypeCoder.Default.Null);\""); } } Type type = obj.GetType(); if (!TypeCoder.IsDirectlyCodeable(type)) { if (HandleRef(ref obj)) { return; } } string elementName; string typeName = null; TypeInfo.Option typeOptions = TypeInfo.Option.Size | TypeInfo.Option.Version; if (TryGetTypeInfo(type, out typeInfo)) { elementName = typeInfo.XmlName; typeOptions = typeInfo.Options; } else { typeName = type.AssemblyQualifiedName; elementName = "object"; if ((m_debugMode & CoderDebugMode.ReportQualifiedNames) != 0) { Report.Line("qualified name \"{0}\"", typeName); } } XElement element = new XElement(elementName); if (typeName != null) { element.Add(new XAttribute("type", typeName)); } if ((typeOptions & TypeInfo.Option.Version) != 0) { m_versionStack.Push(m_version); m_version = typeInfo != null ? typeInfo.Version : 0; element.Add(new XAttribute("version", m_version)); } if (!TypeCoder.IsDirectlyCodeable(type)) { if (m_doRefs && m_writeRefNumbers) { element.Add(new XAttribute("num", m_refs.Count - 1)); } } m_elementStack.Push(m_element); m_element = element; #region code fields based on supported interface if (!TypeCoder.WritePrimitive(this, type, ref obj)) { m_typeInfoStack.Push(typeInfo); var fcobj = obj as IFieldCodeable; if (fcobj != null) { CodeFields(type, m_version, fcobj); var tmobj = obj as ITypedMap; if (tmobj != null) { CodeFields(type, tmobj); } } else { throw new Exception(string.Format("uncodeable object: {0}", obj.GetType())); } m_typeInfoStack.Pop(); } #endregion m_element = m_elementStack.Pop(); AddValue(element); if ((typeOptions & TypeInfo.Option.Version) != 0) { m_version = m_versionStack.Pop(); } }