Ticket #8910: compressed-save-seek.patch

File compressed-save-seek.patch, 2.0 KB (added by fingolfin, 16 years ago)

add zlib backward seeking

  • backends/saves/compressed/compressed-saves.cpp

     
    6262                _stream.zfree = Z_NULL;
    6363                _stream.opaque = Z_NULL;
    6464
    65                 // Verify file header is correct once more
     65                // Verify file header is correct
    6666                w->seek(0, SEEK_SET);
    6767                uint16 header = w->readUint16BE();
    6868                assert(header == 0x1F8B ||
     
    133133        }
    134134        void seek(int32 offset, int whence = SEEK_SET) {
    135135                int32 newPos = 0;
     136                assert(whence != SEEK_END);     // SEEK_END not supported
    136137                switch(whence) {
    137                 case SEEK_END:
    138                         newPos = size() - offset;
    139                         break;
    140138                case SEEK_SET:
    141139                        newPos = offset;
    142140                        break;
    143141                case SEEK_CUR:
    144142                        newPos = _pos + offset;
    145143                }
    146                 offset = newPos - _pos;
     144               
     145                assert(newPos >= 0);
    147146
    148                 if (offset < 0)
    149                         error("Backward seeking not supported in compressed savefiles");
     147                if ((uint32)newPos < _pos) {
     148                        // To search backward, we have to restart the whole decompression
     149                        // from the start of the file. A rather wasteful operation, best
     150                        // to avoid it. :/
     151#if DEBUG
     152                        warning("Backward seeking in CompressedInSaveFile detected");
     153#endif
     154                        _pos = 0;
     155                        _wrapped->seek(0, SEEK_SET);
     156                        _zlibErr = inflateReset(&_stream);
     157                        if (_zlibErr != Z_OK)
     158                                return;
     159                        _stream.next_in = _buf;
     160                        _stream.avail_in = 0;
     161                }
    150162
    151                 // We could implement backward seeking, but it is tricky to do efficiently.
    152                 // A simple solution would be to restart the whole decompression from the
    153                 // start of the file. Or we could decompress the whole file in one go
    154                 // in the constructor, and wrap it into a MemoryReadStream -- but that
    155                 // would be rather wasteful. As long as we don't need it, I'd rather not
    156                 // implement this at all. -- Fingolfin
     163                offset = newPos - _pos;
    157164
    158165                // Skip the given amount of data (very inefficient if one tries to skip
    159166                // huge amounts of data, but usually client code will only skip a few