BinHeader.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include "librpm.h"
00013 extern "C"
00014 {
00015 #ifdef _RPM_5
00016 #undef RPM_NULL_TYPE
00017 #define RPM_NULL_TYPE rpmTagType(0)
00018 typedef rpmuint32_t rpm_count_t;
00019 #else
00020 #ifdef _RPM_4_4
00021 typedef int32_t rpm_count_t;
00022 #endif
00023 #endif
00024 }
00025
00026 #include <iostream>
00027
00028 #include "zypp/base/Logger.h"
00029 #include "zypp/base/NonCopyable.h"
00030
00031 #include "zypp/target/rpm/BinHeader.h"
00032
00033 using namespace std;
00034
00035 #undef Y2LOG
00036 #define Y2LOG "BinHeader"
00037
00038 namespace zypp
00039 {
00040 namespace target
00041 {
00042 namespace rpm
00043 {
00044
00050 struct HeaderEntryGetter : private base::NonCopyable
00051 {
00052 public:
00053 HeaderEntryGetter( const Header & h_r, rpmTag & tag_r );
00054 ~HeaderEntryGetter();
00055 rpmTagType type();
00056 rpm_count_t cnt();
00057 void * val();
00058 private:
00059 #ifdef _RPM_4_X
00060 ::rpmtd _rpmtd;
00061 #else
00062 rpmTagType _type;
00063 rpm_count_t _cnt;
00064 void * _val;
00065 #endif //_RPM_4_X
00066 };
00067
00068 #ifdef _RPM_4_X
00069 inline HeaderEntryGetter::HeaderEntryGetter( const Header & h_r, rpmTag & tag_r )
00070 : _rpmtd( ::rpmtdNew() )
00071 { ::headerGet( h_r, tag_r, _rpmtd, HEADERGET_DEFAULT ); }
00072 inline HeaderEntryGetter::~HeaderEntryGetter()
00073 { ::rpmtdFreeData( _rpmtd ); ::rpmtdFree( _rpmtd ); }
00074 inline rpmTagType HeaderEntryGetter::type() { return rpmtdType( _rpmtd ); }
00075 inline rpm_count_t HeaderEntryGetter::cnt() { return _rpmtd->count; }
00076 inline void * HeaderEntryGetter::val() { return _rpmtd->data; }
00077 #else
00078 inline HeaderEntryGetter::HeaderEntryGetter( const Header & h_r, rpmTag & tag_r )
00079 : _type( RPM_NULL_TYPE )
00080 , _cnt( 0 )
00081 , _val( 0 )
00082 { ::headerGetEntry( h_r, tag_r, hTYP_t(&_type), &_val, &_cnt ); }
00083 inline HeaderEntryGetter::~HeaderEntryGetter()
00084 { if ( _val && _type == RPM_STRING_ARRAY_TYPE ) free( _val ); }
00085 inline rpmTagType HeaderEntryGetter::type() { return _type; }
00086 inline rpm_count_t HeaderEntryGetter::cnt() { return _cnt; }
00087 inline void * HeaderEntryGetter::val() { return _val; }
00088 #endif //_RPM_4_X
00089
00091
00092
00093
00095
00096 unsigned BinHeader::intList::set( void * val_r, unsigned cnt_r, rpmTagType type_r )
00097 {
00098 _type = type_r;
00099 if ( val_r )
00100 switch ( _type )
00101 {
00102 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
00103 case RPM_CHAR_TYPE:
00104 std::vector<long>( (char*)val_r, ((char*)val_r)+cnt_r ).swap( _data );
00105 break;
00106 #endif
00107 case RPM_INT8_TYPE:
00108 std::vector<long>( (int8_t*)val_r, ((int8_t*)val_r)+cnt_r ).swap( _data );
00109 break;
00110 case RPM_INT16_TYPE:
00111 std::vector<long>( (int16_t*)val_r, ((int16_t*)val_r)+cnt_r ).swap( _data );
00112 break;
00113 case RPM_INT32_TYPE:
00114 std::vector<long>( (int32_t*)val_r, ((int32_t*)val_r)+cnt_r ).swap( _data );
00115 break;
00116 #ifdef _RPM_4_X
00117 case RPM_INT64_TYPE:
00118 std::vector<long>( (int64_t*)val_r, ((int64_t*)val_r)+cnt_r ).swap( _data );
00119 break;
00120 #endif
00121 default:
00122 std::vector<long>( cnt_r, 0L ).swap( _data );
00123 break;
00124 }
00125 else
00126 _data.clear();
00127 return _data.size();
00128 }
00129
00131
00132
00133
00135
00136 unsigned BinHeader::stringList::set( char ** val_r, unsigned cnt_r )
00137 {
00138 if ( val_r )
00139 std::vector<std::string>( val_r, val_r+cnt_r ).swap( _data );
00140 else
00141 _data.clear();
00142 return _data.size();
00143 }
00144
00146
00147
00148
00150
00152
00153
00154
00155
00156
00157 BinHeader::BinHeader( Header h_r )
00158 : _h( h_r )
00159 {
00160 if ( _h )
00161 {
00162 headerLink( _h );
00163 }
00164 }
00165
00167
00168
00169
00170
00171
00172 BinHeader::BinHeader( BinHeader::Ptr & rhs )
00173 {
00174 INT << "INJECT from " << rhs;
00175 if ( ! (rhs && rhs->_h) )
00176 {
00177 _h = 0;
00178 }
00179 else
00180 {
00181 _h = rhs->_h;
00182 rhs->_h = 0;
00183 }
00184 INT << ": " << *this << " (" << rhs << ")" << endl;
00185 }
00186
00188
00189
00190
00191
00192
00193 BinHeader::~BinHeader()
00194 {
00195 if ( _h )
00196 {
00197 headerFree( _h );
00198 }
00199 }
00200
00202
00203
00204
00205
00206
00207 bool BinHeader::assertHeader()
00208 {
00209 if ( !_h )
00210 {
00211 _h = ::headerNew();
00212 if ( !_h )
00213 {
00214 INT << "OOPS: NULL HEADER created!" << endl;
00215 return false;
00216 }
00217 }
00218 return true;
00219 }
00220
00222
00223
00224
00225
00226
00227
00228
00229 bool BinHeader::has_tag( tag tag_r ) const
00230 {
00231 return( !empty() && ::headerIsEntry( _h, tag_r ) );
00232 }
00233
00235
00236
00237
00238
00239
00240
00241
00242 unsigned BinHeader::int_list( tag tag_r, intList & lst_r ) const
00243 {
00244 if ( !empty() )
00245 {
00246 HeaderEntryGetter headerget( _h, tag_r );
00247
00248 if ( headerget.val() )
00249 {
00250 switch ( headerget.type() )
00251 {
00252 case RPM_NULL_TYPE:
00253 return lst_r.set( 0, 0, headerget.type() );
00254 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
00255 case RPM_CHAR_TYPE:
00256 #endif
00257 case RPM_INT8_TYPE:
00258 case RPM_INT16_TYPE:
00259 case RPM_INT32_TYPE:
00260 #ifdef _RPM_4_X
00261 case RPM_INT64_TYPE:
00262 #endif
00263 return lst_r.set( headerget.val(), headerget.cnt(), headerget.type() );
00264
00265 default:
00266 INT << "RPM_TAG MISSMATCH: RPM_INTxx_TYPE " << tag_r << " got type " << headerget.type() << endl;
00267 }
00268 }
00269 }
00270 return lst_r.set( 0, 0, RPM_NULL_TYPE );
00271 }
00272
00274
00275
00276
00277
00278
00279
00280
00281 unsigned BinHeader::string_list( tag tag_r, stringList & lst_r ) const
00282 {
00283 if ( !empty() )
00284 {
00285 HeaderEntryGetter headerget( _h, tag_r );
00286
00287 if ( headerget.val() )
00288 {
00289 switch ( headerget.type() )
00290 {
00291 case RPM_NULL_TYPE:
00292 return lst_r.set( 0, 0 );
00293 case RPM_STRING_ARRAY_TYPE:
00294 return lst_r.set( (char**)headerget.val(), headerget.cnt() );
00295
00296 default:
00297 INT << "RPM_TAG MISSMATCH: RPM_STRING_ARRAY_TYPE " << tag_r << " got type " << headerget.type() << endl;
00298 }
00299 }
00300 }
00301 return lst_r.set( 0, 0 );
00302 }
00303
00305
00306
00307
00308
00309
00310
00311
00312 int BinHeader::int_val( tag tag_r ) const
00313 {
00314 if ( !empty() )
00315 {
00316 HeaderEntryGetter headerget( _h, tag_r );
00317
00318 if ( headerget.val() )
00319 {
00320 switch ( headerget.type() )
00321 {
00322 case RPM_NULL_TYPE:
00323 return 0;
00324 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
00325 case RPM_CHAR_TYPE:
00326 return *((char*)headerget.val());
00327 #endif
00328 case RPM_INT8_TYPE:
00329 return *((int8_t*)headerget.val());
00330 case RPM_INT16_TYPE:
00331 return *((int16_t*)headerget.val());
00332 case RPM_INT32_TYPE:
00333 return *((int32_t*)headerget.val());
00334 #ifdef _RPM_4_X
00335 case RPM_INT64_TYPE:
00336 return *((int64_t*)headerget.val());
00337 #endif
00338
00339 default:
00340 INT << "RPM_TAG MISSMATCH: RPM_INTxx_TYPE " << tag_r << " got type " << headerget.type() << endl;
00341 }
00342 }
00343 }
00344 return 0;
00345 }
00346
00348
00349
00350
00351
00352
00353
00354
00355 std::string BinHeader::string_val( tag tag_r ) const
00356 {
00357 if ( !empty() )
00358 {
00359 HeaderEntryGetter headerget( _h, tag_r );
00360
00361 if ( headerget.val() )
00362 {
00363 switch ( headerget.type() )
00364 {
00365 case RPM_NULL_TYPE:
00366 return "";
00367 case RPM_STRING_TYPE:
00368 return (char*)headerget.val();
00369
00370 default:
00371 INT << "RPM_TAG MISSMATCH: RPM_STRING_TYPE " << tag_r << " got type " << headerget.type() << endl;
00372 }
00373 }
00374 }
00375 return "";
00376 }
00377
00379
00380
00381
00382
00383
00384
00385
00386 std::list<std::string> BinHeader::stringList_val( tag tag_r ) const
00387 {
00388 std::list<std::string> ret;
00389
00390 if ( !empty() )
00391 {
00392 stringList lines;
00393 unsigned count = string_list( tag_r, lines );
00394 for ( unsigned i = 0; i < count; ++i )
00395 {
00396 ret.push_back( lines[i] );
00397 }
00398 }
00399 return ret;
00400 }
00401
00403
00404
00405
00406
00407
00408
00409
00410 ostream & BinHeader::dumpOn( ostream & str ) const
00411 {
00412 ReferenceCounted::dumpOn( str );
00413 return str << '{' << (void*)_h << '}';
00414 }
00415
00416 }
00417 }
00418 }