Skip to content

Commit

Permalink
do not read more than there is in istream
Browse files Browse the repository at this point in the history
  • Loading branch information
niXman committed Aug 20, 2021
1 parent 64844ad commit 7af7953
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 10 deletions.
5 changes: 4 additions & 1 deletion include/yas/count_streams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ namespace yas {
/***************************************************************************/

struct count_ostream {
count_ostream()
:total_size{}
{}

template<typename T>
std::size_t write(const T *, const std::size_t size) {
total_size += size;
return size;
}

std::size_t total_size = 0;
std::size_t total_size;
}; // struct null_ostream

/***************************************************************************/
Expand Down
8 changes: 4 additions & 4 deletions include/yas/detail/io/json_streams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,15 @@ struct json_istream {
template<typename T>
void read(T &v, __YAS_ENABLE_IF_IS_ANY_OF(T, std::int16_t, std::int32_t, std::int64_t)) {
char buf[sizeof(T)*4];
const std::size_t n = json_read_num(is, buf, sizeof(buf));
const std::size_t n = json_read_num(is, buf, (std::min)(sizeof(buf), is.available()));
v = Trait::template atoi<T>(buf, n);
}

// for unsigned 16/32/64 bits
template<typename T>
void read(T &v, __YAS_ENABLE_IF_IS_ANY_OF(T, std::uint16_t, std::uint32_t, std::uint64_t)) {
char buf[sizeof(T)*4];
const std::size_t n = json_read_num(is, buf, sizeof(buf));
const std::size_t n = json_read_num(is, buf, (std::min)(sizeof(buf), is.available()));

v = Trait::template atou<T>(buf, n);
}
Expand All @@ -229,7 +229,7 @@ struct json_istream {
is.getch();
}

const std::size_t n = json_read_double(is, buf, sizeof(buf));
const std::size_t n = json_read_double(is, buf, (std::min)(sizeof(buf), is.available()));

if ( is.peekch() == '\"' ) {
is.getch();
Expand All @@ -247,7 +247,7 @@ struct json_istream {
is.getch();
}

const std::size_t n = json_read_double(is, buf, sizeof(buf));
const std::size_t n = json_read_double(is, buf, (std::min)(sizeof(buf), is.available()));

if ( is.peekch() == '\"' ) {
is.getch();
Expand Down
4 changes: 0 additions & 4 deletions include/yas/detail/tools/json_tools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,6 @@ std::size_t json_read_num(Archive &ar, char *ptr, std::size_t size) {
++ptr;
} while ( --size );

ar.ungetch(*ptr);

return ptr-p;
}

Expand Down Expand Up @@ -335,8 +333,6 @@ std::size_t json_read_double(Archive &ar, char *ptr, std::size_t size) {
++ptr;
} while ( --size );

ar.ungetch(*ptr);

return ptr-p;
}

Expand Down
9 changes: 9 additions & 0 deletions include/yas/file_streams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,16 @@ struct file_istream {

file_istream(const char *fname, std::size_t m = 0)
:file(std::fopen(fname, "rb"))
,fsize(0)
{
if ( !file ) {
__YAS_THROW_ERROR_OPEN_FILE();
}

std::fseek(file, 0, SEEK_END);
fsize = std::ftell(file);
std::fseek(file, 0, SEEK_SET);

if ( m & file_nobuf ) {
std::setvbuf(file, nullptr, _IONBF, 0);
}
Expand All @@ -139,6 +144,9 @@ struct file_istream {
return std::fread(ptr, 1, size, file);
}

std::size_t available() const {
return fsize - std::ftell(file);
}
bool empty() const { return peekch() == char(EOF); }
char peekch() const {
// TODO: optimize
Expand All @@ -152,6 +160,7 @@ struct file_istream {

private:
std::FILE *file;
std::size_t fsize;
}; // struct file_istream

/***************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions include/yas/mem_streams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ struct mem_istream {
return avail;
}

std::size_t available() const { return end-cur; }
bool empty() const { return cur == end; }
char peekch() const { return *cur; }
char getch() { return *cur++; }
Expand Down
10 changes: 9 additions & 1 deletion include/yas/std_streams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,27 @@ struct std_istream_adapter {

std_istream_adapter(std::istream &is)
:is(is)
{}
,fsize(0)
{
std::streampos pos = is.tellg();
is.seekg(0, std::ios::end);
fsize = is.tellg() - pos;
is.seekg(pos, std::ios::beg);
}

std::size_t read(void *ptr, const std::size_t size) {
return __YAS_SCAST(std::size_t, is.read(__YAS_SCAST(char*, ptr), size).gcount());
}

std::size_t available() const { return fsize - is.tellg(); }
bool empty() const { return is.peek() == EOF; }
char peekch() const { return __YAS_SCAST(char, is.peek()); }
char getch() { return __YAS_SCAST(char, is.get()); }
void ungetch(char ch) { is.putback(ch); }

private:
std::istream &is;
std::size_t fsize;
}; // struct std_istream

/***************************************************************************/
Expand Down
13 changes: 13 additions & 0 deletions tests/base/include/fundamental.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ bool fundamental_test(std::ostream &log, const char *archive_type, const char *t
}
}

if ( archive_traits::oarchive_type::type() == yas::json ) {
yas::intrusive_buffer ibuf("1234", 2);

yas::mem_istream is(ibuf);
yas::json_iarchive<yas::mem_istream> ia(is);
int v = 0;
ia & v;
if ( v != 12 ) {
YAS_TEST_REPORT(log, archive_type, test_name);
return false;
}
}

return true;
}

Expand Down

0 comments on commit 7af7953

Please sign in to comment.