xref: /haiku/headers/private/package/hpkg/WriterImplBase.h (revision 362efe0c9f36d3dd38b22d2c24ac02e54b189d7c)
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/Strings.h>
15 #include <package/hpkg/ZlibCompressor.h>
16 
17 #include <package/PackageInfo.h>
18 
19 
20 namespace BPackageKit {
21 
22 namespace BHPKG {
23 
24 
25 class BDataReader;
26 class BErrorOutput;
27 
28 
29 namespace BPrivate {
30 
31 
32 struct hpkg_header;
33 
34 class WriterImplBase {
35 public:
36 								WriterImplBase(BErrorOutput* errorOutput);
37 								~WriterImplBase();
38 
39 protected:
40 
41 
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 
96 			struct AbstractDataWriter {
97 				AbstractDataWriter();
98 				virtual ~AbstractDataWriter();
99 
100 				uint64 BytesWritten() const;
101 
102 				virtual status_t WriteDataNoThrow(const void* buffer,
103 					size_t size) = 0;
104 
105 				void WriteDataThrows(const void* buffer, size_t size);
106 
107 			protected:
108 				uint64	fBytesWritten;
109 			};
110 
111 
112 			struct FDDataWriter : AbstractDataWriter {
113 				FDDataWriter(int fd, off_t offset, BErrorOutput* errorOutput);
114 
115 				virtual status_t WriteDataNoThrow(const void* buffer,
116 					size_t size);
117 
118 				off_t Offset() const;
119 
120 			private:
121 				int				fFD;
122 				off_t			fOffset;
123 				BErrorOutput*	fErrorOutput;
124 			};
125 
126 
127 			struct ZlibDataWriter : AbstractDataWriter, private BDataOutput {
128 				ZlibDataWriter(AbstractDataWriter* dataWriter);
129 
130 				void Init();
131 
132 				void Finish();
133 
134 				virtual status_t WriteDataNoThrow(const void* buffer,
135 					size_t size);
136 
137 			private:
138 				// BDataOutput
139 				virtual status_t WriteData(const void* buffer, size_t size);
140 
141 			private:
142 				AbstractDataWriter*	fDataWriter;
143 				ZlibCompressor		fCompressor;
144 			};
145 
146 
147 			typedef DoublyLinkedList<PackageAttribute> PackageAttributeList;
148 
149 protected:
150 			status_t			Init(const char* fileName, const char* type,
151 									uint32 flags);
152 
153 			void				RegisterPackageInfo(
154 									PackageAttributeList& attributeList,
155 									const BPackageInfo& packageInfo);
156 			void				RegisterPackageVersion(
157 									PackageAttributeList& attributeList,
158 									const BPackageVersion& version,
159 									BHPKGAttributeID attributeID
160 										= kDefaultVersionAttributeID);
161 			void				RegisterPackageResolvableExpressionList(
162 									PackageAttributeList& attributeList,
163 									const BObjectList<
164 										BPackageResolvableExpression>& list,
165 									uint8 id);
166 
167 			int32				WriteCachedStrings(const StringCache& cache,
168 									uint32 minUsageCount);
169 
170 			int32				WritePackageAttributes(
171 									const PackageAttributeList& attributes,
172 									uint32& _stringsLengthUncompressed);
173 			void				WritePackageVersion(
174 									const BPackageVersion& version);
175 			void				WritePackageResolvableExpressionList(
176 									const BObjectList<
177 										BPackageResolvableExpression>& list,
178 									uint8 id);
179 
180 			void				WriteAttributeValue(const AttributeValue& value,
181 									uint8 encoding);
182 			void				WriteUnsignedLEB128(uint64 value);
183 	inline	void				WriteString(const char* string);
184 
185 	template<typename Type>
186 	inline	void				Write(const Type& value);
187 
188 			void				WriteBuffer(const void* buffer, size_t size,
189 									off_t offset);
190 
191 	inline	int					FD() const;
192 	inline	uint32				Flags() const;
193 
194 	inline	const PackageAttributeList&	PackageAttributes() const;
195 	inline	PackageAttributeList&	PackageAttributes();
196 
197 	inline	const StringCache&	PackageStringCache() const;
198 	inline	StringCache&		PackageStringCache();
199 
200 	inline	AbstractDataWriter*	DataWriter() const;
201 	inline	void				SetDataWriter(AbstractDataWriter* dataWriter);
202 
203 	inline	void				SetFinished(bool finished);
204 
205 private:
206 	static const BHPKGAttributeID kDefaultVersionAttributeID
207 		= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
208 
209 private:
210 			void				_WritePackageAttributes(
211 									const PackageAttributeList& attributes);
212 
213 private:
214 			BErrorOutput*		fErrorOutput;
215 			const char*			fFileName;
216 			uint32				fFlags;
217 			int					fFD;
218 			bool				fFinished;
219 
220 			AbstractDataWriter*	fDataWriter;
221 
222 			StringCache			fPackageStringCache;
223 			PackageAttributeList	fPackageAttributes;
224 };
225 
226 
227 inline uint64
228 WriterImplBase::AbstractDataWriter::BytesWritten() const
229 {
230 	return fBytesWritten;
231 }
232 
233 
234 inline void
235 WriterImplBase::AbstractDataWriter::WriteDataThrows(const void* buffer,
236 	size_t size)
237 {
238 	status_t error = WriteDataNoThrow(buffer, size);
239 	if (error != B_OK)
240 		throw status_t(error);
241 }
242 
243 inline off_t
244 WriterImplBase::FDDataWriter::Offset() const
245 {
246 	return fOffset;
247 }
248 
249 
250 template<typename Type>
251 inline void
252 WriterImplBase::Write(const Type& value)
253 {
254 	fDataWriter->WriteDataThrows(&value, sizeof(Type));
255 }
256 
257 
258 inline void
259 WriterImplBase::WriteString(const char* string)
260 {
261 	fDataWriter->WriteDataThrows(string, strlen(string) + 1);
262 }
263 
264 
265 inline int
266 WriterImplBase::FD() const
267 {
268 	return fFD;
269 }
270 
271 
272 inline uint32
273 WriterImplBase::Flags() const
274 {
275 	return fFlags;
276 }
277 
278 
279 inline WriterImplBase::AbstractDataWriter*
280 WriterImplBase::DataWriter() const
281 {
282 	return fDataWriter;
283 }
284 
285 
286 inline void
287 WriterImplBase::SetDataWriter(AbstractDataWriter* dataWriter)
288 {
289 	fDataWriter = dataWriter;
290 }
291 
292 
293 inline const WriterImplBase::PackageAttributeList&
294 WriterImplBase::PackageAttributes() const
295 {
296 	return fPackageAttributes;
297 }
298 
299 
300 inline WriterImplBase::PackageAttributeList&
301 WriterImplBase::PackageAttributes()
302 {
303 	return fPackageAttributes;
304 }
305 
306 
307 inline const StringCache&
308 WriterImplBase::PackageStringCache() const
309 {
310 	return fPackageStringCache;
311 }
312 
313 
314 inline StringCache&
315 WriterImplBase::PackageStringCache()
316 {
317 	return fPackageStringCache;
318 }
319 
320 
321 inline void
322 WriterImplBase::SetFinished(bool finished)
323 {
324 	fFinished = finished;
325 }
326 
327 
328 }	// namespace BPrivate
329 
330 }	// namespace BHPKG
331 
332 }	// namespace BPackageKit
333 
334 
335 #endif	// _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
336