示例#1
0
    public BSPHeader(BinaryReader map)
    {

		map.BaseStream.Position=0;
        version = map.ReadInt32();
		if(version!=30) Debug.LogError("Bsp is wrong type");


        for (int i = 0; i < 16; i++)
        {

			directory[i]= new HeaderEntry(map.ReadInt32(),map.ReadInt32(),Lump_type[i]);
			

        }

    }
示例#2
0
        /// <summary>
        /// Encode the header field into the header block.
        /// </summary>
        /// <param name="output">Output.</param>
        /// <param name="name">Name.</param>
        /// <param name="value">Value.</param>
        /// <param name="sensitive">If set to <c>true</c> sensitive.</param>
        public void EncodeHeader(BinaryWriter output, byte[] name, byte[] value, bool sensitive)
        {
            // If the header value is sensitive then it must never be indexed
            if (sensitive)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NEVER, nameIndex);
                return;
            }

            // If the peer will only use the static table
            if (this.capacity == 0)
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex == -1)
                {
                    int nameIndex = StaticTable.GetIndex(name);
                    this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                }
                else
                {
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                return;
            }

            int headerSize = HeaderField.SizeOf(name, value);

            // If the headerSize is greater than the max table size then it must be encoded literally
            if (headerSize > this.capacity)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                return;
            }

            HeaderEntry headerField = this.GetEntry(name, value);

            if (headerField != null)
            {
                int index = this.GetIndex(headerField.Index) + StaticTable.Length;
                // Section 6.1. Indexed Header Field Representation
                Encoder.EncodeInteger(output, 0x80, 7, index);
            }
            else
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex != -1)
                {
                    // Section 6.1. Indexed Header Field Representation
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                else
                {
                    int nameIndex = this.GetNameIndex(name);
                    if (useIndexing)
                    {
                        this.EnsureCapacity(headerSize);
                    }
                    var indexType = useIndexing ? HPackUtil.IndexType.INCREMENTAL : HPackUtil.IndexType.NONE;
                    this.EncodeLiteral(output, name, value, indexType, nameIndex);
                    if (useIndexing)
                    {
                        this.Add(name, value);
                    }
                }
            }
        }
示例#3
0
        public POFile(IO.TextFile textFile, LanguageGetter languageGetter)
        {
            this._dirty           = false;
            this._textFile        = textFile;
            this._textFile.Saved += this.TextFile_Saved;
            List <IO.TextLine> group   = null;
            List <Entry>       entries = new List <Entry>();
            Regex rxNoSpaces           = new Regex(@"\s+", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline);
            bool  firstGroup           = true;

            this._header = null;
            foreach (IO.TextLine line in textFile.Lines)
            {
                if (rxNoSpaces.Replace(line.Value, "").Length > 0)
                {
                    if (group == null)
                    {
                        group = new List <IO.TextLine>();
                    }
                    group.Add(line);
                }
                else
                {
                    if (group != null)
                    {
                        Entry entry = Entry.Parse(firstGroup, this, group);
                        entries.Add(entry);
                        if (entry is HeaderEntry)
                        {
                            this._header = (HeaderEntry)entry;
                        }
                        firstGroup = false;
                        group      = null;
                    }
                }
            }
            if (group != null)
            {
                Entry entry = Entry.Parse(firstGroup, this, group);
                entries.Add(entry);
                if (entry is HeaderEntry)
                {
                    this._header = (HeaderEntry)entry;
                }
                firstGroup = false;
                group      = null;
            }
            this._entries  = entries.ToArray();
            this._header   = (this._entries.Length > 0) ? (this._entries[0] as HeaderEntry) : null;
            this._language = null;
            if ((this._header != null) && (this.Header.LanguageCode.Length > 0))
            {
                try
                { this._language = new CultureInfo(this.Header.LanguageCode); }
                catch
                { }
            }
            if (this._language == null)
            {
                if (languageGetter != null)
                {
                    CultureInfo suggest = null;
                    Match       match   = Regex.Match(Path.GetFileNameWithoutExtension(textFile.FileName), @"(^|\b)(?<code>[a-z]{2})($|[_-](?<code2>[a-z]{2})$)", RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        if (!string.IsNullOrEmpty(match.Groups["code2"].Value))
                        {
                            try
                            { suggest = new CultureInfo(string.Format("{0}-{1}", match.Groups["code"].Value.ToLowerInvariant(), match.Groups["code2"].Value.ToUpperInvariant())); }
                            catch
                            { }
                            if (suggest == null)
                            {
                                try
                                {
                                    suggest = new CultureInfo(match.Groups["code2"].Value.ToLowerInvariant());
                                }
                                catch
                                { }
                            }
                        }
                        if (suggest == null)
                        {
                            try
                            { suggest = new CultureInfo(match.Groups["code"].Value.ToLowerInvariant()); }
                            catch
                            { }
                        }
                    }
                    this._language = languageGetter(suggest);
                    if (this._language == null)
                    {
                        throw new OperationCanceledException();
                    }
                }
            }
            if (this._language == null)
            {
                throw new Exception("Unable to determine the language.");
            }
            this.TotalDataEntries = 0;
            foreach (Entry entry in this._entries)
            {
                if (entry.Kind == Entry.Kinds.Standard)
                {
                    this.TotalDataEntries++;
                }
            }
        }
