forked from Steve132/ubj
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ubj.h
243 lines (183 loc) · 6.76 KB
/
ubj.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
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#ifndef UBJ_H
#define UBJ_H
#ifdef __cplusplus
extern "C" {
#endif
#include<inttypes.h>
#include<stdio.h>
typedef enum
{
UBJ_MIXED=0, //NOT a type...or the type is mixed
UBJ_NULLTYPE,
UBJ_NOOP,
UBJ_BOOL_TRUE,
UBJ_BOOL_FALSE,
UBJ_CHAR,
UBJ_STRING,
UBJ_HIGH_PRECISION,
UBJ_INT8,
UBJ_UINT8 ,
UBJ_INT16,
UBJ_UINT16,
UBJ_INT32,
UBJ_UINT32,
UBJ_INT64,
UBJ_UINT64,
UBJ_FLOAT16,
UBJ_FLOAT32,
UBJ_FLOAT64,
UBJ_ARRAY,
UBJ_OBJECT,
UBJ_NUM_TYPES //this is the size of how many types there are (chris' trick)
} UBJ_TYPE;
typedef union ubj_float16
{
uint8_t byte[2];
uint16_t val;
} bjd_half;
//////////here is the declarations for the writer API////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
struct ubjw_context_t_s;
typedef struct ubjw_context_t_s ubjw_context_t;
ubjw_context_t* ubjw_open_callback(void* userdata,
size_t(*write_cb)(const void* data, size_t size, size_t count, void* userdata),
int(*close_cb)(void* userdata),
void(*error_cb)(const char* error_msg)
);
ubjw_context_t* ubjw_open_file(FILE*);
ubjw_context_t* ubjw_open_memory(uint8_t* dst_b, uint8_t* dst_e);
size_t ubjw_close_context(ubjw_context_t* ctx);
void ubjw_write_string(ubjw_context_t* dst, const char* out);
void ubjw_write_char(ubjw_context_t* dst, char out);
void ubjw_write_int8(ubjw_context_t* dst, int8_t out);
void ubjw_write_uint8(ubjw_context_t* dst, uint8_t out);
void ubjw_write_int16(ubjw_context_t* dst, int16_t out);
void ubjw_write_uint16(ubjw_context_t* dst, uint16_t out);
void ubjw_write_int32(ubjw_context_t* dst, int32_t out);
void ubjw_write_uint32(ubjw_context_t* dst, uint32_t out);
void ubjw_write_int64(ubjw_context_t* dst, int64_t out);
void ubjw_write_uint64(ubjw_context_t* dst, uint64_t out);
void ubjw_write_high_precision(ubjw_context_t* dst, const char* hp);
void ubjw_write_integer(ubjw_context_t* dst, int64_t out);
UBJ_TYPE ubjw_min_integer_type(int64_t in);
void ubjw_write_float16(ubjw_context_t* dst, uint16_t out);
void ubjw_write_float32(ubjw_context_t* dst, float out);
void ubjw_write_float64(ubjw_context_t* dst, double out);
void ubjw_write_floating_point(ubjw_context_t* dst, double out);
void ubjw_write_noop(ubjw_context_t* dst);
void ubjw_write_null(ubjw_context_t* dst);
void ubjw_write_bool(ubjw_context_t* dst, uint8_t out);
void ubjw_begin_array(ubjw_context_t* dst, UBJ_TYPE type, size_t count);
void ubjw_begin_object(ubjw_context_t* dst, UBJ_TYPE type, size_t count);
void ubjw_write_key(ubjw_context_t* dst, const char* key);
void ubjw_end(ubjw_context_t* dst);
//output an efficient buffer of types
void ubjw_write_buffer(ubjw_context_t* dst, const uint8_t* data, UBJ_TYPE type, size_t count);
//Proposal for N-D arrays
void ubjw_begin_ndarray(ubjw_context_t* dst, UBJ_TYPE type, const size_t* dims, uint8_t ndims);
void ubjw_write_ndbuffer(ubjw_context_t* dst,const uint8_t* data, UBJ_TYPE type, const size_t* dims, uint8_t ndims);
//////////here is the declarations for the reader API////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
struct ubjr_context_t_s;
typedef struct ubjr_context_t_s ubjr_context_t;
//Open up a reader context for reading using a custom calllback
ubjr_context_t* ubjr_open_callback(void* userdata,
size_t(*read_cb)(void* data, size_t size, size_t count, void* userdata),
int(*peek_cb)(void* userdata),
int(*close_cb)(void* userdata),
void(*error_cb)(const char* error_msg)
);
//Open a context initialized to a UBJ file
ubjr_context_t* ubjr_open_file(FILE*);
//Open up a context initialized to a memory dump of a UBJ file (or a segment of a UBJ file)
ubjr_context_t* ubjr_open_memory(const uint8_t* dst_b, const uint8_t* dst_e);
//Close a reader context
size_t ubjr_close_context(ubjr_context_t* ctx);
typedef char* ubjr_string_t;
//An array that you read from the stream
typedef struct ubjr_array_t_s
{
uint8_t originally_sized;
UBJ_TYPE type;
size_t size; //total number of elements
void* values;
uint8_t num_dims;
size_t* dims; //this could be faster if it was constant size, but would also make the size of the dynamic object a LOT bigger
} ubjr_array_t;
//a map that you read from the stream
typedef struct ubjr_object_t_s
{
uint8_t originally_sized;
UBJ_TYPE type;
size_t size;
void* values;
ubjr_string_t* keys;
void* metatable; //don't use this..only useful for computing object_lookup
} ubjr_object_t;
//a dynamic type that you parsed.
typedef struct ubjr_dynamic_t_s
{
UBJ_TYPE type;
union
{
uint8_t boolean;
uint16_t half;
double real;
int64_t integer;
ubjr_string_t string;
ubjr_array_t container_array;
ubjr_object_t container_object;
};
} ubjr_dynamic_t;
//Parse a dynamic object from the stream
ubjr_dynamic_t ubjr_read_dynamic(ubjr_context_t* ctx);
void ubjr_cleanup_dynamic(ubjr_dynamic_t* dyn);
ubjr_dynamic_t ubjr_object_lookup(ubjr_object_t* obj, const char* key);
size_t ubjr_local_type_size(UBJ_TYPE typ);//should be equivalent to sizeof()
size_t ubjr_ndarray_index(const ubjr_array_t* arr, const size_t* indices);
//output an efficient buffer of types
///void ubjr_read_buffer(struct ubjr_context_t* dst, const uint8_t* data, UBJ_TYPE type, size_t count);
void ubjr_cleanup_dynamic(ubjr_dynamic_t* dyn);
void ubjr_cleanup_array(ubjr_array_t* arr);
void ubjr_cleanup_object(ubjr_object_t* obj);
///////UBJ_RW api
void ubjrw_write_dynamic(ubjw_context_t* ctx, ubjr_dynamic_t dobj,uint8_t optimize);
//ubjrw_append_object(ubjw_context_t* ctx, ubjr_dynamic_t dobj);
//ubjrw_append_array(ubjw_context_t* ctx, ubjr_dynamic_t dobj);
#ifdef __cplusplus
}
#include<iostream>
static size_t write_os(const void* data, size_t size, size_t count, void* userdata)
{
size_t n = size*count;
reinterpret_cast<std::ostream*>(userdata)->write(data, n);
return n;
}
static void close_os(void* userdata)
{
reinterpret_cast<std::ostream*>(userdata)->close();
}
static size_t read_is(void* data, size_t size, size_t count, void* userdata)
{
size_t n = size*count;
reinterpret_cast<std::istream*>(userdata)->read(data, n);
return n;
}
static int peek_is(void* userdata)
{
return reinterpret_cast<std::istream*>(userdata)->peek();
}
static void close_is(void* userdata)
{
reinterpret_cast<std::istream*>(userdata)->close();
}
static ubjw_context_t* ubjw_open_stream(std::ostream& outstream)
{
return ubjw_open_callback((void*)&outstream, write_os, close_os, NULL);
}
static ubjr_context_t* ubjr_open_stream(std::istream& instream)
{
return ubjr_open_callback((void*)&instream, read_is, peek_is, close_is, NULL);
}
#endif
#endif