Browse Source

ported minimal sets of name methods for code sprint.
added some test cases with gtest.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@118 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya 15 years ago
parent
commit
f123f38207

+ 5 - 5
Makefile.in

@@ -34,8 +34,8 @@ POST_UNINSTALL = :
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
-	depcomp install-sh missing
+	$(top_srcdir)/configure AUTHORS COPYING ChangeLog NEWS depcomp \
+	install-sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -110,9 +110,6 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
-CPPUNIT_INCLUDES = @CPPUNIT_INCLUDES@
-CPPUNIT_LDADD = @CPPUNIT_LDADD@
-CPPUNIT_LDFLAGS = @CPPUNIT_LDFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
@@ -125,6 +122,9 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GREP = @GREP@
+GTEST_INCLUDES = @GTEST_INCLUDES@
+GTEST_LDADD = @GTEST_LDADD@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@

+ 26 - 26
configure

@@ -595,11 +595,11 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
-CPPUNIT_LDADD
-CPPUNIT_LDFLAGS
-CPPUNIT_INCLUDES
-HAVE_CPPUNIT_FALSE
-HAVE_CPPUNIT_TRUE
+GTEST_LDADD
+GTEST_LDFLAGS
+GTEST_INCLUDES
+HAVE_GTEST_FALSE
+HAVE_GTEST_TRUE
 EGREP
 GREP
 CPP
@@ -691,7 +691,7 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 enable_dependency_tracking
-with_cppunit
+with_gtest
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1326,7 +1326,7 @@ Optional Features:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --with-cppunit=PATH     specify a path to CppUnit header files (PATH/include) and library (PATH/lib)
+  --with-gtest=PATH       specify a path to Gtest header files (PATH/include) and library (PATH/lib)
 
 Some influential environment variables:
   CXX         C++ compiler command
@@ -4476,32 +4476,32 @@ fi
 
 
 #
-# Check availablity of CppUnit, which will be used for unit tests.
+# Check availablity of gtest, which might be used for unit tests.
 #
 
-# Check whether --with-cppunit was given.
-if test "${with_cppunit+set}" = set; then :
-  withval=$with_cppunit; cppunit_path="$withval"
+# Check whether --with-gtest was given.
+if test "${with_gtest+set}" = set; then :
+  withval=$with_gtest; gtest_path="$withval"
 else
-  cppunit_path="no"
+  gtest_path="no"
 fi
 
-if test "$cppunit_path" != "no"
+if test "$gtest_path" != "no"
 then
-	CPPUNIT_INCLUDES="-I${cppunit_path}/include"
-	CPPUNIT_LDFLAGS="-L${cppunit_path}/lib"
-	CPPUNIT_LDADD="-lcppunit"
+	GTEST_INCLUDES="-I${gtest_path}/include"
+	GTEST_LDFLAGS="-L${gtest_path}/lib"
+	GTEST_LDADD="-lgtest"
 else
-	CPPUNIT_INCLUDES=
-	CPPUNIT_LDFLAGS=
-	CPPUNIT_LDADD=
+	GTEST_INCLUDES=
+	GTEST_LDFLAGS=
+	GTEST_LDADD=
 fi
- if test $cppunit_path != "no"; then
-  HAVE_CPPUNIT_TRUE=
-  HAVE_CPPUNIT_FALSE='#'
+ if test $gtest_path != "no"; then
+  HAVE_GTEST_TRUE=
+  HAVE_GTEST_FALSE='#'
 else
-  HAVE_CPPUNIT_TRUE='#'
-  HAVE_CPPUNIT_FALSE=
+  HAVE_GTEST_TRUE='#'
+  HAVE_GTEST_FALSE=
 fi
 
 
@@ -4629,8 +4629,8 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   as_fn_error "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${HAVE_CPPUNIT_TRUE}" && test -z "${HAVE_CPPUNIT_FALSE}"; then
-  as_fn_error "conditional \"HAVE_CPPUNIT\" was never defined.
+if test -z "${HAVE_GTEST_TRUE}" && test -z "${HAVE_GTEST_FALSE}"; then
+  as_fn_error "conditional \"HAVE_GTEST\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 

+ 15 - 15
configure.ac

@@ -21,25 +21,25 @@ AC_HEADER_STDBOOL
 AC_TYPE_SIZE_T
 
 #
-# Check availablity of CppUnit, which will be used for unit tests.
+# Check availablity of gtest, which might be used for unit tests.
 #
-AC_ARG_WITH(cppunit,
-[  --with-cppunit=PATH     specify a path to CppUnit header files (PATH/include) and library (PATH/lib)],
-    cppunit_path="$withval", cppunit_path="no")
-if test "$cppunit_path" != "no"
+AC_ARG_WITH(gtest,
+[  --with-gtest=PATH       specify a path to Gtest header files (PATH/include) and library (PATH/lib)],
+    gtest_path="$withval", gtest_path="no")
+if test "$gtest_path" != "no"
 then
-	CPPUNIT_INCLUDES="-I${cppunit_path}/include"
-	CPPUNIT_LDFLAGS="-L${cppunit_path}/lib"
-	CPPUNIT_LDADD="-lcppunit"
+	GTEST_INCLUDES="-I${gtest_path}/include"
+	GTEST_LDFLAGS="-L${gtest_path}/lib"
+	GTEST_LDADD="-lgtest"
 else
-	CPPUNIT_INCLUDES=
-	CPPUNIT_LDFLAGS=
-	CPPUNIT_LDADD=
+	GTEST_INCLUDES=
+	GTEST_LDFLAGS=
+	GTEST_LDADD=
 fi
-AM_CONDITIONAL(HAVE_CPPUNIT, test $cppunit_path != "no")
-AC_SUBST(CPPUNIT_INCLUDES)
-AC_SUBST(CPPUNIT_LDFLAGS)
-AC_SUBST(CPPUNIT_LDADD)
+AM_CONDITIONAL(HAVE_GTEST, test $gtest_path != "no")
+AC_SUBST(GTEST_INCLUDES)
+AC_SUBST(GTEST_LDFLAGS)
+AC_SUBST(GTEST_LDADD)
 
 # Checks for library functions.
 

+ 3 - 3
src/Makefile.in

@@ -95,9 +95,6 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
-CPPUNIT_INCLUDES = @CPPUNIT_INCLUDES@
-CPPUNIT_LDADD = @CPPUNIT_LDADD@
-CPPUNIT_LDFLAGS = @CPPUNIT_LDFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
@@ -110,6 +107,9 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GREP = @GREP@
+GTEST_INCLUDES = @GTEST_INCLUDES@
+GTEST_LDADD = @GTEST_LDADD@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@

+ 3 - 3
src/lib/Makefile.in

@@ -95,9 +95,6 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
-CPPUNIT_INCLUDES = @CPPUNIT_INCLUDES@
-CPPUNIT_LDADD = @CPPUNIT_LDADD@
-CPPUNIT_LDFLAGS = @CPPUNIT_LDFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
@@ -110,6 +107,9 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GREP = @GREP@
+GTEST_INCLUDES = @GTEST_INCLUDES@
+GTEST_LDADD = @GTEST_LDADD@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@

+ 9 - 11
src/lib/dns/Makefile.am

@@ -1,17 +1,15 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib
 
 lib_LIBRARIES = libdns.a
-libdns_a_SOURCES = name.cc name.h
+libdns_a_SOURCES = name.cc buffer.cc name.h buffer.h
 
-if HAVE_CPPUNIT
-TEST_PROGRAM = run_unittests
-else
-TEST_PROGRAM =
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = name_unittest.cc
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(GTEST_LDFLAGS)
+run_unittests_LDADD = ./libdns.a $(GTEST_LDADD)
 endif
 
-TESTS = $(TEST_PROGRAM)
-noinst_PROGRAMS = $(TEST_PROGRAM)
-run_unittests_SOURCES = name_unittest.cc name_unittest.h run_unittests.cc
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_INCLUDES)
-run_unittests_LDFLAGS = $(CPPUNIT_LDFLAGS)
-run_unittests_LDADD = ./libdns.a $(CPPUNIT_LDADD)
+noinst_PROGRAMS = $(TESTS)

+ 20 - 32
src/lib/dns/Makefile.in

@@ -34,7 +34,8 @@ NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 TESTS = $(am__EXEEXT_1)
-noinst_PROGRAMS = $(am__EXEEXT_1)
+@HAVE_GTEST_TRUE@am__append_1 = run_unittests
+noinst_PROGRAMS = $(am__EXEEXT_2)
 subdir = src/lib/dns
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -72,15 +73,18 @@ AR = ar
 ARFLAGS = cru
 libdns_a_AR = $(AR) $(ARFLAGS)
 libdns_a_LIBADD =
