2 * Copyright 2013-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
5 #ifndef _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_ACCESSOR_BASE_H_
6 #define _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_ACCESSOR_BASE_H_
11 #include <Referenceable.h>
13 #include <CompressionAlgorithm.h>
14 #include <package/hpkg/DataReader.h>
17 namespace BPackageKit
{
28 template<typename Parameters
>
29 struct GenericCompressionAlgorithmOwner
: BReferenceable
{
30 BCompressionAlgorithm
* algorithm
;
31 Parameters
* parameters
;
33 GenericCompressionAlgorithmOwner(BCompressionAlgorithm
* algorithm
,
34 Parameters
* parameters
)
37 parameters(parameters
)
41 ~GenericCompressionAlgorithmOwner()
47 static GenericCompressionAlgorithmOwner
* Create(
48 BCompressionAlgorithm
* algorithm
, Parameters
* parameters
)
50 GenericCompressionAlgorithmOwner
* owner
51 = new(std::nothrow
) GenericCompressionAlgorithmOwner(algorithm
,
62 typedef GenericCompressionAlgorithmOwner
<BCompressionParameters
>
63 CompressionAlgorithmOwner
;
64 typedef GenericCompressionAlgorithmOwner
<BDecompressionParameters
>
65 DecompressionAlgorithmOwner
;
68 class PackageFileHeapAccessorBase
: public BAbstractBufferedDataReader
{
73 PackageFileHeapAccessorBase(
74 BErrorOutput
* errorOutput
,
75 BPositionIO
* file
, off_t heapOffset
,
76 DecompressionAlgorithmOwner
*
77 decompressionAlgorithm
);
78 virtual ~PackageFileHeapAccessorBase();
80 off_t
HeapOffset() const
81 { return fHeapOffset
; }
82 off_t
CompressedHeapSize() const
83 { return fCompressedHeapSize
; }
84 uint64
UncompressedHeapSize() const
85 { return fUncompressedHeapSize
; }
86 size_t ChunkSize() const
87 { return kChunkSize
; }
89 // normally used after cloning a PackageFileHeapReader only
90 void SetErrorOutput(BErrorOutput
* errorOutput
)
91 { fErrorOutput
= errorOutput
; }
92 void SetFile(BPositionIO
* file
)
95 // BAbstractBufferedDataReader
96 virtual status_t
ReadDataToOutput(off_t offset
,
97 size_t size
, BDataIO
* output
);
100 static const size_t kChunkSize
= 64 * 1024;
103 virtual status_t
ReadAndDecompressChunk(size_t chunkIndex
,
104 void* compressedDataBuffer
,
105 void* uncompressedDataBuffer
) = 0;
106 status_t
ReadAndDecompressChunkData(uint64 offset
,
107 size_t compressedSize
,
108 size_t uncompressedSize
,
109 void* compressedDataBuffer
,
110 void* uncompressedDataBuffer
);
111 status_t
DecompressChunkData(
112 void* compressedDataBuffer
,
113 size_t compressedSize
,
114 void* uncompressedDataBuffer
,
115 size_t uncompressedSize
);
116 status_t
ReadFileData(uint64 offset
, void* buffer
,
120 BErrorOutput
* fErrorOutput
;
123 uint64 fCompressedHeapSize
;
124 uint64 fUncompressedHeapSize
;
125 DecompressionAlgorithmOwner
* fDecompressionAlgorithm
;
129 /*! Stores the chunk offsets in a compact way, while still providing quick
131 - The object doesn't store the number of chunks/offsets it contains. During
132 initialization the chunk count is provided. Later, when getting an offset,
133 the caller is responsible for ensuring a valid index.
134 - The first (index 0) chunk offset is omitted, since it is always 0.
135 - The chunk offsets that fit in a 32 bit number use only one 32 bit element
136 in the offsets array.
137 - The chunk offsets that don't fit in a 32 bit number use two elements in
139 Memory use is one pointer, if the chunk count is <= 1 (uncompressed heap size
140 <= 64 KiB). Afterwards it's one pointer plus 32 bit per chunk as long as the
141 last offset still fits 32 bit (compressed heap size < 4GiB). For any further
142 chunks it is 64 bit per chunk. So, for the common case we use sizeof(void*)
143 plus 1 KiB per 16 MiB of uncompressed heap, or about 64 KiB per 1 GiB. Which
144 seems reasonable for packagefs to keep in memory.
146 class PackageFileHeapAccessorBase::OffsetArray
{
151 bool InitUncompressedChunksOffsets(
152 size_t totalChunkCount
);
153 bool InitChunksOffsets(size_t totalChunkCount
,
154 size_t baseIndex
, const uint16
* chunkSizes
,
157 bool Init(size_t totalChunkCount
,
158 const OffsetArray
& other
);
161 uint64
operator[](size_t index
) const;
164 static uint32
* _AllocateOffsetArray(size_t totalChunkCount
,
165 size_t offset32BitChunkCount
);
169 // - NULL, if chunkCount <= 1
170 // - element 0 contains the number of 32 bit
171 // offsets that follow, or is 0, when all
172 // offsets are 32 bit only
173 // - the following offsets use two elements
174 // each (lower followed by upper 32 bit)
175 // to represent the 64 bit value
180 PackageFileHeapAccessorBase::OffsetArray::operator[](size_t index
) const
185 if (fOffsets
[0] == 0 || index
< fOffsets
[0])
186 return fOffsets
[index
];
188 index
+= index
- fOffsets
[0];
189 return fOffsets
[index
] | ((uint64
)fOffsets
[index
+ 1] << 32);
193 } // namespace BPrivate
197 } // namespace BPackageKit
200 #endif // _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_ACCESSOR_BASE_H_