ucl_msgpack.c (6525738f63c6fd15b4ae11d935311b804e0c24a6) ucl_msgpack.c (a0409676120c1e558d0ade943019934e0f15118d)
1/*
2 * Copyright (c) 2015, Vsevolod Stakhov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 420 unchanged lines hidden (view full) ---

429 const unsigned char *pos, size_t remain);
430
431#define MSGPACK_FLAG_FIXED (1 << 0)
432#define MSGPACK_FLAG_CONTAINER (1 << 1)
433#define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434#define MSGPACK_FLAG_EXT (1 << 3)
435#define MSGPACK_FLAG_ASSOC (1 << 4)
436#define MSGPACK_FLAG_KEY (1 << 5)
1/*
2 * Copyright (c) 2015, Vsevolod Stakhov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 420 unchanged lines hidden (view full) ---

429 const unsigned char *pos, size_t remain);
430
431#define MSGPACK_FLAG_FIXED (1 << 0)
432#define MSGPACK_FLAG_CONTAINER (1 << 1)
433#define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434#define MSGPACK_FLAG_EXT (1 << 3)
435#define MSGPACK_FLAG_ASSOC (1 << 4)
436#define MSGPACK_FLAG_KEY (1 << 5)
437#define MSGPACK_CONTAINER_BIT (1ULL << 62)
438
439/*
440 * Search tree packed in array
441 */
442struct ucl_msgpack_parser {
443 uint8_t prefix; /* Prefix byte */
444 uint8_t prefixlen; /* Length of prefix in bits */
445 uint8_t fmt; /* The desired format */

--- 317 unchanged lines hidden (view full) ---

763ucl_msgpack_get_container (struct ucl_parser *parser,
764 struct ucl_msgpack_parser *obj_parser, uint64_t len)
765{
766 struct ucl_stack *stack;
767
768 assert (obj_parser != NULL);
769
770 if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
437
438/*
439 * Search tree packed in array
440 */
441struct ucl_msgpack_parser {
442 uint8_t prefix; /* Prefix byte */
443 uint8_t prefixlen; /* Length of prefix in bits */
444 uint8_t fmt; /* The desired format */

--- 317 unchanged lines hidden (view full) ---

762ucl_msgpack_get_container (struct ucl_parser *parser,
763 struct ucl_msgpack_parser *obj_parser, uint64_t len)
764{
765 struct ucl_stack *stack;
766
767 assert (obj_parser != NULL);
768
769 if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
771 assert ((len & MSGPACK_CONTAINER_BIT) == 0);
772 /*
773 * Insert new container to the stack
774 */
775 if (parser->stack == NULL) {
776 parser->stack = calloc (1, sizeof (struct ucl_stack));
777
778 if (parser->stack == NULL) {
779 ucl_create_err (&parser->err, "no memory");
780 return NULL;
781 }
770 /*
771 * Insert new container to the stack
772 */
773 if (parser->stack == NULL) {
774 parser->stack = calloc (1, sizeof (struct ucl_stack));
775
776 if (parser->stack == NULL) {
777 ucl_create_err (&parser->err, "no memory");
778 return NULL;
779 }
780
781 parser->stack->chunk = parser->chunks;
782 }
783 else {
784 stack = calloc (1, sizeof (struct ucl_stack));
785
786 if (stack == NULL) {
787 ucl_create_err (&parser->err, "no memory");
788 return NULL;
789 }
790
782 }
783 else {
784 stack = calloc (1, sizeof (struct ucl_stack));
785
786 if (stack == NULL) {
787 ucl_create_err (&parser->err, "no memory");
788 return NULL;
789 }
790
791 stack->chunk = parser->chunks;
791 stack->next = parser->stack;
792 parser->stack = stack;
793 }
794
792 stack->next = parser->stack;
793 parser->stack = stack;
794 }
795
795 parser->stack->level = len | MSGPACK_CONTAINER_BIT;
796 parser->stack->e.len = len;
796
797#ifdef MSGPACK_DEBUG_PARSER
798 stack = parser->stack;
799 while (stack) {
800 fprintf(stderr, "+");
801 stack = stack->next;
802 }
803

--- 14 unchanged lines hidden (view full) ---

818 }
819
820 return parser->stack;
821}
822
823static bool
824ucl_msgpack_is_container_finished (struct ucl_stack *container)
825{
797
798#ifdef MSGPACK_DEBUG_PARSER
799 stack = parser->stack;
800 while (stack) {
801 fprintf(stderr, "+");
802 stack = stack->next;
803 }
804

--- 14 unchanged lines hidden (view full) ---

819 }
820
821 return parser->stack;
822}
823
824static bool
825ucl_msgpack_is_container_finished (struct ucl_stack *container)
826{
826 uint64_t level;
827
828 assert (container != NULL);
829
827 assert (container != NULL);
828
830 if (container->level & MSGPACK_CONTAINER_BIT) {
831 level = container->level & ~MSGPACK_CONTAINER_BIT;
832
829
833 if (level == 0) {
834 return true;
835 }
830 if (container->e.len == 0) {
831 return true;
836 }
837
838 return false;
839}
840
841static bool
842ucl_msgpack_insert_object (struct ucl_parser *parser,
843 const unsigned char *key,
844 size_t keylen, ucl_object_t *obj)
845{
832 }
833
834 return false;
835}
836
837static bool
838ucl_msgpack_insert_object (struct ucl_parser *parser,
839 const unsigned char *key,
840 size_t keylen, ucl_object_t *obj)
841{
846 uint64_t level;
847 struct ucl_stack *container;
848
849 container = parser->stack;
850 assert (container != NULL);
842 struct ucl_stack *container;
843
844 container = parser->stack;
845 assert (container != NULL);
851 assert (container->level > 0);
846 assert (container->e.len > 0);
852 assert (obj != NULL);
853 assert (container->obj != NULL);
854
855 if (container->obj->type == UCL_ARRAY) {
856 ucl_array_append (container->obj, obj);
857 }
858 else if (container->obj->type == UCL_OBJECT) {
859 if (key == NULL || keylen == 0) {

--- 10 unchanged lines hidden (view full) ---

870
871 ucl_parser_process_object_element (parser, obj);
872 }
873 else {
874 ucl_create_err (&parser->err, "bad container type");
875 return false;
876 }
877
847 assert (obj != NULL);
848 assert (container->obj != NULL);
849
850 if (container->obj->type == UCL_ARRAY) {
851 ucl_array_append (container->obj, obj);
852 }
853 else if (container->obj->type == UCL_OBJECT) {
854 if (key == NULL || keylen == 0) {

--- 10 unchanged lines hidden (view full) ---

865
866 ucl_parser_process_object_element (parser, obj);
867 }
868 else {
869 ucl_create_err (&parser->err, "bad container type");
870 return false;
871 }
872
878 if (container->level & MSGPACK_CONTAINER_BIT) {
879 level = container->level & ~MSGPACK_CONTAINER_BIT;
880 container->level = (level - 1) | MSGPACK_CONTAINER_BIT;
881 }
873 container->e.len--;
882
883 return true;
884}
885
886static struct ucl_stack *
887ucl_msgpack_get_next_container (struct ucl_parser *parser)
888{
889 struct ucl_stack *cur = NULL;
874
875 return true;
876}
877
878static struct ucl_stack *
879ucl_msgpack_get_next_container (struct ucl_parser *parser)
880{
881 struct ucl_stack *cur = NULL;
890 uint64_t level;
882 uint64_t len;
891
892 cur = parser->stack;
893
894 if (cur == NULL) {
895 return NULL;
896 }
897
883
884 cur = parser->stack;
885
886 if (cur == NULL) {
887 return NULL;
888 }
889
898 if (cur->level & MSGPACK_CONTAINER_BIT) {
899 level = cur->level & ~MSGPACK_CONTAINER_BIT;
890 len = cur->e.len;
900
891
901 if (level == 0) {
902 /* We need to switch to the previous container */
903 parser->stack = cur->next;
904 parser->cur_obj = cur->obj;
905 free (cur);
892 if (len == 0) {
893 /* We need to switch to the previous container */
894 parser->stack = cur->next;
895 parser->cur_obj = cur->obj;
896 free (cur);
906
907#ifdef MSGPACK_DEBUG_PARSER
897
898#ifdef MSGPACK_DEBUG_PARSER
908 cur = parser->stack;
899 cur = parser->stack;
909 while (cur) {
910 fprintf(stderr, "-");
911 cur = cur->next;
912 }
913 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
914#endif
915
900 while (cur) {
901 fprintf(stderr, "-");
902 cur = cur->next;
903 }
904 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
905#endif
906
916 return ucl_msgpack_get_next_container (parser);
917 }
907 return ucl_msgpack_get_next_container (parser);
918 }
919
920 /*
921 * For UCL containers we don't know length, so we just insert the whole
922 * message pack blob into the top level container
923 */
924
925 assert (cur->obj != NULL);

--- 98 unchanged lines hidden (view full) ---

1024 }
1025 else {
1026 /* Len is irrelevant now */
1027 len = 0;
1028 }
1029 }
1030 else {
1031 /* Length is not embedded */
908 }
909
910 /*
911 * For UCL containers we don't know length, so we just insert the whole
912 * message pack blob into the top level container
913 */
914
915 assert (cur->obj != NULL);

--- 98 unchanged lines hidden (view full) ---

1014 }
1015 else {
1016 /* Len is irrelevant now */
1017 len = 0;
1018 }
1019 }
1020 else {
1021 /* Length is not embedded */
1022 remain --;
1023
1032 if (remain < obj_parser->len) {
1033 ucl_create_err (&parser->err, "not enough data remain to "
1034 "read object's length: %u remain, %u needed",
1035 (unsigned)remain, obj_parser->len);
1036
1037 return false;
1038 }
1039
1040 p ++;
1024 if (remain < obj_parser->len) {
1025 ucl_create_err (&parser->err, "not enough data remain to "
1026 "read object's length: %u remain, %u needed",
1027 (unsigned)remain, obj_parser->len);
1028
1029 return false;
1030 }
1031
1032 p ++;
1041 remain --;
1042
1043 switch (obj_parser->len) {
1044 case 1:
1045 len = *p;
1046 break;
1047 case 2:
1048 len = FROM_BE16 (*(uint16_t *)p);
1049 break;
1050 case 4:
1051 len = FROM_BE32 (*(uint32_t *)p);
1052 break;
1053 case 8:
1054 len = FROM_BE64 (*(uint64_t *)p);
1055 break;
1056 default:
1033
1034 switch (obj_parser->len) {
1035 case 1:
1036 len = *p;
1037 break;
1038 case 2:
1039 len = FROM_BE16 (*(uint16_t *)p);
1040 break;
1041 case 4:
1042 len = FROM_BE32 (*(uint32_t *)p);
1043 break;
1044 case 8:
1045 len = FROM_BE64 (*(uint64_t *)p);
1046 break;
1047 default:
1057 assert (0);
1058 break;
1048 ucl_create_err (&parser->err, "invalid length of the length field: %u",
1049 (unsigned)obj_parser->len);
1050
1051 return false;
1059 }
1060
1061 p += obj_parser->len;
1062 remain -= obj_parser->len;
1063 }
1064
1065 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1066 /* We have just read the new associative map */

--- 69 unchanged lines hidden (view full) ---

1136
1137 case read_array_value:
1138 /*
1139 * p is now at the value start, len now contains length read and
1140 * obj_parser contains the corresponding specific parser
1141 */
1142 container = parser->stack;
1143
1052 }
1053
1054 p += obj_parser->len;
1055 remain -= obj_parser->len;
1056 }
1057
1058 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1059 /* We have just read the new associative map */

