Merge lp:~fpstovall/nrtb/cpp_common into lp:nrtb

Proposed by Rick Stovall
Status: Merged
Approved by: Rick Stovall
Approved revision: 49
Merged at revision: 5
Proposed branch: lp:~fpstovall/nrtb/cpp_common
Merge into: lp:nrtb
Diff against target: 9400 lines (+6194/-2510)
62 files modified
GPB_proto/ack_nak.proto (+3/-0)
GPB_proto/physics_common.proto (+2/-0)
GPB_proto/sim_obj_tq_update.proto (+2/-0)
GPB_proto/sim_to_db_wrapper.proto (+2/-0)
common/GPB/Makefile (+34/-0)
common/Makefile (+31/-4)
common/common_rl/Makefile (+36/-0)
common/common_rl/common.cpp (+274/-0)
common/common_rl/common.h (+171/-0)
common/common_rl/common_rl_test.cpp (+101/-0)
common/confreader/Makefile (+38/-0)
common/confreader/confreader.cpp (+226/-0)
common/confreader/confreader.h (+287/-0)
common/confreader/conftest.cpp (+129/-0)
common/confreader/test.config (+27/-0)
common/logger/Makefile (+42/-0)
common/logger/log_setup.cpp (+43/-0)
common/logger/log_setup.h (+30/-0)
common/logger/log_test.cpp (+46/-0)
common/plugin_loader/Makefile (+0/-29)
common/plugin_loader/doc/plugins.xmi (+0/-339)
common/plugin_loader/plugin_manager.cpp (+0/-127)
common/plugin_loader/plugin_manager.h (+0/-194)
common/plugin_loader/plugin_wrapper.cpp (+0/-146)
common/plugin_loader/plugin_wrapper.h (+0/-207)
common/plugin_loader/test/Makefile (+0/-13)
common/plugin_loader/test/plugintest.cpp (+0/-12)
common/point/Makefile (+30/-13)
common/point/common_test.cpp (+99/-44)
common/point/triad.h (+54/-27)
common/serializer/Makefile (+36/-0)
common/serializer/serializer.cpp (+43/-0)
common/serializer/serializer.h (+50/-0)
common/serializer/serializer_test.cpp (+56/-0)
common/singleton/Makefile (+0/-18)
common/singleton/singleton.h (+0/-110)
common/singleton/singleton_test.cpp (+0/-32)
common/sockets/Makefile (+38/-0)
common/sockets/base_socket.cpp (+853/-0)
common/sockets/base_socket.h (+588/-0)
common/sockets/socket_test.cpp (+200/-0)
common/threads/Makefile (+36/-0)
common/threads/base_thread.cpp (+497/-0)
common/threads/base_thread.h (+627/-0)
common/threads/tests/cond_var.h (+124/-0)
common/threads/tests/general.h (+194/-0)
common/threads/tests/loop_counter.h (+76/-0)
common/threads/thread_test.cpp (+77/-0)
common/timer/Makefile (+36/-147)
common/timer/hires_timer.cpp (+174/-0)
common/timer/hires_timer.h (+131/-0)
common/timer/nrtb_timer.cpp (+0/-158)
common/timer/nrtb_timer.h (+0/-115)
common/timer/timer_test.cpp (+59/-27)
common/transceiver/Makefile (+31/-0)
common/transceiver/transceiver.cpp (+140/-0)
common/transceiver/transceiver.h (+276/-0)
common/transceiver/transceiver_test.cpp (+145/-0)
common/work_queue_thread/Makefile (+0/-144)
common/work_queue_thread/controlled_wqt.h (+0/-202)
common/work_queue_thread/work_queue_thread.h (+0/-248)
common/work_queue_thread/wqt_tester.cpp (+0/-154)
To merge this branch: bzr merge lp:~fpstovall/nrtb/cpp_common
Reviewer Review Type Date Requested Status
DougPiranha (community) process control Approve
George Jordan functional review for merge Approve
Rick Stovall merge test Approve
Aron Boyette Pending
jdrakey Pending
Review via email: mp+72827@code.launchpad.net

Commit message

C++ common libraries for alpha development.

Description of the change

I believe the expectations for all the C++ common libraries for the Alpha phase have been met at this time. This branch is ready for code review for merge to the alpha main branch.

To post a comment you must log in.
Revision history for this message
Rick Stovall (fpstovall) wrote :

I took the liberty of adding the the team members who can do code reviews to this review record. Have at it guys. If you find any problems, create a new bug and assign it to me for resolution.

Revision history for this message
Rick Stovall (fpstovall) :
review: Abstain (can not review)
Revision history for this message
Rick Stovall (fpstovall) wrote :

I conducted a test merge into a copy of the alpha branch. The merge completed automatically with no manual overrides required. I reviewed the change list and found only the expected changes. I then went to the common directory and ran make, piping the build and unit test output to a file. Careful review of the file showed all builds and all unit tests completed successfully.

In the absence of other reviews, this will constitute sufficient review and approval to merge the cpp_common branch into the alpha main branch.

review: Approve (merge test)
Revision history for this message
Aron Boyette (aron-carolina) wrote :

I'm still going to review out it. Are you available Tuesday to discuss
findings?
On Sep 4, 2011 8:33 PM, "Rick Stovall" <email address hidden> wrote:
> Review: Approve merge test
> I conducted a test merge into a copy of the alpha branch. The merge
completed automatically with no manual overrides required. I reviewed the
change list and found only the expected changes. I then went to the common
directory and ran make, piping the build and unit test output to a file.
Careful review of the file showed all builds and all unit tests completed
successfully.
>
> In the absence of other reviews, this will constitute sufficient review
and approval to merge the cpp_common branch into the alpha main branch.
> --
> https://code.launchpad.net/~fpstovall/nrtb/cpp_common/+merge/72827
> You are requested to review the proposed merge of
lp:~fpstovall/nrtb/cpp_common into lp:nrtb.

Revision history for this message
Rick Stovall (fpstovall) wrote :

Aron (and the rest of the team), while you are certainly welcome to look at any code set at any time, we need to get this code into the main tree to enable further work on the simulation engine and the data broker. At this point, this is a blocker for work on those components. It's been up for review now for 10 days and that seems a reasonable amount of time to hold up things waiting on review.

Please take a look at the code at your leisure and create bugs for any issues you may find. It's only alpha code, so there are sure to be some! In the meanwhile, unless some breaking issue is found by tonight, I'll move the branch forward to the main stream so that we can continue work on the rest of components needed for the alpha milestone.

Revision history for this message
George Jordan (gsjordanc) wrote :

Checked out functional build of cpp_common changes and fixes. Passed functional build test and appears by default to be ready to merge. Will continue to validate however merge may proceed, no apparent discreapancies or problem that would prevent this merge.

review: Approve (functional review for merge)
Revision history for this message
DougPiranha (dougpirahna) wrote :

Rick and George say everything is okay, so WTF. Damn the torpedoes, full speed ahead.

Revision history for this message
DougPiranha (dougpirahna) wrote :

Rick spanked my hand. (I liked it.) He said I did not do it right. Is this better?

review: Approve (process control)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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-25 04:57:16 +0000
@@ -9,6 +9,9 @@
9// in a channel wrapper message.9// in a channel wrapper message.
1010
11// return on of these to ack the recept of each error free message.11// return on of these to ack the recept of each error free message.
12
13package nrtb_msg;
14
12message message_ack {15message message_ack {
13 required uint32 msg_uid = 1;16 required uint32 msg_uid = 1;
14}17}
1518
=== 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-25 04:57:16 +0000
@@ -11,6 +11,8 @@
11// meters for distance, meters/sec for velocity, radians for attitude,11// meters for distance, meters/sec for velocity, radians for attitude,
12// and radians/sec for rotational velocity.12// and radians/sec for rotational velocity.
1313
14package nrtb_msg;
15
14message triplet {16message triplet {
15 required double x = 1;17 required double x = 1;
16 required double y = 2;18 required double y = 2;
1719
=== 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-25 04:57:16 +0000
@@ -8,6 +8,8 @@
8// Note: these are never sent bare.. they are always payloads 8// Note: these are never sent bare.. they are always payloads
9// in a channel wrapper message.9// in a channel wrapper message.
1010
11package nrtb_msg;
12
11import "physics_common.proto";13import "physics_common.proto";
1214
13// This message contains all the information required to report the15// This message contains all the information required to report the
1416
=== 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-25 04:57:16 +0000
@@ -7,6 +7,8 @@
7// Note: The message defined here is a "channel wrapper", a container for 7// Note: The message defined here is a "channel wrapper", a container for
8// all messages from the simulation engine to the data broker.8// all messages from the simulation engine to the data broker.
99
10package nrtb_msg;
11
10import "ack_nak.proto";12import "ack_nak.proto";
11import "sim_obj_tq_update.proto";13import "sim_obj_tq_update.proto";
1214
1315
=== added directory 'common/GPB'
=== added file 'common/GPB/Makefile'
--- common/GPB/Makefile 1970-01-01 00:00:00 +0000
+++ common/GPB/Makefile 2011-08-25 04:57:16 +0000
@@ -0,0 +1,34 @@
1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19proto=../../GPB_proto
20
21lib: lib/nrtb_gpb.a
22 @echo "GPB lib build complete."
23
24lib/nrtb_gpb.a:
25 @protoc -I=${proto} --cpp_out=cpp_src/ ${proto}/*.proto
26 @cd obj; for file in ../cpp_src/*.cc; do g++ -c $$file; done
27 @cp -v cpp_src/*h ../include
28 @ar -r ../lib/nrtb_gpb.a obj/*.o
29
30clean:
31 @cd cpp_src; for file in *h; do rm -vf ../../include/$$file; done
32 @rm -vf ../lib/nrtb_gpb.a
33 @rm -f obj/* cpp_src/*
34 @echo "GPB cleanup complete."
035
=== 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-25 04:57:16 +0000
@@ -1,6 +1,27 @@
1lib:1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: ./lib/nrtb_common.a
20
21./lib/nrtb_common.a:
2 @echo "============= building common libs ==============="22 @echo "============= building common libs ==============="
3 @make action=lib doit23 @make action=lib doit
24 @ar -r ./lib/nrtb_common.a ./obj/*.o
4 @echo "============= common libs complete ==============="25 @echo "============= common libs complete ==============="
526
6modules:27modules:
@@ -11,12 +32,18 @@
11clean:32clean:
12 @echo "============= cleaning common libs ==============="33 @echo "============= cleaning common libs ==============="
13 @make action=clean doit34 @make action=clean doit
14 @rm -fv ./obj/*35 @rm -fv ./obj/* ./lib/*
15 @echo "========== common lib cleanup complete ==========="36 @echo "========== common lib cleanup complete ==========="
1637
17doit:38doit:
39 @cd common_rl; make ${action}
18 @cd point; make ${action}40 @cd point; make ${action}
19 @cd timer; make ${action}41 @cd timer; make ${action}
20 @cd work_queue_thread; make ${action}42 @cd threads; make ${action}
43 @cd sockets; make ${action}
44 @cd serializer; make ${action}
21 @cd singleton; make ${action}45 @cd singleton; make ${action}
22 @cd plugin_loader; make ${action}46 @cd logger; make ${action}
47 @cd confreader; make ${action}
48 @cd GPB; make ${action}
49 @cd transceiver; make ${action}
2350
=== 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-25 04:57:16 +0000
@@ -0,0 +1,36 @@
1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: common_rl_test
20 @./common_rl_test
21 @cp -v common.h ../include
22 @cp -v common.o ../obj
23 @echo build complete
24
25common.o: common.h common.cpp Makefile
26 @rm -f common.o
27 g++ -c -O3 common.cpp
28
29common_rl_test: common.o common_rl_test.cpp
30 @rm -f common_rl_test
31 g++ -c common_rl_test.cpp
32 g++ -o common_rl_test common_rl_test.o common.o
33
34clean:
35 @rm -rvf *.o ../include/common.h ../obj/common.o common_rl_test
36 @echo all objects and executables have been erased.
037
=== 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-25 04:57:16 +0000
@@ -0,0 +1,274 @@
1/***********************************************
2 T his file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include <stdlib.h>
20#include <iostream>
21#include <math.h>
22#include <time.h>
23#include "common.h"
24
25using namespace std;
26
27namespace nrtb
28{
29
30base_exception::base_exception()
31{
32 ctime = time(NULL);
33};
34
35base_exception::base_exception(const string & text)
36{
37 ctime = time(NULL);
38 _text = text;
39};
40
41void base_exception::store(const string & s)
42{
43 _text = s;
44};
45
46string base_exception::comment()
47{
48 return _text;
49};
50
51unsigned long int base_exception::creation_time()
52{
53 return ctime;
54};
55
56const string __ricks_handy_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
57const string __ricks_handy_lower = "abcdefghijklmnopqrstuvwxyz";
58
59string changecase(const string &s,const string &upper, const string &lower)
60{
61 try
62 {
63 string returnme = "";
64 for (int i = 0; i < s.size(); i++)
65 {
66 unsigned long int loc = lower.find(s[i]);
67 if (loc == string::npos)
68 {
69 returnme += s[i];
70 }
71 else
72 {
73 returnme += upper[loc];
74 };
75 };
76 return returnme;
77 }
78 catch (...)
79 {
80 throw translate_exception();
81 };
82};
83
84string upcase(const string &s)
85{
86 return changecase(s,__ricks_handy_upper,__ricks_handy_lower);
87};
88
89string downcase(const string &s)
90{
91 return changecase(s,__ricks_handy_lower,__ricks_handy_upper);
92};
93
94
95const string __ricks_handy_hexits = "0123456789ABCDEF";
96
97string gsub(const string & target, const string & findme, const string & putme)
98{
99 // error checking
100 if (findme.empty() || target.empty())
101 {
102 throw gsub_exception();
103 };
104 string returnme = "";
105 unsigned long int okay_through = 0;
106 unsigned long int step = findme.length();
107 unsigned long int where = target.find(findme,okay_through);
108 while (where != string::npos)
109 {
110 returnme += target.substr(okay_through,where-okay_through) + putme;
111 okay_through = where + step;
112 where = target.find(findme,okay_through);
113 };
114 returnme += target.substr(okay_through);
115 return returnme;
116};
117
118strlist split(const string & source, const char token)
119{
120 strlist returnme;
121 returnme.clear();
122 if (source.size() > 0)
123 {
124 unsigned long int loc;
125 unsigned long int processed = 0;
126 try
127 {
128 loc = source.find(token,processed);
129 while (loc != string::npos)
130 {
131 returnme.push_back(source.substr(processed,loc-processed));
132 processed = loc + 1;
133 loc = source.find(token,processed);
134 }
135 returnme.push_back(source.substr(processed));
136 }
137 catch (...)
138 {
139 throw split_exception();
140 };
141 };
142 return returnme;
143};
144
145string trim(std::string s)
146{
147 const string ws = "\t\n ";
148 unsigned long int where = s.find_first_not_of(ws);
149 if (where != string::npos)
150 {
151 s.erase(0,where);
152 };
153 where = s.find_last_not_of(ws);
154 if (where != string::npos)
155 {
156 s.erase(where+1);
157 };
158 return s;
159};
160
161string mconvert(const string &s)
162{
163 /* This function is designed to escape strings destined for
164 * use in SQL queries and the like. Specifically, the following
165 * is done to the string passed in:
166 * 1. "\" is replaced with "\\"
167 * 2. "'" is replaced with "\'"
168 * 3. """ (double quote) is replaced with "\""
169 * 4. 0x00 is replaced with "\"+0x00.
170 */
171 string returnme = "";
172 if (s.length() > 0)
173 {
174 returnme = gsub(s,"\\","\\\\");
175 returnme = gsub(returnme,"'", "\\'");
176 returnme = gsub(returnme,"\"","\\\"");
177 // special handling is required to make strings including
178 // 0x00; this is the kludge I found to work at 2200 tonight.
179 string findme = " "; findme[0] = 0;
180 returnme = gsub(returnme,findme,"\\0");
181 };
182 return returnme;
183};
184
185string dateflip(string date, const string & sep)
186{
187 string out;
188 try
189 {
190 strlist temp = split(date,'-');
191 out = temp[1]+ sep + temp[2] + sep + temp[0];
192 }
193 catch (...)
194 {
195 throw dateflip_exception();
196 };
197 return out;
198}; // string dateflip
199
200string http_hextochar(string s)
201{
202 try
203 {
204 s = upcase(s);
205 unsigned char v = (16 * __ricks_handy_hexits.find(s[0]))
206 + __ricks_handy_hexits.find(s[1]);
207 return s = v;
208 }
209 catch (...)
210 {
211 throw hextrans_exception();
212 };
213}; // string hextochar
214
215string http_chartohex(const string &s)
216{
217 string out;
218 try
219 {
220 for (long int i=0; i < s.length() ; i++ ) {
221 unsigned char v = s[i];
222 div_t hexval = div(v,16);
223 out += __ricks_handy_hexits[hexval.quot];
224 out += __ricks_handy_hexits[hexval.rem];
225 }; /* endfor */
226 }
227 catch (...)
228 {
229 throw hextrans_exception();
230 };
231 return out;
232};// string chartohex()
233
234string http_enhex(const string & s)
235{
236 string out;
237 try
238 {
239 for (long int i=0; i < s.length() ; i++ ) {
240 unsigned char v = s[i];
241 div_t hexval = div(v,16);
242 out += "%";
243 out += __ricks_handy_hexits[hexval.quot];
244 out += __ricks_handy_hexits[hexval.rem];
245 }; /* endfor */
246 }
247 catch (...)
248 {
249 throw hextrans_exception();
250 };
251 return out;
252}; // string enhex()
253
254string http_unhex(string s)
255{
256 try
257 {
258 while (s.find('%') != string::npos)
259 {
260 int where = s.find('%');
261 string hexchar = s.substr(where+1,2);
262 s.erase(where,3);
263 s.insert(where,http_hextochar(hexchar));
264 }; /* endwhile */
265 }
266 catch (...)
267 {
268 throw hextrans_exception();
269 };
270 return s;
271};// string unhex()
272
273
274} // namespace nrtb
0275
=== 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-25 04:57:16 +0000
@@ -0,0 +1,171 @@
1/***********************************************
2 T his file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19// prevent multiple definitions
20#ifndef __ga_common_h
21#define __ga_common_h 1
22
23//#include <stream.h>
24#include <string>
25#include <map>
26#include <vector>
27
28namespace nrtb
29{
30
31// throwable exception classes
32
33/** Provides a base exception class for use in HCS developed programs.
34 **
35 ** Usage: Inherit your exception classes from this class. When throwing a
36 ** derived exception you'll have the option of either instanciating the
37 ** exception with a comment or not; in any case the time the exception was
38 ** instanciated will be recorded. Later, when catching the exception you can
39 ** get the time the exception was created and any text the thrower may have
40 ** provided.
41 **/
42 class base_exception: public std::exception
43 {
44 protected:
45 unsigned long int ctime;
46 std::string _text;
47 public:
48 /** Default constructor.
49 **
50 ** Creates an nrtb_exception recording it's creation time but without
51 ** a comment string.
52 **/
53 base_exception();
54 /** Constructs with a comment string.
55 **
56 ** Creates an nrtb_exception recording it's creation time and storing the
57 ** provided string "text" for recall later via the comment method.
58 **
59 ** This version takes an ISO standard C++ string.
60 **/
61 base_exception(const std::string & text);
62 /// NOP virtual distructor for safe inheritance
63 virtual ~base_exception() throw() {};
64 /** Stores a comment string.
65 **/
66 void store(const std::string & s);
67 /** Returns the value stored at exception creation.
68 **/
69 std::string comment();
70 /** Returns the unix time the exception was created.
71 **/
72 unsigned long int creation_time();
73};
74
75// Thrown by gsub() in cases of unexpected error.
76class gsub_exception: public nrtb::base_exception {};
77// Thrown by split() in cases of unexpected error.
78class split_exception: public nrtb::base_exception {};
79// Thrown by dateflip in cases of unexpected error.
80class dateflip_exception: public nrtb::base_exception {};
81// Thrown by upcase() and downcase() in cases of unexpected error.
82class translate_exception: public nrtb::base_exception {};
83// Thrown by http_* functions in cases of unexpected error.
84class hextrans_exception: public nrtb::base_exception {};
85// Thrown by the biased_rand* functions in cases of unexpected error.
86class rand_exception: public nrtb::base_exception {};
87
88// handy commonly used maps
89/// A map of ints keyed by ints.
90typedef std::map<int,int> num_map;
91/// A map of ints keyed by strings.
92typedef std::map<std::string,int> string_map;
93
94/// the return type for split.
95typedef std::vector<std::string> strlist;
96
97/** Converts the alpha components of s to all upper case.
98 **
99 ** May throw a nrtb::translate_exception if there is a problem.
100 **/
101std::string upcase(const std::string &s);
102
103/** Converts the alpha components of s to all lower case.
104 **
105 ** May throw a nrtb::translate_exception if there is a problem.
106 **/
107std::string downcase(const std::string &s);
108
109/** Replaces all instances of findme in target with putme.
110 **
111 ** May throw a nrtb::gsub_exception if there is a problem.
112 **/
113std::string gsub(const std::string & target, const std::string & findme,
114 const std::string & putme);
115
116/** Splits the string source using token as a delimiter and returns
117 ** the results in vector of strings.
118 **
119 ** May throw a nrtb::split_exception if there is a problem.
120 **/
121strlist split(const std::string & source, const char token);
122
123/// Performs SQL escaping on the string.
124std::string mconvert(const std::string & s);
125
126/// Removes white space from both ends of a string.
127std::string trim(std::string s);
128
129/** Takes an ISO standard date (YYYY-MM-DD) and returns MM-DD-YYYY.
130 **
131 ** May throw a nrtb::dateflip_exception if there is a problem.
132 **/
133std::string dateflip(std::string date, const std::string & sep="-");
134
135/** Takes a string representing one HTTP hex-encoded byte and returns
136 ** the appropriate character. This will only operate on the first two
137 ** bytes of s, and will throw a nrtb_hextrans_exception if less
138 ** than two bytes are supplied.
139 **
140 ** May throw a nrtb::hextrans_exception if there is a problem.
141 **/
142std::string http_hextochar(std::string s);
143
144/** Takes a string and returns it hex-encoded (i.e. " " returns "20").
145 **
146 ** This function is somewhat misnamed due to hysterical reasons. In
147 ** truth it simply returns the hex equivilent of the input. Use
148 ** http_enhex() when you actually need valid HTTP hex encoding.
149 ** On the other hand, this function is quite
150 ** useful if you need to hex up a series of bytes and don't need the
151 ** overhead of the extra byte per character of true HTTP hex encoding.
152 **
153 ** May throw a nrtb::hextrans_exception if there is a problem.
154*/
155std::string http_chartohex(const std::string &s);
156
157/** Takes a string and returns it in HTTP hex-encoded format (" " returns "%20").
158 **
159 ** May throw a nrtb::hextrans_exception if there is a problem.
160 **/
161std::string http_enhex(const std::string &s);
162
163/** Takes a string and returns it with all HTTP hex-encoded bytes changed to
164 ** their normal single byte representation.
165 **
166 ** May throw a nrtb::hextrans_exception if there is a problem.
167 **/
168std::string http_unhex(std::string s);
169
170} // namespace nrtb
171#endif /* __ga_common_h */
0172
=== 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-25 04:57:16 +0000
@@ -0,0 +1,101 @@
1/***********************************************
2 T his file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include "common.h"
20#include <iostream>
21
22using namespace std;
23
24int report_test(const string banner, bool test)
25{
26 string result;
27 int returnme = 0;
28 if (test)
29 {
30 result = "PASSED";
31 }
32 else
33 {
34 result = "FAILED";
35 returnme = 1;
36 };
37 cout << "\t" << banner << ": " << result << endl;
38 return returnme;
39};
40
41int main()
42{
43 cout << "=== Starting nrtb::common_rl unit test ===" << endl;
44 int returnme = 0;
45 string tstr = "MiXeDcAsE";
46
47 returnme += report_test(
48 "nrtb::upcase()",
49 nrtb::upcase(tstr) == "MIXEDCASE");
50
51 returnme += report_test(
52 "nrtb::downcase()",
53 nrtb::downcase(tstr) == "mixedcase");
54
55 returnme += report_test(
56 "nrtb::gsub()",
57 nrtb::gsub(tstr, "cAsE", " frogs") == "MiXeD frogs");
58
59 // split() testing
60 nrtb::strlist tokens = nrtb::split("this is a test",' ');
61 bool faults = tokens.size() == 4;
62 faults = faults or (tokens[0] == "this");
63 faults = faults or (tokens[0] == "is");
64 faults = faults or (tokens[0] == "a");
65 faults = faults or (tokens[0] == "test");
66 returnme += report_test(
67 "nrtb::split()",
68 faults);
69
70 string tchar = " "; tchar[0] = 0;
71 returnme += report_test(
72 "nrtb::mconvert()",
73 nrtb::mconvert("\\ \" '"+tchar) == "\\\\ \\\" \\\'\\0");
74
75 returnme += report_test(
76 "nrtb::trim()",
77 nrtb::trim("\t"+tstr+" ") == tstr);
78
79 returnme += report_test(
80 "nrtb::dateflip()",
81 nrtb::dateflip("2011-07-21") == "07-21-2011");
82
83 returnme += report_test(
84 "nrtb::http_hextochar()",
85 nrtb::http_hextochar("20") == " ");
86
87 returnme += report_test(
88 "nrtb::http_chartohex()",
89 nrtb::http_chartohex(tstr) == "4D6958654463417345");
90
91 returnme += report_test(
92 "nrtb::http_enhex()",
93 nrtb::http_enhex(tstr) == "%4D%69%58%65%44%63%41%73%45");
94
95 returnme += report_test(
96 "nrtb::http_unhex()",
97 nrtb::http_unhex("%4D%69%58%65%44%63%41%73%45") == tstr);
98
99 cout << "=== nrtb::common_rl unit test complete ===" << endl;
100 return returnme;
101};
0\ No newline at end of file102\ No newline at end of file
1103
=== added directory 'common/confreader'
=== added file 'common/confreader/Makefile'
--- common/confreader/Makefile 1970-01-01 00:00:00 +0000
+++ common/confreader/Makefile 2011-08-25 04:57:16 +0000
@@ -0,0 +1,38 @@
1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: conftest
20 @rm -f conf_test.log
21 @./conftest test=1 test2-2 test2=71.837486 test3="jack danials" --doit
22 @grep "Run Complete" conf_test.log
23 @cp -v confreader.h ../include
24 @cp -v confreader.o ../obj
25 @echo build complete
26
27confreader.o: confreader.h confreader.cpp Makefile
28 @rm -f confreader.o
29 g++ -c confreader.cpp -I../include
30
31conftest: confreader.o conftest.cpp
32 @rm -f conftest
33 g++ -c conftest.cpp -I../include
34 g++ -o conftest conftest.o confreader.o ../obj/common.o ../obj/log_setup.o ../obj/base_thread.o -lpthread -lPocoFoundation -lPocoUtil
35
36clean:
37 @rm -rvf *.o conftest ../include/confreader.h ../obj/confreader.o conf_test.log
38 @echo all objects and executables have been erased.
039
=== added file 'common/confreader/confreader.cpp'
--- common/confreader/confreader.cpp 1970-01-01 00:00:00 +0000
+++ common/confreader/confreader.cpp 2011-08-25 04:57:16 +0000
@@ -0,0 +1,226 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17**********************************************/
18
19// see confreader.h for documentation
20
21#include "confreader.h"
22#include <fstream>
23#include <iostream>
24#include <common.h>
25#include "Poco/Logger.h"
26
27using namespace std;
28using namespace nrtb;
29
30const std::string logname = "conf_reader";
31
32namespace nrtb
33{
34
35conf_reader::conf_reader()
36{
37 Poco::Logger& logger = Poco::Logger::get(logname);
38 logger.information("conf_reader instanciated.");
39};
40
41conf_reader::~conf_reader() {};
42
43unsigned int conf_reader::read(const std::string & _filename, bool _clear)
44{
45 Poco::Logger& logger = Poco::Logger::get(logname);
46 logger.information("Reading from \"" + _filename + "\".");
47 if (_filename != "") { filename = _filename; };
48 if (filename != "")
49 {
50 try
51 {
52 ifstream cfile(filename.c_str());
53 if (!cfile) throw base_exception();
54 if (_clear) values.clear();
55 // read the file line by line, ignoring comments.
56 char inbuff[16*1024];
57 while (cfile)
58 {
59 cfile.getline(inbuff, 16*1024);
60 string in = inbuff;
61 // truncate at the start of a comment.
62 unsigned long int where = in.find("#");
63 while (where != string::npos)
64 {
65 if (in[where-1] == '\\')
66 {
67 // comment char was escaped.. ignore.
68 where = in.find("#",where+1);
69 }
70 else
71 {
72 // truncate the string at this point.
73 in.erase(where);
74 where = string::npos;
75 };
76 };
77 // see if we can parse what's left.
78 in = trim(in);
79 unsigned long int split_point = in.find_first_of("\t ");
80 if (split_point != string::npos)
81 {
82 // okay.. get the fields.
83 pair arg;
84 arg.first = gsub(trim(in.substr(0,split_point)),"\\#","#");
85 arg.second = gsub(trim(in.substr(split_point)),"\\#","#");
86 // is this an include directive?
87 if (arg.first == "*INCLUDE")
88 {
89 read(arg.second,false);
90 }
91 else if (arg.first != "")
92 {
93 values.insert(arg);
94 };
95 };
96 };
97 }
98 catch (...)
99 {
100 logger.warning("Problems reading configuration file \""
101 + filename + "\"; data may be incomplete.");
102 }
103 };
104 return values.size();
105};
106
107unsigned int conf_reader::read(int argc, char * argv[],
108 const string & _filename)
109{
110 Poco::Logger& logger = Poco::Logger::get(logname);
111 logger.information("Reading from command line.");
112 clear();
113 filename = _filename;
114 value_list_type cvars;
115 // read values from the command line first.
116 for (int i = 0; i < argc; i++)
117 {
118 string instring = argv[i];
119 if (i == 0)
120 {
121 instring = "__exec_name="+instring;
122 };
123 strlist t = split(instring,'=');
124 if (t.size() > 0)
125 {
126 // build the new insert pair;
127 pair newval;
128 newval.first = t[0];
129 // assemble the value
130 // (allows for including "=" in the argument)
131 for (unsigned int l = 1; l < t.size(); l++)
132 {
133 newval.second += t[l];
134 if (l < (t.size() -1) )
135 {
136 newval.second += "=";
137 };
138 };
139 // store this in the list
140 trim(newval.first);
141 trim(newval.second);
142 cvars.insert(newval);
143 // is this a config file name?
144 if (newval.first == "configfile")
145 {
146 filename = newval.second;
147 };
148 };
149 }; // read the command line arguments.
150 // read the file args if any.
151 read(filename,false);
152 // override the first instance of any value found in configs
153 // or insert as appropriate.
154 iterator c = cvars.begin();
155 iterator e = cvars.end();
156 while (c != e)
157 {
158 iterator here = values.find(c->first);
159 if (here != values.end())
160 {
161 here->second = c->second;
162 }
163 else
164 {
165 values.insert(*c);
166 };
167 c++;
168 };
169 std::stringstream message;
170 message << "Read " << values.size() << " parameters.";
171 logger.information(message.str());
172 return values.size();
173};
174
175void conf_reader::clear()
176{
177 values.clear();
178};
179
180conf_reader::iterator conf_reader::begin()
181{
182 return values.begin();
183};
184
185conf_reader::iterator conf_reader::end()
186{
187 return values.end();
188};
189
190bool conf_reader::empty()
191{
192 return values.empty();
193};
194
195unsigned int conf_reader::size()
196{
197 return values.size();
198};
199
200strlist conf_reader::all(const std::string & key)
201{
202 strlist returnme;
203 iterator current = values.find(key);
204 iterator e = values.end();
205 while ((current != e) && (current->first == key))
206 {
207 returnme.push_back(current->second);
208 current++;
209 };
210 return returnme;
211};
212
213string conf_reader::operator [] (const std::string & key)
214{
215 iterator res = values.find(key);
216 string returnme = "";
217 if (res != values.end()) returnme = res->second;
218 return returnme;
219};
220
221bool conf_reader::exists(const std::string & key)
222{
223 return (values.find(key) != values.end());
224};
225
226} // namespace nrtb
0227
=== added file 'common/confreader/confreader.h'
--- common/confreader/confreader.h 1970-01-01 00:00:00 +0000
+++ common/confreader/confreader.h 2011-08-25 04:57:16 +0000
@@ -0,0 +1,287 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#ifndef ricklib_confreader_h
20#define ricklib_confreader_h
21
22#include <string.h>
23#include <map>
24#include <vector>
25#include <string>
26#include <fstream>
27#include <boost/lexical_cast.hpp>
28#include <singleton.h>
29
30namespace nrtb
31{
32
33typedef std::vector<std::string> strlist;
34
35/** Reads command line and configuration file information.
36 **
37 ** For this NRTB implementation, this class is implemented as
38 ** a singleton.
39 **
40 ** Values read are stored in a multimap of name/value pairs and
41 ** may be accessed via provided iterators, or directly via the
42 ** [] operator, all(), get<T>() and getall<T>() methods. Automatic
43 ** handling of include files and comments is provided as well. The
44 ** get<>() and getall<>() template methods provide easy and complete
45 ** access to all types that have the ">>" stream operator
46 ** defined, including all the C++ standard types.
47 **/
48class conf_reader
49{
50 private:
51 typedef std::multimap<std::string,std::string> value_list_type;
52 value_list_type values;
53 std::string filename;
54 protected:
55 /** Reads and parses a configuration file.
56 **
57 ** Returns the number of values stored.
58 **
59 ** The optional parameter _clear when true clears the currently
60 ** stored list of values. if false the new values read will be added
61 ** to the existing list.
62 **
63 ** If the file named can not be processed completely, a warning
64 ** message is published to cerr.
65 **
66 ** Configuration files are defined as follows.
67 **
68 ** 1. Files are read line by line. No value can cross a newline
69 ** (and at least in this version) or include one. The good
70 ** news is that you are allowed up to 16k for each line.
71 **
72 ** 2. values are specifed in name/value pairs, one per line, with
73 ** the name first, followed by whitespace, followed by the
74 ** value. Values may include whitespace. All leading and trailing
75 ** whitespace is removed from both the name and the value.
76 **
77 ** 3. Comments start with a \# symbol; all text following a \# is
78 ** ignored. If you need to use \# in a name or value, escape
79 ** it with a backslash instead.
80 **
81 ** 4. Duplicate names are allowed.
82 **
83 ** 5. Names without values will be stored with "" as the value.
84 **
85 ** 6. A configuration file may include another configuration file
86 ** automatically by the use of the "*INCLUDE" reserved name.
87 ** When this name is found, it's value is used as the name of
88 ** the new file to be read.
89 **/
90 unsigned int read(const std::string & _filename = "", bool _clear=true);
91 public:
92 /// conf_reader iterator, points to a conf_reader::pair
93 typedef value_list_type::iterator iterator;
94 /// conf_reader::pair is a std::pair<string,string>
95 typedef std::pair<std::string,std::string> pair;
96 /** No argument constructor; actually calls read() without a filename.
97 **/
98 conf_reader();
99 /** NOP virtual destructor to allow safe inheritance.
100 **/
101 virtual ~conf_reader();
102 /** Reads and parses the command line and the provided file.
103 **
104 ** Returns the number of values stored. argc and argv are, of
105 ** course the same names you used as arguments to main(). Therefore
106 ** you can easily read all command line and configuration file
107 ** values like this:
108 **
109 ** int main(int argc, char* argv[])
110 **
111 ** {
112 **
113 ** conf_reader config;
114 **
115 ** config.read(argc,argv,"my_conf_file");
116 **
117 ** ...
118 **
119 ** }
120 **
121 ** See read(filename,_clear) for a discription of how configuration
122 ** files are structured and parsed. This method unconditionally
123 ** clears the existing value list before starting. For command line
124 ** arguments the following rules are true.
125 **
126 ** 1. The executable name (argv[0]) is stored as a value with the
127 ** name "__exec_name".
128 **
129 ** 2. Command line arguments of the form "name=value" are parsed
130 ** stored as named values.
131 **
132 ** 3. All other command line arguments are stored as names with
133 ** value = "".
134 **
135 ** 4. A command line argument of form "configfile=filename" will
136 ** override the filename supplied as an argument to this method.
137 **
138 ** 5. In the case of duplicate command line arguments, the last one
139 ** specified wins.
140 **
141 ** 6. In the case of names in the configuration file duplicating
142 ** names from the command line, the values from the command line
143 ** dominate. If there were multiple values for a given name
144 ** specified in the file, only the first one (the one returned by
145 ** the "[]" operator or get<>() method) is overridden.
146 **/
147 unsigned int read(int argc, char* argv[],
148 const std::string & _filename);
149 /// clears the name/value list.
150 void clear();
151 /// returns an iterator to the first item in the list.
152 iterator begin();
153 /// returns an iterator one past the end of the list.
154 iterator end();
155 /// True if there are no values, false otherwise.
156 bool empty();
157 /// Returns the number of values stored.
158 unsigned int size();
159 /** Returns the string value matching the supplied name.
160 **
161 ** NOTE: the use of get<T>(key) or get<T>(key,default) is preferred.
162 ** This method is public to allow for specialized handling in the
163 ** rare cases where it may be required.
164 **
165 ** If there are no matching names, "" is returned. Be aware that
166 ** "" is a valid value, so you can not use this to verify that
167 ** a given name was defined. Use exists() for that.
168 **/
169 std::string operator [] (const std::string & key);
170 /** Returns all values associated with the supplied name.
171 **
172 ** NOTE: the use of getall<T>(key) is preferred. This method is
173 ** public to allow specialized handling in rare case where it
174 ** may be required.
175 **
176 ** If there are no values defined the strlist will be empty.
177 **/
178 strlist all(const std::string & key);
179 /// True if the name exists, false otherwise.
180 bool exists(const std::string & key);
181 /** Use this to get all matching values.
182 **
183 ** Usage:
184 **
185 ** vector<type> mylist = conf_reader_object.getall<type>(key);
186 **
187 ** type can be any standard type (string, int, double, etc.) or any
188 ** type for which the ">>" stream operator is defined. All values
189 ** with matching names that can map to the requested type will be
190 ** returned. Any that do not map will not be returned.
191 **/
192 template < class T >
193 typename std::vector<T> getall(const std::string & key);
194 /** Use this to get the matching value.
195 **
196 ** Useage:
197 **
198 ** type myvar = get<type>(key);
199 **
200 ** type can be any standard type (string, int, double, etc.) or any
201 ** type for which the ">>" stream operator is defined. The return
202 ** value is initialized to all zeros if no matching name is found or
203 ** if the first value with that name does not map to the requested
204 ** type. For the numeric types that results in zero being returned,
205 ** but be aware that more complex object may be in non-sensible
206 ** states if they were not found or could not map. Use exists() to
207 ** verify the existance of a given name if needed.
208 **/
209 template < class T >
210 T get(const std::string & key);
211 /** Returns the value for the requested key, or the supplied default.
212 **
213 ** Works exactly like get<>() with the exception that if the key
214 ** is not found in the list, the user supplied default value is
215 ** returned instead of 0 or an empty string. If the value exists but
216 ** can not map to the requested type, 0 or an empty string is
217 ** returned for the standard types.
218 **/
219 template <class T>
220 T get(const std::string & key, const T & def);
221};
222
223typedef singleton<conf_reader> global_conf_reader;
224
225template < class T >
226 typename std::vector<T> conf_reader::getall(const std::string & key)
227{
228 strlist tvals = all(key);
229 std::vector<T> returnme;
230 if (typeid(T) == typeid(std::string))
231 {
232 // T is a std::string.. we can do this quickly.
233 strlist * wl = (strlist *) &returnme;
234 *wl = tvals;
235 }
236 else
237 {
238 // T is non-string.. will require more playing around.
239 unsigned int limit = tvals.size();
240 for (unsigned int i = 0; i < limit; i++)
241 {
242 try
243 {
244 returnme.push_back(boost::lexical_cast<T>(tvals[i]));
245 }
246 catch (...) {};
247 };
248 };
249 return returnme;
250};
251
252template < class T >
253 T conf_reader::get(const std::string & key)
254{
255 conf_reader & me = *this;
256 std::string tval = me[key];
257 T returnme;
258 // initialize the return value to nulls
259 // Needed for the numeric types, but bad for strings.
260 if (typeid(T) != typeid(std::string))
261 {
262 // null out the working area (death for strings!)
263 memset(&returnme,0,sizeof(T));
264 };
265 // This does appear to work for all the standard types.
266 if (tval != "")
267 {
268 try
269 {
270 returnme = boost::lexical_cast<T>(tval);
271 }
272 catch (...) {};
273 };
274 return returnme;
275};
276
277template < class T >
278 T conf_reader::get(const std::string & key, const T & def)
279{
280 if (exists(key)) { return get<T>(key); }
281 else { return def; };
282};
283
284}; // namespace nrtb
285
286#endif // ricklib_confreader_h
287
0288
=== added file 'common/confreader/conftest.cpp'
--- common/confreader/conftest.cpp 1970-01-01 00:00:00 +0000
+++ common/confreader/conftest.cpp 2011-08-25 04:57:16 +0000
@@ -0,0 +1,129 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19/* confreader test program */
20
21#include "confreader.h"
22#include <log_setup.h>
23#include <iostream>
24#include "Poco/Logger.h"
25#include "Poco/SimpleFileChannel.h"
26//#include "Poco/AutoPtr.h"
27
28using namespace nrtb;
29using namespace std;
30
31int main(int argc, char* argv[])
32{
33 bool set_if_failed = false;
34 setup_global_logging("conf_test.log");
35 Poco::Logger & log = Poco::Logger::get("conftest");
36 log.information("=-=-=-=-=-= conftest Init =-=-=-=-=-=-=");
37 global_conf_reader & config = global_conf_reader::get_instance();
38 try
39 {
40 log.information("Starting read");
41 config.read(argc,argv,"test.config");
42 }
43 catch (...)
44 {
45 set_if_failed = true;
46 cerr << "Failed reading the configuration." << endl;
47 };
48 if (config.size() != 12)
49 {
50 set_if_failed = true;
51 cerr << "Did not find 12 parameters." << endl;
52 };
53 // iterator test
54 try
55 {
56 conf_reader::iterator c = config.begin();
57 conf_reader::iterator e = config.end();
58 while (c != e)
59 {
60 cout << "\t\"" << c->first << "\"=\"" << c->second
61 << "\"" << endl;
62 c++;
63 };
64 }
65 catch (...)
66 {
67 set_if_failed = true;
68 cerr << "Iterator test failed." << endl;
69 };
70 // template test.
71 int test = config.get<int>("test",-1);
72 int test2 = config.get<int>("test2",-1);
73 string test3 = config.get<string>("test3","not specified");
74 double test4 = config.get<double>("test",-1);
75 double test5 = config.get<double>("test2",-1);
76 cout << "(int) test = " << test
77 << "\n(int) test2 = " << test2
78 << "\n(string) test3 = \"" << test3 << "\""
79 << "\n(double) test = " << test4
80 << "\n(double) test2 = " << test5
81 << endl;
82 if (
83 (test != 1) or (test2 != 0)
84 or (test3 != "jack danials")
85 or (test4 != 1.0) or (test5 != 71.837486)
86 )
87 {
88 set_if_failed = true;
89 cerr << "** Template test failed." << endl;
90 };
91 // exists test.
92 cout << "?var \"--doit\" exists? "
93 << (config.exists("--doit") ? "Yes" : "No")
94 << endl;
95 if (!config.exists("--doit"))
96 {
97 set_if_failed = true;
98 cerr << "exists() test failed." << endl;
99 };
100 vector<int> intlist = config.getall<int>("test");
101 cout << "valid int \"test\" values:" << endl;
102 for (unsigned int i=0; i < intlist.size(); i++)
103 {
104 cout << "\t" << i << ": " << intlist[i] << endl;
105 };
106 if (intlist.size() != 2)
107 {
108 set_if_failed = true;
109 cerr << "getall<int>() did not find 2 parameters." << endl;
110 };
111 strlist strings = config.getall<string>("test");
112 cout << "valid string \"test\" values:" << endl;
113 for (unsigned int i=0; i < strings.size(); i++)
114 {
115 cout << "\t" << i << ": " << strings[i] << endl;
116 };
117 if (strings.size() != 3)
118 {
119 set_if_failed = true;
120 cerr << "getall<string>() did not find 3 parameters." << endl;
121 };
122 if (set_if_failed)
123 {
124 cerr << "** ntrb::conf_reader UNIT TEST FAILED. **" << endl;
125 log.fatal("UNIT TEST FAILED");
126 };
127 log.information("Run Complete");
128 return set_if_failed;
129};
0130
=== added file 'common/confreader/test.config'
--- common/confreader/test.config 1970-01-01 00:00:00 +0000
+++ common/confreader/test.config 2011-08-25 04:57:16 +0000
@@ -0,0 +1,27 @@
1###### config reader test file ######
2# use this command line to properly test this:
3#
4# ./conftest test=1 test2=2 test2=71.837486 test3="jack danials" --doit
5#
6# You should get a warning about problems reading dummyfile, and 12
7# variables listed. "test" should be 2 overridden by the command line.
8# You can test the ability to override the config file name with the
9# command:
10#
11# ./conftest configfile=dummy
12#
13# It should complain about problems reading dummy, and no variables
14# should be populated.
15#
16
17fileversion version 1.0
18hashtest \#surrounded\# \#by\# \#hashes\#
19test nonsense # should be overridden by commmand line
20test duh! # what happens here?
21\#starthash should start with hash (\#) symbol
22test 21 # should only be seen in getall<int>();
23test3 Working line.
24
25*INCLUDE dummyfile
26#*INCLUDE ../../salesman/tests/bc_bench.config
27lastline this should be complete
028
=== 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-25 04:57:16 +0000
@@ -0,0 +1,42 @@
1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: log_test
20 @echo "Testing..."
21 @rm -f test_output.log
22 @./log_test
23 @grep "Program run complete." test_output.log
24 @cp -fv log_setup.h ../include
25 @cp -fv log_setup.o ../obj
26
27
28log_setup.o: log_setup.h log_setup.cpp Makefile
29 @rm -f log_setup.o
30 g++ -c log_setup.cpp -I ../include
31
32log_test: log_setup.o log_test.cpp Makefile
33 @rm -vf log_test
34 g++ -c log_test.cpp -I../include
35 g++ -o log_test log_setup.o log_test.o -lPocoFoundation
36# g++ -g common_test.cpp -idirafter . -o common_test
37
38clean:
39 @rm -vf *.o log_test ../include/log_setup.h ../obj/log_setup.o test_output.log
40
41
42
043
=== 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-25 04:57:16 +0000
@@ -0,0 +1,43 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include "log_setup.h"
20
21#include "Poco/SimpleFileChannel.h"
22#include "Poco/FormattingChannel.h"
23#include "Poco/PatternFormatter.h"
24#include "Poco/Logger.h"
25#include "Poco/AutoPtr.h"
26
27using Poco::SimpleFileChannel;
28using Poco::FormattingChannel;
29using Poco::PatternFormatter;
30using Poco::Logger;
31using Poco::AutoPtr;
32
33void nrtb::setup_global_logging(const std::string & logfilename)
34{
35 AutoPtr<SimpleFileChannel> pFile(new SimpleFileChannel);
36 pFile->setProperty("path", logfilename);
37 pFile->setProperty("rotation", "250 K");
38 AutoPtr<PatternFormatter> pPF(new PatternFormatter);
39 pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S [%s:%p] %t");
40 AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pFile));
41 Logger::root().setChannel(pFC);
42 Logger::root().notice("Logging system initialized");
43}
0\ No newline at end of file44\ No newline at end of file
145
=== 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-25 04:57:16 +0000
@@ -0,0 +1,30 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#ifndef logger_setup_h
20#define logger_setup_h
21
22#include <string>
23
24namespace nrtb
25{
26
27 void setup_global_logging(const std::string & logfilename);
28}
29
30#endif //logger_setup_h
0\ No newline at end of file31\ No newline at end of file
132
=== 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-25 04:57:16 +0000
@@ -0,0 +1,46 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include "log_setup.h"
20
21#include <string>
22#include <iostream>
23#include <Poco/Logger.h>
24#include "Poco/LogStream.h"
25
26using namespace std;
27
28int main()
29{
30 bool set_if_failed = false;
31 try
32 {
33 nrtb::setup_global_logging("test_output.log");
34 Poco::Logger & logger = Poco::Logger::get("log_test");
35 logger.notice("Logging should be set up now.");
36 Poco::LogStream log(logger);
37 log << "This message used the stream interface" << endl;
38 logger.notice("Program run complete.");
39 }
40 catch (...)
41 {
42 set_if_failed = true;
43 cout << "** UNIT TEST FAILED **" << endl;
44 };
45 return set_if_failed;
46}
047
=== 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 @@
1
2build: plugin_wrapper.o plugin_manager.o
3 @echo build complete
4
5plugin_wrapper.o: plugin_wrapper.h plugin_wrapper.cpp Makefile
6 @rm -f plugin_wrapper.o
7 g++ -c -O3 plugin_wrapper.cpp -idirafter ../../include3
8# g++ -c -g plugin_wrapper.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
9
10plugin_manager.o: plugin_manager.h plugin_manager.cpp Makefile
11 @rm -f plugin_manager.o
12 g++ -c -O3 plugin_manager.cpp -idirafter ../../include3
13# g++ -c -g plugin_wrapper.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
14
15test: plugin_wrapper.o plugin_manager.o wrapper_test.cpp
16 @rm -f plugin_test
17 g++ -c plugin_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
18# g++ -c -g conftest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
19 g++ -o plugtest plugtest.o plugin_wrapper.o plugin_manager.o -l ricklib3 -L../../lib/
20
21clean:
22 @rm -rvf *.o plugin_test ../../include3/plugin_wrapper.h ../../include3/plugin_manager.h
23 ar -d ../../lib/libricklib3.a plugin_wrapper.o plugin_manager.o
24 @echo all objects and executables have been erased.
25
26lib: test
27 @ar -r ../../lib/libricklib3.a plugin_wrapper.o plugin_manager.o
28 @echo the plugin_wrapper class has been added to the library
29 @cp -fv plugin_wrapper.h plugin_manager.h ../../include3
300
=== 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 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2008-07-12T19:11:33" xmi.version="1.2" >
3 <XMI.header>
4 <XMI.documentation>
5 <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
6 <XMI.exporterVersion>1.5.8</XMI.exporterVersion>
7 <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
8 </XMI.documentation>
9 <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
10 </XMI.header>
11 <XMI.content>
12 <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="UML Model" >
13 <UML:Namespace.ownedElement>
14 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
15 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
16 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="singleton&lt;work_queue_thread&lt;message>>" isRoot="false" isAbstract="false" name="singleton&lt;work_queue_thread&lt;message>>" />
17 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="singleton" isRoot="false" isAbstract="false" name="singleton" />
18 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="thread::run" isRoot="false" isAbstract="false" name="thread::run" />
19 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="simObject, ricklib::thread" isRoot="false" isAbstract="false" name="simObject, ricklib::thread" />
20 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="map&lt;string,plugin_list>" isRoot="false" isAbstract="false" name="map&lt;string,plugin_list>" />
21 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="map&lt;string,plugins_by_name>" isRoot="false" isAbstract="false" name="map&lt;string,plugins_by_name>" />
22 <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="triad&lt;double>" isRoot="false" isAbstract="false" name="triad&lt;double>" />
23 <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
24 <UML:Namespace.ownedElement>
25 <UML:Package stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
26 <UML:Namespace.ownedElement>
27 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Ffh4kk3Ca5c0" isRoot="false" isAbstract="false" name="int" />
28 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="dwxIyKY9DGUT" isRoot="false" isAbstract="false" name="char" />
29 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="80aYqgH4Lz85" isRoot="false" isAbstract="false" name="bool" />
30 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hBHFFrFqnD9j" isRoot="false" isAbstract="false" name="float" />
31 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="VfqivJ93JiZ9" isRoot="false" isAbstract="false" name="double" />
32 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="OrDjoJmVT3kg" isRoot="false" isAbstract="false" name="short" />
33 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="syWd9dNeIDLC" isRoot="false" isAbstract="false" name="long" />
34 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="WSFnAnxYc8FQ" isRoot="false" isAbstract="false" name="unsigned int" />
35 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Q1tt2bZuZ5Yg" isRoot="false" isAbstract="false" name="unsigned short" />
36 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="htJz4eBZ4PMF" isRoot="false" isAbstract="false" name="unsigned long" />
37 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="CHlmQ1Co03h3" isRoot="false" isAbstract="false" name="string" />
38 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="z2PlKwwnqyeq" isRoot="false" isAbstract="false" name="void *" />
39 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="FWxLRQq7CGim" isRoot="false" isAbstract="false" name="abstract_weapon *" />
40 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="81JjStCiP83q" isRoot="false" isAbstract="false" name="abstract_sensor *" />
41 <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="qUlL5Ja8j1rY" isRoot="false" isAbstract="false" name="abstract_chassis *" />
42 </UML:Namespace.ownedElement>
43 </UML:Package>
44 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="225YrWUg6CUk" isRoot="false" isAbstract="true" name="plugin_wrapper" >
45 <UML:GeneralizableElement.generalization>
46 <UML:Generalization xmi.idref="vIs8sXpoyxA8" />
47 </UML:GeneralizableElement.generalization>
48 <UML:Classifier.feature>
49 <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" />
50 <UML:Attribute comment="The version number of this plugin." isSpecification="false" visibility="protected" xmi.id="ToJfQEMPzsZc" type="hBHFFrFqnD9j" name="version" />
51 <UML:Attribute comment="The name of this plugin." isSpecification="false" visibility="protected" xmi.id="9egRonGpPYT7" type="CHlmQ1Co03h3" name="plugin_name" />
52 <UML:Attribute comment="The path of the shared library implementing this plugin." isSpecification="false" visibility="protected" xmi.id="ZRl1ZW499wAW" type="YMxgqxXjjUHD" name="path" />
53 <UML:Attribute isSpecification="false" visibility="protected" xmi.id="wOLstKsOU3xd" type="ZSpIFcMrTgYw" name="factory_address" />
54 <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" >
55 <UML:BehavioralFeature.parameter>
56 <UML:Parameter comment="The path of shared library file implementing the plugin." isSpecification="false" visibility="private" xmi.id="95QVtX2h9xRU" value="" type="YMxgqxXjjUHD" name="path" />
57 </UML:BehavioralFeature.parameter>
58 </UML:Operation>
59 <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" >
60 <UML:BehavioralFeature.parameter>
61 <UML:Parameter comment="The path to the library to be loaded." isSpecification="false" visibility="private" xmi.id="SOCOuP71SVVL" value="" type="YMxgqxXjjUHD" name="loadpath" />
62 </UML:BehavioralFeature.parameter>
63 </UML:Operation>
64 <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" >
65 <UML:BehavioralFeature.parameter>
66 <UML:Parameter kind="return" xmi.id="hG7NjAual1aw" type="CHlmQ1Co03h3" />
67 </UML:BehavioralFeature.parameter>
68 </UML:Operation>
69 <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" >
70 <UML:BehavioralFeature.parameter>
71 <UML:Parameter kind="return" xmi.id="jxjLJCew2LSN" type="hBHFFrFqnD9j" />
72 </UML:BehavioralFeature.parameter>
73 </UML:Operation>
74 <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" >
75 <UML:BehavioralFeature.parameter>
76 <UML:Parameter kind="return" xmi.id="g1RhawLICSft" type="CHlmQ1Co03h3" />
77 </UML:BehavioralFeature.parameter>
78 </UML:Operation>
79 <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" >
80 <UML:BehavioralFeature.parameter>
81 <UML:Parameter kind="return" xmi.id="9tDR3e4vEZMa" type="YMxgqxXjjUHD" />
82 </UML:BehavioralFeature.parameter>
83 </UML:Operation>
84 <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="n1z8iZxdRl3R" isRoot="false" isAbstract="false" isQuery="false" name="newInstance" />
85 </UML:Classifier.feature>
86 </UML:Class>
87 <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="1dJfkTAS2RQE" isRoot="false" isAbstract="false" name="std" >
88 <UML:Namespace.ownedElement/>
89 </UML:Package>
90 <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="rsozaUfviJVQ" isRoot="false" isAbstract="false" name="boost" >
91 <UML:Namespace.ownedElement>
92 <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="rsozaUfviJVQ" xmi.id="hQQSxzuiyRF1" isRoot="false" isAbstract="false" name="filesystem" >
93 <UML:Namespace.ownedElement>
94 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="hQQSxzuiyRF1" xmi.id="YMxgqxXjjUHD" isRoot="false" isAbstract="false" name="path" />
95 </UML:Namespace.ownedElement>
96 </UML:Package>
97 </UML:Namespace.ownedElement>
98 </UML:Package>
99 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ZSpIFcMrTgYw" isRoot="false" isAbstract="false" name="factory_ptr" />
100 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="5RxrSpb7LxuI" isRoot="false" isAbstract="false" name="weapon_plugin" >
101 <UML:GeneralizableElement.generalization>
102 <UML:Generalization xmi.idref="FgcyZa21VrTL" />
103 </UML:GeneralizableElement.generalization>
104 <UML:Classifier.feature>
105 <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" />
106 </UML:Classifier.feature>
107 </UML:Class>
108 <UML:Generalization isSpecification="false" child="5RxrSpb7LxuI" visibility="public" namespace="Logical View" xmi.id="FgcyZa21VrTL" parent="225YrWUg6CUk" discriminator="" name="" />
109 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Y1oRrxMFYzBw" isRoot="false" isAbstract="false" name="sensor_plugin" >
110 <UML:GeneralizableElement.generalization>
111 <UML:Generalization xmi.idref="QAC4gEA4Cbfh" />
112 </UML:GeneralizableElement.generalization>
113 <UML:Classifier.feature>
114 <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" />
115 </UML:Classifier.feature>
116 </UML:Class>
117 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="PyRdWPmTPloe" isRoot="false" isAbstract="false" name="etc_plugin" >
118 <UML:GeneralizableElement.generalization>
119 <UML:Generalization xmi.idref="nenipvZyQWG1" />
120 </UML:GeneralizableElement.generalization>
121 <UML:Classifier.feature>
122 <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" />
123 </UML:Classifier.feature>
124 </UML:Class>
125 <UML:Generalization isSpecification="false" child="Y1oRrxMFYzBw" visibility="public" namespace="Logical View" xmi.id="QAC4gEA4Cbfh" parent="225YrWUg6CUk" discriminator="" name="" />
126 <UML:Generalization isSpecification="false" child="225YrWUg6CUk" visibility="public" namespace="Logical View" xmi.id="vIs8sXpoyxA8" parent="PyRdWPmTPloe" discriminator="" name="" />
127 <UML:Generalization isSpecification="false" child="PyRdWPmTPloe" visibility="public" namespace="Logical View" xmi.id="nenipvZyQWG1" parent="225YrWUg6CUk" discriminator="" name="" />
128 <UML:Class stereotype="singleton" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="WT0Ka8jF10jk" isRoot="false" isAbstract="false" name="plugin_manager" >
129 <UML:Classifier.feature>
130 <UML:Attribute isSpecification="false" visibility="protected" xmi.id="HPMtw9k0PQzT" type="ohv3mPtcgGzX" name="plugins" />
131 <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" />
132 <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" >
133 <UML:BehavioralFeature.parameter>
134 <UML:Parameter comment="The class of plugin requested" isSpecification="false" visibility="private" xmi.id="r12fGT7KZYDL" value="" type="CHlmQ1Co03h3" name="plugin_type" />
135 <UML:Parameter comment="The name of the plugin requested." isSpecification="false" visibility="private" xmi.id="WNwM6CGchsAd" value="" type="CHlmQ1Co03h3" name="name" />
136 </UML:BehavioralFeature.parameter>
137 </UML:Operation>
138 <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" />
139 <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" >
140 <UML:BehavioralFeature.parameter>
141 <UML:Parameter kind="return" xmi.id="6dRTso5oWpKV" type="CHlmQ1Co03h3" />
142 </UML:BehavioralFeature.parameter>
143 </UML:Operation>
144 <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" >
145 <UML:BehavioralFeature.parameter>
146 <UML:Parameter comment="Path to the shared libary to be loaded." isSpecification="false" visibility="private" xmi.id="RbQYsO69oaag" value="" type="YMxgqxXjjUHD" name="path" />
147 </UML:BehavioralFeature.parameter>
148 </UML:Operation>
149 <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" >
150 <UML:BehavioralFeature.parameter>
151 <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" />
152 <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" />
153 </UML:BehavioralFeature.parameter>
154 </UML:Operation>
155 <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" />
156 <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" >
157 <UML:BehavioralFeature.parameter>
158 <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" />
159 </UML:BehavioralFeature.parameter>
160 </UML:Operation>
161 </UML:Classifier.feature>
162 <UML:Namespace.ownedElement>
163 <UML:Class stereotype="map&lt;string,plugins_by_name>" isSpecification="false" isLeaf="false" visibility="public" namespace="WT0Ka8jF10jk" xmi.id="qoJ98w4raNBZ" isRoot="false" isAbstract="false" name="plugin_lists_by_class" />
164 </UML:Namespace.ownedElement>
165 </UML:Class>
166 <UML:Class stereotype="map&lt;string,plugin_list>" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="eLKy62PhoKwL" isRoot="false" isAbstract="false" name="plugins_by_name" />
167 <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="TBw9yE3Jk8tz" name="" >
168 <UML:Association.connection>
169 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="OBQB4JJHyejP" aggregation="aggregate" type="qoJ98w4raNBZ" name="" multiplicity="0..n" />
170 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="tUGb3kMc58zH" aggregation="none" type="eLKy62PhoKwL" name="" />
171 </UML:Association.connection>
172 </UML:Association>
173 <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xRtgdkgsvOEx" name="" >
174 <UML:Association.connection>
175 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Vq2iVy3r9S2B" aggregation="aggregate" type="225YrWUg6CUk" name="" multiplicity="1..n" />
176 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lJSix95qbJQe" aggregation="none" type="eLKy62PhoKwL" name="" />
177 </UML:Association.connection>
178 </UML:Association>
179 <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="iYP4MN0Qbl9T" name="" >
180 <UML:Association.connection>
181 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4mG9sDPO2P4V" aggregation="aggregate" type="eLKy62PhoKwL" name="" multiplicity="1..n" />
182 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="N7KVZMgJd7zb" aggregation="none" type="225YrWUg6CUk" name="" />
183 </UML:Association.connection>
184 </UML:Association>
185 <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ohv3mPtcgGzX" isRoot="false" isAbstract="false" name="plugin_lists_by_class" />
186 <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="D6HDTiBxzfAu" name="" >
187 <UML:Association.connection>
188 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="uwmwLqPgvj9T" aggregation="composite" type="WT0Ka8jF10jk" name="" />
189 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="5qkhvjG9ldx6" aggregation="none" type="WT0Ka8jF10jk" name="" />
190 </UML:Association.connection>
191 </UML:Association>
192 <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ozgldpf0rhYJ" name="" >
193 <UML:Association.connection>
194 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="RSWw91M3x6yG" aggregation="composite" type="WT0Ka8jF10jk" name="" />
195 <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="wNuq74JAs3rn" aggregation="none" type="qoJ98w4raNBZ" name="" />
196 </UML:Association.connection>
197 </UML:Association>
198 </UML:Namespace.ownedElement>
199 <XMI.extension xmi.extender="umbrello" >
200 <diagrams>
201 <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" >
202 <widgets>
203 <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" />
204 <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" />
205 <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" />
206 <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" />
207 <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:
208
209For this to work, plugin_wrapper must assume each plugin will export the following symbols:
210
211Variables:
212 string PTYPE: the plugin type (weapon, sensor, etc.)
213 string PNAME: the name of this particular plugin
214 string PVER: the version number of this particular plugin
215
216Function
217 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" />
218 </widgets>
219 <messages/>
220 <associations>
221 <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="eLKy62PhoKwL" widgetaid="qoJ98w4raNBZ" xmi.id="TBw9yE3Jk8tz" type="501" linecolor="none" >
222 <linepath>
223 <startpoint startx="149" starty="114" />
224 <endpoint endx="148" endy="68" />
225 </linepath>
226 <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" />
227 </assocwidget>
228 <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="225YrWUg6CUk" widgetaid="eLKy62PhoKwL" xmi.id="iYP4MN0Qbl9T" type="501" linecolor="none" >
229 <linepath>
230 <startpoint startx="248" starty="41" />
231 <endpoint endx="445" endy="136" />
232 </linepath>
233 <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" />
234 </assocwidget>
235 <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="qoJ98w4raNBZ" widgetaid="WT0Ka8jF10jk" xmi.id="ozgldpf0rhYJ" type="510" linecolor="none" >
236 <linepath>
237 <startpoint startx="195" starty="219" />
238 <endpoint endx="149" endy="168" />
239 </linepath>
240 </assocwidget>
241 </associations>
242 </diagram>
243 </diagrams>
244 </XMI.extension>
245 </UML:Model>
246 <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" >
247 <UML:Namespace.ownedElement/>
248 </UML:Model>
249 <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
250 <UML:Namespace.ownedElement/>
251 </UML:Model>
252 <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
253 <UML:Namespace.ownedElement/>
254 </UML:Model>
255 <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" >
256 <UML:Namespace.ownedElement/>
257 </UML:Model>
258 </UML:Namespace.ownedElement>
259 </UML:Model>
260 </XMI.content>
261 <XMI.extensions xmi.extender="umbrello" >
262 <docsettings viewid="DukLGrX7Qs7l" documentation="" uniqueid="KaC8tCfxNnbM" />
263 <listview>
264 <listitem open="1" type="800" label="Views" >
265 <listitem open="1" type="801" id="Logical View" >
266 <listitem open="0" type="807" id="DukLGrX7Qs7l" label="Plugin Manager Overview" />
267 <listitem open="1" type="813" id="PyRdWPmTPloe" >
268 <listitem open="0" type="815" id="EC8j9pFAdKdx" />
269 </listitem>
270 <listitem open="1" type="813" id="ZSpIFcMrTgYw" />
271 <listitem open="1" type="813" id="ohv3mPtcgGzX" />
272 <listitem open="1" type="813" id="WT0Ka8jF10jk" >
273 <listitem open="0" type="813" id="qoJ98w4raNBZ" />
274 <listitem open="0" type="814" id="HPMtw9k0PQzT" />
275 <listitem open="0" type="815" id="46RtlzCdqiGw" />
276 <listitem open="0" type="815" id="YVcYycxZS0QM" />
277 <listitem open="0" type="815" id="niINN8W0bcBT" />
278 <listitem open="0" type="815" id="HQVTuW3lNEMc" />
279 <listitem open="0" type="815" id="yilX1rI1K1Ye" />
280 <listitem open="0" type="815" id="SOhcCFAtLoIm" />
281 <listitem open="0" type="815" id="cu3qBV5M3heD" />
282 <listitem open="0" type="815" id="D9eyZpw9jz0s" />
283 </listitem>
284 <listitem open="1" type="813" id="225YrWUg6CUk" >
285 <listitem open="0" type="814" id="0kYAfH74JA7p" />
286 <listitem open="0" type="814" id="ToJfQEMPzsZc" />
287 <listitem open="0" type="814" id="9egRonGpPYT7" />
288 <listitem open="0" type="814" id="ZRl1ZW499wAW" />
289 <listitem open="0" type="814" id="wOLstKsOU3xd" />
290 <listitem open="0" type="815" id="evlKlgpUQJmb" />
291 <listitem open="0" type="815" id="j7HBVbv71scs" />
292 <listitem open="0" type="815" id="gx1dfJPPtVf7" />
293 <listitem open="0" type="815" id="lh0Se8lUfT5X" />
294 <listitem open="0" type="815" id="fqiWLNb62bXe" />
295 <listitem open="0" type="815" id="EADACWaXDZwu" />
296 <listitem open="0" type="815" id="n1z8iZxdRl3R" />
297 </listitem>
298 <listitem open="1" type="813" id="eLKy62PhoKwL" />
299 <listitem open="1" type="813" id="Y1oRrxMFYzBw" >
300 <listitem open="0" type="815" id="0zNHSOUVzjY3" />
301 </listitem>
302 <listitem open="1" type="813" id="5RxrSpb7LxuI" >
303 <listitem open="0" type="815" id="WStI1XSjbrPt" />
304 </listitem>
305 <listitem open="1" type="818" id="rsozaUfviJVQ" >
306 <listitem open="1" type="818" id="hQQSxzuiyRF1" >
307 <listitem open="1" type="813" id="YMxgqxXjjUHD" />
308 </listitem>
309 </listitem>
310 <listitem open="1" type="818" id="1dJfkTAS2RQE" />
311 <listitem open="1" type="830" id="Datatypes" >
312 <listitem open="1" type="829" id="qUlL5Ja8j1rY" />
313 <listitem open="1" type="829" id="81JjStCiP83q" />
314 <listitem open="1" type="829" id="FWxLRQq7CGim" />
315 <listitem open="1" type="829" id="80aYqgH4Lz85" />
316 <listitem open="1" type="829" id="dwxIyKY9DGUT" />
317 <listitem open="1" type="829" id="VfqivJ93JiZ9" />
318 <listitem open="1" type="829" id="hBHFFrFqnD9j" />
319 <listitem open="1" type="829" id="Ffh4kk3Ca5c0" />
320 <listitem open="1" type="829" id="syWd9dNeIDLC" />
321 <listitem open="1" type="829" id="OrDjoJmVT3kg" />
322 <listitem open="1" type="829" id="CHlmQ1Co03h3" />
323 <listitem open="1" type="829" id="WSFnAnxYc8FQ" />
324 <listitem open="1" type="829" id="htJz4eBZ4PMF" />
325 <listitem open="1" type="829" id="Q1tt2bZuZ5Yg" />
326 <listitem open="1" type="829" id="z2PlKwwnqyeq" />
327 </listitem>
328 </listitem>
329 <listitem open="1" type="802" id="Use Case View" />
330 <listitem open="1" type="821" id="Component View" />
331 <listitem open="1" type="827" id="Deployment View" />
332 <listitem open="1" type="836" id="Entity Relationship Model" />
333 </listitem>
334 </listview>
335 <codegeneration>
336 <codegenerator language="C++" />
337 </codegeneration>
338 </XMI.extensions>
339</XMI>
3400
=== 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 @@
1//
2// C++ Implementation: plugin_manager
3//
4// Description:
5//
6//
7// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
13#include "plugin_manager.h"
14
15//use boost::filesystem;
16//use boost::filesystem::directory_iterator;
17
18
19// TODO: review to make sure all methods from the .h are implemented.
20namespace NRTB
21{
22
23 plugin_manager::plugin_manager()
24 {
25 // nop in this version.
26 };
27
28 plugin_manager::plugin_manager(const boost::filesystem::path loadpath)
29 {
30 plugin_manager();
31 load_all(loadpath);
32 };
33
34 plugin_manager::~plugin_manager()
35 {
36 release_all();
37 };
38
39 void plugin_manager::load_all(const boost::filesystem::path loadpath)
40 {
41 // check to if loadpath really exists
42 if (!boost::filesystem::exists(loadpath))
43 {
44 path_not_found e;
45 e.store(loadpath.native_directory_string());
46 throw e;
47 };
48 if (!is_directory(loadpath))
49 {
50 not_a_directory e;
51 e.store(loadpath.native_file_string());
52 throw e;
53 };
54 // set up for the scan
55 boost::filesystem::directory_iterator end; // points to the end of the list
56 boost::filesystem::directory_iterator current(loadpath);
57 while (current != end)
58 {
59 if (is_directory(*current))
60 {
61 // recursive call to process the directory.
62 load_all(*current);
63 }
64 else
65 {
66 // try to load the plugin
67 try
68 {
69 load_one(*current);
70 }
71 catch (plugin_wrapper::invalid_plugin & e)
72 {
73 // take no action in this caee...
74 };
75 };
76 current++;
77 };
78 };
79
80 void plugin_manager::load_one(const boost::filesystem::path loadpath)
81 {
82 // check to if loadpath really exists
83 if (!boost::filesystem::exists(loadpath))
84 {
85 path_not_found e;
86 e.store(loadpath.native_directory_string());
87 throw e;
88 };
89 if (boost::filesystem::is_directory(loadpath))
90 {
91 plugin_file_not_found e;
92 e.store(loadpath.native_file_string());
93 throw e;
94 };
95 /* NOTE: since wrapper_p is a smart pointer, any memory
96 allocated to it will be discarded if an exception
97 is thrown in the following section.
98 */
99 // Create the plugin_wrapper.
100 wrapper_p new_plugin(new plugin_wrapper);
101 // Load it... will throw if somehing's not right.
102 new_plugin->load(loadpath);
103 // Store it in our list.
104 plugins[new_plugin->get_type()][new_plugin->get_name()] = new_plugin;
105 };
106
107 void plugin_manager::release_all()
108 {
109 // this will call the destructor and deallocate all
110 // plugin_wrappers currently loaded.
111 plugins.clear();
112 };
113
114 void plugin_manager::release_one(const std::string pclass,
115 const std::string name)
116 {
117 // TODO: more here.
118 plugins[pclass].erase(name);
119 };
120
121 std::string plugin_manager::dump()
122 {
123 // TODO: More to do here.
124 };
125
126}; // namespace NRTB
127
1280
=== 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 @@
1//
2// C++ Interface: plugin_manager
3//
4// Description:
5//
6//
7// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
13#ifndef plugin_manager_h
14#define plugin_manager_h
15
16#include "plugin_wrapper.h"
17#include <map>
18
19namespace NRTB
20{
21 /**
22 * Provides a simple mechanism for an application to
23 * load and manage plugins (shared objects in the unix lingo)
24 * which provide the application with functionality not
25 * not available at the time it was built.
26 *
27 * To be useable with this class a shared object must
28 * meet certain requirements which are outlined in the
29 * NRTB::plugin_wrapper class documentation. Example
30 * plugins are also provided.
31 */
32 class plugin_manager
33 {
34 public:
35 /// Typedef for return values
36 typedef std::vector<std::string> strlist;
37 /// parent for all exceptions thrown by this class
38 class general_exception: public base_exception {};
39 /// thrown if a specified plugin file was no found.
40 class plugin_file_not_found: public general_exception {};
41 /// thrown if a specified load path (directory) was not found.
42 class path_not_found: public general_exception {};
43 /// thown if a specified load path is not a directory.
44 class not_a_directory: public general_exception {};
45 /// thrown if a specifically requested plugin is not loaded.
46 class plugin_not_found: public general_exception {};
47 /**
48 * Simple constructor.
49 */
50 plugin_manager();
51 /**
52 * Constructs the class and then attempts to load all
53 * files found under the given path (recursively) as
54 * plugins.Non-plugin files will be ignored, but
55 * problems reading the given path (path not found,
56 * insufficient permissions, etc.) will cause an
57 * exception to be thrown.
58 *
59 * @param loadpath The top of the file tree to be searched.
60 */
61 plugin_manager(const boost::filesystem::path loadpath);
62 /**
63 * Unloads all managed plugins and destructs the
64 * plugin_manager. Probably not a good thing to do
65 * while any of the plugins are in use.
66 */
67 virtual ~plugin_manager();
68 /**
69 * Attempts to load all files found under the
70 * given path (recursively) as plugins.Non-plugin
71 * files will be ignored, but problems reading the
72 * given path (path not found, insufficient
73 * permissions, etc.) will cause an exception to be thrown.
74 *
75 * If two plugins have the same class and name, the one
76 * with the highest version number will be kept and
77 * the other(s) discarded.
78 *
79 * @param loadpath The top of the file tree to be searched.
80 */
81 void load_all(const boost::filesystem::path loadpath);
82 /**
83 * Attempts to load a plugin from the fully qualified
84 * file path given. Exceptions will be thrown if there
85 * are any problems reading the file, or if it is not a
86 * valid plugin (by plugin_wrapper standards).
87 *
88 * If two plugins have the same class and name, the one
89 * with the highest version number will be kept and
90 * the other(s) discarded.
91 *
92 * @param loadpath A fully qualified file path.
93 */
94 void load_one(const boost::filesystem::path loadpath);
95 /**
96 * Releases all plugins currently being managed. Probably
97 * not a good thing to do if any of them are being used.
98 */
99 void release_all();
100 /**
101 * Attempts to release the single plugin matching the
102 * provided plugin class and name. An exception will be thrown
103 * if the plugin is not found.
104 *
105 * @param pclass The class of the plugin to release.
106 * @param name The name of the plugin to release.
107 */
108 void release_one(const std::string pclass, const std::string name);
109 /**
110 * Dumps a list of all loaded plugins, intended for
111 * diagnostic purposes. The list is formatted:
112 *
113 * plugin_class::plugin_name<eol>
114 *
115 * with one line for each plugin loaded.
116 *
117 * @return A string contianing a formatted plugin listing.
118 */
119 std::string dump();
120 /**
121 * Returns a strlist (a vector<string>) containing
122 * all unique plugin class names loaded, in alpha order.
123 *
124 * @return A list of all unique plugin classes loaded.
125 */
126 strlist get_class_names();
127 /**
128 * Returns a strlist (a vector<string>) containing
129 * the names of all plugins loaded of the given plugin class.
130 *
131 * @param pclass The name of the plugin class to be searched.
132 * @return A list of all plugins loaded for the given plugin class.
133 */
134 strlist get_class_plugin_names(const std::string pclass);
135 /**
136 * Returns true if a plugin with the given class
137 * and name exists, or faise if not.
138 *
139 * @param pclass The class name of the plugin to be checked.
140 * @param pname The name of the plugin to be checked
141 * @return True if the plugin is laoded, false otherwise.
142 */
143 bool exists(const std::string pclass, const std::string pname);
144 /**
145 * Returns a boost::shared_ptr<T> to a new instance
146 * of the class provided by the plugin specified by
147 * the plugin_class and plugin_name provided.
148 *
149 * Usage example:
150 * myTypePointer = create_plugin_instance<mytype>(class,name);
151 *
152 * This routine will succeed unconditionally or throw
153 * one of several possible exceptions. In no case will a
154 * null pointer or improperly constructed instance be
155 * returned.
156 *
157 * @param plugin_class The class name of the plugin desired
158 * @param plugin_name The name of the plugin desired.
159 * @return A boost::shared_ptr<T> to a ready to use instance.
160 */
161 template <class T> boost::shared_ptr<T> create_plugin_instance
162 (
163 const std::string plugin_class,
164 const std::string plugin_name
165 )
166 {
167 typedef boost::shared_ptr<T> returntype;
168 if (!exists(plugin_class, plugin_name))
169 {
170 plugin_not_found e;
171 e.store(plugin_class+"::"+plugin_name);
172 throw e;
173 };
174 returntype returnme =
175 plugins[plugin_class][plugin_name]->create_instance<T>();
176 return returnme;
177 };
178 protected:
179 // smart pointer to a plugin_wrapper
180 typedef boost::shared_ptr<plugin_wrapper> wrapper_p;
181 // type used contain plugins of the same type
182 typedef std::map<std::string, wrapper_p> plugins_by_name;
183 // type used to contain lists of types of plugins.
184 typedef std::map<std::string, plugins_by_name> plugins_list_by_class;
185 // iterator providing access to "plugins_by_name" lists by class
186 typedef plugins_list_by_class::iterator class_iterator;
187 // iterator providing access to individual plugins by name
188 typedef plugins_by_name::iterator plugin_iterator;
189 // container for all plugins being managed.
190 plugins_list_by_class plugins;
191 };
192};
193
194#endif //plugin_manager_h
1950
=== 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 @@
1//
2// C++ Implementation: plugin_wrapper
3//
4// Description:
5//
6//
7// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
13#include "plugin_wrapper.h"
14
15namespace NRTB
16{
17
18 plugin_wrapper::plugin_wrapper()
19 {
20 // Load the "constants"
21 std::string name_key = "PLUGIN_NAME";
22 std::string type_key = "PLUGIN_TYPE";
23 std::string version_key = "PLUGIN_VERSION";
24 std::string factory_key = "PLUGIN_FACTORY";
25 // clear all the associated fields.
26 plugin_type = "";
27 plugin_name = "";
28 plugin_version = 0.0;
29 plugin_path = "";
30 // close the handle if it's already assigned.
31 if (dl_handle)
32 {
33 dlclose(dl_handle);
34 };
35 dl_handle = 0;
36 };
37
38 plugin_wrapper::plugin_wrapper(boost::filesystem::path loadpath)
39 {
40 load(loadpath);
41 };
42
43 plugin_wrapper::~plugin_wrapper()
44 {
45 // close the handle if it's already assigned.
46 if (dl_handle)
47 {
48 dlclose(dl_handle);
49 };
50 dl_handle = 0;
51 };
52
53 void plugin_wrapper::load(boost::filesystem::path loadpath)
54 {
55 // establish initial conditions.
56 plugin_wrapper();
57 if (loadpath.empty())
58 {
59 // an empty path could expose security holes.
60 file_not_found e;
61 e.store("Illegal null path provided");
62 throw e;
63 };
64 dlerror();
65 try
66 {
67 // call dlopen to open the lib
68 dl_handle = dlopen(loadpath.string().c_str(), RTLD_LAZY);
69 if (!dl_handle)
70 {
71 throw new file_not_found;
72 };
73 // load the fields
74 plugin_type = get_value<std::string>(type_key);
75 plugin_name = get_value<std::string>(name_key);
76 plugin_version = get_value<float>(version_key);
77 plugin_path = loadpath;
78 }
79 catch (file_not_found &e)
80 {
81 // is it a missing file or a bad file?
82 if (!boost::filesystem::exists(loadpath))
83 {
84 e.store(loadpath.string());
85 throw e;
86 }
87 else
88 {
89 invalid_plugin ie;
90 ie.store(dlerror());
91 throw ie;
92 };
93 }
94 catch (invalid_plugin & e)
95 {
96 if (e.comment() == "")
97 {
98 e.store(dlerror());
99 };
100 throw e;
101 }
102 catch (std::exception &e)
103 {
104 general_exception ge;
105 ge.store(e.what());
106 throw ge;
107 };
108 };
109
110 std::string plugin_wrapper::get_type()
111 {
112 if (!dl_handle)
113 {
114 throw new not_loaded;
115 };
116 return plugin_type;
117 };
118
119 std::string plugin_wrapper::get_name()
120 {
121 if (!dl_handle)
122 {
123 throw new not_loaded;
124 };
125 return plugin_name;
126 };
127
128 float plugin_wrapper::get_version()
129 {
130 if (!dl_handle)
131 {
132 throw new not_loaded;
133 };
134 return plugin_version;
135 };
136
137 boost::filesystem::path plugin_wrapper::get_path()
138 {
139 if (!dl_handle)
140 {
141 throw new not_loaded;
142 };
143 return plugin_path;
144 };
145
146} // namespace NRTB
1470
=== 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 @@
1//
2// C++ Interface: plugin_wrappr
3//
4// Description:
5//
6//
7// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
13#ifndef plugin_wrapper_h
14#define plugin_wrapper_h
15
16#include <dlfcn.h>
17#include <string>
18#include <ricks_handy.h>
19#include <boost/shared_ptr.hpp>
20#include <boost/filesystem/convenience.hpp>
21
22namespace NRTB
23{
24 /**
25 * A container for a single plugin. A plugin is defined as a
26 * shared object file which provides a class, an associated factory
27 * function, and several housekeeping constants, as follows:
28 *
29 * 1. A std::string identifying the class factory named "PLUGIN_FACTORY"
30 *
31 * 2. A plugin name std::string named "PLUGIN_NAME"
32 *
33 * 3. A plugin type std::stirng named "PLUGIN_TYPE"
34 *
35 * 4. A plugin version number float named "PLUGIN_VERSION"
36 *
37 * This class is not designed to instanticated directly by user code.
38 * Instead, it will be intanciated by the plugin_manager, which acts as
39 * a container for many plugins and provides access to them.
40 *
41 * In call cases except load(), when an exception is thown from a method,
42 * the instance is left the state it was in at the start of the method.
43 **/
44 class plugin_wrapper
45 {
46 public:
47 /// Parent for all plugin_wrapper exceptions.
48 class general_exception: public base_exception {};
49 /// Thrown if a file is not found at the requested path.
50 class file_not_found: public general_exception {};
51 /// Thrown if a requested file does not contain a valid plugin.
52 class invalid_plugin: public general_exception {};
53 /// Thrown if queries are called when no data is present.
54 class not_loaded: public general_exception {};
55 /**
56 * Default constructor; NOP.
57 */
58 plugin_wrapper();
59 /**
60 * This constructor attempts to load a plugin at
61 * the argument provided. Actually calls load() to
62 * to do the work.
63 *
64 * @param loadpath Should be point to a valid plugin file
65 */
66 plugin_wrapper(boost::filesystem::path loadpath);
67 /**
68 * Unloads any plugin, if contained.
69 */
70 virtual ~plugin_wrapper();
71 /**
72 * Discards the current contents of this wrapper, if any,
73 * and then attempts to load the plugin file provided. If there
74 * are any problems, an appropriate exception will be thrown.
75 *
76 * @param loadpath Should point to a valid plugin file.
77 */
78 virtual void load(boost::filesystem::path loadpath);
79 /**
80 * Returns the pligin type associated with the loaded plugin,
81 * or throws if one is not loaded. The plugin type is a string
82 * indicating the what services the plugin provides and in
83 * most cases will have no meaning outside of the application
84 * context.
85 *
86 * For example, a plugin providing printing functionality
87 * may have a type of "printer", while one that provides
88 * database access may have a type of "db_interface".
89 *
90 * @return A std::string indicating plugin type.
91 */
92 virtual std::string get_type();
93 /**
94 * Returns the name of the particular plugin loaded, or
95 * throws if one is not loaded. The name is an arbitrary string
96 * which uniquely identifies a particular plugin within a type.
97 *
98 * For example, a plugin providing printing functionality to
99 * a PDF file may have a type of "printer" and a name of "PDF",
100 * while another "printer" plugin providing output to doc
101 * files may have the name "WordDoc".
102 *
103 * @return A std::string indicating the plugin name.
104 */
105 virtual std::string get_name();
106 /**
107 * Returns the version of the particular plugin loaded, or
108 * throws if one is not loaded. The version is an arbitrary
109 * float value which uniquely identifies a particular version
110 * of a plugin within a name and type.
111 *
112 * @return A float indicating the plugin version.
113 */
114 virtual float get_version();
115 /**
116 * Returns the fully qualified path of the plugin loaded, or
117 * throws if one is not loaded.
118 *
119 * @return A boost::filesystem::path to the plugin file.
120 */
121 boost::filesystem::path get_path();
122 /**
123 * Calls the class factory and returns shared_ptr to an
124 * instance of the type requested. For reliable operation,
125 * the type provided the template must be compatable with
126 * that actually implemented in the plugin.
127 *
128 * An appropriate exception will be thrown if there are issues.
129 *
130 * Usage: mytype myvar createInstance<mytype>();
131 *
132 * @return A boost::shared_ptr to an instanace of
133 * the type provided.
134 */
135 template <class T> boost::shared_ptr<T> create_instance()
136 {
137 if (!dl_handle)
138 {
139 not_loaded e;
140 e.store("create_instance");
141 throw e;
142 };
143 typedef T (*factory_type)();
144 typedef boost::shared_ptr<T> my_pointer;
145 my_pointer returnme;
146 try
147 {
148 factory_type factory = get_value<factory_type>(factory_key);
149 returnme = factory();
150 }
151 catch (std::exception & e)
152 {
153 // Let the caller sort it out.
154 throw;
155 }
156 catch (...)
157 {
158 // most likely a bad problem in the factory function.
159 invalid_plugin e;
160 e.store("create_instance caught an unknown exception");
161 throw e;
162 };
163 return returnme;
164 };
165
166 protected:
167 // gets indivdual field values from the shared lib.
168 template <class T> T get_value(const std::string & key)
169 {
170 typedef T * my_pointer;
171 T returnme;
172 dlerror();
173 my_pointer value = (my_pointer) dlsym(dl_handle,key.c_str());
174 std::string check_error = dlerror();
175 if (!check_error.empty())
176 {
177 invalid_plugin e;
178 e.store(check_error+" ("+key+")");
179 throw e;
180 };
181 if (!value)
182 {
183 invalid_plugin e;
184 e.store("("+key+") returned a null value");
185 throw e;
186 };
187 returnme = *value;
188 return returnme;
189 };
190
191 private:
192 // The following are used to cache plugin data after load.
193 void * dl_handle;
194 std::string plugin_type;
195 std::string plugin_name;
196 float plugin_version;
197 boost::filesystem::path plugin_path;
198 // The following define what labels are expected to be defined.
199 static const std::string name_key;
200 static const std::string type_key;
201 static const std::string version_key;
202 static const std::string factory_key;
203 };
204
205} // nameplace NRTB
206
207#endif // plugin_wrapper_h
2080
=== 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 @@
1
2# makefile for the plugin test routine.
3
4test: ../plugin_wrapper.o ../plugin_manager.o plugintest.cpp
5 @rm -f plugintest
6 g++ -c plugintest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
7# g++ -c -g conftest.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
8 g++ -o plugintest plugintest.o ../plugin_wrapper.o ../plugin_manager.o -l ricklib3 -L../../lib/
9 ./plugintest
10
11clean:
12 @rm -rvf *.o plugintest
13 @echo all objects and executables have been erased.
140
=== 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 @@
1//
2// C++ Implementation: plugintest
3//
4// Description:
5//
6//
7// Author: Rick Stovall <rstovall@gabbie>, (C) 2008
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12
130
=== modified file 'common/point/Makefile'
--- common/point/Makefile 2010-01-14 02:24:25 +0000
+++ common/point/Makefile 2011-08-25 04:57:16 +0000
@@ -1,17 +1,34 @@
1build: common_test Makefile1#***********************************************
2 @echo build complete2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3 3#
4common_test: common_test.cpp triad.h Makefile4# NRTB is free software: you can redistribute it and/or modify
5 @rm -vf triad.o5# it under the terms of the GNU General Public License as published by
6 g++ -O3 common_test.cpp -idirafter . -o common_test6# the Free Software Foundation, either version 3 of the License, or
7# g++ -g common_test.cpp -idirafter . -o common_test7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: common_test Makefile
20 @echo "(2,3.5,7)" | ./common_test
21 @cp -v triad.h ../include
22 @echo nrtb::triad build complete
23
24../include/common.h:
25 @cd ../common_rl; make lib
26
27common_test: common_test.cpp triad.h Makefile ../include/common.h
28 @rm -vf common_test
29 g++ -O3 common_test.cpp -I ../include ../obj/common.o -o common_test
830
9clean:31clean:
10 @rm -vf *.o common_test ../../include3/triad.h32 @rm -vf *.o common_test ../include/triad.h
11
12lib: common_test ../../include3/triad.h
13
14../../include3/triad.h: triad.h
15 @cp -fv triad.h ../../include3
1633
1734
1835
=== 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-25 04:57:16 +0000
@@ -1,4 +1,22 @@
1/*** Test program for triad.h *****/1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19 /*** Test program for triad.h *****/
220
3#include <unistd.h>21#include <unistd.h>
4#include <iostream>22#include <iostream>
@@ -7,56 +25,93 @@
725
8using namespace std;26using namespace std;
927
10typedef NRTB::triad<long double> ld_triad;28typedef nrtb::triad<long double> ld_triad;
29
30int test_triad(const std::string prompt, ld_triad val, ld_triad right, int ec)
31{
32 cout << "\t" << prompt << " = " << val << endl;
33 if (val != right)
34 {
35 ec++;
36 cerr << "\t\tTest Failed: Answer should be " << val << endl;
37 }
38 return ec;
39};
40
41int test_ld(const std::string prompt, long double val, long double right, int ec)
42{
43 cout << "\t" << prompt << " = " << val << endl;
44 if (val != right)
45 {
46 ec++;
47 cerr << "\t\tTest Failed: Answer should be " << val << endl;
48 }
49 return ec;
50};
1151
12int main()52int main()
13{53{
14 ld_triad a(1,2,3);54 ld_triad a(1,2,3);
15 ld_triad b(3,2,1);55 ld_triad b(3,2,1);
56 int returnme = 0;
1657
17 cout << setprecision(10);58 cout << setprecision(10);
18 cout << "=== Triad Test ===" << endl;59 cout << "=== nrtb::triad Unit Test ===" << endl;
19 cout << "\ta = " << a << "; b = " << b << "\n" << endl;60 cout << "\ta = " << a << "; b = " << b << endl;
2061 // basic operations tests
21 cout << "\ta + b = " << a + b << endl;62 returnme = test_triad("a + b",a + b,ld_triad(4,4,4),returnme);
22 cout << "\ta - b = " << a - b << endl;63 returnme = test_triad("a - b",a - b,ld_triad(-2,0,2),returnme);
23 cout << "\ta * b = " << a * b << endl;64 returnme = test_triad("a * b",a * b,ld_triad(3,4,3),returnme);
24 cout << "\ta / b = " << a / b << endl;65 returnme = test_triad("a / b",a / b,ld_triad(1.0d/(long double) 3.0,1,3),returnme);
25 cout << "\ta += b; a = " << (a += b) << endl;66 returnme = test_triad("a += b; a",a += b,ld_triad(4,4,4),returnme);
26 cout << "\ta -= b; a = " << (a -= b) << endl;67 returnme = test_triad("a -= b; a",a -= b,ld_triad(1,2,3),returnme);
27 cout << "\ta *= b; a = " << (a *= b) << endl;68 returnme = test_triad("a *= b; a",a *= b,ld_triad(3,4,3),returnme);
28 cout << "\ta /= b; a = " << (a /= b) << endl;69 returnme = test_triad("a /= b; a",a /= b,ld_triad(1,2,3),returnme);
29 cout << "\n\ta.pow(b) = " << a.pow(b) << endl;70 // power test
30 cout << "\ta.range(b) = " << a.range(b) << endl;71 returnme = test_triad("a.pow(b)",a.pow(b),ld_triad(1,4,3),returnme);
31 cout << "\ta.magnatude() = " << a.magnatude() << endl;72 // range test
32 cout << "\n\ta == a = " << (a == a) << endl;73 ld_triad t = b - a;
33 cout << "\ta == b = " << (a== b) << endl;74 t *= t;
34 cout << "\ta != b = " << (a != b) << endl;75 long double r = sqrt(t.x + t.y + t.z);
35 cout << "\ta != a = " << (a != a) << endl;76 returnme = test_ld("a.range(b)",a.range(b),r,returnme);
3677 // magnatude test
37 cout << endl;78 returnme = test_ld("a.magnatude()",a.magnatude(),a.range(0),returnme);
3879 // boolean tests
39 cout << "\ta + 2 = " << a + 2 << endl;80 returnme = test_ld("a == a",a == a,1,returnme);
40 cout << "\ta - 2 = " << a - 2 << endl;81 returnme = test_ld("a == b",a == b,0,returnme);
41 cout << "\ta * 2 = " << a * 2 << endl;82 returnme = test_ld("a != b",a != b,1,returnme);
42 cout << "\ta / 2 = " << a / 2 << endl;83 returnme = test_ld("a != a",a != a,0,returnme);
43 cout << "\ta += 2; a = " << (a += 2) << endl;84 // point/scalar operations
44 cout << "\ta -= 2; a = " << (a -= 2) << endl;85 returnme = test_triad("a + 2",a + 2,ld_triad(3,4,5),returnme);
45 cout << "\ta *= 2; a = " << (a *= 2) << endl;86 returnme = test_triad("a - 2",a - 2,ld_triad(-1,0,1),returnme);
46 cout << "\ta /= 2; a = " << (a /= 2) << endl;87 returnme = test_triad("a * 2",a * 2,ld_triad(2,4,6),returnme);
47 cout << "\n\ta.pow(2) = " << a.pow(2) << endl;88 returnme = test_triad("a / 2",a / 2,ld_triad(0.5,1,1.5),returnme);
48 cout << "\ta.pow(0.5) = " << a.pow(0.5) << endl;89 returnme = test_triad("a += 2",a += 2,ld_triad(3,4,5),returnme);
90 returnme = test_triad("a -= 2",a -= 2,ld_triad(1,2,3),returnme);
91 returnme = test_triad("a *= 2",a *= 2,ld_triad(2,4,6),returnme);
92 returnme = test_triad("a /= 2",a /= 2,ld_triad(1,2,3),returnme);
93 returnme = test_triad("a.pow(2)",a.pow(2),ld_triad(1,4,9),returnme);
94 // normalization test
49 cout << "\ta.normalize() = " << a.normalize() << endl;95 cout << "\ta.normalize() = " << a.normalize() << endl;
50 cout << "\ta.normalize().magnatude() = "<< a.normalize().magnatude() << endl;96 returnme = test_ld("a.normalize().magnatude()",a.normalize().magnatude(),1.0,returnme);
51 97 // dot and vector product tests.
52 cout << "\n\a\tInput a new value for b (x,y,z): " << flush;98 returnme = test_ld("a.dot_product(b)",a.dot_product(b),10,returnme);
53 cin >> b;99 returnme = test_triad("a.vector_product(b)",a.vector_product(b),
54 cout << "\t\tb = " << b << endl;100 ld_triad(-4,8,-4),returnme);
55 cout << "\tb.to_str() =\"" << b.to_str() << "\"" << endl;101 // string i/o tests, assumes "2,3.5,7) is input.
56 cout << "\tb.from_str(b.to_str(10)) = " << b.from_str(b.to_str(10)) << endl;102 cout << "\tInput a new value for b \"(2,3.5,7)\": " << flush;
57103 cin >> b; cout << endl;
58104 returnme = test_triad("b",b,ld_triad(2,3.5,7),returnme);
59 cout << "\n=== Test Complete ===" << endl;105 returnme = test_triad("b.from_str(b.to_str(10))",
60 return 0;106 b.from_str(b.to_str(10)),ld_triad(2,3.5,7),returnme);
107 // report errors, if any
108 if (returnme)
109 {
110 cerr << "There were " << returnme
111 << " error(s) found." << endl;
112 }
113 cout << "=== nrtb::triad Unit Test Complete ===" << endl;
114 // return the error count as the exit code
115 return returnme;
61 116
62};117};
63118
=== modified file 'common/point/triad.h'
--- common/point/triad.h 2010-01-14 02:24:25 +0000
+++ common/point/triad.h 2011-08-25 04:57:16 +0000
@@ -1,31 +1,40 @@
1/*************************************************************1/***********************************************
2**** CODE REVIEW: triad.h, starting 2008-11-24 ***************2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3* The triad template is fully implemented in this one file.3
4* This class will be used for all vector and point operations4 NRTB is free software: you can redistribute it and/or modify
5* Please make any comments or suggestions directly in the file.5 it under the terms of the GNU General Public License as published by
6*************************************************************/6 the Free Software Foundation, either version 3 of the License, or
77 (at your option) any later version.
8/**************************************************8
9TODO: add methods for dot product, cross multiply, 9 NRTB is distributed in the hope that it will be useful,
10 finding the surface normal, etc.10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11/**************************************************11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212 GNU General Public License for more details.
13#ifndef nrtb_triad_header13
14#define nrtb_triad_header14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#ifndef triad_header
20#define triad_header
1521
16#include <iostream>22#include <iostream>
23#include <vector>
24#include <string>
17#include <sstream>25#include <sstream>
18#include <iomanip>26#include <iomanip>
19#include <math.h>27#include <math.h>
28#include <common.h>
2029
21namespace NRTB30namespace nrtb
22{31{
2332
24/** Template defining a point or vector in cartesian 3d space. Should work33/** Template defining a point or vector in cartesian 3d space. Should work
25 ** with all floating point types.34 ** with all floating point types.
26 ** 35 **
27 ** Implements the following operators: +,=,*,/,+=,-=,*=,/= for both36 ** Implements the following operators: +,=,*,/,+=,-=,*=,/= for both
28 ** triad<T> and <T> arguments; each returns a triad as the result.37 ** triad<T> and <T> arguments; each returns an triad as the result.
29 ** ==,!=,>>,<< are implemented for triad arguments. Additionally38 ** ==,!=,>>,<< are implemented for triad arguments. Additionally
30 ** implements pow() with triad and T arguments. Finally implements range()39 ** implements pow() with triad and T arguments. Finally implements range()
31 ** which returns the distance between the triad and one supplied, and40 ** which returns the distance between the triad and one supplied, and
@@ -76,13 +85,17 @@
76 ** is not modified.85 ** is not modified.
77 ** 86 **
78 ** Normalized triads are very useful when calcuating force or87 ** Normalized triads are very useful when calcuating force or
79 ** accelleration vectors and in many other cases.88 ** accelleration vectors, for example.
80 **/89 **/
81 triad<T> normalize();90 triad<T> normalize();
82 /// Returns the distance between *this and the supplied argument.91 /// Returns the distance between *this and the supplied argument.
83 T range(const triad<T> & a);92 T range(const triad<T> & a);
84 /// Returns the magnatude of the vector.93 /// Returns the magnatude of the vector.
85 T magnatude();94 T magnatude();
95 /// Returns the dot (scalar) product of two triads
96 T dot_product(const triad<T> & a);
97 /// Returns the vector product of two triads
98 triad<T> vector_product(const triad<T> & a);
86 bool operator == (const triad<T> & a);99 bool operator == (const triad<T> & a);
87 bool operator != (const triad<T> & a);100 bool operator != (const triad<T> & a);
88 /// Loads from a std::string.101 /// Loads from a std::string.
@@ -292,6 +305,26 @@
292};305};
293306
294template <class T>307template <class T>
308T triad<T>::dot_product(const triad<T> & a)
309{
310 T returnme;
311 returnme = x * a.x;
312 returnme += y * a.y;
313 returnme += z * a.z;
314 return returnme;
315};
316
317template <class T>
318triad<T> triad<T>::vector_product(const triad<T> & a)
319{
320 triad<T> rv;
321 rv.x = (y * a.z) - (z * a.y);
322 rv.y = (z * a.x) - (x * a.z);
323 rv.z = (x * a.y) - (y * a.x);
324 return rv;
325};
326
327template <class T>
295bool triad<T>::operator == (const triad<T> & a)328bool triad<T>::operator == (const triad<T> & a)
296{329{
297 return ((x == a.x) && (y == a.y) && (z == a.z));330 return ((x == a.x) && (y == a.y) && (z == a.z));
@@ -329,16 +362,11 @@
329 return f;362 return f;
330};363};
331364
332 //?? Review question: should we have the read operator
333 // throw instead of defaulting to (0,0,0) on a bad read?
334 // A: No, because this is the same behavior the read
335 // operator exhibits with other numeric types.
336
337/** Reads the triad<T> from an input stream.365/** Reads the triad<T> from an input stream.
338 ** 366 **
339 ** The acceptable format is [(]x,y,z[)]. Any other format will result367 ** The acceptable format is [(]x,y,z[)]. Any other format will result
340 ** in the triad<T> being set to (0,0,0). Any numeric format acceptable368 ** in the triad<T> being set to (0,0,0). Any numeric format acceptable
341 ** to an iostream is valid for x, y and z. Any other represention of x,369 ** to strtod() is valid for x, y and z. Any other represention of x,
342 ** y or z will result in that particular value being set to 0.370 ** y or z will result in that particular value being set to 0.
343 **/371 **/
344template <class T>372template <class T>
@@ -346,8 +374,7 @@
346{374{
347 std::string element;375 std::string element;
348 f >> element;376 f >> element;
349 //TODO: Need to replace split with boost equivelent377 strlist t = split(element,',');
350 std::vector<std::string> t = split(element,',');
351 if (t.size() != 3)378 if (t.size() != 3)
352 {379 {
353 a = 0;380 a = 0;
@@ -363,6 +390,6 @@
363 return f;390 return f;
364};391};
365392
366} // namespace NRTB393} // namespace nrtb
367394
368#endif // nrtb_triad_header395#endif // triad_header
369396
=== added directory 'common/serializer'
=== added file 'common/serializer/Makefile'
--- common/serializer/Makefile 1970-01-01 00:00:00 +0000
+++ common/serializer/Makefile 2011-08-25 04:57:16 +0000
@@ -0,0 +1,36 @@
1#***********************************************
2#This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: serializer_test
20 @./serializer_test
21 @cp -v serializer.h ../include
22 @cp -v serializer.o ../obj
23 @echo build complete
24
25serializer.o: serializer.h serializer.cpp Makefile
26 @rm -f serializer.o
27 g++ -c serializer.cpp -I ../include
28
29serializer_test: serializer.o serializer_test.cpp
30 @rm -f serializer_test
31 g++ -c serializer_test.cpp -I../include
32 g++ -o serializer_test serializer_test.o serializer.o ../obj/base_thread.o -lpthread ../obj/common.o
33
34clean:
35 @rm -rvf *.o serializer_test ../include/serializer.h ../obj/serializer.o
36 @echo all objects and executables have been erased.
037
=== added file 'common/serializer/serializer.cpp'
--- common/serializer/serializer.cpp 1970-01-01 00:00:00 +0000
+++ common/serializer/serializer.cpp 2011-08-25 04:57:16 +0000
@@ -0,0 +1,43 @@
1/***********************************************
2 T his file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include "serializer.h"
20#include <base_thread.h>
21
22using namespace nrtb;
23
24nrtb::serializer::serializer()
25{
26 counter = 0;
27};
28
29nrtb::serializer::serializer(unsigned long long start)
30{
31 counter = start;
32};
33
34serializer::~serializer()
35{
36 // nop destructor
37};
38
39unsigned long long serializer::operator()()
40{
41 nrtb::scope_lock mylock(lock);
42 return counter++;
43}
044
=== added file 'common/serializer/serializer.h'
--- common/serializer/serializer.h 1970-01-01 00:00:00 +0000
+++ common/serializer/serializer.h 2011-08-25 04:57:16 +0000
@@ -0,0 +1,50 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#ifndef nrtb_serializer_h
20#define nrtb_serializer_h
21#include <base_thread.h>
22
23namespace nrtb
24{
25 /******************************************************************
26 * nrtb::serializer provides a simple, thread safe functor which
27 * returns a series of long long ints increasing by one each time
28 * it's called. By default it starts counting from zero, but may
29 * be started from any arbitrary integer in the range
30 * 0 < x < max long long.
31 * ***************************************************************/
32 class serializer
33 {
34 public:
35 // default constructor; counter starts from zero.
36 serializer();
37 // constructor which sets the starting number.
38 serializer(unsigned long long start);
39 // NOP distructor for inheritance safety
40 ~serializer();
41 // functor method, returns the next value in the sequence.
42 unsigned long long operator ()();
43 private:
44 nrtb::mutex lock;
45 unsigned long long int counter;
46 };
47
48}
49
50#endif // nrtb_serializer_h
0\ No newline at end of file51\ No newline at end of file
152
=== 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-25 04:57:16 +0000
@@ -0,0 +1,56 @@
1/***********************************************
2 T his file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#include "serializer.h"
20#include <iostream>
21
22using namespace nrtb;
23using namespace std;
24
25int main()
26{
27 cout << "** nrtb::serializer unit test **" << endl;
28 bool set_if_failed = false;
29 serializer set_default;
30 serializer set_start(20);
31 serializer rollover((unsigned long long)(0 - 1));
32 cout << "Default initialization" << endl;
33 cout << " " << set_default();
34 cout << " " << set_default();
35 cout << " " << set_default();
36 cout << endl;
37 if (set_default() != 3)
38 set_if_failed = true;
39 cout << "Started from twenty" << endl;
40 cout << " " << set_start();
41 cout << " " << set_start();
42 cout << " " << set_start();
43 cout << endl;
44 if (set_start() != 23)
45 set_if_failed = true;
46 cout << "Rollover Demonstration" << endl;
47 cout << " " << rollover();
48 cout << " " << rollover();
49 cout << " " << rollover();
50 cout << endl;
51 if (rollover() != 2)
52 set_if_failed = true;
53 if (set_if_failed)
54 cout << "UNIT TEST FAILED" << endl;
55 return set_if_failed;
56};
0\ No newline at end of file57\ No newline at end of file
158
=== added directory 'common/singleton'
=== removed directory 'common/singleton'
=== added file 'common/singleton/Makefile'
--- common/singleton/Makefile 1970-01-01 00:00:00 +0000
+++ common/singleton/Makefile 2011-08-25 04:57:16 +0000
@@ -0,0 +1,33 @@
1#***********************************************
2# This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19
20lib: singleton_test
21 @./singleton_test
22 @cp -v singleton.h ../include
23 @echo build complete
24
25singleton_test: singleton_test.cpp Makefile
26 @rm -f singleton_test
27 g++ -c singleton_test.cpp -I ../include
28 g++ -o singleton_test singleton_test.o ../obj/base_thread.o ../obj/common.o ../obj/serializer.o -lpthread
29
30clean:
31 @rm -rvf *.o singleton_test ../include/singleton.h
32 @echo all objects and executables have been erased.
33
034
=== 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 @@
1
2build: singleton_test
3 @echo build complete
4
5singleton_test: singleton_test.cpp Makefile
6 @rm -f singleton_test
7 g++ -c singleton_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
8# g++ -c -g singleton_test.cpp -idirafter ../../include3 -idirafter /usr/local/include/boost-1_31
9 g++ -o singleton_test singleton_test.o -lricklib3 -lpthread -lssl -L../../lib/
10
11clean:
12 @rm -rvf *.o singleton_test ../../include3/singleton.h
13 @echo all objects and executables have been erased.
14
15lib: ../../include3/singleton.h
16
17../../include3/singleton.h: singleton.h
18 @cp -fv singleton.h ../../include3
190
=== added file 'common/singleton/singleton.h'
--- common/singleton/singleton.h 1970-01-01 00:00:00 +0000
+++ common/singleton/singleton.h 2011-08-25 04:57:16 +0000
@@ -0,0 +1,123 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19/* implements a template that takes any class provided and
20 * creates a singleton for it.
21 *
22 * fps 2002-5-29
23 */
24
25#ifndef nrtb_singleton_h
26#define nrtb_singleton_h
27
28#include <base_thread.h>
29
30namespace nrtb
31{
32
33/** Wrapper template to create singleton classes.
34 **
35 ** Classic Singleton pattern template, with thread-safe
36 ** methods for getting an instance and destruction.
37 **
38 ** Singletons are classes that:
39 ** (1) Insure that there are no more than one instance of the
40 ** class at any time.
41 ** (2) Allocate themselves automagically when accessed for the
42 ** first time.
43 ** (3) Provide a globally available access method to allow any
44 ** scope to gain access and use the instance.
45 **
46 ** This template can create a singleton version of any class that has a
47 ** no-argument constructor. The resulting class will have the same
48 ** inteface as the object used to create the template with the constructor
49 ** and destructor made protected and the addition of the get_instance()
50 ** and delete_me() methods.
51 **
52 ** See the documentation on the get_instance() and delete_me() methods for
53 ** usage.
54 **/
55template <class T, int mytag=0>
56class singleton: public T
57{
58 private:
59 static mutex __mylock;
60 static singleton * __me;
61 protected:
62 singleton() : T() {};
63 virtual ~singleton() {};
64 singleton(const singleton &) {};
65 public:
66 /** Used to access the object.
67 **
68 ** Returns a reference to the instanciated singleton object. If
69 ** the object has not been accessed before, the object will be
70 ** instanciated automatically.
71 **
72 ** As is usual for the method that provides access to a singleton,
73 ** this method is static, allowing it to be called via the class
74 ** name as shown. Remember you can only assign the return value to
75 ** a reference:
76 **
77 ** mytype & a = mytype::get_instance();
78 **
79 ** Attempts to make a copy of the instance should throw a compiler
80 ** error.
81 **
82 ** This method is thread safe, but that does not imply that the
83 ** class returned is thread-safe overall; that would depend on the
84 ** implementation of the class used to instaciate the template.
85 **/
86 static singleton & get_instance()
87 {
88 // First test avoids expensive mutex cycle
89 // if the object is already allocated.
90 if (!__me)
91 {
92 scope_lock lock(__mylock);
93 // second test required in case multiple threads
94 // get past the first check.
95 if (!__me)
96 {
97 __me = new singleton;
98 };
99 };
100 return *__me;
101 };
102
103 /** Destructs and deallocates the singleton object.
104 **
105 ** After a call to this method, the singleton object will
106 ** be destructed and deallocated from memory. However, it
107 ** will be automatically reconstruted and allocated if
108 ** get_instance() called at any time afterword.
109 **/
110 void delete_me()
111 {
112 scope_lock lock(__mylock);
113 if (__me) delete __me;
114 __me = 0;
115 };
116};
117
118template <class T, int mytag> mutex singleton<T,mytag>::__mylock;
119template <class T, int mytag> singleton<T,mytag> * singleton<T,mytag>::__me = 0;
120
121} // namespace nrtb;
122
123#endif // nrtb_singleton_h
0124
=== 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 @@
1/* implements a template that takes any class provided and
2 * creates a singleton for it.
3 *
4 * fps 2002-5-29
5 */
6
7/*
8 TODO: Alter to use boost::threads mutexes.
9*/
10
11
12#ifndef NRTB_singleton_h
13#define NRTB_singleton_h
14
15#include <boost/thread>
16
17namespace NRTB
18{
19
20/** Wrapper template to create singleton classes.
21 **
22 ** Classic Singleton pattern template, with thread-safe
23 ** methods for getting an instance and destruction.
24 **
25 ** Singletons are classes that:
26 ** (1) Insure that there are no more than one instance of the
27 ** class at any time.
28 ** (2) Allocate themselves automagically when accessed for the
29 ** first time.
30 ** (3) Provide a globally available access method to allow any
31 ** scope to gain access and use the instance.
32 **
33 ** This template can create a singleton version of any class that has a
34 ** no-argument constructor. The resulting class will have the same
35 ** inteface as the object used to create the template with the constructor
36 ** and destructor made protected and the addition of the get_instance()
37 ** and delete_me() methods.
38 **
39 ** See the documentation on the get_instance() and delete_me() methods for
40 ** usage.
41 **/
42template <class T, int mytag=0>
43class singleton: public T
44{
45 private:
46 static mutex __mylock;
47 static singleton * __me;
48 protected:
49 singleton() : T() {};
50 virtual ~singleton() {};
51 singleton(const singleton &) {};
52 public:
53 /** Used to access the object.
54 **
55 ** Returns a reference to the instanciated singleton object. If
56 ** the object has not been accessed before, the object will be
57 ** instanciated automatically.
58 **
59 ** As is usual for the method that provides access to a singleton,
60 ** this method is static, allowing it to be called via the class
61 ** name as shown. Remember you can only assign the return value to
62 ** a reference:
63 **
64 ** mytype & a = mytype::get_instance();
65 **
66 ** Attempts to make a copy of the instance should throw a compiler
67 ** error.
68 **
69 ** This method is thread safe, but that does not imply that the
70 ** class returned is thread-safe overall; that would depend on the
71 ** implementation of the class used to instaciate the template.
72 **/
73 static singleton & get_instance()
74 {
75 // First test avoids expensive mutex cycle
76 // if the object is already allocated.
77 if (!__me)
78 {
79 scope_lock lock(__mylock);
80 // second test required in case multiple threads
81 // get past the first check.
82 if (!__me)
83 {
84 __me = new singleton;
85 };
86 };
87 return *__me;
88 };
89
90 /** Destructs and deallocates the singleton object.
91 **
92 ** After a call to this method, the singleton object will
93 ** be destructed and deallocated from memory. However, it
94 ** will be automatically reconstruted and allocated if
95 ** get_instance() called at any time afterword.
96 **/
97 void delete_me()
98 {
99 scope_lock lock(__mylock);
100 if (__me) delete __me;
101 __me = 0;
102 };
103};
104
105template <class T, int mytag> mutex singleton<T,mytag>::__mylock;
106template <class T, int mytag> singleton<T,mytag> * singleton<T,mytag>::__me = 0;
107
108} // namespace NRTB;
109
110#endif // NRTB_singleton_h
1110
=== added file 'common/singleton/singleton_test.cpp'
--- common/singleton/singleton_test.cpp 1970-01-01 00:00:00 +0000
+++ common/singleton/singleton_test.cpp 2011-08-25 04:57:16 +0000
@@ -0,0 +1,55 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19// singleton template test program
20
21#include "singleton.h"
22#include <serializer.h>
23#include <iostream>
24
25using namespace nrtb;
26using namespace std;
27
28typedef singleton<serializer> sequence_type;
29
30int main()
31{
32
33 cout << "============== singleton unit test ================"
34 << endl;
35 int er_count = 0;
36
37 sequence_type & a = sequence_type::get_instance();
38
39 for (int i=0; i<10; i++)
40 {
41 cout << a();
42 };
43
44 sequence_type & b = sequence_type::get_instance();
45
46 if ( b() != 10)
47 {
48 er_count++;
49 };
50
51 cout << "\n=========== singleton test " << (er_count ? "failed" : "passed")
52 << " =============" << endl;
53
54 return er_count;
55};
056
=== 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 @@
1// singleton template test program
2
3
4#include <http_page.h>
5#include "singleton.h"
6#include <iostream>
7
8using namespace NRTB;
9using namespace std;
10
11int main()
12{
13 typedef singleton<http_page> p_type;
14
15 {
16 p_type & getter = p_type::get_instance();
17
18 cout << "newly initialized code: " << getter.result_code() << endl;
19
20 getter.get("127.0.0.1:80","/");
21 };
22
23 cout << "first response code: " << p_type::get_instance().result_code()
24 << endl;
25
26 p_type::get_instance().get("127.0.0.1:80","/not_there.html");
27
28 cout << "second response code: " << p_type::get_instance().result_code()
29 << endl;
30
31 p_type::get_instance().delete_me();
32};
330
=== added directory 'common/sockets'
=== added file 'common/sockets/Makefile'
--- common/sockets/Makefile 1970-01-01 00:00:00 +0000
+++ common/sockets/Makefile 2011-08-25 04:57:16 +0000
@@ -0,0 +1,38 @@
1#***********************************************
2# This file is part of the NRTB project (https://launchpad.net/nrtb).
3#
4# NRTB is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# NRTB is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16#
17#***********************************************
18
19lib: socket_test
20 @./socket_test
21 @cp -v base_socket.h ../include/
22 @cp -v base_socket.o ../obj/
23 @echo build complete
24
25socket_test: base_socket.o socket_test.cpp
26 @rm -f socket_test
27 g++ -c socket_test.cpp -I ../include
28 g++ -o socket_test socket_test.o base_socket.o ../obj/hires_timer.o ../obj/common.o ../obj/base_thread.o -lpthread
29
30
31base_socket.o: base_socket.cpp base_socket.h Makefile
32 @rm -f base_socket.o
33 g++ -c -O3 base_socket.cpp -I ../include
34
35clean:
36 @rm -vf *.o ../include/base_socket.h socket_test
37 @echo all objects and executables have been erased.
38
039
=== added file 'common/sockets/base_socket.cpp'
--- common/sockets/base_socket.cpp 1970-01-01 00:00:00 +0000
+++ common/sockets/base_socket.cpp 2011-08-25 04:57:16 +0000
@@ -0,0 +1,853 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19// see base_socket.h for documentation
20
21#include "base_socket.h"
22#include <string.h>
23#include <errno.h>
24#include <arpa/inet.h>
25#include <netdb.h>
26#include <boost/lexical_cast.hpp>
27
28using boost::lexical_cast;
29using std::string;
30
31namespace nrtb
32{
33
34// added for Solaris 2.6
35#ifdef no_inet_aton
36int inet_aton(const char * addr, in_addr * inp)
37{
38 // this workaround defines inet_aton in term in_addr. Drawbacks are
39 // that there is no useful error checking.
40 inp->s_addr = inet_addr(addr);
41 return (inp->s_addr != 0);
42};
43#endif // no_inet_aton
44
45// added for solaris 2.6
46#ifdef no_socklen_t
47typedef int socklen_t;
48#endif // no_sock_len_t
49
50int tcp_socket::transmit(const string & data)
51{
52 return send(mysock,data.c_str(),data.length(),MSG_DONTWAIT);
53};
54
55int tcp_socket::receive(std::string & data, int limit)
56{
57 errno = 0;
58 data = "";
59 // make more room in the input buffer if needed.
60 int bufsize = limit + 1;
61 if (bufsize > inbuff.size()) inbuff.resize(bufsize);
62 // get the data to inbuff
63 int returnme = recv(mysock,(void *) &(inbuff[0]),limit,0);
64 // did we get anything?
65 if (returnme > 0)
66 {
67 // yes.. store for the caller.
68 data.resize(returnme,0);
69 for (int i=0; i<returnme; i++)
70 {
71 data[i] = inbuff[i];
72 };
73 }
74 // ... or was there an error?
75 else if (errno)
76 {
77 // flag it for the caller.
78 returnme = -1;
79 };
80 return returnme;
81};
82
83tcp_socket::tcp_socket(bool autoclose)
84{
85 close_on_destruct = autoclose;
86 mysock = socket(AF_INET,SOCK_STREAM,0);
87 _status = sock_init;
88 _last_error = 0;
89};
90
91tcp_socket::tcp_socket(int existing_socket, bool autoclose)
92{
93 close_on_destruct = autoclose;
94 mysock = existing_socket;
95 _status = sock_connect;
96 _last_error = 0;
97};
98
99tcp_socket::~tcp_socket()
100{
101 if (close_on_destruct)
102 {
103 shutdown(mysock,SHUT_RDWR);
104 ::close(mysock);
105 _status = sock_undef;
106 };
107};
108
109void tcp_socket::reset()
110{
111 // close the old socket if we can.
112 try { close(); } catch (tcp_socket::general_exception) {};
113 // get a new one.
114 mysock = socket(AF_INET,SOCK_STREAM,0);
115 // set up the default conditions;
116 _status = sock_init;
117 _last_error = 0;
118};
119
120sockaddr_in tcp_socket::str_to_sockaddr(const string & address)
121{
122 sockaddr_in in_address;
123 // init our address structure.
124 memset(&in_address,0,sizeof(in_address));
125 //in_address.sin_len = 16;
126 in_address.sin_family = AF_INET;
127 // seperate the IP and port addresses.
128 const int IP = 0;
129 const int PORT = 1;
130 strlist addr;
131 addr = split(address,':');
132 if (addr.size() != 2)
133 {
134 throw bad_address_exception();
135 };
136 if (addr[IP] != "*")
137 {
138 // first attempt name resolution
139 hostent * name = gethostbyname(addr[IP].c_str());
140 if ((name != 0) && (name->h_length > 0))
141 {
142 in_address.sin_addr = *( (in_addr *) (name->h_addr_list[0]));
143 }
144 else if (!inet_aton(addr[IP].c_str(),&in_address.sin_addr))
145 {
146 throw bad_address_exception();
147 };
148 };
149 if (addr[PORT] != "*")
150 {
151 // get the good port;
152 uint16_t port = lexical_cast<uint16_t>(addr[PORT]);
153 in_address.sin_port = htons(port);
154 };
155 return in_address;
156};
157
158string tcp_socket::sockaddr_to_str(const sockaddr_in & address)
159{
160 // get the IP address.
161 string returnme = inet_ntoa(address.sin_addr);
162 // adjust for wild card if appropriate.
163 if (returnme == "0.0.0.0") { returnme = "*"; };
164 // get the port address
165 returnme += ":";
166 uint16_t myport = ntohs(address.sin_port);
167 if (myport > 0 )
168 {
169 returnme += lexical_cast<string>(myport);
170 }
171 else
172 {
173 returnme += "*";
174 };
175 return returnme;
176};
177
178void tcp_socket::bind(const string & address)
179{
180 if (address != "*:*")
181 {
182 sockaddr_in in_address = str_to_sockaddr(address);
183 socklen_t socklen = sizeof(in_address);
184 // try bind.
185 if (::bind(mysock, (sockaddr*) &in_address, socklen))
186 {
187 // failed in some way.
188 _last_error = errno;
189 cant_bind_exception e;
190 e.store(address);
191 throw e;
192 };
193 }; // nop if "*:*" is passed in.
194};
195
196void tcp_socket::connect(const string & address, int timeout)
197{
198 sockaddr_in in_address = str_to_sockaddr(address);
199 if (::connect(mysock, ( sockaddr *) &in_address, sizeof(in_address)))
200 {
201 _last_error = errno;
202 bad_connect_exception e;
203 e.store(address);
204 throw e;
205 }
206 else
207 {
208 _status = sock_connect;
209 };
210};
211
212void tcp_socket::close()
213{
214 if (::close(mysock))
215 {
216 _last_error = errno;
217 throw close_exception();
218 }
219 else
220 {
221 _status = sock_close;
222 };
223};
224
225int tcp_socket::put(string s, int timeout)
226{
227 // set up for the testing loop.
228 time_t endtime = time(NULL);
229 int orig_len = s.length();
230 endtime += timeout;
231 // Try to send.
232 bool done = false;
233 while (!done)
234 {
235 // make an attempt.
236 int results = transmit(s);
237 // remove the chars already sent from the buffer and set done
238 // if appropriate.
239 if (results > 0)
240 {
241 s.erase(0,results);
242 done = (s.length() == 0) ? true : false;
243 };
244 // decide what do do about any possible error results.
245 if (results == -1)
246 {
247 switch (errno)
248 {
249 case EBADF :
250 case ENOTSOCK:
251 {
252 done = true;
253 _last_error = errno;
254 _status = sock_close;
255 not_open_exception e;
256 e.store(s);
257 throw e;
258 break;
259 };
260 case ENOBUFS :
261 case ENOMEM :
262 {
263 done = true;
264 _last_error = errno;
265 buffer_full_exception e;
266 e.store(s);
267 throw e;
268 break;
269 };
270 case EINTR:
271 case EAGAIN :
272// case EWOULDBLOCK :
273 {
274 usleep(50);
275 break;
276 };
277 default :
278 {
279 done = true;
280 _last_error = errno;
281 general_exception e;
282 e.store(s);
283 throw e;
284 break;
285 };
286 }; // switch (errno)
287 }; // until error,
288 if ((timeout > 0) && ((time(NULL) >= endtime)))
289 {
290 done = true;
291 };
292 }; // continue sending until success or error or timeout.
293 // check for timeout.
294 int sent = orig_len - s.length();
295 if (sent != orig_len)
296 {
297 timeout_exception e;
298 e.store(s);
299 throw e;
300 };
301 return sent;
302};
303
304string tcp_socket::get(int maxlen, int timeout)
305{
306/*
307micro_timer run_time;
308run_time.start();
309std::cerr << "ENTER get(" << maxlen << "," << timeout << ")" << std::endl;
310*/
311 string returnme = "";
312 returnme.reserve(maxlen);
313 string in_buffer;
314 // set out timeout marker.
315 time_t endtime = time(NULL);
316 endtime += timeout;
317 timeval wait;
318 // input loop
319 bool done = false;
320 while (!done)
321 {
322 time_t waittime = endtime - time(NULL);
323 wait.tv_sec = (waittime > 0) ? waittime : 0;
324 wait.tv_usec = 10;
325 // set max timeout.
326 // the assert is used because some platforms may not properly support
327 // the SO_RCVTIMEO socket option.
328 setsockopt(mysock,SOL_SOCKET,SO_RCVTIMEO,&wait,sizeof(wait));
329 // is there any data waiting?
330 int results = receive(in_buffer,maxlen-returnme.size());
331 // was there an error?
332 switch (results)
333 {
334 case 0:
335 {
336 if (returnme == "")
337 {
338 throw not_open_exception();
339 }
340 else
341 {
342 done = true;
343 }
344 break;
345 }
346 case -1 :
347 {
348 switch (errno)
349 {
350 case EBADF :
351 case ENOTCONN :
352 case ENOTSOCK :
353 {
354 done = true;
355 _last_error = errno;
356 _status = sock_close;
357 if (returnme == "")
358 {
359 not_open_exception e;
360 e.store(returnme);
361 throw e;
362 };
363 break;
364 }
365 case EAGAIN : // shouldn't happen, but .....
366 case EINTR : // this too....
367 {
368 if (timeout == 0)
369 {
370 done = true;
371 };
372 usleep(50);
373 break;
374 }
375 default :
376 {
377 done = true;
378 _last_error = errno;
379 if (returnme == "")
380 {
381 general_exception e;
382 e.store(returnme);
383 throw e;
384 };
385 break;
386 }
387 }; // there was an error.
388 break;
389 }
390 default:
391 {
392 returnme += in_buffer;
393 break;
394 }
395 };
396 // check boundry conditions;
397 // -- maxlen only effective if maxlen > 0.
398 if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
399 // -- timeout only effective if timeout > 0.
400 if ((timeout > 0) && (time(NULL) > endtime)) { done = true; };
401 if (timeout == 0) { done = true; };
402/*
403std::cerr << "\tstatus: " << returnme.size()
404<< ", done = " << done
405<< " (" << run_time.interval() << ")"
406<< std::endl;
407*/
408 }; // input loop.
409 // did we time out?
410 if ((timeout > 0) && (time(NULL) > endtime))
411 {
412 timeout_exception e;
413 e.store(returnme);
414 throw e;
415 };
416 // done!
417 return returnme;
418};
419
420
421string tcp_socket::getln(string eol, int maxlen, int timeout)
422{
423 // args check.
424 if (eol == "")
425 {
426 throw bad_args_exception();
427 return eol;
428 };
429 // setup.
430 string returnme = "";
431 returnme.reserve(maxlen);
432 int targetlen = eol.length();
433 int searchlen = targetlen - 1;
434 time_t endtime = time(NULL);
435 endtime += timeout;
436 bool done = false;
437 bool success = false;
438 // first, get at least as many characters as are in the eol string.
439 try
440 {
441 int wait_time = timeout;
442 if (timeout < 0) { wait_time = 0; };
443 returnme = get(targetlen,wait_time);
444 }
445 catch (timeout_exception e)
446 {
447 // if get timed out we may be done.
448 if (timeout >= 0) { done = true; };
449 returnme = e.comment();
450 };
451 // We only need to continue if we have not gotten our token yet.
452 if ((!done) && (returnme.length() >= targetlen))
453 {
454// success = returnme.substr(returnme.length()-targetlen,targetlen) == eol;
455 success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
456 };
457 while (!done && !success)
458 {
459 // still more to get, if we have time.
460 int timeleft = endtime - time(NULL);
461 timeleft = (timeleft > 0) ? timeleft : 0;
462 // can we increase our get length?
463 int getlen = 1;
464 if (searchlen > 1)
465 {
466 // see if a token start is near.
467 if (returnme.find(eol[0],returnme.length()-searchlen) == string::npos)
468 {
469 // great!.. get just less than one token's worth.
470 getlen = searchlen;
471 }
472 };
473 // okay.. let's get the next chunk
474 try
475 {
476 returnme += get(getlen,timeleft);
477 }
478 catch (timeout_exception e)
479 {
480 if (timeout >= 0) { done = true; };
481 };
482 // check boundary conditions.
483 // -- did we get it?
484 if (returnme.length() >= targetlen)
485 {
486// success = returnme.substr(returnme.length()-targetlen,targetlen) == eol;
487 success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
488 };
489 // -- maxlen only effective if maxlen > 0.
490 if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
491 };
492 // did we error out?
493 if (!success)
494 {
495 // what type of error was it?
496 if ((maxlen > 0) && (returnme.length() >= maxlen))
497 {
498 overrun_exception e;
499 e.store(returnme);
500 throw e;
501 }
502 else
503 {
504 timeout_exception e;
505 e.store(returnme);
506 throw e;
507 };
508 };
509 return returnme;
510};
511
512string tcp_socket::get_local_address()
513{
514 sockaddr_in myaddr;
515 socklen_t len = sizeof(myaddr);
516 int results = getsockname(mysock,(sockaddr *) &myaddr,&len);
517 // check that getsockname was okay.
518 if (results == -1)
519 {
520 // some type of error occurred.
521 switch (errno)
522 {
523 case ENOBUFS :
524 {
525 throw buffer_full_exception();
526 break;
527 };
528 default :
529 {
530 throw general_exception();
531 break;
532 };
533 }; // switch errno
534 }
535 return sockaddr_to_str(myaddr);
536};
537
538string tcp_socket::get_remote_address()
539{
540 sockaddr_in myaddr;
541 socklen_t len = sizeof(myaddr);
542 int results = getpeername(mysock,(sockaddr *) &myaddr,&len);
543 // check that getsockname was okay.
544 if (results == -1)
545 {
546 // some type of error occurred.
547 switch (errno)
548 {
549 case ENOTCONN :
550 {
551 _status = sock_close;
552 throw not_open_exception();
553 break;
554 };
555 case ENOBUFS :
556 {
557 throw buffer_full_exception();
558 break;
559 };
560 default :
561 {
562 throw general_exception();
563 break;
564 };
565 }; // switch errno
566 }
567 return sockaddr_to_str(myaddr);
568};
569
570
571tcp_server_socket_factory::tcp_server_socket_factory(
572 const string & address, const unsigned short int & backlog)
573{
574 // does not attempt to set up the connection initially.
575 _address = address;
576 _backlog = backlog;
577 _last_thread_fault = 0;
578 thread_return = 0;
579 in_on_accept = false;
580 connect_sock = 0;
581};
582
583tcp_server_socket_factory::~tcp_server_socket_factory()
584{
585 // are we current handling requests?
586 if (is_running())
587 {
588 // yes, this is -rude- shutdown of the listening thread.
589 // Get over it.
590 stop();
591 try
592 {
593 if (listen_sock)
594 close(listen_sock);
595 }
596 catch (...) {};
597 };
598};
599
600void tcp_server_socket_factory::start_listen()
601{
602 // take no action if the listen thread is already running.
603 if (!is_running())
604 {
605 // load up the control flags
606 in_on_accept = false;
607 okay_to_continue = true;
608 thread_return = 0;
609 // start it up!
610 detach();
611 start();
612 };
613};
614
615void tcp_server_socket_factory::stop_listen()
616{
617 // take action only if the listen thread is running.
618 if (is_running())
619 {
620 bool okay_to_kill = false;
621 // set the flag that indicates the thread should not process any more.
622 {
623 scope_lock lock(thread_data);
624 bool okay_to_kill = !in_on_accept;
625 }
626 // close the listener socket.
627 close(listen_sock);
628 // is is okay to cancel the thread?
629 if (!okay_to_kill)
630 {
631 // we'll allow up to 30 seconds for on_accept() to finish.
632 time_t endtime = time(NULL);
633 endtime += 30;
634 bool done = false;
635 while (!done)
636 {
637 // wait a second...
638 sleep(1);
639 // check boundaries.
640 // -- are we out of on_accept()?
641 {
642 scope_lock lock(thread_data);
643 done = !in_on_accept;
644 }
645 // -- are we out of time?
646 okay_to_kill = done;
647 if (time(NULL) > endtime) { done = true; };
648 };
649 };
650 // kill the listener thread.
651 if (!okay_to_kill) { throw on_accept_bound_exception(); };
652 stop();
653 };
654};
655
656bool tcp_server_socket_factory::listening()
657{
658 bool running = is_running();
659 if (!running)
660 {
661 // check to be sure the thread did not die due to an error.
662 if (thread_return != 0)
663 {
664 // Clear the error state before throwing an exception.
665 _last_thread_fault = thread_return;
666 thread_return = 0;
667 // if thread_return was non-zero, it is assumed the thread died an
668 // evil and useless death. Scream in anger!
669 throw listen_terminated_exception();
670 };
671 };
672 return running;
673};
674
675unsigned short int tcp_server_socket_factory::backlog()
676{
677 return _backlog;
678};
679
680void tcp_server_socket_factory::run()
681{
682 /* Put this entire thing in a try block to protect the application.
683 * Without this, an untrapped exception thrown here or in the user supplied
684 * on_accept() method would abort the entire application instead of just this
685 * thread.
686 */
687 try
688 {
689 bool go = true;
690 // set up our listening socket.
691 listen_sock = socket(AF_INET,SOCK_STREAM,0);
692 sockaddr_in myaddr;
693 try
694 {
695 myaddr = tcp_socket::str_to_sockaddr(_address);
696 }
697 catch (...)
698 {
699 // probably a tcp_socket::bad_address_exception,
700 // but any reason will do.
701 go = false;
702 };
703 if (bind(listen_sock,(sockaddr *) &myaddr,sizeof(myaddr)))
704 {
705 // bind did not work.
706 go = false;
707 };
708 if (listen(listen_sock,_backlog))
709 {
710 // listen failed in some way.. I don't care which.
711 go = false;
712 };
713 // processing loop
714 while (go)
715 {
716 // are we okay to proceed?
717 {
718 scope_lock lock(thread_data);
719 in_on_accept = false;
720 go = okay_to_continue;
721 }
722 if (!go)
723 {
724 close(listen_sock);
725 exit(0);
726 };
727 // accept a new connection
728 bool good_connect = true;
729 int new_conn = accept(listen_sock,NULL,NULL);
730 // validate the accept return value.
731 if (new_conn == -1)
732 {
733 // accept returned an error.
734 switch (errno)
735 {
736 case ENETDOWN :
737 case EPROTO :
738 case ENOPROTOOPT :
739 case EHOSTDOWN :
740 case ENONET :
741 case EHOSTUNREACH :
742 case EOPNOTSUPP :
743 case ENETUNREACH :
744 case EAGAIN :
745// case EWOULDBLOCK :
746 case EPERM :
747 case ECONNABORTED :
748 {
749 good_connect = false;
750 break;
751 };
752 default :
753 {
754 // for any other error, we're going to shutdown the
755 // this listener thread.
756 {
757 scope_lock lock(thread_data);
758 // If the error was caused by an attempt to close the
759 // socket and shutdown the thread, don't store an
760 // error flag.
761 if (okay_to_continue)
762 {
763 thread_return = errno;
764 }
765 else
766 {
767 thread_return = 0;
768 };
769 };
770 exit(errno);
771 break;
772 };
773 }; // switch (errno)
774 }; // error thrown by accept.
775 // create connect_sock
776 connect_sock = new tcp_socket(new_conn);
777 // are we okay to proceed?
778 {
779 scope_lock lock(thread_data);
780 go = okay_to_continue;
781 // if we are go, then we'll be going to on_accept next.
782 // Therefore, this equality makes sense if you hold your
783 // head just so. :-P
784 in_on_accept = go;
785 }
786 if (!go)
787 {
788 delete connect_sock;
789 close(listen_sock);
790 exit(0);
791 };
792 // only call on_accept() if we have a good connection.
793 if (good_connect)
794 {
795 // make the thread easily cancelable.
796 set_cancel_anytime();
797 // call on_accept
798 on_accept();
799 // set back to cancel_deferred.
800 set_deferred_cancel();
801 };
802 }; // while go;
803 // if we get here then things are not going well...
804 {
805 scope_lock lock(thread_data);
806 thread_return = -2;
807 }
808 close(listen_sock);
809 exit(-2);
810 }
811 catch (...)
812 {
813 /* an untrapped exception was thrown by someone in this thread.
814 * We'll shutdown this thread and put -1 in the thread_return field
815 * to let the world know that we don't know what killed us.
816 */
817 thread_data.lock();
818 thread_return = -1;
819 thread_data.unlock();
820 close(listen_sock);
821 exit(-1);
822 };
823};
824
825} // namespace nrtb
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
0854
=== added file 'common/sockets/base_socket.h'
--- common/sockets/base_socket.h 1970-01-01 00:00:00 +0000
+++ common/sockets/base_socket.h 2011-08-25 04:57:16 +0000
@@ -0,0 +1,588 @@
1/***********************************************
2 This file is part of the NRTB project (https://*launchpad.net/nrtb).
3
4 NRTB is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 NRTB is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with NRTB. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************/
18
19#ifndef base_socket_header
20#define base_socket_header
21
22#include <base_thread.h>
23#include <boost/shared_ptr.hpp>
24#include <sys/socket.h>
25#include <netinet/in.h>
26
27namespace nrtb
28{
29
30/** Provides an easy to use TCP/IP bidirectional communciations socket.
31 **
32 ** tcp_socket contains all the functionality you'll need for 98% of
33 ** your normal, non-encrypted networking communications needs. Everything
34 ** from creating the socket, binding it if needed, name resolution,
35 ** connecting, sending and receiving, etc. is handled here.
36 **
37 ** Unless you override it, a tcp_socket closes automatically when it
38 ** goes out of scope, preventing hanging sockets.
39 **/
40class tcp_socket
41{
42 public:
43
44 typedef enum {sock_undef,sock_init,sock_connect,sock_close} state;
45
46 protected:
47
48 int mysock;
49 bool close_on_destruct;
50 state _status;
51 int _last_error;
52 std::vector<unsigned char> inbuff;
53
54 virtual int transmit(const std::string & data);
55 virtual int receive(std::string & data,int limit);
56
57 public:
58
59 /// Use to catch all socket exceptions.
60 class general_exception: public base_exception {};
61 /// Thrown by send or get* if the socket is not open for use.
62 class not_open_exception: public general_exception {};
63 /// Thrown by get* if more than maxlen chars are receieved.
64 class overrun_exception: public general_exception {};
65 /// Thrown if a timeout occured during an operation.
66 class timeout_exception: public general_exception {};
67 /// Thrown if the socket could not connect to the target.
68 class bad_connect_exception: public general_exception {};
69 /// Thrown if the address argument is not interpretable.
70 class bad_address_exception: public general_exception {};
71 /// Thrown by bind() if the address/port is not bindable.
72 class cant_bind_exception: public general_exception {};
73 /// Thrown by close() if an error is reported.
74 class close_exception: public general_exception {};
75 /// Thrown by send if the message is too large.
76 class msg_too_large_exception: public general_exception {};
77 /// Thrown by send if buffer overflows.
78 class buffer_full_exception: public general_exception {};
79 /// Thrown if the socket lib complains of bad args.
80 class bad_args_exception: public general_exception {};
81
82 /** Constructs a tcp_socket.
83 **
84 ** Prepares this socket for use. If autoclose=true the socket will be
85 ** closed when the object is distructed, otherwise it will be left in
86 ** whatever state it happened to be in at the time.
87 **
88 ** BTW, I _don't_ recommend you leave the socket open. If the tcp_socket
89 ** was instanciated via this constructor, there will not be any other
90 ** references to the socket save the one held privately, so a socket left
91 ** open will be there forever. This will almost certainly warrent an
92 ** unpleasent visit by one or more SAs of the box(es) hosting your
93 ** application over time.
94 **
95 ** autoclose=true; it's the only way to be sure. ;)
96 **/
97 tcp_socket(bool autoclose=true);
98
99 /** Constructs from an already existing socket.
100 **
101 ** Constructs the tcp_socket from an already existing socket. This
102 ** constructor is specifically for use with the traditional listen()
103 ** sockets function, and probably should not be used in other contexts.
104 **
105 ** If autoclose is true the socket will be closed on destruction of the
106 ** object, otherwise the socket will be left in whatever state it happened
107 ** to be in at the time. As a general rule I suspect you'll want leave
108 ** autoclose defaulted to true.
109 **
110 ** In most cases where you would use listen(), take a look at the
111 ** tcp_server_socket_factory class; it'll probably do everything you need
112 ** with a minimum of programming overhead.
113 **
114 ** BTW, I _don't_ recommend you leave the socket open. If the socket variable
115 ** used for instanciation was discarded, there will not be any other
116 ** references to the socket save the one held privately, so a socket left
117 ** open will be there forever. This will almost certainly warrent an
118 ** unpleasent visit by one or more SAs of the box(es) hosting your
119 ** application over time.
120 **
121 ** autoclose=true; it's the only way to be sure. ;)
122 **/
123 tcp_socket(int existing_socket, bool autoclose=true);
124
125 /** Destructs a tcp_socket.
126 **
127 ** If autoclose was set to true, the socket will be closed if it is open
128 ** at the time of destruction. If no, the socket will be left in whatever
129 ** state it happened to be in at the time.
130 **/
131 virtual ~tcp_socket();
132
133 /** Resets the socket after a hard error.
134 **
135 ** In cases where the socket was invlidated by the operating system
136 ** (typically cases where a SIGPIPE was raised by the TCP/IP stack),
137 ** use this function to discard the old socket id and aquire a new one.
138 ** Understand that this will make the tcp_socket useful again, but you
139 ** will have to reconnect before any traffic can be sent.
140 **/
141 virtual void reset();
142
143 /** Creates a sockaddr_in from a formatted string.
144 **
145 ** address is an "IP:port" formatted string; i.e. 129.168.1.1:80.
146 ** "*" may use used to substatute for the IP, port or both.
147 **
148 ** Returns a properly formatted sockaddr_in struct for use with connect,
149 ** bind, etc. Throws a bad_address_exception if the address argument is
150 ** mal-formed.
151 **/
152 static sockaddr_in str_to_sockaddr(const std::string & address);
153
154 /** Creates a string from a sockaddr_in.
155 **
156 ** The returned string is of the same format accepted as arguments to the
157 ** to the bind() and connect() methods.
158 **
159 ** May throw a bad_address_exception if the sock_addr_in is not
160 ** properly formatted.
161 **/
162 static std::string sockaddr_to_str(const sockaddr_in & address);
163
164 /** binds the tcp_socket to a local address/port.
165 **
166 ** You do _not_ need to use this method if you are setting up a tcp_socket
167 ** for client use. If you don't call bind an ephemeral port and the host's
168 ** IP number will be assigned, as is normal and preferred for client sockets.
169 **
170 ** In very rare cases where you have a multi-homed host and a real
171 ** requirement to specify which IP this connection uses as local, you can
172 ** use this method to select the port and address the client will use.
173 **
174 ** address: string of the format IP:port; example "255.255.255.255:91".
175 ** If you wish to accept input on any active IP address in this host,
176 ** use "*" for the IP address, as in "*:80". If you want to fix the address
177 ** but leave the port up to the host, use "*" for the port, as in
178 ** "10.101.78.33:*". Obviously, using "*:*" as the address gives the
179 ** same results as not calling this method at all.
180 **
181 ** If the address argument is mal-formed a bad_address_exception will be
182 ** thrown and no changes will be made to the tcp_socket.
183 **
184 ** If the address is not bindable (already in use is a common cause) a
185 ** cant_bind_exception will be thrown.
186 **/
187 void bind(const std::string & address);
188
189 /** Opens the connection.
190 **
191 ** address: string of the format IP:port; example "255.255.255.255:91".
192 ** If the address is mal-formed a bad_address_exception will be thrown.
193 **
194 ** If timeout is specified and >0, the system will not wait more than
195 ** timeout seconds before throwing a timeout_exception.
196 **
197 ** If the connection is not set up properly, a bad_connection_exception
198 ** will be thrown.
199 **/
200 void connect(const std::string & address, int timeout=0);
201
202 /** Closes an open connection.
203 **
204 ** If a problem is reported a close_exception will be thrown. Possible
205 ** causes include the socket not being open, unsent data pending in the
206 ** tcp stack, etc.
207 **/
208 virtual void close();
209
210 /** Returns the current status.
211 **
212 ** Possibles states are tcp_socket::undef, tcp_socket::init,
213 ** tcp_socket::connect, and tcp_socket::close.
214 **/
215 state status() { return _status; };
216
217 /** Returns the last socket error recieved.
218 **
219 ** Will contain zero if no errors have occured on the socket since
220 ** the tcp_socket was instanciated, or the errno returned on the most recent
221 ** error otherwise.
222 **
223 ** Check the man pages for bind(), connect(), close(), socket(), send(),
224 ** and recv() for possible values. They are defined in error.h.
225 **/
226 int last_error() { return _last_error; };
227
228 /** Sends the string to the target host.
229 **
230 ** If timeout is specified and >0, a timeout_exception will be thrown
231 ** if the send does not succeed within timeout seconds.
232 **
233 ** If socket is not connected or closes during sending a
234 ** not_open_exception will be thrown.
235 **
236 ** If an exception is thrown, the characters that were not
237 ** sent will be available via the exception's comment() method (as
238 ** a string, of course).
239 **/
240 int put(std::string s, int timeout=10);
241
242 /** gets a string of characters from the socket.
243 **
244 ** This method allows the reception of a string of characters
245 ** limited by length and time. Use this method when you are expecting a
246 ** stream if data that you either know the length of or where there is
247 ** no specific ending character. If the expected traffic is organized
248 ** into messages or lines ending with a specific character or string,
249 ** use the getln() method instead.
250 **
251 ** Examples:
252 **
253 ** get() or get(1) will return a string containing a single
254 ** character or throw a timeout in 10 seconds if one is not
255 ** recieved.
256 **
257 ** get(100,30) will return when 100 characters have been recieved or
258 ** throw a timeout in 30 seconds.
259 **
260 ** get(100,-1) will return after 100 characters have been recieved, and will
261 ** _never_ time out. I strongly recommend that at the very least use timeout
262 ** values >= 0 to this method to prevent program long term program stalls.
263 **
264 ** If maxlen==0, this method will return immediately with whatever characters
265 ** happen to be in the socket's input buffer at the time.
266 **
267 ** If maxlen>0 and timeout<0, this method will block until maxlen characters
268 ** have been recieved and then return. NOTE: this method could block
269 ** forever if the sending host does not send maxlen characters and timeout
270 ** is < 0.
271 **
272 ** If maxlen>0 and timeout>0 this method will return upon recieving
273 ** maxlen characters or throw a timeout_exception after timeout seconds
274 ** have expired in the worse case.
275 **
276 ** In all cases the method returns a string containing the characters
277 ** recieved, if any.
278 **
279 ** If the timeout expires before the required number of characters are
280 ** recieved a timeout_exception will be thrown.
281 **
282 ** If the socket is not connected or closes while being read a
283 ** not_open_exception will be thrown.
284 **
285 ** If an exception is thrown, any characters already recieved
286 ** will be available via the exception's comment() method.
287 **/
288 std::string get(int maxlen=1, int timeout=10);
289
290 /** gets a string of characters from the socket.
291 **
292 ** This method is for the reception of messages (or lines) that have a
293 ** specific ending string. As such it considers the recept of maxlen
294 ** characters or a timeout without the designated eol string to be
295 ** a problem and will throw an exception in those cases. This behavor
296 ** differs from that of the get() method, which simply returns when it
297 ** has received its limit.
298 **
299 ** If there is no specific eol or eom string in your expected data
300 ** stream use the get() method instead.
301 **
302 ** Examples:
303 **
304 ** getln() will return all characters recieved up to and including the
305 ** first carrage return or throw a timeout if a carrage return is not
306 ** recieved after 10 seconds.
307 **
308 ** getln("</alert>") will return all characters recieved up to and
309 ** including "</alert>" or throw a timeout if "</alert>" is not recieved
310 ** within 10 seconds.
311 **
312 ** getln(":",30) will return all characters recieved up to and including
313 ** ":" if ":" is recieved by the 30th character. If 30 characters are recieved
314 ** before ":", an overrun_exception would be thrown. A timeout would be
315 ** thrown if ":" is not recieved within 10 seconds.
316 **
317 ** getln(":",30,20) would react exactly like getln(":",30) except the timeout
318 ** period would be 20 seconds instead of the default 10.
319 **
320 ** getln(":",30,-1) will react exactly like getln(":",30) except that no
321 ** timeout will ever be thrown. In this case, the method may block
322 ** forever if no ":" is received and it never receives 30 characters.
323 ** I strongly recommend that at the very least that timeout be a
324 ** value >= 0 to this method to prevent program long term program stalls.
325 **
326 ** If maxlen==0 and timeout<0, this method will block until the eol
327 ** string is recieved from the host or maxlen characters
328 ** have been recieved. and then return. NOTE: this method could block
329 ** forever if the sending host does not send maxlen characters or the
330 ** eol string and timeout is < 0;
331 **
332 ** If maxlen>0 and timeout>0 this method will return upon recieving the
333 ** eol string, when maxlen characters have be recieved or when
334 ** timeout seconds have expired.
335 **
336 ** In all cases the method returns a string containing the characters
337 ** recieved, if any, including the eol string.
338 **
339 ** If the timeout expires before eol is recieved or maxlen characters are
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: