xref: /haiku/headers/private/package/hpkg/WriterImplBase.h (revision d374a27286b8a52974a97dba0d5966ea026a665d)
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 
152 			void				RegisterPackageInfo(
153 									PackageAttributeList& attributeList,
154 									const BPackageInfo& packageInfo);
155 			void				RegisterPackageVersion(
156 									PackageAttributeList& attributeList,
157 									const BPackageVersion& version);
158 			void				RegisterPackageResolvableExpressionList(
159 									PackageAttributeList& attributeList,
160 									const BObjectList<
161 										BPackageResolvableExpression>& list,
162 									uint8 id);
163 
164 			int32				WriteCachedStrings(const StringCache& cache,
165 									uint32 minUsageCount);
166 
167 			int32				WritePackageAttributes(
168 									const PackageAttributeList& attributes,
169 									uint32& _stringsLengthUncompressed);
170 			void				WritePackageVersion(
171 									const BPackageVersion& version);
172 			void				WritePackageResolvableExpressionList(
173 									const BObjectList<
174 										BPackageResolvableExpression>& list,
175 									uint8 id);
176 
177 			void				WriteAttributeValue(const AttributeValue& value,
178 									uint8 encoding);
179 			void				WriteUnsignedLEB128(uint64 value);
180 	inline	void				WriteString(const char* string);
181 
182 	template<typename Type>
183 	inline	void				Write(const Type& value);
184 
185 			void				WriteBuffer(const void* buffer, size_t size,
186 									off_t offset);
187 
188 	inline	int					FD() const;
189 
190 	inline	const PackageAttributeList&	PackageAttributes() const;
191 	inline	PackageAttributeList&	PackageAttributes();
192 
193 	inline	const StringCache&	PackageStringCache() const;
194 	inline	StringCache&		PackageStringCache();
195 
196 	inline	AbstractDataWriter*	DataWriter() const;
197 	inline	void				SetDataWriter(AbstractDataWriter* dataWriter);
198 
199 	inline	void				SetFinished(bool finished);
200 
201 private:
202 			void				_WritePackageAttributes(
203 									const PackageAttributeList& attributes);
204 
205 private:
206 			BErrorOutput*		fErrorOutput;
207 			const char*			fFileName;
208 			int					fFD;
209 			bool				fFinished;
210 
211 			AbstractDataWriter*	fDataWriter;
212 
213 			StringCache			fPackageStringCache;
214 			PackageAttributeList	fPackageAttributes;
215 };
216 
217 
218 inline uint64
219 WriterImplBase::AbstractDataWriter::BytesWritten() const
220 {
221 	return fBytesWritten;
222 }
223 
224 
225 inline void
226 WriterImplBase::AbstractDataWriter::WriteDataThrows(const void* buffer,
227 	size_t size)
228 {
229 	status_t error = WriteDataNoThrow(buffer, size);
230 	if (error != B_OK)
231 		throw status_t(error);
232 }
233 
234 inline off_t
235 WriterImplBase::FDDataWriter::Offset() const
236 {
237 	return fOffset;
238 }
239 
240 
241 template<typename Type>
242 inline void
243 WriterImplBase::Write(const Type& value)
244 {
245 	fDataWriter->WriteDataThrows(&value, sizeof(Type));
246 }
247 
248 
249 inline void
250 WriterImplBase::WriteString(const char* string)
251 {
252 	fDataWriter->WriteDataThrows(string, strlen(string) + 1);
253 }
254 
255 
256 inline int
257 WriterImplBase::FD() const
258 {
259 	return fFD;
260 }
261 
262 
263 inline WriterImplBase::AbstractDataWriter*
264 WriterImplBase::DataWriter() const
265 {
266 	return fDataWriter;
267 }
268 
269 
270 inline void
271 WriterImplBase::SetDataWriter(AbstractDataWriter* dataWriter)
272 {
273 	fDataWriter = dataWriter;
274 }
275 
276 
277 inline const WriterImplBase::PackageAttributeList&
278 WriterImplBase::PackageAttributes() const
279 {
280 	return fPackageAttributes;
281 }
282 
283 
284 inline WriterImplBase::PackageAttributeList&
285 WriterImplBase::PackageAttributes()
286 {
287 	return fPackageAttributes;
288 }
289 
290 
291 inline const StringCache&
292 WriterImplBase::PackageStringCache() const
293 {
294 	return fPackageStringCache;
295 }
296 
297 
298 inline StringCache&
299 WriterImplBase::PackageStringCache()
300 {
301 	return fPackageStringCache;
302 }
303 
304 
305 inline void
306 WriterImplBase::SetFinished(bool finished)
307 {
308 	fFinished = finished;
309 }
310 
311 
312 }	// namespace BPrivate
313 
314 }	// namespace BHPKG
315 
316 }	// namespace BPackageKit
317 
318 
319 #endif	// _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
320