Example #1
0
 public int readNodeFromBitArrStream(PvfHeader header, FileStream fs, byte[] unpackedHeaderTree, int offsite)
 {
     try
     {
         fileNumber     = BitConverter.ToUInt32(unpackedHeaderTree, offsite);
         filePathLength = BitConverter.ToInt32(unpackedHeaderTree, offsite + 4);
         byte[] filePath = new byte[filePathLength];
         Array.Copy(unpackedHeaderTree, offsite + 8, filePath, 0, filePathLength);
         fileLength     = BitConverter.ToInt32(unpackedHeaderTree, (offsite + filePathLength) + 8);
         fileCrc32      = BitConverter.ToUInt32(unpackedHeaderTree, (offsite + filePathLength) + 12);
         relativeOffset = BitConverter.ToInt32(unpackedHeaderTree, (offsite + filePathLength) + 0x10);
         if (fileLength > 0)
         {
             computedFileLength  = (int)((fileLength + 3L) & 4294967292L);
             unpackedFileByteArr = new byte[computedFileLength];
             fs.Seek(Marshal.SizeOf(typeof(PvfHeader)) + header.dirTreeLength + relativeOffset, SeekOrigin.Begin);
             fs.Read(unpackedFileByteArr, 0, computedFileLength);
             Util.unpackHeaderTree(ref unpackedFileByteArr, computedFileLength, fileCrc32);
             for (int i = 0; i < (computedFileLength - fileLength); i++)
             {
                 unpackedFileByteArr[fileLength + i] = 0;
             }
         }
         filePathName = Encoding.GetEncoding(0x3b5).GetString(filePath).TrimEnd(new char[1]);//CP949(韩语)
         return(filePathLength + 20);
     }
     catch
     {
         return(-1);
     }
 }
Example #2
0
        public Dictionary <string, string> nStringMap = new Dictionary <string, string>();                      //n_string.lst文件的索引键值关系,键值均为字符串

        /*
         *  pvf共分三部分:Header头,Tree文件索引头,文件内容数据,本类中:
         *  使用struct PvfHeader{}来存储Header头,在本类中为header对象
         *  使用Dictionary<string, HeaderTreeNode> headerTreeCache来存储Tree文件索引头,键为文件索引的文件名,值为索引对象
         *  使用HeaderTreeNode的索引对象存储文件内容,详情请看本类构造方法。
         */
        public Pvf(string file)                                                                           //本构造方法使用后需dispose释放内存,构造过程请放到线程中异步调用。
        {
            fs     = new FileStream(file, FileMode.Open);                                                 //打开文件
            header = (PvfHeader)Util.readFileAsType(fs, typeof(PvfHeader));                               //读取pvf文件头结构体到header变量
            int headLength = header.dirTreeLength;                                                        //获取文件索引列表字节总大小

            byte[] decryptedTree = new byte[header.dirTreeLength];                                        //分配内存
            fs.Read(decryptedTree, 0, header.dirTreeLength);                                              //读取文件索引列表
            Util.unpackHeaderTree(ref decryptedTree, header.dirTreeLength, (uint)header.dirTreeChecksum); //解密,解密后的字节数组为decryptedTree
            int pos = 0;                                                                                  //模拟读取字节数组的指针

            for (int i = 0; i < header.numFilesInDirTree; i++)
            {
                HeaderTreeNode item = new HeaderTreeNode();
                int            a    = item.readNodeFromBitArrStream(header, fs, decryptedTree, pos);//从pos位置开始读取HeaderTreeNode对象,返回值为指针应该偏移的字节数
                if (a < 0)
                {
                    throw new Exception("读取错误,格式非法");                                   //读取错误直接报错
                }
                pos += a;                                                               //指针后移
                headerTreeCache[item.filePathName] = item;                              //把对象放入字典,以文件名为键
            }
            loadStringTableBin(headerTreeCache["stringtable.bin"].unpackedFileByteArr); //读取stringtable.bin文件创建stringtable索引
            loadNStringLst(headerTreeCache["n_string.lst"].unpackedFileByteArr);        //读取n_string.lst文件创建n_string索引
            return;
        }