src/json.c

changeset 1078
ffa8bb4e9288
parent 1077
911a154dd469
child 1079
4e1872151fb6
equal deleted inserted replaced
1077:911a154dd469 1078:ffa8bb4e9288
942 false, 942 false,
943 80 943 80
944 }; 944 };
945 } 945 }
946 946
947 static int cx_json_writer_indent(
948 void *target,
949 cx_write_func wfunc,
950 const CxJsonWriter *settings,
951 unsigned int depth
952 ) {
953 if (depth == 0) return 0;
954
955 // determine the width and characters to use
956 const char* indent; // for 32 prepared chars
957 size_t width = depth;
958 if (settings->indent_space) {
959 if (settings->indent == 0) return 0;
960 width *= settings->indent;
961 indent = " ";
962 } else {
963 indent = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
964 }
965
966 // calculate the number of write calls and write
967 size_t full = width / 32;
968 size_t remaining = width % 32;
969 for (size_t i = 0; i < full; i++) {
970 if (32 != wfunc(indent, 1, 32, target)) return 1;
971 }
972 if (remaining != wfunc(indent, 1, remaining, target)) return 1;
973
974 return 0;
975 }
976
947 977
948 int cx_json_write_rec( 978 int cx_json_write_rec(
949 void *target, 979 void *target,
950 const CxJsonValue *value, 980 const CxJsonValue *value,
951 cx_write_func wfunc, 981 cx_write_func wfunc,
952 const CxJsonWriter *settings, 982 const CxJsonWriter *settings,
953 unsigned int depth 983 unsigned int depth
954 ) { 984 ) {
955 // TODO: implement indentation
956
957 // keep track of written items 985 // keep track of written items
986 // the idea is to reduce the number of jumps for error checking
958 size_t actual = 0, expected = 0; 987 size_t actual = 0, expected = 0;
959 988
960 // small buffer for number to string conversions 989 // small buffer for number to string conversions
961 char numbuf[32]; 990 char numbuf[32];
962 991
969 expected += 2; 998 expected += 2;
970 } else { 999 } else {
971 actual += wfunc(begin_obj, 1, 1, target); 1000 actual += wfunc(begin_obj, 1, 1, target);
972 expected++; 1001 expected++;
973 } 1002 }
1003 depth++;
974 CxIterator iter = cxJsonObjIter(value); 1004 CxIterator iter = cxJsonObjIter(value);
975 cx_foreach(CxJsonObjValue*, member, iter) { 1005 cx_foreach(CxJsonObjValue*, member, iter) {
1006 // possible indentation
1007 if (settings->pretty) {
1008 if (cx_json_writer_indent(target, wfunc, settings, depth)) return 1;
1009 }
1010
976 // the name 1011 // the name
977 actual += wfunc("\"", 1, 1, target); 1012 actual += wfunc("\"", 1, 1, target);
978 // TODO: escape the string 1013 // TODO: escape the string
979 actual += wfunc(member->name.ptr, 1, 1014 actual += wfunc(member->name.ptr, 1,
980 member->name.length, target); 1015 member->name.length, target);
987 actual += wfunc(obj_name_sep, 1, 1, target); 1022 actual += wfunc(obj_name_sep, 1, 1, target);
988 expected += 3 + member->name.length; 1023 expected += 3 + member->name.length;
989 } 1024 }
990 1025
991 // the value 1026 // the value
992 if (0 == cx_json_write_rec( 1027 if (cx_json_write_rec(target, member->value, wfunc, settings, depth)) return 1;
993 target, member->value,
994 wfunc, settings, depth + 1)
995 ) {
996 actual++; // count the nested values as one item
997 }
998 expected++;
999 1028
1000 // end of object-value 1029 // end of object-value
1001 if (iter.index < iter.elem_count - 1) { 1030 if (iter.index < iter.elem_count - 1) {
1002 const char *obj_value_sep = ",\n"; 1031 const char *obj_value_sep = ",\n";
1003 if (settings->pretty) { 1032 if (settings->pretty) {
1012 actual += wfunc("\n", 1, 1, target); 1041 actual += wfunc("\n", 1, 1, target);
1013 expected ++; 1042 expected ++;
1014 } 1043 }
1015 } 1044 }
1016 } 1045 }
1046 depth--;
1047 if (settings->pretty) {
1048 if (cx_json_writer_indent(target, wfunc, settings, depth)) return 1;
1049 }
1017 actual += wfunc("}", 1, 1, target); 1050 actual += wfunc("}", 1, 1, target);
1018 expected++; 1051 expected++;
1019 break; 1052 break;
1020 } 1053 }
1021 case CX_JSON_ARRAY: { 1054 case CX_JSON_ARRAY: {
1022 // TODO: implement array wrapping 1055 // TODO: implement array wrapping
1023 actual += wfunc("[", 1, 1, target); 1056 actual += wfunc("[", 1, 1, target);
1024 expected++; 1057 expected++;
1025 CxIterator iter = cxJsonArrIter(value); 1058 CxIterator iter = cxJsonArrIter(value);
1026 cx_foreach(CxJsonValue*, element, iter) { 1059 cx_foreach(CxJsonValue*, element, iter) {
1027 // TODO: pretty printing obj elements vs. primitives 1060 if (cx_json_write_rec(
1028 if (0 == cx_json_write_rec(
1029 target, element, 1061 target, element,
1030 wfunc, settings, depth + 1) 1062 wfunc, settings, depth)
1031 ) { 1063 ) return 1;
1032 actual++; // count the nested values as one item
1033 }
1034 expected++;
1035 1064
1036 if (iter.index < iter.elem_count - 1) { 1065 if (iter.index < iter.elem_count - 1) {
1037 const char *arr_value_sep = ", "; 1066 const char *arr_value_sep = ", ";
1038 if (settings->pretty) { 1067 if (settings->pretty) {
1039 actual += wfunc(arr_value_sep, 1, 2, target); 1068 actual += wfunc(arr_value_sep, 1, 2, target);

mercurial