File InputStreamReader.h
File List > detail > tools > InputStreamReader.h
Go to the documentation of this file
// Copyright (c) 2012-2013, IGN France.
// Copyright (c) 2012-2022, Oslandia.
// SPDX-License-Identifier: LGPL-2.0-or-later
#ifndef _SFCGAL_TOOLS_INPUTSTREAMREADER_H_
#define _SFCGAL_TOOLS_INPUTSTREAMREADER_H_
#include "SFCGAL/config.h"
#include <cctype>
#include <sstream>
#include <stack>
#include <string>
namespace SFCGAL {
namespace tools {
template <typename CharType>
class BasicInputStreamReader;
typedef BasicInputStreamReader<char> InputStreamReader;
typedef BasicInputStreamReader<wchar_t> WInputStreamReader;
template <typename CharType>
class BasicInputStreamReader {
public:
typedef CharType char_type;
typedef typename std::basic_string<char_type> string_type;
typedef typename std::basic_istream<char_type> istream_type;
typedef typename std::basic_istream<char_type>::pos_type pos_type;
BasicInputStreamReader(istream_type &s, bool skipWhiteSpaces = true)
: _s(s), _states(), _skipWhiteSpaces(skipWhiteSpaces)
{
_s >> std::noskipws;
}
bool
match(char_type const &c)
{
begin();
if (_skipWhiteSpaces) {
skipWhiteSpaces();
}
if (!_s.eof() && _s.get() == c) {
commit();
return true;
} else {
rollback();
return false;
}
}
bool
imatch(char_type const &c)
{
begin();
if (_skipWhiteSpaces) {
skipWhiteSpaces();
}
if (!_s.eof() && ::tolower(_s.get()) == ::tolower(c)) {
commit();
return true;
} else {
rollback();
return false;
}
}
bool
match(string_type const &str)
{
begin();
if (_skipWhiteSpaces) {
skipWhiteSpaces();
}
for (typename string_type::const_iterator it = str.begin(); it != str.end();
++it) {
if (!_s.eof() && _s.get() == *it) {
continue;
}
rollback();
return false;
}
commit();
return true;
}
bool
imatch(string_type const &str)
{
begin();
if (_skipWhiteSpaces) {
skipWhiteSpaces();
}
for (typename string_type::const_iterator it = str.begin(); it != str.end();
++it) {
if (!_s.eof() && ::tolower(_s.get()) == ::tolower(*it)) {
continue;
}
rollback();
return false;
}
commit();
return true;
}
template <typename T>
bool
read(T &value)
{
begin();
if (_skipWhiteSpaces) {
skipWhiteSpaces();
}
if (_s >> CGAL::iformat(value)) {
commit();
return true;
} else {
rollback();
return false;
}
}
auto
readBytes(std::string &buffer, size_t bytesToRead) -> void
{
begin();
_s.read(&buffer[0], bytesToRead);
commit();
}
void
begin()
{
_states.push(_s.tellg());
}
void
commit()
{
_states.pop();
}
void
rollback()
{
_s.seekg(_states.top());
_s.clear();
_states.pop();
}
bool
eof() const
{
return _s.eof() || (_s.peek() == std::char_traits<char_type>::eof());
}
inline istream_type &
s()
{
return _s;
}
inline istream_type const &
s() const
{
return _s;
}
string_type
context(size_t nMax = 20)
{
begin();
std::basic_ostringstream<char_type> oss;
for (size_t i = 0; i < nMax; i++) {
if (eof()) {
break;
}
oss << (char_type)s().get();
}
if (!eof()) {
oss << "...";
}
rollback();
return oss.str();
}
private:
istream_type &_s;
std::stack<pos_type> _states;
bool _skipWhiteSpaces;
void
skipWhiteSpaces()
{
while (!_s.eof() && std::isspace(_s.peek())) {
_s.get();
continue;
}
}
BasicInputStreamReader(BasicInputStreamReader const &other);
};
} // namespace tools
} // namespace SFCGAL
#endif