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