Example #1
0
        public object Read(object value, ProtoReader source)
        {
            ProtoReader.ExpectRoot(source);
            if (_protoCompatibility)
            {
                return(_serializer.Read(value, source));
            }

            int    typeKey;
            object obj;
            int    expectedRefKey;
            var    rootToken     = ProtoReader.StartSubItem(source);
            int    formatVersion = source.ReadFieldHeader();

            if (formatVersion != CurrentFormatVersion)
            {
                throw new ProtoException("Wrong format version, required " + CurrentFormatVersion + " but actual " + formatVersion);
            }
            var r = _serializer.Read(value, source);

            while (ProtoReader.TryGetNextLateReference(out typeKey, out obj, out expectedRefKey, source))
            {
                int actualRefKey;
                do
                {
                    actualRefKey = source.ReadFieldHeader() - 1;
                    if (actualRefKey != expectedRefKey)
                    {
                        if (actualRefKey <= -1)
                        {
                            throw new ProtoException("Expected field for late reference");
                        }
                        // should go only up
                        if (actualRefKey > expectedRefKey)
                        {
                            throw new ProtoException("Mismatched order of late reference objects");
                        }
                        source.SkipField(); // refKey < num
                    }
                } while (actualRefKey < expectedRefKey);
                object lateObj = ProtoReader.ReadObject(obj, typeKey, source);
                if (!ReferenceEquals(lateObj, obj))
                {
                    throw new ProtoException("Late reference changed during deserializing");
                }
            }
            ProtoReader.EndSubItem(rootToken, true, source);
            return(r);
        }