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