示例#4
0
 /// <summary>
 /// Creates new entry.
 /// </summary>
 /// <param name="hash">Hash.</param>
 /// <param name="name">Name.</param>
 /// <param name="value">Value.</param>
 /// <param name="index">Index.</param>
 /// <param name="next">Next.</param>
 public HeaderEntry(int hash, string name, string value, int index, HeaderEntry next) : base(name, value)
 {
     Index = index;
     Hash  = hash;
     Next  = next;
 }
示例#5
0
 /// <summary>
 /// Creates new entry.
 /// </summary>
 /// <param name="hash">Hash.</param>
 /// <param name="name">Name.</param>
 /// <param name="value">Value.</param>
 /// <param name="index">Index.</param>
 /// <param name="next">Next.</param>
 public HeaderEntry(int hash, byte[] name, byte[] value, int index, HeaderEntry next) : base(name, value)
 {
     this.index = index;
     this.hash  = hash;
     this.next  = next;
 }
示例#6
0
 /// <summary>
 /// Creates new entry.
 /// </summary>
 /// <param name="hash"></param>
 /// <param name="name"></param>
 /// <param name="value"></param>
 /// <param name="index"></param>
 /// <param name="next"></param>
 internal HeaderEntry(int hash, ICharSequence name, ICharSequence value, int index, HeaderEntry next)
     : base(name, value)
 {
     Index = index;
     Hash  = hash;
     Next  = next;
 }
示例#7
0
 public override IHeaders <ICharSequence, ICharSequence> Clear()
 {
     _firstNonPseudo = _head;
     return(base.Clear());
 }
示例#8
0
 /// <summary>
 /// Creates new entry.
 /// </summary>
 /// <param name="hash">Hash.</param>
 /// <param name="name">Name.</param>
 /// <param name="value">Value.</param>
 /// <param name="index">Index.</param>
 /// <param name="next">Next.</param>
 public HeaderEntry(int hash, byte[] name, byte[] value, int index, HeaderEntry next) : base(name, value)
 {
     this.index = index;
     this.hash = hash;
     this.next = next;
 }
示例#9
0
 /// <summary>
 /// Inserts this entry before the specified existing entry in the list.
 /// </summary>
 /// <param name="existingEntry">Existing entry.</param>
 public void AddBefore(HeaderEntry existingEntry)
 {
     after = existingEntry;
     before = existingEntry.before;
     before.after = this;
     after.before = this;
 }
示例#10
0
 public AsyncDecompressArgs(HeaderEntry he, FileStream file)
 {
     Entry = he;
     File  = file;
 }
示例#11
0
        /// <summary>
        /// Add the header field to the dynamic table.
        /// Entries are evicted from the dynamic table until the size of the table
        /// and the new header field is less than the table's capacity.
        /// If the size of the new entry is larger than the table's capacity,
        /// the dynamic table will be cleared.
        /// </summary>
        /// <param name="name">Name.</param>
        /// <param name="value">Value.</param>
        private void Add(byte[] name, byte[] value)
        {
            int headerSize = HeaderField.SizeOf(name, value);

            // Clear the table if the header field size is larger than the capacity.
            if (headerSize > this.capacity) {
                this.Clear();
                return;
            }

            // Evict oldest entries until we have enough capacity.
            while(this.size + headerSize > this.capacity) {
                this.Remove();
            }

            // Copy name and value that modifications of original do not affect the dynamic table.
            name.CopyTo(name, 0);
            value.CopyTo(value, 0);

            int h = Encoder.Hash(name);
            int i = Encoder.Index(h);
            HeaderEntry old = headerFields[i];
            HeaderEntry e = new HeaderEntry(h, name, value, head.Before.Index - 1, old);
            headerFields[i] = e;
            e.AddBefore(head);
            this.size += headerSize;
        }
示例#12
0
        public static void Rebuild(string[] args)
        {
            if (!Directory.Exists(args[1]))
            {
                Console.Error.WriteLine("Directory '{0}' doesn't exist!", args[1]);
            }
            args[1] = Path.GetFullPath(args[1]);
            // demo vol
            byte[] rofsHeader = new byte[4] {
                (byte)'R', (byte)'o', (byte)'F', (byte)'S'
            };
            byte[] headerString = null;
            if (args.Length > 3)
            {
                g_compressedFlag = 0x2;
                g_directoryFlag  = 0x1;
                headerString     = rofsHeader;
                g_demoVol        = true;
            }
            else
            {
                g_compressedFlag = 0x02000000;
                g_directoryFlag  = 0x01000000;
                headerString     = BitConverter.GetBytes(~BitConverter.ToUInt32(rofsHeader, 0));
                g_demoVol        = false;
            }
            uint numFolders = 0, numFiles = 0, namesLength = 0;
            List <HeaderEntry> rootDir = null;

#if DEBUG
            // building the entry list takes for freaking ever due to all the decompressing
            // so when debugging we do it once, then save the results to a file
            // then on the next run, we don't have to wait for the same info to be recollected
            string        serializeName = Path.GetFileName(args[1]);
            EntryListInfo eli           = DeserializeEntryList(serializeName);
            //Console.WriteLine("Press enter to continue");
            //Console.ReadLine();
            if (eli == null)
            {
#endif
            //DateTime start = DateTime.Now;
            List <HeaderEntry> fileHeaders = BuildEntryList(args[1], ref numFolders, ref numFiles, out namesLength);
            // The dot<nul> for the root entry needs accounting for
            namesLength += g_demoVol ? 4u : 2u;
            rootDir      = new List <HeaderEntry>(1);
            HeaderEntry rootEntry = new HeaderEntry();
            rootDir.Add(rootEntry);
            rootEntry.children     = fileHeaders;
            rootEntry.fullFileName = ".";
            // wait for all the decompression jobs to finish before continuing
            while (Interlocked.CompareExchange(ref g_jobsFinished, g_jobsStarted, g_jobsStarted) != g_jobsStarted)
            {
                Thread.Sleep(100);
            }
            //DateTime end = DateTime.Now;
            //TimeSpan dur = end - start;
            //Console.WriteLine("Building entry list took {0}ms/{1}s", dur.TotalMilliseconds, dur.TotalSeconds);
#if DEBUG
            // still in the if(eli == null) case
            eli               = new EntryListInfo();
            eli.namesLength   = namesLength;
            eli.numCompressed = (uint)g_numCompressed;
            eli.numFiles      = numFiles;
            eli.numFolders    = numFolders;
            eli.root          = rootDir;
            SerializeEntryList(serializeName, eli);
        }     // end of eli == null

        else
        {
            g_numCompressed = (int)eli.numCompressed;
            numFiles        = eli.numFiles;
            numFolders      = eli.numFolders;
            namesLength     = eli.namesLength;
            rootDir         = eli.root;
        }
#endif
            byte[] volHead = BuildHeaderFromList(headerString, rootDir, numFolders, numFiles, namesLength);
            using (FileStream fs = new FileStream(args[2], FileMode.Create, FileAccess.Write))
            {
                byte[] blank = new byte[8191];
                fs.Write(volHead, 0, volHead.Length);
                Stack <List <HeaderEntry> > entryStack  = new Stack <List <HeaderEntry> >();
                List <HeaderEntry>          curIterList = rootDir;
                while (true)
                {
                    if (curIterList.Count == 0)
                    {
                        if (entryStack.Count == 0)
                        {
                            break;
                        }
                        curIterList = entryStack.Pop();
                        continue;
                    }
                    int         last  = curIterList.Count - 1;
                    HeaderEntry entry = curIterList[last];
                    curIterList.RemoveAt(last);
                    if (entry.children == null)
                    {
                        fs.Seek(entry.fileDataPosition, SeekOrigin.Begin);
                        Console.WriteLine("Reading {0} to write to the vol at {1:x}", Path.GetFileName(entry.fullFileName), entry.fileDataPosition);
                        byte[] data = File.ReadAllBytes(entry.fullFileName);
                        fs.Write(data, 0, data.Length);
                        fs.Write(blank, 0, 0x800 - (data.Length % 0x800));
                    }
                    else
                    {
                        entryStack.Push(curIterList);
                        Console.WriteLine("Moving to directory {0}", Path.GetFileName(entry.fullFileName));
                        curIterList = entry.children;
                    }
                }
            }
        }
