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 --- |