-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathendian.c
120 lines (105 loc) · 4.28 KB
/
endian.c
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
#define EXTUNIX_WANT_ENDIAN
#include "config.h"
#include "endian_helper.h"
#include <stdint.h>
/* Copyright © 2012 Goswin von Brederlow <[email protected]> */
/* Convert an intX_t from one endianness to another */
#define CONV(name, type, conv, type_val, val_type) \
CAMLprim value caml_extunix_##name(value v_x) \
{ \
type x = type_val(v_x); \
x = conv(x); \
return (val_type(x)); \
}
/* Get an intX_t out of a string */
#define GET(name, type, conv, Val_type) \
CAMLprim value caml_extunix_get_##name(value v_str, value v_off) { \
const char *str = String_val(v_str); \
size_t off = Long_val(v_off); \
type x; \
memcpy(&x, str + off, sizeof(x)); \
x = conv(x); \
return (Val_type(x)); \
}
/* Store an intX_t in a string */
#define SET(name, type, conv, Type_val) \
CAMLprim value caml_extunix_set_##name(value v_str, value v_off, value v_x) { \
unsigned char *str = Bytes_val(v_str); \
size_t off = Long_val(v_off); \
type x = Type_val(v_x); \
x = conv(x); \
memcpy(str + off, &x, sizeof(x)); \
return Val_unit; \
}
#if defined(EXTUNIX_HAVE_ENDIAN)
/* Big endian */
CONV(htobe16, uint16_t, htobe16, Long_val, Val_long)
CONV(htobe16_signed, int16_t, htobe16, Long_val, Val_long)
CONV(be16toh, uint16_t, be16toh, Long_val, Val_long)
CONV(be16toh_signed, int16_t, be16toh, Long_val, Val_long)
CONV(htobe31, uint32_t, htobe32, Long_val, Val_long)
CONV(htobe31_signed, int32_t, htobe32, Long_val, Val_long)
CONV(be31toh, uint32_t, be32toh, Long_val, Val_long)
CONV(be31toh_signed, int32_t, be32toh, Long_val, Val_long)
CONV(htobe32, int32_t, htobe32, Int32_val, caml_copy_int32)
CONV(be32toh, int32_t, be32toh, Int32_val, caml_copy_int32)
CONV(htobe64, int64_t, htobe64, Int64_val, caml_copy_int64)
CONV(be64toh, int64_t, be64toh, Int64_val, caml_copy_int64)
GET(bu16, uint16_t, be16toh, Val_long)
GET(bs16, int16_t, be16toh, Val_long)
GET(bu31, uint32_t, be32toh, Val_long)
GET(bs31, int32_t, be32toh, Val_long)
GET(bs32, int32_t, be32toh, caml_copy_int32)
GET(bu63, uint64_t, be64toh, Val_long)
GET(bs63, int64_t, be64toh, Val_long)
GET(bs64, int64_t, be64toh, caml_copy_int64)
SET(b16, uint16_t, htobe16, Long_val)
SET(b31, uint32_t, htobe32, Long_val)
SET(b32, uint32_t, htobe32, Int32_val)
SET(b63, uint64_t, htobe64, Long_val)
SET(b64, uint64_t, htobe64, Int64_val)
/* Little endian */
CONV(htole16, uint16_t, htole16, Long_val, Val_long)
CONV(htole16_signed, int16_t, htole16, Long_val, Val_long)
CONV(le16toh, uint16_t, le16toh, Long_val, Val_long)
CONV(le16toh_signed, int16_t, le16toh, Long_val, Val_long)
CONV(htole31, uint32_t, htole32, Long_val, Val_long)
CONV(htole31_signed, int32_t, htole32, Long_val, Val_long)
CONV(le31toh, uint32_t, le32toh, Long_val, Val_long)
CONV(le31toh_signed, int32_t, le32toh, Long_val, Val_long)
CONV(htole32, int32_t, htole32, Int32_val, caml_copy_int32)
CONV(le32toh, int32_t, le32toh, Int32_val, caml_copy_int32)
CONV(htole64, int64_t, htole64, Int64_val, caml_copy_int64)
CONV(le64toh, int64_t, le64toh, Int64_val, caml_copy_int64)
GET(lu16, uint16_t, le16toh, Val_long)
GET(ls16, int16_t, le16toh, Val_long)
GET(lu31, uint32_t, le32toh, Val_long)
GET(ls31, int32_t, le32toh, Val_long)
GET(ls32, int32_t, le32toh, caml_copy_int32)
GET(lu63, uint64_t, le64toh, Val_long)
GET(ls63, int64_t, le64toh, Val_long)
GET(ls64, int64_t, le64toh, caml_copy_int64)
SET(l16, uint16_t, htole16, Long_val)
SET(l31, uint32_t, htole32, Long_val)
SET(l32, uint32_t, htole32, Int32_val)
SET(l63, uint64_t, htole64, Long_val)
SET(l64, uint64_t, htole64, Int64_val)
#endif /* EXTUNIX_HAVE_ENDIAN */
/* Host endian */
#define id(x) x
GET(u8, uint8_t, id, Val_long)
GET(s8, int8_t, id, Val_long)
GET(hu16, uint16_t, id, Val_long)
GET(hs16, int16_t, id, Val_long)
GET(hu31, uint32_t, id, Val_long)
GET(hs31, int32_t, id, Val_long)
GET(hs32, int32_t, id, caml_copy_int32)
GET(hu63, uint64_t, id, Val_long)
GET(hs63, int64_t, id, Val_long)
GET(hs64, int64_t, id, caml_copy_int64)
SET(8, uint8_t, id, Long_val)
SET(h16, uint16_t, id, Long_val)
SET(h31, uint32_t, id, Long_val)
SET(h32, uint32_t, id, Int32_val)
SET(h63, uint64_t, id, Long_val)
SET(h64, uint64_t, id, Int64_val)