hinfo_13.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <exceptions/exceptions.h>
  16. #include <dns/exceptions.h>
  17. #include <dns/rdata.h>
  18. #include <dns/rdataclass.h>
  19. #include <dns/rdata/generic/detail/char_string.h>
  20. #include <util/buffer.h>
  21. using namespace std;
  22. using namespace isc::util;
  23. using namespace isc::dns;
  24. // BEGIN_ISC_NAMESPACE
  25. // BEGIN_RDATA_NAMESPACE
  26. class HINFOImpl {
  27. public:
  28. HINFOImpl(const std::string& hinfo_str) {
  29. std::istringstream ss(hinfo_str);
  30. MasterLexer lexer;
  31. lexer.pushSource(ss);
  32. try {
  33. parseHINFOData(lexer);
  34. // Should be at end of data now
  35. if (lexer.getNextToken(MasterToken::QSTRING, true).getType() !=
  36. MasterToken::END_OF_FILE) {
  37. isc_throw(InvalidRdataText,
  38. "Invalid HINFO text format: too many fields.");
  39. }
  40. } catch (const MasterLexer::LexerError& ex) {
  41. isc_throw(InvalidRdataText, "Failed to construct HINFO RDATA from "
  42. << hinfo_str << "': " << ex.what());
  43. }
  44. }
  45. HINFOImpl(InputBuffer& buffer, size_t rdata_len) {
  46. rdata_len -= detail::bufferToCharString(buffer, rdata_len, cpu);
  47. rdata_len -= detail::bufferToCharString(buffer, rdata_len, os);
  48. if (rdata_len != 0) {
  49. isc_throw(isc::dns::DNSMessageFORMERR, "Error in parsing " <<
  50. "HINFO RDATA: bytes left at end: " <<
  51. static_cast<int>(rdata_len));
  52. }
  53. }
  54. HINFOImpl(MasterLexer& lexer)
  55. {
  56. parseHINFOData(lexer);
  57. }
  58. private:
  59. void
  60. parseHINFOData(MasterLexer& lexer) {
  61. MasterToken token = lexer.getNextToken(MasterToken::QSTRING);
  62. stringToCharString(token.getStringRegion(), cpu);
  63. token = lexer.getNextToken(MasterToken::QSTRING);
  64. stringToCharString(token.getStringRegion(), os);
  65. }
  66. public:
  67. detail::CharString cpu;
  68. detail::CharString os;
  69. };
  70. HINFO::HINFO(const std::string& hinfo_str) : impl_(new HINFOImpl(hinfo_str))
  71. {}
  72. HINFO::HINFO(InputBuffer& buffer, size_t rdata_len) :
  73. impl_(new HINFOImpl(buffer, rdata_len))
  74. {}
  75. HINFO::HINFO(const HINFO& source):
  76. Rdata(), impl_(new HINFOImpl(*source.impl_))
  77. {
  78. }
  79. HINFO::HINFO(MasterLexer& lexer, const Name*,
  80. MasterLoader::Options, MasterLoaderCallbacks&) :
  81. impl_(new HINFOImpl(lexer))
  82. {}
  83. HINFO&
  84. HINFO::operator=(const HINFO& source)
  85. {
  86. impl_.reset(new HINFOImpl(*source.impl_));
  87. return (*this);
  88. }
  89. HINFO::~HINFO() {
  90. }
  91. std::string
  92. HINFO::toText() const {
  93. string result;
  94. result += "\"";
  95. result += detail::charStringToString(impl_->cpu);
  96. result += "\" \"";
  97. result += detail::charStringToString(impl_->os);
  98. result += "\"";
  99. return (result);
  100. }
  101. void
  102. HINFO::toWire(OutputBuffer& buffer) const {
  103. toWireHelper(buffer);
  104. }
  105. void
  106. HINFO::toWire(AbstractMessageRenderer& renderer) const {
  107. toWireHelper(renderer);
  108. }
  109. int
  110. HINFO::compare(const Rdata& other) const {
  111. const HINFO& other_hinfo = dynamic_cast<const HINFO&>(other);
  112. const int cmp = compareCharStrings(impl_->cpu, other_hinfo.impl_->cpu);
  113. if (cmp != 0) {
  114. return (cmp);
  115. }
  116. return (compareCharStrings(impl_->os, other_hinfo.impl_->os));
  117. }
  118. const std::string
  119. HINFO::getCPU() const {
  120. return (detail::charStringToString(impl_->cpu));
  121. }
  122. const std::string
  123. HINFO::getOS() const {
  124. return (detail::charStringToString(impl_->os));
  125. }
  126. template <typename T>
  127. void
  128. HINFO::toWireHelper(T& outputer) const {
  129. outputer.writeData(&impl_->cpu[0], impl_->cpu.size());
  130. outputer.writeData(&impl_->os[0], impl_->os.size());
  131. }
  132. // END_RDATA_NAMESPACE
  133. // END_ISC_NAMESPACE