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 21class BCompressionAlgorithm; 22class BCompressionParameters; 23class BDecompressionParameters; 24 25 26namespace BPackageKit { 27 28namespace BHPKG { 29 30 31class BDataReader; 32class BErrorOutput; 33 34 35namespace BPrivate { 36 37 38struct hpkg_header; 39 40 41class WriterImplBase { 42public: 43 WriterImplBase(const char* fileType, 44 BErrorOutput* errorOutput); 45 ~WriterImplBase(); 46 47protected: 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 103protected: 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 168protected: 169 PackageFileHeapWriter* fHeapWriter; 170 BCompressionAlgorithm* fCompressionAlgorithm; 171 BCompressionParameters* fCompressionParameters; 172 BCompressionAlgorithm* fDecompressionAlgorithm; 173 BDecompressionParameters* fDecompressionParameters; 174 175private: 176 static const BHPKGAttributeID kDefaultVersionAttributeID 177 = B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR; 178 179private: 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 189private: 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 203template<typename Type> 204inline void 205WriterImplBase::Write(const Type& value) 206{ 207 WriteBuffer(&value, sizeof(Type)); 208} 209 210 211inline void 212WriterImplBase::WriteString(const char* string) 213{ 214 WriteBuffer(string, strlen(string) + 1); 215} 216 217 218inline void 219WriterImplBase::WriteBuffer(const void* data, size_t size) 220{ 221 fHeapWriter->AddDataThrows(data, size); 222} 223 224 225inline BPositionIO* 226WriterImplBase::File() const 227{ 228 return fFile; 229} 230 231 232inline uint32 233WriterImplBase::Flags() const 234{ 235 return fParameters.Flags(); 236} 237 238 239inline const BPackageWriterParameters& 240WriterImplBase::Parameters() const 241{ 242 return fParameters; 243} 244 245 246inline const WriterImplBase::PackageAttributeList& 247WriterImplBase::PackageAttributes() const 248{ 249 return fPackageAttributes; 250} 251 252 253inline WriterImplBase::PackageAttributeList& 254WriterImplBase::PackageAttributes() 255{ 256 return fPackageAttributes; 257} 258 259 260inline const StringCache& 261WriterImplBase::PackageStringCache() const 262{ 263 return fPackageStringCache; 264} 265 266 267inline StringCache& 268WriterImplBase::PackageStringCache() 269{ 270 return fPackageStringCache; 271} 272 273 274inline void 275WriterImplBase::SetFinished(bool finished) 276{ 277 fFinished = finished; 278} 279 280 281inline WriterImplBase::PackageAttribute* 282WriterImplBase::_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