예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
 public void Code(Type t, ref object o)
 {
     TypeCoder.Write(this, t, ref o);
 }
예제 #4
0
        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
        }
예제 #5
0
 public void Code(Type t, ref object o)
 {
     TypeCoder.Read(this, t, ref o);
 }
예제 #6
0
        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;
                }
            }
        }
예제 #7
0
        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();
            }
        }