示例#13
0
        private static List <DirInfo> WriteNewDirectory(
            HeaderEntry directory,
            uint parentDirPos,
            ref uint nextDirInfoPos,  // for the directory contents
            ref uint nextFileInfoPos, // for the file info
            ref uint nextFileDataPos, // for the file data
            uint startOfNamesOffset,
            BinaryWriter headerWriter,
            BinaryWriter names,
            List <DirInfo> directories
            )
        {
            uint thisDirPos = GetCurrentStreamPosition(headerWriter);
            // write the name
            uint dirNameOffset = 0;

            AppendVolHeaderFileName(names, Path.GetFileName(directory.fullFileName), out dirNameOffset);
            // fix it up and write it
            dirNameOffset += startOfNamesOffset;
            headerWriter.Write(dirNameOffset | g_directoryFlag);
            List <HeaderEntry> contents = directory.children;

            // then how many entries
            headerWriter.Write(contents.Count + 1);
            // then the parent pos
            headerWriter.Write(parentDirPos);
            // then the entries
            bool doLoop = (directories == null);

            if (directories == null)
            {
                directories = new List <DirInfo>();
            }
            for (int i = 0; i < contents.Count; ++i)
            {
                HeaderEntry he = contents[i];
                if (he.children != null && he.children.Count > 0)
                {
                    // the format of the vol is
                    //                 root
                    //    DirA         DirB        DirC
                    // DirAA DirAB DirBA DirBB DirCA DirCB
                    //
                    // All these go in file order so root->DirA->DirB->DirC->DirAA rather than root->DirA->DirAA->DirAB->DirB
                    // so don't recurse here, or that's what we'd get
                    //
                    headerWriter.Write(nextDirInfoPos);
                    directories.Add(new DirInfo(nextDirInfoPos, thisDirPos, he));
                    // update the position for the next dir
                    nextDirInfoPos += (uint)((3 + he.children.Count) * 4);
                }
                else
                {
                    // next file pos
                    headerWriter.Write(nextFileInfoPos);
                    uint curPos = GetCurrentStreamPosition(headerWriter);
                    SetCurrentStreamPosition(headerWriter, nextFileInfoPos);
                    uint nameOffset = 0;
                    // write the name and fix up its position from name-stream relative
                    // to vol header relative
                    AppendVolHeaderFileName(names, Path.GetFileName(he.fullFileName), out nameOffset);
                    nameOffset += startOfNamesOffset;
                    // save these so we know where to dump the file data in the vol
                    // without having to recalculate stuff
                    he.fileDataPosition = nextFileDataPos;
                    if (he.isCompressed)
                    {
                        headerWriter.Write(nameOffset | g_compressedFlag);
                        headerWriter.Write(nextFileDataPos / 0x800);
                        // this seems to be ignored (if it's incorrect and more than actually required) nothing happens
                        // smaller than required not tested
                        headerWriter.Write(he.decompSize);
                        headerWriter.Write(he.fileSize);
                        nextFileInfoPos += (4 * 4);
                    }
                    else
                    {
                        headerWriter.Write(nameOffset);
                        headerWriter.Write(nextFileDataPos / 0x800);
                        headerWriter.Write(he.fileSize);
                        nextFileInfoPos += (3 * 4);
                        // demo always has four entries per file info, compressed or not
                        if (g_demoVol)
                        {
                            headerWriter.Write(he.fileSize);
                            nextFileInfoPos += 4;
                        }
                    }
                    // reset file pointer for next entry
                    SetCurrentStreamPosition(headerWriter, curPos);
                    // round the file data position to the start of the next sector
                    nextFileDataPos = ((nextFileDataPos + he.fileSize + 0x7ffu) & ~0x7ffu);
                }
            }
            if (!doLoop)
            {
                return(directories);
            }
            while (directories.Count > 0)
            {
                DirInfo dir = directories[0];
                SetCurrentStreamPosition(headerWriter, dir.offset);
                List <DirInfo> childDirs = new List <DirInfo>();
                WriteNewDirectory(
                    dir.entry,
                    dir.parentOffset,
                    ref nextDirInfoPos,
                    ref nextFileInfoPos,
                    ref nextFileDataPos,
                    startOfNamesOffset,
                    headerWriter,
                    names,
                    childDirs
                    );
                directories.RemoveAt(0);
                directories.AddRange(childDirs);
            }
            return(null);
        }