--- 69 unchanged lines hidden (view full) ---

1129
1130 case read_array_value:
1131 /*
1132 * p is now at the value start, len now contains length read and
1133 * obj_parser contains the corresponding specific parser
1134 */
1135 container = parser->stack;
1136
1144 if (container == NULL) {
1137 if (parser->stack == NULL) {
1138 ucl_create_err (&parser->err,
1139 "read assoc value when no container represented");
1145 return false;
1146 }
1147
1148 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1149 p, remain);
1150 CONSUME_RET;
1151
1152

--- 43 unchanged lines hidden (view full) ---

1196 case read_assoc_value:
1197 /*
1198 * p is now at the value start, len now contains length read and
1199 * obj_parser contains the corresponding specific parser
1200 */
1201 container = parser->stack;
1202
1203 if (container == NULL) {
1140 return false;
1141 }
1142
1143 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1144 p, remain);
1145 CONSUME_RET;
1146
1147

--- 43 unchanged lines hidden (view full) ---

1191 case read_assoc_value:
1192 /*
1193 * p is now at the value start, len now contains length read and
1194 * obj_parser contains the corresponding specific parser
1195 */
1196 container = parser->stack;
1197
1198 if (container == NULL) {
1199 ucl_create_err (&parser->err,
1200 "read assoc value when no container represented");
1204 return false;
1205 }
1206
1207 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1208 p, remain);
1209 CONSUME_RET;
1210
1211 assert (key != NULL && keylen > 0);
1212
1213 if (!ucl_msgpack_insert_object (parser, key, keylen,
1214 parser->cur_obj)) {
1201 return false;
1202 }
1203
1204 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1205 p, remain);
1206 CONSUME_RET;
1207
1208 assert (key != NULL && keylen > 0);
1209
1210 if (!ucl_msgpack_insert_object (parser, key, keylen,
1211 parser->cur_obj)) {
1212
1215 return false;
1216 }
1217
1218 key = NULL;
1219 keylen = 0;
1220
1221 if (ucl_msgpack_is_container_finished (container)) {
1222 state = finish_assoc_value;

--- 19 unchanged lines hidden (view full) ---

1242 }
1243
1244 /* Check the finishing state */
1245 switch (state) {
1246 case start_array:
1247 case start_assoc:
1248 /* Empty container at the end */
1249 if (len != 0) {
1213 return false;
1214 }
1215
1216 key = NULL;
1217 keylen = 0;
1218
1219 if (ucl_msgpack_is_container_finished (container)) {
1220 state = finish_assoc_value;

--- 19 unchanged lines hidden (view full) ---

1240 }
1241
1242 /* Check the finishing state */
1243 switch (state) {
1244 case start_array:
1245 case start_assoc:
1246 /* Empty container at the end */
1247 if (len != 0) {
1250 ucl_create_err (&parser->err, "invalid non-empty container at the end");
1248 ucl_create_err (&parser->err,
1249 "invalid non-empty container at the end; len=%zu",
1250 (uintmax_t)len);
1251
1252 return false;
1253 }
1254
1255 parser->cur_obj = ucl_object_new_full (
1256 state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257 parser->chunks->priority);
1251
1252 return false;
1253 }
1254
1255 parser->cur_obj = ucl_object_new_full (
1256 state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257 parser->chunks->priority);
1258
1259 if (parser->stack == NULL) {
1260 ucl_create_err (&parser->err,
1261 "read assoc value when no container represented");
1262 return false;
1263 }
1258 /* Insert to the previous level container */
1259 if (!ucl_msgpack_insert_object (parser,
1260 key, keylen, parser->cur_obj)) {
1261 return false;
1262 }
1263 /* Get new container */
1264 container = ucl_msgpack_get_container (parser, obj_parser, len);
1265

--- 10 unchanged lines hidden (view full) ---

1276 if (len != 0) {
1277 ucl_create_err (&parser->err, "unfinished value at the end");
1278
1279 return false;
1280 }
1281
1282 container = parser->stack;
1283
1264 /* Insert to the previous level container */
1265 if (!ucl_msgpack_insert_object (parser,
1266 key, keylen, parser->cur_obj)) {
1267 return false;
1268 }
1269 /* Get new container */
1270 container = ucl_msgpack_get_container (parser, obj_parser, len);
1271

--- 10 unchanged lines hidden (view full) ---

1282 if (len != 0) {
1283 ucl_create_err (&parser->err, "unfinished value at the end");
1284
1285 return false;
1286 }
1287
1288 container = parser->stack;
1289
1284 if (container == NULL) {
1290 if (parser->stack == NULL) {
1291 ucl_create_err (&parser->err,
1292 "read assoc value when no container represented");
1285 return false;
1286 }
1287
1288 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1289 p, remain);
1290 CONSUME_RET;
1291
1292

--- 13 unchanged lines hidden (view full) ---

1306 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1307 state);
1308
1309 return false;
1310 }
1311
1312 /* Rewind to the top level container */
1313 ucl_msgpack_get_next_container (parser);
1293 return false;
1294 }
1295
1296 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1297 p, remain);
1298 CONSUME_RET;
1299
1300

--- 13 unchanged lines hidden (view full) ---

1314 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1315 state);
1316
1317 return false;
1318 }
1319
1320 /* Rewind to the top level container */
1321 ucl_msgpack_get_next_container (parser);
1314 assert (parser->stack == NULL ||
1315 (parser->stack->level & MSGPACK_CONTAINER_BIT) == 0);
1316
1322
1323 if (parser->stack != NULL) {
1324 ucl_create_err (&parser->err, "incomplete container");
1325
1326 return false;
1327 }
1328
1317 return true;
1318}
1319
1320bool
1321ucl_parse_msgpack (struct ucl_parser *parser)
1322{
1323 ucl_object_t *container = NULL;
1324 const unsigned char *p;

--- 302 unchanged lines hidden ---
1329 return true;
1330}
1331
1332bool
1333ucl_parse_msgpack (struct ucl_parser *parser)
1334{
1335 ucl_object_t *container = NULL;
1336 const unsigned char *p;

--- 302 unchanged lines hidden ---