-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnanocnp.h
107 lines (86 loc) · 2.31 KB
/
nanocnp.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
#pragma once
#ifndef _NANOCNP_H_INCLUDED
#define _NANOCNP_H_INCLUDED
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ncnp_word
{
unsigned char bytes[8];
} __attribute__((aligned(8)));
typedef struct ncnp_word const *ncnp_word_rptr;
struct ncnp_rbuf
{
/* end points one past the last word. */
const struct ncnp_word *start, *end;
};
struct ncnp_struct_meta
{
struct ncnp_rbuf ptr_target_area;
/*
* If n_pointers != 0, then this is guaranteed to point to a real
* struct, and pointers in that struct may be followed. Otherwise
* this may be null if it's in, say, an ncnp_struct_1w.
*/
ncnp_word_rptr data;
uint16_t n_data_words; /* if nonzero, data points somewhere */
uint16_t n_pointers;
};
struct ncnp_list_meta
{
struct ncnp_rbuf ptr_target_area;
ncnp_word_rptr data;
unsigned int elemtype : 3;
uint32_t list_elems : 29;
uint32_t nott1_stride_in_bytes;
uint16_t n_full_data_words;
uint16_t n_pointers;
};
static inline uint64_t ncnp_load_word(ncnp_word_rptr p)
{
return ((uint64_t)p->bytes[0] |
(uint64_t)p->bytes[1] << 8 |
(uint64_t)p->bytes[2] << 16 |
(uint64_t)p->bytes[3] << 24 |
(uint64_t)p->bytes[4] << 32 |
(uint64_t)p->bytes[5] << 40 |
(uint64_t)p->bytes[6] << 48 |
(uint64_t)p->bytes[7] << 56);
/*
* This does not invoke undefined behavior, and it is correct
* on any little-endian architecture. Gcc 5.0 and above
* can optimize the code above, though, so we don't need
* it.
union {
uint64_t val;
unsigned char bytes[8];
} ret;
memcpy(&ret.bytes, p, 8);
return ret.val;
*/
}
static uint32_t ncnp_ptrval_type(uint64_t ptrval)
{
return ptrval & 3;
}
int ncnp_decode_structptr(struct ncnp_struct_meta *meta,
ncnp_word_rptr pptr,
struct ncnp_rbuf targetbuf);
int ncnp_decode_root(struct ncnp_struct_meta *obj,
struct ncnp_rbuf in);
int ncnp_decode_listptr(struct ncnp_list_meta *meta,
ncnp_word_rptr pptr,
struct ncnp_rbuf targetbuf);
bool ncnp_list_get_bit(const struct ncnp_list_meta *list, size_t i);
unsigned char *ncnp_list_get_datum(const struct ncnp_list_meta *list, size_t i);
void ncnp_list_get_struct(struct ncnp_struct_meta *dest,
const struct ncnp_list_meta *list,
size_t i);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _NANOCNP_H_INCLUDED */