Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
d12398ad
Commit
d12398ad
authored
Sep 07, 2022
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow parsing JSON directly from file
parent
e8db2cb1
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
218 additions
and
97 deletions
+218
-97
libcaf_core/caf/detail/json.hpp
libcaf_core/caf/detail/json.hpp
+13
-1
libcaf_core/caf/json_reader.hpp
libcaf_core/caf/json_reader.hpp
+11
-0
libcaf_core/caf/json_value.hpp
libcaf_core/caf/json_value.hpp
+7
-0
libcaf_core/caf/parser_state.hpp
libcaf_core/caf/parser_state.hpp
+0
-3
libcaf_core/src/detail/json.cpp
libcaf_core/src/detail/json.cpp
+127
-73
libcaf_core/src/json_reader.cpp
libcaf_core/src/json_reader.cpp
+31
-7
libcaf_core/src/json_value.cpp
libcaf_core/src/json_value.cpp
+29
-13
No files found.
libcaf_core/caf/detail/json.hpp
View file @
d12398ad
...
@@ -682,7 +682,19 @@ const array* empty_array() noexcept;
...
@@ -682,7 +682,19 @@ const array* empty_array() noexcept;
// -- parsing ------------------------------------------------------------------
// -- parsing ------------------------------------------------------------------
// Parses the input and makes a deep copy of all strings.
// Specialization for parsers operating on mutable character sequences.
using
mutable_string_parser_state
=
parser_state
<
char
*>
;
// Specialization for parsers operating on files.
using
file_parser_state
=
parser_state
<
std
::
istreambuf_iterator
<
char
>>
;
// Parses the input string and makes a deep copy of all strings.
value
*
parse
(
string_parser_state
&
ps
,
monotonic_buffer_resource
*
storage
);
// Parses the input string and makes a deep copy of all strings.
value
*
parse
(
file_parser_state
&
ps
,
monotonic_buffer_resource
*
storage
);
// Parses the input file and makes a deep copy of all strings.
value
*
parse
(
string_parser_state
&
ps
,
monotonic_buffer_resource
*
storage
);
value
*
parse
(
string_parser_state
&
ps
,
monotonic_buffer_resource
*
storage
);
// Parses the input and makes a shallow copy of strings whenever possible.
// Parses the input and makes a shallow copy of strings whenever possible.
...
...
libcaf_core/caf/json_reader.hpp
View file @
d12398ad
...
@@ -133,6 +133,17 @@ public:
...
@@ -133,6 +133,17 @@ public:
/// @note Implicitly calls `reset`.
/// @note Implicitly calls `reset`.
bool
load
(
std
::
string_view
json_text
);
bool
load
(
std
::
string_view
json_text
);
/// Parses the content of the file under the given @p path. After loading the
/// content of the JSON file, the reader is ready for attempting to
/// deserialize inspectable objects.
/// @note Implicitly calls `reset`.
bool
load_file
(
const
char
*
path
);
/// @copydoc load_file
bool
load_file
(
const
std
::
string
&
path
)
{
return
load_file
(
path
.
c_str
());
}
/// Reverts the state of the reader back to where it was after calling `load`.
/// Reverts the state of the reader back to where it was after calling `load`.
/// @post The reader is ready for attempting to deserialize another
/// @post The reader is ready for attempting to deserialize another
/// inspectable object.
/// inspectable object.
...
...
libcaf_core/caf/json_value.hpp
View file @
d12398ad
...
@@ -134,6 +134,13 @@ public:
...
@@ -134,6 +134,13 @@ public:
/// objects created from that value.
/// objects created from that value.
static
expected
<
json_value
>
parse_in_situ
(
std
::
string
&
str
);
static
expected
<
json_value
>
parse_in_situ
(
std
::
string
&
str
);
/// Attempts to parse the content of the file at @p path as JSON input into a
/// self-contained value.
static
expected
<
json_value
>
parse_file
(
const
char
*
path
);
/// @copydoc parse_file
static
expected
<
json_value
>
parse_file
(
const
std
::
string
&
path
);
// -- printing ---------------------------------------------------------------
// -- printing ---------------------------------------------------------------
template
<
class
Buffer
>
template
<
class
Buffer
>
...
...
libcaf_core/caf/parser_state.hpp
View file @
d12398ad
...
@@ -141,7 +141,4 @@ auto make_error(const parser_state<Iterator, Sentinel>& ps, Ts&&... xs)
...
@@ -141,7 +141,4 @@ auto make_error(const parser_state<Iterator, Sentinel>& ps, Ts&&... xs)
/// Specialization for parsers operating on string views.
/// Specialization for parsers operating on string views.
using
string_parser_state
=
parser_state
<
std
::
string_view
::
iterator
>
;
using
string_parser_state
=
parser_state
<
std
::
string_view
::
iterator
>
;
/// Specialization for parsers operating on mutable character sequences.
using
mutable_string_parser_state
=
parser_state
<
char
*>
;
}
// namespace caf
}
// namespace caf
libcaf_core/src/detail/json.cpp
View file @
d12398ad
This diff is collapsed.
Click to expand it.
libcaf_core/src/json_reader.cpp
View file @
d12398ad
...
@@ -8,6 +8,8 @@
...
@@ -8,6 +8,8 @@
#include "caf/detail/print.hpp"
#include "caf/detail/print.hpp"
#include "caf/string_algorithms.hpp"
#include "caf/string_algorithms.hpp"
#include <fstream>
namespace
{
namespace
{
static
constexpr
const
char
class_name
[]
=
"caf::json_reader"
;
static
constexpr
const
char
class_name
[]
=
"caf::json_reader"
;
...
@@ -150,14 +152,36 @@ bool json_reader::load(std::string_view json_text) {
...
@@ -150,14 +152,36 @@ bool json_reader::load(std::string_view json_text) {
set_error
(
make_error
(
ps
));
set_error
(
make_error
(
ps
));
st_
=
nullptr
;
st_
=
nullptr
;
return
false
;
return
false
;
}
else
{
err_
.
reset
();
detail
::
monotonic_buffer_resource
::
allocator
<
stack_type
>
alloc
{
&
buf_
};
st_
=
new
(
alloc
.
allocate
(
1
))
stack_type
(
stack_allocator
{
&
buf_
});
st_
->
reserve
(
16
);
st_
->
emplace_back
(
root_
);
return
true
;
}
}
err_
.
reset
();
detail
::
monotonic_buffer_resource
::
allocator
<
stack_type
>
alloc
{
&
buf_
};
st_
=
new
(
alloc
.
allocate
(
1
))
stack_type
(
stack_allocator
{
&
buf_
});
st_
->
reserve
(
16
);
st_
->
emplace_back
(
root_
);
return
true
;
}
bool
json_reader
::
load_file
(
const
char
*
path
)
{
using
iterator_t
=
std
::
istreambuf_iterator
<
char
>
;
reset
();
std
::
ifstream
input
{
path
};
if
(
!
input
.
is_open
())
{
emplace_error
(
sec
::
cannot_open_file
);
return
false
;
}
detail
::
json
::
file_parser_state
ps
{
iterator_t
{
input
},
iterator_t
{}};
root_
=
detail
::
json
::
parse
(
ps
,
&
buf_
);
if
(
ps
.
code
!=
pec
::
success
)
{
set_error
(
make_error
(
ps
));
st_
=
nullptr
;
return
false
;
}
err_
.
reset
();
detail
::
monotonic_buffer_resource
::
allocator
<
stack_type
>
alloc
{
&
buf_
};
st_
=
new
(
alloc
.
allocate
(
1
))
stack_type
(
stack_allocator
{
&
buf_
});
st_
->
reserve
(
16
);
st_
->
emplace_back
(
root_
);
return
true
;
}
}
void
json_reader
::
revert
()
{
void
json_reader
::
revert
()
{
...
...
libcaf_core/src/json_value.cpp
View file @
d12398ad
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
#include "caf/make_counted.hpp"
#include "caf/make_counted.hpp"
#include "caf/parser_state.hpp"
#include "caf/parser_state.hpp"
#include <fstream>
namespace
caf
{
namespace
caf
{
// -- conversion ---------------------------------------------------------------
// -- conversion ---------------------------------------------------------------
...
@@ -92,35 +94,49 @@ expected<json_value> json_value::parse(std::string_view str) {
...
@@ -92,35 +94,49 @@ expected<json_value> json_value::parse(std::string_view str) {
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
auto
root
=
detail
::
json
::
parse
(
ps
,
&
storage
->
buf
);
auto
root
=
detail
::
json
::
parse
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
if
(
ps
.
code
==
pec
::
success
)
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
return
{
make_error
(
ps
)};
}
}
expected
<
json_value
>
json_value
::
parse_shallow
(
std
::
string_view
str
)
{
expected
<
json_value
>
json_value
::
parse_shallow
(
std
::
string_view
str
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
auto
root
=
detail
::
json
::
parse_shallow
(
ps
,
&
storage
->
buf
);
auto
root
=
detail
::
json
::
parse_shallow
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
if
(
ps
.
code
==
pec
::
success
)
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
return
{
make_error
(
ps
)};
}
}
expected
<
json_value
>
json_value
::
parse_in_situ
(
std
::
string
&
str
)
{
expected
<
json_value
>
json_value
::
parse_in_situ
(
std
::
string
&
str
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
mutable_string_parser_state
ps
{
str
.
data
(),
str
.
data
()
+
str
.
size
()};
detail
::
json
::
mutable_string_parser_state
ps
{
str
.
data
(),
str
.
data
()
+
str
.
size
()};
auto
root
=
detail
::
json
::
parse_in_situ
(
ps
,
&
storage
->
buf
);
auto
root
=
detail
::
json
::
parse_in_situ
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
if
(
ps
.
code
==
pec
::
success
)
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
return
{
make_error
(
ps
)};
}
expected
<
json_value
>
json_value
::
parse_file
(
const
char
*
path
)
{
using
iterator_t
=
std
::
istreambuf_iterator
<
char
>
;
std
::
ifstream
input
{
path
};
if
(
!
input
.
is_open
())
return
make_error
(
sec
::
cannot_open_file
);
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
detail
::
json
::
file_parser_state
ps
{
iterator_t
{
input
},
iterator_t
{}};
auto
root
=
detail
::
json
::
parse
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
==
pec
::
success
)
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
return
{
make_error
(
ps
)};
}
}
expected
<
json_value
>
json_value
::
parse_file
(
const
std
::
string
&
path
)
{
return
parse_file
(
path
.
c_str
());
}
// -- free functions -----------------------------------------------------------
std
::
string
to_string
(
const
json_value
&
val
)
{
std
::
string
to_string
(
const
json_value
&
val
)
{
std
::
string
result
;
std
::
string
result
;
val
.
print_to
(
result
);
val
.
print_to
(
result
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment