hrev47493 adds 6 changesets to branch 'master' old head: b916156a835cd4f1c16990c33d69190014df77b7 new head: e1e6c124809fae466b89b13ef1ecf87f8026d7fb overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=e1e6c12+%5Eb916156 ---------------------------------------------------------------------------- 44c4771: BPackageWriter: Add BPositionIO support 05b565f: Add private BDataPositionIOWrapper Implements the BPositionIO interface on top of a BDataIO, requiring the {Read,Write}At() accesses to be sequential. 1606450: ReaderImplBase::Init(): Make file size check optional If the file doesn't support GetSize(), skip the header total size file size check. 3cc6297: package recompress: Add stdin/stdout support stdin doesn't work quite yet. We'll need to convince the BPackageReader to skip parsing the TOC and package attributes sections. 43a6b92: PackageReaderImpl: Delay reading sections until ParseContent() e1e6c12: BPackageWriter::Recompress(): Change param to BPositionIO* Besides that this is a nicer interface, it allows us to get a the HPKG header as a side effect of initializing the reader, thus preventing seeking backward in the file. This makes "package recompress - <file>" work. [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- 19 files changed, 320 insertions(+), 86 deletions(-) .../private/support/DataPositionIOWrapper.h | 1 + headers/os/package/hpkg/PackageWriter.h | 12 ++- headers/private/package/hpkg/PackageReaderImpl.h | 2 + headers/private/package/hpkg/PackageWriterImpl.h | 10 +- headers/private/package/hpkg/ReaderImplBase.h | 15 ++- headers/private/package/hpkg/WriterImplBase.h | 4 +- headers/private/support/DataPositionIOWrapper.h | 37 +++++++ src/bin/package/Jamfile | 2 +- src/bin/package/command_recompress.cpp | 67 +++++++----- src/bin/package/package.cpp | 6 +- src/build/libbe/support/Jamfile | 1 + src/kits/package/hpkg/PackageReaderImpl.cpp | 38 ++++--- src/kits/package/hpkg/PackageWriter.cpp | 20 +++- src/kits/package/hpkg/PackageWriterImpl.cpp | 42 +++++--- src/kits/package/hpkg/RepositoryWriterImpl.cpp | 3 +- src/kits/package/hpkg/WriterImplBase.cpp | 40 ++++--- src/kits/support/DataPositionIOWrapper.cpp | 103 +++++++++++++++++++ src/kits/support/Jamfile | 1 + src/tools/package/Jamfile | 2 +- ############################################################################ Commit: 44c4771163b9166dc042f69cb5373c9de9e37006 URL: http://cgit.haiku-os.org/haiku/commit/?id=44c4771 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jul 12 22:30:25 2014 UTC BPackageWriter: Add BPositionIO support ---------------------------------------------------------------------------- diff --git a/headers/os/package/hpkg/PackageWriter.h b/headers/os/package/hpkg/PackageWriter.h index 32b6ee9..fccec4b 100644 --- a/headers/os/package/hpkg/PackageWriter.h +++ b/headers/os/package/hpkg/PackageWriter.h @@ -11,6 +11,9 @@ #include <package/hpkg/ErrorOutput.h> +class BPositionIO; + + namespace BPackageKit { namespace BHPKG { @@ -74,6 +77,9 @@ public: status_t Init(const char* fileName, const BPackageWriterParameters* parameters = NULL); + status_t Init(BPositionIO* file, bool keepFile, + const BPackageWriterParameters* parameters + = NULL); status_t SetInstallPath(const char* installPath); void SetCheckLicenses(bool checkLicenses); status_t AddEntry(const char* fileName, int fd = -1); diff --git a/headers/private/package/hpkg/PackageWriterImpl.h b/headers/private/package/hpkg/PackageWriterImpl.h index 1202783..35f3a47 100644 --- a/headers/private/package/hpkg/PackageWriterImpl.h +++ b/headers/private/package/hpkg/PackageWriterImpl.h @@ -49,6 +49,8 @@ public: status_t Init(const char* fileName, const BPackageWriterParameters& parameters); + status_t Init(BPositionIO* file, bool keepFile, + const BPackageWriterParameters& parameters); status_t SetInstallPath(const char* installPath); void SetCheckLicenses(bool checkLicenses); status_t AddEntry(const char* fileName, int fd = -1); @@ -67,7 +69,8 @@ private: typedef DoublyLinkedList<Entry> EntryList; private: - status_t _Init(const char* fileName, + status_t _Init(BPositionIO* file, bool keepFile, + const char* fileName, const BPackageWriterParameters& parameters); status_t _Finish(); diff --git a/headers/private/package/hpkg/WriterImplBase.h b/headers/private/package/hpkg/WriterImplBase.h index c4d975f..0533420 100644 --- a/headers/private/package/hpkg/WriterImplBase.h +++ b/headers/private/package/hpkg/WriterImplBase.h @@ -101,7 +101,8 @@ protected: typedef DoublyLinkedList<PackageAttribute> PackageAttributeList; protected: - status_t Init(const char* fileName, + status_t Init(BPositionIO* file, bool keepFile, + const char* fileName, const BPackageWriterParameters& parameters); status_t InitHeapReader(size_t headerSize); @@ -191,6 +192,7 @@ private: const char* fFileName; BPackageWriterParameters fParameters; BPositionIO* fFile; + bool fOwnsFile; bool fFinished; StringCache fPackageStringCache; diff --git a/src/kits/package/hpkg/PackageWriter.cpp b/src/kits/package/hpkg/PackageWriter.cpp index 69b2fe0..2a18a2e 100644 --- a/src/kits/package/hpkg/PackageWriter.cpp +++ b/src/kits/package/hpkg/PackageWriter.cpp @@ -108,6 +108,20 @@ BPackageWriter::Init(const char* fileName, status_t +BPackageWriter::Init(BPositionIO* file, bool keepFile, + const BPackageWriterParameters* parameters) +{ + if (fImpl == NULL) + return B_NO_MEMORY; + + BPackageWriterParameters defaultParameters; + + return fImpl->Init(file, keepFile, + parameters != NULL ? *parameters : defaultParameters); +} + + +status_t BPackageWriter::SetInstallPath(const char* installPath) { if (fImpl == NULL) diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index 3a15ced..a94c2a0 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -464,7 +464,22 @@ PackageWriterImpl::Init(const char* fileName, const BPackageWriterParameters& parameters) { try { - return _Init(fileName, parameters); + return _Init(NULL, false, fileName, parameters); + } catch (status_t error) { + return error; + } catch (std::bad_alloc) { + fListener->PrintError("Out of memory!\n"); + return B_NO_MEMORY; + } +} + + +status_t +PackageWriterImpl::Init(BPositionIO* file, bool keepFile, + const BPackageWriterParameters& parameters) +{ + try { + return _Init(file, keepFile, NULL, parameters); } catch (status_t error) { return error; } catch (std::bad_alloc) { @@ -624,10 +639,10 @@ PackageWriterImpl::Recompress(PackageReaderImpl* reader) status_t -PackageWriterImpl::_Init(const char* fileName, +PackageWriterImpl::_Init(BPositionIO* file, bool keepFile, const char* fileName, const BPackageWriterParameters& parameters) { - status_t result = inherited::Init(fileName, parameters); + status_t result = inherited::Init(file, keepFile, fileName, parameters); if (result != B_OK) return result; diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp b/src/kits/package/hpkg/RepositoryWriterImpl.cpp index cda6ff0..305d68c 100644 --- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp +++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp @@ -264,7 +264,8 @@ RepositoryWriterImpl::Finish() status_t RepositoryWriterImpl::_Init(const char* fileName) { - status_t error = inherited::Init(fileName, BPackageWriterParameters()); + status_t error = inherited::Init(NULL, false, fileName, + BPackageWriterParameters()); if (error != B_OK) return error; diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index 65d3016..7db79e1 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -228,6 +228,7 @@ WriterImplBase::WriterImplBase(const char* fileType, BErrorOutput* errorOutput) fFileName(NULL), fParameters(), fFile(NULL), + fOwnsFile(false), fFinished(false) { } @@ -241,7 +242,8 @@ WriterImplBase::~WriterImplBase() delete fDecompressionAlgorithm; delete fDecompressionParameters; - delete fFile; + if (fOwnsFile) + delete fFile; if (!fFinished && fFileName != NULL && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) { @@ -251,7 +253,7 @@ WriterImplBase::~WriterImplBase() status_t -WriterImplBase::Init(const char* fileName, +WriterImplBase::Init(BPositionIO* file, bool keepFile, const char* fileName, const BPackageWriterParameters& parameters) { fParameters = parameters; @@ -259,21 +261,31 @@ WriterImplBase::Init(const char* fileName, if (fPackageStringCache.Init() != B_OK) throw std::bad_alloc(); - // open file (don't truncate in update mode) - int openMode = O_RDWR; - if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) - openMode |= O_CREAT | O_TRUNC; + if (file == NULL) { + if (fileName == NULL) + return B_BAD_VALUE; - BFile* file = new BFile; - status_t error = file->SetTo(fileName, openMode); - if (error != B_OK) { - fErrorOutput->PrintError("Failed to open %s file \"%s\": %s\n", - fFileType, fileName, strerror(errno)); - delete file; - return error; + // open file (don't truncate in update mode) + int openMode = O_RDWR; + if ((parameters.Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) + openMode |= O_CREAT | O_TRUNC; + + BFile* newFile = new BFile; + status_t error = newFile->SetTo(fileName, openMode); + if (error != B_OK) { + fErrorOutput->PrintError("Failed to open %s file \"%s\": %s\n", + fFileType, fileName, strerror(errno)); + delete newFile; + return error; + } + + fFile = newFile; + fOwnsFile = true; + } else { + fFile = file; + fOwnsFile = keepFile; } - fFile = file; fFileName = fileName; return B_OK; ############################################################################ Commit: 05b565f4f25a8d0fd482a7697ded510c29630aab URL: http://cgit.haiku-os.org/haiku/commit/?id=05b565f Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jul 12 23:07:34 2014 UTC Add private BDataPositionIOWrapper Implements the BPositionIO interface on top of a BDataIO, requiring the {Read,Write}At() accesses to be sequential. ---------------------------------------------------------------------------- diff --git a/headers/build/private/support/DataPositionIOWrapper.h b/headers/build/private/support/DataPositionIOWrapper.h new file mode 100644 index 0000000..1f687c7 --- /dev/null +++ b/headers/build/private/support/DataPositionIOWrapper.h @@ -0,0 +1 @@ +#include <../private/support/DataPositionIOWrapper.h> diff --git a/headers/private/support/DataPositionIOWrapper.h b/headers/private/support/DataPositionIOWrapper.h new file mode 100644 index 0000000..03478e3 --- /dev/null +++ b/headers/private/support/DataPositionIOWrapper.h @@ -0,0 +1,37 @@ +/* + * Copyright 2014, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Distributed under the terms of the MIT License. + */ +#ifndef _DATA_POSITION_IO_WRAPPER_H_ +#define _DATA_POSITION_IO_WRAPPER_H_ + + +#include <DataIO.h> + + +class BDataPositionIOWrapper : public BPositionIO { +public: + BDataPositionIOWrapper(BDataIO* io); + ~BDataPositionIOWrapper(); + + virtual ssize_t Read(void* buffer, size_t size); + virtual ssize_t Write(const void* buffer, size_t size); + + virtual ssize_t ReadAt(off_t position, void* buffer, + size_t size); + virtual ssize_t WriteAt(off_t position, const void* buffer, + size_t size); + + virtual off_t Seek(off_t position, uint32 seekMode); + virtual off_t Position() const; + + virtual status_t SetSize(off_t size); + virtual status_t GetSize(off_t* size) const; + +private: + BDataIO* fIO; + off_t fPosition; +}; + + +#endif // _DATA_POSITION_IO_WRAPPER_H_ diff --git a/src/build/libbe/support/Jamfile b/src/build/libbe/support/Jamfile index 145c9ec..0b8bdad 100644 --- a/src/build/libbe/support/Jamfile +++ b/src/build/libbe/support/Jamfile @@ -12,6 +12,7 @@ BuildPlatformMergeObjectPIC <libbe_build>support_kit.o : ByteOrder.cpp CompressionAlgorithm.cpp DataIO.cpp + DataPositionIOWrapper.cpp Flattenable.cpp List.cpp Locker.cpp diff --git a/src/kits/support/DataPositionIOWrapper.cpp b/src/kits/support/DataPositionIOWrapper.cpp new file mode 100644 index 0000000..ea2312b --- /dev/null +++ b/src/kits/support/DataPositionIOWrapper.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2014, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Distributed under the terms of the MIT License. + */ + + +#include <DataPositionIOWrapper.h> + +#include <stdio.h> + + +BDataPositionIOWrapper::BDataPositionIOWrapper(BDataIO* io) + : + BPositionIO(), + fIO(io), + fPosition(0) +{ +} + + +BDataPositionIOWrapper::~BDataPositionIOWrapper() +{ +} + + +ssize_t +BDataPositionIOWrapper::Read(void* buffer, size_t size) +{ + ssize_t bytesRead = fIO->Read(buffer, size); + if (bytesRead > 0) + fPosition += bytesRead; + + return bytesRead; +} + + +ssize_t +BDataPositionIOWrapper::Write(const void* buffer, size_t size) +{ + ssize_t bytesWritten = fIO->Write(buffer, size); + if (bytesWritten > 0) + fPosition += bytesWritten; + + return bytesWritten; +} + + +ssize_t +BDataPositionIOWrapper::ReadAt(off_t position, void* buffer, size_t size) +{ + if (position != fPosition) + return B_NOT_SUPPORTED; + + return Read(buffer, size); +} + + +ssize_t +BDataPositionIOWrapper::WriteAt(off_t position, const void* buffer, + size_t size) +{ + if (position != fPosition) + return B_NOT_SUPPORTED; + + return Write(buffer, size); +} + + +off_t +BDataPositionIOWrapper::Seek(off_t position, uint32 seekMode) +{ + switch (seekMode) { + case SEEK_CUR: + return position == 0 ? B_OK : B_NOT_SUPPORTED; + case SEEK_SET: + return position == fPosition ? B_OK : B_NOT_SUPPORTED; + case SEEK_END: + return B_NOT_SUPPORTED; + default: + return B_BAD_VALUE; + } +} + + +off_t +BDataPositionIOWrapper::Position() const +{ + return fPosition; +} + + +status_t +BDataPositionIOWrapper::SetSize(off_t size) +{ + return size == fPosition ? B_OK : B_NOT_SUPPORTED; +} + + +status_t +BDataPositionIOWrapper::GetSize(off_t* size) const +{ + return B_NOT_SUPPORTED; +} diff --git a/src/kits/support/Jamfile b/src/kits/support/Jamfile index 43007f4..76b3d5e 100644 --- a/src/kits/support/Jamfile +++ b/src/kits/support/Jamfile @@ -26,6 +26,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { ByteOrder.cpp CompressionAlgorithm.cpp DataIO.cpp + DataPositionIOWrapper.cpp DateTime.cpp Flattenable.cpp List.cpp ############################################################################ Commit: 1606450b3215f4644aced4e37b01b84e2d5dd718 URL: http://cgit.haiku-os.org/haiku/commit/?id=1606450 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jul 12 23:08:53 2014 UTC ReaderImplBase::Init(): Make file size check optional If the file doesn't support GetSize(), skip the header total size file size check. ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index e6f1314..1341a6e 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -439,9 +439,16 @@ ReaderImplBase::Init(BPositionIO* file, bool keepFile, Header& header, uint32 fl off_t fileSize; error = fFile->GetSize(&fileSize); if (error != B_OK) { - ErrorOutput()->PrintError("Error: Failed to get size of %s file: %s\n", - fFileType, strerror(error)); - return errno; + if (error != B_NOT_SUPPORTED) { + ErrorOutput()->PrintError( + "Error: Failed to get size of %s file: %s\n", + fFileType, strerror(error)); + return error; + } + + // Might be a stream. We only use the file size for checking the total + // heap size, which we don't have to do. + fileSize = -1; } // read the header @@ -480,7 +487,7 @@ ReaderImplBase::Init(BPositionIO* file, bool keepFile, Header& header, uint32 fl // total size uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size); - if (totalSize != (uint64)fileSize) { + if (fileSize >= 0 && totalSize != (uint64)fileSize) { ErrorOutput()->PrintError("Error: Invalid %s file: Total size in " "header (%" B_PRIu64 ") doesn't agree with total file size (%" B_PRIdOFF ")\n", fFileType, totalSize, fileSize); ############################################################################ Commit: 3cc6297e22bc7d945612e50906c78326119b2e62 URL: http://cgit.haiku-os.org/haiku/commit/?id=3cc6297 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sat Jul 12 23:10:35 2014 UTC package recompress: Add stdin/stdout support stdin doesn't work quite yet. We'll need to convince the BPackageReader to skip parsing the TOC and package attributes sections. ---------------------------------------------------------------------------- diff --git a/src/bin/package/Jamfile b/src/bin/package/Jamfile index 111b2de..bc4acc6 100644 --- a/src/bin/package/Jamfile +++ b/src/bin/package/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src bin package ; -UsePrivateHeaders kernel shared ; +UsePrivateHeaders kernel shared storage support ; BinCommand package : command_add.cpp diff --git a/src/bin/package/command_recompress.cpp b/src/bin/package/command_recompress.cpp index 978d3a2..370543f 100644 --- a/src/bin/package/command_recompress.cpp +++ b/src/bin/package/command_recompress.cpp @@ -16,6 +16,9 @@ #include <package/hpkg/PackageReader.h> #include <package/hpkg/PackageWriter.h> +#include <FdIO.h> +#include <DataPositionIOWrapper.h> + #include "package.h" #include "PackageWriterListener.h" @@ -26,6 +29,14 @@ using BPackageKit::BHPKG::BPackageWriterListener; using BPackageKit::BHPKG::BPackageWriterParameters; +static BPositionIO* +create_stdio(bool isInput) +{ + BFdIO* dataIO = new BFdIO(isInput ? 0 : 1, false); + return new BDataPositionIOWrapper(dataIO); +} + + int command_recompress(int argc, const char* const* argv) { @@ -79,32 +90,23 @@ command_recompress(int argc, const char* const* argv) } } - // The remaining arguments are the input package file and optionally the - // output package file, i.e. one or two more arguments. - if (argc - optind < 1 || argc - optind > 2) + // The remaining arguments are the input package file and the output + // package file, i.e. two more arguments. + if (argc - optind != 2) print_usage_and_exit(true); const char* inputPackageFileName = argv[optind++]; - const char* outputPackageFileName = optind < argc ? argv[optind++] : NULL; - - // If compression is used, an output file is required. - if (compressionLevel != 0 && outputPackageFileName == NULL) { - fprintf(stderr, "Error: Writing to stdout is supported only with " - "compression level 0.\n"); - return 1; - } - - // TODO: Implement streaming support! - if (outputPackageFileName == NULL) { - fprintf(stderr, "Error: Writing to stdout is not supported yet.\n"); - return 1; - } + const char* outputPackageFileName = argv[optind++]; // open the input package PackageWriterListener listener(verbose, quiet); BPackageReader packageReader(&listener); - status_t error = packageReader.Init(inputPackageFileName); + status_t error; + if (strcmp(inputPackageFileName, "-") == 0) + error = packageReader.Init(create_stdio(true), true); + else + error = packageReader.Init(inputPackageFileName); if (error != B_OK) return 1; @@ -117,7 +119,17 @@ command_recompress(int argc, const char* const* argv) } BPackageWriter packageWriter(&listener); - error = packageWriter.Init(outputPackageFileName, &writerParameters); + if (strcmp(outputPackageFileName, "-") == 0) { + if (compressionLevel != 0) { + fprintf(stderr, "Error: Writing to stdout is supported only with " + "compression level 0.\n"); + return 1; + } + + error = packageWriter.Init(create_stdio(false), true, + &writerParameters); + } else + error = packageWriter.Init(outputPackageFileName, &writerParameters); if (error != B_OK) return 1; diff --git a/src/bin/package/package.cpp b/src/bin/package/package.cpp index 6bcab5c..5d8c90d 100644 --- a/src/bin/package/package.cpp +++ b/src/bin/package/package.cpp @@ -96,12 +96,14 @@ static const char* kUsage = " -i - Only print the meta information, not the files.\n" " -p - Only print a list of file paths.\n" "\n" - " recompress [ <options> ] <input package> [ <output package> ]\n" + " recompress [ <options> ] <input package> <output package>\n" " Reads the package file <input package> and writes it to new package\n" " <output package> using the specified compression options. If the\n" " compression level 0 is specified (i.e. no compression), " "<output package>\n" - " can be omitted, in which case the data are written to stdout.\n" + " can be \"-\", in which case the data are written to stdout.\n" + " If the input files doesn't use compression <input package>\n" + " can be \"-\", in which case the data are read from stdin.\n" "\n" " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best " "compression.\n" diff --git a/src/tools/package/Jamfile b/src/tools/package/Jamfile index 891bf6d..5764329 100644 --- a/src/tools/package/Jamfile +++ b/src/tools/package/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src tools package ; -UsePrivateBuildHeaders shared kernel ; +UsePrivateBuildHeaders shared kernel storage support ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin package ] ; ############################################################################ Commit: 43a6b92c6424ae5976e467571e6edd7e60354110 URL: http://cgit.haiku-os.org/haiku/commit/?id=43a6b92 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jul 13 15:52:13 2014 UTC PackageReaderImpl: Delay reading sections until ParseContent() ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/PackageReaderImpl.h b/headers/private/package/hpkg/PackageReaderImpl.h index 37cdb34..1219912 100644 --- a/headers/private/package/hpkg/PackageReaderImpl.h +++ b/headers/private/package/hpkg/PackageReaderImpl.h @@ -67,6 +67,8 @@ private: friend class PackageWriterImpl; private: + status_t _PrepareSections(); + status_t _ParseTOC(AttributeHandlerContext* context, AttributeHandler* rootAttributeHandler); diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp b/src/kits/package/hpkg/PackageReaderImpl.cpp index 1ff2bf2..ac04ccd 100644 --- a/src/kits/package/hpkg/PackageReaderImpl.cpp +++ b/src/kits/package/hpkg/PackageReaderImpl.cpp @@ -373,15 +373,6 @@ PackageReaderImpl::Init(BPositionIO* file, bool keepFile, uint32 flags, if (error != B_OK) return error; - // prepare the sections for use - error = PrepareSection(fTOCSection); - if (error != B_OK) - return error; - - error = PrepareSection(fPackageAttributesSection); - if (error != B_OK) - return error; - if (_header != NULL) *_header = header; @@ -392,13 +383,16 @@ PackageReaderImpl::Init(BPositionIO* file, bool keepFile, uint32 flags, status_t PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler) { + status_t error = _PrepareSections(); + if (error != B_OK) + return error; + AttributeHandlerContext context(ErrorOutput(), contentHandler, B_HPKG_SECTION_PACKAGE_ATTRIBUTES, MinorFormatVersion() > B_HPKG_MINOR_VERSION); RootAttributeHandler rootAttributeHandler; - status_t error - = ParsePackageAttributesSection(&context, &rootAttributeHandler); + error = ParsePackageAttributesSection(&context, &rootAttributeHandler); if (error == B_OK) { context.section = B_HPKG_SECTION_PACKAGE_TOC; @@ -412,13 +406,16 @@ PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler) status_t PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler) { + status_t error = _PrepareSections(); + if (error != B_OK) + return error; + AttributeHandlerContext context(ErrorOutput(), contentHandler, B_HPKG_SECTION_PACKAGE_ATTRIBUTES, MinorFormatVersion() > B_HPKG_MINOR_VERSION); LowLevelAttributeHandler rootAttributeHandler; - status_t error - = ParsePackageAttributesSection(&context, &rootAttributeHandler); + error = ParsePackageAttributesSection(&context, &rootAttributeHandler); if (error == B_OK) { context.section = B_HPKG_SECTION_PACKAGE_TOC; @@ -430,6 +427,21 @@ PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler) status_t +PackageReaderImpl::_PrepareSections() +{ + status_t error = PrepareSection(fTOCSection); + if (error != B_OK) + return error; + + error = PrepareSection(fPackageAttributesSection); + if (error != B_OK) + return error; + + return B_OK; +} + + +status_t PackageReaderImpl::_ParseTOC(AttributeHandlerContext* context, AttributeHandler* rootAttributeHandler) { ############################################################################ Revision: hrev47493 Commit: e1e6c124809fae466b89b13ef1ecf87f8026d7fb URL: http://cgit.haiku-os.org/haiku/commit/?id=e1e6c12 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Jul 13 15:56:57 2014 UTC BPackageWriter::Recompress(): Change param to BPositionIO* Besides that this is a nicer interface, it allows us to get a the HPKG header as a side effect of initializing the reader, thus preventing seeking backward in the file. This makes "package recompress - <file>" work. ---------------------------------------------------------------------------- diff --git a/headers/os/package/hpkg/PackageWriter.h b/headers/os/package/hpkg/PackageWriter.h index fccec4b..b57a042 100644 --- a/headers/os/package/hpkg/PackageWriter.h +++ b/headers/os/package/hpkg/PackageWriter.h @@ -18,10 +18,6 @@ namespace BPackageKit { namespace BHPKG { - -class BPackageReader; - - namespace BPrivate { class PackageWriterImpl; } @@ -85,7 +81,7 @@ public: status_t AddEntry(const char* fileName, int fd = -1); status_t Finish(); - status_t Recompress(BPackageReader* reader); + status_t Recompress(BPositionIO* inputFile); // to be called after Init(); no Finish() private: diff --git a/headers/private/package/hpkg/PackageWriterImpl.h b/headers/private/package/hpkg/PackageWriterImpl.h index 35f3a47..c68b06d 100644 --- a/headers/private/package/hpkg/PackageWriterImpl.h +++ b/headers/private/package/hpkg/PackageWriterImpl.h @@ -35,7 +35,6 @@ class BPackageWriterParameters; namespace BPrivate { -class PackageReaderImpl; struct hpkg_header; @@ -56,7 +55,7 @@ public: status_t AddEntry(const char* fileName, int fd = -1); status_t Finish(); - status_t Recompress(PackageReaderImpl* reader); + status_t Recompress(BPositionIO* inputFile); // to be called after Init(); no Finish() private: @@ -74,7 +73,7 @@ private: const BPackageWriterParameters& parameters); status_t _Finish(); - status_t _Recompress(PackageReaderImpl* reader); + status_t _Recompress(BPositionIO* inputFile); status_t _RegisterEntry(const char* fileName, int fd); Entry* _RegisterEntry(Entry* parent, diff --git a/src/bin/package/command_recompress.cpp b/src/bin/package/command_recompress.cpp index 370543f..4452d1c 100644 --- a/src/bin/package/command_recompress.cpp +++ b/src/bin/package/command_recompress.cpp @@ -12,6 +12,8 @@ #include <string.h> #include <unistd.h> +#include <File.h> + #include <package/hpkg/HPKGDefs.h> #include <package/hpkg/PackageReader.h> #include <package/hpkg/PackageWriter.h> @@ -99,14 +101,20 @@ command_recompress(int argc, const char* const* argv) const char* outputPackageFileName = argv[optind++]; // open the input package - PackageWriterListener listener(verbose, quiet); - - BPackageReader packageReader(&listener); - status_t error; - if (strcmp(inputPackageFileName, "-") == 0) - error = packageReader.Init(create_stdio(true), true); - else - error = packageReader.Init(inputPackageFileName); + status_t error = B_OK; + BPositionIO* inputFile; + if (strcmp(inputPackageFileName, "-") == 0) { + inputFile = create_stdio(true); + } else { + BFile* inputFileFile = new BFile; + error = inputFileFile->SetTo(inputPackageFileName, O_RDONLY); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n", + inputPackageFileName, strerror(error)); + return 1; + } + inputFile = inputFileFile; + } if (error != B_OK) return 1; @@ -118,6 +126,7 @@ command_recompress(int argc, const char* const* argv) BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE); } + PackageWriterListener listener(verbose, quiet); BPackageWriter packageWriter(&listener); if (strcmp(outputPackageFileName, "-") == 0) { if (compressionLevel != 0) { @@ -133,7 +142,7 @@ command_recompress(int argc, const char* const* argv) if (error != B_OK) return 1; - error = packageWriter.Recompress(&packageReader); + error = packageWriter.Recompress(inputFile); if (error != B_OK) return 1; diff --git a/src/kits/package/hpkg/PackageWriter.cpp b/src/kits/package/hpkg/PackageWriter.cpp index 2a18a2e..29f1d6e 100644 --- a/src/kits/package/hpkg/PackageWriter.cpp +++ b/src/kits/package/hpkg/PackageWriter.cpp @@ -8,8 +8,6 @@ #include <new> -#include <package/hpkg/PackageReader.h> - #include <package/hpkg/PackageWriterImpl.h> @@ -160,12 +158,12 @@ BPackageWriter::Finish() status_t -BPackageWriter::Recompress(BPackageReader* reader) +BPackageWriter::Recompress(BPositionIO* inputFile) { if (fImpl == NULL) return B_NO_INIT; - return fImpl->Recompress(reader->fImpl); + return fImpl->Recompress(inputFile); } diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index a94c2a0..9ba1d42 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -622,13 +622,13 @@ PackageWriterImpl::Finish() status_t -PackageWriterImpl::Recompress(PackageReaderImpl* reader) +PackageWriterImpl::Recompress(BPositionIO* inputFile) { - if (reader == NULL) + if (inputFile == NULL) return B_BAD_VALUE; try { - return _Recompress(reader); + return _Recompress(inputFile); } catch (status_t error) { return error; } catch (std::bad_alloc) { @@ -772,16 +772,17 @@ PackageWriterImpl::_Finish() status_t -PackageWriterImpl::_Recompress(PackageReaderImpl* reader) +PackageWriterImpl::_Recompress(BPositionIO* inputFile) { - if (reader == NULL) + if (inputFile == NULL) return B_BAD_VALUE; - // read the header + // create a package reader for the input file + PackageReaderImpl reader(fListener); hpkg_header header; - status_t error = reader->ReadBuffer(0, &header, sizeof(header)); + status_t error = reader.Init(inputFile, false, 0, &header); if (error != B_OK) { - fListener->PrintError("Failed to reader hpkg header: %s\n", + fListener->PrintError("Failed to open hpkg file: %s\n", strerror(error)); return error; } @@ -790,7 +791,7 @@ PackageWriterImpl::_Recompress(PackageReaderImpl* reader) // header later, should compression have been used. Doing it this way allows // for streaming an uncompressed package. uint64 uncompressedHeapSize - = reader->RawHeapReader()->UncompressedHeapSize(); + = reader.RawHeapReader()->UncompressedHeapSize(); uint64 compressedHeapSize = uncompressedHeapSize; off_t totalSize = fHeapWriter->HeapOffset() + (off_t)compressedHeapSize; @@ -812,7 +813,7 @@ PackageWriterImpl::_Recompress(PackageReaderImpl* reader) // copy the heap data uint64 bytesCompressed; - error = fHeapWriter->AddData(*reader->RawHeapReader(), uncompressedHeapSize, + error = fHeapWriter->AddData(*reader.RawHeapReader(), uncompressedHeapSize, bytesCompressed); if (error != B_OK) return error;