[haiku-commits] haiku: hrev47493 - src/kits/package/hpkg src/bin/package src/kits/support headers/private/package/hpkg headers/private/support

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 13 Jul 2014 17:58:17 +0200 (CEST)

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;


Other related posts:

  • » [haiku-commits] haiku: hrev47493 - src/kits/package/hpkg src/bin/package src/kits/support headers/private/package/hpkg headers/private/support - ingo_weinhold