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