-am_libdns_a_OBJECTS = name.$(OBJEXT)
+am_libdns_a_OBJECTS = name.$(OBJEXT) buffer.$(OBJEXT)
 libdns_a_OBJECTS = $(am_libdns_a_OBJECTS)
-@HAVE_CPPUNIT_TRUE@am__EXEEXT_1 = run_unittests$(EXEEXT)
+@HAVE_GTEST_TRUE@am__EXEEXT_1 = run_unittests$(EXEEXT)
+am__EXEEXT_2 = $(am__EXEEXT_1)
 PROGRAMS = $(noinst_PROGRAMS)
-am_run_unittests_OBJECTS = run_unittests-name_unittest.$(OBJEXT) \
-	run_unittests-run_unittests.$(OBJEXT)
+am__run_unittests_SOURCES_DIST = name_unittest.cc
+@HAVE_GTEST_TRUE@am_run_unittests_OBJECTS =  \
+@HAVE_GTEST_TRUE@	run_unittests-name_unittest.$(OBJEXT)
 run_unittests_OBJECTS = $(am_run_unittests_OBJECTS)
 am__DEPENDENCIES_1 =
-run_unittests_DEPENDENCIES = ./libdns.a $(am__DEPENDENCIES_1)
+@HAVE_GTEST_TRUE@run_unittests_DEPENDENCIES = ./libdns.a \
+@HAVE_GTEST_TRUE@	$(am__DEPENDENCIES_1)
 run_unittests_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
 	$(run_unittests_LDFLAGS) $(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -97,7 +101,7 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SOURCES = $(libdns_a_SOURCES) $(run_unittests_SOURCES)
-DIST_SOURCES = $(libdns_a_SOURCES) $(run_unittests_SOURCES)
+DIST_SOURCES = $(libdns_a_SOURCES) $(am__run_unittests_SOURCES_DIST)
 ETAGS = etags
 CTAGS = ctags
 am__tty_colors = \
@@ -114,9 +118,6 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
-CPPUNIT_INCLUDES = @CPPUNIT_INCLUDES@
-CPPUNIT_LDADD = @CPPUNIT_LDADD@
-CPPUNIT_LDFLAGS = @CPPUNIT_LDFLAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
@@ -129,6 +130,9 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GREP = @GREP@
+GTEST_INCLUDES = @GTEST_INCLUDES@
+GTEST_LDADD = @GTEST_LDADD@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -199,13 +203,11 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib
 lib_LIBRARIES = libdns.a
-libdns_a_SOURCES = name.cc name.h
-@HAVE_CPPUNIT_FALSE@TEST_PROGRAM = 
-@HAVE_CPPUNIT_TRUE@TEST_PROGRAM = run_unittests
-run_unittests_SOURCES = name_unittest.cc name_unittest.h run_unittests.cc
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_INCLUDES)
-run_unittests_LDFLAGS = $(CPPUNIT_LDFLAGS)
-run_unittests_LDADD = ./libdns.a $(CPPUNIT_LDADD)
+libdns_a_SOURCES = name.cc buffer.cc name.h buffer.h
+@HAVE_GTEST_TRUE@run_unittests_SOURCES = name_unittest.cc
+@HAVE_GTEST_TRUE@run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+@HAVE_GTEST_TRUE@run_unittests_LDFLAGS = $(GTEST_LDFLAGS)
+@HAVE_GTEST_TRUE@run_unittests_LDADD = ./libdns.a $(GTEST_LDADD)
 all: all-am
 
 .SUFFIXES:
@@ -289,9 +291,9 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-name_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-run_unittests.Po@am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -321,20 +323,6 @@ run_unittests-name_unittest.obj: name_unittest.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-name_unittest.obj `if test -f 'name_unittest.cc'; then $(CYGPATH_W) 'name_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/name_unittest.cc'; fi`
 
