xref: /haiku/headers/private/package/hpkg/WriterImplBase.h (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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 
22 namespace BPackageKit {
23 
24 namespace BHPKG {
25 
26 
27 class BDataReader;
28 class BErrorOutput;
29 
30 
31 namespace BPrivate {
32 
33 
34 class AbstractDataWriter;
35 class PackageFileHeapWriter;
36 
37 struct hpkg_header;
38 
39 
40 class WriterImplBase {
41 public:
42 								WriterImplBase(const char* fileType,
43 									BErrorOutput* errorOutput);
44 								~WriterImplBase();
45 
46 protected:
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 
102 protected:
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 
162 protected:
163 			PackageFileHeapWriter* fHeapWriter;
164 
165 private:
166 	static const BHPKGAttributeID kDefaultVersionAttributeID
167 		= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
168 
169 private:
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 
179 private:
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 
194 template<typename Type>
195 inline void
196 WriterImplBase::Write(const Type& value)
197 {
198 	WriteBuffer(&value, sizeof(Type));
199 }
200 
201 
202 inline void
203 WriterImplBase::WriteString(const char* string)
204 {
205 	WriteBuffer(string, strlen(string) + 1);
206 }
207 
208 
209 inline void
210 WriterImplBase::WriteBuffer(const void* data, size_t size)
211 {
212 	fDataWriter->WriteDataThrows(data, size);
213 }
214 
215 
216 inline int
217 WriterImplBase::FD() const
218 {
219 	return fFD;
220 }
221 
222 
223 inline uint32
224 WriterImplBase::Flags() const
225 {
226 	return fParameters.Flags();
227 }
228 
229 
230 inline const WriterImplBase::PackageAttributeList&
231 WriterImplBase::PackageAttributes() const
232 {
233 	return fPackageAttributes;
234 }
235 
236 
237 inline WriterImplBase::PackageAttributeList&
238 WriterImplBase::PackageAttributes()
239 {
240 	return fPackageAttributes;
241 }
242 
243 
244 inline const StringCache&
245 WriterImplBase::PackageStringCache() const
246 {
247 	return fPackageStringCache;
248 }
249 
250 
251 inline StringCache&
252 WriterImplBase::PackageStringCache()
253 {
254 	return fPackageStringCache;
255 }
256 
257 
258 inline void
259 WriterImplBase::SetFinished(bool finished)
260 {
261 	fFinished = finished;
262 }
263 
264 
265 inline WriterImplBase::PackageAttribute*
266 WriterImplBase::_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