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