static void pack_test(void) { /*************** Test of pack *****************/ cw_pack_context pc; cmp_ctx_t cc; mpack_writer_t mw; int ii, itemSize; for (ii=0; ii<BUF_Length; ii++) buffer[ii] = 0; /*Load pages in memory*/ uint8_t item[40]; BEFORE_PTEST(cw_pack_nil(&pc)); PTEST("CMP",cmp_write_nil(&cc)); PTEST("MPack", mpack_write_nil(&mw)); PTEST("CWPack", cw_pack_nil(&pc)); AFTER_PTEST; BEFORE_PTEST(cw_pack_signed(&pc, -1)); PTEST("CMP",cmp_write_integer(&cc, -1)); PTEST("MPack", mpack_write_i64(&mw, -1)); PTEST("CWPack", cw_pack_signed(&pc, -1)); AFTER_PTEST; BEFORE_PTEST(cw_pack_signed(&pc, 200)); PTEST("CMP",cmp_write_integer(&cc, 200)); PTEST("MPack", mpack_write_i64(&mw, 200)); PTEST("CWPack", cw_pack_signed(&pc, 200)); AFTER_PTEST; BEFORE_PTEST(cw_pack_signed(&pc, 10000)); PTEST("CMP",cmp_write_integer(&cc, 10000)); PTEST("MPack", mpack_write_i64(&mw, 10000)); PTEST("CWPack", cw_pack_signed(&pc, 10000)); AFTER_PTEST; BEFORE_PTEST(cw_pack_signed(&pc, 100000)); PTEST("CMP",cmp_write_integer(&cc, 100000)); PTEST("MPack", mpack_write_i64(&mw, 100000)); PTEST("CWPack", cw_pack_signed(&pc, 100000)); AFTER_PTEST; BEFORE_PTEST(cw_pack_float(&pc, (float)3.14)); PTEST("CMP",cmp_write_float(&cc, (float)3.14)); PTEST("MPack", mpack_write_float(&mw, (float)3.14)); PTEST("CWPack", cw_pack_float(&pc, (float)3.14)); AFTER_PTEST; BEFORE_PTEST(cw_pack_double(&pc, 3.14)); PTEST("CMP",cmp_write_decimal(&cc, 3.14)); PTEST("MPack", mpack_write_double(&mw, 3.14)); PTEST("CWPack", cw_pack_double(&pc, 3.14)); AFTER_PTEST; BEFORE_PTEST(cw_pack_str(&pc, "Claes",5)); PTEST("CMP",cmp_write_str(&cc, "Claes",5)); PTEST("MPack", mpack_write_str(&mw, "Claes",5)); PTEST("CWPack", cw_pack_str(&pc, "Claes",5)); AFTER_PTEST; BEFORE_PTEST(cw_pack_str(&pc, "Longer string than the other one.",33)); PTEST("CMP",cmp_write_str(&cc, "Longer string than the other one.",33)); PTEST("MPack", mpack_write_str(&mw, "Longer string than the other one.",33)); PTEST("CWPack", cw_pack_str(&pc, "Longer string than the other one.",33)); AFTER_PTEST; }
int stor_fstat_rsp_mashal(void *ptr, cmp_reader reader, cmp_writer writer, const struct _stor_fstat_rsp *in){ cmp_ctx_t cmp; cmp_init(&cmp, ptr, reader, writer); cmp_write_sint(&cmp, in->fid); if(in->fname == NULL){ cmp_write_str(&cmp, in->fname, 0); }else{ cmp_write_str(&cmp, in->fname, strlen(in->fname)); } if(in->folder == NULL){ cmp_write_str(&cmp, in->folder, 0); }else{ cmp_write_str(&cmp, in->folder, strlen(in->folder)); } cmp_write_sint(&cmp, in->type); cmp_write_sint(&cmp, in->fatime); cmp_write_sint(&cmp, in->fmtime); cmp_write_sint(&cmp, in->fctime); cmp_write_sint(&cmp, in->fsize); cmp_write_bin(&cmp, in->snap, in->snap_len); return 0; }
int main(void) { FILE *fh = NULL; cmp_ctx_t cmp; uint32_t array_size = 0; uint32_t str_size = 0; char hello[6] = {0, 0, 0, 0, 0, 0}; char message_pack[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; fh = fopen("cmp_data.dat", "w+b"); if (fh == NULL) error_and_exit("Error opening data.dat"); cmp_init(&cmp, fh, file_reader, file_writer); if (!cmp_write_array(&cmp, 2)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_str(&cmp, "Hello", 5)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_str(&cmp, "MessagePack", 11)) error_and_exit(cmp_strerror(&cmp)); rewind(fh); if (!cmp_read_array(&cmp, &array_size)) error_and_exit(cmp_strerror(&cmp)); /* You can read the str byte size and then read str bytes... */ if (!cmp_read_str_size(&cmp, &str_size)) error_and_exit(cmp_strerror(&cmp)); if (str_size > (sizeof(hello) - 1)) error_and_exit("Packed 'hello' length too long\n"); if (!read_bytes(hello, str_size, fh)) error_and_exit(cmp_strerror(&cmp)); /* * ...or you can set the maximum number of bytes to read and do it all in * one call */ str_size = sizeof(message_pack); if (!cmp_read_str(&cmp, message_pack, &str_size)) error_and_exit(cmp_strerror(&cmp)); printf("Array Length: %zu.\n", array_size); printf("[\"%s\", \"%s\"]\n", hello, message_pack); fclose(fh); return EXIT_SUCCESS; }
void scriptcomponent_serialize(ScriptComponent* component, lua_State* L, cmp_ctx_t* context) { cmp_write_map(context, 2); cmp_write_str(context, "path", 4); cmp_write_str(context, component->path, strlen(component->path)); cmp_write_str(context, "instance", 8); script_serialize(L, component->instance, context); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Script `%s` serialized.\n", component->path); }
void scene_serialize(Scene* scene, cmp_ctx_t* context) { cmp_write_map(context, 2); cmp_write_str(context, "path", 4); cmp_write_str(context, scene->path, strlen(scene->path)); cmp_write_str(context, "entities", 8); cmp_write_array(context, scene->entities->count); Entity* entity = scene->entities->allocated; while(entity != NULL) { entity_serialize(entity, scene, context); entity = entity->pool.next; } }
int stor_fmoveto_req_mashal(void *ptr, cmp_reader reader, cmp_writer writer, const struct _stor_fmoveto_req *in){ cmp_ctx_t cmp; cmp_init(&cmp, ptr, reader, writer); cmp_write_sint(&cmp, in->fid); cmp_write_sint(&cmp, in->folder); if(in->fname == NULL){ cmp_write_str(&cmp, in->fname, 0); }else{ cmp_write_str(&cmp, in->fname, strlen(in->fname)); } return 0; }
bool msg_header_write(cmp_ctx_t *cmp, const char *msg_id) { bool err = false; err = err || !cmp_write_array(cmp, 2); err = err || !cmp_write_str(cmp, msg_id, strlen(msg_id)); return !err; }
int stor_lookup_next_rsp_mashal(void *ptr, cmp_reader reader, cmp_writer writer, const struct _stor_lookup_next_rsp *in){ cmp_ctx_t cmp; cmp_init(&cmp, ptr, reader, writer); cmp_write_sint(&cmp, in->luid); { stor_fstat_rsp_t *obj; int i; fixarray_zip(in->rfiles); cmp_write_array(&cmp, fixarray_num(in->rfiles)); for (i = 0; i < fixarray_num(in->rfiles); i++){ if(fixarray_get(in->rfiles, i, (void **)&obj) != 0){ return -1; } cmp_write_sint(&cmp, obj->fid); if(obj->fname == NULL){ cmp_write_str(&cmp, obj->fname, 0); }else{ cmp_write_str(&cmp, obj->fname, strlen(obj->fname)); } if(obj->folder == NULL){ cmp_write_str(&cmp, obj->folder, 0); }else{ cmp_write_str(&cmp, obj->folder, strlen(obj->folder)); } cmp_write_sint(&cmp, obj->type); cmp_write_sint(&cmp, obj->fatime); cmp_write_sint(&cmp, obj->fmtime); cmp_write_sint(&cmp, obj->fctime); cmp_write_sint(&cmp, obj->fsize); cmp_write_bin(&cmp, obj->snap, obj->snap_len); } } return 0; }
void script_serialize(lua_State* L, const char* instance, cmp_ctx_t* context) { lua_getglobal(L, instance); lua_getglobal(L, "serialize"); lua_pushvalue(L, -2); if(lua_pcall(L, 1, 1, 0)) { SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "Couldn't run `serialize` instance %s : %s\n", instance, lua_tostring(L, -1)); } size_t size = lua_strlen(L, -1); char serialized[size]; memcpy(serialized, lua_tostring(L, -1), size); cmp_write_str(context, (char*) serialized, size); lua_pop(L, 3); }
bool output_test_cb(void *p, cmp_ctx_t *args_ctx, cmp_ctx_t *output_ctx) { cmp_write_str(output_ctx, "hello", 5); return true; }
int main(void) { FILE *fh = NULL; cmp_ctx_t cmp; uint16_t year = 1983; uint8_t month = 5; uint8_t day = 28; int64_t sint = 0; uint64_t uint = 0; float flt = 0.0f; double dbl = 0.0; bool boolean = false; uint8_t fake_bool = 0; uint32_t string_size = 0; uint32_t array_size = 0; uint32_t binary_size = 0; uint32_t map_size = 0; int8_t ext_type = 0; uint32_t ext_size = 0; char sbuf[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; fh = fopen("cmp_data.dat", "w+b"); if (fh == NULL) error_and_exit("Error opening data.dat"); cmp_init(&cmp, fh, file_reader, file_skipper, file_writer); /* * When you write an array, you first specify the number of array * elements, then you write that many elements. */ if (!cmp_write_array(&cmp, 9)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_sint(&cmp, -14)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_uint(&cmp, 38)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_float(&cmp, 1.8f)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_double(&cmp, 300.4)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_nil(&cmp)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_true(&cmp)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_false(&cmp)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_bool(&cmp, false)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_u8_as_bool(&cmp, 1)) error_and_exit(cmp_strerror(&cmp)); /* Array full */ /* * Maps work similar to arrays, but the length is in "pairs", so this * writes 2 pairs to the map. Subsequently, pairs are written in key, * value order. */ if (!cmp_write_map(&cmp, 2)) error_and_exit(cmp_strerror(&cmp)); /* You can write string data all at once... */ if (!cmp_write_str(&cmp, "Greeting", 8)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_str(&cmp, "Hello", 5)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_str(&cmp, "Name", 4)) error_and_exit(cmp_strerror(&cmp)); /* ...or in chunks */ if (!cmp_write_str_marker(&cmp, 5)) error_and_exit(cmp_strerror(&cmp)); if (file_writer(&cmp, "Li", 2) != 2) error_and_exit(strerror(errno)); if (file_writer(&cmp, "nus", 3) != 3) error_and_exit(strerror(errno)); /* Map full */ /* Binary data functions the same as string data */ if (!cmp_write_bin(&cmp, "MessagePack", 11)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_write_bin_marker(&cmp, 8)) error_and_exit(cmp_strerror(&cmp)); if (file_writer(&cmp, "is ", 3) != 3) error_and_exit(strerror(errno)); if (file_writer(&cmp, "great", 5) != 5) error_and_exit(strerror(errno)); /* * With extended types, you can create your own custom types. Here we * create a simple date type. */ /* cmp_write_ext_marker(type, size) */ if (!cmp_write_ext_marker(&cmp, 1, 4)) error_and_exit(cmp_strerror(&cmp)); file_writer(&cmp, &year, sizeof(uint16_t)); file_writer(&cmp, &month, sizeof(uint8_t)); file_writer(&cmp, &day, sizeof(uint8_t)); /* Now we can read the data back just as easily */ rewind(fh); if (!cmp_read_array(&cmp, &array_size)) error_and_exit(cmp_strerror(&cmp)); if (array_size != 9) error_and_exit("Array size was not 9"); if (!cmp_read_sinteger(&cmp, &sint)) error_and_exit(cmp_strerror(&cmp)); if (sint != -14) error_and_exit("Signed int was not -14"); if (!cmp_read_uinteger(&cmp, &uint)) error_and_exit(cmp_strerror(&cmp)); if (uint != 38) error_and_exit("Unsigned int was not 38"); if (!cmp_read_float(&cmp, &flt)) error_and_exit(cmp_strerror(&cmp)); if (flt != 1.8f) error_and_exit("Float was not 1.8f"); if (!cmp_read_double(&cmp, &dbl)) error_and_exit(cmp_strerror(&cmp)); if (dbl != 300.4) error_and_exit("Double was not 300.f"); if (!cmp_read_nil(&cmp)) error_and_exit(cmp_strerror(&cmp)); if (!cmp_read_bool(&cmp, &boolean)) error_and_exit(cmp_strerror(&cmp)); if (boolean != true) error_and_exit("First boolean was not true"); if (!cmp_read_bool(&cmp, &boolean)) error_and_exit(cmp_strerror(&cmp)); if (boolean != false) error_and_exit("Second boolean was not false"); if (!cmp_read_bool(&cmp, &boolean)) error_and_exit(cmp_strerror(&cmp)); if (boolean != false) error_and_exit("Third boolean was not false"); if (!cmp_read_bool_as_u8(&cmp, &fake_bool)) error_and_exit(cmp_strerror(&cmp)); if (fake_bool != 1) { fprintf(stderr, "%u.\n", fake_bool); error_and_exit("Third boolean (u8) was not 1"); } if (!cmp_read_map(&cmp, &map_size)) error_and_exit(cmp_strerror(&cmp)); if (map_size != 2) error_and_exit("Map size was not 2"); /* * String reading here. Note that normally strings are encoded using * UTF-8. I have cleverly restricted this example to ASCII, which overlaps * UTF-8 encoding, but this must not be assumed in real-world code. * * You can read strings in two ways. Either you can read the string's size * in bytes and then read the bytes manually... */ if (!cmp_read_str_size(&cmp, &string_size)) error_and_exit(cmp_strerror(&cmp)); if (string_size != 8) error_and_exit("Greeting string key size was not 8"); if (!read_bytes(sbuf, 8, fh)) error_and_exit(strerror(errno)); sbuf[string_size] = 0; if (strncmp(sbuf, "Greeting", 8) != 0) error_and_exit("Greeting string key name was not 'Greeting'"); /* * ...or you can set the maximum number of bytes to read and do it all in * one call. cmp_read_str will write no more than "size" bytes, including * the terminating NULL, to the passed buffer. If the string's size * exceeds the passed buffer size, the "size" input is set to the number of * bytes necessary, not including the terminating NULL. Otherwise, the * "size" input is set to the number of bytes written, not including the * terminating NULL. */ string_size = sizeof(sbuf); if (!cmp_read_str(&cmp, sbuf, &string_size)) error_and_exit(cmp_strerror(&cmp)); if (strncmp(sbuf, "Hello", 5) != 0) error_and_exit("Greeting string value was not 'Hello'"); string_size = sizeof(sbuf); if (!cmp_read_str(&cmp, sbuf, &string_size)) error_and_exit(cmp_strerror(&cmp)); if (strncmp(sbuf, "Name", 4) != 0) error_and_exit("Name key name was not 'Name'"); string_size = sizeof(sbuf); if (!cmp_read_str(&cmp, sbuf, &string_size)) error_and_exit(cmp_strerror(&cmp)); if (strncmp(sbuf, "Linus", 5) != 0) error_and_exit("Name key value was not 'Linus'"); memset(sbuf, 0, sizeof(sbuf)); binary_size = sizeof(sbuf); if (!cmp_read_bin(&cmp, &sbuf, &binary_size)) error_and_exit(cmp_strerror(&cmp)); if (memcmp(sbuf, "MessagePack", 11) != 0) error_and_exit("1st binary value was not 'MessagePack'"); memset(sbuf, 0, sizeof(sbuf)); binary_size = sizeof(sbuf); if (!cmp_read_bin(&cmp, &sbuf, &binary_size)) error_and_exit(cmp_strerror(&cmp)); if (memcmp(sbuf, "is great", 8) != 0) error_and_exit("2nd binary value was not 'is great'"); if (!cmp_read_ext_marker(&cmp, &ext_type, &ext_size)) error_and_exit(cmp_strerror(&cmp)); if (!read_bytes(&year, sizeof(uint16_t), fh)) error_and_exit(strerror(errno)); if (!read_bytes(&month, sizeof(uint8_t), fh)) error_and_exit(strerror(errno)); if (!read_bytes(&day, sizeof(uint8_t), fh)) error_and_exit(strerror(errno)); if (year != 1983) error_and_exit("Year was not 1983"); if (month != 5) error_and_exit("Month was not 5"); if (day != 28) error_and_exit("Day was not 28"); rewind(fh); /* Alternately, you can read objects until the stream is empty */ while (1) { cmp_object_t obj; if (!cmp_read_object(&cmp, &obj)) { if (feof(fh)) break; error_and_exit(cmp_strerror(&cmp)); } switch (obj.type) { case CMP_TYPE_POSITIVE_FIXNUM: case CMP_TYPE_UINT8: printf("Unsigned Integer: %u\n", obj.as.u8); break; case CMP_TYPE_FIXMAP: case CMP_TYPE_MAP16: case CMP_TYPE_MAP32: printf("Map: %u\n", obj.as.map_size); break; case CMP_TYPE_FIXARRAY: case CMP_TYPE_ARRAY16: case CMP_TYPE_ARRAY32: printf("Array: %u\n", obj.as.array_size); break; case CMP_TYPE_FIXSTR: case CMP_TYPE_STR8: case CMP_TYPE_STR16: case CMP_TYPE_STR32: if (!read_bytes(sbuf, obj.as.str_size, fh)) error_and_exit(strerror(errno)); sbuf[obj.as.str_size] = 0; printf("String: %s\n", sbuf); break; case CMP_TYPE_BIN8: case CMP_TYPE_BIN16: case CMP_TYPE_BIN32: memset(sbuf, 0, sizeof(sbuf)); if (!read_bytes(sbuf, obj.as.bin_size, fh)) error_and_exit(strerror(errno)); printf("Binary: %s\n", sbuf); break; case CMP_TYPE_NIL: printf("NULL\n"); break; case CMP_TYPE_BOOLEAN: if (obj.as.boolean) printf("Boolean: true\n"); else printf("Boolean: false\n"); break; case CMP_TYPE_EXT8: case CMP_TYPE_EXT16: case CMP_TYPE_EXT32: case CMP_TYPE_FIXEXT1: case CMP_TYPE_FIXEXT2: case CMP_TYPE_FIXEXT4: case CMP_TYPE_FIXEXT8: case CMP_TYPE_FIXEXT16: if (obj.as.ext.type == 1) { /* Date object */ if (!read_bytes(&year, sizeof(uint16_t), fh)) error_and_exit(strerror(errno)); if (!read_bytes(&month, sizeof(uint8_t), fh)) error_and_exit(strerror(errno)); if (!read_bytes(&day, sizeof(uint8_t), fh)) error_and_exit(strerror(errno)); printf("Date: %u/%u/%u\n", year, month, day); } else { printf("Extended type {%d, %u}: ", obj.as.ext.type, obj.as.ext.size ); while (obj.as.ext.size--) { read_bytes(sbuf, sizeof(uint8_t), fh); printf("%02x ", sbuf[0]); } printf("\n"); } break; case CMP_TYPE_FLOAT: printf("Float: %f\n", obj.as.flt); break; case CMP_TYPE_DOUBLE: printf("Double: %f\n", obj.as.dbl); break; case CMP_TYPE_UINT16: printf("Unsigned Integer: %u\n", obj.as.u16); break; case CMP_TYPE_UINT32: printf("Unsigned Integer: %u\n", obj.as.u32); break; case CMP_TYPE_UINT64: printf("Unsigned Integer: %" PRIu64 "\n", obj.as.u64); break; case CMP_TYPE_NEGATIVE_FIXNUM: case CMP_TYPE_SINT8: printf("Signed Integer: %d\n", obj.as.s8); break; case CMP_TYPE_SINT16: printf("Signed Integer: %d\n", obj.as.s16); break; case CMP_TYPE_SINT32: printf("Signed Integer: %d\n", obj.as.s32); break; case CMP_TYPE_SINT64: printf("Signed Integer: %" PRId64 "\n", obj.as.s64); break; default: printf("Unrecognized object type %u\n", obj.type); break; } } fclose(fh); return EXIT_SUCCESS; }