4eb00d5e8d10df10bb318e294b2411ddc528801a
[perl.git] / ext / GDBM_File / GDBM_File.xs
1 #define PERL_NO_GET_CONTEXT
2
3 #include "EXTERN.h"
4 #include "perl.h"
5 #include "XSUB.h"
6
7 #include <gdbm.h>
8 #include <fcntl.h>
9
10 #define fetch_key 0
11 #define store_key 1
12 #define fetch_value 2
13 #define store_value 3
14
15 typedef struct {
16         GDBM_FILE       dbp ;
17         SV *    filter[4];
18         int     filtering ;
19         } GDBM_File_type;
20
21 typedef GDBM_File_type * GDBM_File ;
22 typedef datum datum_key ;
23 typedef datum datum_value ;
24 typedef datum datum_key_copy;
25
26 #define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
27
28 typedef void (*FATALFUNC)();
29
30 #ifndef GDBM_FAST
31 static int
32 not_here(char *s)
33 {
34     croak("GDBM_File::%s not implemented on this architecture", s);
35     return -1;
36 }
37 #endif
38
39 /* GDBM allocates the datum with system malloc() and expects the user
40  * to free() it.  So we either have to free() it immediately, or have
41  * perl free() it when it deallocates the SV, depending on whether
42  * perl uses malloc()/free() or not. */
43 static void
44 output_datum(pTHX_ SV *arg, char *str, int size)
45 {
46         sv_setpvn(arg, str, size);
47 #       undef free
48         free(str);
49 }
50
51 /* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
52    gdbm_exists, and gdbm_setopt functions.  Apparently Slackware
53    (Linux) 2.1 contains gdbm-1.5 (which dates back to 1991).
54 */
55 #ifndef GDBM_FAST
56 #define gdbm_exists(db,key) not_here("gdbm_exists")
57 #define gdbm_sync(db) (void) not_here("gdbm_sync")
58 #define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
59 #endif
60
61 static void
62 croak_string(const char *message) {
63     Perl_croak_nocontext("%s", message);
64 }
65
66 #include "const-c.inc"
67
68 MODULE = GDBM_File      PACKAGE = GDBM_File     PREFIX = gdbm_
69
70 INCLUDE: const-xs.inc
71
72 GDBM_File
73 gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak_string)
74         char *          dbtype
75         char *          name
76         int             read_write
77         int             mode
78         FATALFUNC       fatal_func
79         CODE:
80         {
81             GDBM_FILE   dbp ;
82
83             RETVAL = NULL ;
84             if ((dbp =  gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode, fatal_func))) {
85                 RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type)) ;
86                 RETVAL->dbp = dbp ;
87             }
88             
89         }
90         OUTPUT:
91           RETVAL
92         
93
94 #define gdbm_close(db)                  gdbm_close(db->dbp)
95 void
96 gdbm_close(db)
97         GDBM_File       db
98         CLEANUP:
99
100 void
101 gdbm_DESTROY(db)
102         GDBM_File       db
103         PREINIT:
104         int i = store_value;
105         CODE:
106         gdbm_close(db);
107         do {
108             if (db->filter[i])
109                 SvREFCNT_dec(db->filter[i]);
110         } while (i-- > 0);
111         safefree(db);
112
113 #define gdbm_FETCH(db,key)                      gdbm_fetch(db->dbp,key)
114 datum_value
115 gdbm_FETCH(db, key)
116         GDBM_File       db
117         datum_key_copy  key
118
119 #define gdbm_STORE(db,key,value,flags)          gdbm_store(db->dbp,key,value,flags)
120 int
121 gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
122         GDBM_File       db
123         datum_key       key
124         datum_value     value
125         int             flags
126     CLEANUP:
127         if (RETVAL) {
128             if (RETVAL < 0 && errno == EPERM)
129                 croak("No write permission to gdbm file");
130             croak("gdbm store returned %d, errno %d, key \"%.*s\"",
131                         RETVAL,errno,key.dsize,key.dptr);
132         }
133
134 #define gdbm_DELETE(db,key)                     gdbm_delete(db->dbp,key)
135 int
136 gdbm_DELETE(db, key)
137         GDBM_File       db
138         datum_key       key
139
140 #define gdbm_FIRSTKEY(db)                       gdbm_firstkey(db->dbp)
141 datum_key
142 gdbm_FIRSTKEY(db)
143         GDBM_File       db
144
145 #define gdbm_NEXTKEY(db,key)                    gdbm_nextkey(db->dbp,key)
146 datum_key
147 gdbm_NEXTKEY(db, key)
148         GDBM_File       db
149         datum_key       key 
150
151 #define gdbm_reorganize(db)                     gdbm_reorganize(db->dbp)
152 int
153 gdbm_reorganize(db)
154         GDBM_File       db
155
156
157 #define gdbm_sync(db)                           gdbm_sync(db->dbp)
158 void
159 gdbm_sync(db)
160         GDBM_File       db
161
162 #define gdbm_EXISTS(db,key)                     gdbm_exists(db->dbp,key)
163 int
164 gdbm_EXISTS(db, key)
165         GDBM_File       db
166         datum_key       key
167
168 #define gdbm_setopt(db,optflag, optval, optlen) gdbm_setopt(db->dbp,optflag, optval, optlen)
169 int
170 gdbm_setopt (db, optflag, optval, optlen)
171         GDBM_File       db
172         int             optflag
173         int             &optval
174         int             optlen
175
176
177 SV *
178 filter_fetch_key(db, code)
179         GDBM_File       db
180         SV *            code
181         SV *            RETVAL = &PL_sv_undef ;
182         ALIAS:
183         GDBM_File::filter_fetch_key = fetch_key
184         GDBM_File::filter_store_key = store_key
185         GDBM_File::filter_fetch_value = fetch_value
186         GDBM_File::filter_store_value = store_value
187         CODE:
188             DBM_setFilter(db->filter[ix], code);