1 /*
2 **  OSSP uuid - Universally Unique Identifier
3 **  Copyright (c) 2004-2007 Ralf S. Engelschall <rse@engelschall.com>
4 **  Copyright (c) 2004-2007 The OSSP Project <http://www.ossp.org/>
5 **
6 **  This file is part of OSSP uuid, a library for the generation
7 **  of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
8 **
9 **  Permission to use, copy, modify, and distribute this software for
10 **  any purpose with or without fee is hereby granted, provided that
11 **  the above copyright notice and this permission notice appear in all
12 **  copies.
13 **
14 **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
15 **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
18 **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 **  SUCH DAMAGE.
26 **
27 **  uuid.xs: Perl Binding (Perl/XS part)
28 */
29 
30 #include "uuid.h"
31 
32 #include "EXTERN.h"
33 #include "perl.h"
34 #include "XSUB.h"
35 
36 MODULE = OSSP::uuid PACKAGE = OSSP::uuid
37 
38 void
39 constant(sv)
40     PREINIT:
41         dXSTARG;
42         STRLEN          len;
43         int             i;
44         static struct {
45             const char *name;
46             int         value;
47         } constant_table[] = {
48             { "UUID_VERSION", UUID_VERSION },
49             { "UUID_LEN_BIN", UUID_LEN_BIN },
50             { "UUID_LEN_STR", UUID_LEN_STR },
51             { "UUID_LEN_SIV", UUID_LEN_SIV },
52             { "UUID_RC_OK",   UUID_RC_OK   },
53             { "UUID_RC_ARG",  UUID_RC_ARG  },
54             { "UUID_RC_MEM",  UUID_RC_MEM  },
55             { "UUID_RC_SYS",  UUID_RC_SYS  },
56             { "UUID_RC_INT",  UUID_RC_INT  },
57             { "UUID_RC_IMP",  UUID_RC_IMP  },
58             { "UUID_MAKE_V1", UUID_MAKE_V1 },
59             { "UUID_MAKE_V3", UUID_MAKE_V3 },
60             { "UUID_MAKE_V4", UUID_MAKE_V4 },
61             { "UUID_MAKE_V5", UUID_MAKE_V5 },
62             { "UUID_MAKE_MC", UUID_MAKE_MC },
63             { "UUID_FMT_BIN", UUID_FMT_BIN },
64             { "UUID_FMT_STR", UUID_FMT_STR },
65             { "UUID_FMT_SIV", UUID_FMT_SIV },
66             { "UUID_FMT_TXT", UUID_FMT_TXT }
67         };
68     INPUT:
69         SV             *sv;
70         const char     *s = SvPV(sv, len);
71     PPCODE:
72         for (i = 0; i < sizeof(constant_table)/sizeof(constant_table[0]); i++) {
73             if (strcmp(s, constant_table[i].name) == 0) {
74                 EXTEND(SP, 1);
75                 PUSHs(&PL_sv_undef);
76                 PUSHi(constant_table[i].value);
77                 break;
78             }
79         }
80         if (i == sizeof(constant_table)/sizeof(constant_table[0])) {
81             sv = sv_2mortal(newSVpvf("unknown contant OSSP::uuid::%s", s));
82             PUSHs(sv);
83         }
84 
85 
86 uuid_rc_t
87 uuid_create(uuid)
88     PROTOTYPE:
89         $
90     INPUT:
91         uuid_t *&uuid = NO_INIT
92     CODE:
93         RETVAL = uuid_create(&uuid);
94     OUTPUT:
95         uuid
96         RETVAL
97 
98 uuid_rc_t
99 uuid_destroy(uuid)
100     PROTOTYPE:
101         $
102     INPUT:
103         uuid_t *uuid
104     CODE:
105         RETVAL = uuid_destroy(uuid);
106     OUTPUT:
107         RETVAL
108 
109 uuid_rc_t
110 uuid_load(uuid,name)
111     PROTOTYPE:
112         $$
113     INPUT:
114         uuid_t *uuid
115         const char *name
116     CODE:
117         RETVAL = uuid_load(uuid, name);
118     OUTPUT:
119         RETVAL
120 
121 uuid_rc_t
122 uuid_make(uuid,mode,...)
123     PROTOTYPE:
124         $$;$$
125     INPUT:
126         uuid_t *uuid
127         unsigned int mode
128     PREINIT:
129         uuid_t *ns;
130         const char *name;
131     CODE:
132         if ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5)) {
133             if (items != 4)
134                 croak("mode UUID_MAKE_V3/UUID_MAKE_V5 requires two additional arguments to uuid_make()");
135 	        if (!SvROK(ST(2)))
136                 croak("mode UUID_MAKE_V3/UUID_MAKE_V5 requires a UUID object as namespace");
137             ns   = INT2PTR(uuid_t *, SvIV((SV*)SvRV(ST(2))));
138             name = (const char *)SvPV_nolen(ST(3));
139             RETVAL = uuid_make(uuid, mode, ns, name);
140         }
141         else {
142             if (items != 2)
143                 croak("invalid number of arguments to uuid_make()");
144             RETVAL = uuid_make(uuid, mode);
145         }
146     OUTPUT:
147         RETVAL
148 
149 uuid_rc_t
150 uuid_isnil(uuid,result)
151     PROTOTYPE:
152         $$
153     INPUT:
154         uuid_t *uuid
155         int &result = NO_INIT
156     CODE:
157         RETVAL = uuid_isnil(uuid, &result);
158     OUTPUT:
159         result
160         RETVAL
161 
162 uuid_rc_t
163 uuid_compare(uuid,uuid2,result)
164     PROTOTYPE:
165         $$$
166     INPUT:
167         uuid_t *uuid
168         uuid_t *uuid2
169         int &result = NO_INIT
170     CODE:
171         RETVAL = uuid_compare(uuid, uuid2, &result);
172     OUTPUT:
173         result
174         RETVAL
175 
176 uuid_rc_t
177 uuid_import(uuid,fmt,data_ptr,data_len)
178     PROTOTYPE:
179         $$$$
180     INPUT:
181         uuid_t *uuid
182         uuid_fmt_t fmt
183         const void *data_ptr
184         size_t data_len
185     CODE:
186         if (ST(3) == &PL_sv_undef)
187             data_len = sv_len(ST(2));
188         RETVAL = uuid_import(uuid, fmt, data_ptr, data_len);
189     OUTPUT:
190         RETVAL
191 
192 uuid_rc_t
193 uuid_export(uuid,fmt,data_ptr,data_len)
194     PROTOTYPE:
195         $$$$
196     INPUT:
197         uuid_t *uuid
198         uuid_fmt_t fmt
199         void *&data_ptr = NO_INIT
200         size_t &data_len = NO_INIT
201     PPCODE:
202         data_ptr = NULL;
203         data_len = 0;
204         RETVAL = uuid_export(uuid, fmt, &data_ptr, &data_len);
205         if (RETVAL == UUID_RC_OK) {
206             if (fmt == UUID_FMT_SIV)
207                 data_len = strlen((char *)data_ptr);
208             else if (fmt == UUID_FMT_STR || fmt == UUID_FMT_TXT)
209                 data_len--; /* Perl doesn't wish NUL-termination on strings */
210             sv_setpvn(ST(2), data_ptr, data_len);
211             free(data_ptr);
212             if (ST(3) != &PL_sv_undef)
213                 sv_setuv(ST(3), (UV)data_len);
214         }
215         PUSHi((IV)RETVAL);
216 
217 char *
218 uuid_error(rc)
219     PROTOTYPE:
220         $
221     INPUT:
222         uuid_rc_t rc
223     CODE:
224         RETVAL = uuid_error(rc);
225     OUTPUT:
226         RETVAL
227 
228 unsigned long
229 uuid_version()
230     PROTOTYPE:
231     INPUT:
232     CODE:
233         RETVAL = uuid_version();
234     OUTPUT:
235         RETVAL
236 
237