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