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