mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 05:33:57 +00:00
pretty example
This commit is contained in:
parent
cf95fc7c29
commit
2db5a6c57f
@ -10,11 +10,13 @@
|
||||
GroupSources(example "/")
|
||||
|
||||
add_executable (pretty
|
||||
file.hpp
|
||||
pretty.cpp
|
||||
)
|
||||
set_property(TARGET pretty PROPERTY FOLDER "example")
|
||||
|
||||
add_executable (allocator
|
||||
file.hpp
|
||||
allocator.cpp
|
||||
)
|
||||
set_property(TARGET allocator PROPERTY FOLDER "example")
|
||||
|
111
example/file.hpp
Normal file
111
example/file.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
#ifndef BOOST_JSON_EXAMPLE_FILE_HPP
|
||||
#define BOOST_JSON_EXAMPLE_FILE_HPP
|
||||
|
||||
#include <boost/json/config.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
class file
|
||||
{
|
||||
FILE* f_ = nullptr;
|
||||
|
||||
public:
|
||||
~file()
|
||||
{
|
||||
if(f_)
|
||||
std::fclose(f_);
|
||||
}
|
||||
|
||||
file() = default;
|
||||
|
||||
file( file&& other ) noexcept
|
||||
: f_(other.f_)
|
||||
{
|
||||
other.f_ = nullptr;
|
||||
}
|
||||
|
||||
file( char const* path, char const* mode )
|
||||
{
|
||||
open( path, mode );
|
||||
}
|
||||
|
||||
file&
|
||||
operator=(file&& other) noexcept
|
||||
{
|
||||
close();
|
||||
f_ = other.f_;
|
||||
other.f_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
close()
|
||||
{
|
||||
if(f_)
|
||||
{
|
||||
std::fclose(f_);
|
||||
f_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
open(
|
||||
char const* path,
|
||||
char const* mode,
|
||||
boost::json::error_code& ec)
|
||||
{
|
||||
close();
|
||||
f_ = std::fopen( path, mode );
|
||||
if( ! f_ )
|
||||
{
|
||||
ec.assign( errno, boost::json::generic_category() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
open(
|
||||
char const* path,
|
||||
char const* mode)
|
||||
{
|
||||
boost::json::error_code ec;
|
||||
open(path, mode, ec);
|
||||
if(ec)
|
||||
throw boost::json::system_error(ec);
|
||||
}
|
||||
|
||||
bool
|
||||
eof() const noexcept
|
||||
{
|
||||
return std::feof( f_ ) != 0;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
read( char* data, std::size_t size, boost::json::error_code& ec)
|
||||
{
|
||||
auto const nread = std::fread( data, 1, size, f_ );
|
||||
if( std::ferror(f_) )
|
||||
ec.assign( errno, boost::json::generic_category() );
|
||||
return nread;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
read( char* data, std::size_t size )
|
||||
{
|
||||
boost::json::error_code ec;
|
||||
auto const nread = read( data, size, ec );
|
||||
if(ec)
|
||||
throw boost::json::system_error(ec);
|
||||
return nread;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -13,96 +13,115 @@
|
||||
*/
|
||||
|
||||
#include <boost/json.hpp>
|
||||
#include <cstdio>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include "file.hpp"
|
||||
|
||||
namespace json = boost::json;
|
||||
|
||||
class file
|
||||
{
|
||||
FILE* f_ = nullptr;
|
||||
|
||||
public:
|
||||
~file()
|
||||
{
|
||||
if(f_)
|
||||
std::fclose(f_);
|
||||
}
|
||||
|
||||
file() = default;
|
||||
|
||||
void
|
||||
close()
|
||||
{
|
||||
if(f_)
|
||||
{
|
||||
std::fclose(f_);
|
||||
f_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
open(
|
||||
char const* path,
|
||||
char const* mode,
|
||||
json::error_code& ec)
|
||||
{
|
||||
close();
|
||||
f_ = std::fopen( path, mode );
|
||||
if( ! f_ )
|
||||
{
|
||||
ec.assign( errno, json::generic_category() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
json::value
|
||||
parse_file( char const* filename )
|
||||
{
|
||||
json::error_code ec;
|
||||
auto f = std::fopen( filename, "r" );
|
||||
if( ! f )
|
||||
{
|
||||
ec.assign( errno, json::generic_category() );
|
||||
throw json::system_error(ec);
|
||||
}
|
||||
file f( filename, "r" );
|
||||
json::parser p;
|
||||
p.start();
|
||||
do
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
// Read from the file into our buffer.
|
||||
auto const nread = fread( buf, 1, sizeof(buf), f );
|
||||
if( std::ferror(f) )
|
||||
{
|
||||
ec.assign( errno, json::generic_category() );
|
||||
throw json::system_error(ec);
|
||||
}
|
||||
|
||||
auto nparsed = p.write_some( buf, nread, ec);
|
||||
|
||||
// Make sure we use all the characters in the file.
|
||||
if( ! ec && nparsed < nread )
|
||||
nparsed = p.write_some( buf + nparsed, sizeof(buf) - nparsed, ec );
|
||||
|
||||
if( ec )
|
||||
throw json::system_error(ec);
|
||||
auto const nread = f.read( buf, sizeof(buf) );
|
||||
p.write( buf, nread );
|
||||
}
|
||||
while( ! std::feof(f) );
|
||||
|
||||
// Tell the parser there is no more serialized JSON.
|
||||
p.finish(ec);
|
||||
if( ec )
|
||||
throw json::system_error(ec);
|
||||
|
||||
while( ! f.eof() );
|
||||
p.finish();
|
||||
return p.release();
|
||||
}
|
||||
|
||||
void
|
||||
pretty_print( std::ostream& os, json::value const& jv )
|
||||
pretty_print( std::ostream& os, json::value const& jv, std::string* indent = nullptr )
|
||||
{
|
||||
std::string indent_;
|
||||
if(! indent)
|
||||
indent = &indent_;
|
||||
switch(jv.kind())
|
||||
{
|
||||
case json::kind::object:
|
||||
{
|
||||
os << "{\n";
|
||||
indent->append(4, ' ');
|
||||
auto const& obj = jv.get_object();
|
||||
if(! obj.empty())
|
||||
{
|
||||
auto it = obj.begin();
|
||||
goto loop_obj;
|
||||
while( ++it != obj.end() )
|
||||
{
|
||||
os << ",\n";
|
||||
loop_obj:
|
||||
os << *indent << json::to_string(it->key()) << " : ";
|
||||
pretty_print( os, it->value(), indent);
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
indent->resize(indent->size() - 4);
|
||||
os << *indent << "}";
|
||||
break;
|
||||
}
|
||||
|
||||
case json::kind::array:
|
||||
{
|
||||
os << "[\n";
|
||||
indent->append(4, ' ');
|
||||
auto const& arr = jv.get_array();
|
||||
if(! arr.empty())
|
||||
{
|
||||
auto it = arr.begin();
|
||||
goto loop_arr;
|
||||
while( ++it != arr.end() )
|
||||
{
|
||||
os << ",\n";
|
||||
loop_arr:
|
||||
os << *indent;
|
||||
pretty_print( os, *it, indent);
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
indent->resize(indent->size() - 4);
|
||||
os << *indent << "]";
|
||||
break;
|
||||
}
|
||||
|
||||
case json::kind::string:
|
||||
{
|
||||
os << json::to_string(jv.get_string());
|
||||
break;
|
||||
}
|
||||
|
||||
case json::kind::uint64:
|
||||
os << jv.get_uint64();
|
||||
break;
|
||||
|
||||
case json::kind::int64:
|
||||
os << jv.get_int64();
|
||||
break;
|
||||
|
||||
case json::kind::double_:
|
||||
os << jv.get_double();
|
||||
break;
|
||||
|
||||
case json::kind::bool_:
|
||||
if(jv.get_bool())
|
||||
os << "true";
|
||||
else
|
||||
os << "false";
|
||||
break;
|
||||
|
||||
case json::kind::null:
|
||||
os << "null";
|
||||
break;
|
||||
}
|
||||
|
||||
if(indent->empty())
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -63,7 +63,7 @@ enum class basic_parser::state : char
|
||||
esc1, esc2, esc3, esc4,
|
||||
sur1, sur2, sur3,
|
||||
num,
|
||||
lit,
|
||||
litt, litf, litn
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -244,7 +244,7 @@ loop_val:
|
||||
++p;
|
||||
lit_ = "rue";
|
||||
ev_ = error::expected_true;
|
||||
*st_ = state::lit;
|
||||
*st_ = state::litt;
|
||||
goto loop;
|
||||
|
||||
// false
|
||||
@ -269,7 +269,7 @@ loop_val:
|
||||
++p;
|
||||
lit_ = "alse";
|
||||
ev_ = error::expected_false;
|
||||
*st_ = state::lit;
|
||||
*st_ = state::litf;
|
||||
goto loop;
|
||||
|
||||
// null
|
||||
@ -293,7 +293,7 @@ loop_val:
|
||||
++p;
|
||||
lit_ = "ull";
|
||||
ev_ = error::expected_null;
|
||||
*st_ = state::lit;
|
||||
*st_ = state::litn;
|
||||
goto loop;
|
||||
|
||||
default:
|
||||
@ -829,7 +829,9 @@ loop_num:
|
||||
|
||||
// string literal (true, false, null)
|
||||
|
||||
case state::lit:
|
||||
case state::litt:
|
||||
case state::litf:
|
||||
case state::litn:
|
||||
BOOST_JSON_ASSERT(lit_ != nullptr);
|
||||
while(p < p1)
|
||||
{
|
||||
@ -841,6 +843,14 @@ loop_num:
|
||||
++p;
|
||||
if(*++lit_ == 0)
|
||||
{
|
||||
if(*st_ == state::litt)
|
||||
this->on_bool(true, ec);
|
||||
else if(*st_ == state::litf)
|
||||
this->on_bool(false, ec);
|
||||
else
|
||||
this->on_null(ec);
|
||||
if(ec)
|
||||
goto yield;
|
||||
st_.pop();
|
||||
goto loop;
|
||||
}
|
||||
@ -980,7 +990,9 @@ finish(error_code& ec)
|
||||
break;
|
||||
}
|
||||
|
||||
case state::lit:
|
||||
case state::litt:
|
||||
case state::litf:
|
||||
case state::litn:
|
||||
ec = ev_;
|
||||
return;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user