コード例 #1
0
ファイル: IndexFile.cs プロジェクト: Phynvi/CacheIO
        public byte[] getArchiveData(int id)
        {
            if (_index.getLength() < 6 * id + 6)
            {
                return(null);
            }

            _index.Seek(6 * id);
            _index.Read(_readCacheBuffer, 0, 6);

            int archiveLength = (_readCacheBuffer[2] & 0xFF) + (((0xFF & _readCacheBuffer[0]) << 16) + (_readCacheBuffer[1] << 8 & 0xFF00));

            if (archiveLength < 0 || archiveLength > 1000000)
            {
                return(null);
            }

            int sector = ((_readCacheBuffer[3] & 0xFF) << 16) - (-(0xFF00 & _readCacheBuffer[4] << 8) - (_readCacheBuffer[5] & 0xFF));

            if (sector <= 0 || _data.getLength() / 520L < sector)
            {
                return(null);
            }

            byte[] data           = new byte[archiveLength];
            int    readBytesCount = 0;
            int    part           = 0;

            while (archiveLength > readBytesCount)
            {
                if (sector == 0)
                {
                    return(null);
                }

                int dataBlockSize = archiveLength - readBytesCount;

                byte headerSize;
                int  currentIndex;
                int  currentArchive;
                int  currentPart;
                int  nextSector;

                _data.Seek(520 * sector);

                if (65535 < id && _newProtocol)                 // 2^16 - 1
                {
                    headerSize = 10;

                    if (dataBlockSize > 510)
                    {
                        dataBlockSize = 510;
                    }

                    _data.Read(_readCacheBuffer, 0, headerSize + dataBlockSize);

                    currentIndex   = _readCacheBuffer[9] & 0xFF;
                    currentArchive = ((_readCacheBuffer[1] & 0xFF) << 16) + ((_readCacheBuffer[0] & 0xFF) << 24) + ((0xFF00 & _readCacheBuffer[2] << 8) - -(_readCacheBuffer[3] & 0xFF));
                    currentPart    = ((_readCacheBuffer[4] & 0xFF) << 8) + (0xFF & _readCacheBuffer[5]);
                    nextSector     = (_readCacheBuffer[8] & 0xFF) + (0xFF00 & _readCacheBuffer[7] << 8) + ((0xFF & _readCacheBuffer[6]) << 16);
                }
                else
                {
                    headerSize = 8;

                    if (dataBlockSize > 512)
                    {
                        dataBlockSize = 512;
                    }

                    _data.Read(_readCacheBuffer, 0, headerSize + dataBlockSize);

                    currentIndex   = _readCacheBuffer[7] & 0xFF;
                    currentArchive = (0xFF & _readCacheBuffer[1]) + (0xFF00 & _readCacheBuffer[0] << 8);
                    currentPart    = ((_readCacheBuffer[2] & 0xFF) << 8) + (0xFF & _readCacheBuffer[3]);
                    nextSector     = (_readCacheBuffer[6] & 0xFF) + (0xFF00 & _readCacheBuffer[5] << 8) + ((0xFF & _readCacheBuffer[4]) << 16);
                }

                if ((_newProtocol && id != currentArchive) || currentPart != part || _id != currentIndex)
                {
                    return(null);
                }

                if (nextSector < 0 || _data.getLength() / 520L < nextSector)
                {
                    return(null);
                }

                for (int i = headerSize; dataBlockSize + headerSize > i; i++)
                {
                    data[readBytesCount++] = _readCacheBuffer[i];
                }

                part++;
                sector = nextSector;
            }

            return(data);
        }