-run_unittests-run_unittests.o: run_unittests.cc
-@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-run_unittests.o -MD -MP -MF $(DEPDIR)/run_unittests-run_unittests.Tpo -c -o run_unittests-run_unittests.o `test -f 'run_unittests.cc' || echo '$(srcdir)/'`run_unittests.cc
-@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/run_unittests-run_unittests.Tpo $(DEPDIR)/run_unittests-run_unittests.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='run_unittests.cc' object='run_unittests-run_unittests.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-run_unittests.o `test -f 'run_unittests.cc' || echo '$(srcdir)/'`run_unittests.cc
-
-run_unittests-run_unittests.obj: run_unittests.cc
-@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-run_unittests.obj -MD -MP -MF $(DEPDIR)/run_unittests-run_unittests.Tpo -c -o run_unittests-run_unittests.obj `if test -f 'run_unittests.cc'; then $(CYGPATH_W) 'run_unittests.cc'; else $(CYGPATH_W) '$(srcdir)/run_unittests.cc'; fi`
-@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/run_unittests-run_unittests.Tpo $(DEPDIR)/run_unittests-run_unittests.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='run_unittests.cc' object='run_unittests-run_unittests.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-run_unittests.obj `if test -f 'run_unittests.cc'; then $(CYGPATH_W) 'run_unittests.cc'; else $(CYGPATH_W) '$(srcdir)/run_unittests.cc'; fi`
-
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \

+ 51 - 0
src/lib/dns/buffer.cc

@@ -0,0 +1,51 @@
+// Copyright (C) 2009  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.
+
+// $Id$
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <dns/buffer.h>
+
+using namespace ISC;
+
+// The interface should be revisited.
+int
+SingleBuffer::send_to(int s, const struct sockaddr& to, socklen_t to_len)
+{
+    int cc;
+
+    cc = sendto(s, &buf_[0], buf_.size(), 0, &to, to_len);
+    return (cc);
+}
+
+int
+SingleBuffer::recv_from(int s, struct sockaddr* from, socklen_t* from_len)
+{
+    int cc;
+
+    if (!buf_.empty())
+        throw ISC::ISCBufferInvalidPosition();
+
+    buf_.resize(buf_.capacity());
+    cc = recvfrom(s, &buf_[0], buf_.size(), 0, from, from_len);
+    if (cc >= 0)
+        buf_.resize(cc);
+    else
+        buf_.resize(0);          // XXX
+
+    return (cc);
+}
+

+ 138 - 0
src/lib/dns/buffer.h

@@ -0,0 +1,138 @@
+// Copyright (C) 2009  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.
+
+// $Id$
+
+#ifndef __BUFFER_HH
+#define __BUFFER_HH 1
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <stdint.h>
+#include <string.h>
+
+#include <stdexcept>
+#include <algorithm>
+#include <vector>
+
+#include <dns/exceptions.h>
+
+namespace ISC {
+// Abstraction of buffers for socket I/O.  This is a tentative idea and should
+// be revisited.
+
+class Buffer {
+public:
+    virtual ~Buffer() {}
+    virtual void reserve(size_t len) = 0;
+    virtual void write_data(const void *cp, size_t len) = 0;
+    virtual void write_uint32(uint32_t data) = 0;
+    virtual void write_uint16(uint16_t data) = 0;
+    virtual void write_uint16_at(uint16_t data, size_t pos) = 0;
+    virtual void write_uint8(uint8_t data) = 0;
+    virtual int send_to(int s, const struct sockaddr& to, socklen_t to_len) = 0;
+
+    virtual size_t get_size() const = 0;
+    virtual size_t get_space() const = 0;
+    virtual size_t get_current() const = 0;
+    virtual uint8_t read_uint8() = 0;
+    virtual uint16_t read_uint16() = 0;
+    virtual int recv_from(int s, struct sockaddr *from,
+                          socklen_t *from_len) = 0;
+};
+
+// I/O Buffer with a single array-style storage
+class SingleBuffer : public Buffer {
+public:
+    SingleBuffer() : _readpos(0) { buf_.reserve(4096); }
+
+    void reserve(size_t len) // XXX: API and implementation should be revisited
+    {
+        buf_.resize(len);
+    }
+    void write_data(const void *data, size_t len)
+    {
+        const uint8_t* cp = static_cast<const uint8_t*>(cp);
+        buf_.insert(buf_.end(), cp, cp + len);
+    }
+    void write_uint32(uint32_t data)
+    {
+        data = htonl(data);
+        uint8_t* cp =  static_cast<uint8_t*>((void*)&data);
+        buf_.insert(buf_.end(), cp, cp + sizeof(uint32_t));
+    }
+    void write_uint16(uint16_t data)
+    {
+        data = htons(data);
+        uint8_t* cp =  static_cast<uint8_t*>((void*)&data);
+        buf_.insert(buf_.end(), cp, cp + sizeof(uint16_t));
+    }
+    void write_uint16_at(uint16_t data, size_t pos)
+    {
+        if (pos + sizeof(data) >= buf_.size())
+            throw ISC::ISCBufferInvalidPosition();
+
+        data = htons(data);
+        uint8_t* cp =  static_cast<uint8_t*>((void*)&data);
+        copy(cp, cp + sizeof(uint16_t), buf_.begin() + pos);
+    }
+    void write_uint8(uint8_t data)
+    {
+        buf_.push_back(data);
+    }
+    int send_to(int s, const struct sockaddr& to, socklen_t to_len);
+
+    size_t get_size() const { return (buf_.size()); }
+    size_t get_space() const { return (buf_.size() - _readpos); }
+    size_t get_current() const { return (_readpos); }
+    uint8_t read_uint8();
+    uint16_t read_uint16();
+    int recv_from(int s, struct sockaddr* from, socklen_t* from_len);
+
+private:
+    size_t _readpos;
+    std::vector<uint8_t> buf_;
+};
+
+inline uint8_t
+SingleBuffer::read_uint8()
+{
+    if (_readpos + sizeof(uint8_t) > buf_.size())
+        throw ISCBufferInvalidPosition();
+
+    return (buf_[_readpos++]);
+}
+
+inline uint16_t
+SingleBuffer::read_uint16()
+{
+    uint16_t data;
+
+    if (_readpos + sizeof(data) > buf_.size())
+        throw ISCBufferInvalidPosition();
+
+    memcpy((void*)&data, &buf_[_readpos], sizeof(data));
+    _readpos += sizeof(data);
+
+    return (ntohs(data));
+}
+}
+#endif  // __BUFFER_HH
+
+// Local Variables: 
+// mode: c++
+// End: 

