Commit b557ab47 authored by Ocean Wang's avatar Ocean Wang
Browse files

[trac1112] Move <character-string> related functions to character_string.h/cc files

           Move some duplicated code of toWire() to toWireHelper() function
parent 4e125743
......@@ -94,6 +94,7 @@ libdns___la_SOURCES += tsig.h tsig.cc
libdns___la_SOURCES += tsigerror.h tsigerror.cc
libdns___la_SOURCES += tsigkey.h tsigkey.cc
libdns___la_SOURCES += tsigrecord.h tsigrecord.cc
libdns___la_SOURCES += character_string.h character_string.cc
libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h
libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.cc
......
// Copyright (C) 2011 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 "character_string.h"
#include "rdata.h"
using namespace std;
using namespace isc::dns::rdata;
namespace isc {
namespace dns {
std::string
characterstr::getNextCharacterString(const std::string& input_str,
std::string::const_iterator& input_iterator)
{
string result;
// If the input string only contains white-spaces, it is an invalid
// <character-string>
if (input_iterator >= input_str.end()) {
isc_throw(InvalidRdataText, "Invalid text format, \
<character-string> field is missing.");
}
// Whether the <character-string> is separated with double quotes (")
bool quotes_separated = (*input_iterator == '"');
if (quotes_separated) {
++input_iterator;
}
while(input_iterator < input_str.end()){
if (quotes_separated) {
// If the <character-string> is seperated with quotes symbol and
// another quotes symbol is encountered, it is the end of the
// <character-string>
if (*input_iterator == '"') {
// Inside a " delimited string any character can occur, except
// for a " itself, which must be quoted using \ (back slash).
if (*(input_iterator - 1) == '\\') {
// pop the '\' character
result.resize(result.size() - 1);
} else {
++input_iterator;
// Reach the end of character string
break;
}
}
} else if (*input_iterator == ' ') {
// If the <character-string> is not seperated with quotes symbol,
// it is seperated with <space> char
break;
}
result.push_back(*input_iterator);
++input_iterator;
}
if (result.size() > MAX_CHARSTRING_LEN) {
isc_throw(CharStringTooLong, "<character-string> is too long");
}
return (result);
}
std::string
characterstr::getNextCharacterString(util::InputBuffer& buffer, size_t len) {
uint8_t str_len = buffer.readUint8();
size_t pos = buffer.getPosition();
if (len - pos < str_len) {
isc_throw(InvalidRdataLength, "Invalid string length");
}
uint8_t buf[MAX_CHARSTRING_LEN];
buffer.readData(buf, str_len);
return (string(buf, buf + str_len));
}
} // end of namespace dns
} // end of namespace isc
// Copyright (C) 2011 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 __CHARACTER_STRING_H
#define __CHARACTER_STRING_H
#include <string>
#include <exceptions/exceptions.h>
#include <util/buffer.h>
namespace isc {
namespace dns {
namespace characterstr {
/// Get a <character-string> from a string
///
/// \param input_str The input string
/// \param input_iterator The iterator from which to start extracting,
/// the iterator will be updated to new position after the function
/// is returned
/// \return A std::string that contains the extracted <character-string>
std::string getNextCharacterString(const std::string& input_str,
std::string::const_iterator& input_iterator);
/// Get a <character-string> from a input buffer
///
/// \param buffer The input buffer
/// \param len The input buffer total length
/// \return A std::string that contains the extracted <character-string>
std::string getNextCharacterString(util::InputBuffer& buffer, size_t len);
} // namespace characterstr
} // namespace dns
} // namespace isc
#endif // __CHARACTER_STRING_H
......@@ -24,10 +24,14 @@
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/character_string.h>
#include <util/strutil.h>
using namespace std;
using namespace boost;
using namespace isc::util;
using namespace isc::dns;
using namespace isc::dns::characterstr;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
......@@ -65,20 +69,12 @@ HINFO::toText() const {
void
HINFO::toWire(OutputBuffer& buffer) const {
buffer.writeUint8(cpu_.size());
buffer.writeData(cpu_.c_str(), cpu_.size());
buffer.writeUint8(os_.size());
buffer.writeData(os_.c_str(), os_.size());
toWireHelper(buffer);
}
void
HINFO::toWire(AbstractMessageRenderer& renderer) const {
renderer.writeUint8(cpu_.size());
renderer.writeData(cpu_.c_str(), cpu_.size());
renderer.writeUint8(os_.size());
renderer.writeData(os_.c_str(), os_.size());
toWireHelper(renderer);
}
int
......@@ -129,66 +125,5 @@ HINFO::skipLeftSpaces(const std::string& input_str,
}
}
std::string
HINFO::getNextCharacterString(const std::string& input_str,
std::string::const_iterator& input_iterator)
{
string result;
// If the input string only contains white-spaces, it is an invalid
// <character-string>
if (input_iterator >= input_str.end()) {
isc_throw(InvalidRdataText, "Invalid HINFO text format, \
<character-string> field is missing.");
}
// Whether the <character-string> is separated with double quotes (")
bool quotes_separated = (*input_iterator == '"');
if (quotes_separated) {
++input_iterator;
}
while(input_iterator < input_str.end()){
if (quotes_separated) {
// If the <character-string> is seperated with quotes symbol and
// another quotes symbol is encountered, it is the end of the
// <character-string>
if (*input_iterator == '"') {
++input_iterator;
break;
}
} else if (*input_iterator == ' ') {
// If the <character-string> is not seperated with quotes symbol,
// it is seperated with <space> char
break;
}
result.push_back(*input_iterator);
++input_iterator;
}
if (result.size() > MAX_CHARSTRING_LEN) {
isc_throw(CharStringTooLong, "HINFO <character-string> is too long");
}
return (result);
}
std::string
HINFO::getNextCharacterString(InputBuffer& buffer, size_t len) {
uint8_t str_len = buffer.readUint8();
size_t pos = buffer.getPosition();
if (len - pos < str_len) {
isc_throw(InvalidRdataLength, "Invalid HINFO string length");
}
uint8_t buf[MAX_CHARSTRING_LEN];
buffer.readData(buf, str_len);
return (string(buf, buf + str_len));
}
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
......@@ -51,22 +51,17 @@ private:
void skipLeftSpaces(const std::string& input_str,
std::string::const_iterator& input_iterator);
/// Get a <character-string> from a string
/// Helper template function for toWire()
///
/// \param input_str The input string
/// \param input_iterator The iterator from which to start extracting,
/// the iterator will be updated to new position after the function
/// is returned
/// \return A std::string that contains the extracted <character-string>
std::string getNextCharacterString(const std::string& input_str,
std::string::const_iterator& input_iterator);
/// \param outputer Where to write data in
template <typename T>
void toWireHelper(T& outputer) const {
outputer.writeUint8(cpu_.size());
outputer.writeData(cpu_.c_str(), cpu_.size());
/// Get a <character-string> from a input buffer
///
/// \param buffer The input buffer
/// \param len The input buffer total length
/// \return A std::string that contains the extracted <character-string>
std::string getNextCharacterString(util::InputBuffer& buffer, size_t len);
outputer.writeUint8(os_.size());
outputer.writeData(os_.c_str(), os_.size());
}
std::string cpu_;
std::string os_;
......
......@@ -20,6 +20,7 @@
#include <exceptions/exceptions.h>
#include <dns/character_string.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
......@@ -28,6 +29,8 @@
using namespace std;
using namespace boost;
using namespace isc::util;
using namespace isc::dns;
using namespace isc::dns::characterstr;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
......@@ -56,79 +59,6 @@ skipLeftSpaces(const std::string& input_str,
}
}
/// Get a <character-string> from a string
///
/// \param input_str The input string
/// \param input_iterator The iterator from which to start extracting,
/// the iterator will be updated to new position after the function
/// is returned
/// \return A std::string that contains the extracted <character-string>
std::string
getNextCharacterString(const std::string& input_str,
std::string::const_iterator& input_iterator)
{
string result;
// If the input string only contains white-spaces, it is an invalid
// <character-string>
if (input_iterator >= input_str.end()) {
isc_throw(InvalidRdataText, "Invalid NAPTR text format, \
<character-string> field is missing.");
}
// Whether the <character-string> is separated with double quotes (")
bool quotes_separated = (*input_iterator == '"');
if (quotes_separated) {
++input_iterator;
}
while(input_iterator < input_str.end()){
if (quotes_separated) {
// If the <character-string> is seperated with quotes symbol and
// another quotes symbol is encountered, it is the end of the
// <character-string>
if (*input_iterator == '"') {
++input_iterator;
break;
}
} else if (*input_iterator == ' ') {
// If the <character-string> is not seperated with quotes symbol,
// it is seperated with <space> char
break;
}
result.push_back(*input_iterator);
++input_iterator;
}
if (result.size() > MAX_CHARSTRING_LEN) {
isc_throw(CharStringTooLong, "NAPTR <character-string> is too long");
}
return (result);
}
/// Get a <character-string> from a input buffer
///
/// \param buffer The input buffer
/// \param len The input buffer total length
/// \return A std::string that contains the extracted <character-string>
std::string
getNextCharacterString(InputBuffer& buffer, size_t len) {
uint8_t str_len = buffer.readUint8();
size_t pos = buffer.getPosition();
if (len - pos < str_len) {
isc_throw(InvalidRdataLength, "Invalid NAPTR string length");
}
uint8_t buf[MAX_CHARSTRING_LEN];
buffer.readData(buf, str_len);
return (string(buf, buf + str_len));
}
} // Anonymous namespace
NAPTR::NAPTR(InputBuffer& buffer, size_t len):
......@@ -194,36 +124,12 @@ NAPTR::NAPTR(const NAPTR& naptr):
void
NAPTR::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(order_);
buffer.writeUint16(preference_);
buffer.writeUint8(flags_.size());
buffer.writeData(flags_.c_str(), flags_.size());
buffer.writeUint8(services_.size());
buffer.writeData(services_.c_str(), services_.size());
buffer.writeUint8(regexp_.size());
buffer.writeData(regexp_.c_str(), regexp_.size());
replacement_.toWire(buffer);
toWireHelper(buffer);
}
void
NAPTR::toWire(AbstractMessageRenderer& renderer) const {
renderer.writeUint16(order_);
renderer.writeUint16(preference_);
renderer.writeUint8(flags_.size());
renderer.writeData(flags_.c_str(), flags_.size());
renderer.writeUint8(services_.size());
renderer.writeData(services_.c_str(), services_.size());
renderer.writeUint8(regexp_.size());
renderer.writeData(regexp_.c_str(), regexp_.size());
replacement_.toWire(renderer);
toWireHelper(renderer);
}
string
......
......@@ -46,6 +46,26 @@ public:
const std::string& getRegexp() const;
const Name& getReplacement() const;
private:
/// Helper template function for toWire()
///
/// \param outputer Where to write data in
template <typename T>
void toWireHelper(T& outputer) const {
outputer.writeUint16(order_);
outputer.writeUint16(preference_);
outputer.writeUint8(flags_.size());
outputer.writeData(flags_.c_str(), flags_.size());
outputer.writeUint8(services_.size());
outputer.writeData(services_.c_str(), services_.size());
outputer.writeUint8(regexp_.size());
outputer.writeData(regexp_.c_str(), regexp_.size());
replacement_.toWire(outputer);
}
uint16_t order_;
uint16_t preference_;
std::string flags_;
......
......@@ -39,6 +39,7 @@ class Rdata_HINFO_Test : public RdataTest {
static uint8_t hinfo_rdata[] = {0x07,0x50,0x65,0x6e,0x74,0x69,0x75,0x6d,0x05,
0x4c,0x69,0x6e,0x75,0x78};
static const char *hinfo_str = "\"Pentium\" \"Linux\"";
static const char *hinfo_str1 = "\"Pen\\\"tium\" \"Linux\"";
static const char *hinfo_str_small1 = "\"Lentium\" \"Linux\"";
static const char *hinfo_str_small2 = "\"Pentium\" \"Kinux\"";
......@@ -49,6 +50,10 @@ TEST_F(Rdata_HINFO_Test, createFromText) {
HINFO hinfo(hinfo_str);
EXPECT_EQ(string("Pentium"), hinfo.getCPU());
EXPECT_EQ(string("Linux"), hinfo.getOS());
// Test the text with double quotes in the middle of string
HINFO hinfo1(hinfo_str1);
EXPECT_EQ(string("Pen\"tium"), hinfo1.getCPU());
}
TEST_F(Rdata_HINFO_Test, badText) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment