/*---------------------------------------------------------------------- | DcfParser_GetContentKey +---------------------------------------------------------------------*/ static BLT_Result DcfParser_GetContentKey(DcfParser* self, const char* content_id, NPT_DataBuffer& key) { // default key.SetDataSize(0); // check that we have a key manager if (self->key_manager == NULL) return BLT_ERROR_NO_MEDIA_KEY; // ask the key manager to resolve the key key.Reserve(1024); BLT_Size key_size = 1024; BLT_Result result = BLT_KeyManager_GetKeyByName(self->key_manager, content_id, key.UseData(), &key_size); if (BLT_FAILED(result)) { if (result == ATX_ERROR_NOT_ENOUGH_SPACE) { key.Reserve(key_size); result = BLT_KeyManager_GetKeyByName(self->key_manager, content_id, key.UseData(), &key_size); } else { return result; } } key.SetDataSize(key_size); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_Zip::Inflate +---------------------------------------------------------------------*/ NPT_Result NPT_Zip::Inflate(const NPT_DataBuffer& in, NPT_DataBuffer& out, bool raw) { // assume an output buffer twice the size of the input plus a bit NPT_CHECK_WARNING(out.Reserve(32+2*in.GetDataSize())); // setup the stream z_stream stream; stream.next_in = (Bytef*)in.GetData(); stream.avail_in = (uInt)in.GetDataSize(); stream.next_out = out.UseData(); stream.avail_out = (uInt)out.GetBufferSize(); // setup the memory functions stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; // initialize the decompressor int err = inflateInit2(&stream, raw?-15:15+32); // 15 = default window bits, +32 = automatic header if (err != Z_OK) return MapError(err); // decompress until the end do { err = inflate(&stream, Z_SYNC_FLUSH); if (err == Z_STREAM_END || err == Z_OK || err == Z_BUF_ERROR) { out.SetDataSize((NPT_Size)stream.total_out); if ((err == Z_OK && stream.avail_out == 0) || err == Z_BUF_ERROR) { // grow the output buffer out.Reserve(out.GetBufferSize()*2); stream.next_out = out.UseData()+stream.total_out; stream.avail_out = out.GetBufferSize()-(NPT_Size)stream.total_out; } } } while (err == Z_OK); // check for errors if (err != Z_STREAM_END) { inflateEnd(&stream); return MapError(err); } // cleanup err = inflateEnd(&stream); return MapError(err); }
/*---------------------------------------------------------------------- | NPT_Zip::Deflate +---------------------------------------------------------------------*/ NPT_Result NPT_Zip::Deflate(const NPT_DataBuffer& in, NPT_DataBuffer& out, int compression_level, Format format /* = ZLIB */) { // default return state out.SetDataSize(0); // check parameters if (compression_level < NPT_ZIP_COMPRESSION_LEVEL_DEFAULT || compression_level > NPT_ZIP_COMPRESSION_LEVEL_MAX) { return NPT_ERROR_INVALID_PARAMETERS; } // setup the stream z_stream stream; NPT_SetMemory(&stream, 0, sizeof(stream)); stream.next_in = (Bytef*)in.GetData(); stream.avail_in = (uInt)in.GetDataSize(); // setup the memory functions stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; // initialize the compressor int err = deflateInit2(&stream, compression_level, Z_DEFLATED, 15 + (format == GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return MapError(err); // reserve an output buffer known to be large enough out.Reserve(deflateBound(&stream, stream.avail_in) + (format==GZIP?10:0)); stream.next_out = out.UseData(); stream.avail_out = out.GetBufferSize(); // decompress err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return MapError(err); } // update the output size out.SetDataSize(stream.total_out); // cleanup err = deflateEnd(&stream); return MapError(err); }
/*---------------------------------------------------------------------- | NPT_InputStream::Load +---------------------------------------------------------------------*/ NPT_Result NPT_InputStream::Load(NPT_DataBuffer& buffer, NPT_Size max_read /* = 0 */) { NPT_Result result; NPT_Size total_bytes_read; // reset the buffer buffer.SetDataSize(0); // try to get the stream size NPT_Size size; if (NPT_SUCCEEDED(GetSize(size))) { // make sure we don't read more than max_read if (max_read && max_read < size) size = max_read; } else { size = max_read; } // pre-allocate the buffer if (size) NPT_CHECK(buffer.Reserve(size)); // read the data from the file total_bytes_read = 0; do { NPT_Size available = 0; NPT_Size bytes_to_read; NPT_Size bytes_read; NPT_Byte* data; // check if we know how much data is available result = GetAvailable(available); if (NPT_SUCCEEDED(result) && available) { // we know how much is available bytes_to_read = available; } else { bytes_to_read = NPT_INPUT_STREAM_LOAD_DEFAULT_READ_CHUNK; } // make sure we don't read more than what was asked if (size != 0 && total_bytes_read+bytes_to_read>size) { bytes_to_read = size-total_bytes_read; } // stop if we've read everything if (bytes_to_read == 0) break; // ensure that the buffer has enough space NPT_CHECK(buffer.Reserve(total_bytes_read+bytes_to_read)); // read the data data = buffer.UseData()+total_bytes_read; result = Read((void*)data, bytes_to_read, &bytes_read); if (NPT_SUCCEEDED(result) && bytes_read != 0) { total_bytes_read += bytes_read; buffer.SetDataSize(total_bytes_read); } } while(NPT_SUCCEEDED(result) && (size==0 || total_bytes_read < size)); if (result == NPT_ERROR_EOS) { return NPT_SUCCESS; } else { return result; } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { // setup debugging #if defined(WIN32) && defined(_DEBUG) int flags = _crtDbgFlag | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(flags); //AllocConsole(); //freopen("CONOUT$", "w", stdout); #endif for (unsigned int t=0; t<sizeof(TestVectors)/sizeof(TestVectors[0]); t++) { TestVector* v = &TestVectors[t]; NPT_DataBuffer in1(v->compressed, v->compressed_len); NPT_DataBuffer out1; NPT_Result result = NPT_Zip::Inflate(in1, out1); CHECK(result == NPT_SUCCESS); CHECK(out1.GetDataSize() == v->uncompressed_len); CHECK(NPT_MemoryEqual(out1.GetData(), v->uncompressed, v->uncompressed_len)); NPT_DataBuffer in2(v->uncompressed, v->uncompressed_len); NPT_DataBuffer out2; NPT_DataBuffer out2_check; result = NPT_Zip::Deflate(in2, out2, NPT_ZIP_COMPRESSION_LEVEL_MAX, NPT_Zip::GZIP); CHECK(result == NPT_SUCCESS); result = NPT_Zip::Inflate(out2, out2_check); CHECK(result == NPT_SUCCESS); CHECK(out2_check.GetDataSize() == in2.GetDataSize()); CHECK(NPT_MemoryEqual(v->uncompressed, out2_check.GetData(), in2.GetDataSize())); // try with random data NPT_DataBuffer in3(300000); unsigned char* in3_p = in3.UseData(); for (int i=0; i<300000; i++) { *in3_p++ = NPT_System::GetRandomInteger(); } in3.SetDataSize(300000); NPT_DataBuffer out3; result = NPT_Zip::Deflate(in3, out3); CHECK(result == NPT_SUCCESS); NPT_DataBuffer out3_check; result = NPT_Zip::Inflate(out3, out3_check); CHECK(result == NPT_SUCCESS); CHECK(in3 == out3_check); // try with redundant data in3_p = in3.UseData(); for (int i=0; i<200000; i+=4) { *in3_p++ = NPT_System::GetRandomInteger(); *in3_p++ = 0; *in3_p++ = 0; *in3_p++ = 0; } result = NPT_Zip::Deflate(in3, out3); CHECK(result == NPT_SUCCESS); result = NPT_Zip::Inflate(out3, out3_check); CHECK(result == NPT_SUCCESS); CHECK(in3 == out3_check); // streams for (unsigned int x=0; x<1000; x++) { NPT_MemoryStream* ms_gz = new NPT_MemoryStream(v->compressed, v->compressed_len); NPT_InputStreamReference ms_gz_ref(ms_gz); NPT_ZipInflatingInputStream ziis(ms_gz_ref); NPT_DataBuffer buffer; NPT_Position position = 0; bool expect_eos = false; for (;;) { NPT_Size chunk = NPT_System::GetRandomInteger()%40000; buffer.SetDataSize(chunk); NPT_Size bytes_read = 0; result = ziis.Read(buffer.UseData(), chunk, &bytes_read); if (expect_eos) { CHECK(result == NPT_ERROR_EOS); break; } if (result == NPT_ERROR_EOS) { CHECK(position == v->uncompressed_len); } else { CHECK(result == NPT_SUCCESS); } CHECK(bytes_read <= chunk); if (bytes_read != chunk) expect_eos = true; CHECK(NPT_MemoryEqual(v->uncompressed+position, buffer.GetData(), bytes_read)); position += bytes_read; } CHECK(position == v->uncompressed_len); } for (unsigned int x=0; x<1000; x++) { NPT_MemoryStream* ms = new NPT_MemoryStream(v->uncompressed, v->uncompressed_len); NPT_InputStreamReference ms_ref(ms); NPT_ZipDeflatingInputStream zdis(ms_ref, NPT_ZIP_COMPRESSION_LEVEL_MAX, NPT_Zip::GZIP); NPT_DataBuffer buffer; NPT_Position position = 0; bool expect_eos = false; for (;;) { NPT_Size chunk = NPT_System::GetRandomInteger()%40000; buffer.Reserve(buffer.GetDataSize()+chunk); NPT_Size bytes_read = 0; result = zdis.Read(buffer.UseData()+buffer.GetDataSize(), chunk, &bytes_read); if (expect_eos) { CHECK(result == NPT_ERROR_EOS); break; } CHECK(result == NPT_SUCCESS); CHECK(bytes_read <= chunk); if (bytes_read != chunk) expect_eos = true; position += bytes_read; buffer.SetDataSize(buffer.GetDataSize()+bytes_read); } NPT_DataBuffer out; NPT_DataBuffer check(v->uncompressed, v->uncompressed_len); CHECK(NPT_Zip::Inflate(buffer, out) == NPT_SUCCESS); CHECK(out == check); } } return 0; }