Line data Source code
1 : /*
2 : * libpino - pino.c
3 : *
4 : */
5 : #include <stdio.h>
6 :
7 : #include <stdbool.h>
8 : #include <stddef.h>
9 : #include <stdint.h>
10 :
11 : #include <pino.h>
12 : #include <pino/handler.h>
13 :
14 : #include <pino_internal.h>
15 :
16 1006 : static inline pino_t *pino_create(pino_magic_safe_t magic, pino_handler_t *handler, size_t size)
17 : {
18 : pino_t *pino;
19 :
20 1006 : pino = pmalloc(sizeof(pino_t));
21 1006 : if (!pino) {
22 : return NULL; /* LCOV_EXCL_LINE */
23 : }
24 :
25 1006 : pmemcpy(pino->magic, magic, sizeof(pino_magic_t));
26 1006 : pino->magic[sizeof(pino_magic_t)] = '\0';
27 1006 : pino->static_fields_size = handler->static_fields_size;
28 1006 : pino->static_fields = pcalloc(1, pino->static_fields_size);
29 1006 : if (!pino->static_fields) {
30 : /* LCOV_EXCL_START */
31 : pfree(pino);
32 : return NULL;
33 : /* LCOV_EXCL_STOP */
34 : }
35 1006 : pino->handler = handler;
36 1006 : pino->this = handler->create(size, pino->static_fields);
37 1006 : if (!pino->this) {
38 : PINO_SUPRTF("handler->create failed");
39 0 : pfree(pino);
40 0 : return NULL;
41 : }
42 :
43 1006 : return pino;
44 : }
45 :
46 18 : extern bool pino_init(void)
47 : {
48 18 : return pino_handler_init(HANDLER_STEP);
49 : }
50 :
51 18 : extern void pino_free(void)
52 : {
53 18 : pino_handler_free();
54 18 : }
55 :
56 3 : extern size_t pino_serialize_size(const pino_t *pino)
57 : {
58 3 : if (!pino) {
59 1 : return 0;
60 : }
61 :
62 : PINO_SUPRTF("magic: %.4s, serialize_size: %zu, magic_size: %zu", pino->magic, pino->handler->serialize_size(pino->this, pino->static_fields), sizeof(pino_magic_t));
63 :
64 2 : return pino->handler->serialize_size(pino->this, pino->static_fields) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + pino->static_fields_size;
65 : }
66 :
67 3 : extern bool pino_serialize(const pino_t *pino, void *dest)
68 : {
69 3 : if (!pino || !dest) {
70 1 : return false;
71 : }
72 :
73 2 : pmemcpy(dest, pino->magic, sizeof(pino_magic_t));
74 2 : pmemcpy_n2l(((char *)dest) + sizeof(pino_magic_t), &pino->static_fields_size, sizeof(pino_static_fields_size_t));
75 :
76 : /* fields always use LE */
77 2 : pmemcpy(((char *)dest) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t), pino->static_fields, pino->static_fields_size);
78 :
79 2 : return pino->handler->serialize(pino->this, pino->static_fields, ((char *)dest) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + pino->handler->static_fields_size);
80 : }
81 :
82 7 : extern pino_t *pino_unserialize(const void *src, size_t size)
83 : {
84 : pino_t *pino;
85 : pino_handler_t *handler;
86 : pino_magic_safe_t magic;
87 : pino_static_fields_size_t fields_size;
88 :
89 7 : if (!src) {
90 1 : return NULL;
91 : }
92 :
93 6 : if (size < sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t)) {
94 1 : return NULL;
95 : }
96 :
97 5 : pmemcpy(magic, src, sizeof(pino_magic_t));
98 5 : pmemcpy_l2n(&fields_size, ((char *)src) + sizeof(pino_magic_t), sizeof(pino_static_fields_size_t));
99 :
100 5 : if (size < sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + fields_size) {
101 1 : return NULL;
102 : }
103 :
104 4 : handler = pino_handler_find(magic);
105 4 : if (!handler) {
106 1 : return NULL;
107 : }
108 :
109 3 : pino = pino_create(magic, handler, size - sizeof(pino_magic_t) - sizeof(pino_static_fields_size_t) - fields_size);
110 3 : if (!pino) {
111 : return NULL; /* LCOV_EXCL_LINE */
112 : }
113 :
114 : /* always LE */
115 3 : pmemcpy(pino->static_fields, ((char *)src) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t), fields_size);
116 3 : if (!handler->unserialize(pino->this, pino->static_fields, ((char *)src) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + fields_size, size)) {
117 1 : pino_destroy(pino);
118 1 : return NULL;
119 : }
120 :
121 2 : return pino;
122 : }
123 :
124 1007 : extern pino_t *pino_pack(pino_magic_safe_t magic, const void *src, size_t size)
125 : {
126 : pino_t *pino;
127 : pino_handler_t *handler;
128 :
129 1007 : handler = pino_handler_find(magic);
130 1007 : if (!handler) {
131 : PINO_SUPRTF("handler not found : %s", magic);
132 4 : return NULL;
133 : }
134 :
135 1003 : pino = pino_create(magic, handler, size);
136 1003 : if (!pino) {
137 : PINO_SUPRTF("pino_create failed");
138 0 : return NULL;
139 : }
140 :
141 1003 : if (!handler->pack(pino->this, pino->static_fields, src, size)) {
142 0 : pino_destroy(pino);
143 : PINO_SUPRTF("handler->pack failed");
144 0 : return NULL;
145 : }
146 :
147 1003 : return pino;
148 : }
149 :
150 5 : extern size_t pino_unpack_size(const pino_t *pino)
151 : {
152 : PINO_SUPRTF("magic: %.4s, unpack_size: %zu", pino->magic, pino->handler->unpack_size(pino->this, pino->static_fields));
153 :
154 5 : return pino->handler->unpack_size(pino->this, pino->static_fields);
155 : }
156 :
157 4 : extern bool pino_unpack(const pino_t *pino, void *dest)
158 : {
159 4 : return pino->handler->unpack(pino->this, pino->static_fields, dest);
160 : }
161 :
162 1007 : extern void pino_destroy(pino_t *pino)
163 : {
164 1007 : if (!pino) {
165 1 : return;
166 : }
167 :
168 1006 : if (pino->this) {
169 1006 : pino->handler->destroy(pino->this, pino->static_fields);
170 : }
171 :
172 1006 : if (pino->static_fields) {
173 1006 : pfree(pino->static_fields);
174 : }
175 :
176 1006 : pfree(pino);
177 : }
178 :
179 1 : extern uint32_t pino_version_id()
180 : {
181 1 : return (uint32_t)PINO_VERSION_ID;
182 : }
183 :
184 1 : extern pino_buildtime_t pino_buildtime()
185 : {
186 1 : return (pino_buildtime_t)PINO_BUILDTIME;
187 : }
|