示例#14
0
 public DirInfo(uint inOffset, uint inParentOffset, HeaderEntry inEntry)
 {
     offset       = inOffset;
     parentOffset = inParentOffset;
     entry        = inEntry;
 }
示例#15
0
 /// <summary>
 /// Removes this entry from the linked list.
 /// </summary>
 public void Remove()
 {
     this.before.after = this.after;
     this.after.before = this.before;
 }
示例#16
0
        /// <summary>
        /// 加载数据
        /// </summary>
        /// <param name="reader">树型包读取器实例</param>
        /// <param name="password">密码,为空将会是默认密码。</param>
        /// <returns>返回加载后的树型包实例。</returns>
        public static unsafe TreePackage Load(System.IO.Stream reader, byte[] password = null)
        {
            //if (reader == null)
            //    throw new ArgumentNullException("reader", "树型包读取器不能为 null 。");
            if (reader == null)
            {
                return(null);
            }
            if (!reader.CanRead)
            {
                throw new ArgumentNullException("reader", "树型包读取器不能进行读取操作。");
            }
            //if (reader.Closed)
            //    throw new ObjectDisposedException("reader", "树型包读取器已经关闭。");

            #region header 1
            byte[] buffer = new byte[8];
            if (reader.Read(buffer, 0, 4) != 4)  //位数不够
            {
                return(null);
            }
            //错误的标识
            if (buffer[0] != HeaderEntry.StartFlag[0] ||
                buffer[1] != HeaderEntry.StartFlag[1] ||
                buffer[2] != HeaderEntry.StartFlag[2] ||
                buffer[3] != HeaderEntry.StartFlag[3])
            {
                return(null);
            }
            HeaderEntry packageEntry = new HeaderEntry();
            packageEntry.Started = true;

            //Version,EncryptType
            if (reader.Read(buffer, 0, 2) != 2)
            {
                return(null);
            }
            if (buffer[0] > 9)
            {
                packageEntry.Version = (byte)(buffer[0] / 10);
                buffer[0]           -= (byte)(packageEntry.Version * 10);
            }
            packageEntry.EncryptType = (PackageEncryptTypes)buffer[0];
            //KeyIgnoreCase,HasAttributes,HasComment
            if (buffer[1] >= 100)
            {
                packageEntry.KeyIgnoreCase = true;
                buffer[1] -= 100;
            }
            if (buffer[1] >= 10)
            {
                packageEntry.HasAttributes = true;
                buffer[1] -= 10;
            }
            if (buffer[1] == 1)
            {
                packageEntry.HasComment = true;
            }
            #endregion

            if (password == null || password.Length == 0 || password == _defaultBinaryWavePassword)
            {
                password = _defaultBinaryWavePassword;
                if (packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword)
                {
                    packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_DefaultPassword;
                }
            }
            else
            {
                if (packageEntry.EncryptType != PackageEncryptTypes.BinaryWave_EmptyPassword)
                {
                    packageEntry.EncryptType = PackageEncryptTypes.BinaryWave_CustomPassword;
                }
            }
            TreePackage result = null;
            using (Symbol.Encryption.BinaryEncryptionStream binaryEncryptionStream = new Symbol.Encryption.BinaryEncryptionStream(reader, password, packageEntry.EncryptType == PackageEncryptTypes.BinaryWave_EmptyPassword)) {
                int int32Var;

                #region header 2
                //AttributesLength
                if (packageEntry.HasAttributes)
                {
                    if (binaryEncryptionStream.Read(buffer, 0, 4) != 4)
                    {
                        return(null);
                    }
                    Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4);
                    packageEntry.AttributesLength = int32Var;
                }
                //CommentLength
                if (packageEntry.HasComment)
                {
                    if (binaryEncryptionStream.Read(buffer, 0, 4) != 4)
                    {
                        return(null);
                    }
                    Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4);
                    packageEntry.CommentLength = int32Var;
                }
                //KeysCount
                if (binaryEncryptionStream.Read(buffer, 0, 4) != 4)
                {
                    return(null);
                }
                Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4);
                packageEntry.KeysCount = int32Var;

                //AttributesData
                if (packageEntry.HasAttributes)
                {
                    packageEntry.AttributesData = new byte[packageEntry.AttributesLength];
                    if (binaryEncryptionStream.Read(packageEntry.AttributesData, 0, packageEntry.AttributesLength) != packageEntry.AttributesLength)
                    {
                        return(null);
                    }
                }
                //CommentData
                if (packageEntry.HasComment)
                {
                    packageEntry.CommentData = new byte[packageEntry.CommentLength];
                    if (binaryEncryptionStream.Read(packageEntry.CommentData, 0, packageEntry.CommentLength) != packageEntry.CommentLength)
                    {
                        return(null);
                    }
                }
                #endregion

                result = new TreePackage(packageEntry);

                #region Keys
                //Keys
                ushort   uShortVar = 0;
                ulong    uInt64Var = 0;
                KeyEntry keyEntry;
                byte[]   bufferValueData = null;
                Entry    entry           = null;
                for (int keyIndex = 0; keyIndex < packageEntry.KeysCount; keyIndex++)
                {
                    #region Header
                    if (binaryEncryptionStream.Read(buffer, 0, 5) != 5)
                    {
                        return(null);
                    }
                    //KeyLength
                    Marshal.Copy(buffer, 0, (IntPtr)(&uShortVar), 2);
                    keyEntry           = new KeyEntry();
                    keyEntry.KeyLength = uShortVar;
                    if (keyEntry.KeyLength == 0)
                    {
                        return(null);
                    }
                    //ValueType
                    keyEntry.ValueType = (PackageValueTypes)buffer[2];
                    //Nullable|ArrayType
                    if (buffer[3] >= 100)
                    {
                        keyEntry.Nullable = true;
                        buffer[3]        -= 100;
                    }
                    keyEntry.ArrayType = (PackageArrayTypes)buffer[3];
                    //HasAttributes,CompressType
                    if (buffer[4] >= 100)
                    {
                        keyEntry.HasAttributes = true;
                        buffer[4] -= 100;
                    }
                    keyEntry.CompressType = (PackageCompressTypes)buffer[4];

                    if (keyEntry.HasAttributes)  //AttributesLength
                    {
                        if (binaryEncryptionStream.Read(buffer, 0, 4) != 4)
                        {
                            return(null);
                        }
                        Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4);
                        keyEntry.AttributesLength = int32Var;
                    }
                    //ValueDataLength
                    if (!keyEntry.Nullable)
                    {
                        if (binaryEncryptionStream.Read(buffer, 0, 4) != 4)
                        {
                            return(null);
                        }
                        Marshal.Copy(buffer, 0, (IntPtr)(&int32Var), 4);
                        keyEntry.ValueDataLength = int32Var;
                        //CRC32
                        if (binaryEncryptionStream.Read(buffer, 0, 8) != 8)
                        {
                            return(null);
                        }
                        Marshal.Copy(buffer, 0, (IntPtr)(&uInt64Var), 8);
                        keyEntry.CRC32 = uInt64Var;
                    }
                    #endregion

                    #region Data
                    //KeyData
                    keyEntry.KeyData = new byte[keyEntry.KeyLength];
                    if (binaryEncryptionStream.Read(keyEntry.KeyData, 0, keyEntry.KeyLength) != keyEntry.KeyLength)
                    {
                        return(null);
                    }
                    //AttributesData
                    if (keyEntry.HasAttributes)
                    {
                        keyEntry.AttributesData = new byte[keyEntry.AttributesLength];
                        if (binaryEncryptionStream.Read(keyEntry.AttributesData, 0, keyEntry.AttributesLength) != keyEntry.AttributesLength)
                        {
                            return(null);
                        }
                    }
                    entry = new Entry(keyEntry);
                    ((IEntry)entry).SetIsAdd(false);
                    //ValueData
                    if (!keyEntry.Nullable)
                    {
                        bufferValueData = new byte[keyEntry.ValueDataLength];
                        if (keyEntry.CompressType == PackageCompressTypes.NonEncrypt_NonCompress)
                        {
                            if (binaryEncryptionStream.BaseRead(bufferValueData, 0, keyEntry.ValueDataLength) != keyEntry.ValueDataLength)
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            if (binaryEncryptionStream.Read(bufferValueData, 0, keyEntry.ValueDataLength) != keyEntry.ValueDataLength)
                            {
                                return(null);
                            }
                        }
                        uInt64Var = Symbol.Encryption.CRC32EncryptionHelper.Encrypt(bufferValueData);
                        if (uInt64Var != keyEntry.CRC32)
                        {
                            throw new System.IO.InvalidDataException(string.Format("“{0}”的CRC32数据验证失败。应为:{1:X8},实际:{2:X8}", entry.Key, keyEntry.CRC32, uInt64Var));
                        }
                        UnPackageValueData(keyEntry, entry, bufferValueData, result);
                    }
                    else
                    {
                        entry.Value = null;
                    }
                    #endregion

                    bufferValueData = null;
                    result.Add(entry);
                }
                #endregion
            }

            return(result);
        }