Commit f3f554b9b8
Changed files (2)
lib
std
lib/std/json/dynamic.zig
@@ -93,11 +93,11 @@ pub const Value = union(enum) {
stack.items[stack.items.len - 1] == .array or
(stack.items[stack.items.len - 2] == .object and stack.items[stack.items.len - 1] == .string));
- switch (try source.nextAlloc(allocator, .alloc_if_needed)) {
- inline .string, .allocated_string => |s| {
+ switch (try source.nextAlloc(allocator, .alloc_always)) {
+ .allocated_string => |s| {
return try handleCompleteValue(&stack, allocator, source, Value{ .string = s }) orelse continue;
},
- inline .number, .allocated_number => |slice| {
+ .allocated_number => |slice| {
return try handleCompleteValue(&stack, allocator, source, Value.parseFromNumberSlice(slice)) orelse continue;
},
@@ -106,9 +106,9 @@ pub const Value = union(enum) {
.false => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = false }) orelse continue,
.object_begin => {
- switch (try source.nextAlloc(allocator, .alloc_if_needed)) {
+ switch (try source.nextAlloc(allocator, .alloc_always)) {
.object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = ObjectMap.init(allocator) }) orelse continue,
- inline .string, .allocated_string => |key| {
+ .allocated_string => |key| {
try stack.appendSlice(&[_]Value{
Value{ .object = ObjectMap.init(allocator) },
Value{ .string = key },
@@ -152,7 +152,7 @@ fn handleCompleteValue(stack: *Array, allocator: Allocator, source: anytype, val
// This is an invalid state to leave the stack in,
// so we have to process the next token before we return.
- switch (try source.nextAlloc(allocator, .alloc_if_needed)) {
+ switch (try source.nextAlloc(allocator, .alloc_always)) {
.object_end => {
// This object is complete.
value = stack.pop();
@@ -160,7 +160,7 @@ fn handleCompleteValue(stack: *Array, allocator: Allocator, source: anytype, val
if (stack.items.len == 0) return value;
continue;
},
- inline .string, .allocated_string => |next_key| {
+ .allocated_string => |next_key| {
// We've got another key.
try stack.append(Value{ .string = next_key });
// stack: [..., .object, .string]
lib/std/json/dynamic_test.zig
@@ -15,6 +15,7 @@ const parseFromValueLeaky = @import("static.zig").parseFromValueLeaky;
const ParseOptions = @import("static.zig").ParseOptions;
const jsonReader = @import("scanner.zig").reader;
+const JsonReader = @import("scanner.zig").Reader;
test "json.parser.dynamic" {
const s =
@@ -288,3 +289,42 @@ test "polymorphic parsing" {
try testing.expect(tree.div.color == .blue);
try testing.expectEqualStrings("Cancel", tree.div.children[1].button.caption);
}
+
+test "long object value" {
+ const value = "01234567890123456789";
+ const doc = "{\"key\":\"" ++ value ++ "\"}";
+ var fbs = std.io.fixedBufferStream(doc);
+ var reader = smallBufferJsonReader(testing.allocator, fbs.reader());
+ defer reader.deinit();
+ var parsed = try parseFromTokenSource(Value, testing.allocator, &reader, .{});
+ defer parsed.deinit();
+
+ try testing.expectEqualStrings(value, parsed.value.object.get("key").?.string);
+}
+
+test "many object keys" {
+ const doc =
+ \\{
+ \\ "k1": "v1",
+ \\ "k2": "v2",
+ \\ "k3": "v3",
+ \\ "k4": "v4",
+ \\ "k5": "v5"
+ \\}
+ ;
+ var fbs = std.io.fixedBufferStream(doc);
+ var reader = smallBufferJsonReader(testing.allocator, fbs.reader());
+ defer reader.deinit();
+ var parsed = try parseFromTokenSource(Value, testing.allocator, &reader, .{});
+ defer parsed.deinit();
+
+ try testing.expectEqualStrings("v1", parsed.value.object.get("k1").?.string);
+ try testing.expectEqualStrings("v2", parsed.value.object.get("k2").?.string);
+ try testing.expectEqualStrings("v3", parsed.value.object.get("k3").?.string);
+ try testing.expectEqualStrings("v4", parsed.value.object.get("k4").?.string);
+ try testing.expectEqualStrings("v5", parsed.value.object.get("k5").?.string);
+}
+
+fn smallBufferJsonReader(allocator: Allocator, io_reader: anytype) JsonReader(16, @TypeOf(io_reader)) {
+ return JsonReader(16, @TypeOf(io_reader)).init(allocator, io_reader);
+}