xref: /haiku/src/kits/package/hpkg/PackageDataReader.cpp (revision 32832cbe47f991cc6d2b29824903181d8baaaa63)
10d6b3b20SOliver Tappe /*
2*32832cbeSIngo Weinhold  * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
30d6b3b20SOliver Tappe  * Distributed under the terms of the MIT License.
40d6b3b20SOliver Tappe  */
50d6b3b20SOliver Tappe 
60d6b3b20SOliver Tappe 
70d6b3b20SOliver Tappe #include <package/hpkg/PackageDataReader.h>
80d6b3b20SOliver Tappe 
90d6b3b20SOliver Tappe #include <string.h>
100d6b3b20SOliver Tappe 
110d6b3b20SOliver Tappe #include <algorithm>
120d6b3b20SOliver Tappe #include <new>
130d6b3b20SOliver Tappe 
1433bc4425SOliver Tappe #include <package/hpkg/HPKGDefsPrivate.h>
150d6b3b20SOliver Tappe #include <package/hpkg/PackageData.h>
16d2d1af83SIngo Weinhold #include <package/hpkg/ZlibDecompressor.h>
170d6b3b20SOliver Tappe 
180d6b3b20SOliver Tappe 
190d6b3b20SOliver Tappe namespace BPackageKit {
200d6b3b20SOliver Tappe 
215fb1c6ffSOliver Tappe namespace BHPKG {
220d6b3b20SOliver Tappe 
235fb1c6ffSOliver Tappe 
245fb1c6ffSOliver Tappe using namespace BPrivate;
250d6b3b20SOliver Tappe 
260d6b3b20SOliver Tappe 
271f633814SIngo Weinhold // #pragma mark - PackageDataHeapReader
280d6b3b20SOliver Tappe 
290d6b3b20SOliver Tappe 
301f633814SIngo Weinhold class PackageDataHeapReader : public BAbstractBufferedDataReader {
312c32402dSIngo Weinhold public:
321f633814SIngo Weinhold 	PackageDataHeapReader(BAbstractBufferedDataReader* dataReader,
331f633814SIngo Weinhold 		const BPackageData& data)
340d6b3b20SOliver Tappe 		:
351f633814SIngo Weinhold 		fDataReader(dataReader),
361f633814SIngo Weinhold 		fOffset(data.Offset()),
371f633814SIngo Weinhold 		fSize(data.Size())
380d6b3b20SOliver Tappe 	{
390d6b3b20SOliver Tappe 	}
400d6b3b20SOliver Tappe 
410d6b3b20SOliver Tappe 	virtual status_t ReadData(off_t offset, void* buffer, size_t size)
420d6b3b20SOliver Tappe 	{
430d6b3b20SOliver Tappe 		if (size == 0)
440d6b3b20SOliver Tappe 			return B_OK;
450d6b3b20SOliver Tappe 
460d6b3b20SOliver Tappe 		if (offset < 0)
470d6b3b20SOliver Tappe 			return B_BAD_VALUE;
480d6b3b20SOliver Tappe 
490d6b3b20SOliver Tappe 		if ((uint64)offset > fSize || size > fSize - offset)
500d6b3b20SOliver Tappe 			return B_BAD_VALUE;
510d6b3b20SOliver Tappe 
520d6b3b20SOliver Tappe 		return fDataReader->ReadData(fOffset + offset, buffer, size);
530d6b3b20SOliver Tappe 	}
540d6b3b20SOliver Tappe 
550d6b3b20SOliver Tappe 	virtual status_t ReadDataToOutput(off_t offset, size_t size,
56*32832cbeSIngo Weinhold 		BDataIO* output)
570d6b3b20SOliver Tappe 	{
580d6b3b20SOliver Tappe 		if (size == 0)
590d6b3b20SOliver Tappe 			return B_OK;
600d6b3b20SOliver Tappe 
610d6b3b20SOliver Tappe 		if (offset < 0)
620d6b3b20SOliver Tappe 			return B_BAD_VALUE;
630d6b3b20SOliver Tappe 
640d6b3b20SOliver Tappe 		if ((uint64)offset > fSize || size > fSize - offset)
650d6b3b20SOliver Tappe 			return B_BAD_VALUE;
660d6b3b20SOliver Tappe 
671f633814SIngo Weinhold 		return fDataReader->ReadDataToOutput(fOffset + offset, size, output);
680d6b3b20SOliver Tappe 	}
690d6b3b20SOliver Tappe 
700d6b3b20SOliver Tappe private:
711f633814SIngo Weinhold 	BAbstractBufferedDataReader*	fDataReader;
720d6b3b20SOliver Tappe 	uint64							fOffset;
730d6b3b20SOliver Tappe 	uint64							fSize;
740d6b3b20SOliver Tappe };
750d6b3b20SOliver Tappe 
760d6b3b20SOliver Tappe 
77*32832cbeSIngo Weinhold // #pragma mark - PackageDataInlineReader
780d6b3b20SOliver Tappe 
790d6b3b20SOliver Tappe 
801f633814SIngo Weinhold class PackageDataInlineReader : public BBufferDataReader {
810d6b3b20SOliver Tappe public:
821f633814SIngo Weinhold 	PackageDataInlineReader(const BPackageData& data)
830d6b3b20SOliver Tappe 		:
841f633814SIngo Weinhold 		BBufferDataReader(fData.InlineData(), data.Size()),
851f633814SIngo Weinhold 		fData(data)
860d6b3b20SOliver Tappe 	{
870d6b3b20SOliver Tappe 	}
880d6b3b20SOliver Tappe 
890d6b3b20SOliver Tappe private:
901f633814SIngo Weinhold 	BPackageData	fData;
910d6b3b20SOliver Tappe };
920d6b3b20SOliver Tappe 
930d6b3b20SOliver Tappe 
945fb1c6ffSOliver Tappe // #pragma mark - BPackageDataReaderFactory
950d6b3b20SOliver Tappe 
960d6b3b20SOliver Tappe 
971f633814SIngo Weinhold BPackageDataReaderFactory::BPackageDataReaderFactory()
980d6b3b20SOliver Tappe {
990d6b3b20SOliver Tappe }
1000d6b3b20SOliver Tappe 
1010d6b3b20SOliver Tappe 
1020d6b3b20SOliver Tappe status_t
1031f633814SIngo Weinhold BPackageDataReaderFactory::CreatePackageDataReader(
1041f633814SIngo Weinhold 	BAbstractBufferedDataReader* dataReader, const BPackageData& data,
1051f633814SIngo Weinhold 	BAbstractBufferedDataReader*& _reader)
1060d6b3b20SOliver Tappe {
1071f633814SIngo Weinhold 	BAbstractBufferedDataReader* reader;
1081f633814SIngo Weinhold 	if (data.IsEncodedInline())
1091f633814SIngo Weinhold 		reader = new(std::nothrow) PackageDataInlineReader(data);
1101f633814SIngo Weinhold 	else
1111f633814SIngo Weinhold 		reader = new(std::nothrow) PackageDataHeapReader(dataReader, data);
1120d6b3b20SOliver Tappe 
1130d6b3b20SOliver Tappe 	if (reader == NULL)
1140d6b3b20SOliver Tappe 		return B_NO_MEMORY;
1150d6b3b20SOliver Tappe 
1160d6b3b20SOliver Tappe 	_reader = reader;
1170d6b3b20SOliver Tappe 	return B_OK;
1180d6b3b20SOliver Tappe }
1190d6b3b20SOliver Tappe 
1200d6b3b20SOliver Tappe 
1215fb1c6ffSOliver Tappe }	// namespace BHPKG
1220d6b3b20SOliver Tappe 
1230d6b3b20SOliver Tappe }	// namespace BPackageKit
124