Ejemplo n.º 1
0
        /// <summary>
        /// Deserializes the meta-data.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="tagsCollectionIndex"></param>
        /// <param name="size"></param>
        protected virtual void DeserializeTags(LimitedStream stream, long size, ITagsCollectionIndex tagsCollectionIndex)
        {
            RuntimeTypeModel typeModel = RuntimeTypeModel.Create();

            typeModel.Add(typeof(SerializableTag), true);

            // read tags collection-count.
            var countBytes = new byte[4];

            stream.Read(countBytes, 0, 4);
            int max = BitConverter.ToInt32(countBytes, 0);

            // serialize tags collections one-by-one.
            var currentTags = new List <SerializableTag>();

            if (max > 0)
            { // keep reading until max.
                currentTags.AddRange(typeModel.DeserializeWithSize(stream, null, typeof(SerializableTag[])) as SerializableTag[]);

                // detect an empty collection at zero.
                if (currentTags[0].CollectionId == 1)
                { // no zero, there is an empty collection.
                    tagsCollectionIndex.Add(new TagsCollection());
                }
                while (tagsCollectionIndex.Max < max)
                {
                    // try and detect an id change.
                    bool idChanged = true;
                    while (currentTags.Count > 0 &&
                           idChanged)
                    { // there are tags.
                        idChanged = false;
                        var  tagsCollection = new TagsCollection();
                        int  index          = 0;
                        uint currentId      = currentTags[index].CollectionId;

                        // detect an empty collection in between.
                        if (currentId > tagsCollectionIndex.Max + 1)
                        { // it's possible there was an empty tag collection in there somewhere.
                            tagsCollectionIndex.Add(new TagsCollection());
                        }

                        tagsCollection.Add(new Tag(currentTags[index].Key, currentTags[index].Value));
                        index++;
                        while (currentTags.Count > index)
                        { // test for a different id.
                            if (currentTags[index].CollectionId != currentId ||
                                currentTags[index].CollectionId == uint.MaxValue)
                            { // yes! an id change was detected.
                                idChanged = true;
                                currentTags.RemoveRange(0, index);
                                if (tagsCollection.Count > 0)
                                { // there are tags.
                                    tagsCollectionIndex.AddObject(tagsCollection);
                                }
                                break;
                            }
                            tagsCollection.Add(new Tag(currentTags[index].Key, currentTags[index].Value));
                            index++;
                        }
                    }

                    // read next block.
                    currentTags.AddRange(typeModel.DeserializeWithSize(stream, null, typeof(SerializableTag[])) as SerializableTag[]);
                }
            }
        }