Allow building libzypp with rpm-5 (experimental)
[platform/upstream/libzypp.git] / zypp / target / rpm / BinHeader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/BinHeader.cc
10  *
11 */
12 #include "librpm.h"
13 extern "C"
14 {
15 #ifdef _RPM_5
16 #undef RPM_NULL_TYPE
17 #define RPM_NULL_TYPE rpmTagType(0)
18 #endif
19
20 #ifndef _RPM_4_4_COMPAT
21 #ifdef _RPM_5
22 typedef rpmuint32_t rpm_count_t;
23 #else
24 typedef int32_t rpm_count_t;
25 #endif
26 #endif
27 }
28
29 #include <iostream>
30
31 #include "zypp/base/Logger.h"
32
33 #include "zypp/target/rpm/BinHeader.h"
34
35 using namespace std;
36
37 #undef Y2LOG
38 #define Y2LOG "BinHeader"
39
40 namespace zypp
41 {
42 namespace target
43 {
44 namespace rpm
45 {
46
47 ///////////////////////////////////////////////////////////////////
48 //
49 //        CLASS NAME : BinHeader::intList
50 //
51 ///////////////////////////////////////////////////////////////////
52
53 BinHeader::intList::intList()
54     : cnt( 0 ), val( 0 ), type( RPM_NULL_TYPE )
55 {}
56
57 unsigned BinHeader::intList::set( void * val_r, unsigned cnt_r, rpmTagType type_r )
58 {
59   val = val_r;
60   cnt = val ? cnt_r : 0;
61   type = type_r;
62   return cnt;
63 }
64
65 int BinHeader::intList::operator[]( const unsigned idx_r ) const
66 {
67   if ( idx_r < cnt )
68   {
69     switch ( type )
70     {
71 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
72     case RPM_CHAR_TYPE:
73       return ((char*)val)[idx_r];
74 #endif
75     case RPM_INT8_TYPE:
76       return ((int8_t*)val)[idx_r];
77     case RPM_INT16_TYPE:
78       return ((int16_t*)val)[idx_r];
79     case RPM_INT32_TYPE:
80       return ((int32_t*)val)[idx_r];
81     }
82   }
83   return 0;
84 }
85
86 ///////////////////////////////////////////////////////////////////
87 //
88 //        CLASS NAME : BinHeader::stringList
89 //
90 ///////////////////////////////////////////////////////////////////
91
92 void BinHeader::stringList::clear()
93 {
94   if ( val )
95     free( val );
96   val = 0;
97   cnt = 0;
98 }
99
100 BinHeader::stringList::stringList()
101     : cnt( 0 ), val( 0 )
102 {}
103
104 unsigned BinHeader::stringList::set( char ** val_r, unsigned cnt_r )
105 {
106   clear();
107   val = val_r;
108   cnt = val ? cnt_r : 0;
109   return cnt;
110 }
111
112 std::string BinHeader::stringList::operator[]( const unsigned idx_r ) const
113 {
114   return( idx_r < cnt ? val[idx_r] : "" );
115 }
116
117 ///////////////////////////////////////////////////////////////////
118 //
119 //        CLASS NAME : BinHeader
120 //
121 ///////////////////////////////////////////////////////////////////
122
123 ///////////////////////////////////////////////////////////////////
124 //
125 //
126 //        METHOD NAME : BinHeader::BinHeader
127 //        METHOD TYPE : Constructor
128 //
129 BinHeader::BinHeader( Header h_r )
130     : _h( h_r )
131 {
132   if ( _h )
133   {
134     headerLink( _h );
135   }
136 }
137
138 ///////////////////////////////////////////////////////////////////
139 //
140 //
141 //        METHOD NAME : BinHeader::BinHeader
142 //        METHOD TYPE : Constructor
143 //
144 BinHeader::BinHeader( BinHeader::Ptr & rhs )
145 {
146   INT << "INJECT from " << rhs;
147   if ( ! (rhs && rhs->_h) )
148   {
149     _h = 0;
150   }
151   else
152   {
153     _h = rhs->_h;  // ::headerLink already done in rhs
154     rhs->_h = 0;
155   }
156   INT << ": " << *this << "   (" << rhs << ")" << endl;
157 }
158
159 ///////////////////////////////////////////////////////////////////
160 //
161 //
162 //        METHOD NAME : BinHeader::~BinHeader
163 //        METHOD TYPE : Destructor
164 //
165 BinHeader::~BinHeader()
166 {
167   if ( _h )
168   {
169     headerFree( _h );
170   }
171 }
172
173 ///////////////////////////////////////////////////////////////////
174 //
175 //
176 //        METHOD NAME : BinHeader::assertHeader
177 //        METHOD TYPE : void
178 //
179 bool BinHeader::assertHeader()
180 {
181   if ( !_h )
182   {
183     _h = ::headerNew();
184     if ( !_h )
185     {
186       INT << "OOPS: NULL HEADER created!" << endl;
187       return false;
188     }
189   }
190   return true;
191 }
192
193 ///////////////////////////////////////////////////////////////////
194 //
195 //
196 //        METHOD NAME : BinHeader::has_tag
197 //        METHOD TYPE : bool
198 //
199 //        DESCRIPTION :
200 //
201 bool BinHeader::has_tag( tag tag_r ) const
202 {
203   return( !empty() && ::headerIsEntry( _h, tag_r ) );
204 }
205
206 ///////////////////////////////////////////////////////////////////
207 //
208 //
209 //        METHOD NAME : BinHeader::int_list
210 //        METHOD TYPE : unsigned
211 //
212 //        DESCRIPTION :
213 //
214 unsigned BinHeader::int_list( tag tag_r, intList & lst_r ) const
215 {
216   if ( !empty() )
217   {
218     rpmTagType type = RPM_NULL_TYPE;
219     rpm_count_t cnt = 0;
220     void * val  = 0;
221     ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
222
223     if ( val )
224     {
225       switch ( type )
226       {
227       case RPM_NULL_TYPE:
228         return lst_r.set( 0, 0, type );
229 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
230       case RPM_CHAR_TYPE:
231 #endif
232       case RPM_INT8_TYPE:
233       case RPM_INT16_TYPE:
234       case RPM_INT32_TYPE:
235         return lst_r.set( val, cnt, type );
236
237       case RPM_STRING_ARRAY_TYPE:
238         free( val );
239         // fall through
240       default:
241         INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << type << endl;
242       }
243     }
244   }
245   return lst_r.set( 0, 0, RPM_NULL_TYPE );
246 }
247
248 ///////////////////////////////////////////////////////////////////
249 //
250 //
251 //        METHOD NAME : BinHeader::string_list
252 //        METHOD TYPE : unsigned
253 //
254 //        DESCRIPTION :
255 //
256 unsigned BinHeader::string_list( tag tag_r, stringList & lst_r ) const
257 {
258   if ( !empty() )
259   {
260     rpmTagType type = RPM_NULL_TYPE;
261     rpm_count_t cnt = 0;
262     void * val  = 0;
263     ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
264
265     if ( val )
266     {
267       switch ( type )
268       {
269       case RPM_NULL_TYPE:
270         return lst_r.set( 0, 0 );
271       case RPM_STRING_ARRAY_TYPE:
272         return lst_r.set( (char**)val, cnt );
273
274       default:
275         INT << "RPM_TAG MISSMATCH: RPM_STRING_ARRAY_TYPE " << tag_r << " got type " << type << endl;
276       }
277     }
278   }
279   return lst_r.set( 0, 0 );
280 }
281
282 ///////////////////////////////////////////////////////////////////
283 //
284 //
285 //        METHOD NAME : BinHeader::int_val
286 //        METHOD TYPE : int
287 //
288 //        DESCRIPTION :
289 //
290 int BinHeader::int_val( tag tag_r ) const
291 {
292   if ( !empty() )
293   {
294     rpmTagType type = RPM_NULL_TYPE;
295     rpm_count_t cnt = 0;
296     void * val  = 0;
297     ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
298
299     if ( val )
300     {
301       switch ( type )
302       {
303       case RPM_NULL_TYPE:
304         return 0;
305 #if RPM_CHAR_TYPE != RPM_INT8_TYPE
306       case RPM_CHAR_TYPE:
307         return *((char*)val);
308 #endif
309       case RPM_INT8_TYPE:
310         return *((int8_t*)val);
311       case RPM_INT16_TYPE:
312         return *((int16_t*)val);
313       case RPM_INT32_TYPE:
314         return *((int32_t*)val);
315
316       case RPM_STRING_ARRAY_TYPE:
317         free( val );
318         // fall through
319       default:
320         INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << type << endl;
321       }
322     }
323   }
324   return 0;
325 }
326
327 ///////////////////////////////////////////////////////////////////
328 //
329 //
330 //        METHOD NAME : BinHeader::string_val
331 //        METHOD TYPE : std::string
332 //
333 //        DESCRIPTION :
334 //
335 std::string BinHeader::string_val( tag tag_r ) const
336 {
337   if ( !empty() )
338   {
339     rpmTagType type = RPM_NULL_TYPE;
340     rpm_count_t cnt = 0;
341     void * val  = 0;
342     ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
343
344     if ( val )
345     {
346       switch ( type )
347       {
348       case RPM_NULL_TYPE:
349         return "";
350       case RPM_STRING_TYPE:
351         return (char*)val;
352
353       case RPM_STRING_ARRAY_TYPE:
354         free( val );
355         // fall through
356       default:
357         INT << "RPM_TAG MISSMATCH: RPM_STRING_TYPE " << tag_r << " got type " << type << endl;
358       }
359     }
360   }
361   return "";
362 }
363
364 ///////////////////////////////////////////////////////////////////
365 //
366 //
367 //        METHOD NAME : BinHeader::stringList_val
368 //        METHOD TYPE : std::list<std::string>
369 //
370 //        DESCRIPTION :
371 //
372 std::list<std::string> BinHeader::stringList_val( tag tag_r ) const
373 {
374   std::list<std::string> ret;
375
376   if ( !empty() )
377   {
378     stringList lines;
379     unsigned count = string_list( tag_r, lines );
380     for ( unsigned i = 0; i < count; ++i )
381     {
382       ret.push_back( lines[i] );
383     }
384   }
385   return ret;
386 }
387
388 ///////////////////////////////////////////////////////////////////
389 //
390 //
391 //      METHOD NAME : BinHeader::dumpOn
392 //      METHOD TYPE : ostream &
393 //
394 //      DESCRIPTION :
395 //
396 ostream & BinHeader::dumpOn( ostream & str ) const
397 {
398   ReferenceCounted::dumpOn( str );
399   return str << '{' << (void*)_h << '}';
400 }
401
402 } // namespace rpm
403 } // namespace target
404 } // namespace zypp