WriterImplBase.h revision 44c47711
1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
6#define _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
7
8
9#include <util/DoublyLinkedList.h>
10
11#include <package/hpkg/HPKGDefsPrivate.h>
12
13#include <package/hpkg/PackageWriter.h>
14#include <package/hpkg/Strings.h>
15
16#include <package/PackageInfo.h>
17
18#include <package/hpkg/PackageFileHeapWriter.h>
19
20
21class BCompressionAlgorithm;
22class BCompressionParameters;
23class BDecompressionParameters;
24
25
26namespace BPackageKit {
27
28namespace BHPKG {
29
30
31class BDataReader;
32class BErrorOutput;
33
34
35namespace BPrivate {
36
37
38struct hpkg_header;
39
40
41class WriterImplBase {
42public:
43								WriterImplBase(const char* fileType,
44									BErrorOutput* errorOutput);
45								~WriterImplBase();
46
47protected:
48			struct AttributeValue {
49				union {
50					int64			signedInt;
51					uint64			unsignedInt;
52					CachedString*	string;
53					struct {
54						uint64		size;
55						union {
56							uint64	offset;
57							uint8	raw[B_HPKG_MAX_INLINE_DATA_SIZE];
58						};
59					} data;
60				};
61				uint8		type;
62				int8		encoding;
63
64				AttributeValue();
65				~AttributeValue();
66
67				void SetTo(int8 value);
68				void SetTo(uint8 value);
69				void SetTo(int16 value);
70				void SetTo(uint16 value);
71				void SetTo(int32 value);
72				void SetTo(uint32 value);
73				void SetTo(int64 value);
74				void SetTo(uint64 value);
75				void SetTo(CachedString* value);
76				void SetToData(uint64 size, uint64 offset);
77				void SetToData(uint64 size, const void* rawData);
78				uint8 ApplicableEncoding() const;
79
80			private:
81				static uint8 _ApplicableIntEncoding(uint64 value);
82			};
83
84
85			struct PackageAttribute :
86					public DoublyLinkedListLinkImpl<PackageAttribute>,
87					public AttributeValue {
88				BHPKGAttributeID 					id;
89				DoublyLinkedList<PackageAttribute>	children;
90
91				PackageAttribute(BHPKGAttributeID id_, uint8 type,
92					uint8 encoding);
93				~PackageAttribute();
94
95				void AddChild(PackageAttribute* child);
96
97			private:
98				void _DeleteChildren();
99			};
100
101			typedef DoublyLinkedList<PackageAttribute> PackageAttributeList;
102
103protected:
104			status_t			Init(BPositionIO* file, bool keepFile,
105									const char* fileName,
106									const BPackageWriterParameters& parameters);
107			status_t			InitHeapReader(size_t headerSize);
108
109			void				SetCompression(uint32 compression);
110
111			void				RegisterPackageInfo(
112									PackageAttributeList& attributeList,
113									const BPackageInfo& packageInfo);
114			void				RegisterPackageVersion(
115									PackageAttributeList& attributeList,
116									const BPackageVersion& version,
117									BHPKGAttributeID attributeID
118										= kDefaultVersionAttributeID);
119			void				RegisterPackageResolvableExpressionList(
120									PackageAttributeList& attributeList,
121									const BObjectList<
122										BPackageResolvableExpression>& list,
123									uint8 id);
124
125			PackageAttribute*	AddStringAttribute(BHPKGAttributeID id,
126									const BString& value,
127									DoublyLinkedList<PackageAttribute>& list);
128
129			int32				WriteCachedStrings(const StringCache& cache,
130									uint32 minUsageCount);
131
132			int32				WritePackageAttributes(
133									const PackageAttributeList& attributes,
134									uint32& _stringsLengthUncompressed);
135			void				WritePackageVersion(
136									const BPackageVersion& version);
137			void				WritePackageResolvableExpressionList(
138									const BObjectList<
139										BPackageResolvableExpression>& list,
140									uint8 id);
141
142			void				WriteAttributeValue(const AttributeValue& value,
143									uint8 encoding);
144			void				WriteUnsignedLEB128(uint64 value);
145
146	template<typename Type>
147	inline	void				Write(const Type& value);
148	inline	void				WriteString(const char* string);
149	inline	void				WriteBuffer(const void* data, size_t size);
150									// appends data to the heap
151
152			void				RawWriteBuffer(const void* buffer, size_t size,
153									off_t offset);
154									// writes to the file directly
155
156	inline	BPositionIO*		File() const;
157	inline	uint32				Flags() const;
158	inline	const BPackageWriterParameters& Parameters() const;
159
160	inline	const PackageAttributeList&	PackageAttributes() const;
161	inline	PackageAttributeList&	PackageAttributes();
162
163	inline	const StringCache&	PackageStringCache() const;
164	inline	StringCache&		PackageStringCache();
165
166	inline	void				SetFinished(bool finished);
167
168protected:
169			PackageFileHeapWriter* fHeapWriter;
170			BCompressionAlgorithm* fCompressionAlgorithm;
171			BCompressionParameters* fCompressionParameters;
172			BCompressionAlgorithm* fDecompressionAlgorithm;
173			BDecompressionParameters* fDecompressionParameters;
174
175private:
176	static const BHPKGAttributeID kDefaultVersionAttributeID
177		= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
178
179private:
180	inline	PackageAttribute*	_AddStringAttributeIfNotEmpty(
181									BHPKGAttributeID id, const BString& value,
182									DoublyLinkedList<PackageAttribute>& list);
183			void				_AddStringAttributeList(BHPKGAttributeID id,
184									const BStringList& value,
185									DoublyLinkedList<PackageAttribute>& list);
186			void				_WritePackageAttributes(
187									const PackageAttributeList& attributes);
188
189private:
190			const char*			fFileType;
191			BErrorOutput*		fErrorOutput;
192			const char*			fFileName;
193			BPackageWriterParameters fParameters;
194			BPositionIO*		fFile;
195			bool				fOwnsFile;
196			bool				fFinished;
197
198			StringCache			fPackageStringCache;
199			PackageAttributeList	fPackageAttributes;
200};
201
202
203template<typename Type>
204inline void
205WriterImplBase::Write(const Type& value)
206{
207	WriteBuffer(&value, sizeof(Type));
208}
209
210
211inline void
212WriterImplBase::WriteString(const char* string)
213{
214	WriteBuffer(string, strlen(string) + 1);
215}
216
217
218inline void
219WriterImplBase::WriteBuffer(const void* data, size_t size)
220{
221	fHeapWriter->AddDataThrows(data, size);
222}
223
224
225inline BPositionIO*
226WriterImplBase::File() const
227{
228	return fFile;
229}
230
231
232inline uint32
233WriterImplBase::Flags() const
234{
235	return fParameters.Flags();
236}
237
238
239inline const BPackageWriterParameters&
240WriterImplBase::Parameters() const
241{
242	return fParameters;
243}
244
245
246inline const WriterImplBase::PackageAttributeList&
247WriterImplBase::PackageAttributes() const
248{
249	return fPackageAttributes;
250}
251
252
253inline WriterImplBase::PackageAttributeList&
254WriterImplBase::PackageAttributes()
255{
256	return fPackageAttributes;
257}
258
259
260inline const StringCache&
261WriterImplBase::PackageStringCache() const
262{
263	return fPackageStringCache;
264}
265
266
267inline StringCache&
268WriterImplBase::PackageStringCache()
269{
270	return fPackageStringCache;
271}
272
273
274inline void
275WriterImplBase::SetFinished(bool finished)
276{
277	fFinished = finished;
278}
279
280
281inline WriterImplBase::PackageAttribute*
282WriterImplBase::_AddStringAttributeIfNotEmpty(BHPKGAttributeID id,
283	const BString& value, DoublyLinkedList<PackageAttribute>& list)
284{
285	if (value.IsEmpty())
286		return NULL;
287	return AddStringAttribute(id, value, list);
288}
289
290
291}	// namespace BPrivate
292
293}	// namespace BHPKG
294
295}	// namespace BPackageKit
296
297
298#endif	// _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
299