WriterImplBase.h revision e527b796
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(const char* fileName, size_t headerSize,
105									const BPackageWriterParameters& parameters);
106
107			void				RegisterPackageInfo(
108									PackageAttributeList& attributeList,
109									const BPackageInfo& packageInfo);
110			void				RegisterPackageVersion(
111									PackageAttributeList& attributeList,
112									const BPackageVersion& version,
113									BHPKGAttributeID attributeID
114										= kDefaultVersionAttributeID);
115			void				RegisterPackageResolvableExpressionList(
116									PackageAttributeList& attributeList,
117									const BObjectList<
118										BPackageResolvableExpression>& list,
119									uint8 id);
120
121			PackageAttribute*	AddStringAttribute(BHPKGAttributeID id,
122									const BString& value,
123									DoublyLinkedList<PackageAttribute>& list);
124
125			int32				WriteCachedStrings(const StringCache& cache,
126									uint32 minUsageCount);
127
128			int32				WritePackageAttributes(
129									const PackageAttributeList& attributes,
130									uint32& _stringsLengthUncompressed);
131			void				WritePackageVersion(
132									const BPackageVersion& version);
133			void				WritePackageResolvableExpressionList(
134									const BObjectList<
135										BPackageResolvableExpression>& list,
136									uint8 id);
137
138			void				WriteAttributeValue(const AttributeValue& value,
139									uint8 encoding);
140			void				WriteUnsignedLEB128(uint64 value);
141
142	template<typename Type>
143	inline	void				Write(const Type& value);
144	inline	void				WriteString(const char* string);
145	inline	void				WriteBuffer(const void* data, size_t size);
146									// appends data to the heap
147
148			void				RawWriteBuffer(const void* buffer, size_t size,
149									off_t offset);
150									// writes to the file directly
151
152	inline	BPositionIO*		File() const;
153	inline	uint32				Flags() const;
154	inline	const BPackageWriterParameters& Parameters() const;
155
156	inline	const PackageAttributeList&	PackageAttributes() const;
157	inline	PackageAttributeList&	PackageAttributes();
158
159	inline	const StringCache&	PackageStringCache() const;
160	inline	StringCache&		PackageStringCache();
161
162	inline	void				SetFinished(bool finished);
163
164protected:
165			PackageFileHeapWriter* fHeapWriter;
166			BCompressionAlgorithm* fCompressionAlgorithm;
167			BCompressionParameters* fCompressionParameters;
168			BCompressionAlgorithm* fDecompressionAlgorithm;
169			BDecompressionParameters* fDecompressionParameters;
170
171private:
172	static const BHPKGAttributeID kDefaultVersionAttributeID
173		= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
174
175private:
176	inline	PackageAttribute*	_AddStringAttributeIfNotEmpty(
177									BHPKGAttributeID id, const BString& value,
178									DoublyLinkedList<PackageAttribute>& list);
179			void				_AddStringAttributeList(BHPKGAttributeID id,
180									const BStringList& value,
181									DoublyLinkedList<PackageAttribute>& list);
182			void				_WritePackageAttributes(
183									const PackageAttributeList& attributes);
184
185private:
186			const char*			fFileType;
187			BErrorOutput*		fErrorOutput;
188			const char*			fFileName;
189			BPackageWriterParameters fParameters;
190			BPositionIO*		fFile;
191			bool				fFinished;
192
193			StringCache			fPackageStringCache;
194			PackageAttributeList	fPackageAttributes;
195};
196
197
198template<typename Type>
199inline void
200WriterImplBase::Write(const Type& value)
201{
202	WriteBuffer(&value, sizeof(Type));
203}
204
205
206inline void
207WriterImplBase::WriteString(const char* string)
208{
209	WriteBuffer(string, strlen(string) + 1);
210}
211
212
213inline void
214WriterImplBase::WriteBuffer(const void* data, size_t size)
215{
216	fHeapWriter->AddDataThrows(data, size);
217}
218
219
220inline BPositionIO*
221WriterImplBase::File() const
222{
223	return fFile;
224}
225
226
227inline uint32
228WriterImplBase::Flags() const
229{
230	return fParameters.Flags();
231}
232
233
234inline const BPackageWriterParameters&
235WriterImplBase::Parameters() const
236{
237	return fParameters;
238}
239
240
241inline const WriterImplBase::PackageAttributeList&
242WriterImplBase::PackageAttributes() const
243{
244	return fPackageAttributes;
245}
246
247
248inline WriterImplBase::PackageAttributeList&
249WriterImplBase::PackageAttributes()
250{
251	return fPackageAttributes;
252}
253
254
255inline const StringCache&
256WriterImplBase::PackageStringCache() const
257{
258	return fPackageStringCache;
259}
260
261
262inline StringCache&
263WriterImplBase::PackageStringCache()
264{
265	return fPackageStringCache;
266}
267
268
269inline void
270WriterImplBase::SetFinished(bool finished)
271{
272	fFinished = finished;
273}
274
275
276inline WriterImplBase::PackageAttribute*
277WriterImplBase::_AddStringAttributeIfNotEmpty(BHPKGAttributeID id,
278	const BString& value, DoublyLinkedList<PackageAttribute>& list)
279{
280	if (value.IsEmpty())
281		return NULL;
282	return AddStringAttribute(id, value, list);
283}
284
285
286}	// namespace BPrivate
287
288}	// namespace BHPKG
289
290}	// namespace BPackageKit
291
292
293#endif	// _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
294