Esempio n. 1
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);
            if (BinaryOptions.Unordered)
            {
                InitClassDefUnordered(result, typeName);
            }
            else
            {
                InitClassDef(result, typeName);
            }
            classDefs.Add(result);
            return(result);
        }
Esempio n. 2
0
        private ReaderClassDef GetClassDefUnknown(string typeName)
        {
            var result = new ReaderClassDef {
                Meta = Meta.Unknown,
                Make = (bd, def) => {
                    var obj = new YuzuUnknownBinary {
                        ClassTag = typeName, Def = def
                    };
                    ReadFields(bd, def, obj);
                    return(obj);
                },
            };
            var theirCount = Reader.ReadInt16();

            for (int theirIndex = 0; theirIndex < theirCount; ++theirIndex)
            {
                var theirName = Reader.ReadString();
                var t         = ReadType();
                var rf        = ReadValueFunc(t);
                result.Fields.Add(new ReaderClassDef.FieldDef {
                    Name     = theirName, Type = t, OurIndex = -1,
                    ReadFunc = obj => ((YuzuUnknown)obj).Fields[theirName] = rf()
                });
            }
            classDefs.Add(result);
            return(result);
        }
Esempio n. 3
0
 protected override void PrepareReaders(ReaderClassDef def)
 {
     base.PrepareReaders(def);
     if (readCache.TryGetValue(def.Meta.Type, out ReadCacheAction r))
     {
         def.ReadFields = r;
     }
     if (makeCache.TryGetValue(def.Meta.Type, out MakeCacheAction m))
     {
         def.Make = m;
     }
 }
Esempio n. 4
0
        protected override void PrepareReaders(ReaderClassDef def)
        {
            base.PrepareReaders(def);
            Action <BinaryDeserializer, ReaderClassDef, object> r;

            if (readCache.TryGetValue(def.Meta.Type, out r))
            {
                def.ReadFields = r;
            }
            Func <BinaryDeserializer, ReaderClassDef, object> m;

            if (makeCache.TryGetValue(def.Meta.Type, out m))
            {
                def.Make = m;
            }
        }
Esempio n. 5
0
 private static void ReadFields(BinaryDeserializer d, ReaderClassDef def, object obj)
 {
     def.Meta.BeforeDeserialization.Run(obj);
     d.objStack.Push(obj);
     try {
         if (def.Meta.IsCompact)
         {
             for (int i = 1; i < def.Fields.Count; ++i)
             {
                 def.Fields[i].ReadFunc(obj);
             }
         }
         else
         {
             if (def.Meta.GetUnknownStorage != null)
             {
                 var storage = def.Meta.GetUnknownStorage(obj);
                 storage.Clear();
                 storage.Internal = def;
             }
             var actualIndex = d.Reader.ReadInt16();
             for (int i = 1; i < def.Fields.Count; ++i)
             {
                 var fd = def.Fields[i];
                 if (i < actualIndex || actualIndex == 0)
                 {
                     if (fd.OurIndex < 0 || def.Meta.Items[fd.OurIndex - 1].IsOptional)
                     {
                         continue;
                     }
                     throw d.Error("Expected field '{0}' ({1}), but found '{2}'",
                                   i, fd.Name, actualIndex);
                 }
                 fd.ReadFunc(obj);
                 actualIndex = d.Reader.ReadInt16();
             }
             if (actualIndex != 0)
             {
                 throw d.Error("Unfinished object, expected zero, but got {0}", actualIndex);
             }
         }
     }
     finally {
         d.objStack.Pop();
     }
     def.Meta.AfterDeserialization.Run(obj);
 }
Esempio n. 6
0
        private object MakeAndCheckAssignable <T>(ReaderClassDef def)
        {
            var srcType = def.Meta.Type;
            var dstType = typeof(T);

            if (srcType != typeof(YuzuUnknown) && !dstType.IsAssignableFrom(srcType))
            {
                throw Error("Unable to assign type \"{0}\" to \"{1}\"", srcType.ToString(), dstType);
            }
            var result = def.Make?.Invoke(this, def);

            if (srcType == typeof(YuzuUnknown) && !dstType.IsInstanceOfType(result))
            {
                throw Error("Unable to assign type \"{0}\" to \"{1}\"", ((YuzuUnknownBinary)result).ClassTag, dstType);
            }
            return(result);
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        private void InitClassDefUnordered(ReaderClassDef def, string typeName)
        {
            var theirCount = Reader.ReadInt16();
            int ourIndex = 0, requiredCountActiual = 0;

            for (int theirIndex = 0; theirIndex < theirCount; ++theirIndex)
            {
                var       theirName = Reader.ReadString();
                Meta.Item yi        = null;
                if (def.Meta.TagToItem.TryGetValue(theirName, out yi))
                {
                    if (!ReadCompatibleType(yi.Type))
                    {
                        throw Error(
                                  "Incompatible type for field {0}, expected {1}", theirName, yi.Type);
                    }
                    def.Fields.Add(new ReaderClassDef.FieldDef {
                        Name     = theirName,
                        OurIndex = def.Meta.Items.IndexOf(yi) + 1,
                        Type     = yi.Type,
                        ReadFunc = MakeReadOrMergeFunc(yi),
                    });
                    ourIndex += 1;
                    if (!yi.IsOptional)
                    {
                        requiredCountActiual += 1;
                    }
                }
                else
                {
                    AddUnknownFieldDef(def, theirName, typeName);
                }
            }
            if (requiredCountActiual != def.Meta.RequiredCount)
            {
                throw Error(
                          "Expected {0} required field(s), but found {1} for class {2}",
                          def.Meta.RequiredCount, requiredCountActiual, typeName);
            }
        }
Esempio n. 9
0
        private void InitClassDef(ReaderClassDef def, string typeName)
        {
            var ourCount = def.Meta.Items.Count;
            var theirCount = Reader.ReadInt16();
            int ourIndex = 0, theirIndex = 0;
            var theirName = "";

            while (ourIndex < ourCount && theirIndex < theirCount)
            {
                var yi      = def.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(def, theirName, typeName);
                    theirIndex += 1;
                    theirName   = "";
                }
                else
                {
                    if (!ReadCompatibleType(yi.Type))
                    {
                        throw Error(
                                  "Incompatible type for field {0}, expected {1}", ourName, yi.Type);
                    }
                    def.Fields.Add(new ReaderClassDef.FieldDef {
                        Name     = theirName, OurIndex = ourIndex + 1, Type = yi.Type,
                        ReadFunc = MakeReadOrMergeFunc(yi),
                    });
                    ourIndex   += 1;
                    theirIndex += 1;
                    theirName   = "";
                }
            }
            for (; ourIndex < ourCount; ++ourIndex)
            {
                var yi      = def.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(def, theirName, typeName);
                theirName = "";
            }
        }
Esempio n. 10
0
 protected virtual void PrepareReaders(ReaderClassDef def) => def.ReadFields = ReadFields;
Esempio n. 11
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);
        }