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