mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-02 15:05:16 +00:00
[2369] Add InputSource helper class (work-in-progress)
This commit is contained in:
@@ -93,6 +93,7 @@ libb10_dns___la_LDFLAGS = -no-undefined -version-info 2:0:0
|
||||
libb10_dns___la_SOURCES =
|
||||
libb10_dns___la_SOURCES += edns.h edns.cc
|
||||
libb10_dns___la_SOURCES += exceptions.h exceptions.cc
|
||||
libb10_dns___la_SOURCES += inputsource.h inputsource.cc
|
||||
libb10_dns___la_SOURCES += labelsequence.h labelsequence.cc
|
||||
libb10_dns___la_SOURCES += masterload.h masterload.cc
|
||||
libb10_dns___la_SOURCES += message.h message.cc
|
||||
|
74
src/lib/dns/inputsource.cc
Normal file
74
src/lib/dns/inputsource.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <dns/inputsource.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
|
||||
namespace isc {
|
||||
namespace dns {
|
||||
namespace master_lexer_internal {
|
||||
|
||||
int
|
||||
InputSource::getChar() {
|
||||
if (buffer_pos_ == buffer_.size()) {
|
||||
// We may have reached EOF at the last call to
|
||||
// getChar(). at_eof_ will be set then. We then simply return
|
||||
// early.
|
||||
if (at_eof_) {
|
||||
return -1;
|
||||
}
|
||||
// We are not yet at EOF. Read from the stream.
|
||||
int c = input_.get();
|
||||
// Have we reached EOF now? If so, set at_eof_ and return early,
|
||||
// but don't modify buffer_pos_ (which should still be equal to
|
||||
// the size of buffer_).
|
||||
if (!input_.good()) {
|
||||
at_eof_ = true;
|
||||
return -1;
|
||||
}
|
||||
buffer_.push_back(c);
|
||||
}
|
||||
|
||||
int c = buffer_[buffer_pos_++];
|
||||
if (c == '\n') {
|
||||
line_++;
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
void
|
||||
InputSource::ungetChar() {
|
||||
if (at_eof_) {
|
||||
at_eof_ = false;
|
||||
} else if (buffer_pos_ == 0) {
|
||||
isc_throw(OutOfRange, "Cannot skip before the start of buffer");
|
||||
} else {
|
||||
if (buffer_[buffer_pos_] == '\n') {
|
||||
line_--;
|
||||
}
|
||||
buffer_pos_--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InputSource::ungetAll() {
|
||||
buffer_pos_ = 0;
|
||||
line_ = saved_line_;
|
||||
at_eof_ = false;
|
||||
}
|
||||
|
||||
} // namespace master_lexer_internal
|
||||
} // namespace dns
|
||||
} // namespace isc
|
76
src/lib/dns/inputsource.h
Normal file
76
src/lib/dns/inputsource.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#ifndef DNS_INPUTSOURCE_H
|
||||
#define DNS_INPUTSOURCE_H 1
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace isc {
|
||||
namespace dns {
|
||||
namespace master_lexer_internal {
|
||||
|
||||
class InputSource {
|
||||
public:
|
||||
InputSource(std::istream& input, const std::string& name) :
|
||||
input_(input),
|
||||
name_(name),
|
||||
at_eof_(false),
|
||||
line_(1),
|
||||
saved_line_(line_),
|
||||
buffer_pos_(buffer_.size())
|
||||
{}
|
||||
|
||||
const std::string& getName() {
|
||||
return (name_);
|
||||
}
|
||||
|
||||
bool atEOF() const {
|
||||
return (at_eof_);
|
||||
}
|
||||
|
||||
size_t getCurrentLine() const {
|
||||
return (line_);
|
||||
}
|
||||
|
||||
void saveLine() {
|
||||
saved_line_ = line_;
|
||||
}
|
||||
|
||||
int getChar();
|
||||
void ungetChar();
|
||||
void ungetAll();
|
||||
|
||||
private:
|
||||
std::istream& input_;
|
||||
const std::string name_;
|
||||
bool at_eof_;
|
||||
size_t line_;
|
||||
size_t saved_line_;
|
||||
|
||||
std::vector<char> buffer_;
|
||||
size_t buffer_pos_;
|
||||
};
|
||||
|
||||
} // namespace master_lexer_internal
|
||||
} // namespace dns
|
||||
} // namespace isc
|
||||
|
||||
#endif // DNS_INPUTSOURCE_H
|
||||
|
||||
// Local Variables:
|
||||
// mode: c++
|
||||
// End:
|
@@ -22,6 +22,7 @@ if HAVE_GTEST
|
||||
TESTS += run_unittests
|
||||
run_unittests_SOURCES = unittest_util.h unittest_util.cc
|
||||
run_unittests_SOURCES += edns_unittest.cc
|
||||
run_unittests_SOURCES += inputsource_unittest.cc
|
||||
run_unittests_SOURCES += labelsequence_unittest.cc
|
||||
run_unittests_SOURCES += messagerenderer_unittest.cc
|
||||
run_unittests_SOURCES += name_unittest.cc
|
||||
|
147
src/lib/dns/tests/inputsource_unittest.cc
Normal file
147
src/lib/dns/tests/inputsource_unittest.cc
Normal file
@@ -0,0 +1,147 @@
|
||||
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <dns/inputsource.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace isc::dns;
|
||||
using namespace isc::dns::master_lexer_internal;
|
||||
|
||||
namespace {
|
||||
|
||||
class InputSourceTest : public ::testing::Test {
|
||||
protected:
|
||||
InputSourceTest() :
|
||||
name_("a90wjer"),
|
||||
str_("Line1 to scan.\nLine2 to scan.\nLine3 to scan.\n"),
|
||||
str_length_(strlen(str_)),
|
||||
iss_(str_),
|
||||
source_(iss_, name_)
|
||||
{}
|
||||
|
||||
string name_;
|
||||
const char* str_;
|
||||
size_t str_length_;
|
||||
stringstream iss_;
|
||||
InputSource source_;
|
||||
};
|
||||
|
||||
// Test the default return values set during InputSource construction.
|
||||
TEST_F(InputSourceTest, defaults) {
|
||||
EXPECT_EQ(name_, source_.getName());
|
||||
EXPECT_EQ(1, source_.getCurrentLine());
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
}
|
||||
|
||||
// getChar() should return characters from the input stream in
|
||||
// sequence. ungetChar() should skip backwards.
|
||||
TEST_F(InputSourceTest, getAndUngetChar) {
|
||||
for (size_t i = 0; i < str_length_; i++) {
|
||||
EXPECT_EQ(str_[i], source_.getChar());
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
}
|
||||
|
||||
// At this point, we still have not reached EOF.
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
|
||||
// This should cause EOF to be set.
|
||||
EXPECT_EQ(-1, source_.getChar());
|
||||
|
||||
// Now, EOF should be set.
|
||||
EXPECT_TRUE(source_.atEOF());
|
||||
|
||||
// Now, let's go backwards. This should cause the EOF to be set to
|
||||
// false.
|
||||
source_.ungetChar();
|
||||
|
||||
// Now, EOF should be false.
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
|
||||
// This should cause EOF to be set again.
|
||||
EXPECT_EQ(-1, source_.getChar());
|
||||
|
||||
// Now, EOF should be set.
|
||||
EXPECT_TRUE(source_.atEOF());
|
||||
|
||||
// Now, let's go backwards in a loop. Start by skipping the EOF.
|
||||
source_.ungetChar();
|
||||
|
||||
for (size_t i = 0; i < str_length_; i++) {
|
||||
size_t index = str_length_ - 1 - i;
|
||||
// Skip one character.
|
||||
source_.ungetChar();
|
||||
EXPECT_EQ(str_[index], source_.getChar());
|
||||
// Skip the character we received again.
|
||||
source_.ungetChar();
|
||||
}
|
||||
|
||||
// Skipping past the start of buffer should throw.
|
||||
EXPECT_THROW(source_.ungetChar(), isc::OutOfRange);
|
||||
}
|
||||
|
||||
// ungetAll() should skip back to the place where the InputSource
|
||||
// started at construction.
|
||||
TEST_F(InputSourceTest, ungetAll) {
|
||||
while (!source_.atEOF()) {
|
||||
source_.getChar();
|
||||
}
|
||||
|
||||
// Now, we are at EOF.
|
||||
EXPECT_TRUE(source_.atEOF());
|
||||
EXPECT_EQ(4, source_.getCurrentLine());
|
||||
|
||||
source_.ungetAll();
|
||||
|
||||
// Now we are back to where we started.
|
||||
EXPECT_EQ(1, source_.getCurrentLine());
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
}
|
||||
|
||||
|
||||
// Test line counters.
|
||||
TEST_F(InputSourceTest, lines) {
|
||||
size_t line = 1;
|
||||
while (!source_.atEOF()) {
|
||||
if (source_.getChar() == '\n') {
|
||||
line++;
|
||||
}
|
||||
EXPECT_EQ(line, source_.getCurrentLine());
|
||||
}
|
||||
|
||||
// Now, we are at EOF.
|
||||
EXPECT_TRUE(source_.atEOF());
|
||||
EXPECT_EQ(4, source_.getCurrentLine());
|
||||
|
||||
// Go backwards 1 character, skipping the last '\n'.
|
||||
source_.ungetChar();
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
EXPECT_EQ(3, source_.getCurrentLine());
|
||||
|
||||
source_.ungetAll();
|
||||
|
||||
// Now we are back to where we started.
|
||||
EXPECT_EQ(1, source_.getCurrentLine());
|
||||
EXPECT_FALSE(source_.atEOF());
|
||||
}
|
||||
|
||||
} // end namespace
|
Reference in New Issue
Block a user