-
Notifications
You must be signed in to change notification settings - Fork 11
/
plcb-util.h
71 lines (55 loc) · 2.07 KB
/
plcb-util.h
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
#ifndef PLCB_UTIL_H_
#define PLCB_UTIL_H_
/*this stuff converts from SVs to int64_t (signed and unsigned) depending
on the perl*/
/*XXX:
12:54 < LeoNerd> mordy: Namely, my ( $hi, $lo ) = unpack "L> L>", $packed_64bit;
my $num = Math::BigInt->new( $hi ); $num >>= 32; $num |= $lo;
return $num;
12:55 < mordy> what about vice versa? or would i change my C interface to accept 2
32 bit integers and piece them back together there?
12:55 < LeoNerd> mordy: That might be simplest.
*/
#ifdef PLCB_PERL64
#define plcb_sv_to_u64(sv) SvUV(sv)
#define plcb_sv_to_64(sv) (int64_t)(plcb_sv_to_u64(sv))
#define plcb_sv_from_u64(sv, num) (sv_setuv(sv, num))
#define plcb_sv_from_u64_new(nump) newSVuv( (*nump) )
#define plcb_cas_from_sv(sv, cas_p, lenvar) \
(SvIOK(sv)) \
? cas_p = (uint64_t*)&(SvIVX(sv)) \
: (uint64_t*)die("Expected valid (UV) cas. IOK not true")
#else
static inline uint64_t plcb_sv_to_u64(SV *in)
{
char *sv_blob;
STRLEN blob_len;
uint64_t ret;
sv_blob = SvPV(in, blob_len);
if(blob_len != 8) {
die("expected 8-byte data string. Got %d", blob_len);
}
ret = *(uint64_t*)sv_blob;
return ret;
}
#define plcb_sv_to_64(sv) (plcb_sv_to_u64(sv))
#define plcb_sv_from_u64(sv, num) \
(sv_setpvn(sv, (const char const*)&(num), 8))
#define plcb_sv_from_u64_new(nump) \
newSVpv((const char* const)(nump), 8)
/*Extract a packed 8 byte blob from an SV into a CAS value*/
#define plcb_cas_from_sv(sv, cas_p, lenvar) \
((cas_p) = (uint64_t*)SvPV(sv, lenvar)) \
? (\
(lenvar == 8) \
? (cas_p) \
: (void*)die("Expected 8-byte CAS. Got %d", lenvar) \
) \
: (void*)die("CAS specified, but is null")
#endif /*PLCB_PERL64*/
/*assertively extract a non-null key from an SV, together with its length*/
#define plcb_get_str_or_die(ksv, charvar, lenvar, diespec) \
(charvar = SvPV(ksv, lenvar)) \
? ( (lenvar) ? charvar : (void*)die("Got zero-length %s", diespec) ) \
: (void*)die("Got NULL %s", diespec)
#endif /* PLCB_UTIL_H_ */