static status_t set_package_data_from_attribute_value(const BPackageAttributeValue& value, BPackageData& data) { if (value.encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) data.SetData(value.data.size, value.data.raw); else data.SetData(value.data.size, value.data.offset); return B_OK; }
status_t BPackageDataReaderFactory::CreatePackageDataReader(BDataReader* dataReader, const BPackageData& data, BAbstractBufferedDataReader*& _reader) { if (data.IsEncodedInline()) { BAbstractBufferedDataReader* reader = new(std::nothrow) PackageDataInlineReader(data); if (reader == NULL) return B_NO_MEMORY; _reader = reader; return B_OK; } PackageDataReader* reader; switch (data.Compression()) { case B_HPKG_COMPRESSION_NONE: reader = new(std::nothrow) UncompressedPackageDataReader( dataReader, fBufferPool); break; case B_HPKG_COMPRESSION_ZLIB: reader = new(std::nothrow) ZlibPackageDataReader(dataReader, fBufferPool); break; default: return B_BAD_VALUE; } if (reader == NULL) return B_NO_MEMORY; status_t error = reader->Init(data); if (error != B_OK) { delete reader; return error; } _reader = reader; return B_OK; }
status_t Init(const BPackageData& data) { fOffset = data.Offset(); fCompressedSize = data.CompressedSize(); fUncompressedSize = data.UncompressedSize(); fChunkSize = data.ChunkSize(); // validate chunk size if (fChunkSize == 0) fChunkSize = B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB; if (fChunkSize < kMinSaneZlibChunkSize || fChunkSize > kMaxSaneZlibChunkSize) { return B_BAD_DATA; } fChunkCount = (fUncompressedSize + (fChunkSize - 1)) / fChunkSize; fOffsetTableSize = (fChunkCount - 1) * sizeof(uint64); if (fOffsetTableSize >= fCompressedSize) return B_BAD_DATA; // allocate a buffer for the offset table if (fChunkCount > 1) { fOffsetTableBufferEntryCount = std::min(fChunkCount - 1, (uint64)kMaxZlibOffsetTableBufferSize); fOffsetTable = new(std::nothrow) uint64[ fOffsetTableBufferEntryCount]; if (fOffsetTable == NULL) return B_NO_MEMORY; fOffsetTableIndex = -1; // mark the table content invalid } else fChunkSize = fUncompressedSize; // mark uncompressed content invalid fUncompressedChunk = -1; return B_OK; }
status_t _ExtractFileData(BDataReader* dataReader, const BPackageData& data, int fd) { // create a BPackageDataReader BPackageDataReader* reader; status_t error = BPackageDataReaderFactory(&fBufferCache) .CreatePackageDataReader(dataReader, data, reader); if (error != B_OK) return error; ObjectDeleter<BPackageDataReader> readerDeleter(reader); // write the data off_t bytesRemaining = data.UncompressedSize(); off_t offset = 0; while (bytesRemaining > 0) { // read size_t toCopy = std::min((off_t)fDataBufferSize, bytesRemaining); error = reader->ReadData(offset, fDataBuffer, toCopy); if (error != B_OK) { fprintf(stderr, "Error: Failed to read data: %s\n", strerror(error)); return error; } // write ssize_t bytesWritten = write_pos(fd, offset, fDataBuffer, toCopy); if (bytesWritten < 0) { fprintf(stderr, "Error: Failed to write data: %s\n", strerror(errno)); return errno; } if ((size_t)bytesWritten != toCopy) { fprintf(stderr, "Error: Failed to write all data (%zd of " "%zu)\n", bytesWritten, toCopy); return B_ERROR; } offset += toCopy; bytesRemaining -= toCopy; } return B_OK; }
status_t Init(const BPackageData& data) { fOffset = data.Offset(); fSize = data.UncompressedSize(); return B_OK; }
PackageDataInlineReader(const BPackageData& data) : BBufferDataReader(fData.InlineData(), data.UncompressedSize()), fData(data) { }