예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
	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;
	}
예제 #5
0
	status_t Init(const BPackageData& data)
	{
		fOffset = data.Offset();
		fSize = data.UncompressedSize();
		return B_OK;
	}
예제 #6
0
	PackageDataInlineReader(const BPackageData& data)
		:
		BBufferDataReader(fData.InlineData(), data.UncompressedSize()),
		fData(data)
	{
	}