Муниципальная олимпиада 2024, Пробный турнир / std.check.src.stream.cpp

ru en cn

с начала прошло: 11 д. 19:02
страница обновлена: 30.12.2024 06:02

std.check.src.stream.cpp: src/stream.cpp

#include "error.hpp"
#include "formatter.hpp"
#include "stream.hpp"
// Disable annoying warning 4996: "'function' was declared deprecated"
#if CHECK_MSC_VERSION(14, 0)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
namespace Check
{
const Decision Stream::FormatErrorResult[3] =
{ // 0 = InputStream, 1 = OutputStream, 2 = AnswerStream
UnhandledError, PresentationError, UnhandledError
};
void Stream::initialize()
{
file = NULL;
type = InputStream;
closed = endFound = true;
boolFmt = IntegerBoolean;
trueStr.reserve(DefaultTrueFalseLength);
falseStr.reserve(DefaultTrueFalseLength);
endFileMode = FailAtEnd;
spaceMode = SkipWhite;
charsBeforeWord = &SpaceChars;
commonBuffer.reserve(DefaultTrueFalseLength);
}
Stream &Stream::read(char &symbol)
{
const int value = CHECK_GETC(file);
symbol = static_cast (value); endFound = (value == EOF); if (endFound && endFileMode == FailAtEnd) incite(FormatErrorResult[type]); return *this; } Stream &Stream::read( char *word, const size_t maxLength, const CharSet &before, const CharSet &after, const bool putbackLast) { // If it's impossible to read anything, do not touch the stream if (maxLength == 0) return *this; skip(before); if (CHECK_FEOF(file)) { endFound = true; if (endFileMode == FailAtEnd) incite(FormatErrorResult[type]); else return *this; } for (size_t count = 0; count + 1 != maxLength; ++count) { const int symbol = CHECK_GETC(file); if (symbol == EOF || after.contains(symbol)) { if (putbackLast) CHECK_UNGETC(symbol, file); break; } *word = static_cast(symbol); ++word; } *word = '\0'; return *this; } Stream &Stream::read( std::string &word, const CharSet &before, const CharSet &after, const bool putbackLast) { skip(before); if (CHECK_FEOF(file)) { endFound = true; if (endFileMode == FailAtEnd) incite(FormatErrorResult[type]); else return *this; } word.clear(); size_t count = 0; static char buffer[StringReadBufferSize]; int symbol = CHECK_GETC(file); while (symbol != EOF && !after.contains(symbol)) { if (count == StringReadBufferSize) { word.append(buffer, count); count = 0; } buffer[count] = static_cast(symbol); ++count; symbol = CHECK_GETC(file); } word.append(buffer, count); if (putbackLast) CHECK_UNGETC(symbol, file); return *this; } void Stream::open(const char *fileName, const StreamMode openMode) { close(); name = fileName; type = openMode; endFound = false; // File should be opened as text to handle new lines correctly (on Windows) file = fopen(name.c_str(), "rt"); if (file == NULL) raise( FormatErrorResult[type], "File \'%s\' cannot be opened", name.c_str()); closed = false; } void Stream::close() { if (!closed) { // Mark the file as closed not to try to close it again after fail closed = endFound = true; if (fclose(file) != 0) raise( UnhandledError, "File \'%s\' cannot be closed", name.c_str()); file = NULL; } } Stream &Stream::skip(const CharSet &charSet) { if (charSet.isEmpty()) return *this; int symbol; do symbol = CHECK_GETC(file); while (symbol != EOF && charSet.contains(symbol)); CHECK_UNGETC(symbol, file); return *this; } Stream &Stream::skip(const CharSet &charSet, const size_t maxLength) { if (maxLength == 0 || charSet.isEmpty()) return *this; size_t count = 0; int symbol = CHECK_GETC(file); while (symbol != EOF && charSet.contains(symbol)) { ++count; if (count == maxLength) return *this; symbol = CHECK_GETC(file); } CHECK_UNGETC(symbol, file); return *this; } int Stream::peek() { const int symbol = CHECK_GETC(file); endFound = (symbol == EOF); CHECK_UNGETC(symbol, file); return symbol; } Stream &Stream::putback(const char symbol) { if (CHECK_UNGETC(symbol, file) == EOF) incite(UnhandledError, "Symbol cannot be put back"); return *this; } Stream &Stream::get(char &symbol, const CharSet &charSet) { read(symbol); if (!(endFound || charSet.contains(symbol))) raise( FormatErrorResult[type], "Unexpected symbol \'%c\'", symbol); return *this; } Stream &Stream::operator >> (bool &value) { switch (boolFmt) { case IntegerBoolean: { int number; (*this) >> number; value = (number != 0); } break; case StringBoolean: { get(commonBuffer); if (commonBuffer == trueStr) value = true; else if (commonBuffer == falseStr) value = false; else raise( FormatErrorResult[type], "Unexpected boolean value %s", quote(commonBuffer).c_str()); } break; default: { incite(UnhandledError, "Undefined boolean format"); } break; } return *this; } void Stream::setWhiteMode(const WhitespaceMode value) { spaceMode = value; charsBeforeWord = (value == SkipWhite ? &SpaceChars : &NoneChars); } } #if CHECK_MSC_VERSION(14, 0) # pragma warning(pop) #endif
Дальневосточный федеральный университет