1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/*
* $Id: RPM.h,v 1.2 2000/05/27 05:22:51 rjray Exp $
*
* Various C-specific decls/includes/etc. for the RPM linkage
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifndef H_RPM_XS_HDR
#define H_RPM_XS_HDR
#ifdef Stat
# undef Stat
#endif
#ifdef Mkdir
# undef Mkdir
#endif
#ifdef Fstat
# undef Fstat
#endif
#ifdef Fflush
# undef Fflush
#endif
// Borrowed from DB_File.xs
#ifndef pTHX
# define pTHX
# define pTHX_
# define aTHX
# define aTHX_
#endif
#ifndef newSVpvn
# define newSVpvn(a,b) newSVpv(a,b)
#endif
#include <rpm/rpmlib.h>
#include <rpm/header.h>
#include <rpm/dbindex.h>
//
// This is the underlying struct that implements the interface to the RPM
// database. Since we need the actual object to be a hash, the struct will
// be stored as an SV (actually, a pointer to a struct) on a special key
// defined below.
//
typedef struct {
rpmdb dbp;
int current_rec;
dbiIndexSet* index_set;
} RPM_Database;
typedef HV* RPM__Database;
#define new_RPM__Database(x) x = newHV()
//
// This is the underlying struct that implements the interface to the RPM
// headers. As above, we need the actual object to be a hash, so the struct
// will be stored as an SV on the same sort of special key as RPM__Database
// uses.
//
typedef struct {
Header hdr;
// These three tags will probably cover at leas 80% of data requests
const char* name;
const char* version;
const char* release;
// These are set by rpmReadPackageHeader when applicable
int isSource; // If this header is for a source RPM (SRPM)
int major; // Major and minor rev numbers of package's format
int minor;
// Keep a per-header iterator for things like FIRSTKEY and NEXTKEY
HeaderIterator iterator;
int read_only;
} RPM_Header;
typedef HV* RPM__Header;
#define new_RPM__Header(x) x = newHV()
#define RPM_HEADER_READONLY 1
#define RPM_HEADER_FROM_REF 2
// Because the HV* are going to be set magical, the following is needed for
// explicit fetch and store calls that are done within the tied FETCH/STORE
#define hv_fetch_nomg(SVP, h, k, kl, f) \
SvMAGICAL_off((SV *)(h)); \
(SVP) = hv_fetch((h), (k), (kl), (f)); \
SvMAGICAL_on((SV *)(h))
#define hv_store_nomg(h, k, kl, v, f) \
SvMAGICAL_off((SV *)(h)); \
hv_store((h), (k), (kl), (v), (f)); \
SvMAGICAL_on((SV *)(h))
//
// This silly-looking key is what will be used on the RPM::Header and
// RPM::Database objects to stash the underlying struct.
//
#define STRUCT_KEY "<<<struct>>>"
// This must match!
#define STRUCT_KEY_LEN 13
//
// This struct will be used for RPM data type coming out of an RPM::Header
// object. It will be implemented as a tied scalar, so we shouldn't need any
// weird private-key voodoo like for the two previous.
//
typedef struct {
SV* value; // May be an SV* or a ptr to an AV*
int size; // Number of items
int type; // Will match one of the RPM_*_TYPE values.
} RPM_Header_datum;
typedef RPM_Header_datum* RPM__Header__datum;
#define new_RPM__Header__datum(x) Newz(TRUE, (x), 1, RPM_Header_datum)
//
// These represent the various interfaces that are allowed for use outside
// their native modules.
//
// RPM.xs:
extern int tag2num(const char *);
extern const char* num2tag(int);
extern void clear_errors(void);
extern SV* set_error_callback(SV *);
extern void rpm_error(int, const char *);
// RPM/Header.xs:
extern const char* sv2key(SV *);
extern RPM__Header rpmhdr_TIEHASH(SV *, SV *, int);
extern AV* rpmhdr_FETCH(RPM__Header, SV *, const char *, int, int);
extern int rpmhdr_STORE(RPM__Header, SV *, AV *);
extern int rpmhdr_DELETE(RPM__Header, SV *);
extern int rpmhdr_EXISTS(RPM__Header, SV *);
extern unsigned int rpmhdr_size(RPM__Header);
extern int rpmhdr_tagtype(RPM__Header, SV *);
extern int rpmhdr_write(RPM__Header, SV *, int);
// RPM/Database.xs:
extern RPM__Database rpmdb_TIEHASH(char *, SV *);
extern RPM__Header rpmdb_FETCH(RPM__Database, SV *);
extern int rpmdb_EXISTS(RPM__Database, SV *);
#endif /* H_RPM_XS_HDR */
|