Merge branch 'develop' into feature/filenotfound
This commit is contained in:
commit
1ed510c232
7 changed files with 120 additions and 124 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -14,3 +14,7 @@ doc/html
|
|||
me.nlohmann.json.docset
|
||||
|
||||
benchmarks/files/numbers/*.json
|
||||
|
||||
.idea
|
||||
cmake-build-debug
|
||||
|
||||
|
|
|
@ -84,22 +84,22 @@ matrix:
|
|||
# Coverity (only for branch coverity_scan)
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
compiler: clang
|
||||
before_install: echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5', 'valgrind']
|
||||
packages: ['valgrind']
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "nlohmann/json"
|
||||
description: "Build submitted via Travis CI"
|
||||
notification_email: niels.lohmann@gmail.com
|
||||
build_command_prepend: "make clean ; sudo cp $(which g++-5) $(which g++)"
|
||||
build_command_prepend: "make clean"
|
||||
build_command: "make"
|
||||
branch_pattern: coverity_scan
|
||||
env:
|
||||
- COMPILER=g++-5
|
||||
- LLVM_VERSION=3.6.0
|
||||
- SPECIAL=coverity
|
||||
|
||||
# OSX / Clang
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json)
|
||||
[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json)
|
||||
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
|
||||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
|
||||
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/fsf5FqYe6GoX68W6)
|
||||
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
|
||||
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
|
||||
|
@ -501,6 +502,7 @@ I deeply appreciate the help of the following people.
|
|||
- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.
|
||||
- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.
|
||||
- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling.
|
||||
- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.
|
||||
|
||||
Thanks a lot for helping out!
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#define BENCHPRESS_CONFIG_MAIN
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <benchpress.hpp>
|
||||
#include <json.hpp>
|
||||
#include <pthread.h>
|
||||
#include <thread>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
struct StartUp
|
||||
{
|
||||
StartUp()
|
||||
|
@ -23,129 +26,93 @@ struct StartUp
|
|||
};
|
||||
StartUp startup;
|
||||
|
||||
BENCHMARK("parse jeopardy.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
enum class EMode { input, output_no_indent, output_with_indent };
|
||||
|
||||
BENCHMARK("parse canada.json", [](benchpress::context* ctx)
|
||||
static void bench(benchpress::context& ctx,
|
||||
const std::string& in_path,
|
||||
const EMode mode)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
// using string streams for benchmarking to factor-out cold-cache disk
|
||||
// access.
|
||||
std::stringstream istr;
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/nativejson-benchmark/canada.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
// read file into string stream
|
||||
std::ifstream input_file(in_path);
|
||||
istr << input_file.rdbuf();
|
||||
input_file.close();
|
||||
|
||||
BENCHMARK("parse citm_catalog.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/nativejson-benchmark/citm_catalog.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
|
||||
BENCHMARK("parse twitter.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/nativejson-benchmark/twitter.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
|
||||
BENCHMARK("parse numbers/floats.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/numbers/floats.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
|
||||
BENCHMARK("parse numbers/signed_ints.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/numbers/signed_ints.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
|
||||
BENCHMARK("parse numbers/unsigned_ints.json", [](benchpress::context* ctx)
|
||||
{
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->stop_timer();
|
||||
std::ifstream input_file("benchmarks/files/numbers/unsigned_ints.json");
|
||||
nlohmann::json j;
|
||||
ctx->start_timer();
|
||||
j << input_file;
|
||||
ctx->stop_timer();
|
||||
}
|
||||
})
|
||||
|
||||
BENCHMARK("dump jeopardy.json", [](benchpress::context* ctx)
|
||||
{
|
||||
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
|
||||
nlohmann::json j;
|
||||
j << input_file;
|
||||
std::ofstream output_file("jeopardy.dump.json");
|
||||
|
||||
ctx->reset_timer();
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
ctx->start_timer();
|
||||
output_file << j;
|
||||
ctx->stop_timer();
|
||||
// read the stream once
|
||||
json j;
|
||||
j << istr;
|
||||
// clear flags and rewind
|
||||
istr.clear();
|
||||
istr.seekg(0);
|
||||
}
|
||||
|
||||
std::remove("jeopardy.dump.json");
|
||||
})
|
||||
|
||||
BENCHMARK("dump jeopardy.json with indent", [](benchpress::context* ctx)
|
||||
switch (mode)
|
||||
{
|
||||
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
|
||||
nlohmann::json j;
|
||||
j << input_file;
|
||||
std::ofstream output_file("jeopardy.dump.json");
|
||||
|
||||
ctx->reset_timer();
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
// benchmarking input
|
||||
case EMode::input:
|
||||
{
|
||||
ctx->start_timer();
|
||||
output_file << std::setw(4) << j;
|
||||
ctx->stop_timer();
|
||||
ctx.reset_timer();
|
||||
|
||||
for (size_t i = 0; i < ctx.num_iterations(); ++i)
|
||||
{
|
||||
// clear flags and rewind
|
||||
istr.clear();
|
||||
istr.seekg(0);
|
||||
json j;
|
||||
j << istr;
|
||||
}
|
||||
|
||||
std::remove("jeopardy.dump.json");
|
||||
break;
|
||||
}
|
||||
|
||||
// benchmarking output
|
||||
case EMode::output_no_indent:
|
||||
case EMode::output_with_indent:
|
||||
{
|
||||
// create JSON value from input
|
||||
json j;
|
||||
j << istr;
|
||||
std::stringstream ostr;
|
||||
|
||||
ctx.reset_timer();
|
||||
for (size_t i = 0; i < ctx.num_iterations(); ++i)
|
||||
{
|
||||
if (mode == EMode::output_no_indent)
|
||||
{
|
||||
ostr << j;
|
||||
}
|
||||
else
|
||||
{
|
||||
ostr << std::setw(4) << j;
|
||||
}
|
||||
|
||||
// reset data
|
||||
ostr.str(std::string());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BENCHMARK_I(mode, title, in_path) \
|
||||
BENCHMARK((title), [](benchpress::context* ctx) \
|
||||
{ \
|
||||
bench(*ctx, (in_path), (mode)); \
|
||||
})
|
||||
|
||||
BENCHMARK_I(EMode::input, "parse jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json");
|
||||
BENCHMARK_I(EMode::input, "parse canada.json", "benchmarks/files/nativejson-benchmark/canada.json");
|
||||
BENCHMARK_I(EMode::input, "parse citm_catalog.json", "benchmarks/files/nativejson-benchmark/citm_catalog.json");
|
||||
BENCHMARK_I(EMode::input, "parse twitter.json", "benchmarks/files/nativejson-benchmark/twitter.json");
|
||||
BENCHMARK_I(EMode::input, "parse numbers/floats.json", "benchmarks/files/numbers/floats.json");
|
||||
BENCHMARK_I(EMode::input, "parse numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json");
|
||||
BENCHMARK_I(EMode::input, "parse numbers/unsigned_ints.json", "benchmarks/files/numbers/unsigned_ints.json");
|
||||
|
||||
BENCHMARK_I(EMode::output_no_indent, "dump jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json");
|
||||
BENCHMARK_I(EMode::output_with_indent, "dump jeopardy.json with indent", "benchmarks/files/jeopardy/jeopardy.json");
|
||||
BENCHMARK_I(EMode::output_no_indent, "dump numbers/floats.json", "benchmarks/files/numbers/floats.json");
|
||||
BENCHMARK_I(EMode::output_no_indent, "dump numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json");
|
||||
|
|
|
@ -8742,6 +8742,7 @@ basic_json_parser_66:
|
|||
m_line_buffer.clear();
|
||||
for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor)
|
||||
{
|
||||
assert(m_cursor != nullptr);
|
||||
m_line_buffer.append(1, static_cast<const char>(*m_cursor));
|
||||
}
|
||||
}
|
||||
|
@ -8749,8 +8750,11 @@ basic_json_parser_66:
|
|||
// append n characters to make sure that there is sufficient
|
||||
// space between m_cursor and m_limit
|
||||
m_line_buffer.append(1, '\x00');
|
||||
if (n > 0)
|
||||
{
|
||||
m_line_buffer.append(n - 1, '\x01');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// delete processed characters from line buffer
|
||||
|
|
|
@ -7891,6 +7891,7 @@ class basic_json
|
|||
m_line_buffer.clear();
|
||||
for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor)
|
||||
{
|
||||
assert(m_cursor != nullptr);
|
||||
m_line_buffer.append(1, static_cast<const char>(*m_cursor));
|
||||
}
|
||||
}
|
||||
|
@ -7898,8 +7899,11 @@ class basic_json
|
|||
// append n characters to make sure that there is sufficient
|
||||
// space between m_cursor and m_limit
|
||||
m_line_buffer.append(1, '\x00');
|
||||
if (n > 0)
|
||||
{
|
||||
m_line_buffer.append(n - 1, '\x01');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// delete processed characters from line buffer
|
||||
|
|
|
@ -501,4 +501,19 @@ TEST_CASE("regression tests")
|
|||
std::ifstream f("file_not_found.json");
|
||||
CHECK_THROWS_AS(json::parse(f), std::invalid_argument);
|
||||
}
|
||||
|
||||
SECTION("issue #367 - calling stream at EOF")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j;
|
||||
ss << "123";
|
||||
CHECK_NOTHROW(j << ss);
|
||||
|
||||
// see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
|
||||
// ss is not at EOF; this yielded an error before the fix
|
||||
// (threw basic_string::append). No, it should just throw
|
||||
// a parse error because of the EOF.
|
||||
CHECK_THROWS_AS(j << ss, std::invalid_argument);
|
||||
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue