コード例 #1
0
///////////////////////////////////////////////////////
///
/// Read a string from a stream. The string is following
/// by its size
///
inline string ReadStringFromStream(CNcbiIstream& is)
{
    string str;
    if (!is.good() || is.eof())
        return str;

    size_t size;
    is >> size;
    if (!is.good() || is.eof())
        return str;
    vector<char> buf(size+1, 0);
    is.read(&*buf.begin(), size+1);
    size_t count = is.gcount();
    if (count > 0)
        str.append((&*buf.begin())+1, count-1);

    return str;
}
コード例 #2
0
void g_GZip_ScanForChunks(CNcbiIstream& is, IChunkHandler& handler)
{
    typedef IChunkHandler::TPosition TPos;

    // Use our own total counters to avoid 4GB limit
    TPos in_total  = 0;           // Offset in input compressed data
    TPos out_total = 0;           // Offset in output decompressed data
    z_stream strm;                // Compressed stream structure
    int      ret = Z_STREAM_END;  // zlib return status
    bool     initialized = false;


    // Default buffer size
    size_t in_size  = kCompressionDefaultBufSize;
    size_t out_size = kCompressionDefaultBufSize * 2;

    // Allocate buffers
    AutoArray<unsigned char> in_buf_arr(in_size);
    unsigned char* in_buf = in_buf_arr.get();
    if ( !in_buf ) {
        NCBI_THROW(CCoreException, eNullPtr, kEmptyStr);
    }
    AutoArray<unsigned char> out_buf_arr(out_size);
    unsigned char* out_buf = out_buf_arr.get();
    if ( !out_buf ) {
        NCBI_THROW(CCoreException, eNullPtr, kEmptyStr);
    }

    try {
        IChunkHandler::EAction action = IChunkHandler::eAction_Continue;
        // Process all decompressed data in the input stream
        while ( is  &&  action != IChunkHandler::eAction_Stop) {
            // Get some compressed data
            is.read((char*)in_buf, in_size);
            size_t nread = (size_t)is.gcount();
            if ( !nread ) {
                break;
            }
            // Process all data in the buffer
            strm.next_in  = in_buf;
            strm.avail_in = (unsigned int)nread;
            do {
                // Next gzip-file?
                if (ret == Z_STREAM_END) {
                    // Save current position
                    action = handler.OnChunk(in_total, out_total);
                    if (action == IChunkHandler::eAction_Stop) {
                        // Stop scanning
                        break;
                    }
                    // (Re)Initialize inflate
                    strm.zalloc   = Z_NULL;
                    strm.zfree    = Z_NULL;
                    strm.opaque   = Z_NULL;
                    ret = inflateInit2(&strm, 15+16 /* max windowbits + automatic gzip header decoding */);
                    if (ret != Z_OK) {
                        throw "inflateInit2() failed: " + string(zError(ret));
                    }
                    initialized = true;
                }
                // We don't need uncompressed data -- discard it
                strm.next_out  = out_buf;
                strm.avail_out = (unsigned int)out_size;

                // Decompress
                ret = inflate(&strm, Z_SYNC_FLUSH);
                if (ret != Z_OK  &&  ret != Z_STREAM_END ) {
                    // Error
                    throw "inflate() failed: " + string(zError(ret));
                }
                // Increase counters
                out_total += (out_size - strm.avail_out);
                in_total  += (nread - strm.avail_in);
                nread = strm.avail_in;
                // If found end of compressed stream -- cleanup
                if (ret == Z_STREAM_END) {
                    inflateEnd(&strm);
                    initialized = false;
                }
            } while (strm.avail_in != 0);
        }
        if ( initialized ) {
            inflateEnd(&strm);
        }
    }
    // Cleanup
    catch (string& e) {
        if ( initialized ) {
            inflateEnd(&strm);
        }
        NCBI_THROW(CCompressionException, eCompression, e);
    }
}