mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.json: fix key allocation in HashMap for streaming json parsing (#16422)
This commit is contained in:
parent
32a175740c
commit
04c7b55de4
2 changed files with 29 additions and 6 deletions
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue