1f2022173SOliver Tappe/*
2f2022173SOliver Tappe * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3f2022173SOliver Tappe * Distributed under the terms of the MIT License.
4f2022173SOliver Tappe */
5f2022173SOliver Tappe#ifndef _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
6f2022173SOliver Tappe#define _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
7f2022173SOliver Tappe
8f2022173SOliver Tappe
9f2022173SOliver Tappe#include <util/DoublyLinkedList.h>
10f2022173SOliver Tappe
1133bc4425SOliver Tappe#include <package/hpkg/HPKGDefsPrivate.h>
12f2022173SOliver Tappe
13796343edSIngo Weinhold#include <package/hpkg/PackageWriter.h>
14f2022173SOliver Tappe#include <package/hpkg/Strings.h>
15f2022173SOliver Tappe
16f2022173SOliver Tappe#include <package/PackageInfo.h>
17f2022173SOliver Tappe
18b3263ad3SIngo Weinhold#include <package/hpkg/PackageFileHeapWriter.h>
19b3263ad3SIngo Weinhold
20b3263ad3SIngo Weinhold
21b3263ad3SIngo Weinholdclass BCompressionAlgorithm;
22b3263ad3SIngo Weinholdclass BCompressionParameters;
23b3263ad3SIngo Weinholdclass BDecompressionParameters;
24b3263ad3SIngo Weinhold
25f2022173SOliver Tappe
26f2022173SOliver Tappenamespace BPackageKit {
27f2022173SOliver Tappe
28f2022173SOliver Tappenamespace BHPKG {
29f2022173SOliver Tappe
30f2022173SOliver Tappe
31f2022173SOliver Tappeclass BDataReader;
32f2022173SOliver Tappeclass BErrorOutput;
33f2022173SOliver Tappe
34f2022173SOliver Tappe
35f2022173SOliver Tappenamespace BPrivate {
36f2022173SOliver Tappe
37f2022173SOliver Tappe
38f2022173SOliver Tappestruct hpkg_header;
39f2022173SOliver Tappe
401f633814SIngo Weinhold
41f2022173SOliver Tappeclass WriterImplBase {
42f2022173SOliver Tappepublic:
431f633814SIngo Weinhold								WriterImplBase(const char* fileType,
441f633814SIngo Weinhold									BErrorOutput* errorOutput);
45f2022173SOliver Tappe								~WriterImplBase();
46f2022173SOliver Tappe
47f2022173SOliver Tappeprotected:
48f2022173SOliver Tappe			struct AttributeValue {
49f2022173SOliver Tappe				union {
50f2022173SOliver Tappe					int64			signedInt;
51f2022173SOliver Tappe					uint64			unsignedInt;
52f2022173SOliver Tappe					CachedString*	string;
53f2022173SOliver Tappe					struct {
54f2022173SOliver Tappe						uint64		size;
55f2022173SOliver Tappe						union {
56f2022173SOliver Tappe							uint64	offset;
57f2022173SOliver Tappe							uint8	raw[B_HPKG_MAX_INLINE_DATA_SIZE];
58f2022173SOliver Tappe						};
59f2022173SOliver Tappe					} data;
60f2022173SOliver Tappe				};
61f2022173SOliver Tappe				uint8		type;
62f2022173SOliver Tappe				int8		encoding;
63f2022173SOliver Tappe
64f2022173SOliver Tappe				AttributeValue();
65f2022173SOliver Tappe				~AttributeValue();
66f2022173SOliver Tappe
67f2022173SOliver Tappe				void SetTo(int8 value);
68f2022173SOliver Tappe				void SetTo(uint8 value);
69f2022173SOliver Tappe				void SetTo(int16 value);
70f2022173SOliver Tappe				void SetTo(uint16 value);
71f2022173SOliver Tappe				void SetTo(int32 value);
72f2022173SOliver Tappe				void SetTo(uint32 value);
73f2022173SOliver Tappe				void SetTo(int64 value);
74f2022173SOliver Tappe				void SetTo(uint64 value);
75f2022173SOliver Tappe				void SetTo(CachedString* value);
76f2022173SOliver Tappe				void SetToData(uint64 size, uint64 offset);
77f2022173SOliver Tappe				void SetToData(uint64 size, const void* rawData);
78f2022173SOliver Tappe				uint8 ApplicableEncoding() const;
79f2022173SOliver Tappe
80f2022173SOliver Tappe			private:
81f2022173SOliver Tappe				static uint8 _ApplicableIntEncoding(uint64 value);
82f2022173SOliver Tappe			};
83f2022173SOliver Tappe
84f2022173SOliver Tappe
85f2022173SOliver Tappe			struct PackageAttribute :
86f2022173SOliver Tappe					public DoublyLinkedListLinkImpl<PackageAttribute>,
87f2022173SOliver Tappe					public AttributeValue {
8833bc4425SOliver Tappe				BHPKGAttributeID 					id;
89f2022173SOliver Tappe				DoublyLinkedList<PackageAttribute>	children;
90f2022173SOliver Tappe
9133bc4425SOliver Tappe				PackageAttribute(BHPKGAttributeID id_, uint8 type,
92f2022173SOliver Tappe					uint8 encoding);
93f2022173SOliver Tappe				~PackageAttribute();
94f2022173SOliver Tappe
95f2022173SOliver Tappe				void AddChild(PackageAttribute* child);
96f2022173SOliver Tappe
97f2022173SOliver Tappe			private:
98f2022173SOliver Tappe				void _DeleteChildren();
99f2022173SOliver Tappe			};
100f2022173SOliver Tappe
101f2022173SOliver Tappe			typedef DoublyLinkedList<PackageAttribute> PackageAttributeList;
102f2022173SOliver Tappe
103f2022173SOliver Tappeprotected:
10444c47711SIngo Weinhold			status_t			Init(BPositionIO* file, bool keepFile,
10544c47711SIngo Weinhold									const char* fileName,
106796343edSIngo Weinhold									const BPackageWriterParameters& parameters);
1078f5130edSIngo Weinhold			status_t			InitHeapReader(size_t headerSize);
1088f5130edSIngo Weinhold
1098f5130edSIngo Weinhold			void				SetCompression(uint32 compression);
110f2022173SOliver Tappe
1114ee7d007SOliver Tappe			void				RegisterPackageInfo(
1124ee7d007SOliver Tappe									PackageAttributeList& attributeList,
1134ee7d007SOliver Tappe									const BPackageInfo& packageInfo);
1144ee7d007SOliver Tappe			void				RegisterPackageVersion(
1154ee7d007SOliver Tappe									PackageAttributeList& attributeList,
116b2709d8aSIngo Weinhold									const BPackageVersion& version,
117b2709d8aSIngo Weinhold									BHPKGAttributeID attributeID
118b2709d8aSIngo Weinhold										= kDefaultVersionAttributeID);
1194ee7d007SOliver Tappe			void				RegisterPackageResolvableExpressionList(
1204ee7d007SOliver Tappe									PackageAttributeList& attributeList,
1214ee7d007SOliver Tappe									const BObjectList<
1224ee7d007SOliver Tappe										BPackageResolvableExpression>& list,
1234ee7d007SOliver Tappe									uint8 id);
1244ee7d007SOliver Tappe
125e8533402SIngo Weinhold			PackageAttribute*	AddStringAttribute(BHPKGAttributeID id,
126e8533402SIngo Weinhold									const BString& value,
127e8533402SIngo Weinhold									DoublyLinkedList<PackageAttribute>& list);
128e8533402SIngo Weinhold
129f2022173SOliver Tappe			int32				WriteCachedStrings(const StringCache& cache,
130f2022173SOliver Tappe									uint32 minUsageCount);
131f2022173SOliver Tappe
1324ee7d007SOliver Tappe			int32				WritePackageAttributes(
1334ee7d007SOliver Tappe									const PackageAttributeList& attributes,
1344ee7d007SOliver Tappe									uint32& _stringsLengthUncompressed);
135f2022173SOliver Tappe			void				WritePackageVersion(
136f2022173SOliver Tappe									const BPackageVersion& version);
137f2022173SOliver Tappe			void				WritePackageResolvableExpressionList(
138f2022173SOliver Tappe									const BObjectList<
139f2022173SOliver Tappe										BPackageResolvableExpression>& list,
140f2022173SOliver Tappe									uint8 id);
141f2022173SOliver Tappe
142f2022173SOliver Tappe			void				WriteAttributeValue(const AttributeValue& value,
143f2022173SOliver Tappe									uint8 encoding);
144f2022173SOliver Tappe			void				WriteUnsignedLEB128(uint64 value);
145f2022173SOliver Tappe
146f2022173SOliver Tappe	template<typename Type>
147f2022173SOliver Tappe	inline	void				Write(const Type& value);
1481f633814SIngo Weinhold	inline	void				WriteString(const char* string);
1491f633814SIngo Weinhold	inline	void				WriteBuffer(const void* data, size_t size);
1501f633814SIngo Weinhold									// appends data to the heap
151f2022173SOliver Tappe
1521f633814SIngo Weinhold			void				RawWriteBuffer(const void* buffer, size_t size,
153f2022173SOliver Tappe									off_t offset);
1541f633814SIngo Weinhold									// writes to the file directly
155f2022173SOliver Tappe
156e527b796SIngo Weinhold	inline	BPositionIO*		File() const;
157327b38d6SIngo Weinhold	inline	uint32				Flags() const;
158cdfeba5aSIngo Weinhold	inline	const BPackageWriterParameters& Parameters() const;
1594ee7d007SOliver Tappe
16034d56c1bSOliver Tappe	inline	const PackageAttributeList&	PackageAttributes() const;
16134d56c1bSOliver Tappe	inline	PackageAttributeList&	PackageAttributes();
16234d56c1bSOliver Tappe
16334d56c1bSOliver Tappe	inline	const StringCache&	PackageStringCache() const;
16434d56c1bSOliver Tappe	inline	StringCache&		PackageStringCache();
16534d56c1bSOliver Tappe
16634d56c1bSOliver Tappe	inline	void				SetFinished(bool finished);
1674ee7d007SOliver Tappe
1681f633814SIngo Weinholdprotected:
1691f633814SIngo Weinhold			PackageFileHeapWriter* fHeapWriter;
170b3263ad3SIngo Weinhold			BCompressionAlgorithm* fCompressionAlgorithm;
171b3263ad3SIngo Weinhold			BCompressionParameters* fCompressionParameters;
172b3263ad3SIngo Weinhold			BCompressionAlgorithm* fDecompressionAlgorithm;
173b3263ad3SIngo Weinhold			BDecompressionParameters* fDecompressionParameters;
1741f633814SIngo Weinhold
175b2709d8aSIngo Weinholdprivate:
176b2709d8aSIngo Weinhold	static const BHPKGAttributeID kDefaultVersionAttributeID
177b2709d8aSIngo Weinhold		= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
178b2709d8aSIngo Weinhold
1794ee7d007SOliver Tappeprivate:
1800f4e11e7SIngo Weinhold	inline	PackageAttribute*	_AddStringAttributeIfNotEmpty(
1810f4e11e7SIngo Weinhold									BHPKGAttributeID id, const BString& value,
1820f4e11e7SIngo Weinhold									DoublyLinkedList<PackageAttribute>& list);
183a3e070a7SIngo Weinhold			void				_AddStringAttributeList(BHPKGAttributeID id,
184a3e070a7SIngo Weinhold									const BStringList& value,
185a3e070a7SIngo Weinhold									DoublyLinkedList<PackageAttribute>& list);
1864ee7d007SOliver Tappe			void				_WritePackageAttributes(
1874ee7d007SOliver Tappe									const PackageAttributeList& attributes);
1884ee7d007SOliver Tappe
1894ee7d007SOliver Tappeprivate:
1901f633814SIngo Weinhold			const char*			fFileType;
191f2022173SOliver Tappe			BErrorOutput*		fErrorOutput;
192f2022173SOliver Tappe			const char*			fFileName;
193796343edSIngo Weinhold			BPackageWriterParameters fParameters;
194e527b796SIngo Weinhold			BPositionIO*		fFile;
19544c47711SIngo Weinhold			bool				fOwnsFile;
196f2022173SOliver Tappe			bool				fFinished;
197f2022173SOliver Tappe
198f2022173SOliver Tappe			StringCache			fPackageStringCache;
1994ee7d007SOliver Tappe			PackageAttributeList	fPackageAttributes;
200f2022173SOliver Tappe};
201f2022173SOliver Tappe
202f2022173SOliver Tappe
2031f633814SIngo Weinholdtemplate<typename Type>
204f2022173SOliver Tappeinline void
2051f633814SIngo WeinholdWriterImplBase::Write(const Type& value)
206f2022173SOliver Tappe{
2071f633814SIngo Weinhold	WriteBuffer(&value, sizeof(Type));
208f2022173SOliver Tappe}
209f2022173SOliver Tappe
210f2022173SOliver Tappe
211f2022173SOliver Tappeinline void
2121f633814SIngo WeinholdWriterImplBase::WriteString(const char* string)
213f2022173SOliver Tappe{
2141f633814SIngo Weinhold	WriteBuffer(string, strlen(string) + 1);
215f2022173SOliver Tappe}
216f2022173SOliver Tappe
217f2022173SOliver Tappe
218f2022173SOliver Tappeinline void
2191f633814SIngo WeinholdWriterImplBase::WriteBuffer(const void* data, size_t size)
220f2022173SOliver Tappe{
22184297881SIngo Weinhold	fHeapWriter->AddDataThrows(data, size);
222f2022173SOliver Tappe}
223f2022173SOliver Tappe
224f2022173SOliver Tappe
225e527b796SIngo Weinholdinline BPositionIO*
226e527b796SIngo WeinholdWriterImplBase::File() const
2274ee7d007SOliver Tappe{
228e527b796SIngo Weinhold	return fFile;
2294ee7d007SOliver Tappe}
2304ee7d007SOliver Tappe
2314ee7d007SOliver Tappe
232327b38d6SIngo Weinholdinline uint32
233327b38d6SIngo WeinholdWriterImplBase::Flags() const
234327b38d6SIngo Weinhold{
235796343edSIngo Weinhold	return fParameters.Flags();
236327b38d6SIngo Weinhold}
237327b38d6SIngo Weinhold
238327b38d6SIngo Weinhold
239cdfeba5aSIngo Weinholdinline const BPackageWriterParameters&
240cdfeba5aSIngo WeinholdWriterImplBase::Parameters() const
241cdfeba5aSIngo Weinhold{
242cdfeba5aSIngo Weinhold	return fParameters;
243cdfeba5aSIngo Weinhold}
244cdfeba5aSIngo Weinhold
245cdfeba5aSIngo Weinhold
2464ee7d007SOliver Tappeinline const WriterImplBase::PackageAttributeList&
2474ee7d007SOliver TappeWriterImplBase::PackageAttributes() const
2484ee7d007SOliver Tappe{
2494ee7d007SOliver Tappe	return fPackageAttributes;
2504ee7d007SOliver Tappe}
2514ee7d007SOliver Tappe
2524ee7d007SOliver Tappe
2534ee7d007SOliver Tappeinline WriterImplBase::PackageAttributeList&
2544ee7d007SOliver TappeWriterImplBase::PackageAttributes()
2554ee7d007SOliver Tappe{
2564ee7d007SOliver Tappe	return fPackageAttributes;
2574ee7d007SOliver Tappe}
2584ee7d007SOliver Tappe
2594ee7d007SOliver Tappe
26034d56c1bSOliver Tappeinline const StringCache&
26134d56c1bSOliver TappeWriterImplBase::PackageStringCache() const
26234d56c1bSOliver Tappe{
26334d56c1bSOliver Tappe	return fPackageStringCache;
26434d56c1bSOliver Tappe}
26534d56c1bSOliver Tappe
26634d56c1bSOliver Tappe
26734d56c1bSOliver Tappeinline StringCache&
26834d56c1bSOliver TappeWriterImplBase::PackageStringCache()
26934d56c1bSOliver Tappe{
27034d56c1bSOliver Tappe	return fPackageStringCache;
27134d56c1bSOliver Tappe}
27234d56c1bSOliver Tappe
27334d56c1bSOliver Tappe
2744ee7d007SOliver Tappeinline void
2754ee7d007SOliver TappeWriterImplBase::SetFinished(bool finished)
2764ee7d007SOliver Tappe{
2774ee7d007SOliver Tappe	fFinished = finished;
2784ee7d007SOliver Tappe}
2794ee7d007SOliver Tappe
2804ee7d007SOliver Tappe
2810f4e11e7SIngo Weinholdinline WriterImplBase::PackageAttribute*
2820f4e11e7SIngo WeinholdWriterImplBase::_AddStringAttributeIfNotEmpty(BHPKGAttributeID id,
2830f4e11e7SIngo Weinhold	const BString& value, DoublyLinkedList<PackageAttribute>& list)
2840f4e11e7SIngo Weinhold{
2850f4e11e7SIngo Weinhold	if (value.IsEmpty())
2860f4e11e7SIngo Weinhold		return NULL;
287e8533402SIngo Weinhold	return AddStringAttribute(id, value, list);
2880f4e11e7SIngo Weinhold}
2890f4e11e7SIngo Weinhold
2900f4e11e7SIngo Weinhold
291f2022173SOliver Tappe}	// namespace BPrivate
292f2022173SOliver Tappe
293f2022173SOliver Tappe}	// namespace BHPKG
294f2022173SOliver Tappe
295f2022173SOliver Tappe}	// namespace BPackageKit
296f2022173SOliver Tappe
297f2022173SOliver Tappe
298f2022173SOliver Tappe#endif	// _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
299