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