authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-05-03 19:26:24+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-05-04 17:56:20+12:00
logef3111be236fc389a696562d31bccd3a9b6d1c56
tree4c9b57104193fce77f41e317f6c81f77ba0069f2
parentf17472635ee8bb2fbce8a1105059cd919e1b6d5b

Use allocator backed array for json value decoder


1 files changed, 39 insertions(+), 43 deletions(-)

std/json.zig+39-43
......@@ -1017,9 +1017,7 @@ const JsonParser = struct {
10171017 state: State,
10181018 copy_strings: bool,
10191019 // Stores parent nodes and un-combined Values.
1020 // Worst case scenario we have nested key, values and so need two times the stack size.
1021 stack: [2 * StreamingJsonParser.max_stack_size]Value,
1022 stack_used: u16,
1020 stack: ArrayList(Value),
10231021
10241022 const State = enum {
10251023 ObjectKey,
......@@ -1033,14 +1031,17 @@ const JsonParser = struct {
10331031 .allocator = allocator,
10341032 .state = State.Simple,
10351033 .copy_strings = copy_strings,
1036 .stack = undefined,
1037 .stack_used = 0,
1034 .stack = ArrayList(Value).init(allocator),
10381035 };
10391036 }
10401037
1038 pub fn deinit(p: &JsonParser) void {
1039 p.stack.deinit();
1040 }
1041
10411042 pub fn reset(p: &JsonParser) void {
10421043 p.state = State.Simple;
1043 p.stack_used = 0;
1044 p.stack.shrink(0);
10441045 }
10451046
10461047 pub fn parse(p: &JsonParser, input: []const u8) !ValueTree {
......@@ -1079,11 +1080,11 @@ const JsonParser = struct {
10791080 return error.IncompleteJsonInput;
10801081 }
10811082
1082 std.debug.assert(p.stack_used == 1);
1083 std.debug.assert(p.stack.len == 1);
10831084
10841085 return ValueTree {
10851086 .arena = arena,
1086 .root = p.stack[0],
1087 .root = p.stack.at(0),
10871088 };
10881089 }
10891090
......@@ -1093,16 +1094,15 @@ const JsonParser = struct {
10931094 switch (p.state) {
10941095 State.ObjectKey => switch (token.id) {
10951096 Token.Id.ObjectEnd => {
1096 if (p.stack_used == 1) {
1097 if (p.stack.len == 1) {
10971098 return;
10981099 }
10991100
1100 var value = p.stack[p.stack_used - 1];
1101 p.stack_used -= 1;
1101 var value = p.stack.pop();
11021102 try p.pushToParent(value);
11031103 },
11041104 Token.Id.String => {
1105 p.pushStack(try p.parseString(allocator, token, input, i));
1105 try p.stack.append(try p.parseString(allocator, token, input, i));
11061106 p.state = State.ObjectValue;
11071107 },
11081108 else => {
......@@ -1110,41 +1110,41 @@ const JsonParser = struct {
11101110 },
11111111 },
11121112 State.ObjectValue => {
1113 var object = &p.stack[p.stack_used - 2].Object;
1114 var key = p.stack[p.stack_used - 1].String;
1113 var object = &p.stack.items[p.stack.len - 2].Object;
1114 var key = p.stack.items[p.stack.len - 1].String;
11151115
11161116 switch (token.id) {
11171117 Token.Id.ObjectBegin => {
1118 p.pushStack(Value { .Object = ObjectMap.init(allocator) });
1118 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
11191119 p.state = State.ObjectKey;
11201120 },
11211121 Token.Id.ArrayBegin => {
1122 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });
1122 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
11231123 p.state = State.ArrayValue;
11241124 },
11251125 Token.Id.String => {
11261126 _ = try object.put(key, try p.parseString(allocator, token, input, i));
1127 p.stack_used -= 1;
1127 _ = p.stack.pop();
11281128 p.state = State.ObjectKey;
11291129 },
11301130 Token.Id.Number => {
11311131 _ = try object.put(key, try p.parseNumber(token, input, i));
1132 p.stack_used -= 1;
1132 _ = p.stack.pop();
11331133 p.state = State.ObjectKey;
11341134 },
11351135 Token.Id.True => {
11361136 _ = try object.put(key, Value { .Bool = true });
1137 p.stack_used -= 1;
1137 _ = p.stack.pop();
11381138 p.state = State.ObjectKey;
11391139 },
11401140 Token.Id.False => {
11411141 _ = try object.put(key, Value { .Bool = false });
1142 p.stack_used -= 1;
1142 _ = p.stack.pop();
11431143 p.state = State.ObjectKey;
11441144 },
11451145 Token.Id.Null => {
11461146 _ = try object.put(key, Value.Null);
1147 p.stack_used -= 1;
1147 _ = p.stack.pop();
11481148 p.state = State.ObjectKey;
11491149 },
11501150 else => {
......@@ -1153,24 +1153,23 @@ const JsonParser = struct {
11531153 }
11541154 },
11551155 State.ArrayValue => {
1156 var array = &p.stack[p.stack_used - 1].Array;
1156 var array = &p.stack.items[p.stack.len - 1].Array;
11571157
11581158 switch (token.id) {
11591159 Token.Id.ArrayEnd => {
1160 if (p.stack_used == 1) {
1160 if (p.stack.len == 1) {
11611161 return;
11621162 }
11631163
1164 var value = p.stack[p.stack_used - 1];
1165 p.stack_used -= 1;
1164 var value = p.stack.pop();
11661165 try p.pushToParent(value);
11671166 },
11681167 Token.Id.ObjectBegin => {
1169 p.pushStack(Value { .Object = ObjectMap.init(allocator) });
1168 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
11701169 p.state = State.ObjectKey;
11711170 },
11721171 Token.Id.ArrayBegin => {
1173 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });
1172 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
11741173 p.state = State.ArrayValue;
11751174 },
11761175 Token.Id.String => {
......@@ -1195,27 +1194,27 @@ const JsonParser = struct {
11951194 },
11961195 State.Simple => switch (token.id) {
11971196 Token.Id.ObjectBegin => {
1198 p.pushStack(Value { .Object = ObjectMap.init(allocator) });
1197 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
11991198 p.state = State.ObjectKey;
12001199 },
12011200 Token.Id.ArrayBegin => {
1202 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });
1201 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
12031202 p.state = State.ArrayValue;
12041203 },
12051204 Token.Id.String => {
1206 p.pushStack(try p.parseString(allocator, token, input, i));
1205 try p.stack.append(try p.parseString(allocator, token, input, i));
12071206 },
12081207 Token.Id.Number => {
1209 p.pushStack(try p.parseNumber(token, input, i));
1208 try p.stack.append(try p.parseNumber(token, input, i));
12101209 },
12111210 Token.Id.True => {
1212 p.pushStack(Value { .Bool = true });
1211 try p.stack.append(Value { .Bool = true });
12131212 },
12141213 Token.Id.False => {
1215 p.pushStack(Value { .Bool = false });
1214 try p.stack.append(Value { .Bool = false });
12161215 },
12171216 Token.Id.Null => {
1218 p.pushStack(Value.Null);
1217 try p.stack.append(Value.Null);
12191218 },
12201219 Token.Id.ObjectEnd, Token.Id.ArrayEnd => {
12211220 unreachable;
......@@ -1225,12 +1224,12 @@ const JsonParser = struct {
12251224 }
12261225
12271226 fn pushToParent(p: &JsonParser, value: &const Value) !void {
1228 switch (p.stack[p.stack_used - 1]) {
1227 switch (p.stack.at(p.stack.len - 1)) {
12291228 // Object Parent -> [ ..., object, <key>, value ]
12301229 Value.String => |key| {
1231 p.stack_used -= 1;
1230 _ = p.stack.pop();
12321231
1233 var object = &p.stack[p.stack_used - 1].Object;
1232 var object = &p.stack.items[p.stack.len - 1].Object;
12341233 _ = try object.put(key, value);
12351234 p.state = State.ObjectKey;
12361235 },
......@@ -1245,11 +1244,6 @@ const JsonParser = struct {
12451244 }
12461245 }
12471246
1248 fn pushStack(p: &JsonParser, value: &const Value) void {
1249 p.stack[p.stack_used] = *value;
1250 p.stack_used += 1;
1251 }
1252
12531247 fn parseString(p: &JsonParser, allocator: &Allocator, token: &const Token, input: []const u8, i: usize) !Value {
12541248 // TODO: We don't strictly have to copy values which do not contain any escape
12551249 // characters if flagged with the option.
......@@ -1270,6 +1264,7 @@ const debug = std.debug;
12701264
12711265test "json parser dynamic" {
12721266 var p = JsonParser.init(std.debug.global_allocator, false);
1267 defer p.deinit();
12731268
12741269 const s =
12751270 \\{
......@@ -1289,7 +1284,8 @@ test "json parser dynamic" {
12891284 ;
12901285
12911286 var tree = try p.parse(s);
1292 tree.deinit();
1287 defer tree.deinit();
1288
12931289 var root = tree.root;
12941290
12951291 var image = (??root.Object.get("Image")).value;