libzypp  10.5.0
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 #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 //        CLASS NAME : BinHeader::intList
00093 //
00095 
00096 unsigned BinHeader::intList::set( void * val_r, unsigned cnt_r, rpmTagType type_r )
00097 {
00098   _type = type_r; // remember the type!
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 //        CLASS NAME : BinHeader::stringList
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 //        CLASS NAME : BinHeader
00148 //
00150 
00152 //
00153 //
00154 //        METHOD NAME : BinHeader::BinHeader
00155 //        METHOD TYPE : Constructor
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 //        METHOD NAME : BinHeader::BinHeader
00170 //        METHOD TYPE : Constructor
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;  // ::headerLink already done in rhs
00182     rhs->_h = 0;
00183   }
00184   INT << ": " << *this << "   (" << rhs << ")" << endl;
00185 }
00186 
00188 //
00189 //
00190 //        METHOD NAME : BinHeader::~BinHeader
00191 //        METHOD TYPE : Destructor
00192 //
00193 BinHeader::~BinHeader()
00194 {
00195   if ( _h )
00196   {
00197     headerFree( _h );
00198   }
00199 }
00200 
00202 //
00203 //
00204 //        METHOD NAME : BinHeader::assertHeader
00205 //        METHOD TYPE : void
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 //        METHOD NAME : BinHeader::has_tag
00225 //        METHOD TYPE : bool
00226 //
00227 //        DESCRIPTION :
00228 //
00229 bool BinHeader::has_tag( tag tag_r ) const
00230 {
00231   return( !empty() && ::headerIsEntry( _h, tag_r ) );
00232 }
00233 
00235 //
00236 //
00237 //        METHOD NAME : BinHeader::int_list
00238 //        METHOD TYPE : unsigned
00239 //
00240 //        DESCRIPTION :
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 //        METHOD NAME : BinHeader::string_list
00277 //        METHOD TYPE : unsigned
00278 //
00279 //        DESCRIPTION :
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 //        METHOD NAME : BinHeader::int_val
00308 //        METHOD TYPE : int
00309 //
00310 //        DESCRIPTION :
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 //        METHOD NAME : BinHeader::string_val
00351 //        METHOD TYPE : std::string
00352 //
00353 //        DESCRIPTION :
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 //        METHOD NAME : BinHeader::stringList_val
00382 //        METHOD TYPE : std::list<std::string>
00383 //
00384 //        DESCRIPTION :
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 //      METHOD NAME : BinHeader::dumpOn
00406 //      METHOD TYPE : ostream &
00407 //
00408 //      DESCRIPTION :
00409 //
00410 ostream & BinHeader::dumpOn( ostream & str ) const
00411 {
00412   ReferenceCounted::dumpOn( str );
00413   return str << '{' << (void*)_h << '}';
00414 }
00415 
00416 } // namespace rpm
00417 } // namespace target
00418 } // namespace zypp