Commit 04c7b55de4
Changed files (2)
lib
std
lib/std/json/hashmap.zig
@@ -24,15 +24,10 @@ pub fn ArrayHashMap(comptime T: type) type {
if (.object_begin != try source.next()) return error.UnexpectedToken;
while (true) {
- const token = try source.nextAlloc(allocator, .alloc_if_needed);
+ const token = try source.nextAlloc(allocator, options.allocate.?);
switch (token) {
inline .string, .allocated_string => |k| {
const gop = try map.getOrPut(allocator, k);
- if (token == .allocated_string) {
- // Free the key before recursing in case we're using an allocator
- // that optimizes freeing the last allocated object.
- allocator.free(k);
- }
if (gop.found_existing) {
switch (options.duplicate_field_behavior) {
.use_first => {
lib/std/json/hashmap_test.zig
@@ -5,10 +5,13 @@ const ArrayHashMap = @import("hashmap.zig").ArrayHashMap;
const parseFromSlice = @import("static.zig").parseFromSlice;
const parseFromSliceLeaky = @import("static.zig").parseFromSliceLeaky;
+const parseFromTokenSource = @import("static.zig").parseFromTokenSource;
const parseFromValue = @import("static.zig").parseFromValue;
const stringifyAlloc = @import("stringify.zig").stringifyAlloc;
const Value = @import("dynamic.zig").Value;
+const jsonReader = @import("./scanner.zig").reader;
+
const T = struct {
i: i32,
s: []const u8,
@@ -29,6 +32,31 @@ test "parse json hashmap" {
try testing.expectEqual(@as(i32, 1), parsed.value.map.get("xyz").?.i);
}
+test "parse json hashmap while streaming" {
+ const doc =
+ \\{
+ \\ "abc": {"i": 0, "s": "d"},
+ \\ "xyz": {"i": 1, "s": "w"}
+ \\}
+ ;
+ var stream = std.io.fixedBufferStream(doc);
+ var json_reader = jsonReader(testing.allocator, stream.reader());
+
+ var parsed = try parseFromTokenSource(
+ ArrayHashMap(T),
+ testing.allocator,
+ &json_reader,
+ .{},
+ );
+ defer parsed.deinit();
+ // Deinit our reader to invalidate its buffer
+ json_reader.deinit();
+
+ try testing.expectEqual(@as(usize, 2), parsed.value.map.count());
+ try testing.expectEqualStrings("d", parsed.value.map.get("abc").?.s);
+ try testing.expectEqual(@as(i32, 1), parsed.value.map.get("xyz").?.i);
+}
+
test "parse json hashmap duplicate fields" {
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();