+ 54 - 0
src/lib/dns/exceptions.h

@@ -0,0 +1,54 @@
+// Copyright (C) 2009  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.
+
+// $Id$
+
+#ifndef __EXCEPTIONS_HH
+#define __EXCEPTIONS_HH 1
+
+//
+// Quick hack exception classes for rapid prototyping.  This shouldn't belong
+// here.  Also, exceptions should inherit from standard exception classes.
+
+namespace ISC {
+class ISCException {};
+class ISCUnexpected : public ISCException {};
+class ISCNoSpace : public ISCException {};
+class ISCInvalidAddressString : public ISCException {};
+class ISCBufferInvalidPosition : public ISCException {};
+
+namespace DNS {
+class DNSException {};
+class DNSEmptyLabel : public DNSException {};
+class DNSNameTooLong : public DNSException {};
+class DNSLabelTooLong : public DNSException {};
+class DNSBadEscape : public DNSException {};
+class DNSBadLabelType : public DNSException {};
+class DNSInvalidRRClass : public DNSException {};
+class DNSInvalidRRType : public DNSException {};
+class DNSRdtypeMismatch : public DNSException {};
+class DNSInvalidWireRdata : public DNSException {};
+class DNSNoMessageIOBuffer : public DNSException {};
+class DNSNoNameCompressor : public DNSException {};
+class DNSNoNameDecompressor : public DNSException {};
+class DNSNoMessageParser : public DNSException {};
+class DNSInvalidMessageSection : public DNSException {};
+class DNSInvalidRendererPosition : public DNSException {};
+}
+}
+#endif  // __EXCEPTIONS_HH
+
+// Local Variables: 
+// mode: c++
+// End: 

+ 108 - 17
src/lib/dns/name.cc

@@ -16,23 +16,12 @@
 
 #include <stdexcept>
 
+#include <dns/buffer.h>
 #include <dns/name.h>
 
 using namespace std;
 using namespace ISC::DNS;
 
