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