Example #1
0
        bool DoRead(Stream stream)
        {
            if (stream.Length < _metadataTable.MinLength + SegmentLength)
            {
                return(false); // 虽然插件数据文件存在,但并未包含有效的数据
            }
            // 1. 读取各个分段的长度
            stream.Position = stream.Length - SegmentLength;
            var addinRecordSegmentLength           = stream.ReadInt64();
            var addinMetadataSegmentLength         = stream.ReadInt64();
            var invalidAddinFilePacksSegmentLength = stream.ReadInt64();
            var dataSegmentLength = stream.ReadInt64();

            if (dataSegmentLength + SegmentLength != stream.Length)
            {
                return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
            }
            // 2. 读取 AddinMetadata 分段 (AddinMetadataTable)
            stream.Position = addinRecordSegmentLength; // 指针指向 AddinMetadata 分段 (AddinMetadataTable) 的起始位置
            var hasAddins = _metadataTable.Read(stream);

            if (!hasAddins || _metadataTable.AddinCount == 0)
            {
                return(false); // 虽然插件数据文件存在,但并未包含有效的数据
            }
            // 3. 根据 AddinMetadata 读取 AddinRecord 分段,并进行验证
            foreach (var metadata in _metadataTable.Addins)
            {
                stream.Position = metadata.Position;
                var addin = new AddinRecord(metadata);
                addin.Read(stream);
                if (stream.Position - metadata.Position != metadata.Length || addin.Uid != metadata.AddinUid)
                {
                    return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
                }
                _addinRecords.Add(addin);
            }

            // 4. 读取 InvalidAddinFilePack 分段
            stream.Position        = addinRecordSegmentLength + addinMetadataSegmentLength; // 指针指向 InvalidAddinFilePack 分段的起始位置
            _invalidAddinFilePacks = RecordHelpers.Read(stream, ref AddinFilePack.Factory);
            if (stream.Position - (addinRecordSegmentLength + addinMetadataSegmentLength) != invalidAddinFilePacksSegmentLength)
            {
                return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
            }
            // 5. 读取 Uid 分段
            stream.Position = addinRecordSegmentLength + addinMetadataSegmentLength + invalidAddinFilePacksSegmentLength; // 指针指向 Uid 分段的起始位置
            UidStorage.Read(stream);

            return(true);
        }
Example #2
0
        bool DoWrite(Stream stream)
        {
            long addinRecordSegmentLength           = 0,
                 addinMetadataSegmentLength         = 0,
                 invalidAddinFilePacksSegmentLength = 0,
                 dataSegmentLength = 0;

            // 1. 写入 AddinRecord 分段
            long startPosition = 0;

            foreach (var addin in _addinRecords)
            {
                var addinMetadata = addin.AddinMetadata;
                addinMetadata.AddinUid = addin.Uid;
                // 记录 AddinRecord 的起始位置
                addinMetadata.Position = stream.Position;
                // 写入 AddinRecord
                addin.Write(stream);
                // 记录 AddinRecord 的长度
                addinMetadata.Length = stream.Position - addinMetadata.Position;
            }
            addinRecordSegmentLength = stream.Position - startPosition;

            // 2. 写入 AddinMetadata 分段 (AddinMetadataTable)
            startPosition = stream.Position;
            _metadataTable.Write(stream);
            addinMetadataSegmentLength = stream.Position - startPosition;

            // 3. 写入 InvalidAddinFilePack 分段
            startPosition = stream.Position;
            RecordHelpers.Write(stream, _invalidAddinFilePacks);
            invalidAddinFilePacksSegmentLength = stream.Position - startPosition;

            // 4. 写入 Uid 分段
            UidStorage.Write(stream);

            // 5. 获取数据段的长度
            dataSegmentLength = stream.Position;

            // 6. 写入各个分段 (segemtnt) 的长度
            stream.WriteInt64(addinRecordSegmentLength);
            stream.WriteInt64(addinMetadataSegmentLength);
            stream.WriteInt64(invalidAddinFilePacksSegmentLength);
            stream.WriteInt64(dataSegmentLength);

            return(true);
        }