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