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(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(); } }