1#ifndef SIMDJSON_PADDED_STRING_INL_H
2#define SIMDJSON_PADDED_STRING_INL_H
4#include "simdjson/padded_string.h"
5#include "simdjson/padded_string_view.h"
7#include "simdjson/error-inl.h"
8#include "simdjson/padded_string_view-inl.h"
30inline char *allocate_padded_buffer(
size_t length)
noexcept {
32 if(totalpaddedlength<length) {
36#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
38 if (totalpaddedlength>(1UL<<20)) {
43 char *padded_buffer =
new (std::nothrow)
char[totalpaddedlength];
44 if (padded_buffer ==
nullptr) {
49 std::memset(padded_buffer + length, 0, totalpaddedlength - length);
58 : viable_size(length), data_ptr(internal::allocate_padded_buffer(length)) {
61 : viable_size(length), data_ptr(internal::allocate_padded_buffer(length)) {
62 if ((data !=
nullptr) && (data_ptr !=
nullptr)) {
63 std::memcpy(data_ptr, data, length);
65 if (data_ptr ==
nullptr) {
71 : viable_size(length), data_ptr(internal::allocate_padded_buffer(length)) {
72 if ((data !=
nullptr) && (data_ptr !=
nullptr)) {
73 std::memcpy(data_ptr,
reinterpret_cast<const char *
>(data), length);
75 if (data_ptr ==
nullptr) {
82 : viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) {
83 if (data_ptr ==
nullptr) {
86 std::memcpy(data_ptr, str_.data(), str_.size());
91 : viable_size(sv_.size()), data_ptr(internal::allocate_padded_buffer(sv_.size())) {
92 if(simdjson_unlikely(!data_ptr)) {
98 std::memcpy(data_ptr, sv_.data(), sv_.size());
102 : viable_size(o.viable_size), data_ptr(o.data_ptr) {
103 o.data_ptr =
nullptr;
109 data_ptr = o.data_ptr;
110 viable_size = o.viable_size;
111 o.data_ptr =
nullptr;
117 size_t tmp_viable_size = viable_size;
118 char *tmp_data_ptr = data_ptr;
119 viable_size = o.viable_size;
120 data_ptr = o.data_ptr;
121 o.data_ptr = tmp_data_ptr;
122 o.viable_size = tmp_viable_size;
125inline padded_string::~padded_string() noexcept {
141 size_t new_size = viable_size + length;
142 if (new_size < viable_size) {
146 char *new_data_ptr = internal::allocate_padded_buffer(new_size);
147 if (new_data_ptr ==
nullptr) {
152 if (viable_size > 0) {
153 std::memcpy(new_data_ptr, data_ptr, viable_size);
156 std::memcpy(new_data_ptr + viable_size, data, length);
159 data_ptr = new_data_ptr;
160 viable_size = new_size;
164inline padded_string::operator std::string_view() const simdjson_lifetime_bound {
return std::string_view(data(), length()); }
173 const std::string null_terminated_filename(filename);
175 SIMDJSON_PUSH_DISABLE_WARNINGS
176 SIMDJSON_DISABLE_DEPRECATED_WARNING
177 std::FILE *fp = std::fopen(null_terminated_filename.c_str(),
"rb");
178 SIMDJSON_POP_DISABLE_WARNINGS
186#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
187 ret = _fseeki64(fp, 0, SEEK_END);
189 ret = std::fseek(fp, 0, SEEK_END);
195#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
196 __int64 llen = _ftelli64(fp);
202 long llen = std::ftell(fp);
203 if((llen < 0) || (llen == LONG_MAX)) {
210 size_t len =
static_cast<size_t>(llen);
212 if (s.
data() ==
nullptr) {
219 size_t bytes_read = std::fread(s.
data(), 1, len, fp);
220 if (std::fclose(fp) != 0 || bytes_read != len) {
227#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
231 const std::wstring null_terminated_filename(filename);
233 SIMDJSON_PUSH_DISABLE_WARNINGS
234 SIMDJSON_DISABLE_DEPRECATED_WARNING
235 std::FILE *fp = _wfopen(null_terminated_filename.c_str(), L
"rb");
236 SIMDJSON_POP_DISABLE_WARNINGS
244#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
245 ret = _fseeki64(fp, 0, SEEK_END);
247 ret = std::fseek(fp, 0, SEEK_END);
253#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
254 __int64 llen = _ftelli64(fp);
260 long llen = std::ftell(fp);
261 if((llen < 0) || (llen == LONG_MAX)) {
268 size_t len =
static_cast<size_t>(llen);
269 padded_string s(len);
270 if (s.data() ==
nullptr) {
277 size_t bytes_read = std::fread(s.data(), 1, len, fp);
278 if (std::fclose(fp) != 0 || bytes_read != len) {
291 if (new_capacity > 0) {
292 data = internal::allocate_padded_buffer(new_capacity);
293 if (data !=
nullptr) {
294 this->capacity = new_capacity;
300 : size(o.size), capacity(o.capacity), data(o.data) {
310 capacity = o.capacity;
327 if (!reserve(length)) {
330 std::memcpy(data + size, newdata, length);
336 return append(sv.data(), sv.size());
349 result.data_ptr = data;
350 result.viable_size = size;
357inline bool padded_string_builder::reserve(
size_t additional)
noexcept {
358 if (simdjson_unlikely(additional + size < size)) {
361 size_t needed = size + additional;
362 if (needed <= capacity) {
365 size_t new_capacity = needed;
368 if (new_capacity < 4096) {
371 }
else if (new_capacity + new_capacity / 2 > new_capacity) {
372 new_capacity += new_capacity / 2;
374 char *new_data = internal::allocate_padded_buffer(new_capacity);
375 if (new_data ==
nullptr) {
379 std::memcpy(new_data, data, size);
383 capacity = new_capacity;
389simdjson_inline padded_memory_map::padded_memory_map(
const char *filename)
noexcept {
391 int fd = open(filename, O_RDONLY);
396 if (fstat(fd, &st) == -1) {
400 size =
static_cast<size_t>(st.st_size);
403 mmap(NULL, total_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
404 if (anon_map == MAP_FAILED) {
409 mmap(anon_map, size, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
410 if (file_map == MAP_FAILED) {
411 munmap(anon_map, total_size);
415 data =
static_cast<const char *
>(file_map);
420 if (data !=
nullptr) {
434 return data !=
nullptr;
simdjson_inline bool is_valid() const noexcept
Check if the memory map is valid.
simdjson_inline ~padded_memory_map() noexcept
Destroy the padded memory map and release any resources.
simdjson_inline simdjson::padded_string_view view() const noexcept simdjson_lifetime_bound
Get a view of the memory-mapped file.
Builder for constructing padded_string incrementally.
padded_string convert() noexcept
Convert the current content into a padded_string.
padded_string_builder & operator=(padded_string_builder &&o) noexcept
Move assignment.
~padded_string_builder() noexcept
Destructor.
size_t length() const noexcept
Get the current length of the built string.
padded_string build() const noexcept
Build a padded_string from the current content.
bool append(const char *newdata, size_t length) noexcept
Append data to the builder.
padded_string_builder() noexcept
Create a new, empty padded string builder.
User-provided string that promises it has extra padded bytes at the end for use with parser::parse().
The top level simdjson namespace, containing everything the library provides.
@ MEMALLOC
Error allocating memory, most likely out of memory.
@ IO_ERROR
Error reading a file.
constexpr size_t SIMDJSON_PADDING
The amount of padding needed in a buffer to parse JSON.
String with extra allocation for ease of use with parser::parse()
size_t size() const noexcept
The length of the string.
bool append(const char *data, size_t length) noexcept
Append data to the padded string.
size_t length() const noexcept
The length of the string.
padded_string() noexcept
Create a new, empty padded string.
padded_string & operator=(padded_string &&o) noexcept
Move one padded string into another.
const char * data() const noexcept
The string data.
static simdjson_result< padded_string > load(std::string_view path) noexcept
Load this padded string from a file.
The result of a simdjson operation that could fail.