nrtb-core team mailing list archive
-
nrtb-core team
-
Mailing list archive
-
Message #00177
[Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
Rick Stovall has proposed merging lp:~nrtb-core/nrtb/merge_test into lp:nrtb.
Requested reviews:
DougPiranha (dougpirahna): test - review for alpha merge
For more details, see:
https://code.launchpad.net/~nrtb-core/nrtb/merge_test/+merge/70100
This is a test merge proposal.
--
https://code.launchpad.net/~nrtb-core/nrtb/merge_test/+merge/70100
Your team NRTB Core is subscribed to branch lp:nrtb.
=== modified file 'GPB_proto/ack_nak.proto'
--- GPB_proto/ack_nak.proto 2010-01-14 02:24:25 +0000
+++ GPB_proto/ack_nak.proto 2011-08-02 01:34:24 +0000
@@ -9,6 +9,9 @@
// in a channel wrapper message.
// return on of these to ack the recept of each error free message.
+
+package nrtb_msg;
+
message message_ack {
required uint32 msg_uid = 1;
}
=== modified file 'GPB_proto/physics_common.proto'
--- GPB_proto/physics_common.proto 2010-01-14 02:24:25 +0000
+++ GPB_proto/physics_common.proto 2011-08-02 01:34:24 +0000
@@ -11,6 +11,8 @@
// meters for distance, meters/sec for velocity, radians for attitude,
// and radians/sec for rotational velocity.
+package nrtb_msg;
+
message triplet {
required double x = 1;
required double y = 2;
=== modified file 'GPB_proto/sim_obj_tq_update.proto'
--- GPB_proto/sim_obj_tq_update.proto 2010-01-14 02:24:25 +0000
+++ GPB_proto/sim_obj_tq_update.proto 2011-08-02 01:34:24 +0000
@@ -8,6 +8,8 @@
// Note: these are never sent bare.. they are always payloads
// in a channel wrapper message.
+package nrtb_msg;
+
import "physics_common.proto";
// This message contains all the information required to report the
=== modified file 'GPB_proto/sim_to_db_wrapper.proto'
--- GPB_proto/sim_to_db_wrapper.proto 2010-01-14 02:24:25 +0000
+++ GPB_proto/sim_to_db_wrapper.proto 2011-08-02 01:34:24 +0000
@@ -7,6 +7,8 @@
// Note: The message defined here is a "channel wrapper", a container for
// all messages from the simulation engine to the data broker.
+package nrtb_msg;
+
import "ack_nak.proto";
import "sim_obj_tq_update.proto";
=== added directory 'common/GPB'
=== added file 'common/GPB/Makefile'
--- common/GPB/Makefile 1970-01-01 00:00:00 +0000
+++ common/GPB/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,34 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+proto=../../GPB_proto
+
+lib: lib/nrtb_gpb.a
+ @echo "GPB lib build complete."
+
+lib/nrtb_gpb.a:
+ @protoc -I=${proto} --cpp_out=cpp_src/ ${proto}/*.proto
+ @cd obj; for file in ../cpp_src/*.cc; do g++ -c $$file; done
+ @cp -v cpp_src/*h ../include
+ @ar -r ../lib/nrtb_gpb.a obj/*.o
+
+clean:
+ @cd cpp_src; for file in *h; do rm -vf ../../include/$$file; done
+ @rm -vf ../lib/nrtb_gpb.a
+ @rm -f obj/* cpp_src/*
+ @echo "GPB cleanup complete."
=== added directory 'common/GPB/cpp_src'
=== added directory 'common/GPB/obj'
=== modified file 'common/Makefile'
--- common/Makefile 2010-01-14 02:24:25 +0000
+++ common/Makefile 2011-08-02 01:34:24 +0000
@@ -1,6 +1,27 @@
-lib:
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: ./lib/nrtb_common.a
+
+./lib/nrtb_common.a:
@echo "============= building common libs ==============="
@make action=lib doit
+ @ar -r ./lib/nrtb_common.a ./obj/*.o
@echo "============= common libs complete ==============="
modules:
@@ -11,12 +32,14 @@
clean:
@echo "============= cleaning common libs ==============="
@make action=clean doit
- @rm -fv ./obj/*
+ @rm -fv ./obj/* ./lib/*
@echo "========== common lib cleanup complete ==========="
doit:
+ @cd common_rl; make ${action}
+ @cd serializer; make ${action}
@cd point; make ${action}
@cd timer; make ${action}
- @cd work_queue_thread; make ${action}
- @cd singleton; make ${action}
- @cd plugin_loader; make ${action}
+ @cd logger; make ${action}
+ @cd confreader; make ${action}
+ @cd GPB; make ${action}
=== added directory 'common/common_rl'
=== added file 'common/common_rl/Makefile'
--- common/common_rl/Makefile 1970-01-01 00:00:00 +0000
+++ common/common_rl/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,36 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: common_rl_test
+ @./common_rl_test
+ @cp -v common.h ../include
+ @cp -v common.o ../obj
+ @echo build complete
+
+common.o: common.h common.cpp Makefile
+ @rm -f common.o
+ g++ -c -O3 common.cpp
+
+common_rl_test: common.o common_rl_test.cpp
+ @rm -f common_rl_test
+ g++ -c common_rl_test.cpp
+ g++ -o common_rl_test common_rl_test.o common.o
+
+clean:
+ @rm -rvf *.o ../include/common.h ../obj/common.o common_rl_test
+ @echo all objects and executables have been erased.
=== added file 'common/common_rl/common.cpp'
--- common/common_rl/common.cpp 1970-01-01 00:00:00 +0000
+++ common/common_rl/common.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,274 @@
+/***********************************************
+ T his file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <time.h>
+#include "common.h"
+
+using namespace std;
+
+namespace nrtb
+{
+
+base_exception::base_exception()
+{
+ ctime = time(NULL);
+};
+
+base_exception::base_exception(const string & text)
+{
+ ctime = time(NULL);
+ _text = text;
+};
+
+void base_exception::store(const string & s)
+{
+ _text = s;
+};
+
+string base_exception::comment()
+{
+ return _text;
+};
+
+unsigned long int base_exception::creation_time()
+{
+ return ctime;
+};
+
+const string __ricks_handy_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+const string __ricks_handy_lower = "abcdefghijklmnopqrstuvwxyz";
+
+string changecase(const string &s,const string &upper, const string &lower)
+{
+ try
+ {
+ string returnme = "";
+ for (int i = 0; i < s.size(); i++)
+ {
+ unsigned long int loc = lower.find(s[i]);
+ if (loc == string::npos)
+ {
+ returnme += s[i];
+ }
+ else
+ {
+ returnme += upper[loc];
+ };
+ };
+ return returnme;
+ }
+ catch (...)
+ {
+ throw translate_exception();
+ };
+};
+
+string upcase(const string &s)
+{
+ return changecase(s,__ricks_handy_upper,__ricks_handy_lower);
+};
+
+string downcase(const string &s)
+{
+ return changecase(s,__ricks_handy_lower,__ricks_handy_upper);
+};
+
+
+const string __ricks_handy_hexits = "0123456789ABCDEF";
+
+string gsub(const string & target, const string & findme, const string & putme)
+{
+ // error checking
+ if (findme.empty() || target.empty())
+ {
+ throw gsub_exception();
+ };
+ string returnme = "";
+ unsigned long int okay_through = 0;
+ unsigned long int step = findme.length();
+ unsigned long int where = target.find(findme,okay_through);
+ while (where != string::npos)
+ {
+ returnme += target.substr(okay_through,where-okay_through) + putme;
+ okay_through = where + step;
+ where = target.find(findme,okay_through);
+ };
+ returnme += target.substr(okay_through);
+ return returnme;
+};
+
+strlist split(const string & source, const char token)
+{
+ strlist returnme;
+ returnme.clear();
+ if (source.size() > 0)
+ {
+ unsigned long int loc;
+ unsigned long int processed = 0;
+ try
+ {
+ loc = source.find(token,processed);
+ while (loc != string::npos)
+ {
+ returnme.push_back(source.substr(processed,loc-processed));
+ processed = loc + 1;
+ loc = source.find(token,processed);
+ }
+ returnme.push_back(source.substr(processed));
+ }
+ catch (...)
+ {
+ throw split_exception();
+ };
+ };
+ return returnme;
+};
+
+string trim(std::string s)
+{
+ const string ws = "\t\n ";
+ unsigned long int where = s.find_first_not_of(ws);
+ if (where != string::npos)
+ {
+ s.erase(0,where);
+ };
+ where = s.find_last_not_of(ws);
+ if (where != string::npos)
+ {
+ s.erase(where+1);
+ };
+ return s;
+};
+
+string mconvert(const string &s)
+{
+ /* This function is designed to escape strings destined for
+ * use in SQL queries and the like. Specifically, the following
+ * is done to the string passed in:
+ * 1. "\" is replaced with "\\"
+ * 2. "'" is replaced with "\'"
+ * 3. """ (double quote) is replaced with "\""
+ * 4. 0x00 is replaced with "\"+0x00.
+ */
+ string returnme = "";
+ if (s.length() > 0)
+ {
+ returnme = gsub(s,"\\","\\\\");
+ returnme = gsub(returnme,"'", "\\'");
+ returnme = gsub(returnme,"\"","\\\"");
+ // special handling is required to make strings including
+ // 0x00; this is the kludge I found to work at 2200 tonight.
+ string findme = " "; findme[0] = 0;
+ returnme = gsub(returnme,findme,"\\0");
+ };
+ return returnme;
+};
+
+string dateflip(string date, const string & sep)
+{
+ string out;
+ try
+ {
+ strlist temp = split(date,'-');
+ out = temp[1]+ sep + temp[2] + sep + temp[0];
+ }
+ catch (...)
+ {
+ throw dateflip_exception();
+ };
+ return out;
+}; // string dateflip
+
+string http_hextochar(string s)
+{
+ try
+ {
+ s = upcase(s);
+ unsigned char v = (16 * __ricks_handy_hexits.find(s[0]))
+ + __ricks_handy_hexits.find(s[1]);
+ return s = v;
+ }
+ catch (...)
+ {
+ throw hextrans_exception();
+ };
+}; // string hextochar
+
+string http_chartohex(const string &s)
+{
+ string out;
+ try
+ {
+ for (long int i=0; i < s.length() ; i++ ) {
+ unsigned char v = s[i];
+ div_t hexval = div(v,16);
+ out += __ricks_handy_hexits[hexval.quot];
+ out += __ricks_handy_hexits[hexval.rem];
+ }; /* endfor */
+ }
+ catch (...)
+ {
+ throw hextrans_exception();
+ };
+ return out;
+};// string chartohex()
+
+string http_enhex(const string & s)
+{
+ string out;
+ try
+ {
+ for (long int i=0; i < s.length() ; i++ ) {
+ unsigned char v = s[i];
+ div_t hexval = div(v,16);
+ out += "%";
+ out += __ricks_handy_hexits[hexval.quot];
+ out += __ricks_handy_hexits[hexval.rem];
+ }; /* endfor */
+ }
+ catch (...)
+ {
+ throw hextrans_exception();
+ };
+ return out;
+}; // string enhex()
+
+string http_unhex(string s)
+{
+ try
+ {
+ while (s.find('%') != string::npos)
+ {
+ int where = s.find('%');
+ string hexchar = s.substr(where+1,2);
+ s.erase(where,3);
+ s.insert(where,http_hextochar(hexchar));
+ }; /* endwhile */
+ }
+ catch (...)
+ {
+ throw hextrans_exception();
+ };
+ return s;
+};// string unhex()
+
+
+} // namespace nrtb
=== added file 'common/common_rl/common.h'
--- common/common_rl/common.h 1970-01-01 00:00:00 +0000
+++ common/common_rl/common.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,171 @@
+/***********************************************
+ T his file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+// prevent multiple definitions
+#ifndef __ga_common_h
+#define __ga_common_h 1
+
+//#include <stream.h>
+#include <string>
+#include <map>
+#include <vector>
+
+namespace nrtb
+{
+
+// throwable exception classes
+
+/** Provides a base exception class for use in HCS developed programs.
+ **
+ ** Usage: Inherit your exception classes from this class. When throwing a
+ ** derived exception you'll have the option of either instanciating the
+ ** exception with a comment or not; in any case the time the exception was
+ ** instanciated will be recorded. Later, when catching the exception you can
+ ** get the time the exception was created and any text the thrower may have
+ ** provided.
+ **/
+ class base_exception: public std::exception
+ {
+ protected:
+ unsigned long int ctime;
+ std::string _text;
+ public:
+ /** Default constructor.
+ **
+ ** Creates an nrtb_exception recording it's creation time but without
+ ** a comment string.
+ **/
+ base_exception();
+ /** Constructs with a comment string.
+ **
+ ** Creates an nrtb_exception recording it's creation time and storing the
+ ** provided string "text" for recall later via the comment method.
+ **
+ ** This version takes an ISO standard C++ string.
+ **/
+ base_exception(const std::string & text);
+ /// NOP virtual distructor for safe inheritance
+ virtual ~base_exception() throw() {};
+ /** Stores a comment string.
+ **/
+ void store(const std::string & s);
+ /** Returns the value stored at exception creation.
+ **/
+ std::string comment();
+ /** Returns the unix time the exception was created.
+ **/
+ unsigned long int creation_time();
+};
+
+// Thrown by gsub() in cases of unexpected error.
+class gsub_exception: public nrtb::base_exception {};
+// Thrown by split() in cases of unexpected error.
+class split_exception: public nrtb::base_exception {};
+// Thrown by dateflip in cases of unexpected error.
+class dateflip_exception: public nrtb::base_exception {};
+// Thrown by upcase() and downcase() in cases of unexpected error.
+class translate_exception: public nrtb::base_exception {};
+// Thrown by http_* functions in cases of unexpected error.
+class hextrans_exception: public nrtb::base_exception {};
+// Thrown by the biased_rand* functions in cases of unexpected error.
+class rand_exception: public nrtb::base_exception {};
+
+// handy commonly used maps
+/// A map of ints keyed by ints.
+typedef std::map<int,int> num_map;
+/// A map of ints keyed by strings.
+typedef std::map<std::string,int> string_map;
+
+/// the return type for split.
+typedef std::vector<std::string> strlist;
+
+/** Converts the alpha components of s to all upper case.
+ **
+ ** May throw a nrtb::translate_exception if there is a problem.
+ **/
+std::string upcase(const std::string &s);
+
+/** Converts the alpha components of s to all lower case.
+ **
+ ** May throw a nrtb::translate_exception if there is a problem.
+ **/
+std::string downcase(const std::string &s);
+
+/** Replaces all instances of findme in target with putme.
+ **
+ ** May throw a nrtb::gsub_exception if there is a problem.
+ **/
+std::string gsub(const std::string & target, const std::string & findme,
+ const std::string & putme);
+
+/** Splits the string source using token as a delimiter and returns
+ ** the results in vector of strings.
+ **
+ ** May throw a nrtb::split_exception if there is a problem.
+ **/
+strlist split(const std::string & source, const char token);
+
+/// Performs SQL escaping on the string.
+std::string mconvert(const std::string & s);
+
+/// Removes white space from both ends of a string.
+std::string trim(std::string s);
+
+/** Takes an ISO standard date (YYYY-MM-DD) and returns MM-DD-YYYY.
+ **
+ ** May throw a nrtb::dateflip_exception if there is a problem.
+ **/
+std::string dateflip(std::string date, const std::string & sep="-");
+
+/** Takes a string representing one HTTP hex-encoded byte and returns
+ ** the appropriate character. This will only operate on the first two
+ ** bytes of s, and will throw a nrtb_hextrans_exception if less
+ ** than two bytes are supplied.
+ **
+ ** May throw a nrtb::hextrans_exception if there is a problem.
+ **/
+std::string http_hextochar(std::string s);
+
+/** Takes a string and returns it hex-encoded (i.e. " " returns "20").
+ **
+ ** This function is somewhat misnamed due to hysterical reasons. In
+ ** truth it simply returns the hex equivilent of the input. Use
+ ** http_enhex() when you actually need valid HTTP hex encoding.
+ ** On the other hand, this function is quite
+ ** useful if you need to hex up a series of bytes and don't need the
+ ** overhead of the extra byte per character of true HTTP hex encoding.
+ **
+ ** May throw a nrtb::hextrans_exception if there is a problem.
+*/
+std::string http_chartohex(const std::string &s);
+
+/** Takes a string and returns it in HTTP hex-encoded format (" " returns "%20").
+ **
+ ** May throw a nrtb::hextrans_exception if there is a problem.
+ **/
+std::string http_enhex(const std::string &s);
+
+/** Takes a string and returns it with all HTTP hex-encoded bytes changed to
+ ** their normal single byte representation.
+ **
+ ** May throw a nrtb::hextrans_exception if there is a problem.
+ **/
+std::string http_unhex(std::string s);
+
+} // namespace nrtb
+#endif /* __ga_common_h */
=== added file 'common/common_rl/common_rl_test.cpp'
--- common/common_rl/common_rl_test.cpp 1970-01-01 00:00:00 +0000
+++ common/common_rl/common_rl_test.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,101 @@
+/***********************************************
+ T his file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "common.h"
+#include <iostream>
+
+using namespace std;
+
+int report_test(const string banner, bool test)
+{
+ string result;
+ int returnme = 0;
+ if (test)
+ {
+ result = "PASSED";
+ }
+ else
+ {
+ result = "FAILED";
+ returnme = 1;
+ };
+ cout << "\t" << banner << ": " << result << endl;
+ return returnme;
+};
+
+int main()
+{
+ cout << "=== Starting nrtb::common_rl unit test ===" << endl;
+ int returnme = 0;
+ string tstr = "MiXeDcAsE";
+
+ returnme += report_test(
+ "nrtb::upcase()",
+ nrtb::upcase(tstr) == "MIXEDCASE");
+
+ returnme += report_test(
+ "nrtb::downcase()",
+ nrtb::downcase(tstr) == "mixedcase");
+
+ returnme += report_test(
+ "nrtb::gsub()",
+ nrtb::gsub(tstr, "cAsE", " frogs") == "MiXeD frogs");
+
+ // split() testing
+ nrtb::strlist tokens = nrtb::split("this is a test",' ');
+ bool faults = tokens.size() == 4;
+ faults = faults or (tokens[0] == "this");
+ faults = faults or (tokens[0] == "is");
+ faults = faults or (tokens[0] == "a");
+ faults = faults or (tokens[0] == "test");
+ returnme += report_test(
+ "nrtb::split()",
+ faults);
+
+ string tchar = " "; tchar[0] = 0;
+ returnme += report_test(
+ "nrtb::mconvert()",
+ nrtb::mconvert("\\ \" '"+tchar) == "\\\\ \\\" \\\'\\0");
+
+ returnme += report_test(
+ "nrtb::trim()",
+ nrtb::trim("\t"+tstr+" ") == tstr);
+
+ returnme += report_test(
+ "nrtb::dateflip()",
+ nrtb::dateflip("2011-07-21") == "07-21-2011");
+
+ returnme += report_test(
+ "nrtb::http_hextochar()",
+ nrtb::http_hextochar("20") == " ");
+
+ returnme += report_test(
+ "nrtb::http_chartohex()",
+ nrtb::http_chartohex(tstr) == "4D6958654463417345");
+
+ returnme += report_test(
+ "nrtb::http_enhex()",
+ nrtb::http_enhex(tstr) == "%4D%69%58%65%44%63%41%73%45");
+
+ returnme += report_test(
+ "nrtb::http_unhex()",
+ nrtb::http_unhex("%4D%69%58%65%44%63%41%73%45") == tstr);
+
+ cout << "=== nrtb::common_rl unit test complete ===" << endl;
+ return returnme;
+};
\ No newline at end of file
=== added directory 'common/confreader'
=== added file 'common/confreader/Makefile'
--- common/confreader/Makefile 1970-01-01 00:00:00 +0000
+++ common/confreader/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,44 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: conftest
+ @rm -f conf_test.log
+ @./conftest test=1 test2-2 test2=71.837486 test3="jack danials" --doit
+ @grep "Run Complete" conf_test.log
+ @cp -v confreader.h ../include
+ @cp -v confreader.o ../obj
+ @echo build complete
+
+../include/common.h:
+ @cd ../common_rl; make lib
+
+../include/log_setup.h:
+ @cd ../logger; make lib
+
+confreader.o: confreader.h confreader.cpp Makefile ../include/common.h ../include/log_setup.h
+ @rm -f confreader.o
+ g++ -c confreader.cpp -I ../include
+
+conftest: confreader.o conftest.cpp
+ @rm -f conftest
+ g++ -c conftest.cpp
+ g++ -o conftest conftest.o confreader.o ../obj/common.o ../obj/log_setup.o -lPocoFoundation -lPocoUtil
+
+clean:
+ @rm -rvf *.o conftest ../include/confreader.h ../obj/confreader.o conf_test.log
+ @echo all objects and executables have been erased.
=== added file 'common/confreader/confreader.cpp'
--- common/confreader/confreader.cpp 1970-01-01 00:00:00 +0000
+++ common/confreader/confreader.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,227 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+**********************************************/
+
+// see confreader.h for documentation
+
+#include "confreader.h"
+#include <fstream>
+#include <iostream>
+#include <common.h>
+#include "Poco/Logger.h"
+
+using namespace std;
+using namespace nrtb;
+
+const std::string logname = "conf_reader";
+
+
+namespace nrtb
+{
+
+conf_reader::conf_reader()
+{
+ Poco::Logger& logger = Poco::Logger::get(logname);
+ logger.information("conf_reader instanciated.");
+};
+
+conf_reader::~conf_reader() {};
+
+unsigned int conf_reader::read(const std::string & _filename, bool _clear)
+{
+ Poco::Logger& logger = Poco::Logger::get(logname);
+ logger.information("Reading from \"" + _filename + "\".");
+ if (_filename != "") { filename = _filename; };
+ if (filename != "")
+ {
+ try
+ {
+ ifstream cfile(filename.c_str());
+ if (!cfile) throw base_exception();
+ if (_clear) values.clear();
+ // read the file line by line, ignoring comments.
+ char inbuff[16*1024];
+ while (cfile)
+ {
+ cfile.getline(inbuff, 16*1024);
+ string in = inbuff;
+ // truncate at the start of a comment.
+ unsigned long int where = in.find("#");
+ while (where != string::npos)
+ {
+ if (in[where-1] == '\\')
+ {
+ // comment char was escaped.. ignore.
+ where = in.find("#",where+1);
+ }
+ else
+ {
+ // truncate the string at this point.
+ in.erase(where);
+ where = string::npos;
+ };
+ };
+ // see if we can parse what's left.
+ in = trim(in);
+ unsigned long int split_point = in.find_first_of("\t ");
+ if (split_point != string::npos)
+ {
+ // okay.. get the fields.
+ pair arg;
+ arg.first = gsub(trim(in.substr(0,split_point)),"\\#","#");
+ arg.second = gsub(trim(in.substr(split_point)),"\\#","#");
+ // is this an include directive?
+ if (arg.first == "*INCLUDE")
+ {
+ read(arg.second,false);
+ }
+ else if (arg.first != "")
+ {
+ values.insert(arg);
+ };
+ };
+ };
+ }
+ catch (...)
+ {
+ logger.warning("Problems reading configuration file \""
+ + filename + "\"; data may be incomplete.");
+ }
+ };
+ return values.size();
+};
+
+unsigned int conf_reader::read(int argc, char * argv[],
+ const string & _filename)
+{
+ Poco::Logger& logger = Poco::Logger::get(logname);
+ logger.information("Reading from command line.");
+ clear();
+ filename = _filename;
+ value_list_type cvars;
+ // read values from the command line first.
+ for (int i = 0; i < argc; i++)
+ {
+ string instring = argv[i];
+ if (i == 0)
+ {
+ instring = "__exec_name="+instring;
+ };
+ strlist t = split(instring,'=');
+ if (t.size() > 0)
+ {
+ // build the new insert pair;
+ pair newval;
+ newval.first = t[0];
+ // assemble the value
+ // (allows for including "=" in the argument)
+ for (unsigned int l = 1; l < t.size(); l++)
+ {
+ newval.second += t[l];
+ if (l < (t.size() -1) )
+ {
+ newval.second += "=";
+ };
+ };
+ // store this in the list
+ trim(newval.first);
+ trim(newval.second);
+ cvars.insert(newval);
+ // is this a config file name?
+ if (newval.first == "configfile")
+ {
+ filename = newval.second;
+ };
+ };
+ }; // read the command line arguments.
+ // read the file args if any.
+ read(filename,false);
+ // override the first instance of any value found in configs
+ // or insert as appropriate.
+ iterator c = cvars.begin();
+ iterator e = cvars.end();
+ while (c != e)
+ {
+ iterator here = values.find(c->first);
+ if (here != values.end())
+ {
+ here->second = c->second;
+ }
+ else
+ {
+ values.insert(*c);
+ };
+ c++;
+ };
+ std::stringstream message;
+ message << "Read " << values.size() << " parameters.";
+ logger.information(message.str());
+ return values.size();
+};
+
+void conf_reader::clear()
+{
+ values.clear();
+};
+
+conf_reader::iterator conf_reader::begin()
+{
+ return values.begin();
+};
+
+conf_reader::iterator conf_reader::end()
+{
+ return values.end();
+};
+
+bool conf_reader::empty()
+{
+ return values.empty();
+};
+
+unsigned int conf_reader::size()
+{
+ return values.size();
+};
+
+strlist conf_reader::all(const std::string & key)
+{
+ strlist returnme;
+ iterator current = values.find(key);
+ iterator e = values.end();
+ while ((current != e) && (current->first == key))
+ {
+ returnme.push_back(current->second);
+ current++;
+ };
+ return returnme;
+};
+
+string conf_reader::operator [] (const std::string & key)
+{
+ iterator res = values.find(key);
+ string returnme = "";
+ if (res != values.end()) returnme = res->second;
+ return returnme;
+};
+
+bool conf_reader::exists(const std::string & key)
+{
+ return (values.find(key) != values.end());
+};
+
+} // namespace nrtb
=== added file 'common/confreader/confreader.h'
--- common/confreader/confreader.h 1970-01-01 00:00:00 +0000
+++ common/confreader/confreader.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,293 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef ricklib_confreader_h
+#define ricklib_confreader_h
+
+#include <string.h>
+#include <map>
+#include <vector>
+#include <fstream>
+#include <boost/lexical_cast.hpp>
+#include <string.h>
+#include "Poco/SingletonHolder.h"
+
+namespace nrtb
+{
+
+typedef std::vector<std::string> strlist;
+
+/** Reads command line and configuration file information.
+ **
+ ** For this NRTB implementation, this class is implemented as
+ ** a singleton.
+ **
+ ** Values read are stored in a multimap of name/value pairs and
+ ** may be accessed via provided iterators, or directly via the
+ ** [] operator, all(), get<T>() and getall<T>() methods. Automatic
+ ** handling of include files and comments is provided as well. The
+ ** get<>() and getall<>() template methods provide easy and complete
+ ** access to all types that have the ">>" stream operator
+ ** defined, including all the C++ standard types.
+ **/
+class conf_reader
+{
+ private:
+ typedef std::multimap<std::string,std::string> value_list_type;
+ value_list_type values;
+ std::string filename;
+ protected:
+ /** Reads and parses a configuration file.
+ **
+ ** Returns the number of values stored.
+ **
+ ** The optional parameter _clear when true clears the currently
+ ** stored list of values. if false the new values read will be added
+ ** to the existing list.
+ **
+ ** If the file named can not be processed completely, a warning
+ ** message is published to cerr.
+ **
+ ** Configuration files are defined as follows.
+ **
+ ** 1. Files are read line by line. No value can cross a newline
+ ** (and at least in this version) or include one. The good
+ ** news is that you are allowed up to 16k for each line.
+ **
+ ** 2. values are specifed in name/value pairs, one per line, with
+ ** the name first, followed by whitespace, followed by the
+ ** value. Values may include whitespace. All leading and trailing
+ ** whitespace is removed from both the name and the value.
+ **
+ ** 3. Comments start with a \# symbol; all text following a \# is
+ ** ignored. If you need to use \# in a name or value, escape
+ ** it with a backslash instead.
+ **
+ ** 4. Duplicate names are allowed.
+ **
+ ** 5. Names without values will be stored with "" as the value.
+ **
+ ** 6. A configuration file may include another configuration file
+ ** automatically by the use of the "*INCLUDE" reserved name.
+ ** When this name is found, it's value is used as the name of
+ ** the new file to be read.
+ **/
+ unsigned int read(const std::string & _filename = "", bool _clear=true);
+ public:
+ /// conf_reader iterator, points to a conf_reader::pair
+ typedef value_list_type::iterator iterator;
+ /// conf_reader::pair is a std::pair<string,string>
+ typedef std::pair<std::string,std::string> pair;
+ /** No argument constructor; actually calls read() without a filename.
+ **/
+ conf_reader();
+ /** NOP virtual destructor to allow safe inheritance.
+ **/
+ virtual ~conf_reader();
+ /** Static singletion access point. Unlike common practice, this
+ ** returns a reference to avoid anyone else taking control of a pointer.
+ **/
+ static conf_reader & get_instance()
+ {
+ static Poco::SingletonHolder<conf_reader> sh;
+ return * sh.get();
+ }
+ /** Reads and parses the command line and the provided file.
+ **
+ ** Returns the number of values stored. argc and argv are, of
+ ** course the same names you used as arguments to main(). Therefore
+ ** you can easily read all command line and configuration file
+ ** values like this:
+ **
+ ** int main(int argc, char* argv[])
+ **
+ ** {
+ **
+ ** conf_reader config;
+ **
+ ** config.read(argc,argv,"my_conf_file");
+ **
+ ** ...
+ **
+ ** }
+ **
+ ** See read(filename,_clear) for a discription of how configuration
+ ** files are structured and parsed. This method unconditionally
+ ** clears the existing value list before starting. For command line
+ ** arguments the following rules are true.
+ **
+ ** 1. The executable name (argv[0]) is stored as a value with the
+ ** name "__exec_name".
+ **
+ ** 2. Command line arguments of the form "name=value" are parsed
+ ** stored as named values.
+ **
+ ** 3. All other command line arguments are stored as names with
+ ** value = "".
+ **
+ ** 4. A command line argument of form "configfile=filename" will
+ ** override the filename supplied as an argument to this method.
+ **
+ ** 5. In the case of duplicate command line arguments, the last one
+ ** specified wins.
+ **
+ ** 6. In the case of names in the configuration file duplicating
+ ** names from the command line, the values from the command line
+ ** dominate. If there were multiple values for a given name
+ ** specified in the file, only the first one (the one returned by
+ ** the "[]" operator or get<>() method) is overridden.
+ **/
+ unsigned int read(int argc, char* argv[],
+ const std::string & _filename);
+ /// clears the name/value list.
+ void clear();
+ /// returns an iterator to the first item in the list.
+ iterator begin();
+ /// returns an iterator one past the end of the list.
+ iterator end();
+ /// True if there are no values, false otherwise.
+ bool empty();
+ /// Returns the number of values stored.
+ unsigned int size();
+ /** Returns the string value matching the supplied name.
+ **
+ ** NOTE: the use of get<T>(key) or get<T>(key,default) is preferred.
+ ** This method is public to allow for specialized handling in the
+ ** rare cases where it may be required.
+ **
+ ** If there are no matching names, "" is returned. Be aware that
+ ** "" is a valid value, so you can not use this to verify that
+ ** a given name was defined. Use exists() for that.
+ **/
+ std::string operator [] (const std::string & key);
+ /** Returns all values associated with the supplied name.
+ **
+ ** NOTE: the use of getall<T>(key) is preferred. This method is
+ ** public to allow specialized handling in rare case where it
+ ** may be required.
+ **
+ ** If there are no values defined the strlist will be empty.
+ **/
+ strlist all(const std::string & key);
+ /// True if the name exists, false otherwise.
+ bool exists(const std::string & key);
+ /** Use this to get all matching values.
+ **
+ ** Usage:
+ **
+ ** vector<type> mylist = conf_reader_object.getall<type>(key);
+ **
+ ** type can be any standard type (string, int, double, etc.) or any
+ ** type for which the ">>" stream operator is defined. All values
+ ** with matching names that can map to the requested type will be
+ ** returned. Any that do not map will not be returned.
+ **/
+ template < class T >
+ typename std::vector<T> getall(const std::string & key);
+ /** Use this to get the matching value.
+ **
+ ** Useage:
+ **
+ ** type myvar = get<type>(key);
+ **
+ ** type can be any standard type (string, int, double, etc.) or any
+ ** type for which the ">>" stream operator is defined. The return
+ ** value is initialized to all zeros if no matching name is found or
+ ** if the first value with that name does not map to the requested
+ ** type. For the numeric types that results in zero being returned,
+ ** but be aware that more complex object may be in non-sensible
+ ** states if they were not found or could not map. Use exists() to
+ ** verify the existance of a given name if needed.
+ **/
+ template < class T >
+ T get(const std::string & key);
+ /** Returns the value for the requested key, or the supplied default.
+ **
+ ** Works exactly like get<>() with the exception that if the key
+ ** is not found in the list, the user supplied default value is
+ ** returned instead of 0 or an empty string. If the value exists but
+ ** can not map to the requested type, 0 or an empty string is
+ ** returned for the standard types.
+ **/
+ template <class T>
+ T get(const std::string & key, const T & def);
+};
+
+template < class T >
+ typename std::vector<T> conf_reader::getall(const std::string & key)
+{
+ strlist tvals = all(key);
+ std::vector<T> returnme;
+ if (typeid(T) == typeid(std::string))
+ {
+ // T is a std::string.. we can do this quickly.
+ strlist * wl = (strlist *) &returnme;
+ *wl = tvals;
+ }
+ else
+ {
+ // T is non-string.. will require more playing around.
+ unsigned int limit = tvals.size();
+ for (unsigned int i = 0; i < limit; i++)
+ {
+ try
+ {
+ returnme.push_back(boost::lexical_cast<T>(tvals[i]));
+ }
+ catch (...) {};
+ };
+ };
+ return returnme;
+};
+
+template < class T >
+ T conf_reader::get(const std::string & key)
+{
+ conf_reader & me = *this;
+ std::string tval = me[key];
+ T returnme;
+ // initialize the return value to nulls
+ // Needed for the numeric types, but bad for strings.
+ if (typeid(T) != typeid(std::string))
+ {
+ // null out the working area (death for strings!)
+ memset(&returnme,0,sizeof(T));
+ };
+ // This does appear to work for all the standard types.
+ if (tval != "")
+ {
+ try
+ {
+ returnme = boost::lexical_cast<T>(tval);
+ }
+ catch (...) {};
+ };
+ return returnme;
+};
+
+template < class T >
+ T conf_reader::get(const std::string & key, const T & def)
+{
+ if (exists(key)) { return get<T>(key); }
+ else { return def; };
+};
+
+}; // namespace nrtb
+
+#endif // ricklib_confreader_h
+
=== added file 'common/confreader/conftest.cpp'
--- common/confreader/conftest.cpp 1970-01-01 00:00:00 +0000
+++ common/confreader/conftest.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,129 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+/* confreader test program */
+
+#include "confreader.h"
+#include "../include/log_setup.h"
+#include <iostream>
+#include "Poco/Logger.h"
+#include "Poco/SimpleFileChannel.h"
+#include "Poco/AutoPtr.h"
+
+using namespace nrtb;
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ bool set_if_failed = false;
+ setup_global_logging("conf_test.log");
+ Poco::Logger & log = Poco::Logger::get("conftest");
+ log.information("=-=-=-=-=-= conftest Init =-=-=-=-=-=-=");
+ conf_reader & config = conf_reader::get_instance();
+ try
+ {
+ log.information("Starting read");
+ config.read(argc,argv,"test.config");
+ }
+ catch (...)
+ {
+ set_if_failed = true;
+ cerr << "Failed reading the configuration." << endl;
+ };
+ if (config.size() != 12)
+ {
+ set_if_failed = true;
+ cerr << "Did not find 12 parameters." << endl;
+ };
+ // iterator test
+ try
+ {
+ conf_reader::iterator c = config.begin();
+ conf_reader::iterator e = config.end();
+ while (c != e)
+ {
+ cout << "\t\"" << c->first << "\"=\"" << c->second
+ << "\"" << endl;
+ c++;
+ };
+ }
+ catch (...)
+ {
+ set_if_failed = true;
+ cerr << "Iterator test failed." << endl;
+ };
+ // template test.
+ int test = config.get<int>("test",-1);
+ int test2 = config.get<int>("test2",-1);
+ string test3 = config.get<string>("test3","not specified");
+ double test4 = config.get<double>("test",-1);
+ double test5 = config.get<double>("test2",-1);
+ cout << "(int) test = " << test
+ << "\n(int) test2 = " << test2
+ << "\n(string) test3 = \"" << test3 << "\""
+ << "\n(double) test = " << test4
+ << "\n(double) test2 = " << test5
+ << endl;
+ if (
+ (test != 1) or (test2 != 0)
+ or (test3 != "jack danials")
+ or (test4 != 1.0) or (test5 != 71.837486)
+ )
+ {
+ set_if_failed = true;
+ cerr << "** Template test failed." << endl;
+ };
+ // exists test.
+ cout << "?var \"--doit\" exists? "
+ << (config.exists("--doit") ? "Yes" : "No")
+ << endl;
+ if (!config.exists("--doit"))
+ {
+ set_if_failed = true;
+ cerr << "exists() test failed." << endl;
+ };
+ vector<int> intlist = config.getall<int>("test");
+ cout << "valid int \"test\" values:" << endl;
+ for (unsigned int i=0; i < intlist.size(); i++)
+ {
+ cout << "\t" << i << ": " << intlist[i] << endl;
+ };
+ if (intlist.size() != 2)
+ {
+ set_if_failed = true;
+ cerr << "getall<int>() did not find 2 parameters." << endl;
+ };
+ strlist strings = config.getall<string>("test");
+ cout << "valid string \"test\" values:" << endl;
+ for (unsigned int i=0; i < strings.size(); i++)
+ {
+ cout << "\t" << i << ": " << strings[i] << endl;
+ };
+ if (strings.size() != 3)
+ {
+ set_if_failed = true;
+ cerr << "getall<string>() did not find 3 parameters." << endl;
+ };
+ if (set_if_failed)
+ {
+ cerr << "** ntrb::conf_reader UNIT TEST FAILED. **" << endl;
+ log.fatal("UNIT TEST FAILED");
+ };
+ log.information("Run Complete");
+ return set_if_failed;
+};
=== added file 'common/confreader/test.config'
--- common/confreader/test.config 1970-01-01 00:00:00 +0000
+++ common/confreader/test.config 2011-08-02 01:34:24 +0000
@@ -0,0 +1,27 @@
+###### config reader test file ######
+# use this command line to properly test this:
+#
+# ./conftest test=1 test2=2 test2=71.837486 test3="jack danials" --doit
+#
+# You should get a warning about problems reading dummyfile, and 12
+# variables listed. "test" should be 2 overridden by the command line.
+# You can test the ability to override the config file name with the
+# command:
+#
+# ./conftest configfile=dummy
+#
+# It should complain about problems reading dummy, and no variables
+# should be populated.
+#
+
+fileversion version 1.0
+hashtest \#surrounded\# \#by\# \#hashes\#
+test nonsense # should be overridden by commmand line
+test duh! # what happens here?
+\#starthash should start with hash (\#) symbol
+test 21 # should only be seen in getall<int>();
+test3 Working line.
+
+*INCLUDE dummyfile
+#*INCLUDE ../../salesman/tests/bc_bench.config
+lastline this should be complete
=== added directory 'common/lib'
=== added directory 'common/logger'
=== added file 'common/logger/Makefile'
--- common/logger/Makefile 1970-01-01 00:00:00 +0000
+++ common/logger/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,42 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: log_test
+ @echo "Testing..."
+ @rm -f test_output.log
+ @./log_test
+ @grep "Program run complete." test_output.log
+ @cp -fv log_setup.h ../include
+ @cp -fv log_setup.o ../obj
+
+
+log_setup.o: log_setup.h log_setup.cpp Makefile
+ @rm -f log_setup.o
+ g++ -c log_setup.cpp -I ../include
+
+log_test: log_setup.o log_test.cpp Makefile
+ @rm -vf log_test
+ g++ -c log_test.cpp -I../include
+ g++ -o log_test log_setup.o log_test.o -lPocoFoundation
+# g++ -g common_test.cpp -idirafter . -o common_test
+
+clean:
+ @rm -vf *.o log_test ../include/log_setup.h ../obj/log_setup.o test_output.log
+
+
+
=== added file 'common/logger/log_setup.cpp'
--- common/logger/log_setup.cpp 1970-01-01 00:00:00 +0000
+++ common/logger/log_setup.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,43 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "log_setup.h"
+
+#include "Poco/SimpleFileChannel.h"
+#include "Poco/FormattingChannel.h"
+#include "Poco/PatternFormatter.h"
+#include "Poco/Logger.h"
+#include "Poco/AutoPtr.h"
+
+using Poco::SimpleFileChannel;
+using Poco::FormattingChannel;
+using Poco::PatternFormatter;
+using Poco::Logger;
+using Poco::AutoPtr;
+
+void nrtb::setup_global_logging(const std::string & logfilename)
+{
+ AutoPtr<SimpleFileChannel> pFile(new SimpleFileChannel);
+ pFile->setProperty("path", logfilename);
+ pFile->setProperty("rotation", "250 K");
+ AutoPtr<PatternFormatter> pPF(new PatternFormatter);
+ pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S [%s:%p] %t");
+ AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pFile));
+ Logger::root().setChannel(pFC);
+ Logger::root().notice("Logging system initialized");
+}
\ No newline at end of file
=== added file 'common/logger/log_setup.h'
--- common/logger/log_setup.h 1970-01-01 00:00:00 +0000
+++ common/logger/log_setup.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,30 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef logger_setup_h
+#define logger_setup_h
+
+#include <string>
+
+namespace nrtb
+{
+
+ void setup_global_logging(const std::string & logfilename);
+}
+
+#endif //logger_setup_h
\ No newline at end of file
=== added file 'common/logger/log_test.cpp'
--- common/logger/log_test.cpp 1970-01-01 00:00:00 +0000
+++ common/logger/log_test.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,46 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "log_setup.h"
+
+#include <string>
+#include <iostream>
+#include <Poco/Logger.h>
+#include "Poco/LogStream.h"
+
+using namespace std;
+
+int main()
+{
+ bool set_if_failed = false;
+ try
+ {
+ nrtb::setup_global_logging("test_output.log");
+ Poco::Logger & logger = Poco::Logger::get("log_test");
+ logger.notice("Logging should be set up now.");
+ Poco::LogStream log(logger);
+ log << "This message used the stream interface" << endl;
+ logger.notice("Program run complete.");
+ }
+ catch (...)
+ {
+ set_if_failed = true;
+ cout << "** UNIT TEST FAILED **" << endl;
+ };
+ return set_if_failed;
+}
=== removed directory 'common/plugin_loader'
=== removed file 'common/plugin_loader/Makefile'
--- common/plugin_loader/Makefile 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/Makefile 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-
-build: plugin_wrapper.o plugin_manager.o
- @echo build complete
-
-plugin_wrapper.o: plugin_wrapper.h plugin_wrapper.cpp Makefile
- @rm -f plugin_wrapper.o
- g++ -c -O3 plugin_wrapper.cpp -idirafter ../../include3
-# g++ -c -g plugin_wrapper.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
-
-plugin_manager.o: plugin_manager.h plugin_manager.cpp Makefile
- @rm -f plugin_manager.o
- g++ -c -O3 plugin_manager.cpp -idirafter ../../include3
-# g++ -c -g plugin_wrapper.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
-
-test: plugin_wrapper.o plugin_manager.o wrapper_test.cpp
- @rm -f plugin_test
- g++ -c plugin_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
-# g++ -c -g conftest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
- g++ -o plugtest plugtest.o plugin_wrapper.o plugin_manager.o -l ricklib3 -L../../lib/
-
-clean:
- @rm -rvf *.o plugin_test ../../include3/plugin_wrapper.h ../../include3/plugin_manager.h
- ar -d ../../lib/libricklib3.a plugin_wrapper.o plugin_manager.o
- @echo all objects and executables have been erased.
-
-lib: test
- @ar -r ../../lib/libricklib3.a plugin_wrapper.o plugin_manager.o
- @echo the plugin_wrapper class has been added to the library
- @cp -fv plugin_wrapper.h plugin_manager.h ../../include3
=== removed directory 'common/plugin_loader/doc'
=== removed file 'common/plugin_loader/doc/plugins.xmi'
--- common/plugin_loader/doc/plugins.xmi 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/doc/plugins.xmi 1970-01-01 00:00:00 +0000
@@ -1,339 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2008-07-12T19:11:33" xmi.version="1.2" >
- <XMI.header>
- <XMI.documentation>
- <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
- <XMI.exporterVersion>1.5.8</XMI.exporterVersion>
- <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
- </XMI.documentation>
- <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
- </XMI.header>
- <XMI.content>
- <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="UML Model" >
- <UML:Namespace.ownedElement>
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="singleton<work_queue_thread<message>>" isRoot="false" isAbstract="false" name="singleton<work_queue_thread<message>>" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="singleton" isRoot="false" isAbstract="false" name="singleton" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="thread::run" isRoot="false" isAbstract="false" name="thread::run" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="simObject, ricklib::thread" isRoot="false" isAbstract="false" name="simObject, ricklib::thread" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="map<string,plugin_list>" isRoot="false" isAbstract="false" name="map<string,plugin_list>" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="map<string,plugins_by_name>" isRoot="false" isAbstract="false" name="map<string,plugins_by_name>" />
- <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="triad<double>" isRoot="false" isAbstract="false" name="triad<double>" />
- <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
- <UML:Namespace.ownedElement>
- <UML:Package stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
- <UML:Namespace.ownedElement>
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Ffh4kk3Ca5c0" isRoot="false" isAbstract="false" name="int" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="dwxIyKY9DGUT" isRoot="false" isAbstract="false" name="char" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="80aYqgH4Lz85" isRoot="false" isAbstract="false" name="bool" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hBHFFrFqnD9j" isRoot="false" isAbstract="false" name="float" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="VfqivJ93JiZ9" isRoot="false" isAbstract="false" name="double" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="OrDjoJmVT3kg" isRoot="false" isAbstract="false" name="short" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="syWd9dNeIDLC" isRoot="false" isAbstract="false" name="long" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="WSFnAnxYc8FQ" isRoot="false" isAbstract="false" name="unsigned int" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Q1tt2bZuZ5Yg" isRoot="false" isAbstract="false" name="unsigned short" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="htJz4eBZ4PMF" isRoot="false" isAbstract="false" name="unsigned long" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="CHlmQ1Co03h3" isRoot="false" isAbstract="false" name="string" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="z2PlKwwnqyeq" isRoot="false" isAbstract="false" name="void *" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="FWxLRQq7CGim" isRoot="false" isAbstract="false" name="abstract_weapon *" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="81JjStCiP83q" isRoot="false" isAbstract="false" name="abstract_sensor *" />
- <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="qUlL5Ja8j1rY" isRoot="false" isAbstract="false" name="abstract_chassis *" />
- </UML:Namespace.ownedElement>
- </UML:Package>
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="225YrWUg6CUk" isRoot="false" isAbstract="true" name="plugin_wrapper" >
- <UML:GeneralizableElement.generalization>
- <UML:Generalization xmi.idref="vIs8sXpoyxA8" />
- </UML:GeneralizableElement.generalization>
- <UML:Classifier.feature>
- <UML:Attribute comment="The type of plugin represented here (i.e. weapon, sensor, etc.), must match the types defined for sim engine use." isSpecification="false" visibility="protected" xmi.id="0kYAfH74JA7p" type="CHlmQ1Co03h3" name="plugin_type" />
- <UML:Attribute comment="The version number of this plugin." isSpecification="false" visibility="protected" xmi.id="ToJfQEMPzsZc" type="hBHFFrFqnD9j" name="version" />
- <UML:Attribute comment="The name of this plugin." isSpecification="false" visibility="protected" xmi.id="9egRonGpPYT7" type="CHlmQ1Co03h3" name="plugin_name" />
- <UML:Attribute comment="The path of the shared library implementing this plugin." isSpecification="false" visibility="protected" xmi.id="ZRl1ZW499wAW" type="YMxgqxXjjUHD" name="path" />
- <UML:Attribute isSpecification="false" visibility="protected" xmi.id="wOLstKsOU3xd" type="ZSpIFcMrTgYw" name="factory_address" />
- <UML:Operation comment="Called to load the library." isSpecification="false" isLeaf="false" visibility="public" xmi.id="evlKlgpUQJmb" isRoot="false" isAbstract="false" isQuery="false" name="load" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="The path of shared library file implementing the plugin." isSpecification="false" visibility="private" xmi.id="95QVtX2h9xRU" value="" type="YMxgqxXjjUHD" name="path" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Called to get the raw address to the factory... you'll need to cast it to the correct type." isSpecification="false" isLeaf="false" visibility="public" xmi.id="j7HBVbv71scs" isRoot="false" isAbstract="false" isQuery="false" name="plugin_wrapper" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="The path to the library to be loaded." isSpecification="false" visibility="private" xmi.id="SOCOuP71SVVL" value="" type="YMxgqxXjjUHD" name="loadpath" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Returns the plugin_type for the contained plugin." isSpecification="false" isLeaf="false" visibility="public" xmi.id="gx1dfJPPtVf7" isRoot="false" isAbstract="false" isQuery="false" name="getType" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter kind="return" xmi.id="hG7NjAual1aw" type="CHlmQ1Co03h3" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Returns the version information for the contained plugin." isSpecification="false" isLeaf="false" visibility="public" xmi.id="lh0Se8lUfT5X" isRoot="false" isAbstract="false" isQuery="false" name="getVersion" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter kind="return" xmi.id="jxjLJCew2LSN" type="hBHFFrFqnD9j" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Returns the name of the plugin associated with this wrapper." isSpecification="false" isLeaf="false" visibility="public" xmi.id="fqiWLNb62bXe" isRoot="false" isAbstract="false" isQuery="false" name="getName" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter kind="return" xmi.id="g1RhawLICSft" type="CHlmQ1Co03h3" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Returns the full file path for the plugin loaded." isSpecification="false" isLeaf="false" visibility="public" xmi.id="EADACWaXDZwu" isRoot="false" isAbstract="false" isQuery="false" name="getPath" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter kind="return" xmi.id="9tDR3e4vEZMa" type="YMxgqxXjjUHD" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="n1z8iZxdRl3R" isRoot="false" isAbstract="false" isQuery="false" name="newInstance" />
- </UML:Classifier.feature>
- </UML:Class>
- <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="1dJfkTAS2RQE" isRoot="false" isAbstract="false" name="std" >
- <UML:Namespace.ownedElement/>
- </UML:Package>
- <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="rsozaUfviJVQ" isRoot="false" isAbstract="false" name="boost" >
- <UML:Namespace.ownedElement>
- <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="rsozaUfviJVQ" xmi.id="hQQSxzuiyRF1" isRoot="false" isAbstract="false" name="filesystem" >
- <UML:Namespace.ownedElement>
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="hQQSxzuiyRF1" xmi.id="YMxgqxXjjUHD" isRoot="false" isAbstract="false" name="path" />
- </UML:Namespace.ownedElement>
- </UML:Package>
- </UML:Namespace.ownedElement>
- </UML:Package>
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ZSpIFcMrTgYw" isRoot="false" isAbstract="false" name="factory_ptr" />
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="5RxrSpb7LxuI" isRoot="false" isAbstract="false" name="weapon_plugin" >
- <UML:GeneralizableElement.generalization>
- <UML:Generalization xmi.idref="FgcyZa21VrTL" />
- </UML:GeneralizableElement.generalization>
- <UML:Classifier.feature>
- <UML:Operation comment="Allocates and constructs the abstract_weapon descendent and returns a smart pointer to the new object." isSpecification="false" isLeaf="false" visibility="public" xmi.id="WStI1XSjbrPt" isRoot="false" isAbstract="false" isQuery="false" name="newWeapon" />
- </UML:Classifier.feature>
- </UML:Class>
- <UML:Generalization isSpecification="false" child="5RxrSpb7LxuI" visibility="public" namespace="Logical View" xmi.id="FgcyZa21VrTL" parent="225YrWUg6CUk" discriminator="" name="" />
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Y1oRrxMFYzBw" isRoot="false" isAbstract="false" name="sensor_plugin" >
- <UML:GeneralizableElement.generalization>
- <UML:Generalization xmi.idref="QAC4gEA4Cbfh" />
- </UML:GeneralizableElement.generalization>
- <UML:Classifier.feature>
- <UML:Operation comment="Allocates and constructs a descendent of abstract_sensor and returns a smart pointer to the new object." isSpecification="false" isLeaf="false" visibility="public" xmi.id="0zNHSOUVzjY3" isRoot="false" isAbstract="false" isQuery="false" name="newSensor" />
- </UML:Classifier.feature>
- </UML:Class>
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="PyRdWPmTPloe" isRoot="false" isAbstract="false" name="etc_plugin" >
- <UML:GeneralizableElement.generalization>
- <UML:Generalization xmi.idref="nenipvZyQWG1" />
- </UML:GeneralizableElement.generalization>
- <UML:Classifier.feature>
- <UML:Operation comment="Returns a smart to a new object of the appropriate class." isSpecification="false" isLeaf="false" visibility="public" xmi.id="EC8j9pFAdKdx" isRoot="false" isAbstract="false" isQuery="false" name="newEtc" />
- </UML:Classifier.feature>
- </UML:Class>
- <UML:Generalization isSpecification="false" child="Y1oRrxMFYzBw" visibility="public" namespace="Logical View" xmi.id="QAC4gEA4Cbfh" parent="225YrWUg6CUk" discriminator="" name="" />
- <UML:Generalization isSpecification="false" child="225YrWUg6CUk" visibility="public" namespace="Logical View" xmi.id="vIs8sXpoyxA8" parent="PyRdWPmTPloe" discriminator="" name="" />
- <UML:Generalization isSpecification="false" child="PyRdWPmTPloe" visibility="public" namespace="Logical View" xmi.id="nenipvZyQWG1" parent="225YrWUg6CUk" discriminator="" name="" />
- <UML:Class stereotype="singleton" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="WT0Ka8jF10jk" isRoot="false" isAbstract="false" name="plugin_manager" >
- <UML:Classifier.feature>
- <UML:Attribute isSpecification="false" visibility="protected" xmi.id="HPMtw9k0PQzT" type="ohv3mPtcgGzX" name="plugins" />
- <UML:Operation comment="Loads all plugins found in the default paths (defined by the configuration manager singleton not shown here)." isSpecification="false" isLeaf="false" visibility="public" xmi.id="46RtlzCdqiGw" isRoot="false" isAbstract="false" isQuery="false" name="load_all" />
- <UML:Operation comment="Returns a reference to the requested plugin_wrapper or throws if it is not found." isSpecification="false" isLeaf="false" visibility="public" xmi.id="YVcYycxZS0QM" isRoot="false" isAbstract="false" isQuery="false" name="create_instance" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="The class of plugin requested" isSpecification="false" visibility="private" xmi.id="r12fGT7KZYDL" value="" type="CHlmQ1Co03h3" name="plugin_type" />
- <UML:Parameter comment="The name of the plugin requested." isSpecification="false" visibility="private" xmi.id="WNwM6CGchsAd" value="" type="CHlmQ1Co03h3" name="name" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Releases all plugins held by the manager." isSpecification="false" isLeaf="false" visibility="public" xmi.id="niINN8W0bcBT" isRoot="false" isAbstract="false" isQuery="false" name="release_all" />
- <UML:Operation comment="For debugging, returns a formatted string with a list of all plugins loaded including types, names and version number." isSpecification="false" isLeaf="false" visibility="public" xmi.id="HQVTuW3lNEMc" isRoot="false" isAbstract="false" isQuery="false" name="dump" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter kind="return" xmi.id="6dRTso5oWpKV" type="CHlmQ1Co03h3" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Loads one plugin. Will throw if the provided path is invalid or does not contain a valid plugin." isSpecification="false" isLeaf="false" visibility="public" xmi.id="yilX1rI1K1Ye" isRoot="false" isAbstract="false" isQuery="false" name="load_one" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="Path to the shared libary to be loaded." isSpecification="false" visibility="private" xmi.id="RbQYsO69oaag" value="" type="YMxgqxXjjUHD" name="path" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Releases one plugin, specified by type and name. WIll throw if the plugin is not found." isSpecification="false" isLeaf="false" visibility="public" xmi.id="SOhcCFAtLoIm" isRoot="false" isAbstract="false" isQuery="false" name="release_one" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="The type of the single plugin to be released." isSpecification="false" visibility="private" xmi.id="e6qSbfm4JPXG" value="" type="CHlmQ1Co03h3" name="plugin_type" />
- <UML:Parameter comment="The name of the single plugin to be released." isSpecification="false" visibility="private" xmi.id="1Zq4BqfcCMEM" value="" type="CHlmQ1Co03h3" name="plugin_name" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- <UML:Operation comment="Returns a ricklib::str_list contining all the class names currently loaded." isSpecification="false" isLeaf="false" visibility="public" xmi.id="cu3qBV5M3heD" isRoot="false" isAbstract="false" isQuery="false" name="get_class_names" />
- <UML:Operation comment="returns a ricklib::str_list containing all the plugin names which match a given class." isSpecification="false" isLeaf="false" visibility="public" xmi.id="D9eyZpw9jz0s" isRoot="false" isAbstract="false" isQuery="false" name="get_class_plugin_names" >
- <UML:BehavioralFeature.parameter>
- <UML:Parameter comment="The name of the plugin class to be returned." isSpecification="false" visibility="private" xmi.id="KaC8tCfxNnbM" value="" type="CHlmQ1Co03h3" name="class_name" />
- </UML:BehavioralFeature.parameter>
- </UML:Operation>
- </UML:Classifier.feature>
- <UML:Namespace.ownedElement>
- <UML:Class stereotype="map<string,plugins_by_name>" isSpecification="false" isLeaf="false" visibility="public" namespace="WT0Ka8jF10jk" xmi.id="qoJ98w4raNBZ" isRoot="false" isAbstract="false" name="plugin_lists_by_class" />
- </UML:Namespace.ownedElement>
- </UML:Class>
- <UML:Class stereotype="map<string,plugin_list>" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="eLKy62PhoKwL" isRoot="false" isAbstract="false" name="plugins_by_name" />
- <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="TBw9yE3Jk8tz" name="" >
- <UML:Association.connection>
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="OBQB4JJHyejP" aggregation="aggregate" type="qoJ98w4raNBZ" name="" multiplicity="0..n" />
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="tUGb3kMc58zH" aggregation="none" type="eLKy62PhoKwL" name="" />
- </UML:Association.connection>
- </UML:Association>
- <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xRtgdkgsvOEx" name="" >
- <UML:Association.connection>
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Vq2iVy3r9S2B" aggregation="aggregate" type="225YrWUg6CUk" name="" multiplicity="1..n" />
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lJSix95qbJQe" aggregation="none" type="eLKy62PhoKwL" name="" />
- </UML:Association.connection>
- </UML:Association>
- <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="iYP4MN0Qbl9T" name="" >
- <UML:Association.connection>
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4mG9sDPO2P4V" aggregation="aggregate" type="eLKy62PhoKwL" name="" multiplicity="1..n" />
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="N7KVZMgJd7zb" aggregation="none" type="225YrWUg6CUk" name="" />
- </UML:Association.connection>
- </UML:Association>
- <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ohv3mPtcgGzX" isRoot="false" isAbstract="false" name="plugin_lists_by_class" />
- <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="D6HDTiBxzfAu" name="" >
- <UML:Association.connection>
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="uwmwLqPgvj9T" aggregation="composite" type="WT0Ka8jF10jk" name="" />
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="5qkhvjG9ldx6" aggregation="none" type="WT0Ka8jF10jk" name="" />
- </UML:Association.connection>
- </UML:Association>
- <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ozgldpf0rhYJ" name="" >
- <UML:Association.connection>
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="RSWw91M3x6yG" aggregation="composite" type="WT0Ka8jF10jk" name="" />
- <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="wNuq74JAs3rn" aggregation="none" type="qoJ98w4raNBZ" name="" />
- </UML:Association.connection>
- </UML:Association>
- </UML:Namespace.ownedElement>
- <XMI.extension xmi.extender="umbrello" >
- <diagrams>
- <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="808" snapy="10" showatts="1" xmi.id="DukLGrX7Qs7l" documentation="" type="1" showops="1" showpackage="0" name="Plugin Manager Overview" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="588" >
- <widgets>
- <classwidget usesdiagramfillcolor="0" width="352" showattsigs="601" x="445" fillcolor="#ffffc0" y="19" drawascircle="0" showopsigs="601" linewidth="none" height="234" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="225YrWUg6CUk" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
- <classwidget usesdiagramfillcolor="0" width="378" showattsigs="601" x="6" fillcolor="#ffffc0" y="219" showopsigs="601" linewidth="none" height="198" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="WT0Ka8jF10jk" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
- <classwidget usesdiagramfillcolor="0" width="200" showattsigs="600" x="48" fillcolor="#ffffc0" y="14" showopsigs="600" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="0" isinstance="0" xmi.id="eLKy62PhoKwL" showoperations="0" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
- <classwidget usesdiagramfillcolor="0" width="249" showattsigs="601" x="25" fillcolor="#ffffc0" y="114" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="qoJ98w4raNBZ" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
- <notewidget usesdiagramfillcolor="1" width="383" x="417" fillcolor="none" y="273" linewidth="none" height="251" usefillcolor="1" isinstance="0" xmi.id="cwXZkbyWc9J4" text="IMPORTANT NOTE:
-
-For this to work, plugin_wrapper must assume each plugin will export the following symbols:
-
-Variables:
- string PTYPE: the plugin type (weapon, sensor, etc.)
- string PNAME: the name of this particular plugin
- string PVER: the version number of this particular plugin
-
-Function
- abstract_? * PFACT(...) : the factory which creates the plugin (a c++ class instance). The precise signature of the fuction will vary between plugin types and is not the concern of the plugin manager, as it will not be called in that context. " usesdiagramusefillcolor="1" font="Sans,8,-1,5,50,0,0,0,0,0" linecolor="none" />
- </widgets>
- <messages/>
- <associations>
- <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="eLKy62PhoKwL" widgetaid="qoJ98w4raNBZ" xmi.id="TBw9yE3Jk8tz" type="501" linecolor="none" >
- <linepath>
- <startpoint startx="149" starty="114" />
- <endpoint endx="148" endy="68" />
- </linepath>
- <floatingtext usesdiagramfillcolor="1" width="32" x="151" fillcolor="none" y="90" linewidth="none" posttext="" role="701" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="k5uTjsZAI36P" text="0..n" usesdiagramusefillcolor="1" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="none" />
- </assocwidget>
- <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="225YrWUg6CUk" widgetaid="eLKy62PhoKwL" xmi.id="iYP4MN0Qbl9T" type="501" linecolor="none" >
- <linepath>
- <startpoint startx="248" starty="41" />
- <endpoint endx="445" endy="136" />
- </linepath>
- <floatingtext usesdiagramfillcolor="1" width="32" x="246" fillcolor="none" y="24" linewidth="none" posttext="" role="701" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="4RQzXODSk8Ir" text="1..n" usesdiagramusefillcolor="1" font="Sans,10,-1,5,50,0,0,0,0,0" linecolor="none" />
- </assocwidget>
- <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="qoJ98w4raNBZ" widgetaid="WT0Ka8jF10jk" xmi.id="ozgldpf0rhYJ" type="510" linecolor="none" >
- <linepath>
- <startpoint startx="195" starty="219" />
- <endpoint endx="149" endy="168" />
- </linepath>
- </assocwidget>
- </associations>
- </diagram>
- </diagrams>
- </XMI.extension>
- </UML:Model>
- <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Use Case View" isRoot="false" isAbstract="false" name="Use Case View" >
- <UML:Namespace.ownedElement/>
- </UML:Model>
- <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
- <UML:Namespace.ownedElement/>
- </UML:Model>
- <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
- <UML:Namespace.ownedElement/>
- </UML:Model>
- <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Entity Relationship Model" isRoot="false" isAbstract="false" name="Entity Relationship Model" >
- <UML:Namespace.ownedElement/>
- </UML:Model>
- </UML:Namespace.ownedElement>
- </UML:Model>
- </XMI.content>
- <XMI.extensions xmi.extender="umbrello" >
- <docsettings viewid="DukLGrX7Qs7l" documentation="" uniqueid="KaC8tCfxNnbM" />
- <listview>
- <listitem open="1" type="800" label="Views" >
- <listitem open="1" type="801" id="Logical View" >
- <listitem open="0" type="807" id="DukLGrX7Qs7l" label="Plugin Manager Overview" />
- <listitem open="1" type="813" id="PyRdWPmTPloe" >
- <listitem open="0" type="815" id="EC8j9pFAdKdx" />
- </listitem>
- <listitem open="1" type="813" id="ZSpIFcMrTgYw" />
- <listitem open="1" type="813" id="ohv3mPtcgGzX" />
- <listitem open="1" type="813" id="WT0Ka8jF10jk" >
- <listitem open="0" type="813" id="qoJ98w4raNBZ" />
- <listitem open="0" type="814" id="HPMtw9k0PQzT" />
- <listitem open="0" type="815" id="46RtlzCdqiGw" />
- <listitem open="0" type="815" id="YVcYycxZS0QM" />
- <listitem open="0" type="815" id="niINN8W0bcBT" />
- <listitem open="0" type="815" id="HQVTuW3lNEMc" />
- <listitem open="0" type="815" id="yilX1rI1K1Ye" />
- <listitem open="0" type="815" id="SOhcCFAtLoIm" />
- <listitem open="0" type="815" id="cu3qBV5M3heD" />
- <listitem open="0" type="815" id="D9eyZpw9jz0s" />
- </listitem>
- <listitem open="1" type="813" id="225YrWUg6CUk" >
- <listitem open="0" type="814" id="0kYAfH74JA7p" />
- <listitem open="0" type="814" id="ToJfQEMPzsZc" />
- <listitem open="0" type="814" id="9egRonGpPYT7" />
- <listitem open="0" type="814" id="ZRl1ZW499wAW" />
- <listitem open="0" type="814" id="wOLstKsOU3xd" />
- <listitem open="0" type="815" id="evlKlgpUQJmb" />
- <listitem open="0" type="815" id="j7HBVbv71scs" />
- <listitem open="0" type="815" id="gx1dfJPPtVf7" />
- <listitem open="0" type="815" id="lh0Se8lUfT5X" />
- <listitem open="0" type="815" id="fqiWLNb62bXe" />
- <listitem open="0" type="815" id="EADACWaXDZwu" />
- <listitem open="0" type="815" id="n1z8iZxdRl3R" />
- </listitem>
- <listitem open="1" type="813" id="eLKy62PhoKwL" />
- <listitem open="1" type="813" id="Y1oRrxMFYzBw" >
- <listitem open="0" type="815" id="0zNHSOUVzjY3" />
- </listitem>
- <listitem open="1" type="813" id="5RxrSpb7LxuI" >
- <listitem open="0" type="815" id="WStI1XSjbrPt" />
- </listitem>
- <listitem open="1" type="818" id="rsozaUfviJVQ" >
- <listitem open="1" type="818" id="hQQSxzuiyRF1" >
- <listitem open="1" type="813" id="YMxgqxXjjUHD" />
- </listitem>
- </listitem>
- <listitem open="1" type="818" id="1dJfkTAS2RQE" />
- <listitem open="1" type="830" id="Datatypes" >
- <listitem open="1" type="829" id="qUlL5Ja8j1rY" />
- <listitem open="1" type="829" id="81JjStCiP83q" />
- <listitem open="1" type="829" id="FWxLRQq7CGim" />
- <listitem open="1" type="829" id="80aYqgH4Lz85" />
- <listitem open="1" type="829" id="dwxIyKY9DGUT" />
- <listitem open="1" type="829" id="VfqivJ93JiZ9" />
- <listitem open="1" type="829" id="hBHFFrFqnD9j" />
- <listitem open="1" type="829" id="Ffh4kk3Ca5c0" />
- <listitem open="1" type="829" id="syWd9dNeIDLC" />
- <listitem open="1" type="829" id="OrDjoJmVT3kg" />
- <listitem open="1" type="829" id="CHlmQ1Co03h3" />
- <listitem open="1" type="829" id="WSFnAnxYc8FQ" />
- <listitem open="1" type="829" id="htJz4eBZ4PMF" />
- <listitem open="1" type="829" id="Q1tt2bZuZ5Yg" />
- <listitem open="1" type="829" id="z2PlKwwnqyeq" />
- </listitem>
- </listitem>
- <listitem open="1" type="802" id="Use Case View" />
- <listitem open="1" type="821" id="Component View" />
- <listitem open="1" type="827" id="Deployment View" />
- <listitem open="1" type="836" id="Entity Relationship Model" />
- </listitem>
- </listview>
- <codegeneration>
- <codegenerator language="C++" />
- </codegeneration>
- </XMI.extensions>
-</XMI>
=== removed file 'common/plugin_loader/plugin_manager.cpp'
--- common/plugin_loader/plugin_manager.cpp 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/plugin_manager.cpp 1970-01-01 00:00:00 +0000
@@ -1,127 +0,0 @@
-//
-// C++ Implementation: plugin_manager
-//
-// Description:
-//
-//
-// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#include "plugin_manager.h"
-
-//use boost::filesystem;
-//use boost::filesystem::directory_iterator;
-
-
-// TODO: review to make sure all methods from the .h are implemented.
-namespace NRTB
-{
-
- plugin_manager::plugin_manager()
- {
- // nop in this version.
- };
-
- plugin_manager::plugin_manager(const boost::filesystem::path loadpath)
- {
- plugin_manager();
- load_all(loadpath);
- };
-
- plugin_manager::~plugin_manager()
- {
- release_all();
- };
-
- void plugin_manager::load_all(const boost::filesystem::path loadpath)
- {
- // check to if loadpath really exists
- if (!boost::filesystem::exists(loadpath))
- {
- path_not_found e;
- e.store(loadpath.native_directory_string());
- throw e;
- };
- if (!is_directory(loadpath))
- {
- not_a_directory e;
- e.store(loadpath.native_file_string());
- throw e;
- };
- // set up for the scan
- boost::filesystem::directory_iterator end; // points to the end of the list
- boost::filesystem::directory_iterator current(loadpath);
- while (current != end)
- {
- if (is_directory(*current))
- {
- // recursive call to process the directory.
- load_all(*current);
- }
- else
- {
- // try to load the plugin
- try
- {
- load_one(*current);
- }
- catch (plugin_wrapper::invalid_plugin & e)
- {
- // take no action in this caee...
- };
- };
- current++;
- };
- };
-
- void plugin_manager::load_one(const boost::filesystem::path loadpath)
- {
- // check to if loadpath really exists
- if (!boost::filesystem::exists(loadpath))
- {
- path_not_found e;
- e.store(loadpath.native_directory_string());
- throw e;
- };
- if (boost::filesystem::is_directory(loadpath))
- {
- plugin_file_not_found e;
- e.store(loadpath.native_file_string());
- throw e;
- };
- /* NOTE: since wrapper_p is a smart pointer, any memory
- allocated to it will be discarded if an exception
- is thrown in the following section.
- */
- // Create the plugin_wrapper.
- wrapper_p new_plugin(new plugin_wrapper);
- // Load it... will throw if somehing's not right.
- new_plugin->load(loadpath);
- // Store it in our list.
- plugins[new_plugin->get_type()][new_plugin->get_name()] = new_plugin;
- };
-
- void plugin_manager::release_all()
- {
- // this will call the destructor and deallocate all
- // plugin_wrappers currently loaded.
- plugins.clear();
- };
-
- void plugin_manager::release_one(const std::string pclass,
- const std::string name)
- {
- // TODO: more here.
- plugins[pclass].erase(name);
- };
-
- std::string plugin_manager::dump()
- {
- // TODO: More to do here.
- };
-
-}; // namespace NRTB
-
=== removed file 'common/plugin_loader/plugin_manager.h'
--- common/plugin_loader/plugin_manager.h 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/plugin_manager.h 1970-01-01 00:00:00 +0000
@@ -1,194 +0,0 @@
-//
-// C++ Interface: plugin_manager
-//
-// Description:
-//
-//
-// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#ifndef plugin_manager_h
-#define plugin_manager_h
-
-#include "plugin_wrapper.h"
-#include <map>
-
-namespace NRTB
-{
- /**
- * Provides a simple mechanism for an application to
- * load and manage plugins (shared objects in the unix lingo)
- * which provide the application with functionality not
- * not available at the time it was built.
- *
- * To be useable with this class a shared object must
- * meet certain requirements which are outlined in the
- * NRTB::plugin_wrapper class documentation. Example
- * plugins are also provided.
- */
- class plugin_manager
- {
- public:
- /// Typedef for return values
- typedef std::vector<std::string> strlist;
- /// parent for all exceptions thrown by this class
- class general_exception: public base_exception {};
- /// thrown if a specified plugin file was no found.
- class plugin_file_not_found: public general_exception {};
- /// thrown if a specified load path (directory) was not found.
- class path_not_found: public general_exception {};
- /// thown if a specified load path is not a directory.
- class not_a_directory: public general_exception {};
- /// thrown if a specifically requested plugin is not loaded.
- class plugin_not_found: public general_exception {};
- /**
- * Simple constructor.
- */
- plugin_manager();
- /**
- * Constructs the class and then attempts to load all
- * files found under the given path (recursively) as
- * plugins.Non-plugin files will be ignored, but
- * problems reading the given path (path not found,
- * insufficient permissions, etc.) will cause an
- * exception to be thrown.
- *
- * @param loadpath The top of the file tree to be searched.
- */
- plugin_manager(const boost::filesystem::path loadpath);
- /**
- * Unloads all managed plugins and destructs the
- * plugin_manager. Probably not a good thing to do
- * while any of the plugins are in use.
- */
- virtual ~plugin_manager();
- /**
- * Attempts to load all files found under the
- * given path (recursively) as plugins.Non-plugin
- * files will be ignored, but problems reading the
- * given path (path not found, insufficient
- * permissions, etc.) will cause an exception to be thrown.
- *
- * If two plugins have the same class and name, the one
- * with the highest version number will be kept and
- * the other(s) discarded.
- *
- * @param loadpath The top of the file tree to be searched.
- */
- void load_all(const boost::filesystem::path loadpath);
- /**
- * Attempts to load a plugin from the fully qualified
- * file path given. Exceptions will be thrown if there
- * are any problems reading the file, or if it is not a
- * valid plugin (by plugin_wrapper standards).
- *
- * If two plugins have the same class and name, the one
- * with the highest version number will be kept and
- * the other(s) discarded.
- *
- * @param loadpath A fully qualified file path.
- */
- void load_one(const boost::filesystem::path loadpath);
- /**
- * Releases all plugins currently being managed. Probably
- * not a good thing to do if any of them are being used.
- */
- void release_all();
- /**
- * Attempts to release the single plugin matching the
- * provided plugin class and name. An exception will be thrown
- * if the plugin is not found.
- *
- * @param pclass The class of the plugin to release.
- * @param name The name of the plugin to release.
- */
- void release_one(const std::string pclass, const std::string name);
- /**
- * Dumps a list of all loaded plugins, intended for
- * diagnostic purposes. The list is formatted:
- *
- * plugin_class::plugin_name<eol>
- *
- * with one line for each plugin loaded.
- *
- * @return A string contianing a formatted plugin listing.
- */
- std::string dump();
- /**
- * Returns a strlist (a vector<string>) containing
- * all unique plugin class names loaded, in alpha order.
- *
- * @return A list of all unique plugin classes loaded.
- */
- strlist get_class_names();
- /**
- * Returns a strlist (a vector<string>) containing
- * the names of all plugins loaded of the given plugin class.
- *
- * @param pclass The name of the plugin class to be searched.
- * @return A list of all plugins loaded for the given plugin class.
- */
- strlist get_class_plugin_names(const std::string pclass);
- /**
- * Returns true if a plugin with the given class
- * and name exists, or faise if not.
- *
- * @param pclass The class name of the plugin to be checked.
- * @param pname The name of the plugin to be checked
- * @return True if the plugin is laoded, false otherwise.
- */
- bool exists(const std::string pclass, const std::string pname);
- /**
- * Returns a boost::shared_ptr<T> to a new instance
- * of the class provided by the plugin specified by
- * the plugin_class and plugin_name provided.
- *
- * Usage example:
- * myTypePointer = create_plugin_instance<mytype>(class,name);
- *
- * This routine will succeed unconditionally or throw
- * one of several possible exceptions. In no case will a
- * null pointer or improperly constructed instance be
- * returned.
- *
- * @param plugin_class The class name of the plugin desired
- * @param plugin_name The name of the plugin desired.
- * @return A boost::shared_ptr<T> to a ready to use instance.
- */
- template <class T> boost::shared_ptr<T> create_plugin_instance
- (
- const std::string plugin_class,
- const std::string plugin_name
- )
- {
- typedef boost::shared_ptr<T> returntype;
- if (!exists(plugin_class, plugin_name))
- {
- plugin_not_found e;
- e.store(plugin_class+"::"+plugin_name);
- throw e;
- };
- returntype returnme =
- plugins[plugin_class][plugin_name]->create_instance<T>();
- return returnme;
- };
- protected:
- // smart pointer to a plugin_wrapper
- typedef boost::shared_ptr<plugin_wrapper> wrapper_p;
- // type used contain plugins of the same type
- typedef std::map<std::string, wrapper_p> plugins_by_name;
- // type used to contain lists of types of plugins.
- typedef std::map<std::string, plugins_by_name> plugins_list_by_class;
- // iterator providing access to "plugins_by_name" lists by class
- typedef plugins_list_by_class::iterator class_iterator;
- // iterator providing access to individual plugins by name
- typedef plugins_by_name::iterator plugin_iterator;
- // container for all plugins being managed.
- plugins_list_by_class plugins;
- };
-};
-
-#endif //plugin_manager_h
=== removed file 'common/plugin_loader/plugin_wrapper.cpp'
--- common/plugin_loader/plugin_wrapper.cpp 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/plugin_wrapper.cpp 1970-01-01 00:00:00 +0000
@@ -1,146 +0,0 @@
-//
-// C++ Implementation: plugin_wrapper
-//
-// Description:
-//
-//
-// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#include "plugin_wrapper.h"
-
-namespace NRTB
-{
-
- plugin_wrapper::plugin_wrapper()
- {
- // Load the "constants"
- std::string name_key = "PLUGIN_NAME";
- std::string type_key = "PLUGIN_TYPE";
- std::string version_key = "PLUGIN_VERSION";
- std::string factory_key = "PLUGIN_FACTORY";
- // clear all the associated fields.
- plugin_type = "";
- plugin_name = "";
- plugin_version = 0.0;
- plugin_path = "";
- // close the handle if it's already assigned.
- if (dl_handle)
- {
- dlclose(dl_handle);
- };
- dl_handle = 0;
- };
-
- plugin_wrapper::plugin_wrapper(boost::filesystem::path loadpath)
- {
- load(loadpath);
- };
-
- plugin_wrapper::~plugin_wrapper()
- {
- // close the handle if it's already assigned.
- if (dl_handle)
- {
- dlclose(dl_handle);
- };
- dl_handle = 0;
- };
-
- void plugin_wrapper::load(boost::filesystem::path loadpath)
- {
- // establish initial conditions.
- plugin_wrapper();
- if (loadpath.empty())
- {
- // an empty path could expose security holes.
- file_not_found e;
- e.store("Illegal null path provided");
- throw e;
- };
- dlerror();
- try
- {
- // call dlopen to open the lib
- dl_handle = dlopen(loadpath.string().c_str(), RTLD_LAZY);
- if (!dl_handle)
- {
- throw new file_not_found;
- };
- // load the fields
- plugin_type = get_value<std::string>(type_key);
- plugin_name = get_value<std::string>(name_key);
- plugin_version = get_value<float>(version_key);
- plugin_path = loadpath;
- }
- catch (file_not_found &e)
- {
- // is it a missing file or a bad file?
- if (!boost::filesystem::exists(loadpath))
- {
- e.store(loadpath.string());
- throw e;
- }
- else
- {
- invalid_plugin ie;
- ie.store(dlerror());
- throw ie;
- };
- }
- catch (invalid_plugin & e)
- {
- if (e.comment() == "")
- {
- e.store(dlerror());
- };
- throw e;
- }
- catch (std::exception &e)
- {
- general_exception ge;
- ge.store(e.what());
- throw ge;
- };
- };
-
- std::string plugin_wrapper::get_type()
- {
- if (!dl_handle)
- {
- throw new not_loaded;
- };
- return plugin_type;
- };
-
- std::string plugin_wrapper::get_name()
- {
- if (!dl_handle)
- {
- throw new not_loaded;
- };
- return plugin_name;
- };
-
- float plugin_wrapper::get_version()
- {
- if (!dl_handle)
- {
- throw new not_loaded;
- };
- return plugin_version;
- };
-
- boost::filesystem::path plugin_wrapper::get_path()
- {
- if (!dl_handle)
- {
- throw new not_loaded;
- };
- return plugin_path;
- };
-
-} // namespace NRTB
=== removed file 'common/plugin_loader/plugin_wrapper.h'
--- common/plugin_loader/plugin_wrapper.h 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/plugin_wrapper.h 1970-01-01 00:00:00 +0000
@@ -1,207 +0,0 @@
-//
-// C++ Interface: plugin_wrappr
-//
-// Description:
-//
-//
-// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
-#ifndef plugin_wrapper_h
-#define plugin_wrapper_h
-
-#include <dlfcn.h>
-#include <string>
-#include <ricks_handy.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/filesystem/convenience.hpp>
-
-namespace NRTB
-{
- /**
- * A container for a single plugin. A plugin is defined as a
- * shared object file which provides a class, an associated factory
- * function, and several housekeeping constants, as follows:
- *
- * 1. A std::string identifying the class factory named "PLUGIN_FACTORY"
- *
- * 2. A plugin name std::string named "PLUGIN_NAME"
- *
- * 3. A plugin type std::stirng named "PLUGIN_TYPE"
- *
- * 4. A plugin version number float named "PLUGIN_VERSION"
- *
- * This class is not designed to instanticated directly by user code.
- * Instead, it will be intanciated by the plugin_manager, which acts as
- * a container for many plugins and provides access to them.
- *
- * In call cases except load(), when an exception is thown from a method,
- * the instance is left the state it was in at the start of the method.
- **/
- class plugin_wrapper
- {
- public:
- /// Parent for all plugin_wrapper exceptions.
- class general_exception: public base_exception {};
- /// Thrown if a file is not found at the requested path.
- class file_not_found: public general_exception {};
- /// Thrown if a requested file does not contain a valid plugin.
- class invalid_plugin: public general_exception {};
- /// Thrown if queries are called when no data is present.
- class not_loaded: public general_exception {};
- /**
- * Default constructor; NOP.
- */
- plugin_wrapper();
- /**
- * This constructor attempts to load a plugin at
- * the argument provided. Actually calls load() to
- * to do the work.
- *
- * @param loadpath Should be point to a valid plugin file
- */
- plugin_wrapper(boost::filesystem::path loadpath);
- /**
- * Unloads any plugin, if contained.
- */
- virtual ~plugin_wrapper();
- /**
- * Discards the current contents of this wrapper, if any,
- * and then attempts to load the plugin file provided. If there
- * are any problems, an appropriate exception will be thrown.
- *
- * @param loadpath Should point to a valid plugin file.
- */
- virtual void load(boost::filesystem::path loadpath);
- /**
- * Returns the pligin type associated with the loaded plugin,
- * or throws if one is not loaded. The plugin type is a string
- * indicating the what services the plugin provides and in
- * most cases will have no meaning outside of the application
- * context.
- *
- * For example, a plugin providing printing functionality
- * may have a type of "printer", while one that provides
- * database access may have a type of "db_interface".
- *
- * @return A std::string indicating plugin type.
- */
- virtual std::string get_type();
- /**
- * Returns the name of the particular plugin loaded, or
- * throws if one is not loaded. The name is an arbitrary string
- * which uniquely identifies a particular plugin within a type.
- *
- * For example, a plugin providing printing functionality to
- * a PDF file may have a type of "printer" and a name of "PDF",
- * while another "printer" plugin providing output to doc
- * files may have the name "WordDoc".
- *
- * @return A std::string indicating the plugin name.
- */
- virtual std::string get_name();
- /**
- * Returns the version of the particular plugin loaded, or
- * throws if one is not loaded. The version is an arbitrary
- * float value which uniquely identifies a particular version
- * of a plugin within a name and type.
- *
- * @return A float indicating the plugin version.
- */
- virtual float get_version();
- /**
- * Returns the fully qualified path of the plugin loaded, or
- * throws if one is not loaded.
- *
- * @return A boost::filesystem::path to the plugin file.
- */
- boost::filesystem::path get_path();
- /**
- * Calls the class factory and returns shared_ptr to an
- * instance of the type requested. For reliable operation,
- * the type provided the template must be compatable with
- * that actually implemented in the plugin.
- *
- * An appropriate exception will be thrown if there are issues.
- *
- * Usage: mytype myvar createInstance<mytype>();
- *
- * @return A boost::shared_ptr to an instanace of
- * the type provided.
- */
- template <class T> boost::shared_ptr<T> create_instance()
- {
- if (!dl_handle)
- {
- not_loaded e;
- e.store("create_instance");
- throw e;
- };
- typedef T (*factory_type)();
- typedef boost::shared_ptr<T> my_pointer;
- my_pointer returnme;
- try
- {
- factory_type factory = get_value<factory_type>(factory_key);
- returnme = factory();
- }
- catch (std::exception & e)
- {
- // Let the caller sort it out.
- throw;
- }
- catch (...)
- {
- // most likely a bad problem in the factory function.
- invalid_plugin e;
- e.store("create_instance caught an unknown exception");
- throw e;
- };
- return returnme;
- };
-
- protected:
- // gets indivdual field values from the shared lib.
- template <class T> T get_value(const std::string & key)
- {
- typedef T * my_pointer;
- T returnme;
- dlerror();
- my_pointer value = (my_pointer) dlsym(dl_handle,key.c_str());
- std::string check_error = dlerror();
- if (!check_error.empty())
- {
- invalid_plugin e;
- e.store(check_error+" ("+key+")");
- throw e;
- };
- if (!value)
- {
- invalid_plugin e;
- e.store("("+key+") returned a null value");
- throw e;
- };
- returnme = *value;
- return returnme;
- };
-
- private:
- // The following are used to cache plugin data after load.
- void * dl_handle;
- std::string plugin_type;
- std::string plugin_name;
- float plugin_version;
- boost::filesystem::path plugin_path;
- // The following define what labels are expected to be defined.
- static const std::string name_key;
- static const std::string type_key;
- static const std::string version_key;
- static const std::string factory_key;
- };
-
-} // nameplace NRTB
-
-#endif // plugin_wrapper_h
=== removed directory 'common/plugin_loader/test'
=== removed file 'common/plugin_loader/test/Makefile'
--- common/plugin_loader/test/Makefile 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/test/Makefile 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-
-# makefile for the plugin test routine.
-
-test: ../plugin_wrapper.o ../plugin_manager.o plugintest.cpp
- @rm -f plugintest
- g++ -c plugintest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
-# g++ -c -g conftest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
- g++ -o plugintest plugintest.o ../plugin_wrapper.o ../plugin_manager.o -l ricklib3 -L../../lib/
- ./plugintest
-
-clean:
- @rm -rvf *.o plugintest
- @echo all objects and executables have been erased.
=== removed directory 'common/plugin_loader/test/plugins'
=== removed file 'common/plugin_loader/test/plugintest.cpp'
--- common/plugin_loader/test/plugintest.cpp 2010-01-14 02:24:25 +0000
+++ common/plugin_loader/test/plugintest.cpp 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-//
-// C++ Implementation: plugintest
-//
-// Description:
-//
-//
-// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
-
=== modified file 'common/point/Makefile'
--- common/point/Makefile 2010-01-14 02:24:25 +0000
+++ common/point/Makefile 2011-08-02 01:34:24 +0000
@@ -1,17 +1,34 @@
-build: common_test Makefile
- @echo build complete
-
-common_test: common_test.cpp triad.h Makefile
- @rm -vf triad.o
- g++ -O3 common_test.cpp -idirafter . -o common_test
-# g++ -g common_test.cpp -idirafter . -o common_test
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: common_test Makefile
+ @echo "(2,3.5,7)" | ./common_test
+ @cp -v triad.h ../include
+ @echo nrtb::triad build complete
+
+../include/common.h:
+ @cd ../common_rl; make lib
+
+common_test: common_test.cpp triad.h Makefile ../include/common.h
+ @rm -vf common_test
+ g++ -O3 common_test.cpp -I ../include ../obj/common.o -o common_test
clean:
- @rm -vf *.o common_test ../../include3/triad.h
-
-lib: common_test ../../include3/triad.h
-
-../../include3/triad.h: triad.h
- @cp -fv triad.h ../../include3
+ @rm -vf *.o common_test ../include/triad.h
=== modified file 'common/point/common_test.cpp'
--- common/point/common_test.cpp 2010-01-14 02:24:25 +0000
+++ common/point/common_test.cpp 2011-08-02 01:34:24 +0000
@@ -1,4 +1,22 @@
-/*** Test program for triad.h *****/
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+ /*** Test program for triad.h *****/
#include <unistd.h>
#include <iostream>
@@ -7,56 +25,93 @@
using namespace std;
-typedef NRTB::triad<long double> ld_triad;
+typedef nrtb::triad<long double> ld_triad;
+
+int test_triad(const std::string prompt, ld_triad val, ld_triad right, int ec)
+{
+ cout << "\t" << prompt << " = " << val << endl;
+ if (val != right)
+ {
+ ec++;
+ cerr << "\t\tTest Failed: Answer should be " << val << endl;
+ }
+ return ec;
+};
+
+int test_ld(const std::string prompt, long double val, long double right, int ec)
+{
+ cout << "\t" << prompt << " = " << val << endl;
+ if (val != right)
+ {
+ ec++;
+ cerr << "\t\tTest Failed: Answer should be " << val << endl;
+ }
+ return ec;
+};
int main()
{
ld_triad a(1,2,3);
ld_triad b(3,2,1);
+ int returnme = 0;
cout << setprecision(10);
- cout << "=== Triad Test ===" << endl;
- cout << "\ta = " << a << "; b = " << b << "\n" << endl;
-
- cout << "\ta + b = " << a + b << endl;
- cout << "\ta - b = " << a - b << endl;
- cout << "\ta * b = " << a * b << endl;
- cout << "\ta / b = " << a / b << endl;
- cout << "\ta += b; a = " << (a += b) << endl;
- cout << "\ta -= b; a = " << (a -= b) << endl;
- cout << "\ta *= b; a = " << (a *= b) << endl;
- cout << "\ta /= b; a = " << (a /= b) << endl;
- cout << "\n\ta.pow(b) = " << a.pow(b) << endl;
- cout << "\ta.range(b) = " << a.range(b) << endl;
- cout << "\ta.magnatude() = " << a.magnatude() << endl;
- cout << "\n\ta == a = " << (a == a) << endl;
- cout << "\ta == b = " << (a== b) << endl;
- cout << "\ta != b = " << (a != b) << endl;
- cout << "\ta != a = " << (a != a) << endl;
-
- cout << endl;
-
- cout << "\ta + 2 = " << a + 2 << endl;
- cout << "\ta - 2 = " << a - 2 << endl;
- cout << "\ta * 2 = " << a * 2 << endl;
- cout << "\ta / 2 = " << a / 2 << endl;
- cout << "\ta += 2; a = " << (a += 2) << endl;
- cout << "\ta -= 2; a = " << (a -= 2) << endl;
- cout << "\ta *= 2; a = " << (a *= 2) << endl;
- cout << "\ta /= 2; a = " << (a /= 2) << endl;
- cout << "\n\ta.pow(2) = " << a.pow(2) << endl;
- cout << "\ta.pow(0.5) = " << a.pow(0.5) << endl;
+ cout << "=== nrtb::triad Unit Test ===" << endl;
+ cout << "\ta = " << a << "; b = " << b << endl;
+ // basic operations tests
+ returnme = test_triad("a + b",a + b,ld_triad(4,4,4),returnme);
+ returnme = test_triad("a - b",a - b,ld_triad(-2,0,2),returnme);
+ returnme = test_triad("a * b",a * b,ld_triad(3,4,3),returnme);
+ returnme = test_triad("a / b",a / b,ld_triad(1.0d/(long double) 3.0,1,3),returnme);
+ returnme = test_triad("a += b; a",a += b,ld_triad(4,4,4),returnme);
+ returnme = test_triad("a -= b; a",a -= b,ld_triad(1,2,3),returnme);
+ returnme = test_triad("a *= b; a",a *= b,ld_triad(3,4,3),returnme);
+ returnme = test_triad("a /= b; a",a /= b,ld_triad(1,2,3),returnme);
+ // power test
+ returnme = test_triad("a.pow(b)",a.pow(b),ld_triad(1,4,3),returnme);
+ // range test
+ ld_triad t = b - a;
+ t *= t;
+ long double r = sqrt(t.x + t.y + t.z);
+ returnme = test_ld("a.range(b)",a.range(b),r,returnme);
+ // magnatude test
+ returnme = test_ld("a.magnatude()",a.magnatude(),a.range(0),returnme);
+ // boolean tests
+ returnme = test_ld("a == a",a == a,1,returnme);
+ returnme = test_ld("a == b",a == b,0,returnme);
+ returnme = test_ld("a != b",a != b,1,returnme);
+ returnme = test_ld("a != a",a != a,0,returnme);
+ // point/scalar operations
+ returnme = test_triad("a + 2",a + 2,ld_triad(3,4,5),returnme);
+ returnme = test_triad("a - 2",a - 2,ld_triad(-1,0,1),returnme);
+ returnme = test_triad("a * 2",a * 2,ld_triad(2,4,6),returnme);
+ returnme = test_triad("a / 2",a / 2,ld_triad(0.5,1,1.5),returnme);
+ returnme = test_triad("a += 2",a += 2,ld_triad(3,4,5),returnme);
+ returnme = test_triad("a -= 2",a -= 2,ld_triad(1,2,3),returnme);
+ returnme = test_triad("a *= 2",a *= 2,ld_triad(2,4,6),returnme);
+ returnme = test_triad("a /= 2",a /= 2,ld_triad(1,2,3),returnme);
+ returnme = test_triad("a.pow(2)",a.pow(2),ld_triad(1,4,9),returnme);
+ // normalization test
cout << "\ta.normalize() = " << a.normalize() << endl;
- cout << "\ta.normalize().magnatude() = "<< a.normalize().magnatude() << endl;
-
- cout << "\n\a\tInput a new value for b (x,y,z): " << flush;
- cin >> b;
- cout << "\t\tb = " << b << endl;
- cout << "\tb.to_str() =\"" << b.to_str() << "\"" << endl;
- cout << "\tb.from_str(b.to_str(10)) = " << b.from_str(b.to_str(10)) << endl;
-
-
- cout << "\n=== Test Complete ===" << endl;
- return 0;
+ returnme = test_ld("a.normalize().magnatude()",a.normalize().magnatude(),1.0,returnme);
+ // dot and vector product tests.
+ returnme = test_ld("a.dot_product(b)",a.dot_product(b),10,returnme);
+ returnme = test_triad("a.vector_product(b)",a.vector_product(b),
+ ld_triad(-4,8,-4),returnme);
+ // string i/o tests, assumes "2,3.5,7) is input.
+ cout << "\tInput a new value for b \"(2,3.5,7)\": " << flush;
+ cin >> b; cout << endl;
+ returnme = test_triad("b",b,ld_triad(2,3.5,7),returnme);
+ returnme = test_triad("b.from_str(b.to_str(10))",
+ b.from_str(b.to_str(10)),ld_triad(2,3.5,7),returnme);
+ // report errors, if any
+ if (returnme)
+ {
+ cerr << "There were " << returnme
+ << " error(s) found." << endl;
+ }
+ cout << "=== nrtb::triad Unit Test Complete ===" << endl;
+ // return the error count as the exit code
+ return returnme;
};
=== modified file 'common/point/triad.h'
--- common/point/triad.h 2010-01-14 02:24:25 +0000
+++ common/point/triad.h 2011-08-02 01:34:24 +0000
@@ -1,31 +1,40 @@
-/*************************************************************
-**** CODE REVIEW: triad.h, starting 2008-11-24 ***************
-* The triad template is fully implemented in this one file.
-* This class will be used for all vector and point operations
-* Please make any comments or suggestions directly in the file.
-*************************************************************/
-
-/**************************************************
-TODO: add methods for dot product, cross multiply,
- finding the surface normal, etc.
-/**************************************************
-
-#ifndef nrtb_triad_header
-#define nrtb_triad_header
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef triad_header
+#define triad_header
#include <iostream>
+#include <vector>
+#include <string>
#include <sstream>
#include <iomanip>
#include <math.h>
+#include <common.h>
-namespace NRTB
+namespace nrtb
{
/** Template defining a point or vector in cartesian 3d space. Should work
** with all floating point types.
**
** Implements the following operators: +,=,*,/,+=,-=,*=,/= for both
- ** triad<T> and <T> arguments; each returns a triad as the result.
+ ** triad<T> and <T> arguments; each returns an triad as the result.
** ==,!=,>>,<< are implemented for triad arguments. Additionally
** implements pow() with triad and T arguments. Finally implements range()
** which returns the distance between the triad and one supplied, and
@@ -76,13 +85,17 @@
** is not modified.
**
** Normalized triads are very useful when calcuating force or
- ** accelleration vectors and in many other cases.
+ ** accelleration vectors, for example.
**/
triad<T> normalize();
/// Returns the distance between *this and the supplied argument.
T range(const triad<T> & a);
/// Returns the magnatude of the vector.
T magnatude();
+ /// Returns the dot (scalar) product of two triads
+ T dot_product(const triad<T> & a);
+ /// Returns the vector product of two triads
+ triad<T> vector_product(const triad<T> & a);
bool operator == (const triad<T> & a);
bool operator != (const triad<T> & a);
/// Loads from a std::string.
@@ -292,6 +305,26 @@
};
template <class T>
+T triad<T>::dot_product(const triad<T> & a)
+{
+ T returnme;
+ returnme = x * a.x;
+ returnme += y * a.y;
+ returnme += z * a.z;
+ return returnme;
+};
+
+template <class T>
+triad<T> triad<T>::vector_product(const triad<T> & a)
+{
+ triad<T> rv;
+ rv.x = (y * a.z) - (z * a.y);
+ rv.y = (z * a.x) - (x * a.z);
+ rv.z = (x * a.y) - (y * a.x);
+ return rv;
+};
+
+template <class T>
bool triad<T>::operator == (const triad<T> & a)
{
return ((x == a.x) && (y == a.y) && (z == a.z));
@@ -329,16 +362,11 @@
return f;
};
- //?? Review question: should we have the read operator
- // throw instead of defaulting to (0,0,0) on a bad read?
- // A: No, because this is the same behavior the read
- // operator exhibits with other numeric types.
-
/** Reads the triad<T> from an input stream.
**
** The acceptable format is [(]x,y,z[)]. Any other format will result
** in the triad<T> being set to (0,0,0). Any numeric format acceptable
- ** to an iostream is valid for x, y and z. Any other represention of x,
+ ** to strtod() is valid for x, y and z. Any other represention of x,
** y or z will result in that particular value being set to 0.
**/
template <class T>
@@ -346,8 +374,7 @@
{
std::string element;
f >> element;
- //TODO: Need to replace split with boost equivelent
- std::vector<std::string> t = split(element,',');
+ strlist t = split(element,',');
if (t.size() != 3)
{
a = 0;
@@ -363,6 +390,6 @@
return f;
};
-} // namespace NRTB
+} // namespace nrtb
-#endif // nrtb_triad_header
+#endif // triad_header
=== added directory 'common/serializer'
=== added file 'common/serializer/Makefile'
--- common/serializer/Makefile 1970-01-01 00:00:00 +0000
+++ common/serializer/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,36 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: serializer_test
+ @./serializer_test
+ @cp -v serializer.h ../include
+ @cp -v serializer.o ../obj
+ @echo build complete
+
+serializer.o: serializer.h serializer.cpp Makefile
+ @rm -f serializer.o
+ g++ -c serializer.cpp -I ../include
+
+serializer_test: serializer.o serializer_test.cpp
+ @rm -f serializer_test
+ g++ -c serializer_test.cpp -I../include
+ g++ -o serializer_test serializer_test.o serializer.o ../obj/base_thread.o -lpthread ../obj/common.o
+
+clean:
+ @rm -rvf *.o serializer_test ../include/serializer.h ../obj/serializer.o
+ @echo all objects and executables have been erased.
=== added file 'common/serializer/serializer.cpp'
--- common/serializer/serializer.cpp 1970-01-01 00:00:00 +0000
+++ common/serializer/serializer.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,43 @@
+/***********************************************
+ T his file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "serializer.h"
+#include <base_thread.h>
+
+using namespace nrtb;
+
+nrtb::serializer::serializer()
+{
+ counter = 0;
+};
+
+nrtb::serializer::serializer(unsigned long long start)
+{
+ counter = start;
+};
+
+serializer::~serializer()
+{
+ // nop destructor
+};
+
+unsigned long long serializer::operator()()
+{
+ nrtb::scope_lock mylock(lock);
+ return counter++;
+}
=== added file 'common/serializer/serializer.h'
--- common/serializer/serializer.h 1970-01-01 00:00:00 +0000
+++ common/serializer/serializer.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,50 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef nrtb_serializer_h
+#define nrtb_serializer_h
+#include <base_thread.h>
+
+namespace nrtb
+{
+ /******************************************************************
+ * nrtb::serializer provides a simple, thread safe functor which
+ * returns a series of long long ints increasing by one each time
+ * it's called. By default it starts counting from zero, but may
+ * be started from any arbitrary integer in the range
+ * 0 < x < max long long.
+ * ***************************************************************/
+ class serializer
+ {
+ public:
+ // default constructor; counter starts from zero.
+ serializer();
+ // constructor which sets the starting number.
+ serializer(unsigned long long start);
+ // NOP distructor for inheritance safety
+ ~serializer();
+ // functor method, returns the next value in the sequence.
+ unsigned long long operator ()();
+ private:
+ nrtb::mutex lock;
+ unsigned long long int counter;
+ };
+
+}
+
+#endif // nrtb_serializer_h
\ No newline at end of file
=== added file 'common/serializer/serializer_test.cpp'
--- common/serializer/serializer_test.cpp 1970-01-01 00:00:00 +0000
+++ common/serializer/serializer_test.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,56 @@
+/***********************************************
+ T his file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "serializer.h"
+#include <iostream>
+
+using namespace nrtb;
+using namespace std;
+
+int main()
+{
+ cout << "** nrtb::serializer unit test **" << endl;
+ bool set_if_failed = false;
+ serializer set_default;
+ serializer set_start(20);
+ serializer rollover((unsigned long long)(0 - 1));
+ cout << "Default initialization" << endl;
+ cout << " " << set_default();
+ cout << " " << set_default();
+ cout << " " << set_default();
+ cout << endl;
+ if (set_default() != 3)
+ set_if_failed = true;
+ cout << "Started from twenty" << endl;
+ cout << " " << set_start();
+ cout << " " << set_start();
+ cout << " " << set_start();
+ cout << endl;
+ if (set_start() != 23)
+ set_if_failed = true;
+ cout << "Rollover Demonstration" << endl;
+ cout << " " << rollover();
+ cout << " " << rollover();
+ cout << " " << rollover();
+ cout << endl;
+ if (rollover() != 2)
+ set_if_failed = true;
+ if (set_if_failed)
+ cout << "UNIT TEST FAILED" << endl;
+ return set_if_failed;
+};
\ No newline at end of file
=== removed directory 'common/singleton'
=== removed file 'common/singleton/Makefile'
--- common/singleton/Makefile 2010-01-14 02:24:25 +0000
+++ common/singleton/Makefile 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
-
-build: singleton_test
- @echo build complete
-
-singleton_test: singleton_test.cpp Makefile
- @rm -f singleton_test
- g++ -c singleton_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
-# g++ -c -g singleton_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
- g++ -o singleton_test singleton_test.o -lricklib3 -lpthread -lssl -L../../lib/
-
-clean:
- @rm -rvf *.o singleton_test ../../include3/singleton.h
- @echo all objects and executables have been erased.
-
-lib: ../../include3/singleton.h
-
-../../include3/singleton.h: singleton.h
- @cp -fv singleton.h ../../include3
=== removed file 'common/singleton/singleton.h'
--- common/singleton/singleton.h 2010-01-14 02:24:25 +0000
+++ common/singleton/singleton.h 1970-01-01 00:00:00 +0000
@@ -1,110 +0,0 @@
-/* implements a template that takes any class provided and
- * creates a singleton for it.
- *
- * fps 2002-5-29
- */
-
-/*
- TODO: Alter to use boost::threads mutexes.
-*/
-
-
-#ifndef NRTB_singleton_h
-#define NRTB_singleton_h
-
-#include <boost/thread>
-
-namespace NRTB
-{
-
-/** Wrapper template to create singleton classes.
- **
- ** Classic Singleton pattern template, with thread-safe
- ** methods for getting an instance and destruction.
- **
- ** Singletons are classes that:
- ** (1) Insure that there are no more than one instance of the
- ** class at any time.
- ** (2) Allocate themselves automagically when accessed for the
- ** first time.
- ** (3) Provide a globally available access method to allow any
- ** scope to gain access and use the instance.
- **
- ** This template can create a singleton version of any class that has a
- ** no-argument constructor. The resulting class will have the same
- ** inteface as the object used to create the template with the constructor
- ** and destructor made protected and the addition of the get_instance()
- ** and delete_me() methods.
- **
- ** See the documentation on the get_instance() and delete_me() methods for
- ** usage.
- **/
-template <class T, int mytag=0>
-class singleton: public T
-{
- private:
- static mutex __mylock;
- static singleton * __me;
- protected:
- singleton() : T() {};
- virtual ~singleton() {};
- singleton(const singleton &) {};
- public:
- /** Used to access the object.
- **
- ** Returns a reference to the instanciated singleton object. If
- ** the object has not been accessed before, the object will be
- ** instanciated automatically.
- **
- ** As is usual for the method that provides access to a singleton,
- ** this method is static, allowing it to be called via the class
- ** name as shown. Remember you can only assign the return value to
- ** a reference:
- **
- ** mytype & a = mytype::get_instance();
- **
- ** Attempts to make a copy of the instance should throw a compiler
- ** error.
- **
- ** This method is thread safe, but that does not imply that the
- ** class returned is thread-safe overall; that would depend on the
- ** implementation of the class used to instaciate the template.
- **/
- static singleton & get_instance()
- {
- // First test avoids expensive mutex cycle
- // if the object is already allocated.
- if (!__me)
- {
- scope_lock lock(__mylock);
- // second test required in case multiple threads
- // get past the first check.
- if (!__me)
- {
- __me = new singleton;
- };
- };
- return *__me;
- };
-
- /** Destructs and deallocates the singleton object.
- **
- ** After a call to this method, the singleton object will
- ** be destructed and deallocated from memory. However, it
- ** will be automatically reconstruted and allocated if
- ** get_instance() called at any time afterword.
- **/
- void delete_me()
- {
- scope_lock lock(__mylock);
- if (__me) delete __me;
- __me = 0;
- };
-};
-
-template <class T, int mytag> mutex singleton<T,mytag>::__mylock;
-template <class T, int mytag> singleton<T,mytag> * singleton<T,mytag>::__me = 0;
-
-} // namespace NRTB;
-
-#endif // NRTB_singleton_h
=== removed file 'common/singleton/singleton_test.cpp'
--- common/singleton/singleton_test.cpp 2010-01-14 02:24:25 +0000
+++ common/singleton/singleton_test.cpp 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-// singleton template test program
-
-
-#include <http_page.h>
-#include "singleton.h"
-#include <iostream>
-
-using namespace NRTB;
-using namespace std;
-
-int main()
-{
- typedef singleton<http_page> p_type;
-
- {
- p_type & getter = p_type::get_instance();
-
- cout << "newly initialized code: " << getter.result_code() << endl;
-
- getter.get("127.0.0.1:80","/");
- };
-
- cout << "first response code: " << p_type::get_instance().result_code()
- << endl;
-
- p_type::get_instance().get("127.0.0.1:80","/not_there.html");
-
- cout << "second response code: " << p_type::get_instance().result_code()
- << endl;
-
- p_type::get_instance().delete_me();
-};
=== modified file 'common/timer/Makefile'
--- common/timer/Makefile 2010-01-14 02:24:25 +0000
+++ common/timer/Makefile 2011-08-02 01:34:24 +0000
@@ -1,147 +1,36 @@
-# This file was automatically generated by makemake.
-# Do not edit it directly!
-# Any changes you make will be silently overwritten.
-
-# Edit this file to define constants and custom build targets.
-# Please refer to the makemake documentation for more information.
-#
-# To compile multiple versions of a program or library, please study
-# http://www.its.caltech.edu/~jafl/jcc/multi_version.html
-
-# Useful directories
-
-MYCODEDIR := .
-
-# Directories to search for header files
-
-SEARCHDIRS := -I- -I${MYCODEDIR}
-
-# makemake variables
-
-DEPENDFLAGS := -O3 -Wall -Werror ${SEARCHDIRS}
-
-# C preprocessor (C, C++, FORTRAN)
-
-CPPFLAGS =
-
-# C compiler
-
-CC := gcc
-CFLAGS = ${DEPENDFLAGS}
-
-%.o : %.c
- ${CC} ${CPPFLAGS} ${CFLAGS} -c $< -o $@
-
-# C++ compiler
-
-CXX := g++
-CXXFLAGS = ${DEPENDFLAGS}
-
-%.o : %.cc
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.C
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.cpp
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.cxx
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-# FORTRAN compiler
-
-FC := f77
-FFLAGS =
-
-# C/C++/Eiffel/FORTRAN linker
-
-LINKER := g++
-LDFLAGS =
-LOADLIBES := -lm
-
-# Java compiler
-
-JAVAC := javac
-JFLAGS =
-JAR := jar
-
-%.class : %.java
- ${JAVAC} ${JFLAGS} $<
-
-
-# This is what makemake added
-
-
-# timer_test
-
-timer_test : ./nrtb_timer.o ./timer_test.o
- ${LINKER} ${LDFLAGS} -o $@ ${filter-out %.a %.so, $^} ${LOADLIBES}
-
-# target for making everything
-
-.PHONY : all
-all: timer_test
-
-.PHONY : lib
-lib: nrtb_timer.o ../../include/nrtb_timer.h
- @ar -r ../../lib/libnrtb.a nrtb_timer.o
- @echo nrtb_timer has been added to the library
-
-../../include/nrtb_timer.h: nrtb_timer.h
- @cp -fv nrtb_timer.h ../../include
-
-# target for removing all object files
-
-.PHONY : tidy
-tidy::
- @rm -fv core ./nrtb_timer.o ./timer_test.o
-
-# target for removing all object files
-
-.PHONY : clean
-clean:: tidy
- @rm -rf timer_test ../../include/nrtb_timer.h
- @ar -d ../../lib/libnrtb.a nrtb_timer.o
- @echo "nrtb_timers has been removed from the library"
-
-
-# list of all source files
-
-MM_ALL_SOURCES := ./nrtb_timer.cpp ./timer_test.cpp
-
-
-# target for checking a source file
-
-CHECKSYNTAXFILE := ${basename ${filter %${CHECKSTRING}, ${MM_ALL_SOURCES}}}
-
-.PHONY : checksyntax
-checksyntax:
- ifneq (${CHECKSYNTAXFILE},)
- @${MAKE} ${addsuffix .o, ${CHECKSYNTAXFILE}}
- else
- @echo No target to make ${CHECKSTRING}
- endif
-
-
-# target for touching appropriate source files
-
-.PHONY : touch
-touch::
- @list=$$(grep -l ${TOUCHSTRING} ${MM_ALL_SOURCES}); \
- for file in $$list; do { echo $$file; touch $$file; } done
-
-
-# target for calculating dependencies (MAKEMAKE)
-
-.PHONY : jdepend
-jdepend:
- @${MAKEMAKE} --depend Makefile -- ${DEPENDFLAGS} -- ./nrtb_timers.cpp ./nrtb_timer.o ./timer_test.cpp ./timer_test.o
-
-
-# DO NOT DELETE THIS LINE -- makemake depends on it.
-
-./nrtb_timer.o: ./nrtb_timer.h /usr/include/math.h /usr/include/sys/time.h
-
-./timer_test.o: ./nrtb_timer.h /usr/include/sys/time.h /usr/include/unistd.h
-
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: timer_test
+ @./timer_test
+ @cp -v hires_timer.h ../include
+ @cp -v hires_timer.o ../obj
+ @echo build complete
+
+hires_timer.o: hires_timer.h hires_timer.cpp Makefile
+ @rm -f hires_timer.o
+ g++ -c -O3 hires_timer.cpp
+
+timer_test: hires_timer.o timer_test.cpp
+ @rm -f timer_test
+ g++ -c timer_test.cpp
+ g++ -o timer_test timer_test.o hires_timer.o
+
+clean:
+ @rm -rvf *.o timer_test ../include/hires_timer.h ../obj/hires_timer.o
+ @echo all objects and executables have been erased.
=== added file 'common/timer/hires_timer.cpp'
--- common/timer/hires_timer.cpp 1970-01-01 00:00:00 +0000
+++ common/timer/hires_timer.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,174 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+/* see ricklib_timers.h for whatever documentation you can find */
+#include "hires_timer.h"
+#include <math.h>
+#include <sstream>
+
+namespace nrtb
+{
+
+hirez_timer::hirez_timer(const double init)
+{
+ reset();
+ start(init);
+};
+
+hirez_timer::hirez_timer(const timeval & init)
+{
+ reset();
+ start(init);
+};
+
+void hirez_timer::reset()
+{
+ running = false;
+ starttime = 0;
+ elapsed = 0;
+};
+
+void hirez_timer::start(const double init)
+{
+ if (!running)
+ {
+ timeval startt;
+ gettimeofday(&startt,0);
+ starttime = tv_to_ll(startt);
+ if (init > 0)
+ {
+ starttime -= double_to_ll(init);
+ };
+ };
+ running = true;
+};
+
+void hirez_timer::start(const timeval & init)
+{
+ starttime = tv_to_ll(init);
+ running = true;
+};
+
+double hirez_timer::stop()
+{
+ stop_timer();
+ return ll_to_double(elapsed);
+};
+
+unsigned long long hirez_timer::stop_as_usec()
+{
+ stop_timer();
+ return elapsed;
+};
+
+double hirez_timer::interval()
+{
+ return ll_to_double(interval_time());
+};
+
+unsigned long long hirez_timer::interval_as_usec()
+{
+ return interval_time();
+};
+
+tm hirez_timer::interval_as_tm()
+{
+ time_t temp = (interval_time()+500000)/1000000;
+ return *gmtime(&temp);
+};
+
+double hirez_timer::ll_to_double(const unsigned long long int ll)
+{
+ return ll / (double) 1e6;
+};
+
+timeval hirez_timer::ll_to_tv(const unsigned long long int ll)
+{
+ timeval t;
+ t.tv_sec = ll / (unsigned long long int) 1e6;
+ t.tv_usec = ll % (unsigned long long int) 1e6;
+ return t;
+};
+
+unsigned long long int hirez_timer::tv_to_ll(const timeval & tv)
+{
+ return ((unsigned long long) tv.tv_sec * (unsigned long long) 1e6)
+ + (unsigned long long) tv.tv_usec;
+};
+
+unsigned long long int hirez_timer::double_to_ll(const double d)
+{
+ return (unsigned long long int) floor(d * 1e6);
+};
+
+void hirez_timer::stop_timer()
+{
+ if (running)
+ {
+ timeval endtime;
+ gettimeofday(&endtime,0);
+ elapsed += (tv_to_ll(endtime) - starttime);
+ };
+ running = false;
+};
+
+unsigned long long int hirez_timer::interval_time()
+{
+ if (running)
+ {
+ timeval endtime;
+ gettimeofday(&endtime,0);
+ return elapsed + (tv_to_ll(endtime) - starttime);
+ }
+ else
+ {
+ return elapsed;
+ };
+};
+
+std::string hirez_timer::interval_as_HMS(const bool days)
+{
+ // local working vars.
+ std::stringstream output;
+ double t1;
+ long int t2;
+ t1 = interval();
+ // Days (only if needed)
+ if (days)
+ {
+ t2 = long(t1) / 86400l;
+ if (t2 > 0)
+ {
+ output << t2 << "d, ";
+ t1 -= t2 * 86400l;
+ };
+ };
+ // hours
+ t2 = long(t1) / 3600;
+ output << t2;
+ t1 -= t2 * 3600;
+ // minutes
+ t2 = long(t1) / 60;
+ output << ((t2 < 10) ? ":0" : ":") << t2;
+ t1 -= t2 * 60;
+ // seconds
+ output << ((t1 < 10) ? ":0" : ":") << t1;
+ return output.str();
+};
+
+} // namespace ricklib;
+
=== added file 'common/timer/hires_timer.h'
--- common/timer/hires_timer.h 1970-01-01 00:00:00 +0000
+++ common/timer/hires_timer.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,131 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+#ifndef nrtb_timer_h
+#define nrtb_timer_h
+
+#include <sys/time.h>
+#include <time.h>
+#include <string>
+
+namespace nrtb
+{
+
+/** Provides a timer with microsecond (1e-6 second) resolution.
+ **
+ ** Actual resolution on x86 machines is probably closer to 1e-4 or
+ ** -5, but it's still pretty good.
+ **
+ ** Usage notes: instanciating this class will start the timer
+ ** automagically.
+ **/
+class hirez_timer
+{
+ public:
+ /** initializes the timer and starts it.
+ **
+ ** Sets the the timer's elapsed time to init number of seconds and
+ ** then starts the timer.
+ **/
+ hirez_timer(const double init = 0);
+ /** initalizes the timer and starts it.
+ **
+ ** The timer's elapsed time is set to match the value provided in
+ ** init, and the timer is started.
+ **/
+ hirez_timer(const timeval & init);
+
+ /** Clears the timer.
+ **
+ ** If the timer is running, this stops it as well.
+ **/
+ void reset();
+ /** Starts the timer.
+ **
+ ** Starts the timer, and optionally sets the elapsed time at
+ ** startup to the value provided in init.
+ **/
+ void start(const double init = 0);
+ /** Starts the timer.
+ **
+ ** Sets the elapsed time equal to the value provided in init
+ ** and then starts the timer.
+ **/
+ void start(const timeval & init);
+ /** Stops the timer.
+ **
+ ** Unconditionally stops the timer, preserving the current
+ ** values. It may be restarted using the start() method,
+ ** acummulating from where is stopped.
+ **
+ ** Returns the elapsed time in seconds.
+ **/
+ double stop();
+ /** Stops the timer.
+ ** Unconditionally stops the timer, preserving the current
+ ** values. It may be restarted using the start() method,
+ ** acummulating from where is stopped.
+ **
+ ** The return value is the elapsed time in microseconds
+ ** (1e-6 seconds).
+ **/
+ unsigned long long stop_as_usec();
+ /** Returns the current elapsed time.
+ **
+ ** Returns the number of elapsed seconds on the timer. No change
+ ** is made to the timer's status.
+ **/
+ double interval();
+ /** Returns the current elapsed time.
+ **
+ ** Returns the elapsed time in microseconds (1e-6 seconds). No
+ ** change is made to the timer's status.
+ **/
+ unsigned long long interval_as_usec();
+ /** Returns the elapsed time in a tm struct.
+ **
+ ** See "man gmtime" for the structure of the tm struct. In short
+ ** though, this method provides the current timer value in a
+ ** structure where it's broken down into hours, minutes, seconds and
+ ** the like. No change is made to the timer's status.
+ **/
+ tm interval_as_tm();
+ /** Returns the elapsed time in H:MM:SS format
+ **
+ ** Returns the elapsed time in a std::string. The formate is
+ ** H:MM:SS.sssss. No change is made to the timer's status.
+ ** If the optional days parameter is set to true, the number
+ ** of days will be displayed and hours will be < 24, otherwise
+ ** no days are shown and hours will grow as needed (default).
+ **/
+ std::string interval_as_HMS(const bool days = false);
+ private:
+ unsigned long long int starttime;
+ unsigned long long int elapsed;
+ bool running;
+
+ inline double ll_to_double(const unsigned long long int ll);
+ inline timeval ll_to_tv(const unsigned long long int ll);
+ inline unsigned long long int double_to_ll(const double d);
+ inline unsigned long long int tv_to_ll(const timeval & tv);
+ inline void stop_timer();
+ inline unsigned long long int interval_time();
+};
+
+}; // namespace nrtb
+
+#endif // nrtb_timer_h
=== removed file 'common/timer/nrtb_timer.cpp'
--- common/timer/nrtb_timer.cpp 2010-01-14 02:24:25 +0000
+++ common/timer/nrtb_timer.cpp 1970-01-01 00:00:00 +0000
@@ -1,158 +0,0 @@
-/* see nrtb_timer.h for whatever documentation you can find */
-
-#include <nrtb_timer.h>
-#include <math.h>
-#include <sstream>
-
-namespace NRTB
-{
-
-hirez_timer::hirez_timer(const double init)
-{
- reset();
- start(init);
-};
-
-hirez_timer::hirez_timer(const timeval & init)
-{
- reset();
- start(init);
-};
-
-void hirez_timer::reset()
-{
- running = false;
- starttime = 0;
- elapsed = 0;
-};
-
-void hirez_timer::start(const double init)
-{
- if (!running)
- {
- timeval startt;
- gettimeofday(&startt,0);
- starttime = tv_to_ll(startt);
- if (init > 0)
- {
- starttime -= double_to_ll(init);
- };
- };
- running = true;
-};
-
-void hirez_timer::start(const timeval & init)
-{
- starttime = tv_to_ll(init);
- running = true;
-};
-
-double hirez_timer::stop()
-{
- stop_timer();
- return ll_to_double(elapsed);
-};
-
-unsigned long long hirez_timer::stop_as_usec()
-{
- stop_timer();
- return elapsed;
-};
-
-double hirez_timer::interval()
-{
- return ll_to_double(interval_time());
-};
-
-unsigned long long hirez_timer::interval_as_usec()
-{
- return interval_time();
-};
-
-tm hirez_timer::interval_as_tm()
-{
- time_t temp = (interval_time()+500000)/1000000;
- return *gmtime(&temp);
-};
-
-double hirez_timer::ll_to_double(const unsigned long long int ll)
-{
- return ll / (double) 1e6;
-};
-
-timeval hirez_timer::ll_to_tv(const unsigned long long int ll)
-{
- timeval t;
- t.tv_sec = ll / (unsigned long long int) 1e6;
- t.tv_usec = ll % (unsigned long long int) 1e6;
- return t;
-};
-
-unsigned long long int hirez_timer::tv_to_ll(const timeval & tv)
-{
- return ((unsigned long long) tv.tv_sec * (unsigned long long) 1e6)
- + (unsigned long long) tv.tv_usec;
-};
-
-unsigned long long int hirez_timer::double_to_ll(const double d)
-{
- return (unsigned long long int) floor(d * 1e6);
-};
-
-void hirez_timer::stop_timer()
-{
- if (running)
- {
- timeval endtime;
- gettimeofday(&endtime,0);
- elapsed += (tv_to_ll(endtime) - starttime);
- };
- running = false;
-};
-
-unsigned long long int hirez_timer::interval_time()
-{
- if (running)
- {
- timeval endtime;
- gettimeofday(&endtime,0);
- return elapsed + (tv_to_ll(endtime) - starttime);
- }
- else
- {
- return elapsed;
- };
-};
-
-std::string hirez_timer::interval_as_HMS(const bool days)
-{
- // local working vars.
- std::stringstream output;
- double t1;
- long int t2;
- t1 = interval();
- // Days (only if needed)
- if (days)
- {
- t2 = long(t1) / 86400l;
- if (t2 > 0)
- {
- output << t2 << "d, ";
- t1 -= t2 * 86400l;
- };
- };
- // hours
- t2 = long(t1) / 3600;
- output << t2;
- t1 -= t2 * 3600;
- // minutes
- t2 = long(t1) / 60;
- output << ((t2 < 10) ? ":0" : ":") << t2;
- t1 -= t2 * 60;
- // seconds
- output << ((t1 < 10) ? ":0" : ":") << t1;
- return output.str();
-};
-
-} // namespace NRTB;
-
=== removed file 'common/timer/nrtb_timer.h'
--- common/timer/nrtb_timer.h 2010-01-14 02:24:25 +0000
+++ common/timer/nrtb_timer.h 1970-01-01 00:00:00 +0000
@@ -1,115 +0,0 @@
-
-#ifndef nrtb_timer_h
-#define nrtb_timer_h
-
-#include <sys/time.h>
-#include <time.h>
-#include <string>
-
-namespace NRTB
-{
-
-/** Provides a timer with microsecond (1e-6 second) resolution.
- **
- ** Actual resolution on x86 machines is probably closer to 1e-4 or
- ** -5, but it's still pretty good.
- **
- ** Usage notes: instanciating this class will start the timer
- ** automagically.
- **/
-class hirez_timer
-{
- public:
- /** initializes the timer and starts it.
- **
- ** Sets the the timer's elapsed time to init number of seconds and
- ** then starts the timer.
- **/
- hirez_timer(const double init = 0);
- /** initalizes the timer and starts it.
- **
- ** The timer's elapsed time is set to match the value provided in
- ** init, and the timer is started.
- **/
- hirez_timer(const timeval & init);
-
- /** Clears the timer.
- **
- ** If the timer is running, this stops it as well.
- **/
- void reset();
- /** Starts the timer.
- **
- ** Starts the timer, and optionally sets the elapsed time at
- ** startup to the value provided in init.
- **/
- void start(const double init = 0);
- /** Starts the timer.
- **
- ** Sets the elapsed time equal to the value provided in init
- ** and then starts the timer.
- **/
- void start(const timeval & init);
- /** Stops the timer.
- **
- ** Unconditionally stops the timer, preserving the current
- ** values. It may be restarted using the start() method,
- ** acummulating from where is stopped.
- **
- ** Returns the elapsed time in seconds.
- **/
- double stop();
- /** Stops the timer.
- ** Unconditionally stops the timer, preserving the current
- ** values. It may be restarted using the start() method,
- ** acummulating from where is stopped.
- **
- ** The return value is the elapsed time in microseconds
- ** (1e-6 seconds).
- **/
- unsigned long long stop_as_usec();
- /** Returns the current elapsed time.
- **
- ** Returns the number of elapsed seconds on the timer. No change
- ** is made to the timer's status.
- **/
- double interval();
- /** Returns the current elapsed time.
- **
- ** Returns the elapsed time in microseconds (1e-6 seconds). No
- ** change is made to the timer's status.
- **/
- unsigned long long interval_as_usec();
- /** Returns the elapsed time in a tm struct.
- **
- ** See "man gmtime" for the structure of the tm struct. In short
- ** though, this method provides the current timer value in a
- ** structure where it's broken down into hours, minutes, seconds and
- ** the like. No change is made to the timer's status.
- **/
- tm interval_as_tm();
- /** Returns the elapsed time in H:MM:SS format
- **
- ** Returns the elapsed time in a std::string. The formate is
- ** H:MM:SS.sssss. No change is made to the timer's status.
- ** If the optional days parameter is set to true, the number
- ** of days will be displayed and hours will be < 24, otherwise
- ** no days are shown and hours will grow as needed (default).
- **/
- std::string interval_as_HMS(const bool days = false);
- private:
- unsigned long long int starttime;
- unsigned long long int elapsed;
- bool running;
-
- inline double ll_to_double(const unsigned long long int ll);
- inline timeval ll_to_tv(const unsigned long long int ll);
- inline unsigned long long int double_to_ll(const double d);
- inline unsigned long long int tv_to_ll(const timeval & tv);
- inline void stop_timer();
- inline unsigned long long int interval_time();
-};
-
-}; // namespace NRTB
-
-#endif // nrtb_timer_h
=== modified file 'common/timer/timer_test.cpp'
--- common/timer/timer_test.cpp 2010-01-14 02:24:25 +0000
+++ common/timer/timer_test.cpp 2011-08-02 01:34:24 +0000
@@ -1,40 +1,72 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
/* hirez_timer test program */
#include <iostream>
#include <unistd.h>
-#include <nrtb_timer.h>
+#include "hires_timer.h"
-using namespace NRTB;
+using namespace nrtb;
using namespace std;
int main()
{
hirez_timer overall;
hirez_timer interval;
- overall.start();
- interval.start();
- cout << "sleep 1 second" << endl;
- sleep(1);
- cout << overall.interval() << " | " << interval.stop() << " (stop)" << endl;
- cout << "sleep 3 seconds" << endl;
- sleep(3);
- cout << overall.interval() << " | " << interval.stop() << " (start)" << endl;
- interval.start();
- cout << "sleep 2 seconds" << endl;
- sleep(2);
- cout << overall.interval() << " | " << interval.stop() << " (reset)" << endl;
- interval.reset();
- interval.start();
- cout << "sleep 500000 useconds" << endl;
- usleep(500000);
- cout << overall.interval() << " | " << interval.stop() << endl;
- // test the advanced formationg function
- interval.start(109472.34);
- interval.stop();
- cout << "Extended interval_as_HMS() test: \""
- << interval.interval_as_HMS(true)
- << "\" or \"" << interval.interval_as_HMS() << "\"" << endl;
- cout << "Total run time: " << overall.interval() << " seconds." << endl;
- return 0;
+ int returnme = 0;
+ try
+ {
+ overall.start();
+ interval.start();
+ cout << "sleep 0.1 second" << endl;
+ usleep(1e5);
+ cout << overall.interval() << " | " << interval.stop() << " (stop)" << endl;
+ cout << "sleep 0.3 seconds" << endl;
+ usleep(3e5);
+ cout << overall.interval() << " | " << interval.stop() << " (start)" << endl;
+ interval.start();
+ cout << "sleep 0.2 seconds" << endl;
+ usleep(2e5);
+ cout << overall.interval() << " | " << interval.stop() << " (reset)" << endl;
+ interval.reset();
+ interval.start();
+ cout << "sleep 0.5 seconds" << endl;
+ usleep(5e5);
+ cout << overall.interval() << " | " << interval.stop() << endl;
+ // test the advanced formationg function
+ interval.start(109472.34);
+ interval.stop();
+ cout << "Extended interval_as_HMS() test: \""
+ << interval.interval_as_HMS(true)
+ << "\" or \"" << interval.interval_as_HMS() << "\"" << endl;
+ cout << "Total run time: " << overall.stop() << " seconds." << endl;
+ if ((overall.interval() < 1.1) or (overall.interval() > 1.105))
+ {
+ cerr << "Measured runtime "
+ << overall.interval()
+ << " is outside of expected limits, failed test" << endl;
+ returnme = 1;
+ };
+ }
+ catch (...)
+ {
+ returnme = 1;
+ };
+ return returnme;
};
=== added directory 'common/transceiver'
=== added file 'common/transceiver/Makefile'
--- common/transceiver/Makefile 1970-01-01 00:00:00 +0000
+++ common/transceiver/Makefile 2011-08-02 01:34:24 +0000
@@ -0,0 +1,38 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+# NRTB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NRTB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib: transceiver_test
+ @cp -v transceiver.h ../include
+ @cp -v transceiver.o ../obj
+ @echo build complete
+
+../include/confreader.h:
+ @cp ../confreader; make lib
+
+transceiver.o: transceiver.h transceiver.cpp Makefile ../include/confreader.h
+ @rm -f transceiver.o
+ g++ -c transceiver.cpp -I ../include
+
+transceiver_test: transceiver.o transceiver_test.cpp
+ @rm -f transceiver_test
+ g++ -c transceiver_test.cpp
+ g++ -o transceiver_test transceiver_test.o transceiver.o ../obj/common.o ../obj/log_setup.o -lPocoFoundation -lPocoUtil
+
+clean:
+ @rm -rvf *.o transceiver_test ../include/transceiver.h ../obj/transceiver.o
+ @echo all objects and executables have been erased.
=== added file 'common/transceiver/transceiver.cpp'
--- common/transceiver/transceiver.cpp 1970-01-01 00:00:00 +0000
+++ common/transceiver/transceiver.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,105 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#include "transceiver.h"
+#include "../include/confreader.h"
+#include <Poco/Mutex.h>
+#include <Poco/ScopedLock.h>
+#include <stringstream>
+
+class serializer_type
+{
+public:
+ unsigned int operator()
+ {
+ Poco::ScopedLock<Poco::Mutex>(lock);
+ return ++counter;
+ };
+private:
+ Poco::Mutex lock;
+ unsigned int counter;
+ serializer_type()
+ {
+ counter = 0;
+ };
+};
+
+serializer_type serializer;
+
+using namespace nrtb;
+
+template <class out, class in>
+transceiver::transceiver(Poco::Net::StreamSocket socket)
+{
+ // get the configuration parameters.
+ conf_reader & config = conf_reader::get_instance();
+ send_time_limit = config.get<unsigned int>("transceiver.send_timeout",2);
+ attempt_recovery = config.get<bool>("transceiver.allow_recovery",true);
+ error_run_limit =
+ config.get<unsigned int>("transceiver.max_consecutive_errors",10);
+ sent_messages.resize(config.get<int>("transceiver.history_size",50));
+ // set up uid
+ uid = serializer();
+ // set up logging
+ std::stringstream s << logname << "_" << uid ;
+ log = Poco::Logger::get(s.str());
+};
+
+template <class out, class in>
+transceiver::~transceiver()
+{
+
+};
+
+template <class out, class in>
+in transceiver::get()
+{
+
+};
+
+template <class out, class in>
+void transceiver::send(out & sendme)
+{
+
+};
+
+template <class out, class in>
+void transceiver::nak_invalid_context(const unsigned long int msg_number)
+{
+
+};
+
+template <class out, class in>
+void transceiver::nak_validation_error(const unsigned long int msg_number)
+{
+
+};
+
+template <class out, class in>
+void transceiver::handle_inbound_nak()
+{
+
+};
+
+template <class out, class in>
+void transceiver::handle_outbound_nak()
+{
+
+};
+
+
=== added file 'common/transceiver/transceiver.h'
--- common/transceiver/transceiver.h 1970-01-01 00:00:00 +0000
+++ common/transceiver/transceiver.h 2011-08-02 01:34:24 +0000
@@ -0,0 +1,128 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef nrtb_transceiver_h
+#define nrtb_transceiver_h
+
+#include <string>
+#include <Poco/Net/StreamSocket.h>
+#include <Poco/Net/SocketStream.h>
+#include <Poco/Logger.h>
+#include <Poco/Exception.h>
+#include <boost/circular_buffer.hpp>
+
+namespace nrtb
+{
+ /*******************************************************************
+ * transceiver is used to manage GBP (google protocol buffers)
+ * traffic between NRTB components. This is the only form of
+ * IPC used by NRTB.
+ *
+ * out is the channel wrapper for the outbound channel.
+ * in is the channel wrapper for the inbound channel.
+ *
+ * The nrtb::confreader singleton will be queried for the
+ * following parameters:
+ *
+ * transceiver.history_size (int)
+ * transceiver.send_timeout (int)
+ * transceiver.allow_recovery (bool)
+ * transceiver.max_consecutive_errors (int)
+ *
+ * See https://blueprints.launchpad.net/nrtb/+spec/icp-spec for
+ * specification this class implements.
+ * ***************************************************************/
+ template <class out, class in>
+ class transceiver
+ {
+ public:
+ /// outbound messages will be of this type
+ typedef outbound_type out;
+ /// inbound messages will be of this type.
+ typedef inbound_type in;
+ /**************************************************************
+ * Creates the transceiver and associates it with a provided
+ * socket. Once created this class assumes it uniquely owns the
+ * socket and will close it upon distruction.
+ * ***********************************************************/
+ transceiver(Poco::Net::StreamSocket socket);
+ /**************************************************************
+ * Closes the socket and releases all mmemory associated with
+ * this class.
+ * ***********************************************************/
+ ~transceiver();
+ /**************************************************************
+ * gets the next message from the socket. If no messages are
+ * ready, blocks util one arrives.
+ * ***********************************************************/
+ in & get();
+ /**************************************************************
+ * Sends a message over the socket and adds it to the
+ * sent_messages buffer in case it's needed for error recovery.
+ * ***********************************************************/
+ void send(out & sendme);
+ /**************************************************************
+ * Called by the data consumer when an inbound message was
+ * not valid in the current application context. msg_number
+ * is the sequence number of the offending message.
+ * ***********************************************************/
+ void nak_invalid_context(const unsigned long int msg_number);
+ /**************************************************************
+ * Called by the data consumer when an inbound message's
+ * data failed validation checks. msg_number is the sequence
+ * number of the offending message.
+ * ***********************************************************/
+ void nak_validation_error(const unsigned long int msg_number);
+ /**************************************************************
+ * Exceptions which may be thrown for external resulution.
+ * ***********************************************************/
+ // parent of all transceiver exceptions
+ POCO_DECLARE_EXCEPTION(transceiver, general_exception, Poco::Exception)
+ // thrown if send fails due to timeout.
+ POCO_DECLARE_EXCEPTION(transceiver, send_timeout, general_exception)
+ // thrown in the case of a fault while in get()
+ POCO_DECLARE_EXCEPTION(transceiver, get_fault, general_exception)
+ // Thrown if the socket is closed due to an unrecoverable date error.
+ POCO_DECLARE_EXCEPTION(transceiver, unrecoverable_data_error, general_exception)
+ // Thrown if the socket is closed due to too many errors in a row
+ POCO_DECLARE_EXCEPTION(transceiver, consecutive_error_overrun, general_exception)
+ protected:
+ unsigned in uid;
+ const std::string logname = "transceiver:";
+ unsigned int send_time_limit;
+ bool attempt_recovery;
+ unsigned int error_run_limit;
+ // pointer to this class's logger instance
+ Poco::Logger * log;
+ // The socket used for communcation.
+ Poco::Net::StreamSocket sock;
+ // the associated iostream (Do we need this?)
+ Poco::Net::SocketStream stream;
+ // buffer to hold previously sent messages; required for
+ // error recovery.
+ boost::circular_buffer<out> sent_messages;
+ // fence post for recovery efforts, zero if none in play
+ unsigned long long nak_fence_post;
+ // These methods implment actual nak recovery.
+ void handle_inbound_nak();
+ void handle_outbound_nak();
+ };
+
+} // namespace nrtb
+
+#endif //nrtb_transceiver_h//
\ No newline at end of file
=== added file 'common/transceiver/transceiver_test.cpp'
--- common/transceiver/transceiver_test.cpp 1970-01-01 00:00:00 +0000
+++ common/transceiver/transceiver_test.cpp 2011-08-02 01:34:24 +0000
@@ -0,0 +1,17 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB. If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
\ No newline at end of file
=== removed directory 'common/work_queue_thread'
=== removed file 'common/work_queue_thread/Makefile'
--- common/work_queue_thread/Makefile 2010-01-14 02:24:25 +0000
+++ common/work_queue_thread/Makefile 1970-01-01 00:00:00 +0000
@@ -1,144 +0,0 @@
-# This file was automatically generated by makemake.
-# Do not edit it directly!
-# Any changes you make will be silently overwritten.
-
-# Edit this file to define constants and custom build targets.
-# Please refer to the makemake documentation for more information.
-#
-# To compile multiple versions of a program or library, please study
-# http://www.its.caltech.edu/~jafl/jcc/multi_version.html
-
-# Useful directories
-
-MYCODEDIR := .
-
-# Directories to search for header files
-
-SEARCHDIRS := -I- -I${MYCODEDIR} -I../ricks_handy -I../threads -I../free_thread
-
-# makemake variables
-
-DEPENDFLAGS := -g -Wall -Werror ${SEARCHDIRS}
-
-# C preprocessor (C, C++, FORTRAN)
-
-CPPFLAGS =
-
-# C compiler
-
-CC := gcc
-CFLAGS = ${DEPENDFLAGS}
-
-%.o : %.c
- ${CC} ${CPPFLAGS} ${CFLAGS} -c $< -o $@
-
-# C++ compiler
-
-CXX := g++
-CXXFLAGS = ${DEPENDFLAGS}
-
-%.o : %.cc
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.C
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.cpp
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-%.o : %.cxx
- ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@
-
-# FORTRAN compiler
-
-FC := f77
-FFLAGS =
-
-# C/C++/Eiffel/FORTRAN linker
-
-LINKER := g++
-LDFLAGS = ../ricks_handy/ricks_handy.o ../threads/base_thread.o ../free_thread/free_thread.o
-LOADLIBES := -lm -lpthread
-
-# Java compiler
-
-JAVAC := javac
-JFLAGS =
-JAR := jar
-
-%.class : %.java
- ${JAVAC} ${JFLAGS} $<
-
-
-# This is what makemake added
-
-
-# work_queue_tester
-
-work_queue_tester : ./wqt_tester.o
- ${LINKER} ${LDFLAGS} -o $@ ${filter-out %.a %.so, $^} ${LOADLIBES}
-
-# target for making everything
-
-.PHONY : all
-all: work_queue_tester
-
-
-# target for removing all object files
-
-.PHONY : tidy
-tidy::
- @rm -fv core ./wqt_tester.o
-
-# target for removing all object files
-
-.PHONY : clean
-clean:: tidy
- @rm -fv work_queue_tester ../../include3/work_queue_thread.h ../../include3/controlled_wqt.h
-
-.PHONY : lib
-lib : ./wqt_tester.o ../../include3/work_queue_thread.h ../../include3/controlled_wqt.h
-
-../../include3/work_queue_thread.h: work_queue_thread.h
- @cp -fv work_queue_thread.h ../../include3
-
-../../include3/controlled_wqt.h: controlled_wqt.h
- @cp -fv controlled_wqt.h ../../include3
-
-# list of all source files
-
-MM_ALL_SOURCES := ./wqt_tester.cpp
-
-
-# target for checking a source file
-
-CHECKSYNTAXFILE := ${basename ${filter %${CHECKSTRING}, ${MM_ALL_SOURCES}}}
-
-.PHONY : checksyntax
-checksyntax:
- ifneq (${CHECKSYNTAXFILE},)
- @${MAKE} ${addsuffix .o, ${CHECKSYNTAXFILE}}
- else
- @echo No target to make ${CHECKSTRING}
- endif
-
-
-# target for touching appropriate source files
-
-.PHONY : touch
-touch::
- @list=$$(grep -l ${TOUCHSTRING} ${MM_ALL_SOURCES}); \
- for file in $$list; do { echo $$file; touch $$file; } done
-
-
-# target for calculating dependencies (MAKEMAKE)
-
-.PHONY : jdepend
-jdepend:
- @${MAKEMAKE} --depend Makefile -- ${DEPENDFLAGS} -- ./wqt_tester.cpp ./wqt_tester.o
-
-
-# DO NOT DELETE THIS LINE -- makemake depends on it.
-
-./wqt_tester.o: ../free_thread/free_thread.h ../ricks_handy/ricks_handy.h ../threads/base_thread.h ./work_queue_thread.h /usr/include/pthread.h /usr/include/time.h ./controlled_wqt.h
-
=== removed file 'common/work_queue_thread/controlled_wqt.h'
--- common/work_queue_thread/controlled_wqt.h 2010-01-14 02:24:25 +0000
+++ common/work_queue_thread/controlled_wqt.h 1970-01-01 00:00:00 +0000
@@ -1,202 +0,0 @@
-#include <work_queue_thread.h>
-#include <free_thread.h>
-#include <list>
-
-namespace NRTB
-{
-
-/** A work_queue_thread with a global control queue.
- **
- ** First, read the documentation on work_queue_thread if you are not
- ** comfortable with it. A controlled_work_queue_thread differs from a
- ** work_queue_thread in that it mechanism for sending "control" messages
- ** to all of the threads servicing a given queue.
- **
- ** Control messages are sent once, but are presented to each worker thread
- ** servicing the queue. They are processed on a priority basis, before
- ** messages in the normal work queue, and are always processed in the
- ** order they were sent by each thread. Control messages may be a
- ** completely different data type than the work queue messages and are
- ** proceessed by a different method.
- **
- ** In addition to overridding the do_work() abstract method, you must
- ** override the do_control() method to define the actions you'll take on
- ** any given control message. In addition to the new required template
- ** parameter cltmsg, there is a new optional ctl_seq parameter that allows
- ** you to override the control queue type; it's subject to the same rules
- ** and restrictions as noted for the seq parameter, save that it must
- ** store control messages.
- **
- ** The default thread type for controlled_work_queue_threads is
- ** ricklib::free_thread. This is a good choice, since the control queue
- ** allows easy manipulalation of free running threads. However, this
- ** template should work fine with any clean descendent of ricklib::thread.
- **
- ** NOTE: run() and closeout() provide critical functionality for the
- ** automatic maintainence of the thread list and control queue. Don't
- ** override them unless you grok them completely. In practice, I don't
- ** expect you'll ever need to.
-**/
-template <class workpacket, class ctlmsg,
- class threadclass=ricklib::free_thread,
- int q_uid = 0, class seq = std::queue<workpacket>,
- class ctl_seq = std::queue<ctlmsg> >
-class controlled_work_queue_thread
- : public work_queue_thread<workpacket,threadclass,q_uid,seq>
-{
- public:
- /** Sends a control message to all the threads.
- **
- ** The ctlmsg is copied into the control queue of all the
- ** worker threads operating off of the same work queue.
- **/
- static void control(const ctlmsg & msg);
- protected:
- typedef work_queue_thread<workpacket,threadclass,q_uid,seq> parent_type;
- // static control variables.
- typedef controlled_work_queue_thread * cwqt_ptr;
- typedef std::list<cwqt_ptr> tlist_type;
- static tlist_type tlist;
- // local control variables;
- ctl_seq ctl_queue;
- bool control_pending;
- ctlmsg my_ctl;
- // methods
- /** Provides control message handling.
- **
- ** You must override this method to provide the control
- ** message processing logic. On entry, the control message
- ** will be in the my_ctl data element. You are free to take
- ** any action here, including terminating the thread run.
- **/
- virtual void do_control() = 0;
- /** called when the thread had data to process.
- **
- ** Override this to do the work you need to do. You'll find the data
- ** in my_data, which will be of whatever type you specified to make
- ** the template. This is where you'll actually get the work on the
- ** workpacket done.
- **/
- virtual void do_work() = 0;
- // must override park() and run()
- virtual void park();
- virtual void run();
- // insures thread is pulled from tlist
- static void closeout(void * arg);
- public:
- // used to add control message to the private queue
- // it is not intended to be called directly by user code.
- // Due to the lack of mutex locking here, calling this
- // can result in _EVIL_ behaviour.
- virtual void add_to_control(const ctlmsg & msg);
-};
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid, class seq, class ctl_seq>
-typename controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::tlist_type
- controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::tlist;
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid, class seq, class ctl_seq>
-void controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::control(const ctlmsg & msg)
-{
- scope_lock lock(parent_type::latch);
- typename tlist_type::iterator it = tlist.begin();
- typename tlist_type::iterator end = tlist.end();
- while (it != end)
- {
- if (*it)
- {
- (*it)->add_to_control(msg);
- };
- it++;
- };
- parent_type::latch.broadcast_signal();
-};
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid , class seq, class ctl_seq>
-void controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::park()
-{
- scope_lock lock(parent_type::latch);
- pthread_cleanup_push(ricklib::safe_unlock,&parent_type::latch);
- // increment the number of threads available.
- parent_type::available++;
- control_pending = false;
- // wait until there is data to work with.
- // NOTE: this latch.wait() is a thread cancelation point.
- while (parent_type::pending.empty() && ctl_queue.empty()) {parent_type::latch.wait(); };
- // take the message as our own and clear the buffer.
- if (ctl_queue.empty())
- {
- parent_type::my_data = parent_type::pending.front();
- parent_type::pending.pop();
- }
- else
- {
- my_ctl = ctl_queue.front();
- ctl_queue.pop();
- control_pending = true;
- };
- // decrement the number of threads available.
- parent_type::available--;
- pthread_cleanup_pop(0);
-};
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid, class seq, class ctl_seq>
-void controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::run()
-{
- {
- scope_lock lock(parent_type::latch);
- tlist.push_front(this);
- }
- pthread_cleanup_push(controlled_work_queue_thread::closeout,this);
- while (true)
- {
- try
- {
- park(); // this is a cancellation point
- if (control_pending)
- {
- do_control();
- }
- else
- {
- do_work();
- };
- }
- catch (std::exception & e)
- {
- std::clog << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__
- << ": WARNING!! unexpected exception \"" << e.what() << "\" caught." << std::endl;
- };
- };
- pthread_cleanup_pop(1);
-};
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid, class seq, class ctl_seq>
-void controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::add_to_control(const ctlmsg & msg)
-{
- // can not lock latch here, because it's locked by control();
- // ___NEVER___ call this method directly
- ctl_queue.push(msg);
-};
-
-template <class workpacket, class ctlmsg,
- class threadclass, int q_uid, class seq, class ctl_seq>
-void controlled_work_queue_thread<workpacket,ctlmsg,threadclass,
- q_uid,seq,ctl_seq>::closeout(void * arg)
-{
- scope_lock lock(parent_type::latch);
- tlist.remove(static_cast<cwqt_ptr>(arg));
-};
-
-} // namespace NRTB
=== removed file 'common/work_queue_thread/work_queue_thread.h'
--- common/work_queue_thread/work_queue_thread.h 2010-01-14 02:24:25 +0000
+++ common/work_queue_thread/work_queue_thread.h 1970-01-01 00:00:00 +0000
@@ -1,248 +0,0 @@
-/* provides the basic thread for writing to a database.
-
- TODO: Needs to be adapted to us boost threads.
-
-*/
-
-#ifndef work_queue_thread_h
-#define work_queue_thread_h
-
-#include <base_thread.h>
-#include <fstream>
-#include <queue>
-#include <iostream>
-
-namespace ricklib
-{
-
-/** Implements a general purpose queue driven worker thread framework.
- **
- ** work_queue_threads are useful where you need one or more threads to
- ** process data asyncronously from the feed rate. work_queue_threads can
- ** operate singlely or in teams working the same input queue. Example
- ** applictions could be as a connection handler on a web server, or any
- ** place where you need to business while allowing a "slow" task (i.e.
- ** remote communications) to complete without affecting the primary task.
- **
- ** This template takes two class arguments to instanciate. The first,
- ** workpacket, is the data type that will be passed in and queued for the
- ** threads to work on. The second, threadclass, must implement the same
- ** interface as ricklib::thread, and is in fact generally expected to be
- ** ricklib::thread or one of descendents such as ricklib::free_thread.
- **
- ** Things to remember about classes instanciated from work_queue_thread:
- **
- ** 1. All instances of a class based on work_queue_thread with the
- ** same parameters share the same work queue, and will share in
- ** processing the data placed in that queue by the store() method. As
- ** long as there are one or more instances of a given class running,
- ** the data will processed as soon as thread can get to it.
- **
- ** 2. If you need different classes descended from work_queue_thread
- ** with the same workpacket and thread types, the optional q_uid
- ** template parameter (the third one) when instanciating the
- ** work_queue_threads. q_uid defaults to 0 if not specified, but can be
- ** specified to any valid int value, allowing you have many different
- ** queues that were instanciated with the same data types. If you don't
- ** use q_uid, all work_queue_thread descendents instanciated with the
- ** same workpacket and threadclass types _will_ share the same work
- ** queue, even if they have different do_run() methods.
- **
- ** 3. If you need a different queue type than the default
- ** queue<workpacket> you can use the optional template parameter seq
- ** (the fourth parameter) to specify a different queue type. It will
- ** expected to provide push(), front() and pop() methods, and store and
- ** return the same datatype specified in the first template parameter.
- ** Use this if you need a priority queue for example. Of course, if
- ** you want to specify the queue type, you'll need to specify the q_uid
- ** parameter discussed above.
- **
- ** 4. Data passed to the class using the store() method will be queued,
- ** even if the there are no instances running at that time (both the
- ** data queue and store method are static). processing will start at
- ** the front of the queue in FIFO order once an instance is started.
- **
- ** 5. Please note that there is no way provided in this template
- ** to get data back from the thread once it is processed. If you need
- ** feedback, you'll need to build the mechanism yourself.
- **
- ** 6. As with all derivitives of ricklib::runnable, you can not safely
- ** put a work_queue_thread in most STL constainers because they reserve
- ** the right to move things around at whim. Instead, derive a
- ** boost::shared_ptr for your class, create your instances on the heap,
- ** and put the shared_ptrs in the container instead. Don't use auto_ptr
- ** because it's definately not safe in containers; in fact Containers
- ** Of AutoPtrs (COAPs) are explictitly disallowed by the current C++
- ** standard.
- **
- ** Usage Notes:
- **
- ** You'll need to create a descendent of work_queue_thread and override
- ** do_work() at a minimum to use this. If you need to keep track of
- ** threads after they are created keep smart pointers to them in a
- ** container as noted in #6 above. Don't override run() as you would with
- ** other descendents of ricklib::runable as it controls the park,do_work
- ** cycle. Instead put code to accomplish the needed task in do_work(),
- ** which is abstract in the template anyway.
-**/
-template <class workpacket, class threadclass=boost::thread,
- int q_uid = 0, class seq = std::queue<workpacket> >
-class work_queue_thread : public threadclass
-{
- public:
- /** Stores the workpacket in the pending work queue.
- **
- ** Returns immediately and the message is processed asyncronously.
- ** Generally you will not want to override this method.
- **/
- static void store(const workpacket & message);
- /** Returns the number of threads awaiting work.
- **
- ** Another way to look at this that it represents the number of
- ** running threads the class that are currently idle awaiting work.
- ** When the threads are idle, they are not consuming CPU cycles.
- **/
- static unsigned int parked();
- /** Returns the number of workpackets awaiting processing.
- **
- ** Technically, this returns pending.size(), or the number of
- ** elements in the deque that stores work packets not yet picked up
- ** for processing by a thread. Assuming you have one or more running
- ** instances of your class, this should be zero most of the time
- ** unless you've managed to get all your threads busy at once.
- **
- ** If you occasionally check this value and keep finding it > 0, you
- ** might consider creating more instances of your class.
- **/
- static unsigned int work_pending();
- /** Releases a stalled thread.
- **
- ** Technically, this method signals the condition variable to force
- ** the thread to check the pending queue. Generally this should not
- ** be needed. It is provided to deal with the POSIX legal situation
- ** where a signal generated by the store() method could be ignored
- ** by the thread. If you are truely paranoid, have some other
- ** process in your application call this every few seconds just
- ** ensure that no one got stuck.
- **
- ** Note that while POSIX says it is acceptable to miss the
- ** occasional signal, I've never seen it happen on a modern system.
- ** If you have data hanging in the queue (work_pending() > 0 and
- ** parked() > 0) you can call this method to start processing again.
- ** I don't expect you'll need it.
- **/
- static void kick_start();
- protected:
- /** latch protects data and available as well as signalling when
- ** there is new data to process. Use work_queue_thread::store() to
- ** store the workpacket for later processing.
- **/
- static cond_variable latch;
- static seq pending;
- static int available;
- // thread local data.
- workpacket my_data;
- /** called when the thread had data to process.
- **
- ** Override this to do the work you need to do. You'll find the data
- ** in my_data, which will be of whatever type you specified to make
- ** the template. This is where you'll actually get the work on the
- ** workpacket done.
- **/
- virtual void do_work() = 0;
- /** called by the thread when it is waiting for data.
- **
- ** Avoid overriding this.
- **/
- virtual void park();
- /** the thread's main execution loop.
- **
- ** Avoid overriding this.
- **/
- virtual void run();
-};
-
-// initialize the static variables.
-template <class workpacket, class threadclass, int q_uid, class seq>
- cond_variable work_queue_thread<workpacket,threadclass,q_uid,seq>::latch;
-template <class workpacket, class threadclass, int q_uid, class seq>
- seq work_queue_thread<workpacket,threadclass,q_uid,seq>::pending;
-template <class workpacket, class threadclass, int q_uid, class seq>
- int work_queue_thread<workpacket,threadclass,q_uid,seq>::available = 0;
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- void work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::store(const workpacket & message)
-{
- scope_lock lock(latch);
- pending.push(message);
- latch.signal();
-};
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- unsigned int work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::parked()
-{
- scope_lock lock(latch);
- return available;
-};
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- unsigned int work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::work_pending()
-{
- scope_lock lock(latch);
- return pending.size();
-};
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- void work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::kick_start()
-{
- scope_lock lock(latch);
- latch.signal();
-};
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- void work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::park()
-{
- scope_lock lock(latch);
- pthread_cleanup_push(ricklib::safe_unlock,&latch);
- // increment the number of threads available.
- available++;
- // wait until there is data to work with.
- // NOTE: this latch.wait() is a thread cancelation point.
- while (pending.empty()) { latch.wait(); };
- // take the message as our own and clear the buffer.
- my_data = pending.front();
- pending.pop();
- // decrement the number of threads available.
- available--;
- pthread_cleanup_pop(0);
-};
-
-template <class workpacket, class threadclass, int q_uid, class seq>
- void work_queue_thread<workpacket,threadclass,q_uid,seq>
- ::run()
-{
- while (true)
- {
- try
- {
- park(); // this is a cancellation point
- do_work();
- }
- catch (std::exception & e)
- {
- std::clog << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__
- << ": WARNING!! unexpected exception caught." << std::endl
- << "\t" << e.what() << std::endl;
- throw e;
- };
- };
-};
-
-}; // namespace NRTB
-
-#endif // work_queue_thread_h
=== removed file 'common/work_queue_thread/wqt_tester.cpp'
--- common/work_queue_thread/wqt_tester.cpp 2010-01-14 02:24:25 +0000
+++ common/work_queue_thread/wqt_tester.cpp 1970-01-01 00:00:00 +0000
@@ -1,154 +0,0 @@
-/* work queue thread test program
-
- TODO: Needs to be adapted to boost::theads.
-
-*/
-
-//#include <free_thread.h>
-#include <work_queue_thread.h>
-#include <controlled_wqt.h>
-#include <time.h>
-#include <unistd.h>
-#include <iostream>
-#include <queue>
-
-using namespace NRTB;
-using namespace std;
-
-mutex c_lock;
-
-class worker : public work_queue_thread<int,free_thread>
-{
- public:
- worker()
- {
- scope_lock lock(wlock);
- iam = count++;
- start();
- scope_lock clock(c_lock);
- cout << "worker " << iam << " started" << std::endl;
- };
- ~worker()
- {
- scope_lock lock(c_lock);
- cout << "worker " << iam << " is being deleted." << std::endl;
- };
- protected:
-
- static mutex wlock;
- static int count;
- int iam;
-
- virtual void do_work()
- {
- if (my_data >= 0)
- {
- timespec delaytime;
- delaytime.tv_sec = 0;
- delaytime.tv_nsec = my_data * 1000;
- nanosleep(&delaytime,NULL);
- {
- scope_lock lock(c_lock);
- cout << "\tworker " << iam
- << " reports packet " << my_data << std::endl;
- }
- }
- else
- {
- pthread_exit(0);
- };
- };
-};
-
-mutex worker::wlock;
-int worker::count = 0;
-
-class workera : public controlled_work_queue_thread<int,int,free_thread,1>
-{
- public:
- workera()
- {
- scope_lock lock(wlock);
- iam = count++;
- start();
- scope_lock clock(c_lock);
- cout << "workera " << iam << " started" << std::endl;
- };
- ~workera()
- {
- scope_lock lock(c_lock);
- cout << "workera " << iam << " is being deleted." << std::endl;
- };
- protected:
-
- static mutex wlock;
- static int count;
- int iam;
-
- virtual void do_work()
- {
- timespec delaytime;
- delaytime.tv_sec = 0;
- delaytime.tv_nsec = my_data * 1000;
- nanosleep(&delaytime,NULL);
- {
- scope_lock lock(c_lock);
- cout << "\t\tworkera " << iam
- << " reports packet " << my_data << std::endl;
- }
- };
-
- virtual void do_control()
- {
- switch (my_ctl)
- {
- case 1: pthread_exit(0); break;
- default:
- {
- scope_lock lock(c_lock);
- cout << "\t\t\tworkera " << iam
- << " received control message " << my_ctl
- << std::endl;
- }
- };
- };
-};
-
-mutex workera::wlock;
-int workera::count = 0;
-
-int main()
-{
- // start five workers
- cout << "*** Starting workers ***" << endl;
- for (int i=0; i < 5; i++)
- {
- new worker;
- new workera;
- };
- cout << "*** sending control message 0 ***" << endl;
- workera::control(0);
- cout << "*** queuing 0-9 (0-90) ***" << endl;
- for (int i = 0; i < 10; i++)
- {
- worker::store(i);
- workera::store(i*10);
- };
- cout << "*** sending control message 2 ***" << endl;
- workera::control(2);
- cout << "*** sending 10 \"-1\" to workers ***" << endl;
- for (int i = 0; i < 10; i++)
- {
- worker::store(-1);
- };
- cout << "*** two second sleep here ***" << endl;
- sleep(2);
- cout << "*** Shutting down CWQ now. ***" << endl;
- workera::control(1);
- cout << "*** Starting 10 second sleep ***" << endl;
- sleep(10);
- cout << "worker has " << worker::parked() << " parked threads and "
- << worker::work_pending() << " elements in the queue." << endl;
- cout << "workera has " << workera::parked() << " parked threads and "
- << workera::work_pending() << " elements in the queue." << endl;
-};
Follow ups
-
[Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
[Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: George Jordan, 2011-08-02
-
[Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
[Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: George Jordan, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: DougPiranha, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: George Jordan, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: George Jordan, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02
-
Re: [Merge] lp:~nrtb-core/nrtb/merge_test into lp:nrtb
From: Rick Stovall, 2011-08-02