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