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