recordio.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include <recordio.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #include <stdlib.h>
  23. #ifndef WIN32
  24. #include <netinet/in.h>
  25. #else
  26. #include <winsock2.h> /* for _htonl and _ntohl */
  27. #endif
  28. void deallocate_String(char **s)
  29. {
  30. if (*s)
  31. free(*s);
  32. *s = 0;
  33. }
  34. void deallocate_Buffer(struct buffer *b)
  35. {
  36. if (b->buff)
  37. free(b->buff);
  38. b->buff = 0;
  39. }
  40. struct buff_struct {
  41. int32_t len;
  42. int32_t off;
  43. char *buffer;
  44. };
  45. static int resize_buffer(struct buff_struct *s, int newlen)
  46. {
  47. char *buffer= NULL;
  48. while (s->len < newlen) {
  49. s->len *= 2;
  50. }
  51. buffer = (char*)realloc(s->buffer, s->len);
  52. if (!buffer) {
  53. s->buffer = 0;
  54. return -ENOMEM;
  55. }
  56. s->buffer = buffer;
  57. return 0;
  58. }
  59. int oa_start_record(struct oarchive *oa, const char *tag)
  60. {
  61. return 0;
  62. }
  63. int oa_end_record(struct oarchive *oa, const char *tag)
  64. {
  65. return 0;
  66. }
  67. int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t *d)
  68. {
  69. struct buff_struct *priv = oa->priv;
  70. int32_t i = htonl(*d);
  71. if ((priv->len - priv->off) < sizeof(i)) {
  72. int rc = resize_buffer(priv, priv->len + sizeof(i));
  73. if (rc < 0) return rc;
  74. }
  75. memcpy(priv->buffer+priv->off, &i, sizeof(i));
  76. priv->off+=sizeof(i);
  77. return 0;
  78. }
  79. int64_t zoo_htonll(int64_t v)
  80. {
  81. int i = 0;
  82. char *s = (char *)&v;
  83. if (htonl(1) == 1) {
  84. return v;
  85. }
  86. for (i = 0; i < 4; i++) {
  87. int tmp = s[i];
  88. s[i] = s[8-i-1];
  89. s[8-i-1] = tmp;
  90. }
  91. return v;
  92. }
  93. int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_t *d)
  94. {
  95. const int64_t i = zoo_htonll(*d);
  96. struct buff_struct *priv = oa->priv;
  97. if ((priv->len - priv->off) < sizeof(i)) {
  98. int rc = resize_buffer(priv, priv->len + sizeof(i));
  99. if (rc < 0) return rc;
  100. }
  101. memcpy(priv->buffer+priv->off, &i, sizeof(i));
  102. priv->off+=sizeof(i);
  103. return 0;
  104. }
  105. int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t *count)
  106. {
  107. return oa_serialize_int(oa, tag, count);
  108. }
  109. int oa_end_vector(struct oarchive *oa, const char *tag)
  110. {
  111. return 0;
  112. }
  113. int oa_serialize_bool(struct oarchive *oa, const char *name, const int32_t *i)
  114. {
  115. //return oa_serialize_int(oa, name, i);
  116. struct buff_struct *priv = oa->priv;
  117. if ((priv->len - priv->off) < 1) {
  118. int rc = resize_buffer(priv, priv->len + 1);
  119. if (rc < 0)
  120. return rc;
  121. }
  122. priv->buffer[priv->off] = (*i == 0 ? '\0' : '\1');
  123. priv->off++;
  124. return 0;
  125. }
  126. static const int32_t negone = -1;
  127. int oa_serialize_buffer(struct oarchive *oa, const char *name,
  128. const struct buffer *b)
  129. {
  130. struct buff_struct *priv = oa->priv;
  131. int rc;
  132. if (!b) {
  133. return oa_serialize_int(oa, "len", &negone);
  134. }
  135. rc = oa_serialize_int(oa, "len", &b->len);
  136. if (rc < 0)
  137. return rc;
  138. // this means a buffer of NUll
  139. // with size of -1. This is
  140. // waht we use in java serialization for NULL
  141. if (b->len == -1) {
  142. return rc;
  143. }
  144. if ((priv->len - priv->off) < b->len) {
  145. rc = resize_buffer(priv, priv->len + b->len);
  146. if (rc < 0)
  147. return rc;
  148. }
  149. memcpy(priv->buffer+priv->off, b->buff, b->len);
  150. priv->off += b->len;
  151. return 0;
  152. }
  153. int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
  154. {
  155. struct buff_struct *priv = oa->priv;
  156. int32_t len;
  157. int rc;
  158. if (!*s) {
  159. oa_serialize_int(oa, "len", &negone);
  160. return 0;
  161. }
  162. len = strlen(*s);
  163. rc = oa_serialize_int(oa, "len", &len);
  164. if (rc < 0)
  165. return rc;
  166. if ((priv->len - priv->off) < len) {
  167. rc = resize_buffer(priv, priv->len + len);
  168. if (rc < 0)
  169. return rc;
  170. }
  171. memcpy(priv->buffer+priv->off, *s, len);
  172. priv->off += len;
  173. return 0;
  174. }
  175. int ia_start_record(struct iarchive *ia, const char *tag)
  176. {
  177. return 0;
  178. }
  179. int ia_end_record(struct iarchive *ia, const char *tag)
  180. {
  181. return 0;
  182. }
  183. int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *count)
  184. {
  185. struct buff_struct *priv = ia->priv;
  186. if ((priv->len - priv->off) < sizeof(*count)) {
  187. return -E2BIG;
  188. }
  189. memcpy(count, priv->buffer+priv->off, sizeof(*count));
  190. priv->off+=sizeof(*count);
  191. *count = ntohl(*count);
  192. return 0;
  193. }
  194. int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *count)
  195. {
  196. struct buff_struct *priv = ia->priv;
  197. int64_t v = 0;
  198. if ((priv->len - priv->off) < sizeof(*count)) {
  199. return -E2BIG;
  200. }
  201. memcpy(count, priv->buffer+priv->off, sizeof(*count));
  202. priv->off+=sizeof(*count);
  203. v = zoo_htonll(*count); // htonll and ntohll do the same
  204. *count = v;
  205. return 0;
  206. }
  207. int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
  208. {
  209. return ia_deserialize_int(ia, tag, count);
  210. }
  211. int ia_end_vector(struct iarchive *ia, const char *tag)
  212. {
  213. return 0;
  214. }
  215. int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
  216. {
  217. struct buff_struct *priv = ia->priv;
  218. //fprintf(stderr, "Deserializing bool %d\n", priv->off);
  219. //return ia_deserialize_int(ia, name, v);
  220. if ((priv->len - priv->off) < 1) {
  221. return -E2BIG;
  222. }
  223. *v = priv->buffer[priv->off];
  224. priv->off+=1;
  225. //fprintf(stderr, "Deserializing bool end %d\n", priv->off);
  226. return 0;
  227. }
  228. int ia_deserialize_buffer(struct iarchive *ia, const char *name,
  229. struct buffer *b)
  230. {
  231. struct buff_struct *priv = ia->priv;
  232. int rc = ia_deserialize_int(ia, "len", &b->len);
  233. if (rc < 0)
  234. return rc;
  235. if ((priv->len - priv->off) < b->len) {
  236. return -E2BIG;
  237. }
  238. // set the buffer to null
  239. if (b->len == -1) {
  240. b->buff = NULL;
  241. return rc;
  242. }
  243. b->buff = malloc(b->len);
  244. if (!b->buff) {
  245. return -ENOMEM;
  246. }
  247. memcpy(b->buff, priv->buffer+priv->off, b->len);
  248. priv->off += b->len;
  249. return 0;
  250. }
  251. int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
  252. {
  253. struct buff_struct *priv = ia->priv;
  254. int32_t len;
  255. int rc = ia_deserialize_int(ia, "len", &len);
  256. if (rc < 0)
  257. return rc;
  258. if ((priv->len - priv->off) < len) {
  259. return -E2BIG;
  260. }
  261. if (len < 0) {
  262. return -EINVAL;
  263. }
  264. *s = malloc(len+1);
  265. if (!*s) {
  266. return -ENOMEM;
  267. }
  268. memcpy(*s, priv->buffer+priv->off, len);
  269. (*s)[len] = '\0';
  270. priv->off += len;
  271. return 0;
  272. }
  273. static struct iarchive ia_default = {
  274. ia_start_record,
  275. ia_end_record,
  276. ia_start_vector,
  277. ia_end_vector,
  278. ia_deserialize_bool,
  279. ia_deserialize_int,
  280. ia_deserialize_long ,
  281. ia_deserialize_buffer,
  282. ia_deserialize_string};
  283. static struct oarchive oa_default = {
  284. oa_start_record,
  285. oa_end_record,
  286. oa_start_vector,
  287. oa_end_vector,
  288. oa_serialize_bool,
  289. oa_serialize_int,
  290. oa_serialize_long ,
  291. oa_serialize_buffer,
  292. oa_serialize_string};
  293. struct iarchive *create_buffer_iarchive(char *buffer, int len)
  294. {
  295. struct iarchive *ia;
  296. struct buff_struct *buff;
  297. ia = malloc(sizeof(*ia));
  298. if (!ia) return 0;
  299. buff = malloc(sizeof(struct buff_struct));
  300. if (!buff) {
  301. free(ia);
  302. return 0;
  303. }
  304. *ia = ia_default;
  305. buff->off = 0;
  306. buff->buffer = buffer;
  307. buff->len = len;
  308. ia->priv = buff;
  309. return ia;
  310. }
  311. struct oarchive *create_buffer_oarchive()
  312. {
  313. struct oarchive *oa;
  314. struct buff_struct *buff;
  315. oa = malloc(sizeof(*oa));
  316. if (!oa) return 0;
  317. buff = malloc(sizeof(struct buff_struct));
  318. if (!buff) {
  319. free(oa);
  320. return 0;
  321. }
  322. *oa = oa_default;
  323. buff->off = 0;
  324. buff->buffer = malloc(128);
  325. buff->len = 128;
  326. oa->priv = buff;
  327. return oa;
  328. }
  329. void close_buffer_iarchive(struct iarchive **ia)
  330. {
  331. free((*ia)->priv);
  332. free(*ia);
  333. *ia = 0;
  334. }
  335. void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
  336. {
  337. if (free_buffer) {
  338. struct buff_struct *buff = (struct buff_struct *)(*oa)->priv;
  339. if (buff->buffer) {
  340. free(buff->buffer);
  341. }
  342. }
  343. free((*oa)->priv);
  344. free(*oa);
  345. *oa = 0;
  346. }
  347. char *get_buffer(struct oarchive *oa)
  348. {
  349. struct buff_struct *buff = oa->priv;
  350. return buff->buffer;
  351. }
  352. int get_buffer_len(struct oarchive *oa)
  353. {
  354. struct buff_struct *buff = oa->priv;
  355. return buff->off;
  356. }