Example #1
0
        private void AddUnknownFieldDef(ReaderClassDef def, string fieldName, string typeName)
        {
            if (!Options.AllowUnknownFields)
            {
                throw Error("New field {0} for class {1}", fieldName, typeName);
            }
            var fd = new ReaderClassDef.FieldDef {
                Name = fieldName, OurIndex = -1, Type = ReadType()
            };
            var rf = ReadValueFunc(fd.Type);

            if (def.Meta.GetUnknownStorage == null)
            {
                fd.ReadFunc = obj => rf();
            }
            else
            {
                fd.ReadFunc = obj => def.Meta.GetUnknownStorage(obj).Add(fieldName, rf());
            }
            def.Fields.Add(fd);
        }
Example #2
0
        private ReaderClassDef GetClassDef(short classId)
        {
            if (classId < classDefs.Count)
            {
                return(classDefs[classId]);
            }
            if (classId > classDefs.Count)
            {
                throw Error("Bad classId: {0}", classId);
            }
            var typeName  = Reader.ReadString();
            var classType = Meta.GetTypeByReadAlias(typeName, Options) ?? TypeSerializer.Deserialize(typeName);

            if (classType == null)
            {
                return(GetClassDefUnknown(typeName));
            }
            var result = new ReaderClassDef {
                Meta = Meta.Get(classType, Options)
            };

            PrepareReaders(result);
            var ourCount = result.Meta.Items.Count;
            var theirCount = Reader.ReadInt16();
            int ourIndex = 0, theirIndex = 0;
            var theirName = "";

            while (ourIndex < ourCount && theirIndex < theirCount)
            {
                var yi      = result.Meta.Items[ourIndex];
                var ourName = yi.Tag(Options);
                if (theirName == "")
                {
                    theirName = Reader.ReadString();
                }
                var cmp = String.CompareOrdinal(ourName, theirName);
                if (cmp < 0)
                {
                    if (!yi.IsOptional)
                    {
                        throw Error("Missing required field {0} for class {1}", ourName, typeName);
                    }
                    ourIndex += 1;
                }
                else if (cmp > 0)
                {
                    AddUnknownFieldDef(result, theirName, typeName);
                    theirIndex += 1;
                    theirName   = "";
                }
                else
                {
                    if (!ReadCompatibleType(yi.Type))
                    {
                        throw Error(
                                  "Incompatible type for field {0}, expected {1}", ourName, yi.Type.Name);
                    }
                    var fieldDef = new ReaderClassDef.FieldDef {
                        Name = theirName, OurIndex = ourIndex + 1, Type = yi.Type
                    };
                    if (yi.SetValue != null)
                    {
                        var rf = ReadValueFunc(yi.Type);
                        fieldDef.ReadFunc = obj => yi.SetValue(obj, rf());
                    }
                    else
                    {
                        var mf = MergeValueFunc(yi.Type);
                        fieldDef.ReadFunc = obj => mf(yi.GetValue(obj));
                    }
                    result.Fields.Add(fieldDef);
                    ourIndex   += 1;
                    theirIndex += 1;
                    theirName   = "";
                }
            }
            for (; ourIndex < ourCount; ++ourIndex)
            {
                var yi      = result.Meta.Items[ourIndex];
                var ourName = yi.Tag(Options);
                if (!yi.IsOptional)
                {
                    throw Error("Missing required field {0} for class {1}", ourName, typeName);
                }
            }
            for (; theirIndex < theirCount; ++theirIndex)
            {
                if (theirName == "")
                {
                    theirName = Reader.ReadString();
                }
                AddUnknownFieldDef(result, theirName, typeName);
                theirName = "";
            }
            classDefs.Add(result);
            return(result);
        }