-// quick hack exception classes: should be moved to an appropriate place soon.
-class ISCException {};
-class ISCUnexpected : public ISCException {};
-class ISCNoSpace : public ISCException {};
-
-class DNSException {};
-class DNSEmptyLabel : public DNSException {};
-class DNSLabelTooLong : public DNSException {};
-class DNSBadEscape : public DNSException {};
-class DNSBadLabelType : public DNSException {};
-
-
 typedef enum {
     ft_init = 0,
     ft_start,
@@ -104,8 +93,8 @@ static unsigned char maptolower[] = {
     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
 };
 
-void
-Name::from_string(const string &namestring)
+Name::Name(const std::string& namestr)
+    : length_(0), labels_(0)
 {
     char c;
     ft_state state;
@@ -129,7 +118,7 @@ Name::from_string(const string &namestring)
     // Set up the state machine.
     //
     pos = 0;
-    tlen = namestring.length();
+    tlen = namestr.length();
     tused = 0;
     nrem = 255;
     nused = 0;
@@ -138,7 +127,7 @@ Name::from_string(const string &namestring)
     state = ft_init;
 
     while (nrem > 0 && tlen > 0 && !done) {
-        c = namestring[pos++];
+        c = namestr[pos++];
         tlen--;
         tused++;
 
@@ -277,6 +266,101 @@ Name::from_string(const string &namestring)
     length_ = nused;
 }
 
+Name::Name(NameDecompressor& decompressor, Buffer& buffer)
+{
+    unsigned int nused, labels, n, nmax;
+    unsigned int current;
+    bool done;
+    fw_state state = fw_start;
+    unsigned int c;
+    bool downcase;
+    bool seen_pointer;
+
+    /*
+     * Initialize things to make the compiler happy; they're not required.
+     */
+    n = 0;
+
+    /*
+     * Set up.
+     */
+    labels = 0;
+    done = false;
+    nused = 0;
+
+    /*
+     * Find the maximum number of uncompressed target name
+     * bytes we are willing to generate.  This is the smaller
+     * of the available target buffer length and the
+     * maximum legal domain name length (255).
+     */
+    nmax = MAXWIRE;
+
+    current = buffer.get_current();
+
+    /*
+     * Note:  The following code is not optimized for speed, but
+     * rather for correctness.  Speed will be addressed in the future.
+     */
+    while (current < buffer.get_size() && !done) {
+        c = buffer.read_uint8();
+        current++;
+
+        switch (state) {
+        case fw_start:
+            if (c < 64) {
+                offsets_.push_back(nused);
+                labels++;
+                if (nused + c + 1 > nmax)
+                full:
+                    // The name did not fit even though we had a buffer
+                    // big enough to fit a maximum-length name.
+                    throw DNSNameTooLong();
+                nused += c + 1;
+                ndata_.push_back(c);
+                if (c == 0)
+                    done = true;
+                n = c;
+                state = fw_ordinary;
+            } else if (c >= 128 && c < 192) {
+                /*
+                 * 14 bit local compression pointer.
+                 * Local compression is no longer an
+                 * IETF draft.
+                 */
+                throw DNSBadLabelType();
+            } else if (c >= 192) {
+                /*
+                 * Ordinary 14-bit pointer.
+                 */
+                throw DNSBadLabelType(); // XXX not implemented
+            } else
+                throw DNSBadLabelType();
+            break;
+        case fw_ordinary:
+            if (downcase)
+                c = maptolower[c];
+            /* FALLTHROUGH */
+        case fw_copy:
+            ndata_.push_back(c);
+            n--;
+            if (n == 0)
+                state = fw_start;
+            break;
+        case fw_newcurrent:
+            // XXX not implemented, fall through
+        default:
+            throw ISCUnexpected();
+        }
+    }
+
+    if (!done)
+        throw ISCUnexpected();
+
+    labels_ = labels;
+    length_ = nused;
+}
+
 string
 Name::to_text(bool omit_final_dot) const
 {
@@ -391,9 +475,16 @@ Name::to_text(bool omit_final_dot) const
     return (tdata);
 }
 
+void
+Name::to_wire(Buffer& buffer, NameCompressor& c) const
+{
+    // TBD: very simple version for prototyping; e.g. it omits compression.
+    buffer.write_data(ndata_.c_str(), ndata_.size());
+}
+
 // Are 'this' name and 'other' equal?
 bool
-Name::operator==(const Name& other) const
+Name::equals(const Name& other) const
 {
     unsigned int l;
     unsigned char c, count;

+ 8 - 7
src/lib/dns/name.h

@@ -20,11 +20,13 @@
 #include <string>
 #include <vector>
 
+#include <dns/name.h>
+
 namespace ISC {
 namespace DNS {
-class Buffer;
-class NameCompressor;
-class NameDecompressor;
+// Define them as an empty class for rapid prototyping
+class NameCompressor {};
+class NameDecompressor {};
 
 class NameComparisonResult {
 public:
@@ -51,8 +53,7 @@ private:
 class Name {
 public:
     Name() : length_(0), labels_(0) {}
-    explicit Name(const std::string& namestr) : length_(0), labels_(0)
-	{ from_string(namestr); }
+    explicit Name(const std::string& namestr);
     explicit Name(NameDecompressor& decompressor, Buffer& buffer);
     // copy constructor (default cp-ctor should work fine)
     //Name(const Name& orig);
@@ -67,8 +68,8 @@ public:
     Name split(unsigned int first, unsigned int n) const;
     Name concatenate(const Name& suffix) const;
     bool is_wildcard() const;
-    bool operator==(const Name& other) const;
-    bool equals(const Name& other) const; // alias of ==
+    bool equals(const Name& other) const;
+    bool operator==(const Name& other) const { return (this->equals(other)); }
     bool operator!=(const Name& other) const { return (!(*this == other)); }
     bool nequals(const Name& other) const; // alias of !=
     bool operator<=(const Name& other) const;

+ 65 - 14
src/lib/dns/name_unittest.cc

@@ -14,29 +14,80 @@
 
 // $Id$
 
-#include <string>
+#include <dns/exceptions.h>
+#include <dns/buffer.h>
+#include <dns/name.h>
 
-#include <cppunit/TestAssert.h>
+#include <gtest/gtest.h>
 
-#include <dns/name.h>
-#include <dns/name_unittest.h>
+namespace {
 
 using ISC::DNS::Name;
+using ISC::DNS::DNSLabelTooLong;
+
+// The fixture for testing class Name.
+class NameTest : public ::testing::Test {
+protected:
+    NameTest()
+    {
+        example_name =
+            new ISC::DNS::Name("www.example.com");
+                             //01234567890123456 => length should be 17.
+    }
+    virtual ~NameTest()
+    {
+        delete example_name;
+    }
+
+    ISC::DNS::Name *example_name;
+};
+
+TEST_F(NameTest, get_length)
+{
+    EXPECT_EQ(17, static_cast<int>(example_name->get_length()));
+}
+
+TEST_F(NameTest, to_text)
+{
+    EXPECT_EQ(std::string("www.example.com"), example_name->to_text(true));
+    EXPECT_EQ(std::string("www.example.com."), example_name->to_text(false));
+}
 
-void
-NameTest::get_length()
+TEST_F(NameTest, invalid_label)
 {
-    Name name("www.example.com");
-            //01234567890123456 => length should be 17.
+    EXPECT_THROW(Name invalidlabel("012345678901234567890123456789"
+                                   "0123456789012345678901234567890123456789"),
+                 DNSLabelTooLong);
+}
 
-    CPPUNIT_ASSERT_EQUAL(17, static_cast<int>(name.get_length()));
+TEST_F(NameTest, equals)
+{
+    EXPECT_EQ(true, example_name->equals(Name("WWW.EXAMPLE.COM")));
+    EXPECT_EQ(true, example_name->equals(Name("www.example.com.")));
+}
+
+TEST_F(NameTest, operator_equals)
+{
+    EXPECT_EQ(true, *example_name == Name("WWW.EXAMPLE.COM"));
+    EXPECT_EQ(true, *example_name == Name("www.example.com."));
 }
 
-void
-NameTest::to_text()
+TEST_F(NameTest, to_from_wire)
 {
-    Name name("www.isc.org");
+    ISC::SingleBuffer buffer;
+    ISC::DNS::NameCompressor compressor;
+    ISC::DNS::NameDecompressor decompressor;
 
-    CPPUNIT_ASSERT_EQUAL(std::string("www.isc.org"), name.to_text(true));
-    CPPUNIT_ASSERT_EQUAL(std::string("www.isc.org."), name.to_text(false));
+    example_name->to_wire(buffer, compressor);
+
+    Name name2(decompressor, buffer);
+    EXPECT_EQ(true, *example_name == name2);
+}
+}
+
+int
+main(int argc, char* argv[])
+{
+    ::testing::InitGoogleTest(&argc, argv);
+    return (RUN_ALL_TESTS());
 }