ptypes

ptypes Commit Details


Date:2013-05-08 23:49:00 (11 years 7 months ago)
Author:Natalie Adams
Branch:default
Commit:8edbcdac0d39
Message:initial commit

Changes:
ALICENSE (full)
AMakefile (full)
Adoc/async.examples.html (full)
Adoc/async.html (full)
Adoc/async.jobqueue.html (full)
Adoc/async.message.html (full)
Adoc/async.msgqueue.html (full)
Adoc/async.mutex.html (full)
Adoc/async.rwlock.html (full)
Adoc/async.semaphore.html (full)
Adoc/async.thread.html (full)
Adoc/async.trigger.html (full)
Adoc/async.utils.html (full)
Adoc/basic.html (full)
Adoc/changes.html (full)
Adoc/compiling.html (full)
Adoc/criterrors.html (full)
Adoc/cset.constructors.html (full)
Adoc/cset.html (full)
Adoc/cset.manipulation.html (full)
Adoc/cset.operators.html (full)
Adoc/deploying.html (full)
Adoc/freshmeat-logo.png
Adoc/htsrc.html (full)
Adoc/include/pasync.h.html (full)
Adoc/include/pinet.h.html (full)
Adoc/include/pport.h.html (full)
Adoc/include/pstreams.h.html (full)
Adoc/include/ptime.h.html (full)
Adoc/include/ptypes.h.html (full)
Adoc/index.html (full)
Adoc/inet.examples.html (full)
Adoc/inet.html (full)
Adoc/inet.ipmessage.html (full)
Adoc/inet.ipmsgserver.html (full)
Adoc/inet.ipstmserver.html (full)
Adoc/inet.ipstream.html (full)
Adoc/inet.utils.html (full)
Adoc/intro.html (full)
Adoc/lists.html (full)
Adoc/lists.textmap.html (full)
Adoc/lists.tobjlist.html (full)
Adoc/lists.tpodlist.html (full)
Adoc/lists.tstrlist.html (full)
Adoc/portability.html (full)
Adoc/ref.html (full)
Adoc/ref.tmpl.html (full)
Adoc/source-forge-logo.png
Adoc/streams.errors.html (full)
Adoc/streams.examples.html (full)
Adoc/streams.html (full)
Adoc/streams.infile.html (full)
Adoc/streams.inmem.html (full)
Adoc/streams.instm.html (full)
Adoc/streams.iobase.html (full)
Adoc/streams.logfile.html (full)
Adoc/streams.md5.html (full)
Adoc/streams.namedpipe.html (full)
Adoc/streams.npserver.html (full)
Adoc/streams.outfile.html (full)
Adoc/streams.outmem.html (full)
Adoc/streams.outstm.html (full)
Adoc/streams.stdio.html (full)
Adoc/string.constructors.html (full)
Adoc/string.conversion.html (full)
Adoc/string.html (full)
Adoc/string.manipulation.html (full)
Adoc/string.operators.html (full)
Adoc/string.typecasts.html (full)
Adoc/styles.css (full)
Adoc/time.calendar.html (full)
Adoc/time.datetime.html (full)
Adoc/time.html (full)
Adoc/time.time.html (full)
Adoc/title-21.png
Adoc/unit.html (full)
Adoc/unknown.html (full)
Adoc/variant.arrays.html (full)
Adoc/variant.html (full)
Adoc/variant.objrefs.html (full)
Adoc/variant.typecasts.html (full)
Adoc/variant.utils.html (full)
Adoc/wshare.html (full)
Ainclude/pasync.h (full)
Ainclude/pinet.h (full)
Ainclude/pport.h (full)
Ainclude/pstreams.h (full)
Ainclude/ptime.h (full)
Ainclude/ptypes.h (full)
Aindex.html (full)
Asrc/Makefile.Darwin (full)
Asrc/Makefile.FreeBSD (full)
Asrc/Makefile.HP-UX (full)
Asrc/Makefile.Linux (full)
Asrc/Makefile.SunOS (full)
Asrc/Makefile.common (full)
Asrc/pasync.cxx (full)
Asrc/patomic.cxx (full)
Asrc/patomic.sparc.s (full)
Asrc/pcomponent.cxx (full)
Asrc/pcset.cxx (full)
Asrc/pcsetdbg.cxx (full)
Asrc/pexcept.cxx (full)
Asrc/pfatal.cxx (full)
Asrc/pfdxstm.cxx (full)
Asrc/pinfile.cxx (full)
Asrc/pinfilter.cxx (full)
Asrc/pinmem.cxx (full)
Asrc/pinstm.cxx (full)
Asrc/pintee.cxx (full)
Asrc/piobase.cxx (full)
Asrc/pipbase.cxx (full)
Asrc/pipmsg.cxx (full)
Asrc/pipmsgsv.cxx (full)
Asrc/pipstm.cxx (full)
Asrc/pipstmsv.cxx (full)
Asrc/pipsvbase.cxx (full)
Asrc/pmd5.cxx (full)
Asrc/pmem.cxx (full)
Asrc/pmsgq.cxx (full)
Asrc/pmtxtable.cxx (full)
Asrc/pnpipe.cxx (full)
Asrc/pnpserver.cxx (full)
Asrc/pobjlist.cxx (full)
Asrc/poutfile.cxx (full)
Asrc/poutfilter.cxx (full)
Asrc/poutmem.cxx (full)
Asrc/poutstm.cxx (full)
Asrc/ppipe.cxx (full)
Asrc/ppodlist.cxx (full)
Asrc/pputf.cxx (full)
Asrc/prwlock.cxx (full)
Asrc/psemaphore.cxx (full)
Asrc/pstdio.cxx (full)
Asrc/pstrcase.cxx (full)
Asrc/pstrconv.cxx (full)
Asrc/pstring.cxx (full)
Asrc/pstrlist.cxx (full)
Asrc/pstrmanip.cxx (full)
Asrc/pstrtoi.cxx (full)
Asrc/pstrutils.cxx (full)
Asrc/ptextmap.cxx (full)
Asrc/pthread.cxx (full)
Asrc/ptime.cxx (full)
Asrc/ptimedsem.cxx (full)
Asrc/ptrigger.cxx (full)
Asrc/ptypes_test.cxx (full)
Asrc/punit.cxx (full)
Asrc/punknown.cxx (full)
Asrc/pvariant.cxx (full)
Asrc/pversion.cxx (full)
Awin32/PTypes.opensdf
Awin32/PTypes.sdf
Awin32/PTypes.sln (full)
Awin32/PTypes.sln.old (full)
Awin32/PTypes_DLL.vcproj (full)
Awin32/PTypes_DLL.vcxproj (full)
Awin32/PTypes_DLL.vcxproj.filters (full)
Awin32/PTypes_DLL.vcxproj.user (full)
Awin32/PTypes_Lib.vcproj (full)
Awin32/PTypes_Lib.vcxproj (full)
Awin32/PTypes_Lib.vcxproj.filters (full)
Awin32/PTypes_Lib.vcxproj.user (full)
Awin32/PTypes_Lib_ST.vcproj (full)
Awin32/PTypes_Lib_ST.vcxproj (full)
Awin32/PTypes_Lib_ST.vcxproj.filters (full)
Awin32/PTypes_Lib_ST.vcxproj.user (full)
Awin32/PTypes_Test.vcproj (full)
Awin32/PTypes_Test.vcxproj (full)
Awin32/PTypes_Test.vcxproj.user (full)
Awin32/PTypes_Test_ST.vcproj (full)
Awin32/PTypes_Test_ST.vcxproj (full)
Awin32/PTypes_Test_ST.vcxproj.user (full)
Awin32/UpgradeLog.XML (full)
Awin32/dll_version.rc (full)
Awin32/ipch/ptypes_lib-8b061a97/debug/ptypes_lib-d36c6ce4.ipch
Awin32/resource.h (full)
Awin32/wshare.vcproj (full)
Awin32/wshare.vcxproj (full)
Awin32/wshare.vcxproj.user (full)
Awshare/Makefile.Darwin (full)
Awshare/Makefile.FreeBSD (full)
Awshare/Makefile.HP-UX (full)
Awshare/Makefile.Linux (full)
Awshare/Makefile.SunOS (full)
Awshare/Makefile.common (full)
Awshare/clients.cxx (full)
Awshare/clients.h (full)
Awshare/config.cxx (full)
Awshare/config.h (full)
Awshare/log.cxx (full)
Awshare/log.h (full)
Awshare/mimetable.awk (full)
Awshare/mimetable.cxx (full)
Awshare/mod_about.cxx (full)
Awshare/mod_file.cxx (full)
Awshare/mod_wstat.cxx (full)
Awshare/modules.cxx (full)
Awshare/modules.h (full)
Awshare/request.cxx (full)
Awshare/request.h (full)
Awshare/sysutils.cxx (full)
Awshare/sysutils.h (full)
Awshare/urlutils.cxx (full)
Awshare/urlutils.h (full)
Awshare/utils.cxx (full)
Awshare/utils.h (full)
Awshare/wshare.cxx (full)

File differences

LICENSE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
LICENSE
C++ Portable Types Library (PTypes)
Copyright (C) 2001-2007 Hovik Melikyan
http://www.melikyan.com/ptypes/
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Hovik Melikyan
h@melikyan.com
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for all Unix platforms, places the library in lib/,
# the shared library in so/. Also builds the test program
# src/ptypes_test and the sample program bin/wshare.
#
UMAKEFILE=Makefile.`uname`
all:
cd src ; make -f $(UMAKEFILE) all
cd wshare ; make -f $(UMAKEFILE) all
clean:
cd src ; make -f $(UMAKEFILE) clean
cd wshare ; make -f $(UMAKEFILE) clean
clean-src:
cd src ; make -f $(UMAKEFILE) clean-src
cd wshare ; make -f $(UMAKEFILE) clean-src
install:
cd src ; make -f $(UMAKEFILE) install
uninstall:
cd src ; make -f $(UMAKEFILE) uninstall
doc/async.examples.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: examples</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
Examples </p>
<p><b>Example 1</b>. This simple example shows the use of mutex objects to safely
perform calculation that involves more than one global variable. Note that using
the <span class="lang">rwlock</span> class instead of <span class="lang">mutex</span>
can improve performance by allowing multiple threads call <span class="lang">avg_get()</span>
at once.</p>
<blockquote>
<pre>int avg_sum = 0;
int avg_cnt = 0;
mutex avg_lock;
void avg_add(int v)
{
scopelock lock(avg_lock);
avg_sum += v;
avg_cnt++;
}
int avg_get()
{
int result;
{
scopelock lock(avg_lock);
if (avg_cnt == 0)
result = 0;
else
result = avg_sum / avg_cnt;
}
return result;
}
</pre>
</blockquote>
<p><br>
<b>Example 2</b>. A multithreaded TCP server that uses the <span class="lang">jobqueue</span>
class to maintain a thread pool - a fixed list of reusable threads that receive
job `assignments' from a queue. The code below can be used as a template for a
multithreaded network server.</p>
<blockquote>
<pre>#include &lt;ptypes.h&gt;
#include &lt;ptime.h&gt;
#include &lt;pasync.h&gt;
#include &lt;pinet.h&gt;
USING_PTYPES
const int testport = 8085;
const int maxthreads = 30;
const int maxtoken = 4096;
const int MSG_MYJOB = MSG_USER + 1;
class myjobthread: public thread
{
protected:
int id;
jobqueue* jq;
virtual void execute();
public:
myjobthread(int iid, jobqueue* ijq)
: thread(false), id(iid), jq(ijq) {}
~myjobthread() { waitfor(); }
};
class myjob: public message
{
public:
ipstream* client;
myjob(ipstream* iclient)
: message(MSG_MYJOB), client(iclient) {}
~myjob() { delete client; }
};
void myjobthread::execute()
{
bool quit = false;
while (!quit)
{
<span class="comment">// get the next message from the queue</span>
message* msg = jq->getmessage();
try
{
switch (msg->id)
{
case MSG_MYJOB:
{
ipstream* client = ((myjob*)msg)->client;
<span class="comment">// read the request line</span>
string req = lowercase(client->line(maxtoken));
if (req == "hello")
{
<span class="comment">// send our greeting to the client</span>
client->putline("Hello, " + iptostring(client->get_ip()) + ", nice to see you!");
client->flush();
<span class="comment">// log this request</span>
pout.putf("%t greeting received from %a, handled by thread %d\n",
now(), long(client->get_ip()), id);
}
client->close();
}
break;
case MSG_QUIT:
<span class="comment">// MSG_QUIT is not used in our example</span>
quit = true;
break;
}
}
catch(exception*)
{
<span class="comment">// the message object must be freed!</span>
delete msg;
throw;
}
delete msg;
}
}
void servermain(ipstmserver& svr)
{
jobqueue jq;
tobjlist&lt;myjobthread&gt; threads(true);
<span class="comment">// create the thread pool</span>
int i;
for(i = 0; i < maxthreads; i++)
{
myjobthread* j = new myjobthread(i + 1, &jq);
j->start();
threads.add(j);
}
ipstream* client = new ipstream();
pout.putf("Ready to answer queries on port %d\n", testport);
while(true)
{
svr.serve(*client);
if (client->get_active())
{
<span class="comment">// post the job to the queue; the client object will be freed
// automatically by the job object</span>
jq.post(new myjob(client));
client = new ipstream();
}
}
}
int main()
{
ipstmserver svr;
try
{
<span class="comment">// bind to all local addresses on port 8085</span>
svr.bindall(testport);
<span class="comment">// enter an infinite loop of serving requests</span>
servermain(svr);
}
catch(estream* e)
{
perr.putf("FATAL: %s\n", pconst(e->get_message()));
delete e;
}
return 0;
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="async.thread.html">thread</a>, <a href="async.mutex.html">mutex</a>,
<a href="async.rwlock.html">rwlock</a>, <a href="async.jobqueue.html">jobqueue</a>,
<a href="async.message.html">message</a>, <a href="inet.examples.html">Networking
examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Multithreading</p>
<ul>
<li>
<h5><a href="async.thread.html">thread</a></h5>
</li>
<li>
<h5><a href="async.semaphore.html">semaphore &amp; timedsem</a></h5>
</li>
<li>
<h5><a href="async.mutex.html">mutex</a></h5>
</li>
<li>
<h5><a href="async.rwlock.html">rwlock</a></h5>
</li>
<li>
<h5><a href="async.trigger.html">trigger</a></h5>
</li>
<li>
<h5><a href="async.msgqueue.html">msgqueue</a></h5>
</li>
<li>
<h5><a href="async.jobqueue.html">jobqueue</a></h5>
</li>
<li>
<h5><a href="async.message.html">message</a></h5>
</li>
<li>
<h5><a href="async.utils.html">Atomic functions, utilities</a></h5>
</li>
<li>
<h5><a href="async.examples.html">Examples</a></h5>
</li>
</ul>
<p>PTypes provides a minimal set of utility objects for creating complex multithreaded
and event-driven applications. In addition to <a href="async.thread.html">threads</a>
and inter-thread synchronization primitives <a href="async.semaphore.html">semaphore</a>,
<a href="async.mutex.html">mutex</a>, <a href="async.rwlock.html">rwlock</a> and
<a href="async.trigger.html">trigger</a> the library also allows you to create
message queues (<a href="async.msgqueue.html">msgqueue</a>) typically used in
windowed or other event-driven environments. The <a href="async.jobqueue.html">jobqueue</a>
class helps to build multithreaded server and robot applications with a pool of
reusable thread objects.</p>
<p>The implementation and interfaces of threads and synchronization objects vary
on platforms supported by the library. If an operating system lacks one of the
features, PTypes implements it using the other primitives present in that OS.
Please, see <a href="include/pasync.h.html">&lt;pasync.h&gt;</a> for the implementation
cross-reference of the synchronization primitives.</p>
<p>These interfaces except the atomic functions are available only in multithreaded
versions of the library.</p>
<p>The multithreading classes are declared in <a href="include/pasync.h.html">&lt;pasync.h&gt;</a>.</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.jobqueue.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: jobqueue</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
jobqueue</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class jobqueue {
jobqueue(int limit = DEF_QUEUE_LIMIT);
void post(message* msg);
void post(int id, int param = 0);
void posturgent(message* msg);
void posturgent(int id, int param = 0);
message* getmessage(int timeout = -1);
int get_count();
int get_limit();
}</pre>
</blockquote>
<p>The <span class="lang">jobqueue</span> class implements a thread-safe list
of objects of type <span class="lang"><a href="async.message.html">message</a></span>
or any derivative class. <span class="lang">Jobqueue</span> supports posting to
and reading from the list from multiple threads simultaneously.</p>
<p>The <span class="lang">jobqueue</span> class can help to build multithreaded
server/robot applications by maintaining a pool of reusable threads that receive
job 'assignments' from a queue. This threading model can be faster compared to
applications that create and destroy separate thread objects for each task. See
<a href="async.examples.html">Examples</a> for a full-featured server template
with a thread pool.</p>
<p><span class="def">jobqueue::jobqueue(int limit = DEF_QUEUE_LIMIT)</span> constructs
a job queue object. <span class="lang">Limit</span> specifies the maximum number
of messages this queue can hold. If the limit is reached, the next thread that
posts a message will wait until the queue becomes available again. In this version
the default for <span class="def">limit</span> is 5000.</p>
<p><span class="def">void jobqueue::post(message* msg)</span> adds a message to
the queue. <span class="lang">Msg</span> can be an object of class <span class="lang">message</span>
or any derivative class. The <span class="lang">message</span> object should always
be created dynamically using operator <span class="lang">new</span>. The messages
in the queue are processed in order they were posted, i.e. on first-in-first-out
basis.</p>
<p><span class="def">void jobqueue::post(int id, pintptr param = 0)</span> creates
a message object using <span class="lang">id</span> and <span class="lang">param</span>
and calls <span class="lang">post(message*)</span>.</p>
<p><span class="def">void msgqueue::posturgent(message* msg)</span> posts a message
object &quot;out of turn&quot;, i.e. this message will be processed first. The
messages posted through this method are processed on first-in-last-out basis.
<span class="lang">post()</span> and <span class="lang">posturgent()</span> can
be used alternately on the same queue.</p>
<p><span class="def">void jobqueue::posturgent(int id, pintptr param = 0)</span>
creates a message object using <span class="lang">id</span> and <span class="lang">param</span>
and calls <span class="lang">posturgent(message*)</span>.</p>
<p><span class="def">message* jobqueue::getmessage(int timeout = -1)</span> retrieves
the next message from the queue or waits if there are no messages available. The
<span class="lang">timeout</span> parameter specifies the timeout value in milliseconds.
If <span class="lang">timeout</span> is -1 (the default) <span class="lang">getmessage()</span>
will wait for a message infinitely. This function returns a message object, or
otherwise <span class="lang">NULL</span> if the time specified in <span class="lang">timeout</span>
has elapsed. <b>NOTE</b>: the message object returned by this function must be
freed with operator <span class="lang">delete</span>. It is safe to call <span class="lang">getmessage()</span>
concurrently.</p>
<p><span class="def">int jobqueue::get_count()</span> returns the number of messages
currently in the queue.</p>
<p><span class="def">int jobqueue::get_limit()</span> returns the queue limit
set by the constructor.</p>
<p class="seealso">See also: <a href="async.message.html">message</a>, <a href="async.msgqueue.html">msgqueue</a>,
<a href="async.examples.html">Examples</a></p>
<span class="lang"></span><!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.message.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: message</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
message</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
struct message {
int id;
pintptr param;
pintptr result;
message(int id, pintptr param = 0);
}</pre>
</blockquote>
<p>A <span class="lang">message</span> object or an object of a derived class
can be used to post data to message queues (<a href="async.msgqueue.html">msgqueue</a>)
or job queues (<a href="async.jobqueue.html">jobqueue</a>). Messages are distinguished
by a ID that are defined in your application. The user message IDs can be in the
range <span class="lang">0</span> through <span class="lang">INT_MAX</span>. Negative
values are reserved for internal use by the library.</p>
<p>A simple message can also contain an additional parameter of type <span class="lang">pintptr</span>,
which is an integer with a size equal to the size of a pointer on the given platform.
For more complex message structures you can define classes derived from <span class="lang">message
</span> - the message queue manager can work with any descendant class as well.</p>
<p><span class="def">message::message(int id, pintptr param = 0)</span> constructs
a message object and assigns <span class="lang">id</span> and <span class="lang">param</span>
fields. <span class="lang">param</span> is an additional field that can be used
in your application at your own discretion.</p>
<p><span class="def">int message::id</span> -- this field contains a message ID
assigned through the constructor.</p>
<p><span class="def">pintptr message::param</span> contains the optional parameter.</p>
<p><span class="def">pintptr message::result</span> -- through this field a message
handler can return some simple answer to the sender of this message.</p>
<p class="seealso">See also: <a href="async.msgqueue.html">msgqueue</a>, <a href="async.jobqueue.html">jobqueue</a>,
<a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.msgqueue.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: msgqueue</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
msgqueue </p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class msgqueue {
msgqueue(int limit = DEF_QUEUE_LIMIT);
<span class="comment"> // functions calling from the owner thread:</span>
void processone();
void processmsgs();
void run();
<span class="comment"> // functions calling from any thread:</span>
void post(message* msg);
void post(int id, pintptr param = 0);
void posturgent(message* msg);
void posturgent(int id, pintptr param = 0);
int send(message* msg);
int send(int id, pintptr param = 0);
int get_count();
int get_limit();
<span class="comment"> // message handlers</span>
virtual void msghandler(message& msg) = 0;
void defhandler(message& msg);
}
</pre>
</blockquote>
<p>The <span class="lang">msgqueue</span> class implements a queue of <a href="async.message.html">message</a>
objects and is typically used to synchronously exchange data in a multithreaded
environment.</p>
<p>The thread which created the <span class="lang">msgqueue</span> object can
retrieve messages from the queue using one of <span class="lang">run()</span>,
<span class="lang">processmsgs()</span>, <span class="lang">processone()</span>.
Applications always define a class derived from <span class="lang">msgqueue</span>
and override the pure virtual method <span class="lang">msghandler()</span>. The
overridden method receives <span class="lang">message</span> structures and performs
appropriate actions depending on the message ID. Any other thread or even multiple
threads in your application can send or post messages to the given queue using
<span class="lang">post()</span>, <span class="lang">posturgent()</span> or <span class="lang">send()</span>.</p>
<p><span class="lang">Msgqueue</span> can serve as a synchronization object between
threads. Unlike semaphores, where both sending and receiving threads can &quot;hang&quot;
when waiting for readiness of the peer, <span class="lang">msgqueue</span> allows
the sender to send data and immediately continue the execution. The receiver in
its turn processes messages one by one in the same order as they were posted.
</p>
<p>Threads can not only exchange data through a message queue, but also send simple
notifications about various events. Message queues can as well be used in single-threaded
applications with event-driven logic.</p>
<p>A simple example of using <span class="lang">msgqueue</span> could be a server
application with multiple threads, each serving one client; the server maintains
a log file or a table in a database where it records various events. To record
events synchronously the client threads are sending appropriate messages to the
main thread. The client threads never waste time, they just post their messages
and immediately continue their work.</p>
<p><b>IMPORTANT NOTES</b>: (1) a <span class="lang">message</span> object should
always be constructed dynamically, i.e. using operator <span class="lang">new</span>;
(2) a <span class="lang">message</span> object is always destroyed by the queue
manager after it has been processed; (3) a <span class="lang">message</span> object
can be sent and processed only once.</p>
<p>A slower but more universal alternative to the message queue is local pipe
(see <a href="streams.infile.html">infile::pipe()</a>).</p>
<p><span class="def">msgqueue::msgqueue(int limit = DEF_QUEUE_LIMIT)</span> constructs
a message queue object. It doesn't matter which thread is creating this object,
but later only one thread can process the queue and handle messages. <span class="lang">Limit</span>
specifies the maximum number of unhandled messages this queue can hold. If the
limit is reached, the next thread that posts a message will wait until the queue
becomes available again. In this version the default for <span class="def">limit</span>
is 5000.</p>
<p><span class="def">void msgqueue::processone() </span>processes one message
from the queue. This method may &quot;hang&quot; if no messages are available.
<span class="lang">processone()</span> calls the overridden <span class="lang">msghandler()</span>
and then destroys the message object.</p>
<p><span class="def">void msgqueue::processmsgs()</span> processes all messages
in the queue and returns to the caller. If there are no messages in the queue,
<span class="lang">processmsgs()</span> returns immediately. Each message is processed
as described for <span class="lang">processone()</span>.</p>
<p><span class="def">void msgqueue::run()</span> enters an infinite loop of message
processing which can only be terminated by sending or posting a special message
<span class="lang">MSG_QUIT</span> (e.g. <span class="lang">post(MSG_QUIT)</span>).
Each message is processed as described for <span class="lang">processone()</span>.</p>
<p><span class="def">void msgqueue::post(message* msg)</span> adds a message to
the queue. <span class="lang">Msg</span> can be an object of class <span class="lang">message</span>
or any derivative class. The <span class="lang">message</span> object should always
be created dynamically using operator <span class="lang">new</span>. The messages
in the queue are processed in order they were posted, i.e. on first-in-first-out
basis. <span class="lang">post()</span> can be called from any thread, including
the thread owning the queue.</p>
<p><span class="def">void msgqueue::post(int id, pintptr param = 0)</span> creates
a message object using <span class="lang">id</span> and <span class="lang">param</span>
and calls <span class="lang">post(message*)</span>.</p>
<p><span class="def">void msgqueue::posturgent(message* msg)</span> posts a message
object &quot;out of turn&quot;, i.e. this message will be processed first. The
messages posted through this method are processed on first-in-last-out basis.
<span class="lang">post()</span> and <span class="lang">posturgent()</span> can
be used alternately on the same queue. Like <span class="lang">post()</span>,
this method can be called from any thread.</p>
<p><span class="def">void msgqueue::posturgent(int id, pintptr param = 0)</span>
creates a message object using <span class="lang">id</span> and <span class="lang">param</span>
and calls <span class="lang">posturgent(message*)</span>.</p>
<p><span class="def">pintptr msgqueue::send(message* msg)</span> calls the message
handler directly, by-passing the queue. If the sender is the same as the thread
owning the queue, <span class="lang">send()</span> simply calls <span class="lang">msghandler()</span>.
Otherwise, if the sender is a concurrent thread, <span class="lang">send()</span>
enters an effective wait state until the message is processed by the owner thread.
The return value is the value of <span class="lang">result</span> in the message
object. In both cases the message is destroyed upon return from <span class="lang">send()</span>.</p>
<p><span class="def">pintptr msgqueue::send(int id, pintptr param = 0)</span>
creates a message object using <span class="lang">id</span> and <span class="lang">param</span>
and calls <span class="lang">send(message*)</span>. The return value is the value
of <span class="lang">result</span> in the message object.</p>
<p><span class="def">int msgqueue::get_count()</span> returns the number of messages
currently in the queue.</p>
<p><span class="def">int msgqueue::get_limit()</span> returns the queue limit
set by the constructor.</p>
<p><span class="def">virtual void msgqueue::msghandler(message& msg)</span> this
pure virtual method should be overridden to provide application-specific message
handling functionality. <span class="lang">msghandler()</span> usually checks
the message ID through a <span class="lang">switch</span> statement. If the message
ID is unknown to the application, <span class="lang">defhandler()</span> should
be called. The message object <span class="lang">msg</span> CAN NOT be reused
with <span class="lang">post()</span>, <span class="lang">posturgent()</span>
or <span class="lang">send()</span>, neither it can be destroyed within the message
handler. The message handler can assign some value to <span class="lang">msg.result</span>
to return a simple answer to the caller of <span class="lang">send()</span>.</p>
<p><span class="def">void msgqueue::defhandler(message& msg)</span> is called
from within user-defined <span class="lang">msghandler()</span> when the message
ID is unknown to the application. <span class="lang">defhandler()</span> processes
some messages internally used by the library, e.g. MSG_QUIT.</p>
<p class="seealso">See also: <a href="async.message.html">message</a>, <a href="async.jobqueue.html">jobqueue</a></p>
<span class="lang"></span><!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.mutex.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: mutex</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
mutex</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class mutex {
mutex();
void enter();
void leave();
void lock(); <span class="comment">// alias for enter()</span>
void unlock(); <span class="comment">// alias for leave()</span>
}
class scopelock {
scopelock(mutex&amp;);
~scopelock();
}
</pre>
</blockquote>
<p><span class="lang">Mutex</span> (mutual exclusion) is another synchronization
object which helps to protect shared data structures from being concurrently accessed
and modified.</p>
<p>Accessing and changing simple variables like <span class="lang">int</span>
concurrently can be considered safe provided that the variable is aligned on a
boundary &quot;native&quot; to the given CPU (32 bits on most systems). More often,
however, applications use more complex shared data structures which can not be
modified and accessed at the same time. Otherwise, the logical integrity of the
structure might be corrupt from the &quot;reader's&quot; point of view when some
other process sequentially modifies the fields of a shared structure.</p>
<p>To logically lock the part of code which modifies such complex structures the
thread creates a mutex object and embraces the critical code with calls to <span class="lang">enter()</span>
and <span class="lang">leave()</span>. Reading threads should also mark their
transactions with <span class="lang">enter()</span> and <span class="lang">leave()</span>
for the same mutex object. When either a reader or a writer enters the critical
section, any attempt to enter the same section concurrently causes the thread
to &quot;hang&quot; until the first thread leaves the critical section.</p>
<p>If more than two threads are trying to lock the same critical section, <span class="lang">mutex</span>
builds a queue for them and allows threads to enter the section only one by one.
The order of entering the section is platform dependent.</p>
<p>To avoid infinite locks on a mutex object, applications usually put the critical
section into <span class="lang">try {}</span> block and call <span class="lang">leave()</span>
from within <span class="lang">catch {}</span> in case an exception is raised
during the transaction. The <span class="lang">scopelock</span> class provides
a shortcut for this construct: it automatically locks the specified mutex object
in its constructor and unlocks it in the destructor, so that even if an exception
is raised inside the scope of the <span class="lang">scopelock</span> object <span class="lang">leave()</span>
is guaranteed to be called.</p>
<p>More often applications use a smarter mutual exclusion object called read/write
lock -- <a href="async.rwlock.html">rwlock</a>.</p>
<p> PTypes' <span class="lang">mutex</span> object encapsulates either Windows
CRITICAL_SECTION structure or POSIX mutex object and implements the minimal set
of features common to both platforms. <b>Note</b>: mutex may not be reentrant
on POSIX systems, i.e. a recursive lock from one thread may cause deadlock.</p>
<p><span class="def">mutex::mutex()</span> creates a mutex object.</p>
<p><span class="def">void mutex::enter()</span> marks the start of an indivisible
transaction.</p>
<p><span class="def">void mutex::leave()</span> marks the end of an indivisible
transaction.</p>
<p><span class="def">void mutex::lock()</span> is an alias for <span class="lang">enter()</span>.</p>
<p><span class="def">void mutex::unlock()</span> is an alias for <span class="lang">leave()</span>.</p>
<p><span class="def">scopelock::scopelock(mutex&amp; m)</span> creates a <span class="lang">scopelock</span>
object and calls <span class="lang">enter()</span> for the mutex object <span class="lang">m</span>.</p>
<p><span class="def">scopelock::~scopelock()</span> calls <span class="lang">leave()</span>
for the mutex object specified during construction and destroys the <span class="lang">scopelock</span>
object.</p>
<p class="seealso">See also: <a href="async.thread.html">thread</a>, <a href="async.rwlock.html">rwlock</a>,
<a href="async.trigger.html">trigger</a>, <a href="async.semaphore.html">semaphore</a>,
<a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.rwlock.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: rwlock</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
rwlock</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class rwlock {
rwlock();
void rdlock();
void wrlock();
void unlock();
}
class scoperead {
scoperead(rwlock&amp;);
~scoperead();
}
class scopewrite {
scopewrite(rwlock&amp;);
~scopewrite();
}</pre>
</blockquote>
<p><span class="lang">Rwlock</span> (read/write lock) is a variation of <span class="lang">mutex</span>
with a possibility to control critical sections more efficiently. Unlike the simple
mutex, <span class="lang">rwlock</span> allows multiple <i>reader</i> threads
to enter the critical section, and only one <i>writer</i> thread at a time. Reading
and writing in this context means access to a resource or compound data shared
between threads. Reader threads must lock the critical section with <span class="lang">rdlock()</span>
and the writers must lock it with <span class="lang">wrlock()</span>. Both leave
the critical section with <span class="lang">unlock()</span>.</p>
<p>This class incorporates POSIX rwlock interface on UNIX and library's own implementation
on Windows and MacOS X. When using the <span class="lang">rwlock</span> class
on Linux, you need to define a symbol <span class="lang">_GNU_SOURCE</span> either
in the command line, or anywhere in your source before including any system headers.</p>
<p>Analogously to <span class="lang">scopelock</span> (see <a href="async.mutex.html">mutex</a>),
<span class="lang">scoperead</span> and <span class="lang">scopewrite</span> are
fully-inline'd utility classes provided for exception-safe locking of operator
blocks.</p>
<p>Please, see <a href="portability.html">Portability and performance issues</a>
for additional notes on rwlock implementation. </p>
<p><span class="def">rwlock::rwlock()</span> creates a <span class="lang">rwlock</span>
object.</p>
<p><span class="def">void rwlock::rdlock()</span> locks the object for reading.
Multiple threads can enter the critical section through <span class="lang">rdlock()</span>,
however, if the object is already locked for writing, all reader threads wait
until the writer leaves the critical section.</p>
<p><span class="def">void rwlock::wrlock()</span> locks the object for writing.
If there are readers inside the critical section, the writer waits until all threads
leave and unlock the object. Only one writer at a time can enter the critical
section.</p>
<p><span class="def">void rwlock::unlock()</span> unlocks the object. Both readers
and writers must use this method when leaving the critical section.</p>
<p><span class="def">scoperead::scoperead(rwlock&amp; rw)</span> creates a <span class="lang">scoperead</span>
object and calls <span class="lang">rdlock()</span> for the object <span class="lang">rw</span>.</p>
<p><span class="def">scoperead::~scoperead()</span> calls <span class="lang">unlock()</span>
for the <span class="lang">rwlock</span> object specified during construction
and destroys the <span class="lang">scoperead</span> object.</p>
<p><span class="def">scopewrite::scopewrite(rwlock&amp; rw)</span> creates a <span class="def">scopewrite</span>
object and calls <span class="lang">wrlock()</span> for the object <span class="lang">rw</span>.</p>
<p><span class="def">scopewrite::~scopewrite()</span> calls <span class="lang">unlock()</span>
for the <span class="lang">rwlock</span> object specified during construction
and destroys the <span class="def">scopewrite</span> object.</p>
<p class="seealso">See also: <a href="async.thread.html">thread</a>, <a href="async.mutex.html">mutex</a>,
<a href="async.trigger.html">trigger</a>, <a href="async.semaphore.html">semaphore</a>,
<a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.semaphore.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: semaphore</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
semaphore &amp; timedsem</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class semaphore {
semaphore(int initvalue);
void wait();
void post();
void signal(); <span class="comment">// alias for post()</span>
}
class timedsem {
timedsem(int initvalue);
bool wait( [ int milliseconds ] );
void post();
void signal();
}
</pre>
</blockquote>
<p>Semaphore is a special helper object with very simple logic which is typically
used to synchronize the execution of concurrent threads. A semaphore object can
be considered as an integer value which has one additional feature: if its value
is 0, an attempt to decrement this value will cause the calling thread to &quot;hang&quot;
until some other thread increments it. &quot;Hanging&quot; on the semaphore means
entering effective wait state and consuming no or little CPU time, depending on
the operating system.</p>
<p>One example showing the use of semaphores is when one thread needs to send
data (e.g. through a buffer) to another thread. In multithreading environments
there is no guarantee in which order two threads will come to the point where
the first thread is filling the data buffer and the other thread is reading it.
Therefore, these two threads need to synchronize execution at the exchange point.
Semaphore's logic for this case is fairly simple: the reader thread calls wait()
<i>before</i> reading the buffer and &quot;hangs&quot; if the semaphore is not
yet signaled. The writer thread calls post() <i>after</i> filling the buffer with
data and thus signals the reader thread that the data buffer is ready. This schema
ensures that the data buffer will be read by the second thread only when the data
is actually ready.</p>
<p>If the data exchange cycle is iterative you will have to make sure also that
the buffer is not filled twice before the reading thread takes the first data
chunk. In this situation another semaphore should be created with reverse logic:
the semaphore is set to signaled state when the reading thread has taken the first
data chunk and is ready to take the second chunk. The writing thread, in its turn,
waits on this semaphore to make sure the buffer is ready for the successive data
chunk.</p>
<p>In more complex applications when many threads need to exchange data with each
other or with the main application thread, message queues can be used instead
of semaphores. The message queue object itself is another example of using semaphores
(please see <span class="lang">pmsgq.cxx</span> source file).</p>
<p>You can use semaphores when your application needs to limit the number of concurrently
running threads of the same type. A typical web robot application, for example,
creates a new thread for each download process. To limit the number of threads
the application creates a semaphore with the initial value equal to the maximum
allowed number of threads. Each new thread decrements the semaphore by calling
<span class="lang">wait()</span> and then increments it with <span class="lang">post()</span>
upon termination. If the maximum allowed number of threads is reached, the next
thread calling <span class="lang">wait()</span> will &quot;hang&quot; until one
of the running threads terminates and calls <span class="lang">post()</span>.</p>
<p>PTypes' <span class="lang">semaphore</span> object encapsulates either Windows
semaphore or an implementation based on POSIX synchronization primitives. This
object implements the minimal set of features common to both Windows and POSIX
semaphores. Besides, semaphores can not be shared between processes on some operating
systems, thus limiting the use of PTypes' semaphores to one process.</p>
<p>PTypes' <span class="lang">timedsem</span> adds timed waiting feature to
the simple semaphore. This class has an interface compatible with the simple <span class="lang">semaphore</span>
with one additional function - <span class="lang">wait(int)</span> with timer.
The reason this feature is implemented in a separate class is that not all platforms
support timed waiting. Wherever possible, PTypes uses the system's native sync
objects, or otherwise uses its own implementation based on other primitives. Note
that <span class="lang">timedsem</span> can be used both for infinitely waiting
and timed waiting; it is, however, recommended to use simple <span class="lang">semaphore</span>
if you are not going to use timed waiting.</p>
<p>As an example of using <span class="lang">timedsem</span> see implementation
of <span class="lang">thread</span> 'relaxing' mechanism in <span class="lang">include/pasync.h</span>
and <span class="lang">src/pthread.cxx</span>.</p>
<p><span class="def">semaphore::semaphore(int initvalue)</span> constructs a
semaphore object with the initial value <span class="lang">initvalue</span>.</p>
<p><span class="def">void semaphore::wait()</span> decrements the semaphore's
value by 1. <span class="lang">wait()</span> can enter effective wait state if
the value becomes -1, in which case the thread will &quot;hang&quot; until some
other thread increments the value by calling <span class="lang">post()</span>.</p>
<p><span class="def">void semaphore::post()</span> increments the semaphore's
value by 1. <span class="lang">post()</span> can release some other thread waiting
for the same semaphore if its value was -1.</p>
<p><span class="def">void semaphore::signal()</span> is an alias for <span class="lang">post()</span>.</p>
<p><span class="def">timedsem::timedsem(int initvalue)</span> constructs a
semaphore object with an interface fully compatible with (but not inherited from)
<span class="lang">semaphore</span>. This class has one additional method for
timed waiting (see below).</p>
<p><span class="def">bool timedsem::wait( [ int milliseconds ] )</span> decrements
the semaphore's value by 1 and enters effective wait state if the value becomes
-1. Unlike simple <span class="lang">wait()</span> this function will 'wake' and
return if the time specified in <span class="lang">milliseconds</span> has elapsed,
in which case the function returns false. If the semaphore was signaled with <span class="lang">post()</span>
or <span class="lang">signal()</span> before the time elapses this function returns
true. If <span class="lang">milliseconds</span> is omitted or is -1 the function
will wait infinitely, like simple <span class="lang">wait()</span>.</p>
<p class="seealso">See also: <a href="async.thread.html">thread</a>, <a href="async.mutex.html">mutex</a>,
<a href="async.rwlock.html">rwlock</a>, <a href="async.trigger.html">trigger</a>,
<a href="async.msgqueue.html">msgqueue</a>, <a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.thread.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: thread</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
thread </p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class thread {
thread(bool autofree);
~thread();
void start();
void waitfor();
void signal();
pthread_id_t get_id();
bool get_running();
bool get_finished();
bool get_signaled();
virtual void execute() = 0;
virtual void cleanup() = 0;
bool relax(int milliseconds);
}</pre>
</blockquote>
<p>Create a descendant of <span class="lang">thread</span> to represent an execution
thread in a multithreaded application. All threads are running within the framework
of the parent process and share the same global variables. Each thread, however,
has its own stack. The execution of a thread can be started either from the main
process or from another thread. Further, the newly launched thread executes its
code concurrently.</p>
<p>Multithreading can significantly improve your application when a process consumes
time by waiting for data from some communication device, a slow storage device
or user input. When such pieces of code run concurrently the CPU is loaded more
efficiently. Also, many networking services use threading to serve multiple users
simultaneously.</p>
<p>When threads concurrently access and modify shared data structures precautions
should be taken to preserve logical integrity of these data structures. Synchronization
between threads is performed using either of: <a href="async.semaphore.html">semaphore</a>,
<a href="async.mutex.html">mutex</a>, <a href="async.rwlock.html">rwlock</a>,
<a href="async.trigger.html">trigger</a> or <a href="async.msgqueue.html">msgqueue</a>.</p>
<p><span class="def">thread::thread(bool autofree)</span> creates a thread object,
but does not run it. If <span class="lang">autofree</span> is <span class="lang">true</span>
the thread will destroy itself upon termination. Note, that you can use <span class="lang">autofree</span>
only for dynamically allocated thread objects. A variable that holds a pointer
to a dynamic <span class="lang">autofree</span> thread object can be considered
invalid after a call to <span class="lang">start()</span>.</p>
<p><span class="def">thread::~thread()</span> destroys the thread object. Usually
both the constructor and the destructor for non-autofree threads are called from
a different context. In contrary, autofree threads call their destructors from
their own context.</p>
<p><span class="def">void thread::start()</span> runs the thread. The overridden
virtual method <span class="lang">execute()</span> is called asynchronously. <span class="lang">Start()</span>
itself returns immediately. Each thread object can be run only once.</p>
<p><span class="def">void thread::waitfor()</span> waits for the thread to terminate.
This function is called when a thread needs to synchronize its execution with
the completion of the target non-autofree thread. For non-autofree threads this
method must be called <b>at least once</b> and within the scope of a thread that
called <span class="lang">start()</span>. For convenience, you can place a call
to <span class="lang">waitfor()</span> in the overridden destructor. <span class="lang">waitfor()</span>,
however, can not be called for autofree threads.</p>
<p><span class="def">void thread::signal()</span> sets signaled attribute to true
and possibly wakes up the thread if in a `relaxed' state (see <span class="lang">relax()</span>
below). <span class="lang">signal()</span> is usually called from a different
thread to let the given thread know that the execution should be terminated as
soon as possible. If the given thread performs an iteration one of the conditions
of leaving the loop should be <span class="lang">(!get_signaled())</span>. <span class="lang">Signal()</span>
can be called only once for a thread object.</p>
<p><span class="def">pthread_id_t thread::get_id()</span> returns the thread
ID assigned by the operating system. This ID can then be used in call to <span class="lang">pthrequal()</span>.</p>
<p><span class="def">bool thread::get_running()</span> returns <span class="lang">true</span>
if the given thread object is running. This property is never set to <span class="lang">false</span>
once the thread started. To check whether the thread finished its job, i.e. returned
from <span class="lang">execute()</span>, use <span class="lang">get_finished()</span>.</p>
<p><span class="def">bool thread::get_finished()</span> returns <span class="lang">true</span>
if thread has already terminated its execution, or, in other words, has left <span class="lang">execute()</span>.</p>
<p><span class="def">bool thread::get_signaled()</span> returns <span class="lang">true</span>
if the thread object is in signaled state, i.e. <span class="lang">signal()</span>
has been called from a concurrent thread. See also <span class="lang">signal()</span>.</p>
<p><span class="def">virtual void thread::execute()</span> -- this pure virtual
method should be overridden in the descendant class to implement the functionality
of your thread. <span class="lang">execute()</span> can be viewed as <span class="lang">main()</span>
for your mini-process. Typically, you create a class descendant from <span class="lang">thread</span>
and override at least two virtual methods: <span class="lang">execute()</span>
and <span class="lang">cleanup()</span>.</p>
<p><span class="def">virtual void thread::cleanup()</span> -- this pure virtual
method should be overridden in the descendant class. <span class="lang">cleanup()</span>
is called either when the thread terminates normally or when an exception is raised
within the thread's context. When implementing this method you might want to clean
up any memory and other resources allocated by your thread object. <span class="lang">cleanup()</span>
is guaranteed to be called once upon termination of the thread. To properly shut
down the thread, avoid using operations that can cause exceptions in <span class="lang">cleanup()</span>.</p>
<p><span class="def">bool thread::relax(int milliseconds)</span> is a protected
member function which can be called only from within the overridden <span class="lang">execute()</span>
method. This function suspends the execution of the thread until either of: the
specified amount of time is elapsed, in which case the function returns false,
or <span class="lang">signal()</span> is called from a concurrent thread, in which
case <span class="lang">relax()</span> returns true. If parameter <span class="lang">milliseconds</span>
is -1 the function will wait infinitely. The relax/signal mechanism is useful
for threads doing some job that requires taking periodic actions in the background.</p>
<p class="seealso">See also: <a href="async.semaphore.html">semaphore</a>, <a href="async.examples.html">mutex</a>,
<a href="async.rwlock.html">rwlock</a>, <a href="async.trigger.html">trigger</a>,
<a href="async.utils.html">Utilities</a>, <a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.trigger.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: trigger</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
trigger</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
class trigger {
trigger(bool autoreset, bool initstate);
void wait();
void post();
void signal(); <span class="comment">// alias for post()</span>
void reset();
}
</pre>
</blockquote>
<p><span class="lang">Trigger</span> is a simple synchronization object typically
used to notify one or more threads about some event. <span class="lang">Trigger</span>
can be viewed as a simplified semaphore, which has only two states and does not
count the number of wait's and post's. Multiple threads can wait for an event
to occur; either one thread or all threads waiting on a trigger can be released
as soon as some other thread signals the <span class="lang">trigger</span> object.
Auto-reset triggers release only one thread each time <span class="lang">post()</span>
is called, and manual-reset triggers release all waiting threads at once. <span class="lang">Trigger</span>
mimics the Win32 Event object.</p>
<p><span class="def">trigger::trigger(bool autoreset, bool initstate)</span> creates
a trigger object with the initial state <span class="lang">initstate</span>. The
<span class="lang">autoreset</span> feature defines whether the trigger object
will automatically reset its state back to non-signaled when <span class="lang">post()</span>
is called.</p>
<p><span class="def">void trigger::wait()</span> waits until the state of the
trigger object becomes signaled, or returns immediately if the object is in signaled
state already.</p>
<p><span class="def">void trigger::post()</span> signals the trigger object. If
this is an auto-reset trigger, only one thread will be released and the state
of the object will be set to non-signaled. If this is a manual-reset trigger,
the state of the object is set to signaled and all threads waiting on the object
are being released. Subsequent calls to <span class="lang">wait()</span> from
any number of concurrent threads will return immediately.</p>
<p> <span class="def">void trigger::signal()</span> is an alias for <span class="lang">post()</span>.</p>
<p><span class="def">void trigger::reset()</span> resets the state of the trigger
object to non-signaled.</p>
<p class="seealso">See also: <a href="async.thread.html">thread</a>, <a href="async.mutex.html">mutex</a>,
<a href="async.rwlock.html">rwlock</a>, <a href="async.semaphore.html">semaphore</a>,
<a href="async.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/async.utils.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: multithreading: utils</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="async.html">Multithreading</a>:
Atomic functions, utilities</p>
<blockquote>
<pre class="lang">#include &lt;pasync.h&gt;
int pexchange(int* target, int value);
void* pexchange(void** target, void* value);
int pincrement(int* target);
int pdecrement(int* target);
template &lt;class T&gt; T* tpexchange(T** target, T* value);
void psleep(unsigned milliseconds);
pthread_id_t pthrself();
bool pthrequal(pthread_id_t id);
</pre>
</blockquote>
<p>The atomic functions <span class="lang">pexchange()</span>, <span class="lang">pincrement()</span>
and <span class="lang">pdecrement()</span> can be used in place of mutex locking
in some simple situations. A typical usage of <span class="lang">pexchange()</span>
in a multithreaded environment could be, for example, freeing a dynamic object
and assigning NULL to the pointer <b>atomically</b> to prevent concurrent threads
from freeing the same object more than once.</p>
<p>It is sometimes necessary to increment or decrement some shared counter and
atomically compare it with some value. For example, you have a shared resource
and you keep track of its usage by maintaining a reference counter. When this
counter reaches 0 you want to free the shared resource. To avoid conflicts between
concurrent threads you need to decrement the counter and atomically compare it
with 0. In this situation you can use <span class="lang">pdecrement()</span> instead
of time-consuming mutex locking. (For additional notes, see <a href="portability.html">Portability
and performance issues</a>.)</p>
<p><span class="def">int pexchange(int* target, int value)</span> -- atomically
exchanges two int values.</p>
<p><span class="def">void* pexchange(void** target, void* value)</span> -- atomically
exchanges two pointers.</p>
<p><span class="def">int pincrement(int* target)</span> -- atomically increments
the value of <span class="lang">*target</span> and returns the new value.</p>
<p><span class="def">int pdecrement(int* target)</span> -- atomically decrements
the value of <span class="lang">*target</span> and returns the new value.</p>
<p><span class="def">template &lt;class T&gt; T* tpexchange(T** target, T* value)</span>
-- is equivalent to <span class="lang">pexchange()</span> that adds compile-time
type checking. Use this template to check the correspondence of pointer types
of <span class="lang">target</span> and the returning value.</p>
<p><span class="def">void psleep(unsigned milliseconds)</span> -- suspends execution
for the specified amount of time in milliseconds.</p>
<p><span class="def">pthread_id_t pthrself()</span> -- returns the thread ID of
the calling thread.</p>
<p><span class="def">bool pthrequal(pthread_id_t id)</span> -- checks whether
the calling thread has the given thread <span class="lang">id</span>.</p>
<p class="seealso">See also: <a href="async.semaphore.html">semaphore</a>, <a href="async.examples.html">mutex</a>,
<a href="async.thread.html">thread</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/basic.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: basic types</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" --><span class="seealso"></span>
<p class="hpath"><a href="index.html">Top</a>: Basic types</p>
<ul>
<li>
<h5><a href="string.html">Dynamic strings</a> (string)</h5>
</li>
<li>
<h5><a href="cset.html">Character sets</a> (cset)</h5>
</li>
<li>
<h5><a href="lists.html">Lists</a> (tpodlist, tobjlist, tstrlist, textmap)</h5>
</li>
<li>
<h5><a href="variant.html">Variants</a> (variant)</h5>
</li>
<li>
<h5><a href="time.html">Date/Time type and utilities</a> (datetime)</h5>
</li>
<li>
<h5><a href="unknown.html">Abstract interfaces</a> (unknown &amp; component)</h5>
</li>
<li>
<h5><a href="unit.html">Unit</a></h5>
</li>
</ul>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/changes.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: Changes</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="intro.html">Introduction</a>:
Changes </p>
<p><br>
<b>Version 2.1.1</b></p>
<ul>
<li>Added support for HP-UX</li>
<li>Compilation problems solved on *BSD systems (64-bit seek issue, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1719507&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Several MacOS X compilation problems solved (socklen_t, libtool)</li>
<li>MSVC project files are now in the new VC7+ format (.sln, .vcproj)</li>
<li>Dropped support for BSDi, CygWin and also the Borland C++ compiler.
</ul>
<p><b>Version 2.1.0</b></p>
<ul>
<li>64-bit file positioning is now fully supported in stream classes. New methods <span class="lang">tellx()</span> and <span class="lang">seekx()</span> were added for this. Old methods <span class="lang">tell()</span> and <span class="lang">seek()</span> still return 32-bit offsets and may raise an exception if the returned value doesn't fit. </li>
<li>In addition to Intel and PowerPC processors, atomic functions for SPARC were rewritten in the assembly language, too (previously a mutex hash table was used).</li>
<li>All socket interfaces now have a virtual function <span class="lang">sockopt()</span> that can be overridden in descendant classes. This function is always called immediately after a socket descriptor is created, so that you can set up any additional socket options via a system call <span class="lang">setsockopt()</span>.</li>
<li><span class="lang">semaphore::wait()</span> now handles EINTR which may occur if a process catches a signal. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1648207&group_id=56008&atid=479024">Bug report</a>)</li>
</ul>
<p><b>Version 2.0.3</b></p>
<ul>
<li>Bug fixed that affected <span class="lang">pack()</span> and <span class="lang">grow()</span> methods in list classes (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1402027&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Bug fixed in <span class="lang">del(string&amp; ...)</span> (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=977589&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Bug fixed in <span class="lang">instm::seek()</span> with <span class="lang">IO_CURRENT</span> (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=910890&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Bug fixed in <span class="lang">outmemory::seek()</span> for unlimited streams (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=970980&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Bug fixed in <span class="lang">thread::~thread()</span> for thread objects that never ran (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=964313&group_id=56008&atid=479024">Bug report</a>)</li>
<li>Visual C project files are now in DOS text format. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=777636&group_id=56008&atid=493273">Problem report</a>)</li>
<li>PTypes-1.8 compatibility code removed (1.9-style lists are still supported)</li>
<li>Author's email has changed, please see Introduction.</li>
</ul>
<p><b>Version 2.0.2</b></p>
<ul>
<li>The memory corruption problem with the LinuxThreads library fixed (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=687425&group_id=56008&atid=493273">Problem
report</a>).</li>
<li>Added versions of <span class="lang">ipmessage::receive()</span> that also
return the source IP address.</li>
<li>Added new properties and methods to <span class="lang">inmemory</span> and
<span class="lang">outmemory</span> classes to allow reusability of objects of
these types. Also cleaned up implementation of <span class="lang">outmemory</span>
so that the <span class="lang">increment</span> property is no longer needed.</li>
<li>Added <span class="lang">textmap::getkey()</span> method.</li>
<li>Added const versions of <span class="lang">operator[]</span> for <span class="lang">string</span>
and <span class="lang">tpodlist</span>.</li>
<li>Bug fixed in <span class="lang">pexchange()</span> on PowerPC with gcc 3.3
(<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=947699&group_id=56008&atid=479024">Bug
report</a>) </li>
<li>Bug fixed in the <span class="lang">string</span> class (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=926569&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>Bugs fixed in the memory stream classes (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=947709&group_id=56008&atid=479024">Bug
report1</a>, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=949025&group_id=56008&atid=479024">Bug
report 2</a>)</li>
</ul>
<p><b>Version 2.0.1</b></p>
<ul>
<li>Bugs fixed in 1.9-compatibility interfaces. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=922470&group_id=56008&atid=479024">Bug
report 1</a>, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=924161&group_id=56008&atid=479024">Bug
report 2</a>)</li>
<li>Bug fixed in wshare. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=923830&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>Some minor fixes in the documentation.</li>
</ul>
<p><b>Version 2.0.0</b></p>
<ul>
<li>The list class/template family has been redesigned and expanded with new,
more flexible interfaces. An overview is given in the <a href="lists.html">Introduction
to lists</a>. The old interfaces are preserved in the headers for backward compatibility.</li>
<li>Ported the library to Cygwin.</li>
<li>'<span class="lang">make install</span>' copies the header files and the binaries
to default system locations.</li>
<li><span class="lang">Jobqueue</span> and <span class="lang">msgqueue</span>
are now protected from overflows by an extra semaphore. If the number of unhandled
messages in a queue reaches <span class="lang">limit</span> (a parameter set through
the constructor) the post/send operation waits on a semaphore until the queue
becomes available again.</li>
<li>Windows DLLs now called: ptypes20.dll and ptypes20g.dll, generted by MSVC
and GCC respectively.</li>
<li>Added <span class="lang">__stdcall</span> (<span class="lang">ptdecl</span>
macro) modifiers for all public functions in the library to be independent from
the compiler command-line options on Windows.</li>
<li>Variant arrays have been optimized for memory usage.</li>
<li>All classes in the library are now either copyable or non-copyable explicitly.</li>
<li>The last parameter of <span class="lang">copy()</span> and <span class="lang">del()</span>
for strings is now optional.</li>
<li>Fixed a bug in <span class="lang">instm::seek()</span>. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=910890&group_id=56008&atid=479024">Bug
report</a>)</li>
</ul>
<p><b>Version 1.9.0</b></p>
<ul>
<li>A new class <a href="async.jobqueue.html">jobqueue</a> has been added. As
shown in the multithreading examples, it helps to easily implement a thread-pool
model.</li>
<li><a href="async.examples.html">Multithreading examples</a> have been re-written.
Example 2 is now a full-featured multithreaded server template with a thread pool.</li>
<li>Atomic functions for PowerPC have been implemented in the assembly language.</li>
<li>UNIX shared object naming style has been changed. The shared library is now
named libptypes.so.19 (libptypes.19.dylib on MacOS). The shared object now 'remembers'
its real name (with the -soname option) for correct linking of user applications.
(<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=881525&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>Windows/MSVC DLL has been renamed to ptypes19.dll because of incompatible
changes in the library structures. The DLL built by Dev-C++ has been renamed to
ptypes19dc.dll for the same reason and also to avoid clashing with MSVC-generated
DLL.</li>
<li>The multithreaded version of the dynamic string class has been improved.</li>
<li>A minor performance fixup in <span class="lang">msgqueue::send()</span> -
the semaphore is no longer allocated dynamically.</li>
<li>The <span class="lang">exceptobj</span> class has been renamed to <span class="lang">exception</span>,
<span class="lang">tsemaphore</span> - to <span class="lang">timedsem</span>.
The old names are typedef'ed for compatibility with older versions of the library.</li>
<li>The <span class="lang">message</span> class now uses a portable typedef <span class="lang">pinptr</span>
for the <span class="lang">param</span> and <span class="lang">result</span> fields.
This allows to use these fields both as integers and pointers when necessary.
The <span class="lang">id</span> field can now be in the range <span class="lang">0</span>
to <span class="lang">INT_MAX</span>; the internal value <span class="lang">MSG_QUIT</span>
is now a negative value.</li>
<li><span class="lang">Bind()</span> and <span class="lang">bindall()</span> now
return values that can be used in call to <span class="lang">poll()</span> and
<span class="lang">serve()</span> for <span class="lang">ipserver</span> objects.</li>
<li><span class="lang">setlength(string&amp;)</span> now returns a <span class="lang">char*</span>
value.</li>
<li>A bug has been fixed in the <span class="lang">trigger</span> class. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=804108&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>The <span class="lang">contains()</span> family of functions has been fixed
to correctly handle empty test strings. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=821458&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>The <span class="lang">ins()</span> family of functions has been fixed to
correctly handle values of <span class="lang">at</span> beyond the last character
of a string. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=834876&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>A bug has been fixed in the internal function <span class="lang">psockname()</span>
that caused <span class="lang">get_myport()</span> methods (<span class="lang">ipstream</span>
and <span class="lang">ipmessage</span> classes) to return an incorrect value.
(<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=838823&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>Compiler warning (and a potential problem) has been fixed on 64-bit systems.
(<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=782336&group_id=56008&atid=493273">Problem
report</a>)</li>
</ul>
<p><b>Version 1.8.3</b></p>
<ul>
<li>Public header files are now included in the documentation in browsable form
(see <a href="htsrc.html">Header files</a>).</li>
<li>Delete notification mechanism for components, previously undocumented, now
described in section <a href="unknown.html">Unknown &amp; Component</a>.</li>
<li>Variant-to-string typecast problem has been fixed that caused compilation
errors with GCC 3.3 (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=782334&group_id=56008&atid=493273">Problem
report</a>)</li>
<li>A problem has been solved that allowed template lists to accept any class
type, even if it's not derived from <span class="lang">unknown</span>. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=715928&group_id=56008&atid=493273">Problem
report</a>)</li>
<li>A better explanation of the librarie's policies and philosophy is given in
section 'Why use PTypes?' (see <a href="intro.html">Introduction</a>).</li>
</ul>
<p><b>Version 1.8.2</b></p>
<ul>
<li>The library has been ported to BSD/OS (BSDI). There is also limited support
for OpenBSD and NetBSD without makefiles.</li>
<li>The library now compiles with Visual C/C++ 7.1 (.NET) after considerable changes
in <span class="lang">&lt;ptypes.h&gt;</span></li>
<li>A bug has been fixed in <span class="lang">instm::token()</span> that caused
segfaults. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=769428&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>A problem has been fixed in <span class="lang">phost*()</span> functions that
caused segfaults on SuSE Linux. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=782329&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>A bug has been fixed in wshare: the plus sign '+' should not be decoded as
space in URL components other than query. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=777682&group_id=56008&atid=479024">Bug
report</a>)</li>
</ul>
<p><b>Version 1.8.1</b></p>
<ul>
<li>The following functions have been fixed to be thread-safe on UNIX systems:
<span class="lang">phostbyname()</span>, <span class="lang">phostbyaddr()</span>,
<span class="lang">phostcname()</span>, <span class="lang">nowstring()</span>,
and also <span class="lang">now()</span> and <span class="lang">tzoffset()</span>
on MacOS X. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=762224&group_id=56008&atid=479024">Bug
report 1</a>, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=763891&group_id=56008&atid=479024">Bug
report 2</a>)</li>
</ul>
<p><b>Version 1.8.0</b></p>
<ul>
<li>The library now compiles in 3 versions: static single-threaded, static multithreaded
and dynamic (shared) multithreaded (see <a href="compiling.html">Compiling</a>).
On some platforms single-threaded dynamic strings can be twice as faster than
multithreaded. </li>
<li>New format specifiers for <a href="streams.outstm.html">outstm::putf()</a>
introduced: <span class="lang">%a</span> for IP addresses and <span class="lang">%t</span>
for timestamps. </li>
<li>New classes <a href="async.mutex.html">scopelock</a>, <a href="async.rwlock.html">scoperead</a>
and <a href="async.rwlock.html">scopewrite</a> added in <span class="lang">pasync.h</span>.</li>
<li>New conversion functions added <span class="lang">stringtoie()</span> and
<span class="lang">stringtoue()</span> (see <a href="string.conversion.html">String
conversion</a>).</li>
<li>A bug has been fixed in <span class="lang">tsemaphore::wait()</span>. This
bug affected all platforms except Windows. (<a href="https://sourceforge.net/tracker/index.php?func=detail&aid=755242&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>SO_REUSEADDR problem fixed on Windows. (<a href="https://sourceforge.net/tracker/index.php?func=detail&aid=738829&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>A bug has been fixed in <span class="lang">stringtoi()</span>. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=757188&group_id=56008&atid=479024">Bug
report</a>)</li>
</ul>
<p><b>Version 1.7.6</b></p>
<ul>
<li>The library now compiles with Dev-C++/MinGW on Windows. Dev-C++ project files
have been created for building the static and shared libraries, as well as the
demo and testing programs.</li>
<li>A new file output class called <a href="streams.logfile.html">logfile</a>
has been created as a result of a discussion around this <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=712307&group_id=56008&atid=479024">bug
report</a>.</li>
<li><span class="lang">Wshare</span> can now downgrade process privileges (setuid/setgid)
on UNIX. Also, file handling and server status report has moved to separate optional
modules mod_file.cxx and mod_wstat.cxx.</li>
<li>A new section has been added in the documentation: <a href="http://www.melikyan.com/ptypes/doc/ext/">Resources</a>.
This page can be accessed only on-line on the master server, since changes here
may appear more frequently than in the library documentation.</li>
<li>Bugs have been fixed in <span class="lang">tzoffset()</span> for Windows and
Solaris (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=705957&group_id=56008&atid=479024">Bug
report 1</a>, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=709146&group_id=56008&atid=479024">Bug
report 2</a>).</li>
<li>A bug has been fixed in <span class="lang">strmap::strmap()</span> constructor
(<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=716000&group_id=56008&atid=479024">Bug
report</a>).</li>
<li>Thread creation routine has been changed on Windows to ensure thread-safety
of system static variables (<a href="https://sourceforge.net/tracker/index.php?func=detail&aid=706041&group_id=56008&atid=479024">Bug
report</a>).</li>
</ul>
<p><b>Version 1.7.5</b></p>
<ul>
<li>A <span class="lang">tv_usec</span>-related bug fixed in all socket/pipe waiting
and polling routines. Non-integral timeout values were treated incorrectly in
the previous versions of the library. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=652513&group_id=56008&atid=479024">Bug
report</a>)</li>
<li>Fixed return type for <span class="lang">tstrmap::operator[]</span>. (<a href="http://sourceforge.net/tracker/index.php?func=detail&aid=661312&group_id=56008&atid=479024">Bug
report</a>)</li>
<li><span class="lang">instm::putback()</span> added.</li>
</ul>
<p><b>Version 1.7.4</b></p>
<ul>
<li>A new class <a href="unit.html">unit</a> has been added. Unit is a mini-process
with its own <span class="lang">main()</span> and input/output 'plugs'; several
unit objects within the framework of one application can be connected to form
pipes, like processes in the UNIX shell.</li>
<li>A new method for creating local pipes, <a href="streams.infile.html">infile::pipe()</a>,
has been added.</li>
<li>Null output stream object has been added as a static variable <a href="streams.stdio.html">pnull</a>.</li>
<li><span class="lang">__ptypes_version</span> and the DLL version resource were
not incremented in the previous release. Now they both show 1.7.4.</li>
<li><span class="lang">outmemory::get_strdata()</span> added.</li>
</ul>
<p><b>Version 1.7.3</b></p>
<ul>
<li>Wrapper templates for <span class="lang">objlist</span>, <span class="lang">strlist</span>
and <span class="lang">strmap</span> have been created. These templates help to
avoid extra (dangerous) pointer typecasts and provide better compile-time type
checking when using lists with objects derived from <span class="lang">unknown</span>.
See introduction to <a href="lists.html">Lists</a>.</li>
<li>A new class template <a href="unknown.html">compref</a> has been added that
implements a 'smart' pointer to a reference-counted <span class="lang">component</span>
object.</li>
<li>Function template <a href="async.utils.html">tpexchange()</a> has been added
as a type-safe wrapper for <span class="lang">pexchange()</span>.</li>
<li>New methods <a href="inet.ipstream.html">ipstream::get_myport()</a> and <a href="inet.ipmessage.html">ipmessage::get_myport()</a>
have been added.</li>
</ul>
<p><b>Version 1.7.2</b></p>
<ul>
<li>Fixed compilation and linking parameters for Linux and FreeBSD to build the
shared library correctly (thanks to Alan Eldridge).</li>
<li>Bug fixed in wshare/urlutils.cxx: the URL parameters (protocol parameters,
query string and fragment) were treated incorrectly in previous versions.</li>
</ul>
<p><b>Version 1.7.1</b></p>
<ul>
<li>A new section called &quot;<a href="deploying.html">Deploying the shared (dynamic)
library</a>&quot; is now included in the documentation. It describes in detail
the procedure of using and deploying the shared (dynamic) library, discusses advantages
and disadvantages of dynamic linking vs. static linking.</li>
<li>PTypes.DLL now contains a version resource. In addition, the library declares
a global variable __ptypes_version, which can be checked at run-time or during
installation on UNIX.</li>
<li><span class="lang">strlist::compare()</span> is declared as virtual to allow
alternate sorting algorithms in descendant classes.</li>
</ul>
<p> <b>Version 1.7.0</b></p>
<ul>
<li><a href="variant.html">Variant</a> class implemented. A <span class="lang">variant</span>
variable can hold values of many fundamental types (int, bool, datetime, float,
string) plus associative arrays of variants and reference-counted pointers to
objects. Variants can be used for designing interpreters for higher-level languages,
designing or working with databases and spreadsheets, etc.</li>
<li>Message-oriented networking classes (<a href="inet.ipmessage.html">ipmessage</a>
and <a href="inet.ipmsgserver.html">ipmsgserver</a>) implemented based on the
UDP protocol.</li>
<li>The library now compiles both as a shared object (DLL on Windows) and a static
library. The shared object (or DLL) is placed in <span class="lang">so/</span>
when building the library.</li>
<li><span class="lang">outstm::putf()</span> is now atomic with respect to multithreading.</li>
<li><span class="lang">Ipsocket</span> renamed to <span class="lang">ipstream</span>,
<span class="lang">ipserver</span> renamed to <span class="lang">ipstmserver</span>.
The old names are available as typedef's for compatibility.</li>
</ul>
<p><b>Version 1.6.1</b></p>
<ul>
<li>Read/write lock (<a href="async.rwlock.html">rwlock</a>) algorithm improved
to be &quot;fairer&quot; with respect to both readers and writers.</li>
<li><a href="async.trigger.html">Trigger</a> algorithm fixed to be fully compatible
with Windows event interface.</li>
<li><span class="lang">psleep()</span> fixed on Solaris to be reentrant (multithreaded).</li>
</ul>
<p><b>Version 1.6.0</b></p>
<ul>
<li>Portable named pipes added - <a href="streams.namedpipe.html">namedpipe</a>
and <a href="streams.npserver.html">npserver</a>.</li>
<li>Read/write lock class <a href="async.rwlock.html">rwlock</a> (a smarter mutex)
added.</li>
<li><a href="async.trigger.html">Trigger</a> (a simplified semaphore) class added.</li>
<li>Memory stream classes <a href="streams.inmem.html">inmemory</a> and <a href="streams.outmem.html">outmemory</a>,
previously undocumented, now described in section Streams.</li>
<li> Windows InterlockedXXX calls replaced with internal assembly code to work
as expected even on Win95.</li>
<li>A string-to-int (64-bit) conversion routine added - <span class="lang">stringtoi()</span>.</li>
<li><span class="lang">ipsocket::get_myip()</span> added.</li>
<li>Dynamic string assignment and <span class="lang">itostring()</span> optimized.</li>
<li>Better diagnostics messages for <span class="lang">ipserver</span>.</li>
</ul>
<p><b>Version 1.5.3</b></p>
<ul>
<li>Token extraction methods can now optionally limit input and throw en exception
if the token exceeds the limit. This new feature is targeted to real-world networking
applications.</li>
<li>A new section &quot;<a href="portability.html">Portability and Performance
Issues</a>&quot; and an <a href="ref.html">alphabetical reference</a> of all public
symbols added in the documentation.</li>
<li>Examples for the sockets interface and some other modules rewritten to be
cleaner and more educational.</li>
<li> GCC 3.x compilation problem solved in pinet.h (friend class declaration).</li>
</ul>
<p><b>Version 1.5.2</b></p>
<ul>
<li> Dynamic strings have been optimized and thoroughly tested. Compared to MFC
CString class, PTypes dynamic strings now show much better performance.</li>
<li> Bug fixed in <span class="lang">decodedate()</span>. This function worked
incorrectly for the last day (12/31) of each leap year.</li>
</ul>
<p><b></b><b>Version 1.5.1</b></p>
<ul>
<li> Documentation cleanup.</li>
<li> A sample compile-time module for wshare, which responds to http://hostname/.about
requests. Code cleanup in wshare.</li>
</ul>
<p><b>Version 1.5.0</b></p>
<ul>
<li> Wshare is becoming modular/scalable. Custom handlers for a new HTTP method,
file extension or a nonexistent path can be easily incorporated into wshare at
compile time. Currently this feature is documented only in the source files.</li>
<li> Wshare can show the server status report through http://localhost/.wstat</li>
<li> Standard input, output and error devices are declared in &lt;pstreams.h&gt;
as pin, pout and perr stream objects respectively.</li>
<li> New printf-style formatted output method <span class="lang">outstm::putf()</span>.
Accepts only a subset of format specifiers common to all platforms.</li>
<li> Bug fix in <span class="lang">outstm::put()</span>.</li>
<li> Handle leak on Windows fixed.</li>
<li> realloc-related memory leak on UNIX fixed.</li>
<li> Bug in string class fixed: <span class="lang">s += s</span> was working incorrectly
in previous versions.</li>
</ul>
<p><b></b><b>Version 1.4.1</b></p>
<ul>
<li> The MD5 module is replaced with L. Peter Deutsch's implementation. Please,
see comments in <span class="lang">src/pmd5.cxx</span>.</li>
<li> Wshare: code cleanup in various modules; Borland C++ port (<span class="lang">wshare/wshare.mak</span>);
a new option <span class="lang">-x</span> to ignore default index files and always
show directory indexes.</li>
<li> Include directives in <span class="lang">src/pipserver.cxx</span> and <span class="lang">src/pipsocket.cxx</span>
have been reordered to avoid compiler errors on some Linux systems.</li>
</ul>
<p><b>Version 1.4.0</b></p>
<ul>
<li> A big sample program called wshare is now included in the project. Wshare
is a simple and fast HTTP/1.1 web server; it demonstrates the full power of PTypes.
Currently wshare lacks server-side scripting functionality, however, it can be
used to quickly share local files over the web.</li>
<li> Waiting for data with timeout on a socket object is implemented (<span class="lang">ipsocket::waitfor()</span>).</li>
<li> <span class="lang">SIGPIPE</span> is now blocked on UNIX when using PTypes'
sockets.</li>
<li> A new utility function <span class="lang">utodatetime()</span> for converting
UNIX <span class="lang">time_t</span> values to PTypes datetime.</li>
<li> Atomic exchange for pointers is implemented separately, since on 64-bit platforms
the size of a void pointer differs from the size of int.</li>
<li> A bug fix for autofree threads. Please note that semantics of <span class="lang">thread::waitfor()</span>
has changed (see documentation for details).</li>
</ul>
<p><b></b><b>Version 1.3.2</b></p>
<ul>
<li> Ported to MacOS X (Darwin).</li>
<li> Important fixes in the thread module (<span class="lang">src/pthread.cxx</span>):
PTypes now ensures proper operation and memory cleanup on all platforms, even
with buggy implementation of the POSIX threads specs.</li>
<li> Compiled under Linux/Alpha, Linux/PowerPC and Linux/Sparc with minor fixes:
<span class="lang">ipaddress</span> type is now castable to unsigned long instead
of signed long; variables of type ipaddress must be compared with ipnone instead
of -1.</li>
</ul>
<p><b>Version 1.3.1</b></p>
<ul>
<li> CVS repository setup at SourceForge.net (see the main page for details).</li>
<li> Various fixes in the documentation.</li>
<li> Fixes in the BCC makefile <span class="lang">src/ptypes.mak</span>.</li>
</ul>
<p><b></b><b>Version 1.3</b></p>
<ul>
<li> <a href="inet.html">IP socket</a> manipulation classes and utilities, finally!</li>
<li> The new <a href="time.html">datetime</a> type along with time/calendar manipulation
utilities.</li>
<li> Timed semaphore class <a href="async.semaphore.html">tsemaphore</a>.</li>
<li> The library now compiles within a namespace &quot;pt&quot; by default.</li>
<li> <span class="lang">semaphore::post()</span> and <span class="lang">semaphore::wait()</span>
now do not return any values. If these functions fail, a fatal non-recoverable
error is raised instead of returning an error code to the caller. It is senseless
to run a multithreaded application if the system fails to operate semaphores.</li>
<li> Bug fixed in non-Intel version of <span class="lang">pexchange()</span>.</li>
</ul>
<p><b>Version 1.2</b></p>
<ul>
<li> The entire library can now be conditionally enclosed within a namespace to
avoid name conflicts in large projects. By default the library does NOT compile
within a namespace.</li>
<li> Several fixes to improve performance of the dynamic string class, as well
as to make it thread safe (see introduction to <a href="string.html">string class</a>).</li>
<li> Ported to SunOS. (The library should now compile virtually on any UNIX platform.
Need some time and access to different computers.)</li>
<li> Compiled with Borland C++ 5.5 (aka C++ Builder) under Windows. The makefile
is <span class="lang">src/ptypes.mak</span>.</li>
<li> MD5 (message digest) algorithm is implemented as an output stream class <a href="streams.md5.html">outmd5</a>.</li>
<li> Bug fixes in <span class="lang">src/pinstm.cxx</span> and <span class="lang">src/poutstm.cxx</span>.</li>
</ul>
<p><b>Version 1.1 was the first public release</b></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/compiling.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: Compiling and Porting</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="intro.html">Introduction</a>:
Compiling and Porting</p>
<p><br>
<b>Supported platforms and compilers</b></p>
<blockquote>
<p><b>Linux/i386, Alpha, PPC, Sparc, AMD64</b>: GNU C/C++</p>
<p><b>MacOS X/Intel, PPC</b>: CC - Apple Objective-C compiler</p>
<p><b>SunOS/Sparc, i386</b>: GNU C/C++</p>
<p><b>FreeBSD</b>: GNU C/C++</p>
<p><b>HP-UX</b>: aCC</p>
<p><b>Windows</b>: MS Visual Studio 7, 8</p>
<p><b><br>
</b><br>
The build process on all platforms produces 3 versions of the library: static
single-threaded, static multithreaded and dynamic (shared) multithreaded. In addition,
MSVC can build debug versions for each of these 3 libraries.</p>
<p>Single-threaded versions have a suffix 'n' (non-reentrant) in their names:
<span class="lang">libptypesn.a</span> for UNIX and MinGW and <span class="lang">ptypesn.lib</span>
for MSVC. They are somewhat faster and smaller than the multithreaded versions
and are intended to be used in smaller projects that do not require to be linked
with the slower reentrant system libraries.</p>
<p>The dynamic versions of the library have the library version number in their
names: <span class="lang">ptypes21.dll</span>, <span class="lang">libptypes.so.21</span>
and <span class="lang">libptypes.21.dylib</span>. The version number in file names
reflects incompatible changes and/or significant enhancement of functionality.
Change in the third number in the version usually indicates a compatible improvement
and/or bug fix release, so it is not reflected in the DLL/so file name.</p>
</blockquote>
<p><b><br>
Building on UNIX and MacOS X</b></p>
<blockquote>
<p>In order to build the library on one of the UNIX systems listed above, run
<span class="lang">make</span> in the library's root directory. The makefile in
this directory actually calls makefiles in <span class="lang">src/</span> and
<span class="lang">wshare/</span> with a suffix which is an output of <span class="lang">uname</span>
on the given system (e.g. <span class="lang">src/Makefile.Linux</span> or <span class="lang">src/Makefile.FreeBSD</span>).
Make builds the library and the demo program, and then places:</p>
<ul>
<li>Static single-threaded version -&gt; <span class="lang">lib/libptypesn.a</span></li>
<li>Static multi-threaded version -&gt; <span class="lang">lib/libptypes.a</span></li>
<li>Shared multi-threaded version -&gt; <span class="lang">so/libptypes.so.21</span>
(<span class="lang">libptypes.21.dylib</span> on MacOS X)</li>
<li>Demo program -&gt; <span class="lang">bin/wshare</span></li>
</ul>
<p> The public headers are in <span class="lang">include/</span>.</p>
<p>When building your own multithreaded application on <b>Linux</b> or <b>FreeBSD</b>,
GCC requires you to specify a special command-line option <span class="lang">-pthread</span>
which automatically links POSIX threads library and the reentrant version of <span class="lang">libc</span>.
On <b>Linux</b> you should specify a macro <span class="lang">-D_GNU_SOURCE</span>
in the command line to include the <span class="lang">rwlock</span> interface.</p>
<p>When building your multithreaded application on <b>SunOS</b>, you should specify
a macro <span class="lang">-D_REENTRANT</span> and also link the following libraries:
<span class="lang">-lpthread -lposix4</span> for multithreaded applications, and
in addition, <span class="lang">-lsocket -lnsl</span> for network applications.
<i>NOTE</i>: if you omit <span class="lang">-lpthread</span>, the program links
without errors, but then the thread objects fail to initialize.</p>
</blockquote>
<p><b><br>
Building on Windows with MSVC 7 or 8</b></p>
<blockquote>
<p>The MSVC project files are:</p>
<ul>
<li><span class="lang">win32\PTypes_Lib_ST.vcproj</span> - static single-threaded
version </li>
<li><span class="lang">win32\PTypes_Lib.vcproj</span> - static multithreaded version</li>
<li><span class="lang">win32\PTypes_DLL.vcproj</span> - dynamic multithreaded version</li>
<li><span class="lang">win32\wshare.vcproj</span> - the demo program</li>
</ul>
<p>A "solution" file <span class="lang">PTypes.sln</span> is provided for building
all components and versions of the library.</p>
<p>You can include one of the project files in your own solutions. Make your
project dependent of PTypes to automatically link the library to your program.
To use PTypes headers you will have to explicitly specify the directory in your
project settings, e.g. &quot;<span class="lang">..\ptypes\include</span>&quot;.</p>
<p>In order to link a program against the DLL version of PTypes (<span class="lang">ptypes21.dll</span>)
use <span class="lang">PTYPES_DLL</span> macro definition when compiling your
modules. You may want to add a post-build command in the MSVC environment that
copies the PTypes DLL to the directory where you build and debug your application.</p>
<p>You should link your application with the multithreaded version of CRTL, except
when using the single-threaded <span class="lang">ptypesn.lib</span>. When compiling
with the dynamic version of PTypes, it is recommended also to use the multithreaded
DLL version of CRTL.</p>
<p>Specify an additional library <span class="lang">ws2_32.lib</span> if you are
using PTypes' IP socket classes.</p>
</blockquote>
<p><b><br>
PTypes namespace</b></p>
<blockquote>
<p>The entire PTypes interface is enclosed within a namespace called <span class="lang">pt</span>.
The header file <a href="include/pport.h.html">&lt;pport.h&gt;</a> provides a
macro <span class="lang">USING_PTYPES</span>, which is equivalent to <span class="lang">using
namespace pt</span>. This macro allows you to use PTypes interface symbols without
the scope specifier <span class="lang">pt::</span> in your source code.</p>
</blockquote>
<p><b><br>
Porting the library to other platforms</b></p>
<blockquote>
<p>The author would greatly appreciate any effort to port the library to other
popular platforms. If you either ported the library or just found that PTypes
builds with no problem under your favorite platform with your favorite compiler,
then all you'd have to do is to create a makefile with proper definitions in it.
Take a look at <span class="lang">Makefile.FreeBSD</span> or <span class="lang">Makefile.SunOS</span>,
for example. Besides <span class="lang">OS_CXXOPTS</span> you can specify additional
libraries through <span class="lang">OS_LDLIBS</span>. Name your makefile so that
running <span class="lang">make Makefile.`uname`</span> would work on the given
operating system. Try to build the library and then run <span class="lang">src/ptypes_test</span>
to make sure the library is functioning properly. </p>
<p>And finally, if you send the changes to the author, then (obviously) others
would be able to benefit from using PTypes on your favorite operating system with
your favorite compiler.</p>
</blockquote>
<p class="seealso">See also: <a href="deploying.html">Deploying the shared (dynamic)
library</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/criterrors.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: critical errors</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Exceptions and critical errors</p>
<p>Some of the components in PTypes may produce unrecoverable error conditions,
such like a list index is out of bounds, a stream object is constructed with inconsistent
parameters, an operation on a stream is requested which requires buffering, etc.
These errors are mainly caused by wrong usage of objects or functions of the library.</p>
<p>Whenever an unrecoverable error condition is raised, PTypes calls <span class="lang">fatal()</span>
with a message describing the error condition and terminates the program. On most
platforms this message is sent to <span class="lang">stderr</span>, and
on Windows the message is shown in a simple message box.</p>
<p>The function <span class="lang">fatal()</span> is declared in <a href="include/pport.h.html">&lt;pport.h&gt;</a>.</p>
<p>Some library components also raise recoverable error conditions (exceptions).
PTypes only generates exception of type <span class="lang">(exception*)</span>
defined in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>, or, in some cases,
a derivative class, e.g. <span class="lang">(estream*)</span>. An exception object
at least contains an error message which can be retrieved through <span class="lang">get_message()</span>
method.</p>
<p> <b>NOTE</b>: Exception objects in PTypes are allocated dynamically and therefore,
they should be freed by the catch block if it does not pass the exception farther.
The exception class is derived from <a href="unknown.html">unknown</a> to help
you to detect memory leaks in your program. If a thread in a multithreaded application
is created using PTypes <span class="lang">thread</span> class, then all PTypes
exceptions thrown in each thread are caught and freed automatically (unless
caught in the user code).</p>
<p>See also streams <a href="streams.errors.html">Error handling</a> and <a href="streams.examples.html">Examples</a>.</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/cset.constructors.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: cset: constructors</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="cset.html">cset</a>: Constructors</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class cset {
cset();
cset(const cset& s);
cset(const char* setinit);
}
</pre>
</blockquote>
<p><span class="def">cset::cset()</span> -- default constructor, initializes
the set object to an empty set.</p>
<p><span class="def">cset::cset(const cset& s)</span> -- copy constructor.</p>
<p><span class="def">cset::cset(const char* setinit)</span> constructs a character
set from a string. The <span class="lang">setinit</span> parameter is a sequence
of characters, range specifiers and escape sequences. Range specifier consists
of: lower boundary, dash &quot;-&quot; and higher boundary, e.g. &quot;A-Z&quot;.
Escape sequence begins with tilde &quot;~&quot; and can be followed by a two-digit
hexadecimal number. Escape sequences are also used to include special characters
tilde &quot;~&quot; and dash &quot;-&quot; (see examples below).</p>
<p>Constructing character sets using this interpreter can be a time-consuming
operation. A better practice is to declare all constant character sets as static
variables, so that the interpretation of all set constructing strings will be
done only once during program startup.</p>
<p>An initializer string can also be passed to a <span class="lang">cset</span>
object through <span class="lang">assign()</span>.</p>
<p><b>Note</b>: this constructor does not generate errors if the syntax is violated.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>cset s1 = &quot;135A-CZ&quot;; <span class="comment">// digits 1, 3, 5, letters A through C, and also Z</span>
cset wspace1 = &quot;~09~0d~0a &quot;; <span class="comment">// tab, CR, LF and space</span>
cset wspace2 = &quot;~00-~20&quot;; <span class="comment">// all control and whitespace chars</span>
cset s2 = &quot;:@~~&quot;; <span class="comment">// colon, at and tilde (must be escaped with another tilde)</span>
</pre>
</blockquote>
<p class="seealso">See also: <a href="cset.operators.html">Operators</a>, <a href="cset.manipulation.html">Manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/cset.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: cset</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
cset</p>
<ul>
<li>
<h5><a href="cset.constructors.html">Constructors</a></h5>
</li>
<li>
<h5><a href="cset.operators.html">Operators</a></h5>
</li>
<li>
<h5><a href="cset.manipulation.html">Manipulation</a></h5>
</li>
</ul>
<p>The character set class (<span class="lang">cset</span>) implements Pascal-style
set of integer values from 0 to 255, or set of characters. Unlike Pascal sets,
the range of a <span class="lang">cset</span> cannot be changed and is always
0 through 255. <span class="lang">Cset</span> class implements various operators
(membership, union, intersection, equality, less than or equal to, etc.) as they
are described in the Pascal language. See <a href="cset.operators.html">Operators</a>
for details.</p>
<p><span class="lang">Cset</span> is a packed array of 256 bits, it occupies 32
bytes of static or local memory. Each bit indicates whether the corresponding
character is a member of a given set.</p>
<p>Another difference between <span class="lang">cset</span> and Pascal sets is
that since C++ compiler does not have a built-in set constructor like the one
in Pascal (e.g. ['A'..'Z', 'a'..'z']), <span class="lang">cset</span> provides
a simple run-time interpreter instead (see <a href="cset.constructors.html"> Constructors</a>).</p>
<p>The <span class="lang">cset</span> class is declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p>The example below shows the general usage of character sets.</p>
<blockquote>
<pre>cset s = &quot;A-Za-z!&quot;; <span class="comment">// same as ['A'..'Z', 'a'..'z', '!'] in Pascal</span>
include(s, '_'); <span class="comment"> // include underscore character</span>
include(s, '0', '9'); <span class="comment"> // include all chars from '0' to '9'</span>
if ('a' &amp; s) <span class="comment"> // check membership</span>
cout &lt;&lt; &quot;Letter 'a' found in the set! :)\n&quot;;
const cset letters = &quot;A-Za-z_&quot;; <span class="comment">// define a set of letters</span>
string tok = pin.token(letters); <span class="comment">// read a token from the input stream</span></pre>
</blockquote>
<p class="seealso">See also: <a href="cset.constructors.html">Constructors</a>,
<a href="cset.operators.html">Operators</a>, <a href="cset.manipulation.html">Manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/cset.manipulation.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: cset: manipulation</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="cset.html">cset</a>: Manipulation</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
void assign(cset& s, const char* setinit);
string asstring(const cset&amp; s);
void clear(cset& s);
void fill(cset& s);
void include(cset& s, char b);
void include(cset& s, char min, char max);
void exclude(cset& s, char b);
</pre>
</blockquote>
<p><span class="def">assign(cset& s, const char* setinit)</span> works the same
way as <span class="lang">cset(const char*)</span> constructor (see <a href="cset.constructors.html">constructors</a>).</p>
<p><span class="def">string asstring(const cset&amp; s)</span> returns a string
representing the given set <span class="lang">s</span> using <span class="lang">cset(const
char*)</span> syntax. Typically used for debugging.</p>
<p><span class="def">clear(cset& s)</span> assigns an empty set (removes all
members) to the set <span class="lang">s</span>.</p>
<p><span class="def">fill(cset& s)</span> assigns all 1s to the set - all elements
become members of this set.</p>
<p><span class="def">include(cset& s, char b)</span> adds the element <span class="lang">b</span>
to the set <span class="lang">s</span>. Equivalent to <span class="lang">s +=
b</span>.</p>
<p><span class="def"> include(cset& s, char min, char max)</span> adds a range
of elements <span class="lang">min</span> through <span class="lang">max</span>
to the set <span class="lang">s</span>.</p>
<p> <span class="def">exclude(cset& s, char b)</span> removes the element <span class="lang">b</span>
from the set <span class="lang">s</span>. Equivalent to <span class="lang">s -=
b</span>.</p>
<p class="seealso">See also: <a href="cset.constructors.html">Constructors</a>,
<a href="cset.operators.html">Operators</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/cset.operators.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: cset: operators</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="cset.html">cset</a>: Operators</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class cset {
<span class="comment"> // assignment</span>
cset& operator =(const cset& s);
<span class="comment"> // union</span>
cset& operator +=(const cset& s);
cset& operator +=(char b);
cset operator +(const cset& s) const;
cset operator +(char b) const;
friend cset operator +(char b, const cset& s);
<span class="comment"> // difference</span>
cset& operator -=(const cset& s);
cset& operator -=(char b);
cset operator -(const cset& s) const;
cset operator -(char b) const;
<span class="comment"> // intersection</span>
cset& operator *=(const cset& s);
cset operator *(const cset& s) const;
<span class="comment"> // comparison</span>
bool operator ==(const cset& s) const;
bool operator !=(const cset& s) const;
bool operator <=(const cset& s) const;
bool operator >=(const cset& s) const;
<span class="comment"> // membership</span>
friend bool operator&amp; (char b, const cset& s);
}
</pre>
</blockquote>
<p>The following rules apply to +, -, and *:</p>
<ul>
<li>
<p>An ordinal O is in X + Y if and only if O is in X or Y (or both). Equivalent
of bitwise <b>OR</b>.</p>
</li>
<li>
<p> O is in X - Y if and only if O is in X but not in Y. Equivalent of bitwise
<b>AND NOT</b>.</p>
</li>
<li>
<p>O is in X * Y if and only if O is in both X and Y. Equivalent of bitwise <b>AND</b>.</p>
</li>
</ul>
<p>The following rules apply to comparison operations <=, >=, ==, !=:</p>
<ul>
<li>
<p> X <= Y is true just in case every member of X is a member of Y; Z >= W is
equivalent to W <= Z.</p>
</li>
<li>
<p>U == V is true just in case U and V contain exactly the same members; otherwise,
U != V is true.</p>
</li>
</ul>
<p> For an ordinal O and a set S, O &amp; S is true just in case O is a member
of S. Unlike the Pascal language, where membership operator is <b>in</b>, PTypes
uses ampersand &quot;&amp;&quot; as a membership test operator.</p>
<p><b>Note</b>: regardless of whether default char is signed or unsigned (usually
set through compiler options) <span class="lang">cset</span> always treats char
arguments as unsigned. This means, if the value of an argument is -1, e.g. in
call to <span class="lang">operator &amp;</span> or <span class="lang">operator
+</span>, the value will be converted to 255, -2 will be treated as 254, etc.</p>
<p class="seealso">See also: <a href="cset.constructors.html">Constructors</a>,
<a href="cset.manipulation.html">Manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/deploying.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<html><!-- #BeginTemplate "../Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: deploying</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Deploying the shared (dynamic)
library</p>
<p><b><br>
Static vs. dynamic linking</b></p>
<p>PTypes builds two separate versions of the library: static and shared (DLL
on Windows), giving you a choice, and at the same time putting into a dilemma.</p>
<p>Both static and dynamic linking have their advantages and disadvantages. While
small applications consisting of a single executable would prefer to link the
library directly, more complex projects with multiple dynamic components and executables
would greatly benefit from going 'totally dynamic', including generic low-level
libraries, such like CRTL and PTypes. Before making a decision, consider the following:</p>
<p>Advantages of static linking in general:</p>
<ul>
<li>Faster run-time loading (in return for slower compilation).</li>
<li>The installation process is simpler: the end-user doesn't have to deal with
package dependencies, DLL/so versioning conflicts with other applications, etc.
A simple application may run even without any special installation procedures.</li>
<li>Windows-specific: turning a static library into a DLL on Windows is not as
simple as on UNIX systems. You should at least put special compiler directives
against every public symbol in the library and thus make your header files less
readable.</li>
<li>UNIX-specific: for security reasons, UNIX has strict policies with regard
to finding shared libraries and managing allowed source paths. In most cases you
will have to provide an automated installation procedure and require root privileges
in order to place all shared libraries in the right place. Remember, UNIX is a
true multiuser system, and often the user that downloaded/purchased your program
does not have root access on his computer, and he doesn't want to bother the system
administrator either. You may, of course, override LD_LIBRARY_PATH, but then shared
libraries won't be truly shared if they are installed somewhere under user's home
directory.</li>
</ul>
<p>Advantages of dynamic linking in general:</p>
<ul>
<li>Faster compilation and better modularization in big projects with distributed
development (in return for slower run-time loading).</li>
<li>Bug fixes and improvements in library's implementation do not affect your
application and do not require you to recompile everything. What's more, adding
new features without changing the existing interfaces in the dynamic library,
again, won't affect the other modules.</li>
<li>Smaller executables; dynamic libraries may be shared not only between the
components of your project, but even between applications from different vendors.
(The installation package should offer all dependent libraries anyway.) Freeware
libraries perfectly suit for sharing between vendors, since they usually don't
put any limitation on their usage, at least when linked dynamically.</li>
<li>Dynamic libraries can be loaded and bound to the main application at run-time
allowing you to maintain functional 'drivers' (e.g. an application that extracts
plain text from various text formats can support a generic text extraction interface;
drivers for each format can be developed and shipped independently).</li>
</ul>
<p>In summary, dynamic linking is good (1) for big projects, (2) if the library
is widely used by many software vendors in its dynamic (shared) form or (3) to
take advantage of run-time binding.</p>
<p><b><br>
Using and deploying UNIX shared object</b></p>
<p>PTypes builds a shared object named <span class="lang">libptypes.so.20</span>
(<span class="lang">libptypes.20.dylib</span> on MacOS X), creates a 'default'
symbolic link to this library and finally places them both in <span class="lang">so/</span>.</p>
<p>If you decided to link your program against PTypes shared object instead of
the static library, then all you'd have to do is to change the library path in
your makefile from <span class="lang">-L../ptypes/lib</span> to <span class="lang">-L../ptypes/so</span>.
When running the program, it will require the shared library to be either in one
of the default locations (usually <span class="lang">/usr/lib</span> and <span class="lang">/usr/local/lib</span>),
or you will have to override the LD_LIBRARY_PATH environment variable and point
to the directory where the shared object resides, e.g. <span class="lang">~/ptypes/so</span>.</p>
<p>The shared object <span class="lang">libptypes.so.20</span> should be deployed
and installed along with your application. The version number '20' will change
when PTypes adds a number of new features and becomes bigger and/or if incompatible
changes take place which make it impossible for older programs to use the new
shared object.</p>
<p><b><br>
Using and deploying Windows DLL</b></p>
<p>The PTypes MSVC project is configured so that the 'release' version of <span class="lang">ptypes20.dll</span>
along with its import library is copied into <span class="lang">so\</span> as
the final step of the build process. This module does not contain any debugging
information and is ready to be deployed. Note that the library itself is linked
against the multithreaded DLL version of CRTL.</p>
<p>PTypes places a VERSION resource in the DLL, allowing the system or the setup
program to automatically compare the existing <span class="lang">ptypes20.dll</span>
the user may have in the system with the one that comes with your program. This
is usually done from within the installation script.</p>
<p>The DLL version of the library built with Dev-C++/MinGW is called <span class="lang">ptypes20g.dll</span>.
The reason this name is different is that each C++ compiler uses its own `name
mangling' scheme for exported symbols, so that applications built by one compiler
can't use dynamic libraries built by another one.</p>
<p><b><br>
Version checking sample code</b></p>
<p>If, for some reason, you wish to check the version of the shared library you
linked with dynamically, you may check the global variable <span class="lang">__ptypes_version</span>,
which is declared in <span class="lang"><a href="include/pport.h.html">&lt;pport.h&gt;</a></span>.
This variable holds the version number encoded as a single integer, e.g. <span class="lang">0x010902</span>
designates version 1.9.2. In this form the version numbers (required and actual)
can be easily compared as integers.</p>
<p>Note, the name of the library itself reflects major and minor version numbers,
so that only the third component of the version number can vary in the file.</p>
<p>If you need to check the version of PTypes before loading the library (for
example, during the installation on UNIX), you may write a program that loads
the shared object and reads the global symbol <span class="lang">__ptypes_version</span>
at run-time, using the system dynamic loading interface. Note that this program
itself is not using PTypes. Some UNIX systems require to link the program with
<span class="lang">-ldl</span>.</p>
<blockquote>
<pre>
<span class="cdir">#ifdef</span> WIN32
<span class="cdir"># include</span> &lt;windows.h&gt;
<span class="cdir">#else</span><br><span class="cdir"># include</span> &lt;dlfcn.h&gt;<br><span class="cdir">#endif</span>
<span class="cdir">#include</span> &lt;stdio.h&gt;
const unsigned long required = 0x020001;
<br>
int main()
{
void* handle;
unsigned long* pversion;
int exitcode = 0;
<span class="cdir">#ifdef</span> WIN32
const char* libname = "ptypes20.dll";
handle = LoadLibrary(libname);
if (handle == 0)
{
printf("ptypes20.DLL not found\n");
return 3;
}
pversion = (unsigned long*)GetProcAddress(HMODULE(handle), "__ptypes_version");
<span class="cdir">#else</span>
const char* libname = "libptypes.so.20";
handle = dlopen(libname, RTLD_LAZY);
if (handle == 0)
{
printf("%s\n", dlerror());
return 3;
}
pversion = (unsigned long*)dlsym(handle, "__ptypes_version");
<span class="cdir">#endif</span>
if (pversion == NULL)
{
printf("Couldn't determine the version number of %s\n", libname);
exitcode = 1;
}
else
{
printf("Found %s, version: %ld.%ld.%ld\n", libname,
(*pversion) >> 16, ((*pversion) >> 8) & 0xff, (*pversion) & 0xff);
if (*pversion &lt; required)
{
printf(&quot;Need version %ld.%ld.%ld or later\n&quot;,
required >> 16, (required >> 8) & 0xff, required & 0xff);
exitcode = 2;
}
}
<span class="cdir">#ifdef</span> WIN32
FreeLibrary(HMODULE(handle));
<span class="cdir">#else</span>
dlclose(handle);
<span class="cdir">#endif</span>
return exitcode;
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="compiling.html">Compiling and Porting</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/htsrc.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html><!-- #BeginTemplate "../Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: header files</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Header files</p>
<ul>
<li>
<p><a href="include/pport.h.html">&lt;pport.h&gt;</a> - common declarations, portable
typedefs</p>
</li>
<li>
<p><a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a> - basic types: string,
cset, unknown, component, exception, tpodlist, tobjlist, tstrlist, textmap, variant,
atomic functions </p>
</li>
<li>
<p><a href="include/pstreams.h.html">&lt;pstreams.h&gt;</a> - streams: iobase,
instm, outstm, inmemory, outmemory, infile, outfile, logfile, namedpipe, npserver,
outmd5, unit</p>
</li>
<li>
<p><a href="include/pinet.h.html">&lt;pinet.h&gt;</a> - networking: ipaddress,
ipstream, ipstmserver, ipmessage, ipmsgserver, resolver functions</p>
</li>
<li>
<p><a href="include/ptime.h.html">&lt;ptime.h&gt;</a> - date/time utilities</p>
</li>
<li> <a href="include/pasync.h.html">&lt;pasync.h&gt;</a> - multithreading: mutex,
scopelock, trigger, rwlock, scoperead, scopewrite, semaphore, timedsem, thread,
message, msgqueue, jobqueue</li>
</ul>
<p><br>
<b>NOTE</b>: for better readability, these listings differ from the originals
in that Windows-specific macros <span class="lang">ptpublic</span> and <span class="lang">ptdecl</span>
are not shown.</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/include/pasync.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>pasync.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PASYNC_H__
<font CLASS=preproc>#define</font> __PASYNC_H__
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=preproc>#</font> define _WINSOCKAPI_ <font CLASS=comment>// prevent inclusion of winsock.h, since we need winsock2.h </font>
<font CLASS=preproc>#</font> include &lt;windows.h&gt;
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> include &lt;pthread.h&gt;
<font CLASS=preproc>#</font> ifndef __bsdi__
<font CLASS=preproc>#</font> include &lt;semaphore.h&gt;
<font CLASS=preproc>#</font> endif
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PTYPES_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"ptypes.h"</font>
<font CLASS=preproc>#endif</font>
PTYPES_BEGIN
<font CLASS=comment>//</font>
<font CLASS=comment>// Summary of implementation:</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// atomic increment/decrement/exchange</font>
<font CLASS=comment>// MSVC/BCC/i386: internal, asm</font>
<font CLASS=comment>// GCC/i386: internal, asm</font>
<font CLASS=comment>// GCC/PowerPC: internal, asm</font>
<font CLASS=comment>// GCC/SPARC: internal, asm</font>
<font CLASS=comment>// Other: internal, mutex hash table</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// mutex</font>
<font CLASS=comment>// Win32: Critical section</font>
<font CLASS=comment>// Other: POSIX mutex</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// trigger</font>
<font CLASS=comment>// Win32: Event</font>
<font CLASS=comment>// Other: internal, POSIX condvar/mutex</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// rwlock:</font>
<font CLASS=comment>// Win32: internal, Event/mutex</font>
<font CLASS=comment>// MacOS: internal, POSIX condvar/mutex</font>
<font CLASS=comment>// Other: POSIX rwlock</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// semaphore:</font>
<font CLASS=comment>// Win32: = timedsem</font>
<font CLASS=comment>// MacOS: = timedsem</font>
<font CLASS=comment>// Other: POSIX semaphore</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// timedsem (with timed waiting):</font>
<font CLASS=comment>// Win32: Semaphore</font>
<font CLASS=comment>// Other: internal, POSIX mutex/condvar</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(<font CLASS=keyword>push</font>, <font CLASS=integer>4</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifdef</font> WIN32
typedef <font CLASS=keyword>int</font> pthread_id_t<font CLASS=comment>;</font>
typedef HANDLE pthread_t<font CLASS=comment>;</font>
<font CLASS=preproc>#else</font>
typedef pthread_t pthread_id_t<font CLASS=comment>;</font>
<font CLASS=preproc>#endif</font>
void psleep(uint milliseconds)<font CLASS=comment>;</font>
bool pthrequal(pthread_id_t id)<font CLASS=comment>; // note: this is NOT the thread handle, use thread::get_id()</font>
pthread_id_t pthrself()<font CLASS=comment>; // ... same</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- mutex ---------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#ifdef</font> WIN32
struct mutex: public noncopyable
{
<font CLASS=preproc>protected:</font>
CRITICAL_SECTION critsec<font CLASS=comment>;</font>
<font CLASS=preproc>public:</font>
mutex() { InitializeCriticalSection(&amp<font CLASS=comment>;critsec); }</font>
~mutex() { DeleteCriticalSection(&amp;critsec); }
<font CLASS=keytype>void</font> enter() { EnterCriticalSection(&amp;critsec); }
<font CLASS=keytype>void</font> leave() { LeaveCriticalSection(&amp;critsec); }
<font CLASS=keytype>void</font> lock() { enter(); }
<font CLASS=keytype>void</font> unlock() { leave(); }
};
<font CLASS=preproc>#else</font>
<font CLASS=keyword>struct</font> mutex: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
pthread_mutex_t mtx;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
mutex() { pthread_mutex_init(&amp;mtx, <font CLASS=integer>0</font>); }
~mutex() { pthread_mutex_destroy(&amp;mtx); }
<font CLASS=keytype>void</font> enter() { pthread_mutex_lock(&amp;mtx); }
<font CLASS=keytype>void</font> leave() { pthread_mutex_unlock(&amp;mtx); }
<font CLASS=keytype>void</font> lock() { enter(); }
<font CLASS=keytype>void</font> unlock() { leave(); }
};
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// scopelock</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> scopelock: <font CLASS=keyword>public</font> noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
mutex* mtx;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
scopelock(mutex&amp; imtx): mtx(&amp;imtx) { mtx<font CLASS=symbols>-</font>&gt;lock(); }
~scopelock() { mtx<font CLASS=symbols>-</font>&gt;unlock(); }
};
<font CLASS=comment>//</font>
<font CLASS=comment>// mutex table for hashed memory locking (undocumented)</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#define</font> _MUTEX_HASH_SIZE <font CLASS=integer>29</font> <font CLASS=comment>// a prime number for hashing </font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=preproc>#</font> define pmemlock mutex
<font CLASS=preproc>#</font> define pmementer(m) (m)<font CLASS=symbols>-</font>&gt;lock()
<font CLASS=preproc>#</font> define pmemleave(m) (m)<font CLASS=symbols>-</font>&gt;unlock()
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> define _MTX_INIT PTHREAD_MUTEX_INITIALIZER
<font CLASS=preproc>#</font> define pmemlock pthread_mutex_t
<font CLASS=preproc>#</font> define pmementer pthread_mutex_lock
<font CLASS=preproc>#</font> define pmemleave pthread_mutex_unlock
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>extern</font> pmemlock _mtxtable[_MUTEX_HASH_SIZE];
<font CLASS=preproc>#define</font> pgetmemlock(addr) (_mtxtable <font CLASS=symbols>+</font> pintptr(addr) % _MUTEX_HASH_SIZE)
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- trigger -------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keyword>class</font> trigger: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
HANDLE handle; <font CLASS=comment>// Event object</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
trigger(<font CLASS=keytype>bool</font> autoreset, <font CLASS=keytype>bool</font> state);
~trigger() { CloseHandle(handle); }
<font CLASS=keytype>void</font> wait() { WaitForSingleObject(handle, INFINITE); }
<font CLASS=keytype>void</font> post() { SetEvent(handle); }
<font CLASS=keytype>void</font> signal() { post(); }
<font CLASS=keytype>void</font> reset() { ResetEvent(handle); }
};
<font CLASS=preproc>#else</font>
<font CLASS=keyword>class</font> trigger: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
pthread_mutex_t mtx;
pthread_cond_t cond;
<font CLASS=keytype>int</font> state;
<font CLASS=keytype>bool</font> autoreset;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
trigger(<font CLASS=keytype>bool</font> autoreset, <font CLASS=keytype>bool</font> state);
~trigger();
<font CLASS=keytype>void</font> wait();
<font CLASS=keytype>void</font> post();
<font CLASS=keytype>void</font> signal() { post(); }
<font CLASS=keytype>void</font> reset();
};
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- rwlock --------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#if</font> defined(WIN32) <font CLASS=symbols>||</font> defined(__DARWIN__) <font CLASS=symbols>||</font> defined(__bsdi__)
<font CLASS=preproc>#</font> define __PTYPES_RWLOCK__
<font CLASS=preproc>#elif</font> defined(linux)
<font CLASS=comment>// on Linux rwlocks are included only with -D_GNU_SOURCE.</font>
<font CLASS=comment>// programs that don't use rwlocks, do not need to define</font>
<font CLASS=comment>// _GNU_SOURCE either.</font>
<font CLASS=preproc>#</font> <font CLASS=keyword>if</font> defined(_GNU_SOURCE) <font CLASS=symbols>||</font> defined(__USE_UNIX98)
<font CLASS=preproc>#</font> define __POSIX_RWLOCK__
<font CLASS=preproc>#</font> endif
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> define __POSIX_RWLOCK__
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifdef</font> __PTYPES_RWLOCK__
<font CLASS=keyword>struct</font> rwlock: <font CLASS=keyword>protected</font> mutex
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc>#ifdef</font> WIN32
HANDLE reading; <font CLASS=comment>// Event object</font>
HANDLE finished; <font CLASS=comment>// Event object</font>
<font CLASS=keytype>int</font> readcnt;
<font CLASS=keytype>int</font> writecnt;
<font CLASS=preproc>#else</font>
pthread_mutex_t mtx;
pthread_cond_t readcond;
pthread_cond_t writecond;
<font CLASS=keytype>int</font> locks;
<font CLASS=keytype>int</font> writers;
<font CLASS=keytype>int</font> readers;
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
rwlock();
~rwlock();
<font CLASS=keytype>void</font> rdlock();
<font CLASS=keytype>void</font> wrlock();
<font CLASS=keytype>void</font> unlock();
<font CLASS=keytype>void</font> lock() { wrlock(); }
};
<font CLASS=preproc>#elif</font> defined(__POSIX_RWLOCK__)
<font CLASS=keyword>struct</font> rwlock: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
pthread_rwlock_t rw;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
rwlock();
~rwlock() { pthread_rwlock_destroy(&amp;rw); }
<font CLASS=keytype>void</font> rdlock() { pthread_rwlock_rdlock(&amp;rw); }
<font CLASS=keytype>void</font> wrlock() { pthread_rwlock_wrlock(&amp;rw); }
<font CLASS=keytype>void</font> unlock() { pthread_rwlock_unlock(&amp;rw); }
<font CLASS=keytype>void</font> lock() { wrlock(); }
};
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#if</font> defined(__PTYPES_RWLOCK__) <font CLASS=symbols>||</font> defined(__POSIX_RWLOCK__)
<font CLASS=comment>//</font>
<font CLASS=comment>// scoperead &amp; scopewrite</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> scoperead: <font CLASS=keyword>public</font> noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
rwlock* rw;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
scoperead(rwlock&amp; irw): rw(&amp;irw) { rw<font CLASS=symbols>-</font>&gt;rdlock(); }
~scoperead() { rw<font CLASS=symbols>-</font>&gt;unlock(); }
};
<font CLASS=keyword>class</font> scopewrite: <font CLASS=keyword>public</font> noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
rwlock* rw;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
scopewrite(rwlock&amp; irw): rw(&amp;irw) { rw<font CLASS=symbols>-</font>&gt;wrlock(); }
~scopewrite() { rw<font CLASS=symbols>-</font>&gt;unlock(); }
};
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- semaphore ------------------------------------------------------ //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#if</font> defined(WIN32) <font CLASS=symbols>||</font> defined(__DARWIN__) <font CLASS=symbols>||</font> defined(__bsdi__)
<font CLASS=preproc>#</font> define __SEM_TO_TIMEDSEM__
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifdef</font> __SEM_TO_TIMEDSEM__
<font CLASS=comment>// map ordinary semaphore to timed semaphore</font>
<font CLASS=keyword>class</font> timedsem;
<font CLASS=keyword>typedef</font> timedsem semaphore;
<font CLASS=preproc>#else</font>
<font CLASS=keyword>class</font> semaphore: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
sem_t handle;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
semaphore(<font CLASS=keytype>int</font> initvalue);
<font CLASS=keyword>virtual</font> ~semaphore();
<font CLASS=keytype>void</font> wait();
<font CLASS=keytype>void</font> post();
<font CLASS=keytype>void</font> signal() { post(); }
};
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>class</font> timedsem: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc>#ifdef</font> WIN32
HANDLE handle;
<font CLASS=preproc>#else</font>
<font CLASS=keytype>int</font> count;
pthread_mutex_t mtx;
pthread_cond_t cond;
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
timedsem(<font CLASS=keytype>int</font> initvalue);
<font CLASS=keyword>virtual</font> ~timedsem();
<font CLASS=keytype>bool</font> wait(<font CLASS=keytype>int</font> msecs <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keytype>void</font> post();
<font CLASS=keytype>void</font> signal() { post(); }
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- thread --------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=keyword>class</font> thread: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keytype>unsigned</font> id;
<font CLASS=preproc>#endif</font>
pthread_t handle;
<font CLASS=keytype>int</font> autofree;
<font CLASS=keytype>int</font> running;
<font CLASS=keytype>int</font> signaled;
<font CLASS=keytype>int</font> finished;
<font CLASS=keytype>int</font> freed;
<font CLASS=keytype>int</font> reserved; <font CLASS=comment>// for priorities</font>
timedsem relaxsem;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> execute() <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> cleanup();
<font CLASS=keytype>bool</font> relax(<font CLASS=keytype>int</font> msecs) { <font CLASS=keyword>return</font> relaxsem.wait(msecs); }
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> _threadepilog(thread* thr);
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keyword>friend</font> <font CLASS=keytype>unsigned</font> __stdcall _threadproc(<font CLASS=keytype>void</font>* arg);
<font CLASS=preproc>#else</font>
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font>* _threadproc(<font CLASS=keytype>void</font>* arg);
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
thread(<font CLASS=keytype>bool</font> iautofree);
<font CLASS=keyword>virtual</font> ~thread();
<font CLASS=preproc>#ifdef</font> WIN32
pthread_id_t get_id() { <font CLASS=keyword>return</font> <font CLASS=keytype>int</font>(id); }
<font CLASS=preproc>#else</font>
pthread_id_t get_id() { <font CLASS=keyword>return</font> handle; }
<font CLASS=preproc>#endif</font>
<font CLASS=keytype>bool</font> get_running() { <font CLASS=keyword>return</font> running <font CLASS=symbols>!=</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>bool</font> get_finished() { <font CLASS=keyword>return</font> finished <font CLASS=symbols>!=</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>bool</font> get_signaled() { <font CLASS=keyword>return</font> signaled <font CLASS=symbols>!=</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>void</font> start();
<font CLASS=keytype>void</font> signal();
<font CLASS=keytype>void</font> waitfor();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- jobqueue &amp; msgqueue -------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> MSG_USER <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> MSG_QUIT <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> DEF_QUEUE_LIMIT <font CLASS=symbols>=</font> <font CLASS=integer>5000</font>;
<font CLASS=keyword>class</font> message: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
message* next; <font CLASS=comment>// next in the message chain, used internally</font>
semaphore* sync; <font CLASS=comment>// used internally by msgqueue::send(), when called from a different thread</font>
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> jobqueue; <font CLASS=comment>// my friends, job queue and message queue...</font>
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> msgqueue;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=keytype>int</font> id;
pintptr param;
pintptr result;
message(<font CLASS=keytype>int</font> iid, pintptr iparam <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=keyword>virtual</font> ~message();
};
<font CLASS=keyword>class</font> jobqueue: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
<font CLASS=keytype>int</font> limit; <font CLASS=comment>// queue limit</font>
message* head; <font CLASS=comment>// queue head</font>
message* tail; <font CLASS=comment>// queue tail</font>
<font CLASS=keytype>int</font> qcount; <font CLASS=comment>// number of items in the queue</font>
timedsem sem; <font CLASS=comment>// queue semaphore</font>
timedsem ovrsem; <font CLASS=comment>// overflow semaphore</font>
mutex qlock; <font CLASS=comment>// critical sections in enqueue and dequeue</font>
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>bool</font> enqueue(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keytype>bool</font> push(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
message* dequeue(<font CLASS=keytype>bool</font> safe <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>);
<font CLASS=keytype>void</font> purgequeue();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
jobqueue(<font CLASS=keytype>int</font> ilimit <font CLASS=symbols>=</font> DEF_QUEUE_LIMIT);
<font CLASS=keyword>virtual</font> ~jobqueue();
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> qcount; }
<font CLASS=keytype>int</font> get_limit() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> limit; }
<font CLASS=keytype>bool</font> post(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keytype>bool</font> post(<font CLASS=keytype>int</font> id, pintptr param <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>);
<font CLASS=keytype>bool</font> posturgent(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keytype>bool</font> posturgent(<font CLASS=keytype>int</font> id, pintptr param <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>);
message* getmessage(<font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT
<font CLASS=keytype>int</font> msgsavail() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get_count(); }
<font CLASS=preproc>#endif</font>
};
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> T&gt; <font CLASS=keyword>class</font> tjobqueue: <font CLASS=keyword>protected</font> jobqueue
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
tjobqueue(<font CLASS=keytype>int</font> ilimit <font CLASS=symbols>=</font> DEF_QUEUE_LIMIT);
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> jobqueue::get_count(); }
<font CLASS=keytype>int</font> get_limit() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> jobqueue::get_limit(); }
<font CLASS=keytype>bool</font> post(T* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::post(msg, timeout); }
<font CLASS=keytype>bool</font> posturgent(T* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::posturgent(msg, timeout); }
T* getmessage(<font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> (T*)jobqueue::getmessage(timeout); }
};
<font CLASS=keyword>class</font> msgqueue: <font CLASS=keyword>protected</font> jobqueue
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
mutex thrlock; <font CLASS=comment>// lock for the queue processing</font>
pthread_id_t owner; <font CLASS=comment>// thread ID of the queue processing thread</font>
pintptr finishmsg(message* msg);
<font CLASS=keytype>void</font> handlemsg(message* msg);
<font CLASS=keytype>void</font> takeownership();
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>bool</font> quit;
<font CLASS=keytype>void</font> defhandler(message&amp; msg);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> msghandler(message&amp; msg) <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
msgqueue(<font CLASS=keytype>int</font> ilimit <font CLASS=symbols>=</font> DEF_QUEUE_LIMIT);
<font CLASS=keyword>virtual</font> ~msgqueue();
// functions calling from the owner<font CLASS=preproc> thread:</font>
<font CLASS=keytype>void</font> processone(); <font CLASS=comment>// process one message, may hang if no msgs in the queue</font>
<font CLASS=keytype>void</font> processmsgs(); <font CLASS=comment>// process all available messages and return</font>
<font CLASS=keytype>void</font> run(); <font CLASS=comment>// process messages until MSG_QUIT</font>
// functions calling from any<font CLASS=preproc> thread:</font>
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> jobqueue::get_count(); }
<font CLASS=keytype>int</font> get_limit() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> jobqueue::get_limit(); }
<font CLASS=keytype>bool</font> post(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::post(msg, timeout); }
<font CLASS=keytype>bool</font> post(<font CLASS=keytype>int</font> id, pintptr param <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::post(id, param, timeout); }
<font CLASS=keytype>bool</font> posturgent(message* msg, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::posturgent(msg, timeout); }
<font CLASS=keytype>bool</font> posturgent(<font CLASS=keytype>int</font> id, pintptr param <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>) { <font CLASS=keyword>return</font> jobqueue::posturgent(id, param, timeout); }
pintptr send(message* msg);
pintptr send(int id, pintptr param <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT
<font CLASS=keytype>int</font> msgsavail() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get_count(); }
<font CLASS=preproc>#endif</font>
};
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(pop)
<font CLASS=preproc>#endif</font>
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PASYNC_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/include/pinet.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>pinet.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PINET_H__
<font CLASS=preproc>#define</font> __PINET_H__
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PTYPES_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"ptypes.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PSTREAMS_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pstreams.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=preproc>#</font> include &lt;winsock2.h&gt;
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> include &lt;netdb.h&gt; <font CLASS=comment>// for socklen_t </font>
<font CLASS=preproc>#</font> include &lt;sys/types.h&gt;
<font CLASS=preproc>#</font> include &lt;sys/socket.h&gt;
<font CLASS=preproc>#endif</font>
PTYPES_BEGIN
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(push, <font CLASS=integer>4</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// BSD-compatible socket error codes for Win32</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#if</font> defined(WSAENOTSOCK) &amp;&amp; !defined(ENOTSOCK)
<font CLASS=preproc>#define</font> EWOULDBLOCK WSAEWOULDBLOCK
<font CLASS=preproc>#define</font> EINPROGRESS WSAEINPROGRESS
<font CLASS=preproc>#define</font> EALREADY WSAEALREADY
<font CLASS=preproc>#define</font> ENOTSOCK WSAENOTSOCK
<font CLASS=preproc>#define</font> EDESTADDRREQ WSAEDESTADDRREQ
<font CLASS=preproc>#define</font> EMSGSIZE WSAEMSGSIZE
<font CLASS=preproc>#define</font> EPROTOTYPE WSAEPROTOTYPE
<font CLASS=preproc>#define</font> ENOPROTOOPT WSAENOPROTOOPT
<font CLASS=preproc>#define</font> EPROTONOSUPPORT WSAEPROTONOSUPPORT
<font CLASS=preproc>#define</font> ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
<font CLASS=preproc>#define</font> EOPNOTSUPP WSAEOPNOTSUPP
<font CLASS=preproc>#define</font> EPFNOSUPPORT WSAEPFNOSUPPORT
<font CLASS=preproc>#define</font> EAFNOSUPPORT WSAEAFNOSUPPORT
<font CLASS=preproc>#define</font> EADDRINUSE WSAEADDRINUSE
<font CLASS=preproc>#define</font> EADDRNOTAVAIL WSAEADDRNOTAVAIL
<font CLASS=preproc>#define</font> ENETDOWN WSAENETDOWN
<font CLASS=preproc>#define</font> ENETUNREACH WSAENETUNREACH
<font CLASS=preproc>#define</font> ENETRESET WSAENETRESET
<font CLASS=preproc>#define</font> ECONNABORTED WSAECONNABORTED
<font CLASS=preproc>#define</font> ECONNRESET WSAECONNRESET
<font CLASS=preproc>#define</font> ENOBUFS WSAENOBUFS
<font CLASS=preproc>#define</font> EISCONN WSAEISCONN
<font CLASS=preproc>#define</font> ENOTCONN WSAENOTCONN
<font CLASS=preproc>#define</font> ESHUTDOWN WSAESHUTDOWN
<font CLASS=preproc>#define</font> ETOOMANYREFS WSAETOOMANYREFS
<font CLASS=preproc>#define</font> ETIMEDOUT WSAETIMEDOUT
<font CLASS=preproc>#define</font> ECONNREFUSED WSAECONNREFUSED
<font CLASS=preproc>#define</font> ELOOP WSAELOOP
<font CLASS=comment>// #define ENAMETOOLONG WSAENAMETOOLONG</font>
<font CLASS=preproc>#define</font> EHOSTDOWN WSAEHOSTDOWN
<font CLASS=preproc>#define</font> EHOSTUNREACH WSAEHOSTUNREACH
<font CLASS=comment>// #define ENOTEMPTY WSAENOTEMPTY</font>
<font CLASS=preproc>#define</font> EPROCLIM WSAEPROCLIM
<font CLASS=preproc>#define</font> EUSERS WSAEUSERS
<font CLASS=preproc>#define</font> EDQUOT WSAEDQUOT
<font CLASS=preproc>#define</font> ESTALE WSAESTALE
<font CLASS=preproc>#define</font> EREMOTE WSAEREMOTE
<font CLASS=comment>// NOTE: these are not errno constants in UNIX!</font>
<font CLASS=preproc>#define</font> HOST_NOT_FOUND WSAHOST_NOT_FOUND
<font CLASS=preproc>#define</font> TRY_AGAIN WSATRY_AGAIN
<font CLASS=preproc>#define</font> NO_RECOVERY WSANO_RECOVERY
<font CLASS=preproc>#define</font> NO_DATA WSANO_DATA
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// shutdown() constants</font>
<font CLASS=preproc>#if</font> defined(SD_RECEIVE) &amp;&amp; !defined(SHUT_RD)
<font CLASS=preproc>#</font> define SHUT_RD SD_RECEIVE
<font CLASS=preproc>#</font> define SHUT_WR SD_SEND
<font CLASS=preproc>#</font> define SHUT_RDWR SD_BOTH
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// max backlog value for listen()</font>
<font CLASS=preproc>#ifndef</font> SOMAXCONN
<font CLASS=preproc>#</font> define SOMAXCONN <font CLASS=symbols>-</font><font CLASS=integer>1</font>
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>char</font>* sockval_t;
<font CLASS=preproc>#ifndef</font> WIN32
<font CLASS=preproc>#</font> define closesocket close
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#if</font> (defined(__DARWIN__) &amp;&amp; !defined(_SOCKLEN_T)) <font CLASS=symbols>||</font> defined(WIN32) <font CLASS=symbols>||</font> defined(__hpux)
<font CLASS=keyword>typedef</font> <font CLASS=keytype>int</font> psocklen;
<font CLASS=preproc>#else</font>
<font CLASS=keyword>typedef</font> socklen_t psocklen;
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- IP address class and DNS utilities ---------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// IP address</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>struct</font> ipaddress
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=keyword>union</font>
{
uchar data[<font CLASS=integer>4</font>];
ulong ldata;
};
ipaddress() {}
ipaddress(ulong a) { ldata <font CLASS=symbols>=</font> a; }
ipaddress(<font CLASS=keyword>const</font> ipaddress&amp; a) { ldata <font CLASS=symbols>=</font> a.ldata; }
ipaddress(<font CLASS=keytype>int</font> a, <font CLASS=keytype>int</font> b, <font CLASS=keytype>int</font> c, <font CLASS=keytype>int</font> d);
ipaddress&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (ulong a) { ldata <font CLASS=symbols>=</font> a; <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
ipaddress&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> ipaddress&amp; a) { ldata <font CLASS=symbols>=</font> a.ldata; <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
uchar&amp; <font CLASS=keyword>operator</font> [] (<font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> data[i]; }
<font CLASS=keyword>operator</font> ulong() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ldata; }
};
<font CLASS=keyword>extern</font> ipaddress ipnone;
<font CLASS=keyword>extern</font> ipaddress ipany;
<font CLASS=keyword>extern</font> ipaddress ipbcast;
<font CLASS=comment>//</font>
<font CLASS=comment>// IP peer info: host name, IP and the port name</font>
<font CLASS=comment>// used internally in ipstream and ipmessage</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ippeerinfo: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
ipaddress ip; <font CLASS=comment>// target IP</font>
string host; <font CLASS=comment>// target host name; either IP or hostname must be specified</font>
<font CLASS=keytype>int</font> port; <font CLASS=comment>// target port number</font>
<font CLASS=keytype>void</font> notfound(); <font CLASS=comment>// throws a (estream*) exception</font>
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> psockname(<font CLASS=keytype>int</font>, ippeerinfo&amp;);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ippeerinfo();
ippeerinfo(ipaddress iip, <font CLASS=keyword>const</font> string&amp; ihost, <font CLASS=keytype>int</font> iport);
ipaddress get_ip(); <font CLASS=comment>// resolves the host name if necessary (only once)</font>
string get_host(); <font CLASS=comment>// performs reverse-lookup if necessary (only once)</font>
<font CLASS=keytype>int</font> get_port() { <font CLASS=keyword>return</font> port; }
<font CLASS=keytype>void</font> clear();
string asstring(<font CLASS=keytype>bool</font> showport) <font CLASS=keyword>const</font>;
};
string iptostring(ipaddress ip);
ipaddress phostbyname(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* name);
string phostbyaddr(ipaddress ip);
string phostcname(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* name);
<font CLASS=comment>// internal utilities</font>
<font CLASS=keytype>int</font> usockerrno();
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* usockerrmsg(<font CLASS=keytype>int</font> code);
<font CLASS=keytype>bool</font> psockwait(<font CLASS=keytype>int</font> handle, <font CLASS=keytype>int</font> timeout);
<font CLASS=keytype>bool</font> psockname(<font CLASS=keytype>int</font> handle, ippeerinfo&amp;);
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- TCP socket classes -------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// additional IO status codes</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_RESOLVING <font CLASS=symbols>=</font> <font CLASS=integer>10</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_RESOLVED <font CLASS=symbols>=</font> <font CLASS=integer>11</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_CONNECTING <font CLASS=symbols>=</font> <font CLASS=integer>20</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_CONNECTED <font CLASS=symbols>=</font> <font CLASS=integer>21</font>;
<font CLASS=comment>//</font>
<font CLASS=comment>// ipstream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ipstream: public fdxstm, <font CLASS=keyword>public</font> ippeerinfo
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> ipstmserver;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> svsocket; <font CLASS=comment>// server socket descriptor, used internally by ipstmserver</font>
<font CLASS=preproc>#ifdef</font> WIN32
// sockets are not compatible with file handles on Windows
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> uerrno();
<font CLASS=keyword>virtual</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* uerrmsg(<font CLASS=keytype>int</font> code);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> large doseek(large newpos, ioseekmode mode);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> sockopt(<font CLASS=keytype>int</font> socket);
<font CLASS=keytype>void</font> closehandle();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ipstream();
ipstream(ipaddress ip, <font CLASS=keytype>int</font> port);
ipstream(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* host, <font CLASS=keytype>int</font> port);
ipstream(<font CLASS=keyword>const</font> string&amp; host, <font CLASS=keytype>int</font> port);
<font CLASS=keyword>virtual</font> ~ipstream();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keyword>virtual</font> string get_streamname();
<font CLASS=keytype>bool</font> waitfor(<font CLASS=keytype>int</font> timeout);
ipaddress get_myip();
<font CLASS=keytype>int</font> get_myport();
<font CLASS=keytype>void</font> set_ip(ipaddress);
<font CLASS=keytype>void</font> set_host(<font CLASS=keyword>const</font> string&amp;);
<font CLASS=keytype>void</font> set_host(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
<font CLASS=keytype>void</font> set_port(<font CLASS=keytype>int</font>);
};
<font CLASS=comment>//</font>
<font CLASS=comment>// common internal interfaces for ipstmserver and ipmsgserver</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ipbindinfo: <font CLASS=keyword>public</font> unknown, <font CLASS=keyword>public</font> ippeerinfo
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=keytype>int</font> handle;
ipbindinfo(ipaddress iip, <font CLASS=keyword>const</font> string&amp; ihost, <font CLASS=keytype>int</font> iport);
<font CLASS=keyword>virtual</font> ~ipbindinfo();
};
<font CLASS=keyword>class</font> ipsvbase: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> socktype;
<font CLASS=keytype>bool</font> active;
tobjlist&lt;ipbindinfo&gt; addrlist; <font CLASS=comment>// list of local socket addresses to bind to</font>
<font CLASS=keytype>void</font> error(ippeerinfo&amp; peer, <font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* defmsg);
<font CLASS=keytype>bool</font> dopoll(<font CLASS=keytype>int</font>* i, <font CLASS=keytype>int</font> timeout);
<font CLASS=keytype>void</font> setupfds(<font CLASS=keytype>void</font>* set, <font CLASS=keytype>int</font> i);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> open();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> close();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dobind(ipbindinfo*) <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> sockopt(<font CLASS=keytype>int</font> socket);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ipsvbase(<font CLASS=keytype>int</font> isocktype);
<font CLASS=keyword>virtual</font> ~ipsvbase();
<font CLASS=keytype>int</font> bind(ipaddress ip, <font CLASS=keytype>int</font> port);
<font CLASS=keytype>int</font> bindall(<font CLASS=keytype>int</font> port);
<font CLASS=keytype>int</font> get_addrcount() { <font CLASS=keyword>return</font> addrlist.get_count(); }
<font CLASS=keyword>const</font> ipbindinfo&amp; get_addr(<font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> *addrlist[i]; }
<font CLASS=keytype>void</font> clear();
};
<font CLASS=comment>//</font>
<font CLASS=comment>// ipstmserver</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ipstmserver: public ipsvbase
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dobind(ipbindinfo*);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ipstmserver();
<font CLASS=keyword>virtual</font> ~ipstmserver();
<font CLASS=keytype>bool</font> poll(<font CLASS=keytype>int</font> i <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>, <font CLASS=keytype>int</font> timeout = <font CLASS=integer>0</font>);
<font CLASS=keytype>bool</font> serve(ipstream&amp; client, <font CLASS=keytype>int</font> i <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>, <font CLASS=keytype>int</font> timeout = -<font CLASS=integer>1</font>);
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- UDP socket classes -------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// ipmessage</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ipmessage: public unknown, <font CLASS=keyword>public</font> ippeerinfo
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> handle;
<font CLASS=keytype>void</font> error(<font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg);
<font CLASS=keytype>void</font> open();
<font CLASS=keytype>void</font> close();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> sockopt(<font CLASS=keytype>int</font> socket);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ipmessage();
ipmessage(ipaddress ip, <font CLASS=keytype>int</font> port);
ipmessage(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* host, <font CLASS=keytype>int</font> port);
ipmessage(<font CLASS=keyword>const</font> string&amp; host, <font CLASS=keytype>int</font> port);
<font CLASS=keyword>virtual</font> ~ipmessage();
<font CLASS=keytype>void</font> set_ip(ipaddress iip);
<font CLASS=keytype>void</font> set_host(<font CLASS=keyword>const</font> string&amp;);
<font CLASS=keytype>void</font> set_host(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
<font CLASS=keytype>void</font> set_port(<font CLASS=keytype>int</font>);
ipaddress get_myip();
<font CLASS=keytype>int</font> get_myport();
<font CLASS=keytype>int</font> get_handle() { <font CLASS=keyword>return</font> handle; }
<font CLASS=keytype>bool</font> waitfor(<font CLASS=keytype>int</font> timeout);
<font CLASS=keytype>int</font> receive(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count, ipaddress&amp; src);
<font CLASS=keytype>int</font> receive(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
string receive(<font CLASS=keytype>int</font> max, ipaddress&amp; src);
string receive(<font CLASS=keytype>int</font> max);
<font CLASS=keytype>void</font> send(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>void</font> send(<font CLASS=keyword>const</font> string&amp; s) { send(s, length(s)); }
};
<font CLASS=comment>//</font>
<font CLASS=comment>// ipmsgserver</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> ipmsgserver: public ipsvbase, <font CLASS=keyword>public</font> ippeerinfo
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> handle;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> close();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dobind(ipbindinfo*);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
ipmsgserver();
<font CLASS=keyword>virtual</font> ~ipmsgserver();
<font CLASS=keytype>int</font> get_handle() { <font CLASS=keyword>return</font> handle; }
<font CLASS=keytype>bool</font> poll(<font CLASS=keytype>int</font> i <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>, <font CLASS=keytype>int</font> timeout = <font CLASS=integer>0</font>);
<font CLASS=keytype>int</font> receive(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
string receive(<font CLASS=keytype>int</font> max);
<font CLASS=keytype>void</font> send(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>void</font> send(<font CLASS=keyword>const</font> string&amp; s) { send(s, length(s)); }
<font CLASS=keytype>void</font> sendto(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count, ipaddress ip, <font CLASS=keytype>int</font> port);
<font CLASS=keytype>void</font> sendto(<font CLASS=keyword>const</font> string&amp; s, ipaddress ip, <font CLASS=keytype>int</font> port)
{ sendto(s, length(s), ip, port); }
};
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(pop)
<font CLASS=preproc>#endif</font>
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PINET_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/include/pport.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>pport.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#define</font> __PPORT_H__
<font CLASS=preproc>#if</font> defined(linux)
<font CLASS=preproc>#</font> include &lt;stdint.h&gt; <font CLASS=comment>// for uintptr_t </font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#include</font> &lt;sys/types.h&gt;
<font CLASS=preproc>#ifndef</font> __cplusplus
<font CLASS=preproc>#</font> error <font CLASS=dblquot>"This is a C++ source"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#define</font> PTYPES_NAMESPACE pt
<font CLASS=comment>//</font>
<font CLASS=comment>// conditional namespace declarations</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#ifdef</font> PTYPES_NAMESPACE
<font CLASS=preproc>#</font> define PTYPES_BEGIN <font CLASS=keyword>namespace</font> PTYPES_NAMESPACE {
<font CLASS=preproc>#</font> define PTYPES_END }
<font CLASS=preproc>#</font> define USING_PTYPES <font CLASS=keyword>using</font> <font CLASS=keyword>namespace</font> PTYPES_NAMESPACE;
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> define PTYPES_NAMESPACE
<font CLASS=preproc>#</font> define PTYPES_BEGIN
<font CLASS=preproc>#</font> define PTYPES_END
<font CLASS=preproc>#</font> define USING_PTYPES
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// Windows DLL export/import and calling convention macros</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=preproc>#</font> <font CLASS=keyword>if</font> defined(PTYPES_DLL_EXPORTS)
<font CLASS=preproc>#</font> define ptpublic __declspec(dllexport)
<font CLASS=preproc>#</font> elif defined(PTYPES_DLL)
<font CLASS=preproc>#</font> define ptpublic__declspec(dllimport)
<font CLASS=preproc>#</font> <font CLASS=keyword>else</font>
<font CLASS=preproc>#</font> define
<font CLASS=preproc>#</font> endif
<font CLASS=preproc>#</font> define ptdecl__stdcall
<font CLASS=preproc>#</font> define __PFASTCALL __fastcall
<font CLASS=preproc>#else</font>
<font CLASS=preproc>#</font> define ptpublic
<font CLASS=preproc>#</font> define ptdecl
<font CLASS=preproc>#</font> define __PFASTCALL
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// versioning</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>extern</font> <font CLASS=dblquot>"C"</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>long</font> __ptypes_version;
<font CLASS=comment>// this enables old algebraic list interfaces; NO_PTYPES19_COMPAT</font>
<font CLASS=comment>// can be defined at command line</font>
<font CLASS=preproc>#if</font> !defined(NO_PTYPES19_COMPAT)
<font CLASS=preproc>#</font> define PTYPES19_COMPAT
<font CLASS=preproc>#endif</font>
PTYPES_BEGIN
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=comment>// we don't want "unreferenced inline function" warning</font>
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4514</font>)
<font CLASS=comment>// ... also "copy constructor/assignment operator could not be generated"</font>
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4511</font>)
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4512</font>)
<font CLASS=comment>// disable deprecation warnings for snprintf and others</font>
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4996</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#if</font> defined(_DEBUG) &amp;&amp; !defined(DEBUG)
<font CLASS=preproc>#</font> define DEBUG
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#if</font> defined(__WIN32__) &amp;&amp; !defined(WIN32)
<font CLASS=preproc>#</font> define WIN32
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// __APPLE__ is the only predefined macro on MacOS X</font>
<font CLASS=preproc>#if</font> defined(__APPLE__)
<font CLASS=preproc>#</font> define __DARWIN__
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// CHECK_BOUNDS enables bounds checking for strings and lists</font>
<font CLASS=preproc>#if</font> defined(DEBUG) &amp;&amp; !defined(CHECK_BOUNDS)
<font CLASS=preproc>#</font> define CHECK_BOUNDS
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// COUNT_OBJALLOC helps to keep track of the number of</font>
<font CLASS=comment>// objects created/destroyed</font>
<font CLASS=preproc>#if</font> defined(DEBUG) &amp;&amp; !defined(COUNT_OBJALLOC)
<font CLASS=preproc>#</font> define COUNT_OBJALLOC
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// useful typedefs</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> uint;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>long</font> ulong;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>short</font> ushort;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>char</font> uchar;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>signed</font> <font CLASS=keytype>char</font> schar;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>char</font>* pchar;
<font CLASS=keyword>typedef</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* pconst;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>void</font>* ptr;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>int</font>* pint;
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keyword>typedef</font> uint pintptr;
<font CLASS=preproc>#else</font>
<font CLASS=keyword>typedef</font> uintptr_t pintptr;
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// portable 64-bit integers</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#if</font> defined(_MSC_VER) <font CLASS=symbols>||</font> defined(__BORLANDC__)
<font CLASS=keyword>typedef</font> __int64 large;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> __int64 ularge;
<font CLASS=preproc>#</font> define LLCONST(a) (a##i64)
<font CLASS=preproc>#else</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>long</font> <font CLASS=keytype>long</font> large;
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>long</font> <font CLASS=keytype>long</font> ularge;
<font CLASS=preproc>#</font> define LLCONST(a) (a##ll)
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#define</font> LARGE_MIN (LLCONST(<font CLASS=symbols>-</font><font CLASS=integer>9223372036854775807</font>)<font CLASS=symbols>-</font><font CLASS=integer>1</font>)
<font CLASS=preproc>#define</font> LARGE_MAX (LLCONST(<font CLASS=integer>9223372036854775807</font>))
<font CLASS=preproc>#define</font> ULARGE_MAX (LLCONST(<font CLASS=integer>18446744073709551615</font>u))
<font CLASS=preproc>#if</font> defined(_MSC_VER) <font CLASS=symbols>||</font> defined(__BORLANDC__)
<font CLASS=preproc>#</font> define strcasecmp stricmp
<font CLASS=preproc>#</font> define snprintf _snprintf
<font CLASS=preproc>#endif</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// misc.</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// I like Pascal's nil</font>
<font CLASS=preproc>#define</font> nil <font CLASS=integer>0</font>
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> imax(<font CLASS=keytype>int</font> x, <font CLASS=keytype>int</font> y) { <font CLASS=keyword>return</font> (x &gt; y) ? x : y; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> imin(<font CLASS=keytype>int</font> x, <font CLASS=keytype>int</font> y) { <font CLASS=keyword>return</font> (x &lt; y) ? x : y; }
<font CLASS=keyword>inline</font> large lmax(large x, large y) { <font CLASS=keyword>return</font> (x &gt; y) ? x : y; }
<font CLASS=keyword>inline</font> large lmin(large x, large y) { <font CLASS=keyword>return</font> (x &lt; y) ? x : y; }
<font CLASS=comment>//</font>
<font CLASS=comment>// critical error processing</font>
<font CLASS=comment>//</font>
<font CLASS=preproc>#define</font> CRIT_FIRST 0xC0000
<font CLASS=keyword>typedef</font> <font CLASS=keytype>void</font> (*_pcrithandler)(<font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg);
_pcrithandler getcrithandler();
_pcrithandler setcrithandler(_pcrithandler newh);
<font CLASS=keytype>void</font> fatal(<font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg);
<font CLASS=comment>//</font>
<font CLASS=comment>// memory management (undocumented)</font>
<font CLASS=comment>// hides some BSD* incompatibility issues</font>
<font CLASS=comment>//</font>
<font CLASS=keytype>void</font>* memalloc(uint a);
<font CLASS=keytype>void</font>* memrealloc(<font CLASS=keytype>void</font>* p, uint a);
<font CLASS=keytype>void</font> memfree(<font CLASS=keytype>void</font>* p);
<font CLASS=keytype>void</font> memerror();
<font CLASS=keytype>int</font> memquantize(<font CLASS=keytype>int</font>);
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PPORT_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/include/pstreams.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>pstreams.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PSTREAMS_H__
<font CLASS=preproc>#define</font> __PSTREAMS_H__
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PTYPES_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"ptypes.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> PTYPES_ST
<font CLASS=preproc>#</font> ifndef __PASYNC_H__
<font CLASS=preproc>#</font> include <font CLASS=dblquot>"pasync.h"</font> <font CLASS=comment>// for logfile.lock </font>
<font CLASS=preproc>#</font> endif
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#include</font> &lt;stdarg.h&gt;
<font CLASS=preproc>#include</font> &lt;errno.h&gt;
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=preproc>#</font> define _WINSOCKAPI_ <font CLASS=comment>// prevent inclusion of winsock.h, because we need winsock2.h </font>
<font CLASS=preproc>#</font> include <font CLASS=dblquot>"windows.h"</font> <font CLASS=comment>// for OVERLAPPED </font>
<font CLASS=preproc>#endif</font>
PTYPES_BEGIN
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(push, <font CLASS=integer>4</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- abstract stream i/o classes ----------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// stream exception class</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> iobase;
<font CLASS=keyword>class</font> estream: public exception
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> code;
iobase* errstm;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
estream(iobase* ierrstm, <font CLASS=keytype>int</font> icode, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* imsg);
estream(iobase* ierrstm, <font CLASS=keytype>int</font> icode, <font CLASS=keyword>const</font> string&amp; imsg);
<font CLASS=keyword>virtual</font> ~estream();
<font CLASS=keytype>int</font> get_code() { <font CLASS=keyword>return</font> code; }
iobase* get_errstm() { <font CLASS=keyword>return</font> errstm; }
};
<font CLASS=keyword>typedef</font> <font CLASS=keytype>void</font> (*iostatusevent)(iobase* sender, <font CLASS=keytype>int</font> code);
<font CLASS=keytype>int</font> unixerrno();
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* unixerrmsg(<font CLASS=keytype>int</font> code);
<font CLASS=comment>// status codes: compatible with WinInet API</font>
<font CLASS=comment>// additional status codes are defined in pinet.h for ipsocket</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_CREATED <font CLASS=symbols>=</font> <font CLASS=integer>1</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_OPENING <font CLASS=symbols>=</font> <font CLASS=integer>5</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_OPENED <font CLASS=symbols>=</font> <font CLASS=integer>35</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_READING <font CLASS=symbols>=</font> <font CLASS=integer>37</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_WRITING <font CLASS=symbols>=</font> <font CLASS=integer>38</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_EOF <font CLASS=symbols>=</font> <font CLASS=integer>45</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_CLOSING <font CLASS=symbols>=</font> <font CLASS=integer>250</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> IO_CLOSED <font CLASS=symbols>=</font> <font CLASS=integer>253</font>;
<font CLASS=comment>//</font>
<font CLASS=comment>// iobase</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>enum</font> ioseekmode
{
IO_BEGIN,
IO_CURRENT,
IO_END
};
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> invhandle <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>;
<font CLASS=keyword>class</font> iobase: public component
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> fdxoutstm;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>bool</font> active; <font CLASS=comment>// active status, changed by open() and close()</font>
<font CLASS=keytype>bool</font> cancelled; <font CLASS=comment>// the stream was cancelled by cancel()</font>
<font CLASS=keytype>bool</font> eof; <font CLASS=comment>// end of file reached, only for input streams</font>
<font CLASS=keytype>int</font> handle; <font CLASS=comment>// used in many derivative classes</font>
large abspos; <font CLASS=comment>// physical stream position</font>
<font CLASS=keytype>int</font> bufsize; <font CLASS=comment>// buffer size, can be changed only when not active</font>
<font CLASS=keytype>char</font>* bufdata; <font CLASS=comment>// internal: allocated buffer data</font>
<font CLASS=keytype>int</font> bufpos; <font CLASS=comment>// internal: current position</font>
<font CLASS=keytype>int</font> bufend; <font CLASS=comment>// internal: current data size in the buffer</font>
<font CLASS=keytype>int</font> stmerrno; <font CLASS=comment>// UNIX-compatible error numbers, see comments in piobase.cxx</font>
string deferrormsg; <font CLASS=comment>// internal: default error message when an exception is thrown,</font>
<font CLASS=keytype>int</font> status; <font CLASS=comment>// stream status code, see IO_xxx constants above</font>
iostatusevent onstatus; <font CLASS=comment>// user-defined status change handler</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> bufalloc();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> buffree();
<font CLASS=keytype>void</font> bufclear() { bufpos <font CLASS=symbols>=</font> <font CLASS=integer>0</font>; bufend <font CLASS=symbols>=</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>void</font> errstminactive();
<font CLASS=keytype>void</font> errbufrequired();
<font CLASS=keytype>void</font> requireactive() { <font CLASS=keyword>if</font> (!active) errstminactive(); }
<font CLASS=keytype>void</font> requirebuf() { requireactive(); <font CLASS=keyword>if</font> (bufdata <font CLASS=symbols>==</font> <font CLASS=integer>0</font>) errbufrequired(); }
<font CLASS=keytype>int</font> convertoffset(large);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen() <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> large doseek(large newpos, ioseekmode mode);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> chstat(<font CLASS=keytype>int</font> newstat);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> uerrno();
<font CLASS=keyword>virtual</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* uerrmsg(<font CLASS=keytype>int</font> code);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
iobase(<font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~iobase();
<font CLASS=keytype>void</font> open();
<font CLASS=keytype>void</font> close();
<font CLASS=keytype>void</font> cancel();
<font CLASS=keytype>void</font> reopen() { open(); }
large seekx(large newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN);
<font CLASS=keytype>int</font> seek(<font CLASS=keytype>int</font> newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN) { <font CLASS=keyword>return</font> convertoffset(seekx(newpos, mode)); }
<font CLASS=keytype>void</font> error(<font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* defmsg);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> flush();
<font CLASS=keyword>virtual</font> string get_errormsg();
<font CLASS=keyword>virtual</font> string get_errstmname();
<font CLASS=keyword>virtual</font> string get_streamname() <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keytype>bool</font> get_active() { <font CLASS=keyword>return</font> active; }
<font CLASS=keytype>void</font> set_active(<font CLASS=keytype>bool</font> newval);
<font CLASS=keytype>bool</font> get_cancelled() { <font CLASS=keyword>return</font> cancelled; }
<font CLASS=keytype>void</font> set_cancelled(<font CLASS=keytype>bool</font> newval) { cancelled <font CLASS=symbols>=</font> newval; }
<font CLASS=keytype>int</font> get_handle() { <font CLASS=keyword>return</font> handle; }
<font CLASS=keytype>int</font> get_bufsize() { <font CLASS=keyword>return</font> bufsize; }
<font CLASS=keytype>void</font> set_bufsize(<font CLASS=keytype>int</font> newval);
<font CLASS=keytype>int</font> get_stmerrno() { <font CLASS=keyword>return</font> stmerrno; }
<font CLASS=keytype>int</font> get_status() { <font CLASS=keyword>return</font> status; }
iostatusevent get_onstatus() { <font CLASS=keyword>return</font> onstatus; }
<font CLASS=keytype>void</font> set_onstatus(iostatusevent newval) { onstatus <font CLASS=symbols>=</font> newval; }
};
<font CLASS=keyword>typedef</font> iobase* piobase;
<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> defbufsize;
<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> stmbalance;
<font CLASS=comment>//</font>
<font CLASS=comment>// instm - abstract input stream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font> eofchar <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keyword>class</font> instm: public iobase
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>int</font> rawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> bufvalidate();
<font CLASS=keytype>void</font> skipeol();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
instm(<font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~instm();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>bool</font> get_eof();
<font CLASS=keytype>void</font> set_eof(<font CLASS=keytype>bool</font> ieof) { eof <font CLASS=symbols>=</font> ieof; }
<font CLASS=keytype>bool</font> get_eol();
<font CLASS=keytype>int</font> get_dataavail();
<font CLASS=keytype>char</font> preview();
<font CLASS=keytype>char</font> get();
<font CLASS=keytype>void</font> putback();
string token(<font CLASS=keyword>const</font> cset&amp; chars);
string token(<font CLASS=keyword>const</font> cset&amp; chars, <font CLASS=keytype>int</font> limit);
<font CLASS=keytype>int</font> token(<font CLASS=keyword>const</font> cset&amp; chars, char* buf, <font CLASS=keytype>int</font> size);
string line();
string line(<font CLASS=keytype>int</font> limit);
<font CLASS=keytype>int</font> line(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> size, <font CLASS=keytype>bool</font> eateol <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
<font CLASS=keytype>int</font> read(<font CLASS=keytype>void</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>int</font> skip(<font CLASS=keytype>int</font> count);
<font CLASS=keytype>int</font> skiptoken(<font CLASS=keyword>const</font> cset&amp; chars);
<font CLASS=keytype>void</font> skipline(<font CLASS=keytype>bool</font> eateol <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
large tellx();
<font CLASS=keytype>int</font> tell() { <font CLASS=keyword>return</font> convertoffset(tellx()); }
large seekx(large newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN);
<font CLASS=keytype>int</font> seek(<font CLASS=keytype>int</font> newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN) { <font CLASS=keyword>return</font> convertoffset(seekx(newpos, mode)); }
};
<font CLASS=keyword>typedef</font> instm* pinstm;
<font CLASS=comment>//</font>
<font CLASS=comment>// outstm - abstract output stream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outstm: public iobase
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>bool</font> flusheol;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>int</font> rawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> bufvalidate();
<font CLASS=keytype>void</font> bufadvance(<font CLASS=keytype>int</font> delta)
{ bufpos <font CLASS=symbols>+=</font> delta; <font CLASS=keyword>if</font> (bufend &lt; bufpos) bufend <font CLASS=symbols>=</font> bufpos; }
<font CLASS=keytype>bool</font> canwrite();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outstm(<font CLASS=keytype>bool</font> iflusheol <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>, <font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> -<font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~outstm();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>bool</font> get_flusheol() { <font CLASS=keyword>return</font> flusheol; }
<font CLASS=keytype>void</font> set_flusheol(<font CLASS=keytype>bool</font> newval) { flusheol <font CLASS=symbols>=</font> newval; }
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> flush();
<font CLASS=keytype>bool</font> get_eof() { <font CLASS=keyword>return</font> eof; }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>char</font> c);
<font CLASS=keytype>void</font> put(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str);
<font CLASS=keytype>void</font> put(<font CLASS=keyword>const</font> string&amp; str);
<font CLASS=keytype>void</font> vputf(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt, va_list);
<font CLASS=keytype>void</font> putf(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt, ...);
<font CLASS=keytype>void</font> putline(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str);
<font CLASS=keytype>void</font> putline(<font CLASS=keyword>const</font> string&amp; str);
<font CLASS=keytype>void</font> puteol();
<font CLASS=keytype>int</font> write(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* buf, <font CLASS=keytype>int</font> count);
large tellx() { <font CLASS=keyword>return</font> abspos <font CLASS=symbols>+</font> bufpos; }
<font CLASS=keytype>int</font> tell() { <font CLASS=keyword>return</font> convertoffset(tellx()); }
large seekx(large newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN);
<font CLASS=keytype>int</font> seek(<font CLASS=keytype>int</font> newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN) { <font CLASS=keyword>return</font> convertoffset(seekx(newpos, mode)); }
};
<font CLASS=keyword>typedef</font> outstm* poutstm;
<font CLASS=comment>// %t and %T formats</font>
<font CLASS=keyword>extern</font> <font CLASS=keytype>char</font>* shorttimefmt; <font CLASS=comment>// "%d-%b-%Y %X"</font>
<font CLASS=keyword>extern</font> <font CLASS=keytype>char</font>* longtimefmt; <font CLASS=comment>// "%a %b %d %X %Y"</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// internal class used in fdxstm</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> fdxstm;
<font CLASS=keyword>class</font> fdxoutstm: public outstm
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> fdxstm;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
fdxstm* in;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> chstat(<font CLASS=keytype>int</font> newstat);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> uerrno();
<font CLASS=keyword>virtual</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* uerrmsg(<font CLASS=keytype>int</font> code);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
fdxoutstm(<font CLASS=keytype>int</font> ibufsize, fdxstm* iin);
<font CLASS=keyword>virtual</font> ~fdxoutstm();
<font CLASS=keyword>virtual</font> string get_streamname();
};
<font CLASS=keyword>typedef</font> fdxstm* pfdxstm;
<font CLASS=comment>//</font>
<font CLASS=comment>// fdxstm: abstract full-duplex stream (for sockets and pipes)</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> fdxstm: public instm
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> fdxoutstm;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
fdxoutstm out;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
fdxstm(<font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~fdxstm();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>void</font> set_bufsize(<font CLASS=keytype>int</font> newval); <font CLASS=comment>// sets both input and output buffer sizes</font>
<font CLASS=keytype>void</font> open(); <font CLASS=comment>// rewritten to pass the call to the output stream too</font>
<font CLASS=keytype>void</font> close();
<font CLASS=keytype>void</font> cancel();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> flush();
large tellx(<font CLASS=keytype>bool</font>); <font CLASS=comment>// true for input and false for output</font>
<font CLASS=keytype>int</font> tell(<font CLASS=keytype>bool</font> forin) { <font CLASS=keyword>return</font> convertoffset(tellx(forin)); }
// output interface: pretend <font CLASS=keyword>this</font> <font CLASS=keyword>class</font> is derived both
// from instm and outstm. actually we can<font CLASS=sinquot>'t use multiple
// inheritance here, since this is a full-duplex stream,
// hence everything must be duplicated for input and output
void putf(const char* fmt, ...);
void put(char c) { out.put(c); }
void put(const char* str) { out.put(str); }
void put(const string&amp; str) { out.put(str); }
void putline(const char* str) { out.putline(str); }
void putline(const string&amp; str) { out.putline(str); }
void puteol() { out.puteol(); }
int write(const void* buf, int count) { return out.write(buf, count); }
bool get_flusheol() { return out.get_flusheol(); }
void set_flusheol(bool newval) { out.set_flusheol(newval); }
operator outstm&amp;() { return out; }
};
<font CLASS=comment>//</font>
<font CLASS=comment>// abstract input filter class</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> infilter: public instm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
instm* stm;
<font CLASS=keytype>char</font>* savebuf;
<font CLASS=keytype>int</font> savecount;
string postponed;
<font CLASS=keytype>void</font> copytobuf(string&amp; s);
<font CLASS=keytype>void</font> copytobuf(pconst&amp; buf, <font CLASS=keytype>int</font>&amp; count);
<font CLASS=keytype>bool</font> copytobuf(<font CLASS=keytype>char</font> c);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> freenotify(component* sender);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofilter() <font CLASS=symbols>=</font> <font CLASS=integer>0</font>;
<font CLASS=keytype>bool</font> bufavail() { <font CLASS=keyword>return</font> savecount &gt; <font CLASS=integer>0</font>; }
<font CLASS=keytype>void</font> post(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>void</font> post(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s);
<font CLASS=keytype>void</font> post(<font CLASS=keytype>char</font> c);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> post(string s);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
infilter(instm* istm, <font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~infilter();
<font CLASS=keyword>virtual</font> string get_errstmname();
instm* get_stm() { <font CLASS=keyword>return</font> stm; }
<font CLASS=keytype>void</font> set_stm(instm* stm);
};
<font CLASS=comment>//</font>
<font CLASS=comment>// abstract output filter class</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outfilter: public outstm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
outstm* stm;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> freenotify(component* sender);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outfilter(outstm* istm, <font CLASS=keytype>int</font> ibufsize <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~outfilter();
<font CLASS=keyword>virtual</font> string get_errstmname();
outstm* get_stm() { <font CLASS=keyword>return</font> stm; }
<font CLASS=keytype>void</font> set_stm(outstm* stm);
};
<font CLASS=comment>//</font>
<font CLASS=comment>// inmemory - memory stream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> inmemory: public instm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
string mem;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> bufalloc();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> buffree();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> bufvalidate();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> large doseek(large newpos, ioseekmode mode);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
inmemory(<font CLASS=keyword>const</font> string&amp; imem);
<font CLASS=keyword>virtual</font> ~inmemory();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keyword>virtual</font> string get_streamname();
large seekx(large newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN);
<font CLASS=keytype>int</font> seek(<font CLASS=keytype>int</font> newpos, ioseekmode mode <font CLASS=symbols>=</font> IO_BEGIN) { <font CLASS=keyword>return</font> convertoffset(seekx(newpos, mode)); }
string get_strdata() { <font CLASS=keyword>return</font> mem; }
<font CLASS=keytype>void</font> set_strdata(<font CLASS=keyword>const</font> string&amp; data);
};
<font CLASS=comment>//</font>
<font CLASS=comment>// outmemory - memory stream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outmemory: public outstm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
string mem;
<font CLASS=keytype>int</font> limit;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> large doseek(large newpos, ioseekmode mode);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outmemory(<font CLASS=keytype>int</font> limit <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
<font CLASS=keyword>virtual</font> ~outmemory();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keyword>virtual</font> string get_streamname();
large tellx() { <font CLASS=keyword>return</font> abspos; }
<font CLASS=keytype>int</font> tell() { <font CLASS=keyword>return</font> (<font CLASS=keytype>int</font>)abspos; }
string get_strdata();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- file input/output --------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// infile - file input</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outfile;
<font CLASS=keyword>class</font> infile: public instm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
string filename;
<font CLASS=keytype>int</font> syshandle; <font CLASS=comment>// if not -1, assigned to handle in open() instead of opening a file by a name</font>
<font CLASS=keytype>int</font> peerhandle; <font CLASS=comment>// pipe peer handle, needed for closing the peer after fork() on unix</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
infile();
infile(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn);
infile(<font CLASS=keyword>const</font> string&amp; ifn);
<font CLASS=keyword>virtual</font> ~infile();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>void</font> pipe(outfile&amp;);
<font CLASS=keyword>virtual</font> string get_streamname();
<font CLASS=keytype>int</font> get_syshandle() { <font CLASS=keyword>return</font> syshandle; }
<font CLASS=keytype>void</font> set_syshandle(<font CLASS=keytype>int</font> ihandle) { close(); syshandle <font CLASS=symbols>=</font> ihandle; }
<font CLASS=keytype>int</font> get_peerhandle() { <font CLASS=keyword>return</font> peerhandle; }
string get_filename() { <font CLASS=keyword>return</font> filename; }
<font CLASS=keytype>void</font> set_filename(<font CLASS=keyword>const</font> string&amp; ifn) { close(); filename <font CLASS=symbols>=</font> ifn; }
<font CLASS=keytype>void</font> set_filename(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn) { close(); filename <font CLASS=symbols>=</font> ifn; }
};
<font CLASS=comment>//</font>
<font CLASS=comment>// outfile - file output</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outfile: public outstm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> infile; <font CLASS=comment>// infile::pipe() needs access to peerhandle</font>
string filename;
<font CLASS=keytype>int</font> syshandle; <font CLASS=comment>// if not -1, assigned to handle in open() instead of opening a file by a name</font>
<font CLASS=keytype>int</font> peerhandle; <font CLASS=comment>// pipe peer handle, needed for closing the peer after fork() on unix</font>
<font CLASS=keytype>int</font> umode; <font CLASS=comment>// unix file mode (unix only), default = 644</font>
<font CLASS=keytype>bool</font> append; <font CLASS=comment>// append (create new if needed), default = false</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outfile();
outfile(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
outfile(<font CLASS=keyword>const</font> string&amp; ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keyword>virtual</font> ~outfile();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> flush();
<font CLASS=keyword>virtual</font> string get_streamname();
<font CLASS=keytype>int</font> get_syshandle() { <font CLASS=keyword>return</font> syshandle; }
<font CLASS=keytype>void</font> set_syshandle(<font CLASS=keytype>int</font> ihandle) { close(); syshandle <font CLASS=symbols>=</font> ihandle; }
<font CLASS=keytype>int</font> get_peerhandle() { <font CLASS=keyword>return</font> peerhandle; }
string get_filename() { <font CLASS=keyword>return</font> filename; }
<font CLASS=keytype>void</font> set_filename(<font CLASS=keyword>const</font> string&amp; ifn) { close(); filename <font CLASS=symbols>=</font> ifn; }
<font CLASS=keytype>void</font> set_filename(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn) { close(); filename <font CLASS=symbols>=</font> ifn; }
<font CLASS=keytype>bool</font> get_append() { <font CLASS=keyword>return</font> append; }
<font CLASS=keytype>void</font> set_append(<font CLASS=keytype>bool</font> iappend) { close(); append <font CLASS=symbols>=</font> iappend; }
<font CLASS=keytype>int</font> get_umode() { <font CLASS=keyword>return</font> umode; }
<font CLASS=keytype>void</font> set_umode(<font CLASS=keytype>int</font> iumode) { close(); umode <font CLASS=symbols>=</font> iumode; }
};
<font CLASS=comment>//</font>
<font CLASS=comment>// logfile - file output with thread-safe putf()</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> logfile: public outfile
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc>#ifndef</font> PTYPES_ST
mutex lock;
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
logfile();
logfile(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
logfile(<font CLASS=keyword>const</font> string&amp; ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
<font CLASS=keyword>virtual</font> ~logfile();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>void</font> vputf(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt, va_list);
<font CLASS=keytype>void</font> putf(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt, ...);
};
<font CLASS=comment>//</font>
<font CLASS=comment>// intee - UNIX tee-style utility class</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> intee: public infilter {
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
outfile file;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofilter();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
intee(instm* istm, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
intee(instm* istm, <font CLASS=keyword>const</font> string&amp; ifn, <font CLASS=keytype>bool</font> iappend <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keyword>virtual</font> ~intee();
outfile* get_file() { <font CLASS=keyword>return</font> &amp;file; }
<font CLASS=keyword>virtual</font> string get_streamname();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- named pipes --------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// on Unix this directory can be overridden by providing the</font>
<font CLASS=comment>// full path, e.g. '/var/run/mypipe'. the path is ignored on </font>
<font CLASS=comment>// Windows and is always replaced with '\\&lt;server&gt;\pipe\'</font>
<font CLASS=preproc>#ifndef</font> WIN32
<font CLASS=preproc>#</font> define DEF_NAMED_PIPES_DIR <font CLASS=dblquot>"/tmp/"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> DEF_PIPE_TIMEOUT <font CLASS=symbols>=</font> <font CLASS=integer>20000</font>; <font CLASS=comment>// in milliseconds, for reading and writing</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> DEF_PIPE_OPEN_TIMEOUT <font CLASS=symbols>=</font> <font CLASS=integer>1000</font>; <font CLASS=comment>// for connecting to the remote pipe:</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> DEF_PIPE_OPEN_RETRY <font CLASS=symbols>=</font> <font CLASS=integer>5</font>; <font CLASS=comment>// will double the timeout value for each retry,</font>
<font CLASS=comment>// i.e. 1 second, then 2, then 4 etc.</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> DEF_PIPE_SYSTEM_BUF_SIZE <font CLASS=symbols>=</font> <font CLASS=integer>4096</font>;
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>class</font> namedpipe: public fdxstm
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> npserver;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
string pipename;
<font CLASS=keytype>int</font> svhandle;
<font CLASS=preproc>#ifdef</font> WIN32
// we use overlapped IO in order to have timed waiting in serve()
// and also to implement timeout error on the client side
OVERLAPPED ovr;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawread(<font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>static</font> string realpipename(<font CLASS=keyword>const</font> string&amp; pipename, <font CLASS=keyword>const</font> string&amp; svrname <font CLASS=symbols>=</font> nullstring);
<font CLASS=keytype>void</font> initovr();
<font CLASS=preproc>#else</font>
<font CLASS=keytype>static</font> string realpipename(<font CLASS=keyword>const</font> string&amp; pipename);
<font CLASS=keytype>static</font> <font CLASS=keytype>bool</font> setupsockaddr(<font CLASS=keyword>const</font> string&amp; pipename, <font CLASS=keytype>void</font>* sa);
<font CLASS=keytype>void</font> initovr() {}
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> large doseek(large, ioseekmode);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
namedpipe();
namedpipe(<font CLASS=keyword>const</font> string&amp; ipipename);
<font CLASS=preproc>#ifdef</font> WIN32
namedpipe(<font CLASS=keyword>const</font> string&amp; ipipename, <font CLASS=keyword>const</font> string&amp; servername);
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>virtual</font> ~namedpipe();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> flush();
<font CLASS=keyword>virtual</font> string get_streamname();
string get_pipename() { <font CLASS=keyword>return</font> pipename; }
<font CLASS=keytype>void</font> set_pipename(<font CLASS=keyword>const</font> string&amp;);
<font CLASS=keytype>void</font> set_pipename(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
};
<font CLASS=keyword>class</font> npserver: public unknown
{
string pipename;
<font CLASS=keytype>int</font> handle;
<font CLASS=keytype>bool</font> active;
<font CLASS=keytype>void</font> error(<font CLASS=keytype>int</font> code, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* defmsg);
<font CLASS=keytype>void</font> open();
<font CLASS=keytype>void</font> close();
<font CLASS=preproc>#ifdef</font> WIN32
<font CLASS=keytype>void</font> openinst();
<font CLASS=keytype>void</font> closeinst();
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
npserver(<font CLASS=keyword>const</font> string&amp; ipipename);
~npserver();
<font CLASS=keytype>bool</font> serve(namedpipe&amp; client, <font CLASS=keytype>int</font> timeout <font CLASS=symbols>=</font> <font CLASS=symbols>-</font><font CLASS=integer>1</font>);
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- utility streams ----------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// MD5 -- message digest algorithm</font>
<font CLASS=comment>// Derived from L. Peter Deutsch's work, please see src/pmd5.cxx</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> md5_digsize <font CLASS=symbols>=</font> <font CLASS=integer>16</font>;
<font CLASS=keyword>typedef</font> uchar md5_digest[md5_digsize];
<font CLASS=comment>// from md5.h</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>char</font> md5_byte_t; <font CLASS=comment>/* 8-bit byte */</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> md5_word_t; <font CLASS=comment>/* 32-bit word */</font>
<font CLASS=keyword>typedef</font> <font CLASS=keyword>struct</font> md5_state_s
{
md5_word_t count[<font CLASS=integer>2</font>];<font CLASS=comment>/* message length in bits, lsw first */</font>
md5_word_t abcd[<font CLASS=integer>4</font>];<font CLASS=comment>/* digest buffer */</font>
md5_byte_t buf[<font CLASS=integer>64</font>];<font CLASS=comment>/* accumulate block */</font>
} md5_state_t;
<font CLASS=keyword>class</font> outmd5: public outfilter
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
md5_state_s ctx;
md5_digest digest;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> count);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outmd5(outstm* istm <font CLASS=symbols>=</font> nil);
<font CLASS=keyword>virtual</font> ~outmd5();
<font CLASS=keyword>virtual</font> string get_streamname();
<font CLASS=keyword>const</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>char</font>* get_bindigest() { close(); <font CLASS=keyword>return</font> digest; }
string get_digest();
};
<font CLASS=comment>//</font>
<font CLASS=comment>// null output stream</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>class</font> outnull: public outstm
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> dorawwrite(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doopen();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> doclose();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
outnull();
<font CLASS=keyword>virtual</font> ~outnull();
<font CLASS=keyword>virtual</font> string get_streamname();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- unit ---------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=comment>// disable "type name first seen using 'struct' now seen using 'class'" warning</font>
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4099</font>)
<font CLASS=comment>// disable "class '...' needs to have dll-interface to be used by clients of class </font>
<font CLASS=comment>// '...'" warning, since the compiler may sometimes give this warning incorrectly.</font>
<font CLASS=preproc>#</font> pragma warning (disable: <font CLASS=integer>4251</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=keyword>class</font> unit_thread;
<font CLASS=keyword>class</font> unit: public component
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> unit_thread;
unit* pipe_next; <font CLASS=comment>// next unit in the pipe chain, assigned by connect()</font>
unit_thread* main_thread; <font CLASS=comment>// async execution thread, started by run() if necessary</font>
<font CLASS=keytype>int</font> running; <font CLASS=comment>// running status, to protect from recursive calls to run() and waitfor()</font>
<font CLASS=keytype>void</font> do_main();
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
compref&lt;instm&gt; uin;
compref&lt;outstm&gt; uout;
unit();
<font CLASS=keyword>virtual</font> ~unit();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
// things that may be overridden in descendant classes
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> main(); <font CLASS=comment>// main code, called from run()</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> cleanup(); <font CLASS=comment>// main code cleanup, called from run()</font>
// service methods
<font CLASS=keytype>void</font> connect(unit* next);
<font CLASS=keytype>void</font> run(<font CLASS=keytype>bool</font> async <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keytype>void</font> waitfor();
};
<font CLASS=keyword>typedef</font> unit* punit;
<font CLASS=keyword>typedef</font> unit CUnit; <font CLASS=comment>// send me a $10 check if you use this alias (not obligatory though,</font>
<font CLASS=comment>// because the library is free, after all)</font>
<font CLASS=comment>//</font>
<font CLASS=comment>// standard input, output and error devices</font>
<font CLASS=comment>//</font>
<font CLASS=keyword>extern</font> infile pin;
<font CLASS=keyword>extern</font> logfile pout;
<font CLASS=keyword>extern</font> logfile perr;
<font CLASS=keyword>extern</font> outnull pnull;
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(pop)
<font CLASS=preproc>#endif</font>
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PSTREAMS_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/include/ptime.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>ptime.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PTIME_H__
<font CLASS=preproc>#define</font> __PTIME_H__
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#ifndef</font> __PTYPES_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"ptypes.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#include</font> &lt;time.h&gt;
PTYPES_BEGIN
<font CLASS=comment>// datetime type: 64-bit, number of milliseconds since midnight 01/01/0001</font>
<font CLASS=keyword>typedef</font> large datetime;
<font CLASS=preproc>#define</font> invdatetime LLCONST(<font CLASS=symbols>-</font><font CLASS=integer>1</font>)
<font CLASS=preproc>#define</font> _msecsmax <font CLASS=integer>86400000</font> <font CLASS=comment>// number of milliseconds in one day </font>
<font CLASS=preproc>#define</font> _daysmax <font CLASS=integer>3652059</font> <font CLASS=comment>// number of days between 01/01/0001 and 12/31/9999 </font>
<font CLASS=preproc>#define</font> _datetimemax LLCONST(<font CLASS=integer>315537897600000</font>) <font CLASS=comment>// max. allowed number for datetime type </font>
<font CLASS=preproc>#define</font> _unixepoch LLCONST(<font CLASS=integer>62135596800000</font>) <font CLASS=comment>// difference between time_t and datetime in milliseconds </font>
<font CLASS=comment>// datetime general utilities</font>
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> days(datetime d) { <font CLASS=keyword>return</font> <font CLASS=keytype>int</font>(d / _msecsmax); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> msecs(datetime d) { <font CLASS=keyword>return</font> <font CLASS=keytype>int</font>(d % _msecsmax); }
datetime mkdt(<font CLASS=keytype>int</font> days, <font CLASS=keytype>int</font> msecs);
<font CLASS=keytype>bool</font> isvalid(datetime);
datetime now(<font CLASS=keytype>bool</font> utc <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
<font CLASS=keytype>void</font> tzupdate();
<font CLASS=keytype>int</font> tzoffset();
string dttostring(datetime, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt);
string nowstring(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* fmt, <font CLASS=keytype>bool</font> utc <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
datetime utodatetime(time_t u);
<font CLASS=keyword>struct</font> tm* dttotm(datetime dt, <font CLASS=keyword>struct</font> tm&amp; t);
<font CLASS=comment>// date/calendar manipulation</font>
<font CLASS=keytype>bool</font> isleapyear(<font CLASS=keytype>int</font> year);
<font CLASS=keytype>int</font> daysinmonth(<font CLASS=keytype>int</font> year, <font CLASS=keytype>int</font> month);
<font CLASS=keytype>int</font> daysinyear(<font CLASS=keytype>int</font> year, <font CLASS=keytype>int</font> month);
<font CLASS=keytype>int</font> dayofweek(datetime);
<font CLASS=keytype>bool</font> isdatevalid(<font CLASS=keytype>int</font> year, <font CLASS=keytype>int</font> month, <font CLASS=keytype>int</font> day);
datetime encodedate(<font CLASS=keytype>int</font> year, <font CLASS=keytype>int</font> month, <font CLASS=keytype>int</font> day);
<font CLASS=keytype>bool</font> decodedate(datetime, <font CLASS=keytype>int</font>&amp; year, <font CLASS=keytype>int</font>&amp; month, <font CLASS=keytype>int</font>&amp; day);
<font CLASS=comment>// time manipulation</font>
<font CLASS=keytype>bool</font> istimevalid(<font CLASS=keytype>int</font> hour, <font CLASS=keytype>int</font> min, <font CLASS=keytype>int</font> sec, <font CLASS=keytype>int</font> msec <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
datetime encodetime(<font CLASS=keytype>int</font> hour, <font CLASS=keytype>int</font> min, <font CLASS=keytype>int</font> sec, <font CLASS=keytype>int</font> msec <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=keytype>bool</font> decodetime(datetime, <font CLASS=keytype>int</font>&amp; hour, <font CLASS=keytype>int</font>&amp; min, <font CLASS=keytype>int</font>&amp; sec, <font CLASS=keytype>int</font>&amp; msec);
<font CLASS=keytype>bool</font> decodetime(datetime, <font CLASS=keytype>int</font>&amp; hour, <font CLASS=keytype>int</font>&amp; min, <font CLASS=keytype>int</font>&amp; sec);
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PTIME_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/include/ptypes.h.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Syntax highlighting generated by Web C Plus Plus software v0.8.4
Webcpp Copyright (C)2001-2004 Jeffrey Bakker under the GNU GPL
Get webcpp at http://webcpp.sf.net
-->
<html>
<head>
<title>ptypes.h</title>
<style type="text/css">
/*
Webcpp v0.8.1 compatible StyleSheet
http://webcpp.sf.net
Theme: ide-msvcpp
*/
body
{
background-color: #ffffff
}
.webcpp a:link {color:#000000}
.webcpp a:visited {color:#008000}
.webcpp a:active {color:#0000ff}
.webcpp a:hover {color:#0000ff}
.webcpp pre
{
color: #000000
}
.webcpp font
{
font-size:100%
}
.webcpp .symbols
{
color: #000000
}
.webcpp .preproc
{
color: #0000ff
}
.webcpp .integer
{
color: #000000
}
.webcpp .floatpt
{
color: #000000
}
.webcpp .dblquot
{
color: #000000
}
.webcpp .sinquot
{
color: #000000
}
.webcpp .keyword
{
color: #0000ff;
}
.webcpp .keytype
{
color: #0000ff;
}
.webcpp .comment
{
color: #008000;
}
</style>
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40"> <p><a href="../htsrc.html">Index</a><hr noshade></p>
<div class="webcpp">
<pre>
<font CLASS=preproc>#ifndef</font> __PTYPES_H__
<font CLASS=preproc>#define</font> __PTYPES_H__
<font CLASS=preproc>#ifndef</font> __PPORT_H__
<font CLASS=preproc>#include</font> <font CLASS=dblquot>"pport.h"</font>
<font CLASS=preproc>#endif</font>
<font CLASS=preproc>#include</font> &lt;string.h&gt;
PTYPES_BEGIN
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> pack(push, <font CLASS=integer>4</font>)
<font CLASS=comment>// disable "non dll-interface class '...' used as base for dll-interface class '...'" warning</font>
<font CLASS=preproc>#pragma</font> warning(disable : <font CLASS=integer>4275</font>)
<font CLASS=comment>// disable "conditional expression constant" warning</font>
<font CLASS=preproc>#pragma</font> warning(push)
<font CLASS=preproc>#pragma</font> warning(disable : <font CLASS=integer>4127</font>)
<font CLASS=preproc>#endif</font>
<font CLASS=keytype>int</font> __PFASTCALL pincrement(<font CLASS=keytype>int</font>* target);
<font CLASS=keytype>int</font> __PFASTCALL pdecrement(<font CLASS=keytype>int</font>* target);
<font CLASS=keytype>int</font> __PFASTCALL pexchange(<font CLASS=keytype>int</font>* target, <font CLASS=keytype>int</font> value);
<font CLASS=keytype>void</font>* __PFASTCALL pexchange(<font CLASS=keytype>void</font>** target, <font CLASS=keytype>void</font>* value);
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> T&gt; <font CLASS=keyword>inline</font> T* tpexchange(T** target, T* value)
{ <font CLASS=keyword>return</font> (T*)pexchange((<font CLASS=keytype>void</font>**)target, (<font CLASS=keytype>void</font>*)value); }
<font CLASS=preproc>#if</font> ((__GNUC__ <font CLASS=symbols>==</font> <font CLASS=integer>3</font>) &amp;&amp; (__GNUC_MINOR__ &gt;<font CLASS=symbols>=</font> <font CLASS=integer>3</font>)) || (__GNUC__ == <font CLASS=integer>4</font>) || defined(__hpux)
<font CLASS=preproc>#</font> define VARIANT_TYPECAST_HACK
<font CLASS=preproc>#endif</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- string class --------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// dynamic string class with thread-safe ref-counted buffer</font>
<font CLASS=keyword>struct</font> _strrec
{
<font CLASS=keytype>int</font> refcount;
<font CLASS=keytype>int</font> length;
};
<font CLASS=keyword>typedef</font> _strrec* _pstrrec;
<font CLASS=preproc>#define</font> STR_BASE(x) (_pstrrec(x)<font CLASS=symbols>-</font><font CLASS=integer>1</font>)
<font CLASS=preproc>#define</font> STR_REFCOUNT(x) (STR_BASE(x)<font CLASS=symbols>-</font>&gt;refcount)
<font CLASS=preproc>#define</font> STR_LENGTH(x) (STR_BASE(x)<font CLASS=symbols>-</font>&gt;length)
<font CLASS=preproc>#define</font> PTR_TO_PSTRING(p) (pstring(&amp;(p)))
<font CLASS=preproc>#define</font> PTR_TO_STRING(p) (*PTR_TO_PSTRING(p))
<font CLASS=keyword>extern</font> <font CLASS=keytype>char</font>* emptystr;
<font CLASS=keyword>class</font> variant;
<font CLASS=keyword>class</font> string
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> variant;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>char</font>* data;
<font CLASS=keytype>static</font> <font CLASS=keytype>void</font> idxerror();
<font CLASS=keytype>void</font> _alloc(<font CLASS=keytype>int</font>);
<font CLASS=keytype>void</font> _realloc(<font CLASS=keytype>int</font>);
<font CLASS=keytype>void</font> _free();
<font CLASS=keytype>void</font> initialize() { data <font CLASS=symbols>=</font> emptystr; }
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
<font CLASS=keytype>void</font> initialize(<font CLASS=keytype>char</font>);
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> variant&amp;);
<font CLASS=keytype>void</font> finalize();
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font>);
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> string&amp;);
<font CLASS=keytype>void</font> assign(<font CLASS=keytype>char</font>);
<font CLASS=preproc>#ifdef</font> CHECK_BOUNDS
<font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) &gt;<font CLASS=symbols>=</font> <font CLASS=keytype>unsigned</font>(STR_LENGTH(data))) idxerror(); }
<font CLASS=preproc>#else</font>
<font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font> { }
<font CLASS=preproc>#endif</font>
string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> len1, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s2, <font CLASS=keytype>int</font> len2) { initialize(s1, len1, s2, len2); }
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> length(<font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> refcount(<font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> assign(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> len);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> clear(string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isempty(<font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>char</font>* setlength(string&amp;, <font CLASS=keytype>int</font>);
<font CLASS=keyword>friend</font> <font CLASS=keytype>char</font>* unique(string&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> concat(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keytype>int</font> catlen);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> concat(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> concat(string&amp; s, <font CLASS=keytype>char</font> s1);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> concat(string&amp; s, <font CLASS=keyword>const</font> string&amp; s1);
<font CLASS=keyword>friend</font> string copy(<font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> from, <font CLASS=keytype>int</font> cnt);
<font CLASS=keyword>friend</font> string copy(<font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> from);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ins(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> s1len, string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ins(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ins(<font CLASS=keytype>char</font> s1, string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ins(<font CLASS=keyword>const</font> string&amp; s1, string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(string&amp; s, <font CLASS=keytype>int</font> at, <font CLASS=keytype>int</font> cnt);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> pos(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> pos(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> pos(<font CLASS=keyword>const</font> string&amp; s1, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> rpos(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> contains(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keytype>int</font> len, <font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> contains(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1, <font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> contains(<font CLASS=keytype>char</font> s1, <font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> contains(<font CLASS=keyword>const</font> string&amp; s1, <font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> at);
<font CLASS=keyword>friend</font> string dup(<font CLASS=keyword>const</font> string&amp; s);
string() { initialize(); }
string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keytype>int</font> initlen) { initialize(sc, initlen); }
string(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) { initialize(sc); }
string(<font CLASS=keytype>char</font> c) { initialize(c); }
string(<font CLASS=keyword>const</font> string&amp; s) { initialize(s); }
~string() { finalize(); }
<font CLASS=preproc>#ifdef</font> VARIANT_TYPECAST_HACK
string(<font CLASS=keyword>const</font> variant&amp; v) { initialize(v); }
<font CLASS=preproc>#endif</font>
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) { assign(sc); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>char</font> c) { assign(c); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> string&amp; s) { assign(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) { concat(*<font CLASS=keyword>this</font>, sc); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keytype>char</font> c) { concat(*<font CLASS=keyword>this</font>, c); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> string&amp; s) { concat(*<font CLASS=keyword>this</font>, s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font>;
string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> c) <font CLASS=keyword>const</font>;
string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keyword>const</font> string&amp; s) <font CLASS=keyword>const</font>;
<font CLASS=keyword>friend</font> string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keyword>friend</font> string <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> strcmp(data, sc) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font>) <font CLASS=keyword>const</font>;
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> string&amp;) <font CLASS=keyword>const</font>;
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == sc); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font> c) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == c); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> string&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> <font CLASS=symbols>!</font>(*<font CLASS=keyword>this</font> == s); }
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keyword>const</font> string&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font>, <font CLASS=keyword>const</font> string&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keyword>const</font> string&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font>, <font CLASS=keyword>const</font> string&amp;);
<font CLASS=keyword>operator</font> <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> data; }
<font CLASS=keyword>operator</font> <font CLASS=keyword>const</font> uchar*() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (uchar*)data; }
<font CLASS=keytype>char</font>&amp; <font CLASS=keyword>operator</font>[] (<font CLASS=keytype>int</font> i) { idx(i); <font CLASS=keyword>return</font> unique(*<font CLASS=keyword>this</font>)[i]; }
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>&amp; <font CLASS=keyword>operator</font>[] (<font CLASS=keytype>int</font> i) <font CLASS=keyword>const</font> { idx(i); <font CLASS=keyword>return</font> data[i]; }
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string&amp; s, <font CLASS=keyword>const</font> string&amp; s1);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> finalize(string&amp; s);
};
<font CLASS=keyword>typedef</font> string* pstring;
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> length(<font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> STR_LENGTH(s.data); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> refcount(<font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> STR_REFCOUNT(s.data); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> assign(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* buf, <font CLASS=keytype>int</font> len) { s.assign(buf, len); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(string&amp; s) { s.finalize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isempty(<font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> pos(<font CLASS=keyword>const</font> string&amp; s1, <font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> pos(s1.data, s); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string&amp; s){ <font CLASS=keyword>return</font> s <font CLASS=symbols>==</font> sc; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> s <font CLASS=symbols>==</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* sc, <font CLASS=keyword>const</font> string&amp; s){ <font CLASS=keyword>return</font> s <font CLASS=symbols>!=</font> sc; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keytype>char</font> c, <font CLASS=keyword>const</font> string&amp; s) { <font CLASS=keyword>return</font> s <font CLASS=symbols>!=</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string&amp; s) { s.initialize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string&amp; s, <font CLASS=keyword>const</font> string&amp; s1) { s.initialize(s1); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(string&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s1) { s.initialize(s1); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> finalize(string&amp; s) { s.finalize(); }
<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> stralloc;
<font CLASS=keyword>extern</font> string nullstring;
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- string utilities ----------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
string fill(<font CLASS=keytype>int</font> width, <font CLASS=keytype>char</font> pad);
string pad(<font CLASS=keyword>const</font> string&amp; s, <font CLASS=keytype>int</font> width, <font CLASS=keytype>char</font> c, <font CLASS=keytype>bool</font> left <font CLASS=symbols>=</font> <font CLASS=keyword>true</font>);
string itostring(large value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(ularge value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(<font CLASS=keytype>int</font> value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(<font CLASS=keytype>unsigned</font> value, <font CLASS=keytype>int</font> base, <font CLASS=keytype>int</font> width <font CLASS=symbols>=</font> <font CLASS=integer>0</font>, <font CLASS=keytype>char</font> pad <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
string itostring(large v);
string itostring(ularge v);
string itostring(<font CLASS=keytype>int</font> v);
string itostring(<font CLASS=keytype>unsigned</font> v);
large stringtoi(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
large stringtoie(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
ularge stringtoue(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*, <font CLASS=keytype>int</font> base);
string lowercase(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* s);
string lowercase(<font CLASS=keyword>const</font> string&amp; s);
<font CLASS=keytype>char</font> hex4(<font CLASS=keytype>char</font> c);
<font CLASS=keyword>inline</font> <font CLASS=keytype>char</font> locase(<font CLASS=keytype>char</font> c)
{ <font CLASS=keyword>if</font> (c &gt;<font CLASS=symbols>=</font> <font CLASS=sinquot>'A'</font> &amp;&amp; c &lt;<font CLASS=symbols>=</font> <font CLASS=sinquot>'Z'</font>) <font CLASS=keyword>return</font> <font CLASS=keytype>char</font>(c + <font CLASS=integer>32</font>); <font CLASS=keyword>return</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>char</font> upcase(<font CLASS=keytype>char</font> c)
{ <font CLASS=keyword>if</font> (c &gt;<font CLASS=symbols>=</font> <font CLASS=sinquot>'a'</font> &amp;&amp; c &lt;<font CLASS=symbols>=</font> <font CLASS=sinquot>'z'</font>) <font CLASS=keyword>return</font> <font CLASS=keytype>char</font>(c - <font CLASS=integer>32</font>); <font CLASS=keyword>return</font> c; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> hstrlen(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* p) <font CLASS=comment>// some Unix systems do not accept NULL</font>
{ <font CLASS=keyword>return</font> p <font CLASS=symbols>==</font> nil ? <font CLASS=integer>0</font> : (<font CLASS=keytype>int</font>)strlen(p); }
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- character set -------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> _csetbits <font CLASS=symbols>=</font> <font CLASS=integer>256</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> _csetbytes <font CLASS=symbols>=</font> _csetbits / <font CLASS=integer>8</font>;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> _csetwords <font CLASS=symbols>=</font> _csetbytes / <font CLASS=keyword>sizeof</font>(<font CLASS=keytype>int</font>);
<font CLASS=keyword>const</font> <font CLASS=keytype>char</font> _csetesc <font CLASS=symbols>=</font> <font CLASS=sinquot>'~'</font>;
<font CLASS=keyword>class</font> cset
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>char</font> data[_csetbytes];
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> cset&amp; s) { memcpy(data, s.data, _csetbytes); }
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit);
<font CLASS=keytype>void</font> clear() { memset(data, <font CLASS=integer>0</font>, _csetbytes); }
<font CLASS=keytype>void</font> fill() { memset(data, <font CLASS=symbols>-</font><font CLASS=integer>1</font>, _csetbytes); }
<font CLASS=keytype>void</font> include(<font CLASS=keytype>char</font> b) { data[uchar(b) / <font CLASS=integer>8</font>] <font CLASS=symbols>|=</font> uchar(<font CLASS=integer>1</font> &lt;&lt; (uchar(b) % <font CLASS=integer>8</font>)); }
<font CLASS=keytype>void</font> include(<font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max);
<font CLASS=keytype>void</font> exclude(<font CLASS=keytype>char</font> b) { data[uchar(b) / <font CLASS=integer>8</font>] &amp;<font CLASS=symbols>=</font> uchar(~(<font CLASS=integer>1</font> &lt;&lt; (uchar(b) % <font CLASS=integer>8</font>))); }
<font CLASS=keytype>void</font> unite(<font CLASS=keyword>const</font> cset&amp; s);
<font CLASS=keytype>void</font> subtract(<font CLASS=keyword>const</font> cset&amp; s);
<font CLASS=keytype>void</font> intersect(<font CLASS=keyword>const</font> cset&amp; s);
<font CLASS=keytype>void</font> invert();
<font CLASS=keytype>bool</font> contains(<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (data[uchar(b) / <font CLASS=integer>8</font>] &amp; (<font CLASS=integer>1</font> &lt;&lt; (uchar(b) % <font CLASS=integer>8</font>))) <font CLASS=symbols>!=</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>bool</font> eq(<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> memcmp(data, s.data, _csetbytes) <font CLASS=symbols>==</font> <font CLASS=integer>0</font>; }
<font CLASS=keytype>bool</font> le(<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font>;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
cset() { clear(); }
cset(<font CLASS=keyword>const</font> cset&amp; s) { assign(s); }
cset(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit) { assign(setinit); }
cset&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset&amp; s) { assign(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keyword>const</font> cset&amp; s) { unite(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>+=</font> (<font CLASS=keytype>char</font> b) { include(b); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t += s; }
cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t += b; }
cset&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>-=</font> (<font CLASS=keyword>const</font> cset&amp; s) { subtract(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>-=</font> (<font CLASS=keytype>char</font> b) { exclude(b); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset <font CLASS=keyword>operator</font><font CLASS=symbols>-</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t -= s; }
cset <font CLASS=keyword>operator</font><font CLASS=symbols>-</font> (<font CLASS=keytype>char</font> b) <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t -= b; }
cset&amp; <font CLASS=keyword>operator</font>*<font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset&amp; s) { intersect(s); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
cset <font CLASS=keyword>operator</font>* (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; <font CLASS=keyword>return</font> t *<font CLASS=symbols>=</font> s; }
cset <font CLASS=keyword>operator</font><font CLASS=symbols>!</font> () <font CLASS=keyword>const</font> { cset t <font CLASS=symbols>=</font> *<font CLASS=keyword>this</font>; t.invert(); <font CLASS=keyword>return</font> t; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> eq(s); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> !eq(s); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>&lt;<font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> le(s); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>&gt;<font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> cset&amp; s) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> s.le(*<font CLASS=keyword>this</font>); }
<font CLASS=keyword>friend</font> cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>&amp; (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> assign(cset&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> clear(cset&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> fill(cset&amp; s);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> include(cset&amp; s, <font CLASS=keytype>char</font> b);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> include(cset&amp; s, <font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> exclude(cset&amp; s, <font CLASS=keytype>char</font> b);
<font CLASS=keyword>friend</font> string asstring(<font CLASS=keyword>const</font> cset&amp; s);
};
<font CLASS=keyword>inline</font> cset <font CLASS=keyword>operator</font><font CLASS=symbols>+</font> (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset&amp; s) { <font CLASS=keyword>return</font> s <font CLASS=symbols>+</font> b; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font>&amp; (<font CLASS=keytype>char</font> b, <font CLASS=keyword>const</font> cset&amp; s) { <font CLASS=keyword>return</font> s.contains(b); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> assign(cset&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* setinit) { s.assign(setinit); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(cset&amp; s) { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> fill(cset&amp; s) { s.fill(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> include(cset&amp; s, <font CLASS=keytype>char</font> b) { s.include(b); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> include(cset&amp; s, <font CLASS=keytype>char</font> min, <font CLASS=keytype>char</font> max) { s.include(min, max); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> exclude(cset&amp; s, <font CLASS=keytype>char</font> b) { s.exclude(b); }
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- basic abstract classes ----------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// basic class with virtual destructor; historically was used as a base</font>
<font CLASS=comment>// for all list items. also helps to count the number of created and</font>
<font CLASS=comment>// destroyed objects in a program (objalloc global) in DEBUG mode, to</font>
<font CLASS=comment>// detect memory leaks. most classes in ptypes are derived from unknown.</font>
<font CLASS=keyword>extern</font> <font CLASS=keytype>int</font> objalloc;
<font CLASS=keyword>class</font> unknown
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
// make all classes non-copyable by <font CLASS=keyword>default</font>
unknown(<font CLASS=keyword>const</font> unknown&amp;);
<font CLASS=keyword>const</font> unknown&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> unknown&amp;);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
<font CLASS=preproc>#ifdef</font> COUNT_OBJALLOC
unknown() { pincrement(&amp;objalloc); }
<font CLASS=keyword>virtual</font> ~unknown() { pdecrement(&amp;objalloc); }
<font CLASS=preproc>#else</font>
unknown() { }
<font CLASS=keyword>virtual</font> ~unknown() { }
<font CLASS=preproc>#endif</font>
};
<font CLASS=keyword>typedef</font> unknown* punknown;
<font CLASS=comment>// provide non-copyable base for all classes that are</font>
<font CLASS=comment>// not derived from 'unknown'</font>
<font CLASS=keyword>class</font> noncopyable
{
<font CLASS=preproc><font CLASS=keyword>private</font>:</font>
noncopyable(<font CLASS=keyword>const</font> noncopyable&amp;);
<font CLASS=keyword>const</font> noncopyable&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> noncopyable&amp;);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
noncopyable() {}
~noncopyable() {}
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- exception ------------------------------------------------------ //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// the basic exception class. NOTE: the library always throws dynamically</font>
<font CLASS=comment>// allocated exception objects.</font>
<font CLASS=keyword>class</font> exception: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
string message;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
exception(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* imsg);
exception(<font CLASS=keyword>const</font> string&amp; imsg);
<font CLASS=keyword>virtual</font> ~exception();
<font CLASS=keyword>virtual</font> string get_message() { <font CLASS=keyword>return</font> message; }
};
<font CLASS=comment>// conversion exception class for stringtoie() and stringtoue()</font>
<font CLASS=keyword>class</font> econv: public exception
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
econv(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg): exception(msg) {}
econv(<font CLASS=keyword>const</font> string&amp; msg): exception(msg) {}
<font CLASS=keyword>virtual</font> ~econv();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tpodlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// _podlist implements dynamic array of small POD structures; it serves</font>
<font CLASS=comment>// as a basis for all list types in the library. this class is undocumented.</font>
<font CLASS=comment>// tpodlist template must be used instead.</font>
<font CLASS=keyword>class</font> _podlist: public noncopyable
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>void</font>* list; <font CLASS=comment>// pointer to the array</font>
<font CLASS=keytype>int</font> count; <font CLASS=comment>// number of items in the list</font>
<font CLASS=keytype>int</font> capacity; <font CLASS=comment>// allocated for the list</font>
<font CLASS=keytype>int</font> itemsize; <font CLASS=comment>// list item size</font>
<font CLASS=keytype>static</font> <font CLASS=keytype>void</font> idxerror();
_podlist&amp; <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> _podlist&amp; t);
<font CLASS=keytype>void</font> grow();
<font CLASS=keytype>void</font>* doins(<font CLASS=keytype>int</font> index);
<font CLASS=keytype>void</font> doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> _podlist&amp;);
<font CLASS=keytype>void</font>* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (<font CLASS=keytype>char</font>*)list <font CLASS=symbols>+</font> index * itemsize; }
<font CLASS=keytype>void</font> dodel(<font CLASS=keytype>int</font> index);
<font CLASS=keytype>void</font> dodel(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>void</font> dopop();
<font CLASS=preproc>#ifdef</font> CHECK_BOUNDS
<font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) &gt;<font CLASS=symbols>=</font> <font CLASS=keytype>unsigned</font>(count)) idxerror(); }
<font CLASS=keytype>void</font> idxa(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>if</font> (<font CLASS=keytype>unsigned</font>(index) &gt; <font CLASS=keytype>unsigned</font>(count)) idxerror(); }
<font CLASS=preproc>#else</font>
<font CLASS=keytype>void</font> idx(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font> { }
<font CLASS=keytype>void</font> idxa(<font CLASS=keytype>int</font>) <font CLASS=keyword>const</font> { }
<font CLASS=preproc>#endif</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
_podlist(<font CLASS=keytype>int</font> itemsize);
~_podlist();
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> count; }
<font CLASS=keytype>void</font> set_count(<font CLASS=keytype>int</font> newcount, <font CLASS=keytype>bool</font> zero <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keytype>int</font> get_capacity() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> capacity; }
<font CLASS=keytype>void</font> set_capacity(<font CLASS=keytype>int</font> newcap);
<font CLASS=keytype>void</font> clear() { set_count(<font CLASS=integer>0</font>); }
<font CLASS=keytype>void</font> pack() { set_capacity(count); }
<font CLASS=keytype>void</font>* ins(<font CLASS=keytype>int</font> index) { idxa(index); <font CLASS=keyword>return</font> doins(index); }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> _podlist&amp; t) { idxa(index); doins(index, t); }
<font CLASS=keytype>void</font>* add();
<font CLASS=keytype>void</font> add(<font CLASS=keyword>const</font> _podlist&amp; t);
<font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) { idx(index); <font CLASS=keyword>return</font> doget(index); }
<font CLASS=keytype>void</font>* top() { <font CLASS=keyword>return</font> <font CLASS=keyword>operator</font> [](count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index) { idx(index); dodel(index); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count) { idx(index); dodel(index, count); }
<font CLASS=keytype>void</font> pop() { idx(<font CLASS=integer>0</font>); dopop(); }
};
<font CLASS=comment>// tpodlist is a fully-inlined template based on _podlist</font>
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X, <font CLASS=keytype>bool</font> initzero <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>&gt; <font CLASS=keyword>class</font> tpodlist: <font CLASS=keyword>public</font> _podlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
X&amp; dozero(X&amp; t) { <font CLASS=keyword>if</font> (initzero) memset(&amp;t, <font CLASS=integer>0</font>, <font CLASS=keyword>sizeof</font>(X)); <font CLASS=keyword>return</font> t; }
X&amp; doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ((X*)list)[index]; }
X&amp; doins(<font CLASS=keytype>int</font> index) { X&amp; t <font CLASS=symbols>=</font> *(X*)_podlist::doins(index); <font CLASS=keyword>return</font> dozero(t); }
<font CLASS=keytype>void</font> doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> X&amp; item) { *(X*)_podlist::doins(index) <font CLASS=symbols>=</font> item; }
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
tpodlist(): _podlist(<font CLASS=keyword>sizeof</font>(X)) {}
tpodlist&lt;X, initzero&gt;&amp; <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> tpodlist&lt;X, initzero&gt;&amp; t)
{ _podlist::<font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(t); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
<font CLASS=keytype>void</font> set_count(<font CLASS=keytype>int</font> newcount) { _podlist::set_count(newcount, initzero); }
X&amp; ins(<font CLASS=keytype>int</font> index) { idxa(index); <font CLASS=keyword>return</font> doins(index); }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> X&amp; item) { idxa(index); doins(index, item); }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> tpodlist&lt;X, initzero&gt;&amp; t)
{ _podlist::ins(index, t); }
X&amp; add() { grow(); <font CLASS=keyword>return</font> dozero(doget(count<font CLASS=symbols>++</font>)); }
<font CLASS=keytype>void</font> add(<font CLASS=keyword>const</font> X&amp; item) { grow(); doget(count<font CLASS=symbols>++</font>) <font CLASS=symbols>=</font> item; }
<font CLASS=keytype>void</font> add(<font CLASS=keyword>const</font> tpodlist&lt;X, initzero&gt;&amp; t)
{ _podlist::add(t); }
X&amp; <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) { idx(index); <font CLASS=keyword>return</font> doget(index); }
<font CLASS=keyword>const</font> X&amp; <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> doget(index); }
X&amp; top() { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> doget(count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tobjlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// _objlist is a base for the tobjlist template, don't use it directly.</font>
<font CLASS=comment>// also, _objlist is a base for _strlist and derivatives.</font>
<font CLASS=keyword>class</font> _objlist: public unknown, <font CLASS=keyword>protected</font> tpodlist&lt;<font CLASS=keytype>void</font>*, <font CLASS=keyword>true</font>&gt;
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>struct</font>
{
<font CLASS=keytype>unsigned</font> ownobjects :<font CLASS=integer>1</font>; <font CLASS=comment>// list is responsible for destroying the items; used in _objlist</font>
<font CLASS=keytype>unsigned</font> ownslobjects :<font CLASS=integer>1</font>; <font CLASS=comment>// same but for _strlist items (in _stritem structure)</font>
<font CLASS=keytype>unsigned</font> sorted :<font CLASS=integer>1</font>; <font CLASS=comment>// sorted list (_objlist+)</font>
<font CLASS=keytype>unsigned</font> duplicates :<font CLASS=integer>1</font>; <font CLASS=comment>// sorted: allows duplicate keys (_objlist+)</font>
<font CLASS=keytype>unsigned</font> casesens :<font CLASS=integer>1</font>; <font CLASS=comment>// sorted: string comparison is case sensitive (_strlist+)</font>
<font CLASS=keytype>unsigned</font> _reserved :<font CLASS=integer>27</font>;
} config;
_objlist(bool ownobjects); <font CLASS=comment>// we hide this ctor, since _objlist actually can't free objects</font>
<font CLASS=keytype>void</font>* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ((<font CLASS=keytype>void</font>**)list)[index]; }
<font CLASS=keytype>void</font> doput(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj);
<font CLASS=keytype>void</font> dodel(<font CLASS=keytype>int</font> index);
<font CLASS=keytype>void</font> dodel(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);
<font CLASS=keytype>void</font>* dopop();
<font CLASS=keytype>void</font> dofree(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* obj); <font CLASS=comment>// pure method; defined in tobjlist instances</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>; <font CLASS=comment>// pure method; defined in _strlist</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
_objlist();
<font CLASS=keyword>virtual</font> ~_objlist();
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> count; }
<font CLASS=keytype>void</font> set_count(<font CLASS=keytype>int</font> newcount);
<font CLASS=keytype>int</font> get_capacity() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> capacity; }
<font CLASS=keytype>void</font> set_capacity(<font CLASS=keytype>int</font> newcap) { tpodlist&lt;<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>&gt;::set_capacity(newcap); }
<font CLASS=keytype>void</font> clear() { set_count(<font CLASS=integer>0</font>); }
<font CLASS=keytype>void</font> pack() { tpodlist&lt;<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>&gt;::pack(); }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj) { tpodlist&lt;<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>&gt;::ins(index, obj); }
<font CLASS=keytype>void</font> add(<font CLASS=keytype>void</font>* obj) { tpodlist&lt;<font CLASS=keytype>void</font>*,<font CLASS=keyword>true</font>&gt;::add(obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj) { idx(index); doput(index, obj); }
<font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> doget(index); }
<font CLASS=keytype>void</font>* top() <font CLASS=keyword>const</font> { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> doget(count <font CLASS=symbols>-</font> <font CLASS=integer>1</font>); }
<font CLASS=keytype>void</font>* pop() { idx(<font CLASS=integer>0</font>); <font CLASS=keyword>return</font> dopop(); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index) { idx(index); dodel(index); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> count) { idx(index); dodel(index, count); }
<font CLASS=keytype>int</font> indexof(<font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>;
<font CLASS=keytype>bool</font> search(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keytype>int</font>&amp; index) <font CLASS=keyword>const</font>;
};
<font CLASS=comment>// the tobjlist template implements a list of pointers to arbitrary</font>
<font CLASS=comment>// structures. optionally can automatically free objects (ownobjects)</font>
<font CLASS=comment>// when removed from a list. only 2 virtual functions are being</font>
<font CLASS=comment>// instantiated by this template, the rest is static code in _objlist.</font>
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; <font CLASS=keyword>class</font> tobjlist: <font CLASS=keyword>public</font> _objlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
X* doget(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (X*)_objlist::doget(index); }
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* obj);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
tobjlist(<font CLASS=keytype>bool</font> ownobjects <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>): _objlist(ownobjects) {}
<font CLASS=keyword>virtual</font> ~tobjlist();
<font CLASS=keytype>bool</font> get_ownobjects() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> config.ownobjects; }
<font CLASS=keytype>void</font> set_ownobjects(<font CLASS=keytype>bool</font> newval) { config.ownobjects <font CLASS=symbols>=</font> newval; }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, X* obj) { _objlist::ins(index, obj); }
<font CLASS=keytype>void</font> add(X* obj) { _objlist::add(obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, X* obj) { _objlist::put(index, obj); }
X* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> (X*)doget(index); }
X* top() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (X*)_objlist::top(); }
X* pop() { <font CLASS=keyword>return</font> (X*)_objlist::pop(); }
<font CLASS=keytype>int</font> indexof(X* obj) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> _objlist::indexof(obj); }
<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(tobjlist&amp; s, <font CLASS=keytype>int</font> i, X* obj) { s.ins(i, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> add(tobjlist&amp; s, X* obj) { s.add(obj); <font CLASS=keyword>return</font> s.get_count() <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tobjlist&amp; s, <font CLASS=keytype>int</font> i, X* obj) { s.put(i, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> tobjlist&amp; s, X* obj) { <font CLASS=keyword>return</font> s.indexof(obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> push(tobjlist&amp; s, X* obj) { s.add(obj); <font CLASS=keyword>return</font> s.get_count() <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* pop(tobjlist&amp; s) { <font CLASS=keyword>return</font> (X*)s.pop(); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* top(<font CLASS=keyword>const</font> tobjlist&amp; s) { <font CLASS=keyword>return</font> (X*)s.top(); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* get(<font CLASS=keyword>const</font> tobjlist&amp; s, <font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> (X*)s[i]; }
<font CLASS=preproc>#endif</font>
};
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; <font CLASS=keytype>void</font> tobjlist&lt;X&gt;::dofree(<font CLASS=keytype>void</font>* item)
{
<font CLASS=keyword>delete</font> (X*)item;
}
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; tobjlist&lt;X&gt;::~tobjlist()
{
set_count(<font CLASS=integer>0</font>);
}
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- tstrlist ------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// _strlist is a base for the tstrlist template</font>
<font CLASS=keyword>typedef</font> <font CLASS=keytype>int</font> slflags; <font CLASS=comment>// left for compatibility</font>
<font CLASS=preproc>#define</font> SL_SORTED <font CLASS=integer>1</font>
<font CLASS=preproc>#define</font> SL_DUPLICATES <font CLASS=integer>2</font>
<font CLASS=preproc>#define</font> SL_CASESENS <font CLASS=integer>4</font>
<font CLASS=preproc>#define</font> SL_OWNOBJECTS <font CLASS=integer>8</font>
<font CLASS=keyword>struct</font> _stritem
{
string key;
<font CLASS=keytype>void</font>* obj;
_stritem(<font CLASS=keyword>const</font> string&amp; ikey, <font CLASS=keytype>void</font>* iobj)
: key(ikey), obj(iobj) {}
};
<font CLASS=keyword>class</font> _strlist: <font CLASS=keyword>protected</font> tobjlist&lt;_stritem&gt;
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>static</font> <font CLASS=keytype>void</font> sortederror();
<font CLASS=keytype>static</font> <font CLASS=keytype>void</font> notsortederror();
<font CLASS=keytype>static</font> <font CLASS=keytype>void</font> duperror();
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofree(<font CLASS=keytype>void</font>* item);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* item) <font CLASS=keyword>const</font>;
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofreeobj(<font CLASS=keytype>void</font>* obj); <font CLASS=comment>// pure; tstrlist overrides it</font>
<font CLASS=keyword>const</font> string&amp; dogetkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>&gt;key; }
<font CLASS=keytype>void</font>* dogetobj(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>&gt;obj; }
<font CLASS=keytype>void</font> doins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj);
<font CLASS=keytype>void</font> doput(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj);
<font CLASS=keytype>void</font> doput(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
_strlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=keyword>virtual</font> ~_strlist();
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> count; }
<font CLASS=keytype>void</font> set_count(<font CLASS=keytype>int</font> newcount) { tobjlist&lt;_stritem&gt;::set_count(newcount); }
<font CLASS=keytype>int</font> get_capacity() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> capacity; }
<font CLASS=keytype>void</font> set_capacity(<font CLASS=keytype>int</font> newcap) { tobjlist&lt;_stritem&gt;::set_capacity(newcap); }
<font CLASS=keytype>void</font> clear() { tobjlist&lt;_stritem&gt;::clear(); }
<font CLASS=keytype>void</font> pack() { tobjlist&lt;_stritem&gt;::pack(); }
<font CLASS=keytype>bool</font> get_sorted() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> config.sorted; }
<font CLASS=keytype>bool</font> get_duplicates() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> config.duplicates; }
<font CLASS=keytype>bool</font> get_casesens() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> config.casesens; }
<font CLASS=keytype>bool</font> get_ownobjects() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> config.ownslobjects; }
<font CLASS=keytype>void</font> set_ownobjects(<font CLASS=keytype>bool</font> newval) { config.ownslobjects <font CLASS=symbols>=</font> newval; }
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj) { idxa(index); doins(index, key, obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj) { idx(index); doput(index, key, obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, <font CLASS=keytype>void</font>* obj) { idx(index); doput(index, obj); }
<font CLASS=keytype>int</font> put(<font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj);
<font CLASS=keytype>int</font> add(<font CLASS=keyword>const</font> string&amp; key, <font CLASS=keytype>void</font>* obj);
<font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> dogetobj(index); }
<font CLASS=keytype>void</font>* <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
<font CLASS=keyword>const</font> string&amp; getkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> dogetkey(index); }
<font CLASS=keytype>bool</font> search(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key, <font CLASS=keytype>int</font>&amp; index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> _objlist::search(key, index); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index) { idx(index); dodel(index); }
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index, <font CLASS=keytype>int</font> delcount) { idx(index); dodel(index, delcount); }
<font CLASS=keytype>void</font> del(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) { put(key, nil); }
<font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
<font CLASS=keytype>int</font> indexof(<font CLASS=keytype>void</font>* obj) <font CLASS=keyword>const</font>;
};
<font CLASS=comment>// the tstrlist template implements a list of string/object pairs,</font>
<font CLASS=comment>// optionally sorted for fast searching by string key.</font>
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; <font CLASS=keyword>class</font> tstrlist: <font CLASS=keyword>public</font> _strlist
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> dofreeobj(<font CLASS=keytype>void</font>* obj);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
tstrlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>): _strlist(flags) {}
<font CLASS=keyword>virtual</font> ~tstrlist();
<font CLASS=keytype>void</font> ins(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, X* obj) { _strlist::ins(index, key, obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> string&amp; key, X* obj) { _strlist::put(index, key, obj); }
<font CLASS=keytype>void</font> put(<font CLASS=keytype>int</font> index, X* obj) { _strlist::put(index, obj); }
<font CLASS=keytype>int</font> put(<font CLASS=keyword>const</font> string&amp; key, X* obj) { <font CLASS=keyword>return</font> _strlist::put(key, obj); }
<font CLASS=keytype>int</font> add(<font CLASS=keyword>const</font> string&amp; key, X* obj) { <font CLASS=keyword>return</font> _strlist::add(key, obj); }
X* <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (X*)_strlist::<font CLASS=keyword>operator</font> [](index); }
X* <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (X*)_strlist::<font CLASS=keyword>operator</font> [](key); }
<font CLASS=keytype>int</font> indexof(X* obj) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> _strlist::indexof(obj); }
<font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> _strlist::indexof(key); }
<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT
// pre<font CLASS=symbols>-</font><font CLASS=floatpt>2.0</font> interface <font CLASS=keyword>for</font> backwards compatibility
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(tstrlist&amp; s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string&amp; str, X* obj) { s.ins(i, str, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> add(tstrlist&amp; s, <font CLASS=keyword>const</font> string&amp; str, X* obj) { <font CLASS=keyword>return</font> s.add(str, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrlist&amp; s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string&amp; str, X* obj) { s.put(i, str, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrlist&amp; s, <font CLASS=keytype>int</font> i, X* obj) { s.put(i, obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> tstrlist&amp; s, X* obj) { <font CLASS=keyword>return</font> s.indexof(obj); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* get(<font CLASS=keyword>const</font> tstrlist&amp; s, <font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> (X*)s[i]; }
<font CLASS=preproc>#endif</font>
};
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; <font CLASS=keytype>void</font> tstrlist&lt;X&gt;::dofreeobj(<font CLASS=keytype>void</font>* obj)
{
<font CLASS=keyword>delete</font> (X*)obj;
}
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; tstrlist&lt;X&gt;::~tstrlist()
{
set_count(<font CLASS=integer>0</font>);
}
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- textmap -------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// textmap is a list of string pairs (key/value)</font>
<font CLASS=keyword>struct</font> _textitem
{
string key;
string value;
_textitem(<font CLASS=keyword>const</font> string&amp; ikey, <font CLASS=keyword>const</font> string&amp; ivalue)
: key(ikey), value(ivalue) {}
};
<font CLASS=keyword>class</font> textmap: <font CLASS=keyword>protected</font> tobjlist&lt;_textitem&gt;
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> compare(<font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* key, <font CLASS=keyword>const</font> <font CLASS=keytype>void</font>* item) <font CLASS=keyword>const</font>;
<font CLASS=keyword>const</font> string&amp; dogetvalue(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>&gt;value; }
<font CLASS=keyword>const</font> string&amp; dogetkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> doget(index)<font CLASS=symbols>-</font>&gt;key; }
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
textmap(<font CLASS=keytype>bool</font> casesens <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keyword>virtual</font> ~textmap();
<font CLASS=keytype>int</font> get_count() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> tobjlist&lt;_textitem&gt;::get_count(); }
<font CLASS=keytype>void</font> pack() { tobjlist&lt;_textitem&gt;::pack(); }
<font CLASS=keytype>void</font> clear() { tobjlist&lt;_textitem&gt;::clear(); }
<font CLASS=keytype>int</font> put(<font CLASS=keyword>const</font> string&amp; key, <font CLASS=keyword>const</font> string&amp; value);
<font CLASS=keytype>void</font> del(<font CLASS=keytype>int</font> index) { idx(index); dodel(index); }
<font CLASS=keytype>void</font> del(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) { put(key, nullstring); }
<font CLASS=keyword>const</font> string&amp; get(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> dogetvalue(index); }
<font CLASS=keyword>const</font> string&amp; getkey(<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { idx(index); <font CLASS=keyword>return</font> dogetkey(index); }
<font CLASS=keyword>const</font> string&amp; get(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
<font CLASS=keyword>const</font> string&amp; <font CLASS=keyword>operator</font> [](<font CLASS=keytype>int</font> index) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get(index); }
<font CLASS=keyword>const</font> string&amp; <font CLASS=keyword>operator</font> [](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get(key); }
<font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font>;
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- component ------------------------------------------------------ //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// the component class is an abstract class that provides reference</font>
<font CLASS=comment>// counting and delete notification mechanisms. all stream classes</font>
<font CLASS=comment>// in ptypes are derived from component.</font>
<font CLASS=comment>// class ID's for all basic types: the first byte (least significant)</font>
<font CLASS=comment>// contains the base ID, the next is for the second level of inheritance,</font>
<font CLASS=comment>// etc. total of 4 levels allowed for basic types. call classid() for an</font>
<font CLASS=comment>// object, mask out first N bytes of interest and compare with a CLASS_XXX</font>
<font CLASS=comment>// value. f.ex. to determine whether an object is of type infile or any</font>
<font CLASS=comment>// derivative: (o-&gt;classid() &amp; 0xffff) == CLASS2_INFILE. this scheme is for</font>
<font CLASS=comment>// internal use by PTypes and Objection; partly replaces the costly C++ RTTI</font>
<font CLASS=comment>// system.</font>
<font CLASS=comment>// first level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_UNDEFINED <font CLASS=symbols>=</font> 0x00000000;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_INSTM <font CLASS=symbols>=</font> 0x00000001;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_OUTSTM <font CLASS=symbols>=</font> 0x00000002;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS_UNIT <font CLASS=symbols>=</font> 0x00000003;
<font CLASS=comment>// second level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_INFILE <font CLASS=symbols>=</font> 0x00000100 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_INMEMORY <font CLASS=symbols>=</font> 0x00000200 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_FDX <font CLASS=symbols>=</font> 0x00000300 <font CLASS=symbols>|</font> CLASS_INSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_OUTFILE <font CLASS=symbols>=</font> 0x00000100 <font CLASS=symbols>|</font> CLASS_OUTSTM;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS2_OUTMEMORY <font CLASS=symbols>=</font> 0x00000200 <font CLASS=symbols>|</font> CLASS_OUTSTM;
<font CLASS=comment>// third level of inheritance</font>
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_LOGFILE <font CLASS=symbols>=</font> 0x00010000 <font CLASS=symbols>|</font> CLASS2_OUTFILE;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_IPSTM <font CLASS=symbols>=</font> 0x00020000 <font CLASS=symbols>|</font> CLASS2_FDX;
<font CLASS=keyword>const</font> <font CLASS=keytype>int</font> CLASS3_NPIPE <font CLASS=symbols>=</font> 0x00030000 <font CLASS=symbols>|</font> CLASS2_FDX;
<font CLASS=keyword>class</font> component: public unknown
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> refcount; <font CLASS=comment>// reference counting, used by addref() and release()</font>
tobjlist&lt;component&gt;* freelist; <font CLASS=comment>// list of components to notify about destruction, safer alternative to ref-counting</font>
<font CLASS=keytype>void</font>* typeinfo; <font CLASS=comment>// reserved for future use</font>
<font CLASS=keyword>virtual</font> <font CLASS=keytype>void</font> freenotify(component* sender);
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
component();
<font CLASS=keyword>virtual</font> ~component();
<font CLASS=keytype>void</font> addnotification(component* obj);
<font CLASS=keytype>void</font> delnotification(component* obj);
<font CLASS=keyword>friend</font> component* addref(component*);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> release(component*);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> refcount(component* c);
<font CLASS=keyword>virtual</font> <font CLASS=keytype>int</font> classid();
<font CLASS=keytype>void</font> set_typeinfo(<font CLASS=keytype>void</font>* t) { typeinfo <font CLASS=symbols>=</font> t; }
<font CLASS=keytype>void</font>* get_typeinfo() { <font CLASS=keyword>return</font> typeinfo; }
};
<font CLASS=keyword>typedef</font> component* pcomponent;
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> refcount(component* c) { <font CLASS=keyword>return</font> c<font CLASS=symbols>-</font>&gt;refcount; }
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> T&gt; <font CLASS=keyword>inline</font> T* taddref(T* c)
{ <font CLASS=keyword>return</font> (T*)addref((component*)c); }
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> T&gt; <font CLASS=keyword>class</font> compref
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
T* ref;
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
compref() { ref <font CLASS=symbols>=</font> <font CLASS=integer>0</font>; }
compref(<font CLASS=keyword>const</font> compref&lt;T&gt;&amp; r) { ref <font CLASS=symbols>=</font> taddref&lt;T&gt;(r.ref); }
compref(T* c) { ref <font CLASS=symbols>=</font> taddref&lt;T&gt;(c); }
~compref() { release(ref); }
compref&lt;T&gt;&amp; <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(T* c);
compref&lt;T&gt;&amp; <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(<font CLASS=keyword>const</font> compref&lt;T&gt;&amp; r) { <font CLASS=keyword>return</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(r.ref); }
T&amp; <font CLASS=keyword>operator</font> *() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> *ref; }
T* <font CLASS=keyword>operator</font> <font CLASS=symbols>-</font>&gt;() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>==</font>(<font CLASS=keyword>const</font> compref&lt;T&gt;&amp; r) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>==</font> r.ref; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>==</font>(T* c) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>==</font> c; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>!=</font>(<font CLASS=keyword>const</font> compref&lt;T&gt;&amp; r) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>!=</font> r.ref; }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font> <font CLASS=symbols>!=</font>(T* c) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref <font CLASS=symbols>!=</font> c; }
<font CLASS=keyword>operator</font> T*() <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> ref; }
};
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> T&gt; compref&lt;T&gt;&amp; compref&lt;T&gt;::<font CLASS=keyword>operator</font> <font CLASS=symbols>=</font>(T* c)
{
release(tpexchange&lt;T&gt;(&amp;ref, taddref&lt;T&gt;(c)));
<font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>;
}
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- variant -------------------------------------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=keyword>enum</font> {
VAR_NULL,
VAR_INT,
VAR_BOOL,
VAR_FLOAT,
VAR_STRING,
VAR_ARRAY,
VAR_OBJECT,
VAR_COMPOUND <font CLASS=symbols>=</font> VAR_STRING
};
<font CLASS=keyword>class</font> _varray;
<font CLASS=keyword>class</font> variant
{
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> string;
<font CLASS=keyword>friend</font> <font CLASS=keyword>class</font> _varray;
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=keytype>int</font> tag; <font CLASS=comment>// VAR_XXX</font>
<font CLASS=keyword>union</font> {
large i; <font CLASS=comment>// 64-bit int value</font>
<font CLASS=keytype>bool</font> b; <font CLASS=comment>// bool value</font>
<font CLASS=keytype>double</font> f; <font CLASS=comment>// double value</font>
char* s; <font CLASS=comment>// string object; can't declare as string because of the union</font>
_varray* a; <font CLASS=comment>// pointer to a reference-counted _strlist object</font>
component* o; <font CLASS=comment>// pointer to a reference-counted component object (or derivative)</font>
} value; <font CLASS=comment>// we need this name to be able to copy the entire union in some situations</font>
<font CLASS=keytype>void</font> initialize() { tag <font CLASS=symbols>=</font> VAR_NULL; }
<font CLASS=keytype>void</font> initialize(large v) { tag <font CLASS=symbols>=</font> VAR_INT; value.i <font CLASS=symbols>=</font> v; }
<font CLASS=keytype>void</font> initialize(<font CLASS=keytype>bool</font> v) { tag <font CLASS=symbols>=</font> VAR_BOOL; value.b <font CLASS=symbols>=</font> v; }
<font CLASS=keytype>void</font> initialize(<font CLASS=keytype>double</font> v) { tag <font CLASS=symbols>=</font> VAR_FLOAT; value.f <font CLASS=symbols>=</font> v; }
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v) { tag <font CLASS=symbols>=</font> VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> string&amp; v) { tag <font CLASS=symbols>=</font> VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
<font CLASS=keytype>void</font> initialize(_varray* a);
<font CLASS=keytype>void</font> initialize(component* o);
<font CLASS=keytype>void</font> initialize(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keytype>void</font> finalize();
<font CLASS=keytype>void</font> assign(large);
<font CLASS=keytype>void</font> assign(<font CLASS=keytype>bool</font>);
<font CLASS=keytype>void</font> assign(<font CLASS=keytype>double</font>);
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>*);
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> string&amp;);
<font CLASS=keytype>void</font> assign(_varray*);
<font CLASS=keytype>void</font> assign(component*);
<font CLASS=keytype>void</font> assign(<font CLASS=keyword>const</font> variant&amp;);
<font CLASS=keytype>bool</font> equal(<font CLASS=keyword>const</font> variant&amp; v) <font CLASS=keyword>const</font>;
variant(_varray* a) { initialize(a); }
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
// construction
variant() { initialize(); }
variant(<font CLASS=keytype>int</font> v) { initialize(large(v)); }
variant(<font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> v) { initialize(large(v)); }
variant(large v) { initialize(v); }
variant(<font CLASS=keytype>bool</font> v) { initialize(v); }
variant(<font CLASS=keytype>double</font> v) { initialize(v); }
variant(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v) { initialize(v); }
variant(<font CLASS=keyword>const</font> string&amp; v) { initialize(v); }
variant(component* v) { initialize(v); }
variant(<font CLASS=keyword>const</font> variant&amp; v) { initialize(v); }
~variant() { finalize(); }
// assignment
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>int</font> v) { assign(large(v)); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> v) { assign(large(v)); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (large v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>bool</font> v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keytype>double</font> v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> string&amp; v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (component* v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
variant&amp; <font CLASS=keyword>operator</font><font CLASS=symbols>=</font> (<font CLASS=keyword>const</font> variant&amp; v) { assign(v); <font CLASS=keyword>return</font> *<font CLASS=keyword>this</font>; }
// typecast
<font CLASS=keyword>operator</font> <font CLASS=keytype>int</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> <font CLASS=keytype>long</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> <font CLASS=keytype>unsigned</font> <font CLASS=keytype>long</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> large() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> <font CLASS=keytype>bool</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> <font CLASS=keytype>double</font>() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> string() <font CLASS=keyword>const</font>;
<font CLASS=keyword>operator</font> component*() <font CLASS=keyword>const</font>;
// comparison
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>==</font> (<font CLASS=keyword>const</font> variant&amp; v) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> equal(v); }
<font CLASS=keytype>bool</font> <font CLASS=keyword>operator</font><font CLASS=symbols>!=</font> (<font CLASS=keyword>const</font> variant&amp; v) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> !equal(v); }
// typification
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> clear(variant&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> vartype(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isnull(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isint(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isbool(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isfloat(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isstring(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isarray(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> isobject(<font CLASS=keyword>const</font> variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> iscompound(<font CLASS=keyword>const</font> variant&amp; v);
// array manipulation
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> aclear(variant&amp;);
<font CLASS=keyword>friend</font> variant aclone(<font CLASS=keyword>const</font> variant&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant&amp; get(<font CLASS=keyword>const</font> variant&amp;, <font CLASS=keyword>const</font> string&amp; key);
<font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant&amp; get(<font CLASS=keyword>const</font> variant&amp;, large key);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> put(variant&amp;, <font CLASS=keyword>const</font> string&amp; key, <font CLASS=keyword>const</font> variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> put(variant&amp;, large key, <font CLASS=keyword>const</font> variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(variant&amp;, <font CLASS=keyword>const</font> string&amp; key);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> del(variant&amp;, large key);
// indexed access to arrays
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> alength(<font CLASS=keyword>const</font> variant&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> apack(variant&amp;);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> anext(<font CLASS=keyword>const</font> variant&amp; a, <font CLASS=keytype>int</font>&amp;, variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>bool</font> anext(<font CLASS=keyword>const</font> variant&amp; a, <font CLASS=keytype>int</font>&amp;, variant&amp; item, string&amp; key);
<font CLASS=keyword>friend</font> <font CLASS=keytype>int</font> aadd(variant&amp;, <font CLASS=keyword>const</font> variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> aput(variant&amp;, <font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> ains(variant&amp;, <font CLASS=keytype>int</font> index, <font CLASS=keyword>const</font> variant&amp; item);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> adel(variant&amp;, <font CLASS=keytype>int</font> index);
<font CLASS=keyword>friend</font> <font CLASS=keyword>const</font> variant&amp; aget(<font CLASS=keyword>const</font> variant&amp;, <font CLASS=keytype>int</font> index);
<font CLASS=keyword>friend</font> string akey(<font CLASS=keyword>const</font> variant&amp;, <font CLASS=keytype>int</font> index);
<font CLASS=keyword>const</font> variant&amp; <font CLASS=keyword>operator</font>[](<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, string(key)); }
<font CLASS=keyword>const</font> variant&amp; <font CLASS=keyword>operator</font>[](<font CLASS=keyword>const</font> string&amp; key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, key); }
<font CLASS=keyword>const</font> variant&amp; <font CLASS=keyword>operator</font>[](large key) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> get(*<font CLASS=keyword>this</font>, key); }
// <font CLASS=sinquot>'manual'</font> initialization/finalization, undocumented. use with care<font CLASS=symbols>!</font>
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, large i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>int</font> i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>bool</font> i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>double</font> i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> string&amp; i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, component* i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> variant&amp; i);
<font CLASS=keyword>friend</font> <font CLASS=keytype>void</font> finalize(variant&amp; v);
};
<font CLASS=keyword>typedef</font> variant* pvariant;
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> vartype(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isnull(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_NULL; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isint(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_INT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isbool(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_BOOL; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isfloat(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_FLOAT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isstring(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_STRING; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isarray(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_ARRAY; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> isobject(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag <font CLASS=symbols>==</font> VAR_OBJECT; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> iscompound(<font CLASS=keyword>const</font> variant&amp; v) { <font CLASS=keyword>return</font> v.tag &gt;<font CLASS=symbols>=</font> VAR_COMPOUND; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v) { v.initialize(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, large i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>int</font> i) { v.initialize(large(i)); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>unsigned</font> <font CLASS=keytype>int</font> i) { v.initialize(large(i)); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>bool</font> i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keytype>double</font> i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> string&amp; i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, component* i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> initialize(variant&amp; v, <font CLASS=keyword>const</font> variant&amp; i) { v.initialize(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> finalize(variant&amp; v) { <font CLASS=keyword>if</font> (v.tag &gt;<font CLASS=symbols>=</font> VAR_COMPOUND) v.finalize(); }
<font CLASS=keyword>extern</font> <font CLASS=keyword>const</font> variant nullvar;
<font CLASS=comment>// variant exception class; may be thrown when a variant</font>
<font CLASS=comment>// is being typecast'ed to 32-bit int and the value is</font>
<font CLASS=comment>// out of range</font>
<font CLASS=keyword>class</font> evariant: public exception
{
<font CLASS=preproc><font CLASS=keyword>protected</font>:</font>
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
evariant(<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* msg): exception(msg) {}
evariant(<font CLASS=keyword>const</font> string&amp; msg): exception(msg) {}
<font CLASS=keyword>virtual</font> ~evariant();
};
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=comment>// --- pre-2.0 compatibility declarations ----------------------------- //</font>
<font CLASS=comment>// -------------------------------------------------------------------- //</font>
<font CLASS=preproc>#ifdef</font> PTYPES19_COMPAT
<font CLASS=comment>// ptypes-1.9 objlist and strlist: accept only 'unknown' and</font>
<font CLASS=comment>// derivatives as a base type</font>
<font CLASS=keyword>class</font> objlist: public tobjlist&lt;unknown&gt;
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
objlist(<font CLASS=keytype>bool</font> ownobjects <font CLASS=symbols>=</font> <font CLASS=keyword>false</font>);
<font CLASS=keyword>virtual</font> ~objlist();
};
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> length(<font CLASS=keyword>const</font> _objlist&amp; s) { <font CLASS=keyword>return</font> s.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> setlength(_objlist&amp; s, <font CLASS=keytype>int</font> newcount) { s.set_count(newcount); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> pack(_objlist&amp; s) { s.pack(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(_objlist&amp; s) { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> push(_objlist&amp; s, unknown* obj) { s.add(obj); <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>inline</font> unknown* top(<font CLASS=keyword>const</font> _objlist&amp; s) { <font CLASS=keyword>return</font> (unknown*)s.top(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(_objlist&amp; s, <font CLASS=keytype>int</font> i, unknown* obj) { s.ins(i, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> add(_objlist&amp; s, unknown* obj) { s.add(obj); <font CLASS=keyword>return</font> length(s) <font CLASS=symbols>-</font> <font CLASS=integer>1</font>; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_objlist&amp; s, <font CLASS=keytype>int</font> i, unknown* obj) { s.put(i, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> _objlist&amp; s, <font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> (unknown*)s[i]; }
<font CLASS=keyword>inline</font> unknown* pop(_objlist&amp; s) { <font CLASS=keyword>return</font> (unknown*)s.pop(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(_objlist&amp; s, <font CLASS=keytype>int</font> i) { s.del(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> _objlist&amp; s, unknown* obj) { <font CLASS=keyword>return</font> s.indexof(obj); }
<font CLASS=keyword>class</font> strlist: public tstrlist&lt;unknown&gt;
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
strlist(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=keyword>virtual</font> ~strlist();
};
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> length(<font CLASS=keyword>const</font> _strlist&amp; s) { <font CLASS=keyword>return</font> s.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(_strlist&amp; s) { s.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> pack(_strlist&amp; s) { s.pack(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>bool</font> search(<font CLASS=keyword>const</font> _strlist&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key, <font CLASS=keytype>int</font>&amp; i) { <font CLASS=keyword>return</font> s.search(key, i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> ins(_strlist&amp; s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string&amp; key, unknown* obj) { s.ins(i, key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> add(_strlist&amp; s, <font CLASS=keyword>const</font> string&amp; key, unknown* obj) { <font CLASS=keyword>return</font> s.add(key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_strlist&amp; s, <font CLASS=keytype>int</font> i, <font CLASS=keyword>const</font> string&amp; key, unknown* obj) { s.put(i, key, obj); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(_strlist&amp; s, <font CLASS=keytype>int</font> i, unknown* obj) { s.put(i, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> _strlist&amp; s, <font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> (unknown*)s[i]; }
<font CLASS=keyword>inline</font> <font CLASS=keyword>const</font> string&amp; getstr(<font CLASS=keyword>const</font> _strlist&amp; s, <font CLASS=keytype>int</font> i) { <font CLASS=keyword>return</font> s.getkey(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(_strlist&amp; s, <font CLASS=keytype>int</font> i) { s.del(i); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> find(<font CLASS=keyword>const</font> _strlist&amp; s, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) { <font CLASS=keyword>return</font> s.indexof(key); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> indexof(<font CLASS=keyword>const</font> _strlist&amp; s, unknown* obj) { <font CLASS=keyword>return</font> s.indexof(obj); }
<font CLASS=comment>// ptypes-1.9 strmap: now replaced with _strlist(SL_SORTED)</font>
<font CLASS=keyword>class</font> strmap: public tstrlist&lt;unknown&gt;
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
strmap(<font CLASS=keytype>int</font> flags <font CLASS=symbols>=</font> <font CLASS=integer>0</font>);
<font CLASS=keyword>virtual</font> ~strmap();
};
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(strmap&amp; m, <font CLASS=keyword>const</font> string&amp; key, unknown* obj) { m.put(key, obj); }
<font CLASS=keyword>inline</font> unknown* get(<font CLASS=keyword>const</font> strmap&amp; m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) { <font CLASS=keyword>return</font> m[key]; }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(strmap&amp; m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* key) { m.del(key); }
<font CLASS=keyword>template</font> &lt;<font CLASS=keyword>class</font> X&gt; <font CLASS=keyword>class</font> tstrmap: <font CLASS=keyword>public</font> strmap
{
<font CLASS=preproc><font CLASS=keyword>public</font>:</font>
tstrmap(): strmap() {}
tstrmap(<font CLASS=keytype>int</font> iflags): strmap(iflags) {}
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> X* get(<font CLASS=keyword>const</font> tstrmap&amp; m, <font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str) { <font CLASS=keyword>return</font> (X*)PTYPES_NAMESPACE::get((<font CLASS=keyword>const</font> strmap&amp;)m, str); }
<font CLASS=keyword>friend</font> <font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(tstrmap&amp; m, <font CLASS=keyword>const</font> string&amp; str, X* obj) { unknown* t <font CLASS=symbols>=</font> obj; PTYPES_NAMESPACE::put(m, str, t); }
X* <font CLASS=keyword>operator</font>[] (<font CLASS=keyword>const</font> <font CLASS=keytype>char</font>* str) <font CLASS=keyword>const</font> { <font CLASS=keyword>return</font> (X*)PTYPES_NAMESPACE::get(*<font CLASS=keyword>this</font>, str); }
};
<font CLASS=comment>// ptypes-1.9 textmap interface</font>
<font CLASS=keyword>inline</font> <font CLASS=keytype>int</font> length(<font CLASS=keyword>const</font> textmap&amp; m) { <font CLASS=keyword>return</font> m.get_count(); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> clear(textmap&amp; m) { m.clear(); }
<font CLASS=keyword>inline</font> <font CLASS=keyword>const</font> string&amp; get(<font CLASS=keyword>const</font> textmap&amp; m, <font CLASS=keyword>const</font> string&amp; k) { <font CLASS=keyword>return</font> m.get(k); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> put(textmap&amp; m, <font CLASS=keyword>const</font> string&amp; k, <font CLASS=keyword>const</font> string&amp; v) { m.put(k, v); }
<font CLASS=keyword>inline</font> <font CLASS=keytype>void</font> del(textmap&amp; m, <font CLASS=keyword>const</font> string&amp; k) { m.del(k); }
<font CLASS=preproc>#endif</font> <font CLASS=comment>// PTYPES19_COMPAT </font>
<font CLASS=preproc>#ifdef</font> _MSC_VER
<font CLASS=preproc>#pragma</font> warning(pop)
<font CLASS=preproc>#pragma</font> pack(pop)
<font CLASS=preproc>#endif</font>
PTYPES_END
<font CLASS=preproc>#endif</font> <font CLASS=comment>// __PTYPES_H__ </font>
</pre>
</div>
<hr noshade></body>
</html>
doc/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<ul>
<li>
<p><a href="intro.html" class="menu">Introduction</a><br>
Main features, change log, compilation, known problems, credits, contacts.</p>
</li>
</ul>
<ul>
<li>
<p><a href="basic.html" class="menu">Basic types</a><br>
Dynamic strings, character sets, variants, date/time manipulation, lists, abstract
classes unknown, component and unit.</p>
</li>
</ul>
<ul>
<li>
<p><a href="streams.html" class="menu">I/O streams</a><br>
Common input/output interfaces, file streams, named pipes, memory streams, standard
input/output/error objects, MD5 stream.</p>
</li>
</ul>
<ul>
<li>
<p><a href="async.html" class="menu">Multithreading</a><br>
Thread, semaphore, mutex, rwlock, trigger message queue and job queue interfaces,
atomic functions and other utilities.</p>
</li>
</ul>
<ul>
<li>
<p><a href="inet.html" class="menu">Networking</a><br>
IP client and server interfaces, utilities.</p>
</li>
</ul>
<ul>
<li>
<p><a href="criterrors.html" class="menu">Exceptions and critical errors</a><br>
Exception classes, non-recoverable errors.</p>
</li>
</ul>
<ul>
<li>
<p><a href="portability.html" class="menu">Portability and performance issues</a></p>
</li>
</ul>
<ul>
<li>
<p><a href="deploying.html" class="menu">Deploying the shared (dynamic) library</a><br>
Static vs. dynamic linking, deploying PTypes with your application, checking the
version of the dynamic library.</p>
</li>
</ul>
<ul>
<li>
<p><a href="wshare.html" class="menu">PTypes demo program -- wshare</a><br>
A simple web server (HTTP daemon) that demonstrates the full power of PTypes.</p>
</li>
</ul>
<ul>
<li>
<p><a href="http://www.melikyan.com/ptypes/doc/ext/"><span class="menu">Library
add-ons, external resources</span></a><br>
Library add-ons and branches, links to external resources. Updated independently
from library releases.</p>
</li>
</ul>
<ul>
<li>
<p><a href="ref.html"><span class="menu">INDEX</span></a><br>
Alphabetical reference of all public symbols defined in the library.</p>
</li>
</ul>
<ul>
<li>
<p><a href="htsrc.html" class="menu">Header files</a><br>
PTypes public header files in browsable (HTML) format.</p>
</li>
</ul>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.examples.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: examples</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
Examples</p>
<p><b><br>
Example 1</b>. A simple IP client that tries to retrieve the main page at www.yahoo.com via an HTTP request. </p>
<blockquote>
<pre>
#include &lt;pinet.h&gt;
USING_PTYPES
int main()
{
ipstream client(&quot;www.yahoo.com&quot;, 80);
try
{
client.open();
<span class="comment">// send a valid HTTP/1.1 request</span>
client.put(&quot;GET / HTTP/1.1\r\n&quot;<br> &quot;Accept: * /*\r\n&quot;<br> &quot;User-Agent: TestAgent/1.0\r\n&quot;<br> &quot;Host: www.yahoo.com\r\n&quot;<br> &quot;Connection: close\r\n\r\n&quot;);
client.flush();
<span class="comment">// receive the response and print it line by line</span>
while (!client.get_eof())
pout.putline(client.line());
client.close();
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
return 0;
}</pre>
</blockquote>
<p><b>Example 2 </b>. This example demonstrates the basic usage of streaming network
interfaces <span class="lang">ipstream</span> and <span class="lang">ipstmserver</span>.
It consists of two programs: test client and test server. The
server handles requests that contain a single word &quot;Hello&quot; by sending
a response greeting back to the client. This example would work for named pipes
as well, i.e. if you replace the class names <span class="lang">ipstream</span>
and <span class="lang">ipstmserver</span> with <span class="lang">namedpipe</span>
and <span class="lang">npserver</span> and fix the construction parameters.</p>
<p><u>Client:</u></p>
<blockquote>
<pre>
#include &lt;pinet.h&gt;
USING_PTYPES
const int testport = 8085;
const int maxtoken = 4096;
int main()
{
<span class="comment">// create a client socket and send a greeting to the server
// assuming that the server is on the same host (127.0.0.1)</span>
ipstream client(ipaddress(127, 0, 0, 1), testport);
try
{
client.open();
pout.put("Sending a request to the server...\n");
client.putline("Hello");
client.flush();
<span class="comment">// receive the response</span>
string rsp = client.line(maxtoken);
pout.putf("Received: %s\n", pconst(rsp));
<span class="comment">// need to close the socket explicitly to gracefully shutdown
// the peer host too. otherwise, ~ipstream() will call cancel()
// and leave the peer in a waiting state (not forever though)</span>.
client.close();
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
return 0;
}</pre>
</blockquote>
<p>&nbsp;</p>
<p><u>Server:</u></p>
<blockquote>
<pre>
#include &lt;ptime.h&gt;
#include &lt;pinet.h&gt;
USING_PTYPES
const int testport = 8085;
const int maxtoken = 4096;
void servermain(ipstmserver&amp; svr)
{
ipstream client;
pout.putf("Ready to answer queries on port %d\n", testport);
while(true)
{
<span class="comment">// serve() will wait for a connection request and will prepare
// the supplied ipstream object for talking to the peer.
// note that (unlikely) exceptions thrown in serve() will be
// caught in main()</span>
svr.serve(client);
<span class="comment">// for better performance the server would start a new thread
// for each client request. for simplicity, we serve the request
// in-place. see multithreading examples for the full multithreaded
// server template.</span>
if (client.get_active())
{
try
{
<span class="comment">// read the request line:
// real-world network applications should limit input data
// to prevent potential denial-of-service attacks</span>
string req = lowercase(client.line(maxtoken));
if (req == "hello")
{
<span class="comment">// try to reverse-lookup the client's IP</span>
string host = phostbyaddr(client.get_ip());
if (isempty(host))
host = iptostring(client.get_ip());
<span class="comment">// now send our greeting to the client</span>
client.putline("Hello, " + host + " ("
+ iptostring(client.get_ip()) + "), nice to see you!");
client.flush();
<span class="comment">// log this request</span>
pout.putf("%t greeting received from %s (%a)\n",
now(), pconst(host), long(client.get_ip()));
}
client.close();
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
}
}
}
int main()
{
ipstmserver svr;
try
{
<span class="comment">// bind to all local addresses on port 8085</span>
svr.bindall(testport);
<span class="comment"> // enter an infinite loop of serving requests</span>
servermain(svr);
}
catch(estream* e)
{
perr.putf("FATAL: %s\n", pconst(e->get_message()));
delete e;
}
return 0;
}
</pre>
</blockquote>
<p><b>Example 3 </b>. This example demonstrates the use of message-oriented networking
interfaces <span class="lang">ipmessage</span> and <span class="lang">ipmsgserver</span>.
The client sends a broadcast message to the local network and waits for a response.
It may retry the request several times.</p>
<p><u>Client:</u></p>
<blockquote>
<pre>
#include &lt;pinet.h&gt;
USING_PTYPES
const int testport = 8085;
const int maxtoken = 4096;
const int tries = 3;
const int firsttimeout = 2000;
bool dorequest(int timeout)
{
ipmessage msg(ipbcast, testport);
try
{
pout.put("Broadcasting a request...\n");
msg.send("Hello");
<span class="comment">// wait for a response the specified amount of time</span>
if (!msg.waitfor(timeout))
return false;
ipaddress src;
string rsp = msg.receive(maxtoken, src);
pout.putf(&quot;Received: '%s' (from %a)\n&quot;, pconst(rsp), long(src));
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
return true;
}
int main()
{
int timeout = firsttimeout;
for (int i = 0; i < tries; i++)
{
if (dorequest(timeout))
break;
<span class="comment">// double the timeout value</span>
timeout *= 2;
}
return 0;
}
</pre>
</blockquote>
<p>&nbsp;</p>
<p><u>Server:</u></p>
<blockquote>
<pre>
#include &lt;ptime.h&gt;
#include &lt;pinet.h&gt;
USING_PTYPES
const int testport = 8085;
const int maxtoken = 4096;
void servermain(ipmsgserver& svr)
{
pout.putf("Ready to answer queries on port %d\n", testport);
bool quit = false;
do
{
try
{
<span class="comment">// receive the "hello" request and send a simple answer
// back to the client</span>
string req = lowercase(svr.receive(maxtoken));
if (req == "hello")
{
string host = svr.get_host();
if (isempty(host))
host = iptostring(svr.get_ip());
svr.send("Hello, " + host + " ("
+ iptostring(svr.get_ip()) + "), nice to see you!");
<span class="comment">// log this request</span>
pout.putf("%t greeting received from %s (%a)\n",
now(), pconst(host), long(svr.get_ip()));
}
}
catch(estream* e)
{
perr.putf("Server error: %s\n", pconst(e->get_message()));
delete e;
}
} while (!quit);
}
int main()
{
ipmsgserver svr;
try
{
svr.bindall(testport);
<span class="comment">// try to listen on socket once to generate an error right away,
// before entering the main server loop</span>
svr.poll();
<span class="comment">// enter an infinite loop of serving requests</span>
servermain(svr);
}
catch(estream* e)
{
perr.putf("FATAL: %s\n", pconst(e->get_message()));
delete e;
}
return 0;
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="inet.ipstream.html">ipstream</a>, <a href="inet.ipstmserver.html">ipstmserver</a>,
<a href="inet.ipmessage.html">ipmessage</a>, <a href="inet.ipmsgserver.html">ipmsgserver</a>,
<a href="inet.utils.html">Utilities</a>, <a href="async.examples.html">Multithreading
examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Networking</p>
<ul>
<li>
<h5><a href="inet.ipstream.html">ipstream</a> - stream-oriented client</h5>
</li>
<li>
<h5><a href="inet.ipstmserver.html">ipstmserver</a> - stream-oriented server</h5>
</li>
<li>
<h5><a href="inet.ipmessage.html">ipmessage</a> - message-oriented client</h5>
</li>
<li>
<h5><a href="inet.ipmsgserver.html">ipmsgserver</a> - message-oriented server</h5>
</li>
<li>
<h5><a href="inet.utils.html">Utilities</a></h5>
</li>
<li>
<h5><a href="inet.examples.html">Examples</a></h5>
</li>
</ul>
<p>PTypes' networking module provides simple means of creating both client and
server applications communicating over a IP network. The networking classes and
utilities are built on top of BSD sockets and WinSock2 frameworks. PTypes not
only solves and hides all incompatibility issues between these two API's, but
also makes the task of creating networking applications even simpler.</p>
<p>Building client/server applications requires you to either use an existing
protocol (such like HTTP, FTP, SMTP) or develop your own high-level communication
protocol for your specific needs. Since the latter may be a nontrivial task, to
avoid logical mistakes in the communication process we recommend you, first of
all, to study some of the widely used protocols, and second, use one of the existing
protocols with possible modifications instead of creating new ones. For example,
HTTP (Hypertext Transfer Protocol) used by web servers and browsers was designed
to be as generic as possible, so that it can be used virtually for any task with
simple request-response logic.</p>
<p>A real-world example of using PTypes networking is included in the source code
(See <a href="wshare.html">wshare</a>).</p>
<p>The networking classes and utilities are declared in <a href="include/pinet.h.html">&lt;pinet.h&gt;</a>.</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.ipmessage.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: ipmessage</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
ipmessage</p>
<blockquote>
<pre class="lang">#include &lt;pinet.h&gt;
class ipmessage {
ipmessage();
ipmessage(ipaddress ip, int port);
ipmessage(string host, int port);
bool waitfor(int timeout);
void send(const char* buf, int count);
void send(string s);<br> int receive(char* buf, int count [, ipaddress&amp; src ] );
string receive(int max [, ipaddress&amp; src ] );
ipaddress get/set_ip();
string get/set_host();
int get/set_port();
ipaddress get_myip();
int get_myport();
virtual void sockopt(int socket);
}</pre>
</blockquote>
<p>The <span class="lang">ipmessage</span> class implements connectionless, unreliable
datagram communication between IP hosts. The underlying protocol (UDP) never guarantees
that a message will be delivered, however, in return, it has
the ability to send broadcast messages on a local network. Unlike stream-oriented
protocols which have some traffic overhead because of the control packets (for
opening/closing connections and for confirming each delivery), message-oriented
protocols always send a single packet, sometimes fragmented if it exceeds the
size of a physical frame.</p>
<p>In summary, message-oriented communication is useful in the following situations:</p>
<ul>
<li>For sending streaming data (as a rule, sound or video) when losing packets
is not crucial. An application may measure the bandwidth and the reliability of
a connection before starting a streaming session, to estimate the optimal frequency
of packets and adjust the quality of multimedia data (e.g. frames per second,
resolution, etc).</li>
<li>For finding hosts of a specific type on a local network using broadcast/multicast
messages. You may want your client application to find its services on a network
automatically to free the user from entering the addresses manually.</li>
<li>For sending very short messages or request/reply cycles, possibly with confirmation/retry
mechanism. In most cases developing such applications may be costly compared to
using stream-oriented protocols instead.</li>
</ul>
<p>The maximum message size is limited to 64 KBytes on most systems. Note however,
that sending large messages may result in fragmentation and hence a lesser probability
that the whole message will be delivered. You may assume that a maximum data size
for a UDP message is 1472 bytes, even though such message may still be fragmented
when transferred over a non-Ethernet medium. The size of a guaranteed indivisible
UDP packet is 512 bytes on all physical media types.</p>
<p>For larger data chunks you may consider using streaming protocols, since the
TCP control traffic overhead is insignificant compared to data in such cases.</p>
<p>The <span class="lang">ipmessage</span> and <span class="lang">ipmsgserver</span>
classes are not compatible with PTypes streaming interfaces due to unreliable
and connectionless nature of the underlying protocol. These classes provide a
pair of low-level methods <span class="lang">receive()</span> and <span class="lang">send()</span>
and require that the client (<span class="lang">ipmessage</span>) first call <span class="lang">send()</span>
prior to receiving, and the server (<span class="lang">ipmsgserver</span>) must
first receive data prior to sending. In addition, the server object can be polled
for pending data (optionally with timed waiting) using <span class="lang">poll()</span>.</p>
<p>The <span class="lang">ipmessage</span> class is reusable, i.e. you may use
one object to send data to multiple destinations by changing the <span class="lang">ip</span>
(or <span class="lang">host</span>) and <span class="lang">port</span> properties.</p>
<p><span class="lang">Ipmessage</span> can generate exceptions of type <span class="lang">(estream*)</span>
with a corresponding error code and a message string.</p>
<p>(See also Example 3 in <a href="inet.examples.html">Examples</a>)</p>
<p><span class="def">ipmessage::ipmessage()</span> is the default constructor.</p>
<p><span class="def">ipmessage::ipmessage(ipaddress ip, int port)</span> constructs
an <span class="lang">ipmessage</span> object and assigns the peer <span class="lang">ip</span>/<span class="lang">port</span>
values. To send a broadcast message to all hosts on a local network, assign a
predefined constant <span class="lang">ipbcast</span> to <span class="lang">ip</span>.</p>
<p><span class="def">ipmessage::ipmessage(string host, int port)</span> constructs
an <span class="lang">ipmessage</span> object and assigns the peer host name and
port values. Before actually sending data first time, the object resolves the
host name to a numeric IP address. <span class="lang">Host</span> can be either
a symbolic DNS name or a numeric address in a string form (e.g. &quot;somehost.com&quot;
or &quot;192.168.1.1&quot;).</p>
<p><span class="def">bool ipmessage::waitfor(int milliseconds)</span> waits on
a socket until data is available for reading (returns <span class="lang">true</span>)
or the time specified has elapsed, in which case it returns <span class="lang">false</span>.</p>
<p><span class="def">ipmessage::send(const char* buf, int count)</span> sends
data to the peer. <span class="lang">Ip</span>/<span class="lang">host</span>
and <span class="lang">port</span> properties must be assigned prior to calling
<span class="lang">send()</span>. A client must first call <span class="lang">send()</span>
before receiving data from the peer.</p>
<p> <span class="def">ipmessage::send(string s)</span> works like the previous
version of <span class="lang">send()</span> except that it sends the string <span class="lang">s</span>
(not including the terminating null-symbol).</p>
<p><span class="def">int ipmessage::receive(char* buf, int count [, ipaddress&amp;
src ] )</span> reads data from the socket. <span class="lang">Receive()</span>
may hang if no data is available for reading. This function returns the actual
number of bytes read. If the packet received exceeds the size of the supplied
buffer, an exception is raised with code EMSGSIZE. You may check if there is data
available for reading without 'hanging' using <span class="lang">waitfor()</span>
described above. The last optional parameter <span class="lang">src</span> receives
the IP address of the host that sent this packet: it may be useful if the packet
is received in response to a broadcast request.</p>
<p><span class="def">string ipmessage::receive(int max [, ipaddress&amp; src ]
)</span> works like the previous version of <span class="lang">receive()</span>
except that it returns data in a dynamic string. The parameter <span class="lang">max</span>
specifies the limit which may not be exceeded when reading data from the network,
like with the previous version of <span class="lang">receive()</span>.</p>
<p><span class="def">ipaddress ipmessage::get/set_ip()</span> sets/retrieves the
peer address in a numerical form. If the object was constructed using a symbolic
name, <span class="lang">get_ip()</span> may perform a DNS lookup (only once).
To send a broadcast message to all hosts on a local network, assign a predefined
constant <span class="lang">ipbcast</span> to this property.</p>
<p><span class="def">string ipmessage::get/set_host()</span> sets/retrieves the
peer address in a symbolic form. If the object was constructed using a numeric
IP address, <span class="lang">get_host()</span> may perform a reverse DNS lookup.</p>
<p><span class="def">int ipmessage::get/set_port()</span> sets/retrieves the peer
port number.</p>
<p><span class="def">ipaddress ipmessage::get_myip()</span> returns the local
address associated with the socket.</p>
<p><span class="def">int ipmessage::get_myport()</span> returns the local port
number associated with the socket.</p>
<p><span class="def">virtual void ipmessage::sockopt(int socket)</span> - override this method in a descendant class if you want to set up additional socket options (normally, by calling <span class="lang">setsockopt()</span>).</p>
<p class="seealso">See also: <a href="inet.ipmsgserver.html">ipmsgserver</a>,
<a href="inet.utils.html">Utilities</a>, <a href="inet.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.ipmsgserver.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: ipstmserver</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
ipmsgserver</p>
<blockquote>
<pre class="lang">#include &lt;pinet.h&gt;
class ipmsgserver {
ipmsgserver();
int bind(ipaddress ip, int port);
int bindall(int port);
bool poll(int bindnum = -1, int timeout = 0);
int receive(char* buf, int count);
string receive(int max);
void send(const char* buf, int count);
void send(string s);
void sendto(const char* buf, int count, ipaddress ip, int port);
void sendto(string s, ipaddress ip, int port)
ipaddress get_ip();
string get_host();
virtual void sockopt(int socket);
}
</pre>
</blockquote>
<p>The <span class="lang">ipmsgserver</span> class is used on the server side
of a client-server application. It bounds itself to a specified port/address and
waits until a packet is received from a client host. Once a packet is read with
<span class="lang">receive()</span>, subsequent calls to <span class="lang">send()</span>
will post data back to the client that sent the last request. Each request must
be fulfilled immediately; unlike the stream-oriented server class, <span class="lang">ipmsgserver</span>
can not handle requests concurrently.</p>
<p><span class="lang">ipmsgserver</span> can generate exceptions of type <span class="lang">(estream*)</span>
with a corresponding error code and a message string.</p>
<p>Please, see also the introduction to <a href="inet.ipmessage.html">ipmessage</a>.</p>
<p><span class="def">ipmsgserver::ipmsgserver()</span> constructs an <span class="lang">ipmsgserver</span>
object.</p>
<p><span class="def">int ipmsgserver::bind(ipaddress ip, int port)</span> binds
the server to the specified local IP address and port number. This function can
be called multiple times for different local addresses and port numbers. <span class="lang">Bind()</span>
returns a value that can be used later in call to <span class="lang">poll()</span>
as the parameter <span class="lang">bindnum</span>.</p>
<p><span class="def">int ipmsgserver::bindall(int port)</span> binds the server
to all local IP addresses on the specified port number. Can be called multiple
times for different port numbers. <span class="lang">Bindall()</span> returns
a value that can be used later in call to <span class="lang">poll()</span> as
the parameter <span class="lang">bindnum</span>.</p>
<p><span class="def">bool ipmsgserver::poll(int bindnum = -1, int timeout = 0)</span>
polls the listening sockets for data available for reading. <span class="lang">Bindnum</span>
specifies the socket number reutrned by <span class="lang">bind()</span> or <span class="lang">bindall()</span>.
If this parameter is -1 <span class="lang">poll()</span> tests all sockets. The
second parameter <span class="lang">timeout</span> specifies the amount of time
in milliseconds to wait for data. If <span class="lang">timeout</span> is 0 <span class="lang">poll()</span>
returns immediately; if it's -1 <span class="lang">poll()</span> waits infinitely.
This function returns <span class="lang">true</span> if there is data available
for reading.</p>
<p><span class="def">int ipmsgserver::receive(char* buf, int count)</span> reads
data from the socket. <span class="lang">Receive()</span> may hang if no data
is available for reading. This function returns the actual number of bytes read.
If the packet received exceeds the size of the supplied buffer, an exception is
raised with code EMSGSIZE. You may check if there is data available for reading
without 'hanging' using <span class="lang">poll()</span> described above.</p>
<p><span class="def">string ipmsgserver::receive(int max)</span> works like the
previous version of <span class="lang">receive()</span> except that it returns
data in a dynamic string. The parameter <span class="lang">max</span> specifies
the limit which may not be exceeded when reading data from the network, like with
the previous version of <span class="lang">receive()</span>.</p>
<p><span class="def">void ipmsgserver::send(const char* buf, int count)</span>
sends data to the peer. The destination address is determined from the last packet
read using <span class="lang">receive()</span>.</p>
<p><span class="def">void ipmsgserver::send(string s)</span> works like the previous
version of <span class="lang">send()</span> except that it sends the string <span class="lang">s</span>
(not including the terminating null-symbol).</p>
<p><span class="def">void ipmsgserver::sendto(const char* buf, int count, ipaddress ip, int port)</span>
sends data to the specified address and port.</p>
<p><span class="def">void ipmsgserver::sendto(string s, ipaddress ip, int port)</span> works like the previous
version of <span class="lang">send()</span> except that it sends the string <span class="lang">s</span>
(not including the terminating null-symbol).</p>
<p><span class="def">ipaddress ipmsgserver::get_ip()</span> returns the IP address
of the peer. The information about the peer is determined during a successful
call to <span class="lang">receive()</span>.</p>
<p><span class="def">string ipmsgserver::get_host()</span> returns the peer host
name. A reverse DNS lookup may be performed if necessary. The information about
the peer is determined during a successful call to <span class="lang">receive()</span>.</p>
<p><span class="def">virtual void ipmsgserver::sockopt(int socket)</span> - override this method in a descendant class if you want to set up additional socket options (normally, by calling <span class="lang">setsockopt()</span>).</p>
<p class="seealso">See also: <a href="inet.ipmessage.html">ipmessage</a>, <a href="inet.utils.html">Utilities</a>,
<a href="inet.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.ipstmserver.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: ipstmserver</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
ipstmserver</p>
<blockquote>
<pre class="lang">#include &lt;pinet.h&gt;
class ipstmserver {
ipstmserver();
int bind(ipaddress ip, int port);
int bindall(int port);
bool poll(int bindnum = -1, int timeout = 0);
bool serve(ipstream&amp; client, int bindnum = -1, int timeout = -1);
virtual void sockopt(int socket);
}</pre>
</blockquote>
<p>The <span class="lang">ipstmserver</span> class is used on the server side
of a stream-oriented client-server application. It bounds itself to a specified
port/address and waits until a connection request is received from a client host.
For each connection request a server application performs some actions and returns
to the waiting state. For better performance your daemon may start a new thread
for each client connection.</p>
<p><span class="lang">Ipstmserver</span> can generate exceptions of type <span class="lang">(estream*)</span>
with a corresponding error code and a message string.</p>
<p><span class="def">ipstmserver::ipstmserver()</span> constructs an <span class="lang">ipstmserver</span>
object.</p>
<p><span class="def">int ipstmserver::bind(ipaddress ip, int port)</span> binds
the server to the specified local IP address and port number. This function can
be called multiple times for different local addresses and port numbers. <span class="lang">Bind()</span>
returns a value that can be used later in call to <span class="lang">poll()</span>
and <span class="lang">serve()</span> as the parameter <span class="lang">bindnum</span>.</p>
<p><span class="def">int ipstmserver::bindall(int port)</span> binds the server
to all local IP addresses on the specified port number. Can be called multiple
times for different port numbers. <span class="lang">Bindall()</span> returns
a value that can be used later in call to <span class="lang">poll()</span> and
<span class="lang">serve()</span> as the parameter <span class="lang">bindnum</span>.</p>
<p><span class="def">bool ipstmserver::poll(int bindnum = -1, int timeout = 0)</span>
polls the listening sockets for connection requests. <span class="lang">Bindnum</span>
specifies the socket number reutrned by <span class="lang">bind()</span> or <span class="lang">bindall()</span>.
If <span class="lang">bindnum</span> is -1 <span class="lang">poll()</span> tests
all sockets. The second parameter <span class="lang">timeout</span> specifies
the amount of time in milliseconds to wait for a connection request. If <span class="lang">timeout</span>
is 0 <span class="lang">poll()</span> returns immediately; if it's -1 <span class="lang">poll()</span>
waits infinitely. This function returns <span class="lang">true</span> if there
is a new connection request waiting for processing.</p>
<p><span class="def">bool ipstmserver::serve(ipstream&amp; client, int bindnum
= -1, int timeout = -1)</span> polls the specified bound sockets for connection
requests. If there is a connection request, <span class="lang">serve()</span>
opens and prepares the supplied <span class="lang">ipstream</span> object for
communicating with the client, i.e. <span class="lang">client</span> will be active
upon return from <span class="lang">serve()</span> and will contain the peer IP
address and the port number. The meanings of <span class="lang">bindnum</span>
and <span class="lang">timeout</span> are the same as for <span class="lang">poll()</span>
except that the default value for <span class="lang">timeout</span> in this case
is -1, i.e. wait infinitely. This function returns <span class="lang">true</span>
if there is a new connection request and <span class="lang">client</span> is active,
or <span class="lang">false</span> if the call has timed out.</p>
<p><span class="def">virtual void ipstmserver::sockopt(int socket)</span> - override this method in a descendant class if you want to set up additional socket options (normally, by calling <span class="lang">setsockopt()</span>).</p>
<p class="seealso">See also: <a href="inet.ipstream.html">ipstream</a>, <a href="inet.utils.html">Utilities</a>,
<a href="inet.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.ipstream.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: ipstream</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
ipstream</p>
<blockquote>
<pre class="lang">#include &lt;pinet.h&gt;
class ipstream: instm, outstm {
ipstream();
ipstream(ipaddress ip, int port);
ipstream(string host, int port);
~ipstream();
void open();
void close();
void cancel();
bool waitfor(int milliseconds);
ipaddress get/set_ip();
string get/set_host();
int get/set_port();
ipaddress get_myip();
int get_myport();
virtual void sockopt(int socket);
}</pre>
</blockquote>
<p>The <span class="lang">ipstream</span> class implements full-duplex streaming
communication between IP hosts. <span class="lang">Ipstream</span> incorporates
<a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>
and <a href="streams.outstm.html">outstm</a> interfaces and adds two more properties:
peer IP address and peer port number. This means, you can work with <span class="lang">ipstream</span>
the same way you work with <span class="lang">infile</span> and <span class="lang">outfile</span>,
except that you specify the target IP address or the symbolic hostname along with
the port number instead of the filename when constructing an object. Besides,
the rules of object-oriented inheritance allow you to manipulate <span class="lang">ipstream</span>
objects in those parts of your code which are only 'familiar' with the basic <span class="lang">instm</span>
and <span class="lang">outstm</span> interfaces.</p>
<p>In order to open a connection and exchange data you need to set target (peer
host) address and the port number. The peer address can be either a symbolic DNS
name or a numeric IPv4 address. Regardless of which one of these two properties
you set first, the <span class="lang">ipstream</span> object can perform DNS resolving
as necessary and return both properties on your request.</p>
<p><span class="lang">Ipstream</span> adds the following status codes: IO_RESOLVING,
IO_RESOLVED, IO_CONNECTING, IO_CONNECTED (see also <a href="streams.iobase.html">iobase</a>
for the status codes common to all streams).</p>
<p>On UNIX the library startup code blocks <span class="lang">SIGPIPE</span>,
so that all error conditions on sockets always raise exceptions of type <span class="lang">(estream*)</span>.</p>
<p><span class="def">ipstream::ipstream()</span> is the default constructor.</p>
<p><span class="def">ipstream::ipstream(ipaddress ip, int port)</span> constructs
an <span class="lang">ipstream</span> object and assigns the peer <span class="lang">ip</span>/<span class="lang">port</span>
values.</p>
<p><span class="def">ipstream::ipstream(string host, int port)</span> constructs
an <span class="lang">ipstream</span> object and assigns the peer host name and
port values. Before actually opening the stream <span class="lang">ipstream</span>
resolves the host name to a numeric IP address. <span class="lang">Host</span>
can be either a symbolic DNS name or even a numeric address in a string form (e.g.
&quot;somehost.com&quot; or &quot;192.168.1.1&quot;).</p>
<p><span class="def">ipstream::~ipstream()</span> cancels the connection immediately
and destroys the object. To shut down the connection 'gracefully' you should call
<span class="lang">close()</span> before destroying the object or before the program
goes beyond the scope of a static/local <span class="lang">ipstream</span> object.</p>
<p><span class="def">void ipstream::open()</span> opens a connection with the
peer. <span class="lang">host</span> or <span class="lang">ip</span> along with
<span class="lang">port</span> properties must be set before opening the stream.</p>
<p><span class="def">void ipstream::close()</span> closes the stream 'gracefully',
and in some situations may be time-consuming. Although all stream objects in PTypes
are closed by the destructors automatically, it is recommended to explicitly
call <span class="lang">close()</span> for socket objects.</p>
<p><span class="def">void ipstream::cancel()</span> closes the stream immediately.
If the connection was successful, calling <span class="lang">cancel()</span> may
leave the peer host in a waiting state for a long time.</p>
<p><span class="def">bool ipstream::waitfor(int milliseconds)</span> waits on
the socket until either data is available for reading (returns <span class="lang">true</span>)
or the time specified in the parameter has elapsed, in which case it returns <span class="lang">false</span>.</p>
<p><span class="def">ipaddress ipstream::get/set_ip()</span> sets/retrieves the
peer address in a numerical form. If the object was constructed using a symbolic
name, <span class="lang">get_ip()</span> may perform a DNS lookup (only once).</p>
<p><span class="def">string ipstream::get/set_host()</span> sets/retrieves the
peer address in a symbolic form. If the object was constructed using a numeric
IP address, <span class="lang">get_host()</span> may perform a reverse DNS lookup.</p>
<p><span class="def">int ipstream::get/set_port()</span> sets/retrieves the peer
port number.</p>
<p><span class="def">ipaddress ipstream::get_myip()</span> returns the local address
associated with the socket.</p>
<p><span class="def">int ipstream::get_myport()</span> returns the local port
number associated with the socket.</p>
<p><span class="def">virtual void ipstream::sockopt(int socket)</span> - override this method in a descendant class if you want to set up additional socket options (normally, by calling <span class="lang">setsockopt()</span>).</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>,
<a href="streams.outstm.html">outstm</a>, <a href="inet.ipstmserver.html">ipstmserver</a>,
<a href="inet.utils.html">Utilities</a>, <a href="inet.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/inet.utils.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: networking: utilities</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="inet.html">Networking</a>:
Utilities</p>
<blockquote>
<pre class="lang">#include &lt;pinet.h&gt;
string iptostring(ipaddress ip);
ipaddress phostbyname(const string&amp; name);
string phostbyaddr(ipaddress ip);
string phostcname(const string&amp; name);
</pre>
</blockquote>
<p>Many PTypes networking utility functions and class methods manipulate a new
data type <span class="lang">ipaddress</span> - IPv4 (4-byte) internetwork address
type. The objects of this type can be constructed either by explicitly specifying
the 4 bytes separately (e.g. <span class="lang">ipaddress(192, 168, 1, 1)</span>)
or by assigning another <span class="lang">ipaddress</span>. The objects of this
type are mutually compatible with <span class="lang">unsigned long</span> type,
however, you can not rely on the order of bytes if an <span class="lang">ipaddress</span>
is converted to a <span class="lang">unsigned long</span> and vice versa. This
implicit typecast is provided only for comparing an <span class="lang">ipaddress</span>
value with 0 or <span class="lang">ipnone</span> (see <a href="inet.examples.html">Examples</a>).</p>
<p><span class="def">string iptostring(ipaddress ip)</span> converts an IP address
to a string, e.g. <span class="lang">ipaddress(127, 0, 0, 1)</span> would be &quot;127.0.0.1&quot;.</p>
<p><span class="def">ipaddress phostbyname(const string&amp; name)</span> resolves
a symbolic DNS name or a numeric IP addresses to <span class="lang">ipaddress</span>.
On error this function returns <span class="lang">ipnone</span>.</p>
<p><span class="def">string phostbyaddr(ipaddress ip)</span> performs reverse
DNS lookup for the given IP address. On error this function returns an empty string.</p>
<p><span class="def">string phostcname(const string&amp; name)</span> returns
the canonical name of the host. On error this function returns an empty string.</p>
<p class="seealso">See also: <a href="inet.ipstream.html">ipstream</a>, <a href="inet.ipstmserver.html">ipstmserver</a>,
<a href="inet.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/intro.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: introduction</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Introduction</p>
<ul>
<li>
<h5><a href="compiling.html">Compiling and Porting</a></h5>
</li>
<li>
<h5><a href="changes.html">Changes</a></h5>
</li>
</ul>
<p><br>
<b>Basic features</b></p>
<ul>
<li>
<p>Threads and synchronization primitives solve the vital problem of diversity
of the threading API's on different platforms. The library also offers message
queues and job queues as additional methods of thread synchronization and maintenance.</p>
</li>
<li>
<p> IP socket classes and utilities provide complete IP-based framework for
both client-side and server-side programming. Combined with PTypes multithreading,
these classes can be used for designing complex non-visual applications,
such like network daemons or web robots.</p>
</li>
<li>
<p> Dynamic strings, variants, character sets, date/time type and various
kinds of dynamic and associative arrays: Delphi programmers will find them
very similar to the ones in their favorite language. The collection of
these basic data types may be useful, among other things, for building
compilers and interpreters for higher-level languages.</p>
</li>
<li>
<p>Streaming interfaces provide buffered I/O with simple and powerful text
parsing methods. A strictly defined syntax for a given text format or a
formal language can be represented by calls to PTypes token extraction
methods. The unified streaming interface is applicable to files, named
pipes and network sockets.</p>
</li>
<li>
<p>Special thread class with enhanced functionality called unit. Units have their
own main() and input/output 'plugs'; they can be connected to each other within
one application to form pipes, like processes in the UNIX shell.</p>
</li>
<li>
<p>Finally, everything above is portable: all platform-dependent details
are hidden inside.</p>
</li>
</ul>
<p><b><br>
Why use PTypes?</b></p>
<blockquote>
<p>PTypes is yet another generic class library among tens and hundreds of others.
To find its own niche in this variety of generic programming tools we decided
to emphasis on simplicity of the interfaces and readability of the resulting
code (i.e. the code that uses the library). The library focuses
only on most widely used data types and functional interfaces. We think that
like programming languages themselves, low-level libraries, too, should use
the minimal set of notions for covering most programming patterns.</p>
<p>Some data types in the library (strings, character sets and variants) use algebraic
notation rather than object-oriented, i.e. you write <span class="lang">length(s)</span>
for a string object instead of <span class="lang">s.length()</span>. We believe
that traditional notation better fits to a class that represents some fundamental
notion and is not supposed to produce subclasses with overridden methods. In other
words, if there is no inheritance and polymorphism, there is no need for method
calls as well.</p>
<p>PTypes uses old-fashioned all-lowercase naming style, since it can
peacefully co-exist with other styles in one program. Whether you are a `unixoid'
or you are using modern writing styles (Hungarian, Borland, etc.) you can
combine your favorite style with PTypes with no or very little harm to your
source code.</p>
<p>And finally, in order to achieve better readability of the resulting
code we use
clean
class
naming,
i.e. the string type is called <span class="lang">string</span>, thread
is <span class="lang">thread</span>,
etc.</p>
<p>We designed this library in the hope that PTypes with its conciseness and
intuitiveness could find its own 'target audience'.</p>
</blockquote>
<p><br>
<b>Versions and availability</b></p>
<blockquote>
<p>Version 2.1 of PTypes is the eleventh public release. The third number in the
version indicates insignificant improvements or bug fixes. You might want to take
a look at the <a href="changes.html">Changes</a> page if you are familiar with
one of the previous versions.</p>
<p>The latest source code and both on-line and out-of-line documentation can be
found at</p>
<blockquote>
<p><a href="http://www.melikyan.com/ptypes/">http://www.melikyan.com/ptypes/</a></p>
</blockquote>
<p>You can receive announcements about new releases through one of the following
services:</p>
<blockquote>
<p><a href="http://freshmeat.net/projects/ptypes/">Subscribe to the project
at freshmeat.net</a><br>
<a href="http://sourceforge.net/projects/ptypes/">Monitor the project
at SourceForge.net</a></p>
</blockquote>
<p>The development version of PTypes is available at SourceForge.net's CVS server.
If you are willing to join the development of the library, please become a SourceForge.net
user and then contact me to get full access to the CVS repository. The file TODO
in the development branch contains the immediate development plan for the library.</p>
</blockquote>
<p><br>
<b>Bugs and known problems</b></p>
<blockquote>
<p>The list of problems encountered in the latest version along with their
solutions, if available, can be found at PTypes project management page (at
SourceForge.net):</p>
<blockquote>
<p><a href="http://sourceforge.net/projects/ptypes/">PTypes project management
page</a></p>
</blockquote>
</blockquote>
<p><b><br>
Contributors</b></p>
<blockquote>
<p>We would like to thank:</p>
<blockquote>
<p>Pierre-Frederic Caillaud &lt;peufeu at free dot fr&gt;<br>
Ralph Siemsen &lt;ralphs at netwinder dot org&gt;<br>
Marco Geri &lt;m.geri at list dot it&gt;<br>
Philippe Le Rohellec &lt;plerohel at hotmail dot com&gt;<br>
Mark Lentczner &lt;markl at glyphic dot com&gt;<br>
Jordan Ritter &lt;jpr5 at darkridge dot com&gt;<br>
Sergey Matveychuk &lt;sem at ciam dot ru&gt;</p>
</blockquote>
</blockquote>
<p><b><br>
Contacts</b></p>
<blockquote>
<p>PTypes is open and free, which also means it is open to your comments and
suggestions. Please, submit bug reports and feature requests through <a href="http://sourceforge.net/projects/ptypes/">PTypes
project management page</a> at sf.net. There is a public <a href="http://sourceforge.net/forum/forum.php?forum_id=187216">discussion
forum</a> for general questions.</p>
<p>The author would be grateful if you let him know that you use the library
in your project. The author's email address is:</p>
<blockquote>
<p>Hovik Melikyan &lt;h at melikyan dot com&gt;</p>
</blockquote>
</blockquote>
<p class="seealso">See also: <a href="compiling.html">Compiling and Porting</a>, <a href="changes.html">Changes</a>, <a href="http://www.melikyan.com/ptypes/doc/ext/">Resources</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/lists.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: lists</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
Lists</p>
<ul>
<li>
<h5><a href="lists.tpodlist.html">tpodlist</a> - dynamic array of POD objects</h5>
</li>
<li>
<h5><a href="lists.tobjlist.html">tobjlist</a> - dynamic array of pointers to
arbitrary objects</h5>
</li>
<li>
<h5><a href="lists.tstrlist.html">tstrlist</a> - dynamic list and associative
array of string/object pairs</h5>
</li>
<li>
<h5><a href="lists.textmap.html">textmap</a> - associative array of textual key/value
pairs</h5>
</li>
</ul>
<p><br>
PTypes offers a set of list templates/classes that were designed to eliminate
the template 'code bloat' problem and also to allow reallocating of dynamic arrays
in the most efficient way.</p>
<p><b>Why not STL containers?</b> Or, why there is no universal container for
arbitrary types, like std::vector, in PTypes? There are 3 main reasons for this:</p>
<ul>
<li> A universal container template would require the item type to be either a
POD-type or a copyable class, since it copies items during reallocation of the
dynamic array. Otherwise, if its implementation would use fragmentation to avoid
copying, the indexed access would become a costly operation. As a result, you
are forced to provide copy constructors (often bulky, non-trivial code) for many
classes in your program, even though it wouldn't be necessary otherwise.</li>
</ul>
<ul>
<li>Such container would be (and in real world it is) very inefficient for the
same reason: each reallocation of the dynamic array requires items to be copied
instead of just moved. Possibly a built-in reallocation operator in C++ would
solve this problem.</li>
</ul>
<ul>
<li>The 'code bloat' problem: containers like std:vector usually produce enormous
amount of automatically generated code (sometimes duplicate code) during instantiation
of templates.</li>
</ul>
<p><br>
<b>Overview of PTypes list templates.</b> As a replacement of a universal vector-like
container PTypes offers two separate templates: <span class="lang">tpodlist</span>
and <span class="lang">tobjlist</span>. Each of them have certain limitations
in return for the following advantages: dynamic arrays are reallocated in the most
efficient way, templates produce no or very little code during instantiation.</p>
<p>The <span class="lang">tpodlist</span> template is intended for use with small
POD (plain-old-data) objects. For bigger structures or for arbitrary non-POD types
in general the library offers a list of pointers, <span class="lang">tobjlist</span>,
that has the ability to automatically destroy objects when they are removed from
the list. <span class="lang">Tobjlist</span> never reallocates items themselves,
instead, it only deals with pointers.</p>
<p>As a universal way of holding string/object pairs in an indexed list the library
offers the <span class="lang">tstrlist</span> template. When constructed as a
sorted list, this template can also serve as a map indexed by textual keys. And
finally, the <span class="lang">textmap</span> class provides a simple interface
for mapping strings to strings, i.e. textual keys to values.</p>
<p>Historically, PTypes was using list classes that required the list item to
be derived from <span class="lang">unknown</span>. These list classes (objlist,
strlist and strmap) are still present in the library for backward compatibility.
There is no such limitation in the newer versions of the library, however, deriving
your classes from <span class="lang">unknown</span> can still give you an advantage
of automatically detecting memory leaks in your program.</p>
<p><b>Bounds checking</b>. All list operations that involve indexes can be checked
for validity at run-time. If an index value is invalid, the library generates
an unrecoverable (fatal) error. Bounds checking is done when compiling your code
in debug mode (i.e. if macro <span class="lang">DEBUG</span> is defined). You
may also enable it explicitly for your release builds by defining <span class="lang">CHECK_BOUNDS</span>.
Note that the bounds checking code is fully inlined and the library itself is
not affected by these macros.</p>
<p>The list class family is declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p class="seealso">See also: <a href="unknown.html">unknown</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/lists.textmap.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: lists: textmap</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="lists.html">Lists</a>: textmap</p>
<blockquote>
<pre class="lang">
class textmap {
textmap(bool casesens = false);
int get_count() const;
void pack();
void clear();
int put(string key, string value);
string operator [](int index) const;
string operator [](string key) const;
string getkey(int index) const;
}
</pre>
</blockquote>
<p><br>
The <span class="lang">textmap</span> class implements an associative array of
strings, i.e. textual key/value pairs. Items in a <span class="lang">textmap</span>
object can be accessed both via integral indexes and textual keys. Internally,
<span class="lang">textmap</span> keeps the list sorted in alphabetical order
and uses binary search to find keys in a list.</p>
<p>The methods <span class="lang">get_count()</span>, <span class="lang">clear()</span>
and <span class="lang">pack()</span> work as for <a href="lists.tobjlist.html">tobjlist</a>
and are not described in this section.</p>
<p><span class="def">textmap::textmap(bool casesens = false)</span> constructs
a textmap object, optionally with case-sensitive key search.</p>
<p><span class="def">int textmap::put(string key, string value)</span> associates
<span class="lang">value</span> with <span class="lang">key</span>. This method
can either insert or replace an existing value, as well as remove it from a textmap
if <span class="lang">value</span> is an empty string.</p>
<p><span class="def">string textmap::operator [](string key)</span> returns a
value associated with the <span class="lang">key</span>, or an empty string if
<span class="lang">key</span> does not exist in a textmap.</p>
<p><span class="def">string textmap::operator [](int index)</span> returns a value
at the position <span class="lang">index</span>. This method along with <span class="lang">get_count()</span>
can be used to iterate through a textmap.</p>
<p><span class="def">string textmap::getkey(int index)</span> returns the key
value at the position <span class="lang">index</span>.</p>
<p class="seealso">See also: <a href="lists.tstrlist.html">tstrlist</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/lists.tobjlist.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: lists: tobjlist</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="lists.html">Lists</a>: tobjlist</p>
<blockquote>
<pre class="lang">template &lt;class X&gt; class tobjlist {
tobjlist(bool ownobjects = false);
~tobjlist();
int get/set_count(int);
int get/set_capacity(int);
bool get/set_ownobjects(bool);
void ins(int index, X* obj);
void add(X* obj);
X* operator [](int index) const;
X* top() const;
void put(int index, X* obj);
void del(int index);
X* pop();
void clear();
void pack();
bool search(const void* key, int&amp; index) const;
virtual int compare(const void* key, const void* obj) const;
}</pre>
</blockquote>
<p><br>
The <span class="lang">tobjlist</span> template implements a dynamic array of
pointers to objects of an arbitrary type <span class="lang">X</span>. Since the
list itself only holds pointers to objects, the element type can be any structure,
including a class with constructors and destructors. The element type is not required
to have a copy constructor. A list can contain objects of any derivative class
of <span class="lang">X</span> as well.</p>
<p><span class="lang">Tobjlist</span> can optionally (with <span class="lang">ownobjects</span>
= <span class="lang">true</span>) be responsible for freeing objects whenever
they are removed from a list, in which case the objects are required to be dynamically
allocated with operator <span class="lang">new</span>. Objects can be automatically
freed by the following methods: <span class="lang">set_count()</span> if the new
value is less than the old one, also <span class="lang">del()</span>, <span class="lang">clear()</span>,
<span class="lang">put()</span> and <span class="lang">~tobjlist()</span>.</p>
<p><span class="def">tobjlist::tobjlist(bool ownobjects = false)</span> constructs
a <span class="lang">tobjlist</span> object. See note for the parameter <span class="lang">ownobjects</span>
above.</p>
<p><span class="def">tobjlist::~tobjlist()</span> calls <span class="lang">clear()</span>
and destroys the list object.</p>
<p><span class="def">int tobjlist::get/set_count(int)</span> gets or sets the
number of items in a list. If the new value for <span class="lang">count</span>
is greater than the old one, all new slots are filled with NULL pointers. If it's
smaller and if <span class="lang">ownobjects</span> is true, extra objects are
freed.</p>
<p><span class="def">int tobjlist::get/set_capacity(int)</span> gets or sets the
capacity of a list. The <span class="lang">capacity</span> property reflects the
number of slots actually allocated for a list and is set automatically by other
methods whenever necessary. Like <span class="lang">tpodlist</span>, <span class="lang">tobjlist</span>
uses a 'lazy allocation' technique (see also <a href="lists.tpodlist.html">tpodlist::get/set_capacity</a>).</p>
<p><span class="def">bool tobjlist::get/set_ownobjects(bool)</span> returns or
sets the <span class="lang">ownobjects</span> flag.</p>
<p><span class="def">void tobjlist::ins(int index, X* obj)</span> inserts the
object <span class="lang">obj</span> into a list at the position <span class="lang">index</span>.
All pointers with greater indexes are moved up to make room for the new pointer.</p>
<p><span class="def">void tobjlist::add(X* obj)</span> adds the object <span class="lang">obj</span>
to the end of a list.</p>
<p><span class="def">X* tobjlist::operator [](int index)</span> returns the pointer
to an object at the position <span class="lang">index</span>. </p>
<p><span class="def">X* tobjlist::top()</span> returns the last pointer in a list.</p>
<p><span class="def">void tobjlist::put(int index, X* obj)</span> replaces the
pointer at the position <span class="lang">index</span> with <span class="lang">obj</span>.
Can free the old object if <span class="lang">ownobjects</span> is <span class="lang">true</span>.</p>
<p><span class="def">void tobjlist::del(int index)</span> deletes the pointer
at the position <span class="lang">index</span> and moves all pointers with greater
indexes down. Can also free the object if <span class="lang">ownobjects</span>
is <span class="lang">true</span>.</p>
<p><span class="def">X* tobjlist::pop()</span> returns the last pointer in a list
and deletes it from a list.</p>
<p><span class="def">void tobjlist::clear()</span> deletes all pointers from a
list. Can also free all objects if <span class="lang">ownobjects</span> is <span class="lang">true</span>.</p>
<p><span class="def">void tobjlist::pack()</span> sets <span class="lang">capacity</span>
equal to <span class="lang">count</span>. You can call <span class="lang">pack()</span>
after deleting multiple pointers from a list to optimize memory usage.</p>
<p><span class="def">bool tobjlist::search(const void* key, int&amp; index)</span>
performs binary search on a list. The virtual method <span class="lang">compare()</span>
(below) must be overridden in order for <span class="lang">search()</span> to
work.</p>
<p><span class="def">virtual int tobjlist::compare(const void* key, const void*
obj)</span> override this method in a descendant class to be able to perform binary
search on a list. The value of <span class="lang">key</span> is the same as in
the call to <span class="lang">search()</span>. <span class="lang">Obj</span>
is a pointer to an object that must be compared against <span class="lang">key</span>.
The return value must be -1, 0 or 1, similarly to the function <span class="lang">strcmp()</span>.</p>
<p class="seealso">See also: <a href="lists.tpodlist.html">tpodlist</a>, <a href="lists.tstrlist.html">tstrlist</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/lists.tpodlist.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: lists: tpodlist</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="lists.html">Lists</a>: tpodlist</p>
<blockquote>
<pre class="lang">template &lt;class X, bool initzero = false&gt; class tpodlist {
tpodlist();
tpodlist&amp; operator =(const tpodlist&amp; t);
int get/set_count(int);
int get/set_capacity(int);
X&amp; ins(int index);
void ins(int index, const X&amp; item);
void ins(int index, const tpodlist&amp; t);
X&amp; add();
void add(const X&amp; item);
void add(const tpodlist&amp; t);
X&amp; operator [](int index);
const X&amp; operator [](int index) const;
X&amp; top();
void del(int index, int count = 1);
void pop();
void clear();
void pack();
}</pre>
</blockquote>
<p><br>
The <span class="lang">tpodlist</span> template implements a dynamic array of
so-called POD (plain-old-data) objects. POD types in C++ are: all integral types,
pointers, floating point types, and also compound types (i.e. arrays and structures)
that contain only POD items. With optimizing compilation, the instantiation of
this template produces no extra code.</p>
<p>The parameter <span class="lang">X</span> of this template specifies the element
type for the list. The optional parameter <span class="lang">initzero</span> indicates
whether the memory allocated for new elements should be initialized to zero in
methods <span class="lang">ins(int)</span>, <span class="lang">add()</span> and
<span class="lang">set_count(int)</span>.</p>
<p><span class="def">tpodlist::tpodlist()</span> is the default constructor.</p>
<p><span class="def">tpodlist&amp; tpodlist::operator =(const tpodlist&amp; t)</span>
is an assignment operator that clears a list and then copies all items from <span class="lang">t</span>.</p>
<p><span class="def">int tpodlist::get/set_count(int)</span> gets or sets the
number of items in a list.</p>
<p><span class="def">int tpodlist::get/set_capacity(int)</span> gets or sets the
capacity of a list. The <span class="lang">capacity</span> property reflects the
number of items actually allocated for a list and is set automatically by other
methods whenever necessary. <span class="lang">Tpodlist</span> uses a 'lazy allocation'
technique for better performance: when items are added with <span class="lang">add()</span>
or <span class="lang">ins()</span>, the capacity grows in bigger increments. This
property, however, does not change when you delete items from a list, with only
exception when <span class="lang">count</span> becomes 0, in which case <span class="lang">capacity</span>
is also set to 0. You can call <span class="lang">pack()</span> to optimize memory
usage after deleting multiple items. Setting <span class="lang">capacity</span>
to a value less than <span class="lang">count</span> is an error.</p>
<p><span class="def">X&amp; tpodlist::ins(int index)</span> allocates a slot for
a new item at the position <span class="lang">index</span> and returns a reference
to the slot. All items with greater indexes are moved up to make room for the
new item. The slot can be initialized to zero if the template parameter <span class="lang">initzero</span>
was <span class="lang">true</span>. Calling <span class="lang">ins()</span> with
<span class="lang">index</span> equal to <span class="lang">count</span> is equivalent
to calling <span class="lang">add()</span>.</p>
<p><span class="def">void tpodlist::ins(int index, const X&amp; item)</span> inserts
<span class="lang">item</span> at <span class="lang">index</span>.</p>
<p><span class="def">void tpodlist::ins(int index, const tpodlist&amp; t)</span>
inserts all items of the list <span class="lang">t</span> at the position <span class="lang">index</span>.</p>
<p><span class="def">X&amp; tpodlist::add()</span> allocates a slot for a new
item at the end of a list and returns a reference to the slot.</p>
<p><span class="def">void tpodlist::add(const X&amp; item)</span> appends <span class="lang">item</span>
to a list.</p>
<p><span class="def">void tpodlist::add(const tpodlist&amp; t)</span> appends
the list <span class="lang">t</span> to a given list.</p>
<p><span class="def">X&amp; tpodlist::operator [](int index)</span> returns a
reference to an item at the position <span class="lang">index</span>. A const
version of this operator also exists.</p>
<p><span class="def">X&amp; tpodlist::top()</span> returns a reference to the
last item (one that has the greatest index) in a list.</p>
<p><span class="def">void tpodlist::del(int index, int count = 1)</span> deletes
<span class="lang">count</span> items from a list and moves all items with greater
indexes down. The parameter <span class="lang">count</span> is optional and defaults
to 1.</p>
<p><span class="def">void tpodlist::pop()</span> deletes the last item from a
list.</p>
<p><span class="def">void tpodlist::clear()</span> deletes all items from a list
and also sets <span class="lang">capacity</span> to 0.</p>
<p><span class="def">void tpodlist::pack()</span> sets <span class="lang">capacity</span>
equal to <span class="lang">count</span>. You can call <span class="lang">pack()</span>
after deleting multiple items from a list to optimize memory usage.</p>
<p class="seealso">See also: <a href="lists.tobjlist.html">tobjlist</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/lists.tstrlist.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: lists: tstrlist</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="lists.html">Lists</a>: tstrlist</p>
<blockquote>
<pre class="lang">template &lt;class X&gt; class tstrlist {
tstrlist(int flags = 0);
~tstrlist();
int get/set_count(int);
int get/set_capacity(int);
bool get/set_ownobjects(bool);
void clear();
void pack();
bool get_sorted() const;
bool get_duplicates() const;
bool get_casesens() const;
<span class="comment">// methods that work both on sorted and unsorted lists</span>
void ins(int index, string key, X* obj);
void put(int index, string key, X* obj);
void put(int index, X* obj);
int add(string key, X* obj);
X* operator [](int index) const;
string getkey(int index) const;
void del(int index);
int indexof(string key) const;
int indexof(void* obj) const;
<span class="comment">// these methods are allowed only on sorted lists</span>
int put(string key, X* obj);
X* operator [](string key) const;
void del(string key);
bool search(string key, int&amp; index) const;
}</pre>
</blockquote>
<p><br>
The <span class="lang">tstrlist</span> template is similar to <span class="lang">tobjlist</span>
in many ways, except that it maintains pairs of strings and objects of type <span class="lang">X</span>,
and defines some additional methods described below. <span class="lang">Tstrlist</span>
can optionally be sorted by string keys, which allows to use it as an associative
array of objects. Thus, <span class="lang">tstrlist</span> combines functionality
of an indexed dynamic array and an associative array at the same time. Like <span class="lang">tobjlist</span>,
<span class="lang">tstrlist</span> can 'own objects', which means it can automatically
free objects whenever they are removed from a list.</p>
<p>The methods <span class="lang">get/set_count()</span>, <span class="lang">get/set_capacity()</span>,
<span class="lang">get/set_ownobjects()</span>, <span class="lang">clear()</span>
and <span class="lang">pack()</span> work as for <a href="lists.tobjlist.html">tobjlist</a>
and are not described in this section.</p>
<p><span class="def">tstrlist::tstrlist(int flags = 0)</span> constructs a <span class="lang">tstrlist</span>
object. The parameter <span class="lang">flags</span> can be a combination of
the following constants:</p>
<ul>
<li><span class="lang">SL_OWNOBJECTS</span> - this <span class="lang">tstrlist</span>
object will be responsible for freeing objects.</li>
<li><span class="lang">SL_SORTED</span> - create a sorted list; the items are
kept in an alphabetically sorted order. This allows to use a <span class="lang">tstrlist</span>
object as an associative array.</li>
<li><span class="lang">SL_DUPLICATES</span> - allow duplicate keys. Must be combined
with <span class="lang">SL_SORTED</span>.</li>
<li><span class="lang">SL_CASESENS</span> - perform case-sensitive search. By
default the search is case-insensitive.</li>
</ul>
<p><span class="def">void tstrlist::ins(int index, string key, X* obj)</span>
inserts a key/object pair into a list at the position <span class="lang">index</span>.
For sorted lists <span class="lang">index</span> must be equal to the value returned
by <span class="lang">search()</span> for the given <span class="lang">key</span>.
A common pattern of using <span class="lang">ins()</span> on sorted lists is to
call <span class="lang">search()</span> for a key to determine whether an object
associated with a given key exists, then either insert a new object at the position
pointed to by <span class="lang">search()</span> or to get the existing object
at that position.</p>
<p><span class="def">void tstrlist::put(int index, string key, X* obj)</span>
puts (replaces) the key/object pair at the position <span class="lang">index</span>.</p>
<p><span class="def">void tstrlist::put(int index, X* obj)</span> puts <span class="lang">obj</span>
at the position <span class="lang">index</span>. The key at this position remains
unchanged.</p>
<p><span class="def">int tstrlist::add(string key, X* obj)</span> on sorted lists
this method performs search and inserts the key/object pair at a proper position
to keep the list in a sorted order. For ordinary (unsorted) lists this method
adds the key/object pair at the end of a list.</p>
<p><span class="def">X* tstrlist::operator [](int index)</span> returns an object
at the position <span class="lang">index</span>.</p>
<p><span class="def">string tstrlist::getkey(int index)</span> returns the key
value at the position <span class="lang">index</span>.</p>
<p><span class="def">void tstrlist::del(int index)</span> deletes the key/object
pair at the position <span class="lang">index</span>.</p>
<p><span class="def">int tstrlist::indexof(string key)</span> determines the index
of a given <span class="lang">key</span>. This function performs binary search
on sorted lists, or otherwise linear search on unsorted lists. Returns -1 if <span class="lang">key</span>
is not found.</p>
<p><span class="def">int tstrlist::indexof(void* obj)</span> determines the index
of a given object. Always uses linear search. Returns -1 if <span class="lang">obj</span>
is not found.</p>
<p><span class="def">int tstrlist::put(string key, X* obj)</span> is a universal
method of adding, replacing and removing objects in a sorted list. <span class="lang">Put()</span>
performs search by a given <span class="lang">key</span> and inserts <span class="lang">obj</span>
if the key doesn't exist in a list, replaces the old object with <span class="lang">obj</span>
if the key was found in a list, or deletes the key/object pair if the parameter
<span class="lang">obj</span> was NULL.</p>
<p><span class="def">X* tstrlist::operator [](string key)</span> returns an object
associated with a given <span class="lang">key</span>. Works only on sorted lists.
Returns NULL if <span class="lang">key</span> is not found.</p>
<p><span class="def">void tstrlist::del(string key)</span> deletes the key/object
pair for a given <span class="lang">key</span>. Works only on sorted lists. </p>
<p><span class="def">bool tstrlist::search(string key, int&amp; index)</span>
performs binary search on a list. Returns <span class="lang">true</span> if key
is present in a list. The output parameter <span class="lang">index</span> contains
either the position at which <span class="lang">key</span> was found, or otherwise
the position where <span class="lang">key</span> must be inserted to preserve
the sorted order.</p>
<p class="seealso">See also: <a href="lists.tobjlist.html">tobjlist</a>, <a href="lists.textmap.html">textmap</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/portability.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: Portability and Performance Issues</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Portability and performance issues</p>
<p><br>
<b> 64-bit integers</b>: most compilers provide <span class="lang">long long</span>
type modifier for declaring 64-bit integers, but at least two of them, Microsoft
C/C++ and Borland C/C++, use quite unaesthetic keyword <span class="lang">__int64</span>.
PTypes offers its own wrapper type <span class="lang">large</span> (in <a href="include/pport.h.html">&lt;pport.h&gt;</a>),
which is a portable signed 64-bit integer. <span class="lang">Unsigned large</span>
or <span class="lang">ularge</span> are also available. For portable 64-bit string
conversions use <span class="lang">itostring()</span> and <span class="lang">stringto*()</span>
declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p>Another incompatibility exists for printf-style formatted output routines:
Windows uses &quot;I64&quot; type modifier for 64-bit integers, whereas standard-compliant
libraries recognize &quot;ll&quot; (ell-ell). PTypes solves this problem in its
<span class="lang">outstm::putf()</span> method: you can safely use &quot;ll&quot;
modifier on all platforms.</p>
<p><b>End-of-line sequences</b>: PTypes input stream routines automatically recognize
three types of EOL sequences: LF (UNIX), CR (Mac) and CR-LF (DOS/Win) and set
<span class="lang">instm::eol</span> property accordingly.</p>
<p>As for output streams, unlike many Windows-based C run-time libraries, PTypes
does NOT make any translations and always sends your data as is. In order to generate
an EOL sequence appropriate to the target platform (i.e. the system your application
is running on), use <span class="lang">outstm::puteol()</span> and <span class="lang">outstm::putline(string)</span>.
Some protocols and data formats, however, require some predetermined EOL sequence
regardless of the target platform, e.g. HTTP always uses CR-LF, PostScript uses
CR, etc. In such cases you can use standard C escape sequences to send appropriate
codes to the output stream, e.g. &quot;\r\n&quot; or &quot;\r&quot;.</p>
<p><b>File names</b>: you can always use UNIX-style path names (with slash '/')
when working with files through PTypes streaming classes. Since drive specifiers
in path names are specific only to Windows, try to use relative paths in your
program whenever possible. For additional notes on pipe naming, please see introduction
for the <a href="streams.namedpipe.html">namedpipe</a> class.</p>
<p><b>Arithmetic operations and multithreading</b>: a simple increment and decrement
operation (i++ and i--) in a multithreaded application may NOT be thread-safe
on most RISC CPU's and on i386-based multiprocessor systems. Even if you are not
interested in the resulting value of an increment/decrement operation, still use
PTypes <span class="lang">pincrement()</span> and <span class="lang">pdecrement()</span>
on variables shared between threads.</p>
<p><b>Performance of dynamic strings</b>: most of the string operations rely on
dynamic memory reallocation. PTypes tries to avoid frequent use of physical reallocation
by aligning the dynamic string buffers on 16, 32, 64 ... 4096-byte boundaries,
depending on the logical size of a string. Physical reallocation highly depends
on the performance of the standard <span class="lang">realloc()</span> function,
which may vary from OS to OS. Linux, for example, performs reallocations up to
30 times faster than Windows on a similar computer. PTypes dynamic strings also
depend on the performance of the atomic increment and decrement functions (see
below).</p>
<p><b>Performance of atomic increment/decrement/exchange operations</b>: on SPARC, PowerPC
and i386-based platforms PTypes implements atomic operations using CPU instructions. On all other platforms these operations use slower mutex
locking (see <span class="lang">src/patomic.cxx</span>).</p>
<p><b>Reentrancy of synchronization objects</b>: the POSIX standard does not specify
whether synchronization objects should be reentrant or not. For instance, if you
use recursive locks on a mutex object the behaviour of your application may vary
on different systems. Most POSIX systems, such like Linux, provide a faster but
non-reentrant implementation of synchronization primitives.</p>
<p><b>Read/write lock portability issues</b>: the <span class="lang">rwlock</span>
class is built on top of the POSIX rwlock interface, wherever available, or uses
the internal implementation (see <span class="lang">src/rwlock.cxx</span>). Various
system-level implementations use different prioritization schemes: they may be
'fair' with respect to both reader and writer threads, or a higher priority may
be given to one of them. Unfortunately the behaviour of rwlock is not standardized
yet. PTypes' internal implementation uses the 'fair' scheme which we believe is
the best and the only DoS-proof (denial-of-service) among other algorithms. On
the other hand, replacing the system-level rwlock with our own implementation
on all systems would lead to a preformance penalty compared to using 'native'
objects. We set this issue aside for some time and we are open to discuss it with
interested/experienced developers.</p>
<p class="seealso">See also: <a href="string.conversion.html">String Conversion</a>,
<a href="async.utils.html"></a><a href="streams.outstm.html">outstm</a>, <a href="streams.namedpipe.html">namedpipe</a>,
<a href="string.html">string</a>, <a href="async.utils.html">Multithreading Utilities</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/ref.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: INDEX</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: INDEX</p>
<blockquote>
<p>
<table border=0>
<tr><td><a href="variant.arrays.html">aclear</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="variant.arrays.html">aclone</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="unknown.html">addref</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="variant.arrays.html">anext</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="cset.manipulation.html">assign</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="cset.manipulation.html">asstring</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="cset.manipulation.html">clear</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="string.manipulation.html">clear</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="variant.utils.html">clear</a></td><td>variant: utilities
</td></tr>
<tr><td><a href="unknown.html">component::addnotification</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="unknown.html">component::~component</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="unknown.html">component::delnotification</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="unknown.html">component::freenotify</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="unknown.html">compref</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="string.manipulation.html">concat</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="string.manipulation.html">contains</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="string.manipulation.html">copy</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="cset.constructors.html">cset::cset</a></td><td>cset: constructors
</td></tr>
<tr><td><a href="time.calendar.html">dayofweek</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.datetime.html">days</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="time.calendar.html">daysinmonth</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.calendar.html">daysinyear</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.calendar.html">decodedate</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.time.html">decodetime</a></td><td>date/time: time
</td></tr>
<tr><td><a href="string.manipulation.html">del</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="variant.arrays.html">del</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="time.datetime.html">dttostring</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="time.calendar.html">encodedate</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.time.html">encodetime</a></td><td>date/time: time
</td></tr>
<tr><td><a href="cset.manipulation.html">exclude</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="cset.manipulation.html">fill</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="variant.arrays.html">get</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="cset.manipulation.html">include</a></td><td>cset: manipulation
</td></tr>
<tr><td><a href="streams.infile.html">infile::get/set_filename</a></td><td>streams: infile
</td></tr>
<tr><td><a href="streams.infile.html">infile::infile</a></td><td>streams: infile
</td></tr>
<tr><td><a href="streams.infile.html">infile::pipe</a></td><td>streams: infile
</td></tr>
<tr><td><a href="streams.inmem.html">inmemory::get/set_strdata</a></td><td>streams: inmemory
</td></tr>
<tr><td><a href="streams.inmem.html">inmemory::inmemory</a></td><td>streams: inmemory
</td></tr>
<tr><td><a href="string.manipulation.html">ins</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="streams.instm.html">instm::get</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::get_eof</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::get_eol</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::line</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::preview</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::putback</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::read</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::skipline</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::skiptoken</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.instm.html">instm::token</a></td><td>streams: instm
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::cancel</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::close</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get/set_active</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get/set_bufsize</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get/set_cancelled</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get/set_onstatus</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get_status</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::get_streamname</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::open</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::seek</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::seekx</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::tell</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="streams.iobase.html">iobase::tellx</a></td><td>streams: iobase
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::get_myip</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::get_myport</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::get/set_host</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::get/set_ip</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::get/set_port</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::ipmessage</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::receive</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::send</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::sockopt</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmessage.html">ipmessage::waitfor</a></td><td>networking: ipmessage
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::bind</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::bindall</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::get_host</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::get_ip</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::ipmsgserver</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::poll</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::receive</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::send</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::sendto</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipmsgserver.html">ipmsgserver::sockopt</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::bind</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::bindall</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::ipstmserver</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::poll</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::serve</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstmserver.html">ipstmserver::sockopt</a></td><td>networking: ipstmserver
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::cancel</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::close</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::get_myip</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::get_myport</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::get/set_host</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::get/set_ip</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::get/set_port</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::ipstream</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::~ipstream</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::open</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::sockopt</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.ipstream.html">ipstream::waitfor</a></td><td>networking: ipstream
</td></tr>
<tr><td><a href="inet.utils.html">iptostring</a></td><td>networking: utilities
</td></tr>
<tr><td><a href="time.calendar.html">isdatevalid</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="string.manipulation.html">isempty</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="time.calendar.html">isleapyear</a></td><td>date/time: calendar
</td></tr>
<tr><td><a href="time.time.html">istimevalid</a></td><td>date/time: time
</td></tr>
<tr><td><a href="time.datetime.html">isvalid</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="variant.utils.html">isXXX</a></td><td>variant: utilities
</td></tr>
<tr><td><a href="string.conversion.html">itostring</a></td><td>string: conversion
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::get_count</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::get_limit</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::getmessage</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::jobqueue</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::post</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">jobqueue::posturgent</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="string.manipulation.html">length</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="streams.logfile.html">logfile::logfile</a></td><td>streams: logfile
</td></tr>
<tr><td><a href="streams.logfile.html">logfile::putf</a></td><td>streams: logfile
</td></tr>
<tr><td><a href="string.conversion.html">lowercase</a></td><td>string: conversion
</td></tr>
<tr><td><a href="async.message.html">message::id</a></td><td>multithreading: message
</td></tr>
<tr><td><a href="async.message.html">message::message</a></td><td>multithreading: message
</td></tr>
<tr><td><a href="async.message.html">message::param</a></td><td>multithreading: message
</td></tr>
<tr><td><a href="async.message.html">message::result</a></td><td>multithreading: message
</td></tr>
<tr><td><a href="time.datetime.html">mkdt</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="time.datetime.html">msecs</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::defhandler</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::get_count</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::get_limit</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::msghandler</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::msgqueue</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::post</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.jobqueue.html">msgqueue::posturgent</a></td><td>multithreading: jobqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::posturgent</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::processmsgs</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::processone</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::run</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.msgqueue.html">msgqueue::send</a></td><td>multithreading: msgqueue
</td></tr>
<tr><td><a href="async.mutex.html">mutex::enter</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.mutex.html">mutex::leave</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.mutex.html">mutex::lock</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.mutex.html">mutex::mutex</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.mutex.html">mutex::unlock</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="streams.namedpipe.html">namedpipe::get/set_pipename</a></td><td>streams: namedpipe
</td></tr>
<tr><td><a href="streams.namedpipe.html">namedpipe::namedpipe</a></td><td>streams: namedpipe
</td></tr>
<tr><td><a href="time.datetime.html">now</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="time.datetime.html">nowstring</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="streams.npserver.html">npserver::npserver</a></td><td>streams: npserver
</td></tr>
<tr><td><a href="streams.npserver.html">npserver::serve</a></td><td>streams: npserver
</td></tr>
<tr><td><a href="streams.outfile.html">outfile::get/set_append</a></td><td>streams: outfile
</td></tr>
<tr><td><a href="streams.outfile.html">outfile::get/set_filename</a></td><td>streams: outfile
</td></tr>
<tr><td><a href="streams.outfile.html">outfile::get/set_umode</a></td><td>streams: outfile
</td></tr>
<tr><td><a href="streams.outfile.html">outfile::outfile</a></td><td>streams: outfile
</td></tr>
<tr><td><a href="streams.md5.html">outmd5::get_bindigest</a></td><td>streams: outmd5
</td></tr>
<tr><td><a href="streams.md5.html">outmd5::get_digest</a></td><td>streams: outmd5
</td></tr>
<tr><td><a href="streams.md5.html">outmd5::outmd5</a></td><td>streams: outmd5
</td></tr>
<tr><td><a href="streams.outmem.html">outmemory::get_strdata</a></td><td>streams: outmemory
</td></tr>
<tr><td><a href="streams.outmem.html">outmemory::outmemory</a></td><td>streams: outmemory
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::flush</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::get/set_flusheol</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::put</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::puteol</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::putf</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::putline</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="streams.outstm.html">outstm::write</a></td><td>streams: outstm
</td></tr>
<tr><td><a href="async.utils.html">pdecrement</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="async.utils.html">pexchange</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="inet.utils.html">phostbyaddr</a></td><td>networking: utilities
</td></tr>
<tr><td><a href="inet.utils.html">phostbyname</a></td><td>networking: utilities
</td></tr>
<tr><td><a href="inet.utils.html">phostcname</a></td><td>networking: utilities
</td></tr>
<tr><td><a href="async.utils.html">pincrement</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="string.manipulation.html">pos</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="async.utils.html">psleep</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="async.utils.html">pthrequal</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="async.utils.html">pthrself</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="variant.arrays.html">put</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="unknown.html">release</a></td><td>unknown &amp; component
</td></tr>
<tr><td><a href="async.rwlock.html">rwlock::rdlock</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">rwlock::rwlock</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">rwlock::unlock</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">rwlock::wrlock</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.mutex.html">scopelock::scopelock</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.mutex.html">scopelock::~scopelock</a></td><td>multithreading: mutex
</td></tr>
<tr><td><a href="async.rwlock.html">scoperead::scoperead</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">scoperead::~scoperead</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">scopewrite::scopewrite</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.rwlock.html">scopewrite::~scopewrite</a></td><td>multithreading: rwlock
</td></tr>
<tr><td><a href="async.semaphore.html">semaphore::post</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="async.semaphore.html">semaphore::semaphore</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="async.semaphore.html">semaphore::signal</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="async.semaphore.html">semaphore::wait</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="string.manipulation.html">setlength</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="string.constructors.html">string</a></td><td>string: constructors/destructors
</td></tr>
<tr><td><a href="string.conversion.html">stringtoi</a></td><td>string: conversion
</td></tr>
<tr><td><a href="string.conversion.html">stringtoie</a></td><td>string: conversion
</td></tr>
<tr><td><a href="string.conversion.html">stringtoue</a></td><td>string: conversion
</td></tr>
<tr><td><a href="lists.textmap.html">textmap::[]</a></td><td>lists: textmap
</td></tr>
<tr><td><a href="lists.textmap.html">textmap::getkey</a></td><td>lists: textmap
</td></tr>
<tr><td><a href="lists.textmap.html">textmap::put</a></td><td>lists: textmap
</td></tr>
<tr><td><a href="lists.textmap.html">textmap::textmap</a></td><td>lists: textmap
</td></tr>
<tr><td><a href="async.thread.html">thread::cleanup</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::execute</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::get_finished</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::get_id</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::get_running</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::get_signaled</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::relax</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::signal</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::start</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::thread</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::~thread</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.thread.html">thread::waitfor</a></td><td>multithreading: thread
</td></tr>
<tr><td><a href="async.semaphore.html">timedsem::timedsem</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="async.semaphore.html">timedsem::wait</a></td><td>multithreading: semaphore
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::[]</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::add</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::clear</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::compare</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::del</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::get/set_capacity</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::get/set_count</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::get/set_ownobjects</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::ins</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::pack</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::pop</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::put</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::search</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::tobjlist</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::~tobjlist</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="lists.tobjlist.html">tobjlist::top</a></td><td>lists: tobjlist
</td></tr>
<tr><td><a href="async.utils.html">tpexchange</a></td><td>multithreading: utils
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::=</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::[]</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::add</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::clear</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::del</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::get/set_capacity</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::get/set_count</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::ins</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::pack</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::pop</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::top</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="lists.tpodlist.html">tpodlist::tpodlist</a></td><td>lists: tpodlist
</td></tr>
<tr><td><a href="async.trigger.html">trigger::post</a></td><td>multithreading: trigger
</td></tr>
<tr><td><a href="async.trigger.html">trigger::reset</a></td><td>multithreading: trigger
</td></tr>
<tr><td><a href="async.trigger.html">trigger::signal</a></td><td>multithreading: trigger
</td></tr>
<tr><td><a href="async.trigger.html">trigger::trigger</a></td><td>multithreading: trigger
</td></tr>
<tr><td><a href="async.trigger.html">trigger::wait</a></td><td>multithreading: trigger
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::[]</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::add</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::del</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::getkey</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::indexof</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::ins</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::put</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::search</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="lists.tstrlist.html">tstrlist::tstrlist</a></td><td>lists: tstrlist
</td></tr>
<tr><td><a href="time.datetime.html">tzoffset</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="time.datetime.html">tzupdate</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="string.manipulation.html">unique</a></td><td>string: manipulation
</td></tr>
<tr><td><a href="unit.html">unit::cleanup</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::connect</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::main</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::run</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::uin</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::uout</a></td><td>unit
</td></tr>
<tr><td><a href="unit.html">unit::waitfor</a></td><td>unit
</td></tr>
<tr><td><a href="time.datetime.html">utodatetime</a></td><td>date/time: datetime
</td></tr>
<tr><td><a href="variant.arrays.html">variant::[]</a></td><td>variant: arrays
</td></tr>
<tr><td><a href="variant.utils.html">vartype</a></td><td>variant: utilities
</td></tr>
</table>
</p>
</blockquote>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/ref.tmpl.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: INDEX</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: INDEX</p>
<blockquote>
<p>
%REF%
</p>
</blockquote>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.errors.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: error handling</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
Error handling</p>
<p>When a recoverable error occurs during input/output operations, an exception
of type <span class="lang">(estream*)</span> is thrown. The exception object
contains an error message which can be shown to the user. The message is accessible
through <span class="def">estream::get_message()</span>. </p>
<p>The example below shows how to catch an exception and recover normal execution
of the program:</p>
<blockquote>
<pre>#include &lt;pstreams.h&gt;
USING_PTYPES
infile f(&quot;somefile.txt&quot;);
try
{
f.open();
while(!f.get_eof())
<span class="comment"> // read the file...</span>
}
catch (estream* e)
{
perr.putline(e-&gt;get_message());
delete e;
}
</pre>
</blockquote>
<p>The <span class="lang">estream</span> class provides a system error code in
UNIX errno semantics through <span class="def">estream::get_code()</span>. On
Windows most error codes are translated into corresponding UNIX errno codes. Less
frequently occurring errors are translated to a generic errno code EIO. When an
<span class="lang">estream</span> object returns EIO, the actual message string
is constructed based on the status code of the stream. For example, if the status
code was IO_OPENING, the error code was EIO, the message would be &quot;Couldn't
open <i>[filename]</i>&quot;. For explanations on what each errno code means,
see comments in <span class="lang">src/piobase.cxx</span> source file.</p>
<p><span class="lang">Estream</span> also provides a reference to the stream object
that raised the error condition through <span class="lang">estream::get_errstm()</span>.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.examples.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: examples</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
Examples </p>
<p><b>Example 1.</b> This simple program creates a new file and writes a string
to it.</p>
<blockquote>
<pre>#include &lt;pstreams.h&gt;
USING_PTYPES
int main()
{
<span class="comment">// the outfile object is declared and constructed outside
// the try...catch clause, since the exception object
// contains a reference to the stream that caused the error.
// besides, stream constructors and destructors in PTypes
// never throw exceptions.</span>
outfile f(fname);
f.set_bufsize(1024); <span class="comment">// the default value in this version is 8192</span>
try
{
f.open();
f.put(&quot;This is a test file.&quot;);
f.close();
}
catch (estream* e)
{
perr.putf(&quot;File error: %s\n&quot;, e->get_message());
delete e;
}
return 0;
}
</pre>
</blockquote>
<p><b>Example 2.</b> This program reads a C source, extracts identifiers and builds
a usage dictionary. It does not understand C comments and string literals though,
but can be easily improved to understand them too.</p>
<blockquote>
<pre>#include &lt;ptypes.h&gt;
#include &lt;pstreams.h&gt;
USING_PTYPES
const cset letters(&quot;_A-Za-z&quot;);
const cset digits(&quot;0-9&quot;);
const cset identchars = letters + digits;
const cset otherchars = !letters;
void main(int argc, char* argv[])
{
tstrlist&lt;void*&gt; dic(SL_SORTED | SL_CASESENS);
infile f(argv[1]);
try
{
f.open();
while (!f.get_eof())
{
char c = f.preview();
<span class="comment">// a C identifier begins with a letter</span>
if (c &amp; letters)
{
<span class="comment">// ... and may contain letters and digits</span>
string ident = f.token(identchars);
int i;
if (!dic.search(ident, i))
dic.ins(i, ident, 0);
}
else
<span class="comment">// ignore everything else</span>
f.skiptoken(otherchars);
}
}
catch (estream* e)
{
pout.putf(&quot;Error: %s\n&quot;, e->get_message());
delete e;
}
<span class="comment">// now print the dictionary</span>
for (int i = 0; i < dic.get_count(); i++)
pout.putline(dic.getkey(i));
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>,
<a href="streams.infile.html">infile</a>, <a href="streams.outstm.html">outstm</a>,
<a href="streams.outfile.html">outfile</a>, <a href="streams.errors.html">Error
handling</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: Streams</p>
<ul>
<li>
<h5><a href="streams.iobase.html">iobase</a> - common input/output interface</h5>
</li>
<li>
<h5><a href="streams.instm.html">instm</a> - basic input stream</h5>
</li>
<li>
<h5><a href="streams.outstm.html">outstm</a> - basic output stream</h5>
</li>
<li>
<h5><a href="streams.infile.html">infile</a> - file input</h5>
</li>
<li>
<h5><a href="streams.outfile.html">outfile</a> - file output</h5>
</li>
<li>
<h5><a href="streams.logfile.html">logfile</a> - file output with thread-safe
formatting functions</h5>
</li>
<li>
<h5><a href="streams.namedpipe.html">namedpipe</a> - named pipe/UNIX local socket</h5>
</li>
<li>
<h5><a href="streams.npserver.html">npserver</a> - named pipe server</h5>
</li>
<li>
<h5><a href="streams.stdio.html">Standard input, output and error devices</a></h5>
</li>
<li>
<h5><a href="streams.md5.html">outmd5</a> - MD5 message digest computation</h5>
</li>
<li>
<h5><a href="streams.inmem.html">inmemory</a> - memory input</h5>
</li>
<li>
<h5><a href="streams.outmem.html">outmemory</a> - memory output</h5>
</li>
<li>
<h5><a href="streams.errors.html">Error handling</a></h5>
</li>
<li>
<h5><a href="streams.examples.html">Examples</a></h5>
</li>
</ul>
<p>The stream input/output module, which is an integral part of PTypes, declares
a family of classes that implement abstract functionality of stream-oriented data
processing. The main features of this module include:</p>
<ul>
<li> Text processing utilities, such like token extraction using character sets.</li>
<li> Buffering: both input and output streams can be buffered to speed up operation.</li>
<li> Scalability: the functionality of either input or output streams can be overridden
by providing several low-level routines for the given device or communication
protocol.</li>
<li> System-independent error handling: regardless of the system on which the
library is compiled, the error codes are presented in UNIX &quot;errno&quot; semantics.</li>
</ul>
<p>The basic class <a href="streams.iobase.html">iobase</a> encapsulates features
common to both input and output, such like buffering, event and error handling,
etc. This class is derived from <a href="unknown.html">component</a>. Two descendant
classes -- <a href="streams.instm.html">instm</a> and <a href="streams.outstm.html">outstm</a>
-- specialize in data input and output respectively, as well as provide simple
and powerful text processing utility methods.</p>
<p>PTypes declares three built-in objects for <a href="streams.stdio.html">standard
input, output and error devices</a>. </p>
<p>All recoverable error conditions generate exceptions of class <span class="lang">(estream*)</span>.
See <a href="streams.errors.html">Error handling</a> for details.</p>
<p>Some encapsulated structure fields in this module are accessed through <span class="lang">get_X()</span>
and <span class="lang">set_X()</span> function pairs. To simplify documentation,
we use a single description in the form <span class="lang">get/set_X()</span>
for such fields, and sometimes we refer to them as <i>properties</i>.</p>
<p>The stream i/o class family is declared in <a href="include/pstreams.h.html">&lt;pstreams.h&gt;</a>.</p>
<p class="seealso">See also: <a href="inet.html">Networking</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.infile.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: infile</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
infile </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class infile: instm {
infile( [ const string&amp; filename ] );
void pipe(outfile&amp; peer);
string get/set_filename(string);
}
</pre>
</blockquote>
<p>This class derives all public methods and properties from <a href="streams.iobase.html">iobase</a>
and <a href="streams.instm.html">instm</a>, and in addition, defines the following:</p>
<p><span class="def">infile::infile( [ const string&amp; filename ] )</span> creates
an input file stream, but does not open the file. <span class="lang">Filename</span>
is optional and can be set later, using <span class="lang">set_filename()</span>.</p>
<p><span class="def">void infile::pipe(outfile&amp; peer)</span> creates a local
pipe. This function sets up and opens the <span class="lang">infile</span> and
<span class="lang">outfile</span> objects so that a thread can asynchronously
pass data to another thread within one process. Note that <span class="lang">pipe()</span>
opens both streams; subsequent calls to <span class="lang">open()</span>, <span class="lang">close()</span>
or <span class="lang">cancel()</span> shuts down the pipe. Local pipe is a slower
alternative to the message queue. The only advantage of local pipes is that they
provide a standard streaming interface.</p>
<p><span class="def"> string infile::get/set_filename(string)</span> sets the
file name. <span class="lang">set_filename()</span> closes the stream prior to
assigning the new value.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>,
<a href="streams.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.inmem.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: inmemory</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
inmemory </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class inmemory: instm {
inmemory(string mem);
string get/set_strdata(string);
}</pre>
</blockquote>
<p>Use <span class="lang">inmemory</span> to read data from a dynamic memory buffer
by means of the streaming interface. <span class="lang">Inmemory</span> is derived
from <a href="streams.instm.html">instm</a>.</p>
<p><span class="def">inmemory::inmemory(string mem)</span> - constructs an <span class="lang">inmemory</span>
object. The string passed through the <span class="lang">mem</span> parameter
will be used by this object as a data source.</p>
<p><span class="def">string inmemory::get/set_strdata(string)</span> - gets or
sets the memory buffer. <span class="lang">Set_strdata()</span> closes the stream
prior to assigning the new value.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>
</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.instm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: instm</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
instm </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class instm: iobase {
bool get_eof();
bool get_eol();
char preview();
char get();
void putback();
string token(const cset& chars [, int limit ] );
int token(const cset& chars, char* buf, int size);
string line();
string line( [ int limit ] );
int line(char* buf, int size);
void skipline();
void skiptoken(const cset& chars);
int skip(int numbytes);
int read(char* buf, int count);
}
</pre>
</blockquote>
<p>This class implements the basic functionality of input streams. <span class="lang">Instm</span>
is derived from <a href="streams.iobase.html">iobase</a> and inherits all its
public methods and properties. All methods of <span class="lang">instm</span>
except <span class="lang">read()</span> and <span class="lang">get_eof()</span>
require buffering.</p>
<p><span class="def">bool instm::get_eof()</span> returns <span class="lang">true</span>
if the end of file is reached.</p>
<p><span class="def">bool instm::get_eol()</span> returns <span class="lang">true</span>
if the file pointer is currently at the end of a line. Since operating systems
use different end-of-line codes or combinations of codes, it is recommended to
check the end-of-line status using this property and skip the end-of-line sequence
by calling <span class="lang">skipline()</span> method.</p>
<p> <span class="def">char instm::preview()</span> returns the next character
from the stream but does not advance the file pointer. If the pointer is at the
end of file, <span class="lang">preview()</span> returns <span class="lang">eofchar</span>
(null character).</p>
<p><span class="def">char instm::get()</span> returns the next character from
the stream. If an attempt is made to read beyond the file (i.e. if the property
<span class="lang">eof</span> is set), this method returns <span class="lang">eofchar</span>
(null character).</p>
<p><span class="def">void instm::putback()</span> puts the last retrieved character
back to the stream; a faster equivalent to <span class="lang">seek(-1, IO_CURRENT)</span>.
This function can be called only after a call to <span class="lang">get()</span>
if the latter did not return an <span class="lang">eof</span> character.</p>
<p><span class="def">string instm::token(const cset& chars [, int limit ] )</span>
reads the next token that only contains characters of the given set <span class="lang">chars</span>.
The optional parameter <span class="lang">limit</span> specifies the maximum number
of bytes to read. If the token exceeds the limit, an exception <span class="lang">(estream*)</span>
is thrown with error number ERANGE.</p>
<p><span class="def">int instm::token(const cset& chars, char* buf, int size)</span>
-- this version of <span class="lang">token()</span> reads the next token to the
given buffer <span class="lang">buf</span>. The number of characters is limited
to <span class="lang">size</span>. This method returns the actual number of characters
read from the stream which can not be greater than <span class="lang">size</span>.
Unlike the other version of <span class="lang">token()</span>, does not throw
exceptions if the token exceeds the limit, but rather truncates it to <span class="lang">size</span>.
Note: this function does not put a terminating null symbol in the buffer.</p>
<p><span class="def">string instm::line( [ int limit ] )</span> reads the current
line from the stream. The end-of-line code(s) are not included in the returning
value, however, <span class="lang">line()</span> skips them and sets the file
pointer at the beginning of the next line. The optional parameter <span class="lang">limit</span>
specifies the maximum number of bytes to read. If the token exceeds the limit,
an exception <span class="lang">(estream*)</span> is thrown with error number
ERANGE.</p>
<p><span class="def">int instm::line(char* buf, int size)</span> -- this version
of <span class="lang">line()</span> reads the next line from the stream to the
buffer <span class="lang">buf</span>. The number of characters is limited to <span class="lang">size</span>.
This method returns the actual number of characters read from the stream which
can not be greater than <span class="lang">size</span>. Unlike the other version
of <span class="lang">line()</span>, does not throw exceptions if the token exceeds
the limit, but rather truncates it to <span class="lang">size</span>. Note: this
function does not put a terminating null symbol in the buffer.</p>
<p><span class="def">void instm::skiptoken(const cset& chars)</span> works like
previous versions of <span class="lang">token()</span> except that the token string
is not returned. Can be safely used to skip very large tokens.</p>
<p><span class="def">void instm::skipline()</span> skips the current line and
sets the file pointer at the beginning of the next line.</p>
<p><span class="lang">int instm::skip(int numbytes)</span> skips the specified
number of bytes from the input stream.</p>
<p><span class="def">int instm::read(char* buf, int count)</span> reads <span class="lang">count</span>
bytes from the stream and stores them in the buffer <span class="lang">buf</span>.
Returns the number of bytes actually read. This method does
not require buffering.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.outstm.html">outstm</a>,
<a href="string.html">string</a>, <a href="cset.html">cset</a>, <a href="streams.errors.html">Error
handling</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.iobase.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: iobase</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
iobase </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
typedef void (*iostatusevent)(iobase* sender, int code);
class iobase {
void open();
void close();
void cancel();
large tellx();
int tell();
large seekx(large newpos, ioseekmode mode = IO_BEGIN);
int seek(int newpos, ioseekmode mode = IO_BEGIN);
string get_streamname();
bool get/set_active(bool);
bool get/set_cancelled(bool);
int get/set_bufsize(int);
int get_status();
iostatusevent get/set_onstatus(<span class="def">iostatusevent</span>);
}
</pre>
</blockquote>
<p>The methods and properties of this abstract class are common to all stream
interfaces in PTypes.</p>
<p><span class="def">void iobase::open()</span> opens (activates) the stream.</p>
<p><span class="def">void iobase::close()</span> closes (deactivates) the stream.
This method is called automatically during destruction of an object. <span class="lang">Close()</span>
calls <span class="lang">flush()</span> for output streams. To simplify error
handling in user programs, this method never throws exceptions. If you want to
check for errors during the last write operation, call <span class="lang">flush()</span>
explicitly before closing the stream.</p>
<p><span class="def">void iobase::cancel()</span> closes the stream and sets the
<span class="lang">cancelled</span> property to true. In communication streams
this method may close the connection immediately, unlike <span class="lang">close()</span>,
which always tries to flush data buffers and then close the stream gracefully.</p>
<p><span class="def">large iobase::tellx()</span> returns either the current position
in the target media (usually file) or, for communication channels, the number
of bytes transfered from the beginning of the session.</p>
<p><span class="def">int iobase::tell()</span> left for compatibility; returns a 32-bit file offset or raises an exception if the value doesn't fit the <span class="lang">int</span> type.</p>
<p><span class="def">large iobase::seekx(large newpos, ioseekmode mode = IO_BEGIN)</span> changes the media pointer (e.g. file pointer). Possible values for <span class="lang">mode</span> are: IO_BEGIN, IO_CURRENT and IO_END. This function first tries to position the
stream pointer within the scope of the I/O buffer. If the new pointer is out of
buffer's range, <span class="lang">seekx()</span> then tries to change the physical
pointer of the target media. Note that physical positioning is not supported by
some stream types, e.g. by <span class="lang">ipstream</span>.</p>
<p><span class="def">int iobase::seek(int newpos, ioseekmode mode = IO_BEGIN)</span> left for compatibility; tries to seek in 32-bit mode and return a 32-bit file offset. Raises an exception if the return value doesn't fir the <span class="lang">int</span> type.</p>
<p><span class="def"> string iobase::get_streamname()</span> returns a string
containing either a file name, an URL, or some other string describing the underlying
media or object. Useful for diagnostics messages.</p>
<p><span class="def"> bool iobase::get/set_active(bool)</span> indicates whether
the stream is active. Setting this property to <span class="lang">true</span>
or <span class="lang">false</span> opens or closes the stream respectively.</p>
<p><span class="def"> bool iobase::get/set_cancelled(bool)</span> returns <span class="lang">true</span>
if the stream was closed using <span class="lang">cancel()</span>.</p>
<p><span class="def"> int iobase::get/set_bufsize(int)</span> sets the buffer
size for the stream. Setting this property to -1 will assign some reasonable default
value, which may vary depending on the operating environment, available memory,
etc. Note: text input routines require buffering (see <a href="streams.instm.html">instm</a>).</p>
<p><span class="def"> int iobase::get_status(int)</span> returns the current status
of the stream. The value of this property can be one of the following: IO_CREATED,
IO_OPENING, IO_OPENED, IO_READING, IO_WRITING, IO_EOF, IO_CLOSING, IO_CLOSED.
Derivative classes may add other status codes, e.g. see <a href="inet.ipstream.html">ipstream</a>.</p>
<p> <span class="def"> iostatusevent iobase::get/set_onstatus(iostatusevent)</span>
-- sets or returns user-defined callback function. The callback function is called
whenever the status of the stream is changed (see also <span class="lang">get_status()</span>).</p>
<p class="seealso">See also: <a href="streams.instm.html">instm</a>, <a href="streams.outstm.html">outstm</a>,
<a href="streams.errors.html">Error handling</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.logfile.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: logfile</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
logfile </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class logfile: outfile {
logfile( [ const string& filename, bool append = true ] );
void putf(const char* fmt, ...);
}
</pre>
</blockquote>
<p> The <span class="lang">lofgile</span> class inherits all public methods and
properties from <a href="streams.outfile.html">outfile</a>, but differs in the
following:</p>
<ul>
<li>The <span class="lang">append</span> property is set to <span class="lang">true</span>
by default.</li>
<li>The buffer size is set to 0 by default.</li>
<li>The <span class="lang">logfile::putf()</span> function is thread-safe: you
can call this function for the same logfile object from concurrent threads.</li>
</ul>
<p><span class="def">logfile::logfile( [ const string&amp; filename, bool append
= true ] )</span> creates an output file stream, but does not open the file. When
opening a file with <span class="lang">open()</span>, the file pointer is positioned
at the end of the file, unless <span class="lang">append</span> is set to <span class="lang">false</span>.
<span class="lang">Filename</span> and <span class="lang">append</span> parameters
are optional.</p>
<p><span class="def">void logfile::putf(const char* fmt, ...)</span> is a thread-safe
version of <span class="lang">outstm::putf()</span>.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.outstm.html">outstm</a>,
<a href="streams.outfile.html">outfile</a>, <a href="streams.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.md5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: outmd5</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
outmd5 </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class outmd5: outstm {
outmd5();
outmd5(outstm* outthru);
string get_digest();
const unsigned char* get_bindigest();
}
</pre>
</blockquote>
<p>MD5, the message digest algorithm described in RFC 1321, computes a 128-bit
sequence (sometimes called 'message digest', 'fingerprint' or 'MD5 checksum')
from arbitrary data. As stated in RFC 1321, it is conjectured that it is computationally
infeasible to produce two messages having the same message digest, or to produce
any message having a given prespecified target message digest. MD5 can be viewed
as a one-way encryption system and can be used, for example, to encrypt passwords
in a password database.</p>
<p>The MD5 fingerprint is more often converted to so-called ASCII-64 form in order
to conveniently store it in plain text environments and protocols. Thus, the 128-bit
binary sequence becomes a 22-character text string consisting of letters, digits
and two special symbols '.' and '/'. (Note that this is not the same as Base64
encoding in MIME).</p>
<p>In order to compute a MD5 fingerprint you first create a stream object of type
<span class="lang">outmd5</span> and then send data to it as if it was an ordinary
output file or a socket stream. After you close the stream, you can obtain the
fingerprint in ASCII-64 form using the object's <span class="lang">get_digest()</span>
method.</p>
<p>The implementation of MD5 is derived from L. Peter Deutsch's work.</p>
<p>This class derives all public methods and properties from <a href="streams.iobase.html">iobase</a>
and <a href="streams.outstm.html">outstm</a>, and in addition defines the following:</p>
<p><span class="def">outmd5::outmd5()</span> creates a bufferless MD5 stream.</p>
<p><span class="def">outmd5::outmd5(outstm* outthru)</span> creates a MD5 stream
and attaches an output stream <span class="lang">outthru</span> to it. Everything
sent to the MD5 stream will also be duplicated to <span class="lang">outthru</span>.
You may want, for example, to attach <span class="lang">perr</span> to your MD5
stream for debugging purposes.</p>
<p><span class="def">string outmd5::get_digest()</span> closes the stream and
returns the computed fingerprint in text form (ASCII-64).</p>
<p><span class="def">const unsigned char* outmd5::get_bindigest()</span> closes
the stream and returns a pointer to a 16-byte buffer with the binary MD5 fingerprint.</p>
<p><b>Example:</b></p>
<blockquote>
<pre>
string cryptpw(string username, string password)
{
outmd5 m;
m.open();
m.put(username);
m.put(password);
m.put(&quot;Banana with ketchup&quot;);
return m.get_digest();
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.outstm.html">outstm</a>
</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.namedpipe.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: namedpipe</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
namedpipe </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class namedpipe: instm, outstm {
namedpipe( [ string pipename ] );
string get/set_pipename(string);
}
</pre>
</blockquote>
<p>The <span class="lang">namedpipe</span> class implements full-duplex streaming
communication between processes, typically on one computer. It is built on top
of Windows named pipes and local UNIX sockets. <span class="lang">Namedpipe</span>
incorporates <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>
and <a href="streams.outstm.html">outstm</a> interfaces and adds one more property:
the pipe name to connect to. PTypes named pipes are session-oriented.</p>
<p><b>Naming</b>. Local sockets on UNIX can be created anywhere in the file system
and generally behave like ordinary files, except that the input and output streams
for a socket file is handled by the server process that created the socket. In
contrast to UNIX, Windows allocates named pipes in a special directory (actually
a share name) <span class="lang">\\.\pipe</span>, which is not visible to the
end-user. </p>
<p>PTypes can accept both a file name and an absolute path name when creating
a named pipe object, however, absolute paths have effect only on UNIX. If you
specify a single file name on UNIX, PTypes will place the socket file in <span class="lang">/tmp</span>.
That is, if you are writing a portable application, and you want the socket file
to be placed in a directory other than <span class="lang">/tmp</span> on UNIX
(e.g. some daemons running as root place their sockets in <span class="lang">/var/run</span>),
you can specify the full path in both Windows and UNIX versions of your program:
the library will ignore the path on Windows, since it can not place it other than
in <span class="lang">\\.\pipe</span>, and will use it on UNIX.</p>
<p><b>Usage</b>. Named pipes provide efficient means of interprocess communication.
Many networking applications, typically SQL servers, offer both network sockets
and local sockets as alternate ways of connecting to the service. For security
reasons, a system administrator may choose to configure the service such that
it will use only the local socket, or the service can be open to the network too
if it provides strong authentication at application level.</p>
<p><span class="lang">Namedpipe</span> and <a href="inet.ipstream.html">ipstream</a>
classes are compatible: both are full-duplex streams and are derived from <span class="lang">instm</span>
and <span class="lang">outstm</span> simultaneously. Thus, PTypes allows you to
easily combine both methods of communication in one application. Each thread serving
connections on server-side of your application can accept two parameters of basic
types <span class="lang">instm</span> and <span class="lang">outsm</span>; you
can then pass either an <span class="lang">ipstream</span> or a <span class="lang">namedpipe</span>
object (or any other compatible stream object) to the newly instantiated thread
to serve the request coming from the client. Note that it is sometimes necessary
to provide explicit typecast when assigning <span class="lang">namedpipe</span>
or <span class="lang">ipstream</span> to <span class="lang">outstm</span> or <span class="lang">instm</span>.</p>
<p><b>Windows security note</b>. Named pipes on Windows are open to the network,
i.e. any computer can connect to a pipe through \\<i>computer-name</i>\pipe\...,
where<i> computer-name</i> can be a NetBIOS name or even an IP address. Even though
PTypes' interfaces do not allow you to connect to a remote named pipe for the
sake of compatibility with UNIX, still, you should consider a situation when someone
knowing the pipe name and the protocol you use, writes his own program to 'illegally'
access your service on a Windows machine from a remote computer. Hence, for better
security, your service should provide user authentication at application level
(of course, unless it's a public service and is open anyway). Aside from security,
network named pipes are much slower than any other networking protocol, such like
TCP/IP, so we do not encourage using named pipes remotely in any case.</p>
<p>Unlike Windows, UNIX local sockets can never be accessed from a remote computer
even through a NFS-mounted directory. Note that remote access to named pipes on
Windows can be disabled by stopping all Windows networking services and leaving
only the transport-level protocol stacks.</p>
<p>Local unnamed pipes for exchanging data within one process can be created using
<a href="streams.infile.html">infile::pipe()</a>.</p>
<p><b>Interface</b>. <span class="lang">Namedpipe</span> is compatible with <a href="streams.iobase.html">iobase</a>,
<a href="streams.instm.html">instm</a> and <a href="streams.outstm.html">outstm</a>
and in addition, defines the following:</p>
<p><span class="def">namedpipe::namedpipe( [ string pipename ] )</span> creates
a named pipe object and optionally assigns the pipe name. When creating a <span class="lang">namedpipe</span>
object that will be passed to <span class="lang">npserver::serve()</span>, it
is not necessary to assign a pipe name.</p>
<p><span class="def">string namedpipe::get/set_pipename(string)</span> gets or
sets the pipe name. When assigning a new pipe name, <span class="lang">set_pipename()</span>
first closes the stream.</p>
<p class="seealso">See also: <a href="streams.npserver.html">npserver</a>, <a href="streams.iobase.html">iobase</a>,
<a href="streams.instm.html">instm</a>, <a href="streams.outstm.html">outstm</a>,
<a href="inet.examples.html">Networking examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.npserver.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: npserver</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
npserver</p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class npserver {
npserver(string pipename);
bool serve(namedpipe&amp; client, int timeout = -1);
}</pre>
</blockquote>
<p>The <span class="lang">npserver</span> class is used on the server side of
an interprocess communication channel. It listens to connections on the specified
named pipe or a local UNIX socket and for each connection provides a <span class="lang">namedpipe</span>
object for exchanging data with the peer.</p>
<p>Please, read the introduction to <a href="streams.namedpipe.html">namedpipe</a>
first.</p>
<p><span class="def">npserver::npserver(string pipename)</span> creates a named
pipe server object. The named pipe or a local socket is actually created during
the first call to <span class="lang">serve()</span> for this object.</p>
<p><span class="def">bool npserver::serve(namedpipe&amp; client, int timeout =
-1)</span> polls the pipe for connection requests. If there is a connection request
from a client, <span class="lang">serve()</span> opens and prepares the supplied
namedpipe object for communicating with the client, i.e. <span class="lang">client</span>
will be active upon return from <span class="lang">serve()</span>. The second
optional parameter <span class="lang">timeout</span> specifies the amount of time
in milliseconds to wait for a connection request. If timeout is 0 <span class="lang">serve()</span>
will return immediately; if it's -1 <span class="lang">serve()</span> will wait
infinitely. This function returns <span class="lang">true</span> if there is a
connection request and the <span class="lang">client</span> object is active,
or <span class="lang">false</span> if the call has timed out.</p>
<p class="seealso">See also: <a href="streams.namedpipe.html">namedpipe</a>, <a href="inet.examples.html">Networking
examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.outfile.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: outfile</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
outfile </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class outfile: outstm {
outfile( [ const string& filename, bool append = false ] );
string get/set_filename(string);
bool get/set_append(bool);
int get/set_umode(int);
}
</pre>
</blockquote>
<p>This class derives all public methods and properties from <a href="streams.iobase.html">iobase</a>
and <a href="streams.outstm.html">outstm</a>, and in addition defines the following:</p>
<p><span class="def">outfile::outfile( [ const string&amp; filename, bool append
= false ] )</span> creates an output file stream, but does not open the file.
When opening a file with <span class="lang">open()</span>, it is truncated to
zero unless <span class="lang">append</span> property is set to true. <span class="lang">Filename</span>
and <span class="lang">append</span> parameters are optional.</p>
<p><span class="def">string outfile::get/set_filename(string)</span> sets the
file name. <span class="lang">set_filename()</span> closes the stream prior to
assigning the new value.</p>
<p><span class="def">bool outfile::get/set_append(bool)</span> -- if set to true,
the file pointer is set beyond the last byte of the file when opening the stream
with <span class="lang">open()</span>.</p>
<p><span class="def">int outfile::get/set_umode(int)</span> sets UNIX file mode
when creating a new file. By default a file is created with <span class="lang">0644</span>
octal, which on UNIX means read/write access for the owner and read-only access
for group members and all others. This property has no effect on Windows.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.outstm.html">outstm</a>,
<a href="streams.logfile.html">logfile</a>, <a href="streams.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.outmem.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: outmemory</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
outmemory </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class outmemory: outstm {
outmemory(int limit = -1);
string get_strdata();
}</pre>
</blockquote>
<p>Use <span class="lang">outmemory</span> to write data to a dynamic memory buffer
by means of the streaming interface. <span class="lang">Outmemory</span> is derived
from <a href="streams.outstm.html">outstm</a>.</p>
<p><span class="def">outmemory::outmemory(int limit = -1)</span> creates an <span class="lang">outmemory</span>
object. The memory buffer grows as data is written to the stream. You can optionally
limit the size of the memory buffer to <span class="lang">limit</span> (-1 means
unlimited).</p>
<p><span class="def">string outmemory::get_strdata()</span> returns data written
to the stream as a dynamic string and closes the stream.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.outstm.html">outstm</a>
</p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.outstm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: outstm</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
outstm </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class outstm: iobase {
void putf(const char* fmt, ...);
void put(char);
void put(string);
void puteol();
void putline(string);
int write(const char* buf, int count);
void flush();
bool get/set_flusheol(bool);
}
</pre>
</blockquote>
<p>This class implements the basic functionality of output streams. <span class="lang">Outstm</span>
is derived from <a href="streams.iobase.html">iobase</a> and inherits all its
public methods and properties.</p>
<p>End-of-line sequences are not translated when you send data through the output
methods. To write an end-of-line sequence appropriate to the given operating environment
use <span class="lang">puteol()</span> instead.</p>
<p><span class="def">void outstm::putf(const char* fmt, ...)</span> is a printf-style
output method. PTypes supports a subset of format specifiers common to all platforms:
&lt;blank&gt;, '#', '+' and '-' formatting flags, 'L', 'h', 'l' and 'll' format
modifiers, and the following standard format specifiers: <span class="lang">cdiouxXeEfgGps</span>.
In addition, PTypes supports a format specifier <span class="lang">a</span> for
IP addresses (<span class="lang">ipaddress</span> type) and also <span class="lang">t</span>
and <span class="lang">T</span> for timestamps (<span class="lang">datetime</span>
type). Note that some compilers require to explicitly cast <span class="lang">ipaddress</span>
arguments to <span class="lang">long</span> type, and also <span class="lang">string</span>
arguments to <span class="lang">const char*</span> (or <span class="lang">pconst</span>).</p>
<p><span class="def">void outstm::put(char c)</span> writes the character <span class="lang">c</span>
to the stream.</p>
<p><span class="def">void outstm::put(string str)</span> writes the string <span class="lang">str</span>
to the stream.</p>
<p><span class="def">void outstm::puteol()</span> writes an end-of-line sequence
to the stream. The actual sequence depends on the platform the library was compiled
on. May flush data if the property <span class="lang">flusheol</span> is set to
<span class="lang">true</span>.</p>
<p><span class="def">void outstm::putline(string str)</span> writes the string
<span class="lang">str</span> to the stream followed by an end-of-line sequence,
as in call to <span class="lang">puteol()</span>.</p>
<p><span class="def">int outstm::write(const char* buf, int count)</span> writes
<span class="lang">count</span> bytes from the buffer <span class="lang">buf</span>
to the stream.</p>
<p><span class="def">void outstm::flush()</span> writes the remaining data in
the buffer to the media, if any. This method is called automatically when the
stream is being closed.</p>
<p><span class="def"> bool outstm::get/set_flusheol(bool)</span> -- set this property
to true if you want each line to be written to the media or communication stream
immediately. Default is <span class="lang">false</span>.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>,
<a href="streams.errors.html">Error handling</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/streams.stdio.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: streams: Standard input, output and error devices</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="streams.html">Streams</a>:
Standard input, output and error devices </p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
instm pin;
outstm pout;
outstm perr;
outstm pnull;</pre>
</blockquote>
<p>PTypes declares four static stream objects for standard input, output, error
and null devices - <span class="lang">pin</span>, <span class="lang">pout</span>,
<span class="lang">perr</span> and <span class="lang">pnull </span>respectively.
These objects can be used in place of the standard C or C++ input/output interfaces.
<span class="lang">Pnull</span> is an output stream that discards any data written
to it. The <span class="lang">putf()</span> method in standard output objects
<span class="lang">pout</span> and <span class="lang">perr</span> is atomic with
respect to multithreading.</p>
<p class="seealso">See also: <a href="streams.iobase.html">iobase</a>, <a href="streams.instm.html">instm</a>,
<a href="streams.outstm.html">outstm</a>, <a href="streams.examples.html">Examples</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.constructors.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string: constructors/destructors</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="string.html">string</a>: Constructors/destructors</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class string {
string();
string(const string&amp;);
string(char);
string(const char*);
string(const char*, int);
~string();
}
</pre>
</blockquote>
<p>A string object can be constructed in 5 different ways:</p>
<ul>
<li>
<p> default constructor <span class="lang">string()</span> creates an empty string.</p>
</li>
<li>
<p>copy constructor <span class="lang">string(const string&amp; s)</span> creates
a copy of the given string <span class="lang">s</span>. Actually this constructor
only increments the reference count by 1 and no memory allocation takes place.</p>
</li>
<li>
<p><span class="def">string(char c)</span> constructs a new string consisting
of one character <span class="lang">c</span>.</p>
</li>
<li>
<p><span class="def">string(const char* s)</span> constructs a new string object
from a null-terminated string. If <span class="lang">s</span> is either <span class="lang">NULL</span>
or is a pointer to a null character, an empty string object is created. This constructor
can be used to assign a string literal to a string object (see examples below).</p>
</li>
<li>
<p><span class="def">string(const char* s, int len)</span> copies <span class="lang">len</span>
bytes of data from buffer <span class="lang">s</span> to the newly allocated string
buffer.</p>
</li>
</ul>
<p>Destructor <span class="lang">~string()</span> decrements the reference count
for the given string buffer and removes it from the dynamic memory if necessary.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>string s1; <span class="comment">// empty string</span>
string s2 = s1; <span class="comment">// copy</span>
string s3 = 'A'; <span class="comment">// single character</span>
string s4 = &quot;ABCabc&quot;; <span class="comment">// string literal</span>
char* p = &quot;ABCabc&quot;;
string s5 = p; <span class="comment">// null-terminated string</span>
string s6(p, 3); <span class="comment">// buffer/length</span>
</pre>
</blockquote>
<p class="seealso">See also: <a href="string.operators.html">Operators</a>, <a href="string.typecasts.html">Typecasts</a>,
<a href="string.manipulation.html">Manipulation</a>, <a href="string.conversion.html">Conversion</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.conversion.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string: conversion</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="string.html">string</a>: Conversion</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
string itostring(<i>&lt;ordinal</i>&gt; value);
string itostring(<i>&lt;ordinal</i>&gt; value, int base, int width = 0, char pad = ' ');
large stringtoi(const string&amp; s);
large stringtoie(const string&amp; s);
ularge stringtoue(const string&amp; s, int base);
string lowercase(const string&amp; s);
</pre>
</blockquote>
<p><br>
PTypes provides 3 different string-to-int conversion functions: <span class="lang">stringtoi()</span>,
<span class="lang">stringtoie()</span> and <span class="lang">stringtoue()</span>.
The first function <span class="lang">stringtoi()</span> is for non-negative decimal
numbers; it returns -1 on error. The other two functions with a suffix 'e' in
their names ('e' is for 'exception') may throw exceptions, but they accept the
full range of 64-bit values.</p>
<p>These functions replace the CRTL functions <span class="lang">atoll()</span>
and <span class="lang">strtoll()</span> which are not implemented on all systems.</p>
<p>Both function families, string-to-int and int-to-string, accept numeration
bases in the range 2 to 64. The 64-digit numeration uses all digits, letters and
also '.' and '/'. It may be useful for representing, for example, MD5 checksums
in a compact printable form (see function <span class="lang">outmd5::get_digest()</span>
in src/pmd5.cxx).<br>
</p>
<p><span class="def">string itostring(<i>&lt;ordinal&gt;</i> value)</span> converts
the given ordinal <span class="lang">value</span> to a string. Various overloaded
versions of this function accept ordinal values of different sizes and signness.</p>
<p><span class="def">string itostring(<i>&lt;ordinal</i>&gt; value, int base,
int width = 0, char pad = ' ')</span> converts an integer value to a string with
the numeration base specified by <span class="lang">base</span>, which can be
in the range 2 - 64. To right-justify the resulting string you can specify <span class="lang">width</span>
and <span class="lang">pad</span> parameters. If the numeration base is greater
than 36 in addition to digits and letters <span class="lang">itostring()</span>
uses '.' and '/' characters and also lowercase letters. For numeration bases other
than 10 the parameter <span class="lang">value</span> is always treated as unsigned.</p>
<p><span class="def">large stringtoi(const string&amp; s)</span> converts a string
to a 64-bit integer. This function accepts only <b>positive decimal large numbers</b>
and 0. It returns -1 if the string does not represent a valid positive number
or an overflow occurred.</p>
<p><span class="def">large stringtoie(const string&amp; s)</span> converts a string
to a 64-bit integer. This function accepts <b>signed decimal large numbers</b>.
Unlike <span class="lang">stringtoi()</span>, this function may throw an exception
of type <span class="lang">(econv*)</span> if the string does not represent a
valid number or an overflow occurred.</p>
<p><span class="def">unsigned large stringtoue(const string&amp; s, int base)</span>
converts a string to an unsigned 64-bit integer using the numeration base specified
by <span class="lang">base</span>. This function accepts <b>unsigned large numbers</b>.
It may throw an exception of type <span class="lang">(econv*)</span> if the string
does not represent a valid number or an overflow occurred. <span class="lang">Base</span>
can be in the range 2 - 64. For numeration bases from 2 to 36 this function uses
digits and letters, and the letter case is insignificant. For numeration bases
grater than 36, '.', '/' and lowercase letters are used additionaly.</p>
<p><span class="def">string lowercase(const string&amp; s)</span> converts all
characters of the given string <span class="lang">s</span> to lower case. The
current version of the library &quot;understands&quot; only lower ASCII characters;
all other characters remain unchanged. This function can effectively detect if
all characters in the string are already in lower-case to avoid unnecessary string
allocations. </p>
<p class="seealso">See also: <a href="string.constructors.html">Constructors/destructors</a>,
<a href="string.operators.html">Operators</a>, <a href="string.typecasts.html">Typecasts</a>,
<a href="string.manipulation.html">Manipulation</a> </p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
string</p>
<ul>
<li>
<h5><a href="string.constructors.html">Constructors/destructors</a></h5>
</li>
<li>
<h5><a href="string.operators.html">Operators</a></h5>
</li>
<li>
<h5><a href="string.typecasts.html">Typecasts</a></h5>
</li>
<li>
<h5><a href="string.manipulation.html">Manipulation</a></h5>
</li>
<li>
<h5><a href="string.conversion.html">Conversion</a></h5>
</li>
</ul>
<p>The <span class="lang">string</span> class implements dynamically allocated
reference-counted 8-bit character strings. The <span class="lang">string</span>
class is a mixture of L-type and null-terminated strings: it has both the length
indicator and the terminating null-symbol. The length of a string is theoretically
limited to <span class="lang">INT_MAX</span>, and practically is limited to the
amount of virtual memory space available to the application. </p>
<p>A string object itself contains only a reference to the first character of
the string buffer. A string object can be implicitly converted to a null-terminated
string, either a variable or passed as an actual parameter, thus allowing to combine
both PTypes strings and traditional C strings in your application. A string object
converted to <span class="lang">char*</span> or <span class="lang">const char*</span>
never returns <span class="lang">NULL</span> pointers: it guarantees to always
point to some data, even if the string is zero-sized.</p>
<p>The reference counting mechanism works <b>transparently</b> (known also as
copy-on-write) and <b>safely</b> with regard to multithreading. You can manipulate
string objects as if each object had its own copy of string data. Whenever you
modify a string object the library safely detaches the buffer from all other string
objects that may be using the same buffer and creates a unique copy so that changes
won't affect the other &quot;holders&quot; of this string.</p>
<p><b>NOTE on multithreading</b>: the dynamic string objects themselves are NOT
thread-safe. In other words, each thread can manipulate objects (variables) of
type <span class="lang">string</span> only within their scope. However, it is
safe to pass strings as (copy) parameters when, for example, sending a message
to a concurrent thread through a message queue. Whenever the recipient thread
tries to modify the string, the shared data buffer is safely detached.</p>
<p>The string class is declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p class="seealso">See also: <a href="string.constructors.html">Constructors/destructors</a>,
<a href="string.operators.html">Operators</a>, <a href="string.typecasts.html">Typecasts</a>,
<a href="string.manipulation.html">Manipulation</a>, <a href="string.conversion.html">Conversion</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.manipulation.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string: manipulation</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="string.html">string</a>: Manipulation</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
<span class="comment">// get/set length and misc.</span>
int length(const string& s);
char* setlength(string&, int);
char* unique(string&);
void clear(string& s);
bool isempty(const string& s);
<span class="comment">// concatenate</span>
void concat(string& s, const char* sc, int catlen);
<span class="comment">// copy (get substring by position and length)</span>
string copy(const string& s, int from [, int cnt ] );
<span class="comment">// insert string or character</span>
void ins(const char* s1, string& s, int at);
void ins(char s1, string& s, int at);
void ins(const string& s1, string& s, int at);
void ins(const char* s1, int s1len, string& s, int at);
<span class="comment">// delete substring</span>
void del(string& s, int at [, int cnt ] );
<span class="comment">// find substring or character</span>
int pos(const char* s1, const string& s);
int pos(char s1, const string& s);
int pos(const string& s1, const string& s);
int rpos(char s1, const string& s);
<span class="comment">// compare substring</span>
bool contains(const char* s1, const string& s, int at);
bool contains(char s1, const string& s, int at);
bool contains(const string& s1, const string& s, int at);
bool contains(const char* s1, int s1len, const string& s, int at);
</pre>
</blockquote>
<p><span class="def">int length(const string& s)</span> returns the actual length
of the string, not counting the terminating null-symbol.</p>
<p><span class="def">char* setlength(string&, int)</span> changes the actual length
of the string. The content of the original string is preserved, however the content
of extra characters added during reallocation is undefined. This function returns
a pointer to a unique buffer (i.e. refcount is 1), like function <span class="lang">unique()</span>
below. Even if the length of the string is not changing, <span class="lang">setlength()</span>
guarantees to make the string unique.</p>
<p><span class="def">char* unique(string&)</span> makes the string buffer unique,
i.e. a new buffer is allocated and data is copied if necessary, so that the reference
count after calling this function is guaranteed to be 1. All string manipulation
functions call <span class="lang">unique()</span> whenever a modification is made
on the string buffer. You may need to call this function explicitly to obtain
a character pointer to the buffer; in all other cases reference counting mechanism
works transparently.</p>
<p><span class="def">bool isempty(string&amp;)</span> returns true if the given
string is empty. Using this function is preferable to comparing the string with
empty string literal &quot;&quot;.</p>
<p><span class="def">clear(string&amp;)</span> makes the given string empty. Using
this function is preferable to assigning an empty string literal &quot;&quot;.</p>
<p><span class="def">concat(string& s, const char* sc, int catlen)</span> adds
the given buffer <span class="lang">sc</span> of length <span class="lang">catlen</span>
to the string object <span class="lang">s</span>. Use operators + and += instead
to concatenate characters, null-terminated strings and string objects.</p>
<p><span class="def">string copy(const string& s, int from [, int cnt ] )</span>
returns a substring of <span class="lang">s</span> starting from position <span class="lang">from</span>
and containing <span class="lang">cnt</span> characters. If <span class="lang">cnt</span>
is omitted, the rest of the string <span class="lang">s</span> starting from position
<span class="lang">from</span> is returned.</p>
<p><span class="def">ins(..., string& s, int at)</span> inserts a character, a
null-terminated string, a string object or a buffer with specified length into
string object <span class="lang">s</span> at the given position <span class="lang">at</span>.
If the position is out of bounds, <span class="lang">ins()</span> does nothing.</p>
<p><span class="def">del(string& s, int at [, int cnt ] )</span> deletes <span class="lang">cnt</span>
characters starting from position <span class="lang">at</span> of the string <span class="lang">s</span>.
If <span class="lang">cnt</span> is omitted, the rest of the string starting from
<span class="lang">at</span> is deleted.</p>
<p><span class="def">int pos(..., const string& s)</span> returns the position
of the first occurrence of a character, a null-terminated string or a string object
(first parameter) in the source string <span class="lang">s</span>, or returns
-1 if the substring is not found. Function <span class="lang">rpos()</span> performs
reverse-search.</p>
<p><span class="def">bool contains(..., const string& s, int at)</span> returns
true if the given character, null-terminated string or string object (first parameter)
equals the substring of <span class="lang">s</span> at the given position <span class="lang">at</span>.</p>
<p class="seealso">See also: <a href="string.constructors.html">Constructors/destructors</a>,
<a href="string.operators.html">Operators</a>, <a href="string.typecasts.html">Typecasts</a>,
<a href="string.conversion.html">Conversion</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.operators.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string: operators</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="string.html">string</a>: Operators</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class string {
<span class="comment"> // assignment</span>
string& operator =(const char*);
string& operator =(char);
string& operator =(const string&);
friend void assign(string&, const char* buf, int len);
<span class="comment"> // concatenation</span>
string& operator +=(const char*);
string& operator +=(char);
string& operator +=(const string&);
string operator +(const char*) const;
string operator +(char) const;
string operator +(const string&) const;
friend string operator +(const char*, const string&);
friend string operator +(char c, const string&);
<span class="comment"> // comparison</span>
bool operator ==(const char*) const;
bool operator ==(char) const;
bool operator ==(const string&) const;
bool operator !=(const char*) const;
bool operator !=(char c) const;
bool operator !=(const string&) const;
<span class="comment"> // indexed character access, 0-based</span>
char& string::operator[] (int index);
const char& string::operator[] (int index) const;
}</pre>
</blockquote>
<p>The string class defines the following binary operators: assignment (<span class="lang">=</span>),
concatenation (<span class="lang">+</span>), concatenation with assignment (<span class="lang">+=</span>)
and comparison (<span class="lang">==</span>,<span class="lang"> !=</span>). At
least one of the operands (either left or right) must be of type <span class="lang">string</span>.
Another operand can be one of the following: <span class="lang">char</span>, <span class="lang">char*</span>
or <span class="lang">string</span>.</p>
<p>Indexed access operator allows to store or retrieve a value of an individual
character. The index is 0-based. When compiled with either <span class="lang">DEBUG</span>
or <span class="lang">CHECK_BOUNDS</span> conditional symbol, bounds checking
is performed for the indexed access; if the index is out of bounds (i.e. less
than 0 or equals to or greater than the length of the string), an unrecoverable
error is raised. The non-debugging version of the library never checks for index
overlfows, thus making your program somewhat faster but less safe.</p>
<p><b>Examples</b></p>
<blockquote>
<pre>string s1 = &quot;abc&quot;, s2 = 'd', s3;
s3 = s1 + s2;
s2 += &quot;ef&quot;;
s3[2] = 'B';
</pre>
</blockquote>
<p class="seealso">See also: <a href="string.constructors.html">Constructors/destructors</a>,
<a href="string.typecasts.html">Typecasts</a>, <a href="string.manipulation.html">Manipulation</a>,
<a href="string.conversion.html">Conversion</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/string.typecasts.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: string: typecasts</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="string.html">string</a>: Typecasts </p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class string {
operator (const char*)() const;
}</pre>
</blockquote>
<p>A string object can be assigned to a variable or passed as an actual parameter
of type <span class="lang">const char*</span> implicitly (by default). Such assignments
should be used carefully, since the library does not keep track of whether a char
pointer refers to the given string buffer. To make sure that a char pointer refers
to a valid string buffer, always make the scope of a char pointer variable smaller
than or equal to the scope of a string object. In most cases passing a string
object to a system or API call is safe (see examples below). This typecast operator
does not perform any actions and simply returns a pointer to the string buffer.</p>
<p>The value of the char pointer is guaranteed to be non-NULL. Even if the string
is empty, the char pointer will refer to a null-symbol.</p>
<p>A string buffer can not be modified through a constant char pointer. If you
want to modify the string buffer through a char pointer, use <span class="lang">unique(string&amp;)</span>
function instead. This function always returns a reference to a unique string
buffer (i.e. when the reference count is 1).</p>
<p><b>Compatibility note</b>: MSVC and GCC may treat type casts in different ways
when passing a string object to a function that takes (...) parameters, e.g. <span class="lang">printf()</span>
or <span class="lang">outstm::putf()</span>. You should explicitly instruct the
compiler to cast the string object to <span class="lang">(const char*)</span>
to avoid this problem. PTypes provides a shorter typedef <span class="lang">pconst</span>
for this.</p>
<p><b>Examples</b></p>
<blockquote>
<pre>
void assignment_example()
{
string s = &quot;abcdef&quot;;
const char* p = s;
<span class="comment">// do string manipulation here...</span>
}
void function_call_example()
{
string s = &quot;abcdef&quot;;
puts(s);
printf(&quot;%s\n&quot;, pconst(s));
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="string.constructors.html">Constructors/destructors</a>,
<a href="string.operators.html">Operators</a>, <a href="string.manipulation.html">Manipulation</a>,
<a href="string.conversion.html">Conversion</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/styles.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
p {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px}
td {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px}
h5 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px}
a:link { }
a:visited {color: #0066CC}
a:hover {color: #FF0033; text-decoration: underline}
a:active {color: #FF0033}
.seealso {font-weight: bold; background-color: #dddddd; padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 4px}
.lang {color: #557799; font-weight: bold }
.def {color: #557799; font-weight: bold }
.hpath {font-size: 16px; font-weight: bold; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; font-family: Arial, Helvetica, sans-serif; font-style: italic}
.comment { color: #009900; font-weight: normal;}
.menu {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px ; font-weight: bold}
.ns { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px}
li { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px }
.cdir { color: #0000FF; font-weight: normal; }
doc/time.calendar.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: date/time: calendar</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="time.html">Date/time</a>: Date/calendar manipulation</p>
<blockquote>
<pre class="lang">#include &lt;ptime.h&gt;
typedef large datetime;
bool isleapyear(int year);
int daysinmonth(int year, int month);
int daysinyear(int year, int month);
int dayofweek(datetime d);
bool isdatevalid(int year, int month, int day);
datetime encodedate(int year, int month, int day);
bool decodedate(datetime d, int& year, int& month, int& day);
</pre>
</blockquote>
<p><span class="def">bool isleapyear(int year)</span> determines whether <span class="lang">year</span>
is a leap year.</p>
<p><span class="def">int daysinmonth(int year, int month)</span> returns the
number of days in <span class="lang">month</span> (1 - 12). The parameter <span class="lang">year</span>
is needed to determine whether it's a leap year in order to return the correct
number of days for February. The returned value can be in the range 28 - 31. If
<span class="lang">month</span> is out of the allowed range (1 - 12) this function
returns 0.</p>
<p><span class="def">int daysinyear(int year, int month)</span> returns the number
of days since the beginning of the <span class="lang">year</span> up to the <span class="lang">month</span>
(1 - 12), inclusive. If <span class="lang">month</span> is 12 the function will
return the total number of days in the <span class="lang">year</span>. If <span class="lang">month</span>
is out of the allowed range (1 - 12) this function returns 0.</p>
<p><span class="def">int dayofweek(datetime d)</span> returns the day of the
week (0 - 6) for the given date <span class="lang">d</span>. 0 corresponds to
Sunday, 1 - Monday etc. This function does not check the value of <span class="lang">d</span>
for validity, it always returns some result in the range 0 - 6.</p>
<p><span class="def">bool isdatevalid(int year, int month, int day)</span> checks
the values of <span class="lang">year</span>, <span class="lang">month</span>
and <span class="lang">day</span> for validity. This function takes into account
that <span class="lang">day</span> must be in the correct range depending on <span class="lang">year</span>
and <span class="lang">month</span>. Also, it checks whether <span class="lang">year</span>
is in the allowed range 1 - 9999.</p>
<p><span class="def">datetime encodedate(int year, int month, int day)</span>
returns a <span class="lang">datetime</span> value, i.e. the number of milliseconds
since the beginning of the calendar up to the midnight of <span class="lang">month</span>/<span class="lang">day</span>/<span class="lang">year</span>.
This value can then be added to the value returned by <span class="lang">encodetime()</span>
to form the exact time stamp with millisecond precision, or it can be used alone
as a calendar date value without the time correction.</p>
<p><span class="def">bool decodedate(datetime d, int& year, int& month, int&
day)</span> is the inverse version of <span class="lang">encodedate()</span>:
it breaks the value of <span class="lang">d</span> into its <span class="lang">year</span>,
<span class="lang">month</span> and <span class="lang">day</span>. This function
returns <span class="lang">false</span> if the value of <span class="lang">d</span>
is invalid.</p>
<p class="seealso">See also: <a href="time.datetime.html">Datetime type</a>, <a href="time.time.html">Time
manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/time.datetime.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: date/time: datetime</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="time.html">Date/time</a>: Datetime type</p>
<blockquote>
<pre class="lang">#include &lt;ptime.h&gt;
typedef large datetime;
datetime now(bool utc = true);
int days(datetime d);
int msecs(datetime d);
datetime mkdt(int days, int msecs);
bool isvalid(datetime d);
void tzupdate();
int tzoffset();
string dttostring(datetime d, const char* fmt);
string nowstring(const char* fmt, bool utc = true);
datetime utodatetime(time_t u);</pre>
</blockquote>
<p><span class="def">datetime now(bool utc = true)</span> returns the current
date/time. The returned value can be either the local time or the Universal Coordinated
Time (UTC, aka GMT), depending on the parameter <span class="lang">utc</span>.
It is recommended to manipulate with the UTC time internally in your application
whenever possible (f.ex. when it's not needed to display the time to the user),
since in many countries the local time may be automatically adjusted when entering
or leaving the daylight saving period, which may confuse your application. On
the contrary, the UTC time never changes. That's why all modern operating systems
rely on the UTC time internally. (See also <span class="lang">tzupdate()</span>
below for additional notes).</p>
<p><span class="def">int days(datetime d)</span> returns the number of days since
the beginning of the calendar contained in the <span class="lang">datetime</span>
value <span class="lang">d</span>.</p>
<p><span class="def">int msecs(datetime d)</span> returns the number of milliseconds
since midnight contained in the <span class="lang">datetime</span> value <span class="lang">d</span>.</p>
<p><span class="def">datetime mkdt(int days, int msecs)</span> calculates the
datetime value from <span class="lang">days</span> and <span class="lang">msecs</span>
parameters. <span class="lang">Days</span> is the number of days since the beginning
of the calendar, and <span class="lang">msecs</span> is the number of milliseconds
since midnight. No checks are made for validity of these values. There exists
an easier way to build a datetime value using <span class="lang">encodedate()</span>
and <span class="lang">encodetime()</span> functions having the year, month and
day numbers, as well as (not necessarily) the hour, minute, second and millisecond
values.</p>
<p><span class="def">bool isvalid(datetime d)</span> checks a <span class="lang">datetime</span>
value for validity. The value of <span class="lang">d</span> is valid if it holds
a time stamp between 01/01/0001 and 12/31/9999.</p>
<p><span class="def">void tzupdate()</span> updates the internal timezone information,
which affects the value of local time returned by <span class="lang">now()</span>
and <span class="lang">nowstring()</span>. If your application is supposed to
be running infinitely (e.g. if it's a network daemon), you might want to update
the internal timezone information from time to time in order to return correct
local time to the user on DST adjustment days. Depending on the precision of local
time you wish to show to the user, you can call this function, for example, every
minute or every hour. Without this, the local time may become incorrect at the
moment of DST adjustment, which occurs twice a year in most countries.</p>
<p><span class="def">int tzoffset()</span> returns the time zone offset in minutes.
This value is negative in the West. Multiplying this value by 60000 (i.e. the
offset in milliseconds) and adding it to the UTC <span class="lang">datetime</span>
value will give the local time.</p>
<p><span class="def">string dttostring(datetime d, const char* fmt)</span> converts
a <span class="lang">datetime</span> value to string representation as specified
by <span class="lang">fmt</span>. The syntax of the format specifier is the same
as for <span class="lang">strftime()</span> (please, refer to the corresponding
manual pages in your programming environment). Note that there might be slight
incompatibilities between different implementations of <span class="lang">strftime()</span>.
</p>
<p><span class="def">string nowstring(const char* fmt, bool utc = true)</span>
returns a string representing the current time in a format specified by <span class="lang">fmt</span>.
<span class="lang">Utc</span> specifies whether the local time or the UTC time
is required. Like for <span class="lang">dttostring()</span>, the syntax of the
format specifier <span class="lang">fmt</span> is the same as for the system function
<span class="lang">strftime()</span>.</p>
<p><span class="def">datetime utodatetime(time_t u)</span> converts UNIX <span class="lang">time_t</span>
value to PTypes <span class="lang">datetime</span>.</p>
<p class="seealso">See also: <a href="time.calendar.html">Date/calendar manipulation</a>,
<a href="time.time.html">Time manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/time.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: date/time: </title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
Date/time: </p>
<ul>
<li>
<h5><a href="time.datetime.html">Datetime type</a></h5>
</li>
<li>
<h5><a href="time.calendar.html">Date/calendar manipulation</a></h5>
</li>
<li>
<h5><a href="time.time.html">Time manipulation</a></h5>
</li>
</ul>
<p>The <span class="lang">datetime</span> data type and the accompanying utilities
provide portable (system-independent) means of calendar and time manipulation.
<span class="lang">Datetime</span> is equivalent to signed 64-bit integer type
(<span class="lang">large</span> type in PTypes) which holds a time value with
a millisecond precision in the range of dates 01/01/0001 through 12/31/9999. The
value of a datetime variable represents the number of milliseconds since the beginning
of the calendar, i.e. midnight January 1st, year 1. The upper limit is caused
by the fact that the leap year rule may (and most likely will) change after the
year 10000.</p>
<p>Variables of type <span class="lang">datetime</span> can be used in various
ways: as a date/time stamp, as a difference between two events in the range from
1 millisecond up to 10,000 years, as a date alone without the time (e.g. for calendar
manipulation), and as a time value alone.</p>
<p>The date/time manipulation functions are divided into 3 groups in this documentation:
<a href="time.datetime.html">general</a>, <a href="time.calendar.html">date/calendar</a>
and <a href="time.time.html">time</a>. Most of these functions work with parameters
of type <span class="lang">datetime</span>. The prototypes and other declarations
are in the header file <a href="include/ptime.h.html">&lt;ptime.h&gt;</a>. </p>
<p>Here are some examples of using <span class="lang">datetime</span> and the
accompanying utilities:</p>
<blockquote>
<pre>#include &lt;pasync.h&gt; <span class="comment">// for psleep()</span>
#include &lt;ptime.h&gt;
#include &lt;pstreams.h&gt;
USING_PTYPES
int main()
{
<span class="comment">// PTypes' birthday (birth moment, if you wish)</span>
datetime d = encodedate(2000, 3, 30) + encodetime(13, 24, 58, 995);
<span class="comment">// The format specifier %t is for timestamps</span>
pout.putf("PTypes' birth moment: %t\n", d);
<span class="comment">// now see how old is PTypes in milliseconds</span>
datetime diff = now() - d;
int hours, mins, secs, msecs;
decodetime(diff, hours, mins, secs, msecs);
pout.putf("PTypes' life time: %d hours %d minutes %d seconds and %d milliseconds\n",
days(diff) * 24 + hours, mins, secs, msecs);
<span class="comment">// measure the difference in milliseconds between two calls to now()</span>
datetime m = now();
psleep(17); <span class="comment">// sleep 17 milliseconds</span>
pout.putf("A 17 millisecond dream lasted actually %d milliseconds\n", now() - m);
<span class="comment">// this will show the actual precision of the clock on the given platform;
// Windows, f.ex., always shows the difference in 10 msec increments</span>
}
</pre>
</blockquote>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/time.time.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: date/time: time</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="time.html">Date/time</a>: Time manipulation</p>
<blockquote>
<pre class="lang">#include &lt;ptime.h&gt;
typedef large datetime;
bool istimevalid(int hour, int min, int sec, int msec = 0);
datetime encodetime(int hour, int min, int sec, int msec = 0);
bool decodetime(datetime d, int& hour, int& min, int& sec [, int& msec] );
</pre>
</blockquote>
<p><span class="def">bool istimevalid(int hour, int min, int sec, int msec =
0)</span> checks whether <span class="lang">hour</span>, <span class="lang">min</span>,
<span class="lang">sec</span> and <span class="lang">msec</span> (millisecond)
contain correct values in their respective ranges. The last parameter is optional.</p>
<p><span class="def">datetime encodetime(int hour, int min, int sec, int msec
= 0)</span> returns a <span class="lang">datetime</span> value, i.e. the number
of milliseconds since midnight. This function does NOT check the input parameters
for validity. The value returned by this function can be added to the return value
of <span class="lang">encodedate()</span> to form the exact time stamp for the
given year, month, day, hour, minute, second and (optionally) millisecond.</p>
<p><span class="def">bool decodetime(datetime d, int& hour, int& min, int& sec
[, int& msec] )</span> splits the value of <span class="lang">d</span> into <span class="lang">hour</span>,
<span class="lang">minute</span>, <span class="lang">sec</span> and <span class="lang">msec</span>
(millisecond) passed since midnight. The last parameter is optional.</p>
<p class="seealso">See also: <a href="time.datetime.html">Datetime type</a>, <a href="time.calendar.html">Date/calendar
manipulation</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/unit.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: unit</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
unit</p>
<p>
<blockquote>
<pre class="lang">#include &lt;pstreams.h&gt;
class unit {
compref&lt;instm&gt; uin;
compref&lt;outstm&gt; uout;
virtual void main() = 0;
virtual void cleanup() = 0;
void connect(unit* next);
void run(bool async = false);
void waitfor();
}</pre>
</blockquote>
<p><span class="lang">Units</span> represent functionality similar to console
applications in UNIX. Each unit has its own <span class="lang">main()</span> along
with input and output 'plugs' - <span class="lang">uin</span> and <span class="lang">uout</span>,
that may be mapped to the standard input and output, a local pipe or any other
stream compatible with <span class="lang">instm</span> and <span class="lang">outstm</span>,
respectively. </p>
<p>Each unit class must at least override the abstract method <span class="lang">main()</span>.
Overridden unit classes typically read input data from <span class="lang">uin</span>
and send the result of processing to <span class="lang">uout</span>, like if they
were console applications. By default <span class="lang">uin</span> and <span class="lang">uout</span>
are attached to standard input and output. After instantiating a unit object you
(the user of a unit class) may attach any <span class="lang">instm</span>-compatible
stream to <span class="lang">uin</span> and any <span class="lang">outstm</span>-compatible
stream to <span class="lang">uout</span>. In addition, units are able to connect
to each other using local pipes, and thus form data processing chains within your
application.</p>
<p>You may define other public methods or fields in your unit class that represent
additional options. E.g. a regular expression parser unit may have a string field
that represents the regular expression itself (see example below).</p>
<p>Units can be run either synchronously or asynchronously. In the latter case,
a separate thread is created for executing unit's <span class="lang">main()</span>
function. If connected to a pipe using <span class="lang">connect()</span>, the
first unit in the chain runs within the scope of the calling thread, the others
run in separate threads.</p>
<p>The <span class="lang">unit</span> class is a subclass of <a href="unknown.html">component</a>,
and thus it inherits reference counting and delete notification mechanisms from
<span class="lang">component</span>. <span class="lang">Unit</span> is declared
in <a href="include/pstreams.h.html">&lt;pstreams.h&gt;</a>.</p>
<p>This interface is available only in the multithreaded versions of the library.
</p>
<p><span class="def">compref&lt;instm&gt; unit::uin</span> is a reference-counted
pointer to an input stream, that is unit's input 'plug'. By default <span class="lang">uin</span>
refers to the standard input object <span class="lang">pin</span>. Typically both
<span class="lang">uin</span> and <span class="lang">uout</span> are assigned
by the user of the unit after instantiating a unit object. You may assign dynamically
allocated stream objects to <span class="lang">uin</span> and <span class="lang">uout</span>
- they will be freed automatically by the 'smart' <span class="lang">compref</span>
pointer.</p>
<p><span class="def">compref&lt;outstm&gt; unit::uout</span> -- same as <span class="lang">uin</span>;
represents the output 'plug' of the unit.</p>
<p><span class="def">virtual void unit::main()</span> is unit's main code. Override
this method to implement functionality of your mini-process. Note that code in
<span class="lang">main()</span> must avoid accessing static/global data, since
it may be executed in a separate thread. You may choose to write a reusable unit,
i.e. when <span class="lang">main()</span> can be called multiple times for the
same object, however <span class="lang">main()</span> is protected from overlapping
(recursive) calls, which means, you need not to write reentrant code in this function.</p>
<p><span class="def">virtual void unit::cleanup()</span> -- override this method
to perform finalization and cleanup of a unit. This function is guaranteed to
be called even if <span class="lang">main()</span> threw an exception of type
<span class="lang">(exception*)</span> or a derivative.</p>
<p><span class="def">void unit::connect(unit* next)</span> connects a unit object
to another object using a local pipe. Multiple units can be connected to form
a chain. A user then calls <span class="lang">run()</span> for the first object;
all other members of the chain are started automatically in separate threads.</p>
<p><span class="def">void unit::run(bool async = false)</span> runs a unit object.
This function calls <span class="lang">main()</span> for the given object and
possibly for other units, if this is the first object of a chain. You can not
call <span class="lang">run()</span> for an object which is not the first in a
chain. If <span class="lang">async</span> is <span class="lang">true</span>, this
function starts a unit in a separate thread and returns immediately. Use <span class="lang">waitfor()</span>
to synchronize with the completion of a unit if started asynchronously.</p>
<p><span class="def">void unit::waitfor()</span> waits for the unit to terminate
if run asynchronously. For unit chains, this method needs to be called only for
the first object in a chain.</p>
<p><b>Example</b>. Consider there is a unit type <span class="lang">ugrep</span>
that performs regular expression matching and a unit type <span class="lang">utextconv</span>
for converting various text formats. The code below demonstrates how to connect
these units and run the chain.</p>
<blockquote>
<pre>#include &lt;pstreams.h&gt;
#include &quot;ugrep.h&quot; <span class="comment">// imaginary headers with unit declarations</span>
#include &quot;utextconv.h&quot;
USING_PTYPES
int main()
{
ugrep grep;
grep.regex = &quot;^abc&quot;;
grep.casesens = false;
utextconv textconv;
textconv.from = CONV_UNIX;
textconv.to = CONV_WIN;
<span class="comment">// connect the two units and set up the input and output plugs.
</span> grep.uin = new ipstream(&quot;somehost.com&quot;, 8282);
grep.connect(&amp;textconv);
textconv.uout = new outfile(&quot;output.txt&quot;);
<span class="comment">// now run the chain; will read input from the socket, pass
// through the grep and textconv units and write it to the
// output file.</span>
grep.run();
}
</pre>
</blockquote>
<p class="seealso">See also: <a href="unknown.html">unknown &amp; component</a>,
<a href="streams.html">Streams</a> </p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/unknown.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: unknown &amp; component</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
unknown &amp; component</p>
<p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
class unknown {
unknown();
virtual ~unknown();
}
class component {
component();
virtual ~component();
void addnotification(component* c);
void delnotification(component* c);
virtual void freenotify(component* c);
}
component* addref(component*);
bool release(component*);
template &lt;class T&gt; class compref;
int objalloc;</pre>
</blockquote>
<p>The <span class="lang">unknown</span> interface is the base for all interfaces
(classes) in PTypes, <b>except</b> <span class="lang">string</span>, <span class="lang">cset</span>,
<span class="lang">variant</span>, <span class="lang">mutex</span>, <span class="lang">rwlock</span>,
<span class="lang">msgqueue</span> and <span class="lang">tpodlist</span>. The
<span class="lang">unknown</span> class has no semantic or functional meaning,
except that deriving a class from <span class="lang">unknown</span> provides a
simple mechanism of tracking the number of created/destroyed objects in a program.
Historically, <span class="lang">unknown</span> was used in PTypes as a base for
all list item types, however, starting from version 2.0 of the library this requirement
is no longer in place.</p>
<p>The <span class="lang">component</span> class adds reference-counting functionality
to <span class="lang">unknown</span> (see <span class="lang">addref()</span> and
<span class="lang">release()</span> below). PTypes variants require objects to
be derived from <span class="lang">component</span> instead of <span class="lang">unknown</span>
to be able to make assignments and destruction of variants properly. See also
<span class="lang">compref </span>below.</p>
<p>As an alternative to reference-counting <span class="lang">component</span>
also provides so-called 'delete notification' mechanism. If object A holds a reference
to object B, A can add itself to B's notification list to be notified when B is
being destroyed. This allows A to take appropriate actions, e.g. invalidate the
reference to B. A in this case can declare reference to B as a plain pointer.
In other words, A should override its own virtual method <span class="lang">freenotify()</span>,
and it also should call <span class="lang">addnotification(this)</span> for the
object it holds reference to.</p>
<p>All stream objects in PTypes and aslo the <span class="lang">unit</span> class
are derived from <span class="lang">component</span>.</p>
<p>A global variable <span class="lang">objalloc</span> is declared to keep track
of the number of allocated objects (derived from <span class="lang">unknown</span>
or <span class="lang">component</span>) in an application program, which can help
you to find memory leaks or other potential bugs. The allocation counting works
only in <span class="lang">DEBUG</span> mode. If the memory is cleaned up properly,
this value should be zero upon program termination. You can write code, possibly
enclosed within <span class="lang">#ifdef DEBUG ... #endif</span>, which checks
whether this value is zero at the end of <span class="lang">main()</span>.</p>
<p>These interfaces are declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p><span class="def">component* addref(component* c)</span> increments the reference
counter for the given component object <span class="lang">c</span>. The return
value is the same as <span class="lang">c</span> and is provided for convenience.</p>
<p><span class="def">bool release(component* c)</span> decrements the reference
counter and destroys the object <span class="lang">c</span> if the counter reached
0. Returns <span class="lang">true</span> if the object has been destroyed. Passing
<span class="lang">NULL</span> to this function is not an error.</p>
<p><span class="def">template &lt;class T&gt; class compref</span> implements
a 'smart' pointer to <span class="lang">component</span> (or any derivative class)
with automatic reference counting. Use this template in place of a plain pointer
declaration (e.g. <span class="lang">compref&lt;myclass&gt;</span> instead of
<span class="lang">myclass*</span>) to automatically destroy objects as soon as
there are no more references left. The behavior of <span class="lang">compref</span>
pointers is similar to plain pointers, except that they perform additional actions
when assigning new values to them.</p>
<p><span class="def">virtual component::~component()</span> destroys the component
and calls <span class="lang">freenotify()</span> for each object in the notification
list.</p>
<p><span class="def">component::addnotification(component* c)</span> adds object
<span class="lang">c</span> to the notification list of this object. This object's
destructor will then call <span class="lang">c-&gt;freenotify()</span>.</p>
<p><span class="def">component::delnotification(component* c)</span> deletes object
<span class="lang">c</span> from this object's notification list.</p>
<p><span class="def">virtual component::freenotify(component* caller)</span> is
called by the <span class="lang">caller</span>'s destructor for each object
in the notification list. This method should be overriden in classes which add
themselves to other objects' notification lists. The overridden method usually
invalidates (assigns NULL) all references to <span class="lang">caller</span>.</p>
<p class="seealso">See also: <a href="lists.html">Lists</a>, <a href="variant.html">variant</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/variant.arrays.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: variant: arrays</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="variant.html">variant</a>: Arrays</p>
<blockquote>
<pre class="lang">
#include &lt;ptypes.h&gt;
void aclear(variant&amp; a);<br>variant aclone(const variant&amp; a);
void put(variant&amp; a, <i>&lt;key&gt;</i>, const variant&amp; item);
const variant&amp; get(const variant&amp; a, <i>&lt;key&gt;</i>);
const variant&amp; variant::operator [](<i>&lt;key&gt;</i>) const;
void del(variant&amp; a, <i>&lt;key&gt;</i>);
bool anext(const variant&amp; array, int&amp; index, variant&amp; item, [ string&amp; key ]);
</pre>
</blockquote>
<p>A variant object can hold an associative array of variants. The variant changes
its type to an array as soon as <span class="lang">put()</span> or <span class="lang">aclear()</span>
is called for an object. When assigning variants, only a reference to an array
is being copied, which means, modifying an array through one variant object affects
all other objects that hold a reference to the same array. To duplicate the contents
of an array use <span class="lang">aclone()</span>.</p>
<p>Variant arrays can associate values with either strings or integers (32 or
64 bit). Integer keys are not required to be consecutive. It should be noted that
in the current implementation there is no difference in performance between these
two methods. Both methods can be mixed in one array.</p>
<p>PTypes uses reference counting on arrays to properly clean up unused dynamic
structures. However, since variant arrays may recursively contain arrays and in
some situations there may be a circular reference, it is possible to have memory
leak when using such structures. Since PTypes does not provide garbage collection
(e.g. like in Java), compound variant data structures should be designed so that
variants never reference each other circularly.</p>
<p><span class="def">void aclear(variant&amp; a)</span> clears the variant array.
This function may affect other variant objects holding a reference to the same
array data.</p>
<p><span class="def">variant aclone(const variant&amp; a)</span> creates a copy
of an array or creates an empty array if <span class="lang">a</span> is of any
other variant type. If <span class="lang">a</span> contains variant arrays as
elements, only their references are copied.</p>
<p><span class="def">void put(variant&amp; a, <i>&lt;key&gt;</i>, const variant&amp;
item)</span> associates <span class="lang">item</span> with <span class="lang">key</span>
in the variant array <span class="lang">a</span>. <span class="lang">Key</span>
can be either a string or an integer. The previous value associated with this
key, if any, is replaced with the new value. <span class="lang"></span>If <span class="lang">item</span>
is an unassigned variant, the new value is not stored in the array.</p>
<p><span class="def">const variant&amp; get(const variant&amp; a, <i>&lt;key&gt;</i>)</span>
retrieves an element associated with <span class="lang">key</span> in the array
<span class="lang">a</span>. If the element does not exist, or <span class="lang">a</span>
is not an array, this function returns an unassigned variant (a reference to <span class="lang">nullvar</span>).
<span class="lang">Key</span> can be either a string or an integer. Variant arrays
use hashing to retrieve elements by keys.</p>
<p><span class="def">const variant&amp; variant::operator [](<i>&lt;key&gt;</i>)</span>
equivalent to <span class="lang">get()</span>. This operator can be used only
for retrieving elements.</p>
<p><span class="def">void del(variant&amp; a, <i>&lt;key&gt;</i>)</span> removes
the element associated with <span class="lang">key</span> from the array <span class="lang">a</span>.
Does nothing if the element does not exist or <span class="lang">a</span> is not
an array. Equivalent to calling <span class="lang">put()</span> with an unassigned
variant item.</p>
<p><span class="def">bool anext(const variant&amp; a, int&amp; index, variant&amp;
item, [ string&amp; key ])</span> iterates through array elements (please see
examples in the introduction to variants). Each time <span class="lang">anext()</span>
is called it assigns the next item in the array to <span class="lang">item</span>
and optionally assigns its key value to <span class="lang">key</span>. <span class="lang">Index</span>
must be zero when calling this function first time. If there are no items left
in the array, or <span class="lang">a</span> is not an array, this function returns
<span class="lang">false</span>.</p>
<p class="seealso">See also: <a href="string.html">string</a>, <a href="variant.typecasts.html">Assignments
and typecasts</a>, <a href="variant.objrefs.html">Object references</a>, <a href="variant.utils.html">Utilities</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/variant.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: variant</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
variant </p>
<ul>
<li>
<h5><a href="variant.typecasts.html">Assignments and typecasts</a></h5>
</li>
<li>
<h5><a href="variant.arrays.html">Arrays</a></h5>
</li>
<li>
<h5><a href="variant.objrefs.html">Object references</a></h5>
</li>
<li>
<h5><a href="variant.utils.html">Utilities</a></h5>
</li>
</ul>
<p>The <span class="lang">variant</span> class offers a universal and flexible
way to store values whose types can not be determined at compile time. A variant
object can hold integer, boolean, floating point or string values as well as associative
arrays of variants or references to objects derived from <span class="lang">component</span>.
Variants can change their types at run-time. In return for their flexibility,
variants have some memory usage and performance overhead. They always occupy 12
bytes of static or local memory, however, they may also use dynamic memory allocation
for strings and arrays.</p>
<p>The <span class="lang">variant</span> class provides all possible automatic
typecasts, so that in most cases, when variants are used in assignments and function
calls, the compiler will generate implicit typecasts appropriate for the context.
The typecast functions always try to perform conversion regardless of the current
and target types, although it may not always be sensible. For example, if a variant
object holds an integer value, an attempt to cast it to a string will result in
converting the value to its string representation; if a variant is an associative
array, an attempt to cast it to boolean will return true if the array is not empty.
Variant typecast routines never generate errors except when a 64-bit integer value
is converted to 32-bit int and the value exceeds the allowed range.</p>
<p>A variant variable may itself represent an associative array of variants. </p>
<p>This interface can be useful for (but not limited to) designing interpreters
and compilers, working with databases and spreadsheets, etc. </p>
<p>The variant class is declared in <a href="include/ptypes.h.html">&lt;ptypes.h&gt;</a>.</p>
<p><b>Examples</b></p>
<blockquote>
<pre>variant v1 = 11;
variant v2 = &quot;33&quot;;
variant v3 = int(v1) + int(v2) + 22; <span class="comment">// explicit typecasts: without them the compiler can't</span>
variant v4 = string(v2) + &quot; cows&quot;; <span class="comment">// figure out which of + operators to use here</span>
large i1 = v1; <span class="comment">// implicit typecast is possible here</span>
int a = v2; <span class="comment">// large-to-int: may generate (evariant*) exception</span>
variant v5;
put(v5, &quot;key1&quot;, v1); <span class="comment">// variants may be associated with both strings and</span>
put(v5, 15, &quot;value2&quot;); <span class="comment">// integer values in variant arrays</span>
variant v6 = v5[15];
variant v7 = v5; <span class="comment">// a reference to the array is passed</span>
variant varray = aclone(v5); <span class="comment">// array is duplicated</span>
variant item; <span class="comment"> // array iteration example</span>
for (int i = 0; anext(varray, i, item); )
pout.putf(&quot;%d: %d\n&quot;, i, int(item));<br></pre>
</blockquote>
<p class="seealso">See also: <a href="string.html">string</a>, <a href="unknown.html">unknown
&amp; component</a>, <a href="variant.typecasts.html">Assignments and typecasts</a>,
<a href="variant.arrays.html">Arrays</a>, <a href="variant.objrefs.html">Object
references</a>, <a href="variant.utils.html">Utilities</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/variant.objrefs.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: variant: object references</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="variant.html">variant</a>: Object references</p>
<p><br>
Variants can hold references to objects derived from <span class="lang">component</span>.
PTypes performs reference counting, so that assigning variants containing object
references can be considered safe: an object will only be destroyed when there
are no more references left to it. If you want to control the destruction of an
object 'manually', you can increment the reference count with <span class="lang">addref()</span>
before assigning a reference to a variant (see <a href="unknown.html">unknown
&amp; component</a>). In this case, each call to <span class="lang">addref()</span>
should be balanced with a call to <span class="lang">release()</span>.</p>
<p>It should be noted that the reference counting mechanism has a potential flaw
which may lead to memory leaks. Consider two objects containing variants with
cross-referencing pointers to each other. The library can not keep track of such
circular references, and an attempt to free one of the objects will result in
destroying only one of them and leaving the other in the memory without any references
to it. This is a known problem and can be solved by either eliminating circular
references when designing data structures or by providing a complex memory 'garbage
collector' which keeps track of all object references in the program.</p>
<p class="seealso">See also: <a href="unknown.html">unknown &amp; component</a>,
<a href="variant.typecasts.html">Assignments and typecasts</a>, <a href="variant.arrays.html">Arrays</a>,
<a href="variant.utils.html">Utilities</a> </p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/variant.typecasts.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: variant: assignments and typecasts</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="variant.html">variant</a>: Assignments and typecasts</p>
<p><br>
Variants may hold values of the following types:</p>
<ul>
<li>64-bit integer (<span class="lang">large</span>)</li>
<li>boolean (<span class="lang">bool</span>)</li>
<li>floating point (<span class="lang">double</span>)</li>
<li><span class="lang">string</span></li>
<li>associative array of variants</li>
<li>reference to an object derived from <span class="lang">component</span></li>
<li>unassigned (no type)</li>
</ul>
<p>Variants are compatible with variables and constants of all numeric types,
the string type and a pointer to <span class="lang">component</span>, which means,
you can assign any of these values to a variant object and vice versa, including
passing as parameters to functions. The type of a variant can be changed at run-time
by simply assigning a new value to it. </p>
<p>By default variants are initialized to an unassigned state, which is the same
as calling <span class="lang">clear()</span> for a variant object.</p>
<p>You may store <span class="lang">datetime</span> values in variants, since
<span class="lang">datetime</span> is equivalent to <span class="lang">large</span>
in PTypes. Besides, arbitrary binary data can be stored in a dynamic string and
then assigned to a variant.</p>
<p>The variant class declares (or rather, overloads) all possible typecast operators
to other fundamental data types. These typecast operators always try to return
some value, even when it is not sensible. Below is a list of rules for typecasts
that may make sense in your program, leaving the other less meaningful cases as
'unspecified'. Although variants store integers as 64-bit values, for simplicity
we use the word <span class="lang">int</span> in this list.</p>
<ul>
<li>integers and floating point variants are compatible and mutually castable
in a manner similar to the C language rules</li>
<li>int to bool: returns true if the value is non-zero</li>
<li>int to string: returns the string representing the value in ASCII form</li>
<li>bool to int: returns 0 or 1</li>
<li>bool to string: returns &quot;0&quot; or &quot;1&quot;</li>
<li>string to int: converts the string to an integer; no spaces are allowed before
or after the number; returns 0 if the string does not represent a number</li>
<li>string to float: similar to string-to-int, converts the string to a floating-point
value</li>
<li>string to bool: returns true if the string is not empty</li>
<li>array to bool: returns true if the array is not empty</li>
<li>(component*) to bool: returns true if the pointer is not NULL</li>
<li>unassigned variants return 0, false, 0.0, empty string, empty array or NULL
when trying to cast to int, boolean, floating point, string, array or reference,
respectively.</li>
</ul>
<p>Typecast operators never affect the actual value of a variant object.</p>
<p>When trying to cast a variant to signed or unsigned 32-bit <span class="lang">int</span>,
the typecast operator first casts the value to 64-bit <span class="lang">large</span>
according to the rules above, and then checks the resulting value. If the value
is out of range, an exception of type (evariant*) is raised. You may always cast
variants to <span class="lang">large</span> to get rid of extra exception handling
code in your program.</p>
<p class="seealso">See also: <a href="string.html">string</a>, <a href="time.html">datetime</a>,
<a href="unknown.html">unknown &amp; component</a>, <a href="variant.arrays.html">Arrays</a>,
<a href="variant.objrefs.html">Object references</a>, <a href="variant.utils.html">Utilities</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/variant.utils.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: variant: utilities</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: <a href="basic.html">Basic types</a>:
<a href="variant.html">variant</a>: Utilities</p>
<blockquote>
<pre class="lang">#include &lt;ptypes.h&gt;
enum { VAR_NULL, VAR_INT, VAR_BOOL, VAR_FLOAT,
VAR_STRING, VAR_ARRAY, VAR_OBJECT };
void clear(variant&amp;);
int vartype(const variant&amp;);
bool isnull(const variant&amp;);
bool isint(const variant&amp;);
bool isbool(const variant&amp;);
bool isfloat(const variant&amp;);
bool isstring(const variant&amp;);
bool isarray(const variant&amp;);
bool isobject(const variant&amp;);
const variant nullvar;
</pre>
</blockquote>
<p><span class="def">void clear(variant&amp;)</span> clears the variant and sets
its state to unassigned (null).</p>
<p><span class="def">int vartype(const variant&amp;)</span> returns the type of
a variant, which can be compared with one of the <span class="lang">VAR_XXX</span>
constants.</p>
<p><span class="def">bool isXXX(const variant&amp;)</span> this group of inlined
functions is provided to check whether the variant is of particular type.</p>
<p class="seealso">See also: <a href="variant.typecasts.html">Assignments and
typecasts</a>, <a href="variant.arrays.html">Arrays</a>, <a href="variant.objrefs.html">Object
references</a></p>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
doc/wshare.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<html><!-- #BeginTemplate "/Templates/tmpl.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>PTypes: wshare</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<p><a href="../index.html"><img src="title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1" border="0"></a>
<hr size="1" noshade>
<!-- #BeginEditable "body" -->
<p class="hpath"><a href="index.html">Top</a>: PTypes demo program -- wshare</p>
<p><b><br>
Overview</b></p>
<blockquote>
<p><span class="lang">Wshare</span> is a simple multithreaded web server (HTTP
daemon) that uses almost all functional parts of the library and serves as an
example of using PTypes. <span class="lang">Wshare</span> supports protocol versions
up to HTTP/1.1. It provides simple means of sharing files over the web, but it
lacks server-side scripting and authentication functionality.</p>
<blockquote>
<p><i> The program is covered by the same license as PTypes. The authors can not
be responsible for any data loss or accidental disclosure of confidential information
caused by this software. It is provided `as is' with the hope that it can be useful
both as a library demo program and a simple web server.</i></p>
</blockquote>
<p>The sources are in <span class="lang">./wshare</span>. On UNIX, this application
is built along with the library and is copied to <span class="lang">./bin</span>.
For MSVC, a separate project is provided as a part of the PTypes workspace. For
BCC on Windows, the makefile is <span class="lang">wshare/wshare.mak</span>.</p>
<p><span class="lang">Wshare</span> does not require any special installation
or configuration procedures and can be easily run from the command line with at
least one parameter: the directory you wish to share over the web. Note that <span class="lang">wshare</span>
does not understand <span class="lang">.htaccess</span> or any other configuration
files in your directories, so the web site you might previously have will run
with <span class="lang">wshare</span>'s default configuration and access rights.</p>
<p><span class="lang">Wshare</span> is scalable: you can write your own handlers
for new HTTP methods, virtual paths and for specific file extensions. Currently
custom modules can be incorporated into <span class="lang">wshare</span> only
at compile-time. Please, see <span class="lang">wshare/modules.h</span> and <span class="lang">wshare/request.h</span>
for details. Also take a look at the sample compile-time module <span class="lang">wshare/mod_about.cxx.</span></p>
<p>Please, run the program to see the summary of the command-line options.</p>
<blockquote>
<pre class="lang">
usage: wshare [options] document-root
-D daemonize, UNIX only
-d allow directory indexes
-g group group ID to run as, UNIX only
-n num maximum number of simultaneous connections (default: 30)
-o file-name write HTTP access log to file-name
-p port-num port number to listen to
-u user user ID to run as, UNIX only
-x always show directory indexes (ignore default index files)
</pre>
</blockquote>
</blockquote>
<p><b><br>
Running on UNIX</b></p>
<blockquote>
<p>By default the daemon is trying to bind to port 80, which is a privileged port
on UNIX. You will have to either run it as root, or to specify a port number higher
than 1024 with the option <span class="lang">-p&nbsp;<i>port-number</i></span>,
e.g. <span class="lang">-p 8080</span>.</p>
<p><span class="lang">Wshare</span> uses UNIX's syslog to log error messages.
The HTTP access log goes to stderr, which can be overridden with <span class="lang">-o&nbsp;<i>logfile</i></span>.</p>
<p><span class="lang">Wshare</span> can also daemonize itself, i.e. detach from
the console and remain active after the user logs out. Use option <span class="lang">-D</span>
to daemonize the program. After that, the only way to stop the server is to send
a SIGKILL signal, i.e. determine the process ID with <span class="lang">ps</span>
and then invoke <span class="lang">kill&nbsp;-KILL&nbsp;<i>PID</i></span>. On
some systems you will need to use <span class="lang">ps</span> with the option
that specifies your user ID.</p>
<p>For better security, <span class="lang">wshare</span> can downgrade process
privileges to the user/group specified through <span class="lang">-u <i>user</i></span>
and <span class="lang">-g <i>group</i></span> command-line options. This is done
after binding to the socket and opening the log file. If <span class="lang">-g</span>
is omitted and only <span class="lang">-u</span> is specified, <span class="lang">wshare</span>
downgrades the process to the primary group of that user. For example, if you
specify <span class="lang">-u nobody</span>, the group will be automatically assigned
to a group <span class="lang">nobody</span>.</p>
</blockquote>
<p><b><br>
Running on Windows</b></p>
<blockquote>
<p>On Windows <span class="lang">wshare</span> runs as a simple console application.
All you can do with <span class="lang">wshare</span> on Windows is to specify
a different port to bind to with option <span class="lang">-p&nbsp;<i>port-number</i></span>
and to redirect the HTTP access log to some file with option <span class="lang">-o&nbsp;<i>logfile</i></span>.
Redirecting the access log to a file instead of writing it to the console window
can speed up the server.</p>
</blockquote>
<p><b><br>
Common features</b></p>
<blockquote>
<p>By default <span class="lang">wshare</span> does not generate directory indexes
(analogue of `Option Indexes' in Apache's configuration), which means the directory
must have a default index file named as either of: <span class="lang">index.html</span>,
<span class="lang">Index.html</span> or <span class="lang">default.htm</span>.
Directory indexes can be allowed by specifying option <span class="lang">-d</span>.
In this case, if the directory does not have any of the default index files listed
above, <span class="lang">wshare</span> will generate a page with the list of
files the directory contains.</p>
<p>If you don't want default index files at all, use option <span class="lang">-x</span>
in the command line: the server will then show the directory indexes, like if
you specified an empty &quot;DirectoryIndex&quot; directive with Apache.</p>
<p>You can limit the number of simultaneous connections with option <span class="lang">-n
<i>num</i></span>, which is 30 by default. When the number of connections reaches
<span class="lang">num/2</span> , the server stops supporting persistent connections.
When it reaches <span class="lang">num</span>, the server sends &quot;503 Service
unavailable&quot; to the client. And finally, when the number of connection requests
reaches <span class="lang">num * 2</span>, wshare simply aborts the connection
by closing the socket.</p>
<p>You can get the current status of the server by requesting <span class="lang">http://localhost/.wstat</span>
in your browser. <span class="lang">Wshare</span> responds to this request only
if the client is on the same host as the server, i.e. <span class="lang">localhost</span>
or 127.0.0.1.</p>
<p>Some other features are hardcoded into <span class="lang">wshare</span> and
can be changed only by recompiling it. The list of default index files can be
found in <span class="lang">wshare/config.cxx</span>, and the file extension-to-MIME
translation table is in <span class="lang">wshare/mimetable.cxx</span>. An awk
script <span class="lang">wshare/mimetable.awk</span> is provided to translate
an apache-style <span class="lang">mime.conf</span> file into C++ code that can
be linked with <span class="lang">wshare</span>.</p>
</blockquote>
<p><b><br>
Examples (UNIX)</b></p>
<blockquote>
<p>The simplest usage:</p>
<blockquote>
<p class="lang">wshare ./</p>
</blockquote>
<p>Quickly share your files through port 8080 and ignore any index.html files
in the directories:</p>
<blockquote>
<p class="lang">wshare -x -p 8080 ~/mydocs</p>
</blockquote>
<p>Run a real server for real users (must be root on UNIX):</p>
<blockquote>
<p class="lang">wshare -D -n 100 -u nobody -o /var/log/wshare-access.log /usr/local/www</p>
</blockquote>
<p>BE CAREFUL and double check the directory you are opening to the world.</p>
</blockquote>
<!-- #EndEditable -->
<hr size="1">
<a href="../index.html" class="ns">PTypes home</a>
</body>
<!-- #EndTemplate --></html>
include/pasync.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PASYNC_H__
#define __PASYNC_H__
#ifdef WIN32
# define _WINSOCKAPI_ // prevent inclusion of winsock.h, since we need winsock2.h
# include <windows.h>
#else
# include <pthread.h>
# ifndef __bsdi__
# include <semaphore.h>
# endif
#endif
#ifndef __PPORT_H__
#include "pport.h"
#endif
#ifndef __PTYPES_H__
#include "ptypes.h"
#endif
PTYPES_BEGIN
//
// Summary of implementation:
//
// atomic increment/decrement/exchange
// MSVC/BCC/i386: internal, asm
// GCC/i386: internal, asm
// GCC/PowerPC: internal, asm
// GCC/SPARC: internal, asm
// Other: internal, mutex hash table
//
// mutex
// Win32: Critical section
// Other: POSIX mutex
//
// trigger
// Win32: Event
// Other: internal, POSIX condvar/mutex
//
// rwlock:
// Win32: internal, Event/mutex
// MacOS: internal, POSIX condvar/mutex
// Other: POSIX rwlock
//
// semaphore:
// Win32: = timedsem
// MacOS: = timedsem
// Other: POSIX semaphore
//
// timedsem (with timed waiting):
// Win32: Semaphore
// Other: internal, POSIX mutex/condvar
//
#ifdef _MSC_VER
#pragma pack(push, 4)
#endif
#ifdef WIN32
typedef int pthread_id_t;
typedef HANDLE pthread_t;
#else
typedef pthread_t pthread_id_t;
#endif
ptpublic void ptdecl psleep(uint milliseconds);
ptpublic bool ptdecl pthrequal(pthread_id_t id); // note: this is NOT the thread handle, use thread::get_id()
ptpublic pthread_id_t ptdecl pthrself(); // ... same
// -------------------------------------------------------------------- //
// --- mutex ---------------------------------------------------------- //
// -------------------------------------------------------------------- //
#ifdef WIN32
struct ptpublic mutex: public noncopyable
{
protected:
CRITICAL_SECTION critsec;
public:
mutex() { InitializeCriticalSection(&critsec); }
~mutex() { DeleteCriticalSection(&critsec); }
void enter() { EnterCriticalSection(&critsec); }
void leave() { LeaveCriticalSection(&critsec); }
void lock() { enter(); }
void unlock() { leave(); }
};
#else
struct ptpublic mutex: public noncopyable
{
protected:
pthread_mutex_t mtx;
public:
mutex() { pthread_mutex_init(&mtx, 0); }
~mutex() { pthread_mutex_destroy(&mtx); }
void enter() { pthread_mutex_lock(&mtx); }
void leave() { pthread_mutex_unlock(&mtx); }
void lock() { enter(); }
void unlock() { leave(); }
};
#endif
//
// scopelock
//
class scopelock: public noncopyable
{
protected:
mutex* mtx;
public:
scopelock(mutex& imtx): mtx(&imtx) { mtx->lock(); }
~scopelock() { mtx->unlock(); }
};
//
// mutex table for hashed memory locking (undocumented)
//
#define _MUTEX_HASH_SIZE 29 // a prime number for hashing
#ifdef WIN32
# define pmemlock mutex
# define pmementer(m) (m)->lock()
# define pmemleave(m) (m)->unlock()
#else
# define _MTX_INIT PTHREAD_MUTEX_INITIALIZER
# define pmemlock pthread_mutex_t
# define pmementer pthread_mutex_lock
# define pmemleave pthread_mutex_unlock
#endif
ptpublic extern pmemlock _mtxtable[_MUTEX_HASH_SIZE];
#define pgetmemlock(addr) (_mtxtable + pintptr(addr) % _MUTEX_HASH_SIZE)
// -------------------------------------------------------------------- //
// --- trigger -------------------------------------------------------- //
// -------------------------------------------------------------------- //
#ifdef WIN32
class ptpublic trigger: public noncopyable
{
protected:
HANDLE handle; // Event object
public:
trigger(bool autoreset, bool state);
~trigger() { CloseHandle(handle); }
void wait() { WaitForSingleObject(handle, INFINITE); }
void post() { SetEvent(handle); }
void signal() { post(); }
void reset() { ResetEvent(handle); }
};
#else
class ptpublic trigger: public noncopyable
{
protected:
pthread_mutex_t mtx;
pthread_cond_t cond;
int state;
bool autoreset;
public:
trigger(bool autoreset, bool state);
~trigger();
void wait();
void post();
void signal() { post(); }
void reset();
};
#endif
// -------------------------------------------------------------------- //
// --- rwlock --------------------------------------------------------- //
// -------------------------------------------------------------------- //
#if defined(WIN32) || defined(__DARWIN__) || defined(__bsdi__)
# define __PTYPES_RWLOCK__
#elif defined(linux)
// on Linux rwlocks are included only with -D_GNU_SOURCE.
// programs that don't use rwlocks, do not need to define
// _GNU_SOURCE either.
# if defined(_GNU_SOURCE) || defined(__USE_UNIX98)
# define __POSIX_RWLOCK__
# endif
#else
# define __POSIX_RWLOCK__
#endif
#ifdef __PTYPES_RWLOCK__
struct ptpublic rwlock: protected mutex
{
protected:
#ifdef WIN32
HANDLE reading; // Event object
HANDLE finished; // Event object
int readcnt;
int writecnt;
#else
pthread_mutex_t mtx;
pthread_cond_t readcond;
pthread_cond_t writecond;
int locks;
int writers;
int readers;
#endif
public:
rwlock();
~rwlock();
void rdlock();
void wrlock();
void unlock();
void lock() { wrlock(); }
};
#elif defined(__POSIX_RWLOCK__)
struct ptpublic rwlock: public noncopyable
{
protected:
pthread_rwlock_t rw;
public:
rwlock();
~rwlock() { pthread_rwlock_destroy(&rw); }
void rdlock() { pthread_rwlock_rdlock(&rw); }
void wrlock() { pthread_rwlock_wrlock(&rw); }
void unlock() { pthread_rwlock_unlock(&rw); }
void lock() { wrlock(); }
};
#endif
#if defined(__PTYPES_RWLOCK__) || defined(__POSIX_RWLOCK__)
//
// scoperead & scopewrite
//
class scoperead: public noncopyable
{
protected:
rwlock* rw;
public:
scoperead(rwlock& irw): rw(&irw) { rw->rdlock(); }
~scoperead() { rw->unlock(); }
};
class scopewrite: public noncopyable
{
protected:
rwlock* rw;
public:
scopewrite(rwlock& irw): rw(&irw) { rw->wrlock(); }
~scopewrite() { rw->unlock(); }
};
#endif
// -------------------------------------------------------------------- //
// --- semaphore ------------------------------------------------------ //
// -------------------------------------------------------------------- //
#if defined(WIN32) || defined(__DARWIN__) || defined(__bsdi__)
# define __SEM_TO_TIMEDSEM__
#endif
#ifdef __SEM_TO_TIMEDSEM__
// map ordinary semaphore to timed semaphore
class timedsem;
typedef timedsem semaphore;
#else
class ptpublic semaphore: public unknown
{
protected:
sem_t handle;
public:
semaphore(int initvalue);
virtual ~semaphore();
void wait();
void post();
void signal() { post(); }
};
#endif
class ptpublic timedsem: public unknown
{
protected:
#ifdef WIN32
HANDLE handle;
#else
int count;
pthread_mutex_t mtx;
pthread_cond_t cond;
#endif
public:
timedsem(int initvalue);
virtual ~timedsem();
bool wait(int msecs = -1);
void post();
void signal() { post(); }
};
// -------------------------------------------------------------------- //
// --- thread --------------------------------------------------------- //
// -------------------------------------------------------------------- //
class ptpublic thread: public unknown
{
protected:
#ifdef WIN32
unsigned id;
#endif
pthread_t handle;
int autofree;
int running;
int signaled;
int finished;
int freed;
int reserved; // for priorities
timedsem relaxsem;
virtual void execute() = 0;
virtual void cleanup();
bool relax(int msecs) { return relaxsem.wait(msecs); }
friend void _threadepilog(thread* thr);
#ifdef WIN32
friend unsigned __stdcall _threadproc(void* arg);
#else
friend void* _threadproc(void* arg);
#endif
public:
thread(bool iautofree);
virtual ~thread();
#ifdef WIN32
pthread_id_t get_id() { return int(id); }
#else
pthread_id_t get_id() { return handle; }
#endif
bool get_running() { return running != 0; }
bool get_finished() { return finished != 0; }
bool get_signaled() { return signaled != 0; }
void start();
void signal();
void waitfor();
};
// -------------------------------------------------------------------- //
// --- jobqueue & msgqueue -------------------------------------------- //
// -------------------------------------------------------------------- //
const int MSG_USER = 0;
const int MSG_QUIT = -1;
const int DEF_QUEUE_LIMIT = 5000;
class ptpublic message: public unknown
{
protected:
message* next; // next in the message chain, used internally
semaphore* sync; // used internally by msgqueue::send(), when called from a different thread
friend class jobqueue; // my friends, job queue and message queue...
friend class msgqueue;
public:
int id;
pintptr param;
pintptr result;
message(int iid, pintptr iparam = 0);
virtual ~message();
};
class ptpublic jobqueue: public noncopyable
{
private:
int limit; // queue limit
message* head; // queue head
message* tail; // queue tail
int qcount; // number of items in the queue
timedsem sem; // queue semaphore
timedsem ovrsem; // overflow semaphore
mutex qlock; // critical sections in enqueue and dequeue
protected:
bool enqueue(message* msg, int timeout = -1);
bool push(message* msg, int timeout = -1);
message* dequeue(bool safe = true, int timeout = -1);
void purgequeue();
public:
jobqueue(int ilimit = DEF_QUEUE_LIMIT);
virtual ~jobqueue();
int get_count() const { return qcount; }
int get_limit() const { return limit; }
bool post(message* msg, int timeout = -1);
bool post(int id, pintptr param = 0, int timeout = -1);
bool posturgent(message* msg, int timeout = -1);
bool posturgent(int id, pintptr param = 0, int timeout = -1);
message* getmessage(int timeout = -1);
#ifdef PTYPES19_COMPAT
int msgsavail() const { return get_count(); }
#endif
};
template <class T> class tjobqueue: protected jobqueue
{
public:
tjobqueue(int ilimit = DEF_QUEUE_LIMIT);
int get_count() const { return jobqueue::get_count(); }
int get_limit() const { return jobqueue::get_limit(); }
bool post(T* msg, int timeout = -1) { return jobqueue::post(msg, timeout); }
bool posturgent(T* msg, int timeout = -1) { return jobqueue::posturgent(msg, timeout); }
T* getmessage(int timeout = -1) { return (T*)jobqueue::getmessage(timeout); }
};
class ptpublic msgqueue: protected jobqueue
{
private:
mutex thrlock; // lock for the queue processing
pthread_id_t owner; // thread ID of the queue processing thread
pintptr finishmsg(message* msg);
void handlemsg(message* msg);
void takeownership();
protected:
bool quit;
void defhandler(message& msg);
virtual void msghandler(message& msg) = 0;
public:
msgqueue(int ilimit = DEF_QUEUE_LIMIT);
virtual ~msgqueue();
// functions calling from the owner thread:
void processone(); // process one message, may hang if no msgs in the queue
void processmsgs(); // process all available messages and return
void run(); // process messages until MSG_QUIT
// functions calling from any thread:
int get_count() const { return jobqueue::get_count(); }
int get_limit() const { return jobqueue::get_limit(); }
bool post(message* msg, int timeout = -1) { return jobqueue::post(msg, timeout); }
bool post(int id, pintptr param = 0, int timeout = -1) { return jobqueue::post(id, param, timeout); }
bool posturgent(message* msg, int timeout = -1) { return jobqueue::posturgent(msg, timeout); }
bool posturgent(int id, pintptr param = 0, int timeout = -1) { return jobqueue::posturgent(id, param, timeout); }
pintptr send(message* msg);
pintptr send(int id, pintptr param = 0);
#ifdef PTYPES19_COMPAT
int msgsavail() const { return get_count(); }
#endif
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
PTYPES_END
#endif // __PASYNC_H__
include/pinet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PINET_H__
#define __PINET_H__
#ifndef __PPORT_H__
#include "pport.h"
#endif
#ifndef __PTYPES_H__
#include "ptypes.h"
#endif
#ifndef __PSTREAMS_H__
#include "pstreams.h"
#endif
#ifdef WIN32
# include <winsock2.h>
#else
# include <netdb.h> // for socklen_t
# include <sys/types.h>
# include <sys/socket.h>
#endif
PTYPES_BEGIN
#ifdef _MSC_VER
#pragma pack(push, 4)
#endif
//
// BSD-compatible socket error codes for Win32
//
#if defined(WSAENOTSOCK) && !defined(ENOTSOCK)
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#define EALREADY WSAEALREADY
#define ENOTSOCK WSAENOTSOCK
#define EDESTADDRREQ WSAEDESTADDRREQ
#define EMSGSIZE WSAEMSGSIZE
#define EPROTOTYPE WSAEPROTOTYPE
#define ENOPROTOOPT WSAENOPROTOOPT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#define EOPNOTSUPP WSAEOPNOTSUPP
#define EPFNOSUPPORT WSAEPFNOSUPPORT
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define EADDRINUSE WSAEADDRINUSE
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define ENETDOWN WSAENETDOWN
#define ENETUNREACH WSAENETUNREACH
#define ENETRESET WSAENETRESET
#define ECONNABORTED WSAECONNABORTED
#define ECONNRESET WSAECONNRESET
#define ENOBUFS WSAENOBUFS
#define EISCONN WSAEISCONN
#define ENOTCONN WSAENOTCONN
#define ESHUTDOWN WSAESHUTDOWN
#define ETOOMANYREFS WSAETOOMANYREFS
#define ETIMEDOUT WSAETIMEDOUT
#define ECONNREFUSED WSAECONNREFUSED
#define ELOOP WSAELOOP
// #define ENAMETOOLONG WSAENAMETOOLONG
#define EHOSTDOWN WSAEHOSTDOWN
#define EHOSTUNREACH WSAEHOSTUNREACH
// #define ENOTEMPTY WSAENOTEMPTY
#define EPROCLIM WSAEPROCLIM
#define EUSERS WSAEUSERS
#define EDQUOT WSAEDQUOT
#define ESTALE WSAESTALE
#define EREMOTE WSAEREMOTE
// NOTE: these are not errno constants in UNIX!
#define HOST_NOT_FOUND WSAHOST_NOT_FOUND
#define TRY_AGAIN WSATRY_AGAIN
#define NO_RECOVERY WSANO_RECOVERY
#define NO_DATA WSANO_DATA
#endif
// shutdown() constants
#if defined(SD_RECEIVE) && !defined(SHUT_RD)
# define SHUT_RD SD_RECEIVE
# define SHUT_WR SD_SEND
# define SHUT_RDWR SD_BOTH
#endif
// max backlog value for listen()
#ifndef SOMAXCONN
# define SOMAXCONN -1
#endif
typedef char* sockval_t;
#ifndef WIN32
# define closesocket close
#endif
#if (defined(__DARWIN__) && !defined(_SOCKLEN_T)) || defined(WIN32) || defined(__hpux)
typedef int psocklen;
#else
typedef socklen_t psocklen;
#endif
// -------------------------------------------------------------------- //
// --- IP address class and DNS utilities ---------------------------- //
// -------------------------------------------------------------------- //
//
// IP address
//
struct ptpublic ipaddress
{
public:
union
{
uchar data[4];
ulong ldata;
};
ipaddress() {}
ipaddress(ulong a) { ldata = a; }
ipaddress(const ipaddress& a) { ldata = a.ldata; }
ipaddress(int a, int b, int c, int d);
ipaddress& operator= (ulong a) { ldata = a; return *this; }
ipaddress& operator= (const ipaddress& a) { ldata = a.ldata; return *this; }
uchar& operator [] (int i) { return data[i]; }
operator ulong() const { return ldata; }
};
ptpublic extern ipaddress ipnone;
ptpublic extern ipaddress ipany;
ptpublic extern ipaddress ipbcast;
//
// IP peer info: host name, IP and the port name
// used internally in ipstream and ipmessage
//
class ptpublic ippeerinfo: public noncopyable
{
protected:
ipaddress ip; // target IP
string host; // target host name; either IP or hostname must be specified
int port; // target port number
void notfound(); // throws a (estream*) exception
ptpublic friend bool ptdecl psockname(int, ippeerinfo&);
public:
ippeerinfo();
ippeerinfo(ipaddress iip, const string& ihost, int iport);
ipaddress get_ip(); // resolves the host name if necessary (only once)
string get_host(); // performs reverse-lookup if necessary (only once)
int get_port() { return port; }
void clear();
string asstring(bool showport) const;
};
ptpublic string ptdecl iptostring(ipaddress ip);
ptpublic ipaddress ptdecl phostbyname(const char* name);
ptpublic string ptdecl phostbyaddr(ipaddress ip);
ptpublic string ptdecl phostcname(const char* name);
// internal utilities
ptpublic int ptdecl usockerrno();
ptpublic const char* ptdecl usockerrmsg(int code);
ptpublic bool ptdecl psockwait(int handle, int timeout);
ptpublic bool ptdecl psockname(int handle, ippeerinfo&);
// -------------------------------------------------------------------- //
// --- TCP socket classes -------------------------------------------- //
// -------------------------------------------------------------------- //
// additional IO status codes
const int IO_RESOLVING = 10;
const int IO_RESOLVED = 11;
const int IO_CONNECTING = 20;
const int IO_CONNECTED = 21;
//
// ipstream
//
class ptpublic ipstream: public fdxstm, public ippeerinfo
{
friend class ipstmserver;
protected:
int svsocket; // server socket descriptor, used internally by ipstmserver
#ifdef WIN32
// sockets are not compatible with file handles on Windows
virtual int dorawread(char* buf, int count);
virtual int dorawwrite(const char* buf, int count);
#endif
virtual int uerrno();
virtual const char* uerrmsg(int code);
virtual void doopen();
virtual large doseek(large newpos, ioseekmode mode);
virtual void doclose();
virtual void sockopt(int socket);
void closehandle();
public:
ipstream();
ipstream(ipaddress ip, int port);
ipstream(const char* host, int port);
ipstream(const string& host, int port);
virtual ~ipstream();
virtual int classid();
virtual string get_streamname();
bool waitfor(int timeout);
ipaddress get_myip();
int get_myport();
void set_ip(ipaddress);
void set_host(const string&);
void set_host(const char*);
void set_port(int);
};
//
// common internal interfaces for ipstmserver and ipmsgserver
//
class ipbindinfo: public unknown, public ippeerinfo
{
public:
int handle;
ipbindinfo(ipaddress iip, const string& ihost, int iport);
virtual ~ipbindinfo();
};
class ptpublic ipsvbase: public unknown
{
protected:
int socktype;
bool active;
tobjlist<ipbindinfo> addrlist; // list of local socket addresses to bind to
void error(ippeerinfo& peer, int code, const char* defmsg);
bool dopoll(int* i, int timeout);
void setupfds(void* set, int i);
virtual void open();
virtual void close();
virtual void dobind(ipbindinfo*) = 0;
virtual void sockopt(int socket);
public:
ipsvbase(int isocktype);
virtual ~ipsvbase();
int bind(ipaddress ip, int port);
int bindall(int port);
int get_addrcount() { return addrlist.get_count(); }
const ipbindinfo& get_addr(int i) { return *addrlist[i]; }
void clear();
};
//
// ipstmserver
//
class ptpublic ipstmserver: public ipsvbase
{
protected:
virtual void dobind(ipbindinfo*);
public:
ipstmserver();
virtual ~ipstmserver();
bool poll(int i = -1, int timeout = 0);
bool serve(ipstream& client, int i = -1, int timeout = -1);
};
// -------------------------------------------------------------------- //
// --- UDP socket classes -------------------------------------------- //
// -------------------------------------------------------------------- //
//
// ipmessage
//
class ptpublic ipmessage: public unknown, public ippeerinfo
{
protected:
int handle;
void error(int code, const char* msg);
void open();
void close();
virtual void sockopt(int socket);
public:
ipmessage();
ipmessage(ipaddress ip, int port);
ipmessage(const char* host, int port);
ipmessage(const string& host, int port);
virtual ~ipmessage();
void set_ip(ipaddress iip);
void set_host(const string&);
void set_host(const char*);
void set_port(int);
ipaddress get_myip();
int get_myport();
int get_handle() { return handle; }
bool waitfor(int timeout);
int receive(char* buf, int count, ipaddress& src);
int receive(char* buf, int count);
string receive(int max, ipaddress& src);
string receive(int max);
void send(const char* buf, int count);
void send(const string& s) { send(s, length(s)); }
};
//
// ipmsgserver
//
class ptpublic ipmsgserver: public ipsvbase, public ippeerinfo
{
protected:
int handle;
virtual void close();
virtual void dobind(ipbindinfo*);
public:
ipmsgserver();
virtual ~ipmsgserver();
int get_handle() { return handle; }
bool poll(int i = -1, int timeout = 0);
int receive(char* buf, int count);
string receive(int max);
void send(const char* buf, int count);
void send(const string& s) { send(s, length(s)); }
void sendto(const char* buf, int count, ipaddress ip, int port);
void sendto(const string& s, ipaddress ip, int port)
{ sendto(s, length(s), ip, port); }
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
PTYPES_END
#endif // __PINET_H__
include/pport.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PPORT_H__
#define __PPORT_H__
#if defined(linux)
# include <stdint.h> // for uintptr_t
#endif
#include <sys/types.h>
#ifndef __cplusplus
# error "This is a C++ source"
#endif
#define PTYPES_NAMESPACE pt
//
// conditional namespace declarations
//
#ifdef PTYPES_NAMESPACE
# define PTYPES_BEGIN namespace PTYPES_NAMESPACE {
# define PTYPES_END }
# define USING_PTYPES using namespace PTYPES_NAMESPACE;
#else
# define PTYPES_NAMESPACE
# define PTYPES_BEGIN
# define PTYPES_END
# define USING_PTYPES
#endif
//
// Windows DLL export/import and calling convention macros
//
#ifdef WIN32
# if defined(PTYPES_DLL_EXPORTS)
# define ptpublic __declspec(dllexport)
# elif defined(PTYPES_DLL)
# define ptpublic__declspec(dllimport)
# else
# define ptpublic
# endif
# define ptdecl__stdcall
# define __PFASTCALL __fastcall
#else
# define ptpublic
# define ptdecl
# define __PFASTCALL
#endif
//
// versioning
//
extern "C" ptpublic unsigned long __ptypes_version;
// this enables old algebraic list interfaces; NO_PTYPES19_COMPAT
// can be defined at command line
#if !defined(NO_PTYPES19_COMPAT)
# define PTYPES19_COMPAT
#endif
PTYPES_BEGIN
#ifdef _MSC_VER
// we don't want "unreferenced inline function" warning
# pragma warning (disable: 4514)
// ... also "copy constructor/assignment operator could not be generated"
# pragma warning (disable: 4511)
# pragma warning (disable: 4512)
// disable deprecation warnings for snprintf and others
# pragma warning (disable: 4996)
#endif
#if defined(_DEBUG) && !defined(DEBUG)
# define DEBUG
#endif
#if defined(__WIN32__) && !defined(WIN32)
# define WIN32
#endif
// __APPLE__ is the only predefined macro on MacOS X
#if defined(__APPLE__)
# define __DARWIN__
#endif
// CHECK_BOUNDS enables bounds checking for strings and lists
#if defined(DEBUG) && !defined(CHECK_BOUNDS)
# define CHECK_BOUNDS
#endif
// COUNT_OBJALLOC helps to keep track of the number of
// objects created/destroyed
#if defined(DEBUG) && !defined(COUNT_OBJALLOC)
# define COUNT_OBJALLOC
#endif
//
// useful typedefs
//
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef signed char schar;
typedef char* pchar;
typedef const char* pconst;
typedef void* ptr;
typedef int* pint;
#ifdef WIN32
typedef uint pintptr;
#else
typedef uintptr_t pintptr;
#endif
//
// portable 64-bit integers
//
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 large;
typedef unsigned __int64 ularge;
# define LLCONST(a) (a##i64)
#else
typedef long long large;
typedef unsigned long long ularge;
# define LLCONST(a) (a##ll)
#endif
#define LARGE_MIN (LLCONST(-9223372036854775807)-1)
#define LARGE_MAX (LLCONST(9223372036854775807))
#define ULARGE_MAX (LLCONST(18446744073709551615u))
#if defined(_MSC_VER) || defined(__BORLANDC__)
# define strcasecmp stricmp
# define snprintf _snprintf
#endif
//
// misc.
//
// I like Pascal's nil
#define nil 0
inline int imax(int x, int y) { return (x > y) ? x : y; }
inline int imin(int x, int y) { return (x < y) ? x : y; }
inline large lmax(large x, large y) { return (x > y) ? x : y; }
inline large lmin(large x, large y) { return (x < y) ? x : y; }
//
// critical error processing
//
#define CRIT_FIRST 0xC0000
typedef void (ptdecl *_pcrithandler)(int code, const char* msg);
ptpublic _pcrithandler ptdecl getcrithandler();
ptpublic _pcrithandler ptdecl setcrithandler(_pcrithandler newh);
ptpublic void ptdecl fatal(int code, const char* msg);
//
// memory management (undocumented)
// hides some BSD* incompatibility issues
//
ptpublic void* ptdecl memalloc(uint a);
ptpublic void* ptdecl memrealloc(void* p, uint a);
ptpublic void ptdecl memfree(void* p);
ptpublic void ptdecl memerror();
ptpublic int ptdecl memquantize(int);
PTYPES_END
#endif // __PPORT_H__
include/pstreams.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PSTREAMS_H__
#define __PSTREAMS_H__
#ifndef __PPORT_H__
#include "pport.h"
#endif
#ifndef __PTYPES_H__
#include "ptypes.h"
#endif
#ifndef PTYPES_ST
# ifndef __PASYNC_H__
# include "pasync.h" // for logfile.lock
# endif
#endif
#include <stdarg.h>
#include <errno.h>
#ifdef WIN32
# define _WINSOCKAPI_ // prevent inclusion of winsock.h, because we need winsock2.h
# include "windows.h" // for OVERLAPPED
#endif
PTYPES_BEGIN
#ifdef _MSC_VER
#pragma pack(push, 4)
#endif
// -------------------------------------------------------------------- //
// --- abstract stream i/o classes ----------------------------------- //
// -------------------------------------------------------------------- //
//
// stream exception class
//
class iobase;
class ptpublic estream: public exception
{
protected:
int code;
iobase* errstm;
public:
estream(iobase* ierrstm, int icode, const char* imsg);
estream(iobase* ierrstm, int icode, const string& imsg);
virtual ~estream();
int get_code() { return code; }
iobase* get_errstm() { return errstm; }
};
typedef void (ptdecl *iostatusevent)(iobase* sender, int code);
ptpublic int ptdecl unixerrno();
ptpublic const char* ptdecl unixerrmsg(int code);
// status codes: compatible with WinInet API
// additional status codes are defined in pinet.h for ipsocket
const int IO_CREATED = 1;
const int IO_OPENING = 5;
const int IO_OPENED = 35;
const int IO_READING = 37;
const int IO_WRITING = 38;
const int IO_EOF = 45;
const int IO_CLOSING = 250;
const int IO_CLOSED = 253;
//
// iobase
//
enum ioseekmode
{
IO_BEGIN,
IO_CURRENT,
IO_END
};
const int invhandle = -1;
class ptpublic iobase: public component
{
friend class fdxoutstm;
protected:
bool active; // active status, changed by open() and close()
bool cancelled; // the stream was cancelled by cancel()
bool eof; // end of file reached, only for input streams
int handle; // used in many derivative classes
large abspos; // physical stream position
int bufsize; // buffer size, can be changed only when not active
char* bufdata; // internal: allocated buffer data
int bufpos; // internal: current position
int bufend; // internal: current data size in the buffer
int stmerrno; // UNIX-compatible error numbers, see comments in piobase.cxx
string deferrormsg; // internal: default error message when an exception is thrown,
int status; // stream status code, see IO_xxx constants above
iostatusevent onstatus; // user-defined status change handler
virtual void bufalloc();
virtual void buffree();
void bufclear() { bufpos = 0; bufend = 0; }
void errstminactive();
void errbufrequired();
void requireactive() { if (!active) errstminactive(); }
void requirebuf() { requireactive(); if (bufdata == 0) errbufrequired(); }
int convertoffset(large);
virtual void doopen() = 0;
virtual void doclose();
virtual large doseek(large newpos, ioseekmode mode);
virtual void chstat(int newstat);
virtual int uerrno();
virtual const char* uerrmsg(int code);
public:
iobase(int ibufsize = -1);
virtual ~iobase();
void open();
void close();
void cancel();
void reopen() { open(); }
large seekx(large newpos, ioseekmode mode = IO_BEGIN);
int seek(int newpos, ioseekmode mode = IO_BEGIN) { return convertoffset(seekx(newpos, mode)); }
void error(int code, const char* defmsg);
virtual void flush();
virtual string get_errormsg();
virtual string get_errstmname();
virtual string get_streamname() = 0;
bool get_active() { return active; }
void set_active(bool newval);
bool get_cancelled() { return cancelled; }
void set_cancelled(bool newval) { cancelled = newval; }
int get_handle() { return handle; }
int get_bufsize() { return bufsize; }
void set_bufsize(int newval);
int get_stmerrno() { return stmerrno; }
int get_status() { return status; }
iostatusevent get_onstatus() { return onstatus; }
void set_onstatus(iostatusevent newval) { onstatus = newval; }
};
typedef iobase* piobase;
ptpublic extern int defbufsize;
ptpublic extern int stmbalance;
//
// instm - abstract input stream
//
const char eofchar = 0;
class ptpublic instm: public iobase
{
protected:
virtual int dorawread(char* buf, int count);
int rawread(char* buf, int count);
virtual void bufvalidate();
void skipeol();
public:
instm(int ibufsize = -1);
virtual ~instm();
virtual int classid();
bool get_eof();
void set_eof(bool ieof) { eof = ieof; }
bool get_eol();
int get_dataavail();
char preview();
char get();
void putback();
string token(const cset& chars);
string token(const cset& chars, int limit);
int token(const cset& chars, char* buf, int size);
string line();
string line(int limit);
int line(char* buf, int size, bool eateol = true);
int read(void* buf, int count);
int skip(int count);
int skiptoken(const cset& chars);
void skipline(bool eateol = true);
large tellx();
int tell() { return convertoffset(tellx()); }
large seekx(large newpos, ioseekmode mode = IO_BEGIN);
int seek(int newpos, ioseekmode mode = IO_BEGIN) { return convertoffset(seekx(newpos, mode)); }
};
typedef instm* pinstm;
//
// outstm - abstract output stream
//
class ptpublic outstm: public iobase
{
protected:
bool flusheol;
virtual int dorawwrite(const char* buf, int count);
int rawwrite(const char* buf, int count);
virtual void bufvalidate();
void bufadvance(int delta)
{ bufpos += delta; if (bufend < bufpos) bufend = bufpos; }
bool canwrite();
public:
outstm(bool iflusheol = false, int ibufsize = -1);
virtual ~outstm();
virtual int classid();
bool get_flusheol() { return flusheol; }
void set_flusheol(bool newval) { flusheol = newval; }
virtual void flush();
bool get_eof() { return eof; }
void put(char c);
void put(const char* str);
void put(const string& str);
void vputf(const char* fmt, va_list);
void putf(const char* fmt, ...);
void putline(const char* str);
void putline(const string& str);
void puteol();
int write(const void* buf, int count);
large tellx() { return abspos + bufpos; }
int tell() { return convertoffset(tellx()); }
large seekx(large newpos, ioseekmode mode = IO_BEGIN);
int seek(int newpos, ioseekmode mode = IO_BEGIN) { return convertoffset(seekx(newpos, mode)); }
};
typedef outstm* poutstm;
// %t and %T formats
ptpublic extern char* shorttimefmt; // "%d-%b-%Y %X"
ptpublic extern char* longtimefmt; // "%a %b %d %X %Y"
//
// internal class used in fdxstm
//
class ptpublic fdxstm;
class ptpublic fdxoutstm: public outstm
{
friend class fdxstm;
protected:
fdxstm* in;
virtual void chstat(int newstat);
virtual int uerrno();
virtual const char* uerrmsg(int code);
virtual void doopen();
virtual void doclose();
virtual int dorawwrite(const char* buf, int count);
public:
fdxoutstm(int ibufsize, fdxstm* iin);
virtual ~fdxoutstm();
virtual string get_streamname();
};
typedef fdxstm* pfdxstm;
//
// fdxstm: abstract full-duplex stream (for sockets and pipes)
//
class ptpublic fdxstm: public instm
{
friend class fdxoutstm;
protected:
fdxoutstm out;
virtual int dorawwrite(const char* buf, int count);
public:
fdxstm(int ibufsize = -1);
virtual ~fdxstm();
virtual int classid();
void set_bufsize(int newval); // sets both input and output buffer sizes
void open(); // rewritten to pass the call to the output stream too
void close();
void cancel();
virtual void flush();
large tellx(bool); // true for input and false for output
int tell(bool forin) { return convertoffset(tellx(forin)); }
// output interface: pretend this class is derived both
// from instm and outstm. actually we can't use multiple
// inheritance here, since this is a full-duplex stream,
// hence everything must be duplicated for input and output
void putf(const char* fmt, ...);
void put(char c) { out.put(c); }
void put(const char* str) { out.put(str); }
void put(const string& str) { out.put(str); }
void putline(const char* str) { out.putline(str); }
void putline(const string& str) { out.putline(str); }
void puteol() { out.puteol(); }
int write(const void* buf, int count) { return out.write(buf, count); }
bool get_flusheol() { return out.get_flusheol(); }
void set_flusheol(bool newval) { out.set_flusheol(newval); }
operator outstm&() { return out; }
};
//
// abstract input filter class
//
class ptpublic infilter: public instm
{
protected:
instm* stm;
char* savebuf;
int savecount;
string postponed;
void copytobuf(string& s);
void copytobuf(pconst& buf, int& count);
bool copytobuf(char c);
virtual void freenotify(component* sender);
virtual void doopen();
virtual void doclose();
virtual int dorawread(char* buf, int count);
virtual void dofilter() = 0;
bool bufavail() { return savecount > 0; }
void post(const char* buf, int count);
void post(const char* s);
void post(char c);
virtual void post(string s);
public:
infilter(instm* istm, int ibufsize = -1);
virtual ~infilter();
virtual string get_errstmname();
instm* get_stm() { return stm; }
void set_stm(instm* stm);
};
//
// abstract output filter class
//
class ptpublic outfilter: public outstm
{
protected:
outstm* stm;
virtual void freenotify(component* sender);
virtual void doopen();
virtual void doclose();
public:
outfilter(outstm* istm, int ibufsize = -1);
virtual ~outfilter();
virtual string get_errstmname();
outstm* get_stm() { return stm; }
void set_stm(outstm* stm);
};
//
// inmemory - memory stream
//
class ptpublic inmemory: public instm
{
protected:
string mem;
virtual void bufalloc();
virtual void buffree();
virtual void bufvalidate();
virtual void doopen();
virtual void doclose();
virtual large doseek(large newpos, ioseekmode mode);
virtual int dorawread(char* buf, int count);
public:
inmemory(const string& imem);
virtual ~inmemory();
virtual int classid();
virtual string get_streamname();
large seekx(large newpos, ioseekmode mode = IO_BEGIN);
int seek(int newpos, ioseekmode mode = IO_BEGIN) { return convertoffset(seekx(newpos, mode)); }
string get_strdata() { return mem; }
void set_strdata(const string& data);
};
//
// outmemory - memory stream
//
class ptpublic outmemory: public outstm
{
protected:
string mem;
int limit;
virtual void doopen();
virtual void doclose();
virtual large doseek(large newpos, ioseekmode mode);
virtual int dorawwrite(const char* buf, int count);
public:
outmemory(int limit = -1);
virtual ~outmemory();
virtual int classid();
virtual string get_streamname();
large tellx() { return abspos; }
int tell() { return (int)abspos; }
string get_strdata();
};
// -------------------------------------------------------------------- //
// --- file input/output --------------------------------------------- //
// -------------------------------------------------------------------- //
//
// infile - file input
//
class outfile;
class ptpublic infile: public instm
{
protected:
string filename;
int syshandle; // if not -1, assigned to handle in open() instead of opening a file by a name
int peerhandle; // pipe peer handle, needed for closing the peer after fork() on unix
virtual void doopen();
virtual void doclose();
public:
infile();
infile(const char* ifn);
infile(const string& ifn);
virtual ~infile();
virtual int classid();
void pipe(outfile&);
virtual string get_streamname();
int get_syshandle() { return syshandle; }
void set_syshandle(int ihandle) { close(); syshandle = ihandle; }
int get_peerhandle() { return peerhandle; }
string get_filename() { return filename; }
void set_filename(const string& ifn) { close(); filename = ifn; }
void set_filename(const char* ifn) { close(); filename = ifn; }
};
//
// outfile - file output
//
class ptpublic outfile: public outstm
{
protected:
friend class infile; // infile::pipe() needs access to peerhandle
string filename;
int syshandle; // if not -1, assigned to handle in open() instead of opening a file by a name
int peerhandle; // pipe peer handle, needed for closing the peer after fork() on unix
int umode; // unix file mode (unix only), default = 644
bool append; // append (create new if needed), default = false
virtual void doopen();
virtual void doclose();
public:
outfile();
outfile(const char* ifn, bool iappend = false);
outfile(const string& ifn, bool iappend = false);
virtual ~outfile();
virtual int classid();
virtual void flush();
virtual string get_streamname();
int get_syshandle() { return syshandle; }
void set_syshandle(int ihandle) { close(); syshandle = ihandle; }
int get_peerhandle() { return peerhandle; }
string get_filename() { return filename; }
void set_filename(const string& ifn) { close(); filename = ifn; }
void set_filename(const char* ifn) { close(); filename = ifn; }
bool get_append() { return append; }
void set_append(bool iappend) { close(); append = iappend; }
int get_umode() { return umode; }
void set_umode(int iumode) { close(); umode = iumode; }
};
//
// logfile - file output with thread-safe putf()
//
class ptpublic logfile: public outfile
{
protected:
#ifndef PTYPES_ST
mutex lock;
#endif
public:
logfile();
logfile(const char* ifn, bool iappend = true);
logfile(const string& ifn, bool iappend = true);
virtual ~logfile();
virtual int classid();
void vputf(const char* fmt, va_list);
void putf(const char* fmt, ...);
};
//
// intee - UNIX tee-style utility class
//
class ptpublic intee: public infilter {
protected:
outfile file;
virtual void doopen();
virtual void doclose();
virtual void dofilter();
public:
intee(instm* istm, const char* ifn, bool iappend = false);
intee(instm* istm, const string& ifn, bool iappend = false);
virtual ~intee();
outfile* get_file() { return &file; }
virtual string get_streamname();
};
// -------------------------------------------------------------------- //
// --- named pipes --------------------------------------------------- //
// -------------------------------------------------------------------- //
// on Unix this directory can be overridden by providing the
// full path, e.g. '/var/run/mypipe'. the path is ignored on
// Windows and is always replaced with '\\<server>\pipe\'
#ifndef WIN32
# define DEF_NAMED_PIPES_DIR "/tmp/"
#endif
#ifdef WIN32
const int DEF_PIPE_TIMEOUT = 20000; // in milliseconds, for reading and writing
const int DEF_PIPE_OPEN_TIMEOUT = 1000; // for connecting to the remote pipe:
const int DEF_PIPE_OPEN_RETRY = 5; // will double the timeout value for each retry,
// i.e. 1 second, then 2, then 4 etc.
const int DEF_PIPE_SYSTEM_BUF_SIZE = 4096;
#endif
class ptpublic namedpipe: public fdxstm
{
friend class npserver;
protected:
string pipename;
int svhandle;
#ifdef WIN32
// we use overlapped IO in order to have timed waiting in serve()
// and also to implement timeout error on the client side
OVERLAPPED ovr;
virtual int dorawread(char* buf, int count);
virtual int dorawwrite(const char* buf, int count);
static string ptdecl realpipename(const string& pipename, const string& svrname = nullstring);
void initovr();
#else
static string realpipename(const string& pipename);
static bool setupsockaddr(const string& pipename, void* sa);
void initovr() {}
#endif
virtual void doopen();
virtual void doclose();
virtual large doseek(large, ioseekmode);
public:
namedpipe();
namedpipe(const string& ipipename);
#ifdef WIN32
namedpipe(const string& ipipename, const string& servername);
#endif
virtual ~namedpipe();
virtual int classid();
virtual void flush();
virtual string get_streamname();
string get_pipename() { return pipename; }
void set_pipename(const string&);
void set_pipename(const char*);
};
class ptpublic npserver: public unknown
{
string pipename;
int handle;
bool active;
void error(int code, const char* defmsg);
void open();
void close();
#ifdef WIN32
void openinst();
void closeinst();
#endif
public:
npserver(const string& ipipename);
~npserver();
bool serve(namedpipe& client, int timeout = -1);
};
// -------------------------------------------------------------------- //
// --- utility streams ----------------------------------------------- //
// -------------------------------------------------------------------- //
//
// MD5 -- message digest algorithm
// Derived from L. Peter Deutsch's work, please see src/pmd5.cxx
//
const int md5_digsize = 16;
typedef uchar md5_digest[md5_digsize];
// from md5.h
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
typedef struct md5_state_s
{
md5_word_t count[2];/* message length in bits, lsw first */
md5_word_t abcd[4];/* digest buffer */
md5_byte_t buf[64];/* accumulate block */
} md5_state_t;
class ptpublic outmd5: public outfilter
{
protected:
md5_state_s ctx;
md5_digest digest;
virtual void doopen();
virtual void doclose();
virtual int dorawwrite(const char* buf, int count);
public:
outmd5(outstm* istm = nil);
virtual ~outmd5();
virtual string get_streamname();
const unsigned char* get_bindigest() { close(); return digest; }
string get_digest();
};
//
// null output stream
//
class ptpublic outnull: public outstm
{
protected:
virtual int dorawwrite(const char*, int);
virtual void doopen();
virtual void doclose();
public:
outnull();
virtual ~outnull();
virtual string get_streamname();
};
// -------------------------------------------------------------------- //
// --- unit ---------------------------------------------------------- //
// -------------------------------------------------------------------- //
#ifdef _MSC_VER
// disable "type name first seen using 'struct' now seen using 'class'" warning
# pragma warning (disable: 4099)
// disable "class '...' needs to have dll-interface to be used by clients of class
// '...'" warning, since the compiler may sometimes give this warning incorrectly.
# pragma warning (disable: 4251)
#endif
class unit_thread;
class ptpublic unit: public component
{
protected:
friend class unit_thread;
unit* pipe_next; // next unit in the pipe chain, assigned by connect()
unit_thread* main_thread; // async execution thread, started by run() if necessary
int running; // running status, to protect from recursive calls to run() and waitfor()
void do_main();
public:
compref<instm> uin;
compref<outstm> uout;
unit();
virtual ~unit();
virtual int classid();
// things that may be overridden in descendant classes
virtual void main(); // main code, called from run()
virtual void cleanup(); // main code cleanup, called from run()
// service methods
void connect(unit* next);
void run(bool async = false);
void waitfor();
};
typedef unit* punit;
typedef unit CUnit; // send me a $10 check if you use this alias (not obligatory though,
// because the library is free, after all)
//
// standard input, output and error devices
//
ptpublic extern infile pin;
ptpublic extern logfile pout;
ptpublic extern logfile perr;
ptpublic extern outnull pnull;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
PTYPES_END
#endif // __PSTREAMS_H__
include/ptime.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PTIME_H__
#define __PTIME_H__
#ifndef __PPORT_H__
#include "pport.h"
#endif
#ifndef __PTYPES_H__
#include "ptypes.h"
#endif
#include <time.h>
PTYPES_BEGIN
// datetime type: 64-bit, number of milliseconds since midnight 01/01/0001
typedef large datetime;
#define invdatetime LLCONST(-1)
#define _msecsmax 86400000 // number of milliseconds in one day
#define _daysmax 3652059 // number of days between 01/01/0001 and 12/31/9999
#define _datetimemax LLCONST(315537897600000) // max. allowed number for datetime type
#define _unixepoch LLCONST(62135596800000) // difference between time_t and datetime in milliseconds
// datetime general utilities
inline int days(datetime d) { return int(d / _msecsmax); }
inline int msecs(datetime d) { return int(d % _msecsmax); }
ptpublic datetime ptdecl mkdt(int days, int msecs);
ptpublic bool ptdecl isvalid(datetime);
ptpublic datetime ptdecl now(bool utc = true);
ptpublic void ptdecl tzupdate();
ptpublic int ptdecl tzoffset();
ptpublic string ptdecl dttostring(datetime, const char* fmt);
ptpublic string ptdecl nowstring(const char* fmt, bool utc = true);
ptpublic datetime ptdecl utodatetime(time_t u);
ptpublic struct tm* ptdecl dttotm(datetime dt, struct tm& t);
// date/calendar manipulation
ptpublic bool ptdecl isleapyear(int year);
ptpublic int ptdecl daysinmonth(int year, int month);
ptpublic int ptdecl daysinyear(int year, int month);
ptpublic int ptdecl dayofweek(datetime);
ptpublic bool ptdecl isdatevalid(int year, int month, int day);
ptpublic datetime ptdecl encodedate(int year, int month, int day);
ptpublic bool ptdecl decodedate(datetime, int& year, int& month, int& day);
// time manipulation
ptpublic bool ptdecl istimevalid(int hour, int min, int sec, int msec = 0);
ptpublic datetime ptdecl encodetime(int hour, int min, int sec, int msec = 0);
ptpublic bool ptdecl decodetime(datetime, int& hour, int& min, int& sec, int& msec);
ptpublic bool ptdecl decodetime(datetime, int& hour, int& min, int& sec);
PTYPES_END
#endif // __PTIME_H__
include/ptypes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef __PTYPES_H__
#define __PTYPES_H__
#ifndef __PPORT_H__
#include "pport.h"
#endif
#include <string.h>
PTYPES_BEGIN
#ifdef _MSC_VER
#pragma pack(push, 4)
// disable "non dll-interface class '...' used as base for dll-interface class '...'" warning
#pragma warning(disable : 4275)
// disable "conditional expression constant" warning
#pragma warning(push)
#pragma warning(disable : 4127)
#endif
ptpublic int __PFASTCALL pincrement(int* target);
ptpublic int __PFASTCALL pdecrement(int* target);
ptpublic int __PFASTCALL pexchange(int* target, int value);
ptpublic void* __PFASTCALL pexchange(void** target, void* value);
template <class T> inline T* tpexchange(T** target, T* value)
{ return (T*)pexchange((void**)target, (void*)value); }
#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ == 4) || defined(__hpux)
# define VARIANT_TYPECAST_HACK
#endif
// -------------------------------------------------------------------- //
// --- string class --------------------------------------------------- //
// -------------------------------------------------------------------- //
// dynamic string class with thread-safe ref-counted buffer
struct _strrec
{
int refcount;
int length;
};
typedef _strrec* _pstrrec;
#define STR_BASE(x) (_pstrrec(x)-1)
#define STR_REFCOUNT(x) (STR_BASE(x)->refcount)
#define STR_LENGTH(x) (STR_BASE(x)->length)
#define PTR_TO_PSTRING(p) (pstring(&(p)))
#define PTR_TO_STRING(p) (*PTR_TO_PSTRING(p))
ptpublic extern char* emptystr;
class ptpublic variant;
class ptpublic string
{
friend class variant;
protected:
char* data;
static void idxerror();
void _alloc(int);
void _realloc(int);
void _free();
void initialize() { data = emptystr; }
void initialize(const char*, int);
void initialize(const char*);
void initialize(char);
void initialize(const string& s);
void initialize(const char*, int, const char*, int);
void initialize(const variant&);
void finalize();
void assign(const char*, int);
void assign(const char*);
void assign(const string&);
void assign(char);
#ifdef CHECK_BOUNDS
void idx(int index) const { if (unsigned(index) >= unsigned(STR_LENGTH(data))) idxerror(); }
#else
void idx(int) const { }
#endif
string(const char* s1, int len1, const char* s2, int len2) { initialize(s1, len1, s2, len2); }
public:
friend int length(const string& s);
friend int refcount(const string& s);
friend void assign(string& s, const char* buf, int len);
friend void clear(string& s);
friend bool isempty(const string& s);
ptpublic friend char* ptdecl setlength(string&, int);
ptpublic friend char* ptdecl unique(string&);
ptpublic friend void ptdecl concat(string& s, const char* sc, int catlen);
ptpublic friend void ptdecl concat(string& s, const char* s1);
ptpublic friend void ptdecl concat(string& s, char s1);
ptpublic friend void ptdecl concat(string& s, const string& s1);
ptpublic friend string ptdecl copy(const string& s, int from, int cnt);
ptpublic friend string ptdecl copy(const string& s, int from);
ptpublic friend void ptdecl ins(const char* s1, int s1len, string& s, int at);
ptpublic friend void ptdecl ins(const char* s1, string& s, int at);
ptpublic friend void ptdecl ins(char s1, string& s, int at);
ptpublic friend void ptdecl ins(const string& s1, string& s, int at);
ptpublic friend void ptdecl del(string& s, int at, int cnt);
ptpublic friend void ptdecl del(string& s, int at);
ptpublic friend int ptdecl pos(const char* s1, const string& s);
ptpublic friend int ptdecl pos(char s1, const string& s);
friend int pos(const string& s1, const string& s);
ptpublic friend int ptdecl rpos(char s1, const string& s);
ptpublic friend bool ptdecl contains(const char* s1, int len, const string& s, int at);
ptpublic friend bool ptdecl contains(const char* s1, const string& s, int at);
ptpublic friend bool ptdecl contains(char s1, const string& s, int at);
ptpublic friend bool ptdecl contains(const string& s1, const string& s, int at);
ptpublic friend string ptdecl dup(const string& s);
string() { initialize(); }
string(const char* sc, int initlen) { initialize(sc, initlen); }
string(const char* sc) { initialize(sc); }
string(char c) { initialize(c); }
string(const string& s) { initialize(s); }
~string() { finalize(); }
#ifdef VARIANT_TYPECAST_HACK
string(const variant& v) { initialize(v); }
#endif
string& operator= (const char* sc) { assign(sc); return *this; }
string& operator= (char c) { assign(c); return *this; }
string& operator= (const string& s) { assign(s); return *this; }
string& operator+= (const char* sc) { concat(*this, sc); return *this; }
string& operator+= (char c) { concat(*this, c); return *this; }
string& operator+= (const string& s) { concat(*this, s); return *this; }
string operator+ (const char* sc) const;
string operator+ (char c) const;
string operator+ (const string& s) const;
ptpublic friend string ptdecl operator+ (const char* sc, const string& s);
ptpublic friend string ptdecl operator+ (char c, const string& s);
bool operator== (const char* sc) const { return strcmp(data, sc) == 0; }
bool operator== (char) const;
bool operator== (const string&) const;
bool operator!= (const char* sc) const { return !(*this == sc); }
bool operator!= (char c) const { return !(*this == c); }
bool operator!= (const string& s) const { return !(*this == s); }
friend bool operator== (const char*, const string&);
friend bool operator== (char, const string&);
friend bool operator!= (const char*, const string&);
friend bool operator!= (char, const string&);
operator const char*() const { return data; }
operator const uchar*() const { return (uchar*)data; }
char& operator[] (int i) { idx(i); return unique(*this)[i]; }
const char& operator[] (int i) const { idx(i); return data[i]; }
friend void initialize(string& s);
friend void initialize(string& s, const string& s1);
friend void initialize(string& s, const char* s1);
friend void finalize(string& s);
};
typedef string* pstring;
inline int length(const string& s) { return STR_LENGTH(s.data); }
inline int refcount(const string& s) { return STR_REFCOUNT(s.data); }
inline void assign(string& s, const char* buf, int len) { s.assign(buf, len); }
inline void clear(string& s) { s.finalize(); }
inline bool isempty(const string& s) { return length(s) == 0; }
inline int pos(const string& s1, const string& s) { return pos(s1.data, s); }
inline bool operator== (const char* sc, const string& s){ return s == sc; }
inline bool operator== (char c, const string& s) { return s == c; }
inline bool operator!= (const char* sc, const string& s){ return s != sc; }
inline bool operator!= (char c, const string& s) { return s != c; }
inline void initialize(string& s) { s.initialize(); }
inline void initialize(string& s, const string& s1) { s.initialize(s1); }
inline void initialize(string& s, const char* s1) { s.initialize(s1); }
inline void finalize(string& s) { s.finalize(); }
ptpublic extern int stralloc;
ptpublic extern string nullstring;
// -------------------------------------------------------------------- //
// --- string utilities ----------------------------------------------- //
// -------------------------------------------------------------------- //
ptpublic string ptdecl fill(int width, char pad);
ptpublic string ptdecl pad(const string& s, int width, char c, bool left = true);
ptpublic string ptdecl itostring(large value, int base, int width = 0, char pad = 0);
ptpublic string ptdecl itostring(ularge value, int base, int width = 0, char pad = 0);
ptpublic string ptdecl itostring(int value, int base, int width = 0, char pad = 0);
ptpublic string ptdecl itostring(unsigned value, int base, int width = 0, char pad = 0);
ptpublic string ptdecl itostring(large v);
ptpublic string ptdecl itostring(ularge v);
ptpublic string ptdecl itostring(int v);
ptpublic string ptdecl itostring(unsigned v);
ptpublic large ptdecl stringtoi(const char*);
ptpublic large ptdecl stringtoie(const char*);
ptpublic ularge ptdecl stringtoue(const char*, int base);
ptpublic string ptdecl lowercase(const char* s);
ptpublic string ptdecl lowercase(const string& s);
char hex4(char c);
inline char locase(char c)
{ if (c >= 'A' && c <= 'Z') return char(c + 32); return c; }
inline char upcase(char c)
{ if (c >= 'a' && c <= 'z') return char(c - 32); return c; }
inline int hstrlen(const char* p) // some Unix systems do not accept NULL
{ return p == nil ? 0 : (int)strlen(p); }
// -------------------------------------------------------------------- //
// --- character set -------------------------------------------------- //
// -------------------------------------------------------------------- //
const int _csetbits = 256;
const int _csetbytes = _csetbits / 8;
const int _csetwords = _csetbytes / sizeof(int);
const char _csetesc = '~';
class ptpublic cset
{
protected:
char data[_csetbytes];
void assign(const cset& s) { memcpy(data, s.data, _csetbytes); }
void assign(const char* setinit);
void clear() { memset(data, 0, _csetbytes); }
void fill() { memset(data, -1, _csetbytes); }
void include(char b) { data[uchar(b) / 8] |= uchar(1 << (uchar(b) % 8)); }
void include(char min, char max);
void exclude(char b) { data[uchar(b) / 8] &= uchar(~(1 << (uchar(b) % 8))); }
void unite(const cset& s);
void subtract(const cset& s);
void intersect(const cset& s);
void invert();
bool contains(char b) const { return (data[uchar(b) / 8] & (1 << (uchar(b) % 8))) != 0; }
bool eq(const cset& s) const { return memcmp(data, s.data, _csetbytes) == 0; }
bool le(const cset& s) const;
public:
cset() { clear(); }
cset(const cset& s) { assign(s); }
cset(const char* setinit) { assign(setinit); }
cset& operator= (const cset& s) { assign(s); return *this; }
cset& operator+= (const cset& s) { unite(s); return *this; }
cset& operator+= (char b) { include(b); return *this; }
cset operator+ (const cset& s) const { cset t = *this; return t += s; }
cset operator+ (char b) const { cset t = *this; return t += b; }
cset& operator-= (const cset& s) { subtract(s); return *this; }
cset& operator-= (char b) { exclude(b); return *this; }
cset operator- (const cset& s) const { cset t = *this; return t -= s; }
cset operator- (char b) const { cset t = *this; return t -= b; }
cset& operator*= (const cset& s) { intersect(s); return *this; }
cset operator* (const cset& s) const { cset t = *this; return t *= s; }
cset operator! () const { cset t = *this; t.invert(); return t; }
bool operator== (const cset& s) const { return eq(s); }
bool operator!= (const cset& s) const { return !eq(s); }
bool operator<= (const cset& s) const { return le(s); }
bool operator>= (const cset& s) const { return s.le(*this); }
friend cset operator+ (char b, const cset& s);
friend bool operator& (char b, const cset& s);
friend void assign(cset& s, const char* setinit);
friend void clear(cset& s);
friend void fill(cset& s);
friend void include(cset& s, char b);
friend void include(cset& s, char min, char max);
friend void exclude(cset& s, char b);
ptpublic friend string ptdecl asstring(const cset& s);
};
inline cset operator+ (char b, const cset& s) { return s + b; }
inline bool operator& (char b, const cset& s) { return s.contains(b); }
inline void assign(cset& s, const char* setinit) { s.assign(setinit); }
inline void clear(cset& s) { s.clear(); }
inline void fill(cset& s) { s.fill(); }
inline void include(cset& s, char b) { s.include(b); }
inline void include(cset& s, char min, char max) { s.include(min, max); }
inline void exclude(cset& s, char b) { s.exclude(b); }
// -------------------------------------------------------------------- //
// --- basic abstract classes ----------------------------------------- //
// -------------------------------------------------------------------- //
// basic class with virtual destructor; historically was used as a base
// for all list items. also helps to count the number of created and
// destroyed objects in a program (objalloc global) in DEBUG mode, to
// detect memory leaks. most classes in ptypes are derived from unknown.
ptpublic extern int objalloc;
class ptpublic unknown
{
private:
// make all classes non-copyable by default
unknown(const unknown&);
const unknown& operator= (const unknown&);
public:
#ifdef COUNT_OBJALLOC
unknown() { pincrement(&objalloc); }
virtual ~unknown() { pdecrement(&objalloc); }
#else
unknown() { }
virtual ~unknown() { }
#endif
};
typedef unknown* punknown;
// provide non-copyable base for all classes that are
// not derived from 'unknown'
class ptpublic noncopyable
{
private:
noncopyable(const noncopyable&);
const noncopyable& operator= (const noncopyable&);
public:
noncopyable() {}
~noncopyable() {}
};
// -------------------------------------------------------------------- //
// --- exception ------------------------------------------------------ //
// -------------------------------------------------------------------- //
// the basic exception class. NOTE: the library always throws dynamically
// allocated exception objects.
class ptpublic exception: public unknown
{
protected:
string message;
public:
exception(const char* imsg);
exception(const string& imsg);
virtual ~exception();
virtual string get_message() { return message; }
};
// conversion exception class for stringtoie() and stringtoue()
class ptpublic econv: public exception
{
public:
econv(const char* msg): exception(msg) {}
econv(const string& msg): exception(msg) {}
virtual ~econv();
};
// -------------------------------------------------------------------- //
// --- tpodlist ------------------------------------------------------- //
// -------------------------------------------------------------------- //
// _podlist implements dynamic array of small POD structures; it serves
// as a basis for all list types in the library. this class is undocumented.
// tpodlist template must be used instead.
class ptpublic _podlist: public noncopyable
{
protected:
void* list; // pointer to the array
int count; // number of items in the list
int capacity; // allocated for the list
int itemsize; // list item size
static void idxerror();
_podlist& operator =(const _podlist& t);
void grow();
void* doins(int index);
void doins(int index, const _podlist&);
void* doget(int index) const { return (char*)list + index * itemsize; }
void dodel(int index);
void dodel(int index, int count);
void dopop();
#ifdef CHECK_BOUNDS
void idx(int index) const { if (unsigned(index) >= unsigned(count)) idxerror(); }
void idxa(int index) const { if (unsigned(index) > unsigned(count)) idxerror(); }
#else
void idx(int) const { }
void idxa(int) const { }
#endif
public:
_podlist(int itemsize);
~_podlist();
int get_count() const { return count; }
void set_count(int newcount, bool zero = false);
int get_capacity() const { return capacity; }
void set_capacity(int newcap);
void clear() { set_count(0); }
void pack() { set_capacity(count); }
void* ins(int index) { idxa(index); return doins(index); }
void ins(int index, const _podlist& t) { idxa(index); doins(index, t); }
void* add();
void add(const _podlist& t);
void* operator [](int index) { idx(index); return doget(index); }
void* top() { return operator [](count - 1); }
void del(int index) { idx(index); dodel(index); }
void del(int index, int count) { idx(index); dodel(index, count); }
void pop() { idx(0); dopop(); }
};
// tpodlist is a fully-inlined template based on _podlist
template <class X, bool initzero = false> class tpodlist: public _podlist
{
protected:
X& dozero(X& t) { if (initzero) memset(&t, 0, sizeof(X)); return t; }
X& doget(int index) const { return ((X*)list)[index]; }
X& doins(int index) { X& t = *(X*)_podlist::doins(index); return dozero(t); }
void doins(int index, const X& item) { *(X*)_podlist::doins(index) = item; }
public:
tpodlist(): _podlist(sizeof(X)) {}
tpodlist<X, initzero>& operator =(const tpodlist<X, initzero>& t)
{ _podlist::operator =(t); return *this; }
void set_count(int newcount) { _podlist::set_count(newcount, initzero); }
X& ins(int index) { idxa(index); return doins(index); }
void ins(int index, const X& item) { idxa(index); doins(index, item); }
void ins(int index, const tpodlist<X, initzero>& t)
{ _podlist::ins(index, t); }
X& add() { grow(); return dozero(doget(count++)); }
void add(const X& item) { grow(); doget(count++) = item; }
void add(const tpodlist<X, initzero>& t)
{ _podlist::add(t); }
X& operator [](int index) { idx(index); return doget(index); }
const X& operator [](int index) const { idx(index); return doget(index); }
X& top() { idx(0); return doget(count - 1); }
};
// -------------------------------------------------------------------- //
// --- tobjlist ------------------------------------------------------- //
// -------------------------------------------------------------------- //
// _objlist is a base for the tobjlist template, don't use it directly.
// also, _objlist is a base for _strlist and derivatives.
class ptpublic _objlist: public unknown, protected tpodlist<void*, true>
{
protected:
struct
{
unsigned ownobjects :1; // list is responsible for destroying the items; used in _objlist
unsigned ownslobjects :1; // same but for _strlist items (in _stritem structure)
unsigned sorted :1; // sorted list (_objlist+)
unsigned duplicates :1; // sorted: allows duplicate keys (_objlist+)
unsigned casesens :1; // sorted: string comparison is case sensitive (_strlist+)
unsigned _reserved :27;
} config;
_objlist(bool ownobjects); // we hide this ctor, since _objlist actually can't free objects
void* doget(int index) const { return ((void**)list)[index]; }
void doput(int index, void* obj);
void dodel(int index);
void dodel(int index, int count);
void* dopop();
void dofree(int index, int count);
virtual void dofree(void* obj); // pure method; defined in tobjlist instances
virtual int compare(const void* key, const void* obj) const; // pure method; defined in _strlist
public:
_objlist();
virtual ~_objlist();
int get_count() const { return count; }
void set_count(int newcount);
int get_capacity() const { return capacity; }
void set_capacity(int newcap) { tpodlist<void*,true>::set_capacity(newcap); }
void clear() { set_count(0); }
void pack() { tpodlist<void*,true>::pack(); }
void ins(int index, void* obj) { tpodlist<void*,true>::ins(index, obj); }
void add(void* obj) { tpodlist<void*,true>::add(obj); }
void put(int index, void* obj) { idx(index); doput(index, obj); }
void* operator [](int index) const { idx(index); return doget(index); }
void* top() const { idx(0); return doget(count - 1); }
void* pop() { idx(0); return dopop(); }
void del(int index) { idx(index); dodel(index); }
void del(int index, int count) { idx(index); dodel(index, count); }
int indexof(void* obj) const;
bool search(const void* key, int& index) const;
};
// the tobjlist template implements a list of pointers to arbitrary
// structures. optionally can automatically free objects (ownobjects)
// when removed from a list. only 2 virtual functions are being
// instantiated by this template, the rest is static code in _objlist.
template <class X> class tobjlist: public _objlist
{
protected:
X* doget(int index) const { return (X*)_objlist::doget(index); }
virtual void dofree(void* obj);
public:
tobjlist(bool ownobjects = false): _objlist(ownobjects) {}
virtual ~tobjlist();
bool get_ownobjects() const { return config.ownobjects; }
void set_ownobjects(bool newval) { config.ownobjects = newval; }
void ins(int index, X* obj) { _objlist::ins(index, obj); }
void add(X* obj) { _objlist::add(obj); }
void put(int index, X* obj) { _objlist::put(index, obj); }
X* operator [](int index) const { idx(index); return (X*)doget(index); }
X* top() const { return (X*)_objlist::top(); }
X* pop() { return (X*)_objlist::pop(); }
int indexof(X* obj) const { return _objlist::indexof(obj); }
#ifdef PTYPES19_COMPAT
friend inline void ins(tobjlist& s, int i, X* obj) { s.ins(i, obj); }
friend inline int add(tobjlist& s, X* obj) { s.add(obj); return s.get_count() - 1; }
friend inline void put(tobjlist& s, int i, X* obj) { s.put(i, obj); }
friend inline int indexof(const tobjlist& s, X* obj) { return s.indexof(obj); }
friend inline int push(tobjlist& s, X* obj) { s.add(obj); return s.get_count() - 1; }
friend inline X* pop(tobjlist& s) { return (X*)s.pop(); }
friend inline X* top(const tobjlist& s) { return (X*)s.top(); }
friend inline X* get(const tobjlist& s, int i) { return (X*)s[i]; }
#endif
};
template <class X> void tobjlist<X>::dofree(void* item)
{
delete (X*)item;
}
template <class X> tobjlist<X>::~tobjlist()
{
set_count(0);
}
// -------------------------------------------------------------------- //
// --- tstrlist ------------------------------------------------------- //
// -------------------------------------------------------------------- //
// _strlist is a base for the tstrlist template
typedef int slflags; // left for compatibility
#define SL_SORTED 1
#define SL_DUPLICATES 2
#define SL_CASESENS 4
#define SL_OWNOBJECTS 8
struct _stritem
{
string key;
void* obj;
_stritem(const string& ikey, void* iobj)
: key(ikey), obj(iobj) {}
};
class ptpublic _strlist: protected tobjlist<_stritem>
{
protected:
static void sortederror();
static void notsortederror();
static void duperror();
virtual void dofree(void* item);
virtual int compare(const void* key, const void* item) const;
virtual void dofreeobj(void* obj); // pure; tstrlist overrides it
const string& dogetkey(int index) const { return doget(index)->key; }
void* dogetobj(int index) const { return doget(index)->obj; }
void doins(int index, const string& key, void* obj);
void doput(int index, const string& key, void* obj);
void doput(int index, void* obj);
public:
_strlist(int flags = 0);
virtual ~_strlist();
int get_count() const { return count; }
void set_count(int newcount) { tobjlist<_stritem>::set_count(newcount); }
int get_capacity() const { return capacity; }
void set_capacity(int newcap) { tobjlist<_stritem>::set_capacity(newcap); }
void clear() { tobjlist<_stritem>::clear(); }
void pack() { tobjlist<_stritem>::pack(); }
bool get_sorted() const { return config.sorted; }
bool get_duplicates() const { return config.duplicates; }
bool get_casesens() const { return config.casesens; }
bool get_ownobjects() const { return config.ownslobjects; }
void set_ownobjects(bool newval) { config.ownslobjects = newval; }
void ins(int index, const string& key, void* obj) { idxa(index); doins(index, key, obj); }
void put(int index, const string& key, void* obj) { idx(index); doput(index, key, obj); }
void put(int index, void* obj) { idx(index); doput(index, obj); }
int put(const string& key, void* obj);
int add(const string& key, void* obj);
void* operator [](int index) const { idx(index); return dogetobj(index); }
void* operator [](const char* key) const;
const string& getkey(int index) const { idx(index); return dogetkey(index); }
bool search(const char* key, int& index) const { return _objlist::search(key, index); }
void del(int index) { idx(index); dodel(index); }
void del(int index, int delcount) { idx(index); dodel(index, delcount); }
void del(const char* key) { put(key, nil); }
int indexof(const char* key) const;
int indexof(void* obj) const;
};
// the tstrlist template implements a list of string/object pairs,
// optionally sorted for fast searching by string key.
template <class X> class tstrlist: public _strlist
{
protected:
virtual void dofreeobj(void* obj);
public:
tstrlist(int flags = 0): _strlist(flags) {}
virtual ~tstrlist();
void ins(int index, const string& key, X* obj) { _strlist::ins(index, key, obj); }
void put(int index, const string& key, X* obj) { _strlist::put(index, key, obj); }
void put(int index, X* obj) { _strlist::put(index, obj); }
int put(const string& key, X* obj) { return _strlist::put(key, obj); }
int add(const string& key, X* obj) { return _strlist::add(key, obj); }
X* operator [](int index) const { return (X*)_strlist::operator [](index); }
X* operator [](const char* key) const { return (X*)_strlist::operator [](key); }
int indexof(X* obj) const { return _strlist::indexof(obj); }
int indexof(const char* key) const { return _strlist::indexof(key); }
#ifdef PTYPES19_COMPAT
// pre-2.0 interface for backwards compatibility
friend inline void ins(tstrlist& s, int i, const string& str, X* obj) { s.ins(i, str, obj); }
friend inline int add(tstrlist& s, const string& str, X* obj) { return s.add(str, obj); }
friend inline void put(tstrlist& s, int i, const string& str, X* obj) { s.put(i, str, obj); }
friend inline void put(tstrlist& s, int i, X* obj) { s.put(i, obj); }
friend inline int indexof(const tstrlist& s, X* obj) { return s.indexof(obj); }
friend inline X* get(const tstrlist& s, int i) { return (X*)s[i]; }
#endif
};
template <class X> void tstrlist<X>::dofreeobj(void* obj)
{
delete (X*)obj;
}
template <class X> tstrlist<X>::~tstrlist()
{
set_count(0);
}
// -------------------------------------------------------------------- //
// --- textmap -------------------------------------------------------- //
// -------------------------------------------------------------------- //
// textmap is a list of string pairs (key/value)
struct _textitem
{
string key;
string value;
_textitem(const string& ikey, const string& ivalue)
: key(ikey), value(ivalue) {}
};
class ptpublic textmap: protected tobjlist<_textitem>
{
protected:
virtual int compare(const void* key, const void* item) const;
const string& dogetvalue(int index) const { return doget(index)->value; }
const string& dogetkey(int index) const { return doget(index)->key; }
public:
textmap(bool casesens = false);
virtual ~textmap();
int get_count() const { return tobjlist<_textitem>::get_count(); }
void pack() { tobjlist<_textitem>::pack(); }
void clear() { tobjlist<_textitem>::clear(); }
int put(const string& key, const string& value);
void del(int index) { idx(index); dodel(index); }
void del(const char* key) { put(key, nullstring); }
const string& get(int index) const { idx(index); return dogetvalue(index); }
const string& getkey(int index) const { idx(index); return dogetkey(index); }
const string& get(const char* key) const;
const string& operator [](int index) const { return get(index); }
const string& operator [](const char* key) const { return get(key); }
int indexof(const char* key) const;
};
// -------------------------------------------------------------------- //
// --- component ------------------------------------------------------ //
// -------------------------------------------------------------------- //
// the component class is an abstract class that provides reference
// counting and delete notification mechanisms. all stream classes
// in ptypes are derived from component.
// class ID's for all basic types: the first byte (least significant)
// contains the base ID, the next is for the second level of inheritance,
// etc. total of 4 levels allowed for basic types. call classid() for an
// object, mask out first N bytes of interest and compare with a CLASS_XXX
// value. f.ex. to determine whether an object is of type infile or any
// derivative: (o->classid() & 0xffff) == CLASS2_INFILE. this scheme is for
// internal use by PTypes and Objection; partly replaces the costly C++ RTTI
// system.
// first level of inheritance
const int CLASS_UNDEFINED = 0x00000000;
const int CLASS_INSTM = 0x00000001;
const int CLASS_OUTSTM = 0x00000002;
const int CLASS_UNIT = 0x00000003;
// second level of inheritance
const int CLASS2_INFILE = 0x00000100 | CLASS_INSTM;
const int CLASS2_INMEMORY = 0x00000200 | CLASS_INSTM;
const int CLASS2_FDX = 0x00000300 | CLASS_INSTM;
const int CLASS2_OUTFILE = 0x00000100 | CLASS_OUTSTM;
const int CLASS2_OUTMEMORY = 0x00000200 | CLASS_OUTSTM;
// third level of inheritance
const int CLASS3_LOGFILE = 0x00010000 | CLASS2_OUTFILE;
const int CLASS3_IPSTM = 0x00020000 | CLASS2_FDX;
const int CLASS3_NPIPE = 0x00030000 | CLASS2_FDX;
class ptpublic component: public unknown
{
protected:
int refcount; // reference counting, used by addref() and release()
tobjlist<component>* freelist; // list of components to notify about destruction, safer alternative to ref-counting
void* typeinfo; // reserved for future use
virtual void freenotify(component* sender);
public:
component();
virtual ~component();
void addnotification(component* obj);
void delnotification(component* obj);
ptpublic friend component* ptdecl addref(component*);
ptpublic friend bool ptdecl release(component*);
friend int refcount(component* c);
virtual int classid();
void set_typeinfo(void* t) { typeinfo = t; }
void* get_typeinfo() { return typeinfo; }
};
typedef component* pcomponent;
inline int refcount(component* c) { return c->refcount; }
template <class T> inline T* taddref(T* c)
{ return (T*)addref((component*)c); }
template <class T> class compref
{
protected:
T* ref;
public:
compref() { ref = 0; }
compref(const compref<T>& r) { ref = taddref<T>(r.ref); }
compref(T* c) { ref = taddref<T>(c); }
~compref() { release(ref); }
compref<T>& operator =(T* c);
compref<T>& operator =(const compref<T>& r) { return operator =(r.ref); }
T& operator *() const { return *ref; }
T* operator ->() const { return ref; }
bool operator ==(const compref<T>& r) const { return ref == r.ref; }
bool operator ==(T* c) const { return ref == c; }
bool operator !=(const compref<T>& r) const { return ref != r.ref; }
bool operator !=(T* c) const { return ref != c; }
operator T*() const { return ref; }
};
template <class T> compref<T>& compref<T>::operator =(T* c)
{
release(tpexchange<T>(&ref, taddref<T>(c)));
return *this;
}
// -------------------------------------------------------------------- //
// --- variant -------------------------------------------------------- //
// -------------------------------------------------------------------- //
enum {
VAR_NULL,
VAR_INT,
VAR_BOOL,
VAR_FLOAT,
VAR_STRING,
VAR_ARRAY,
VAR_OBJECT,
VAR_COMPOUND = VAR_STRING
};
class ptpublic _varray;
class ptpublic variant
{
friend class string;
friend class _varray;
protected:
int tag; // VAR_XXX
union {
large i; // 64-bit int value
bool b; // bool value
double f; // double value
char* s; // string object; can't declare as string because of the union
_varray* a; // pointer to a reference-counted _strlist object
component* o; // pointer to a reference-counted component object (or derivative)
} value; // we need this name to be able to copy the entire union in some situations
void initialize() { tag = VAR_NULL; }
void initialize(large v) { tag = VAR_INT; value.i = v; }
void initialize(bool v) { tag = VAR_BOOL; value.b = v; }
void initialize(double v) { tag = VAR_FLOAT; value.f = v; }
void initialize(const char* v) { tag = VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
void initialize(const string& v) { tag = VAR_STRING; PTYPES_NAMESPACE::initialize(PTR_TO_STRING(value.s), v); }
void initialize(_varray* a);
void initialize(component* o);
void initialize(const variant& v);
void finalize();
void assign(large);
void assign(bool);
void assign(double);
void assign(const char*);
void assign(const string&);
void assign(_varray*);
void assign(component*);
void assign(const variant&);
bool equal(const variant& v) const;
variant(_varray* a) { initialize(a); }
public:
// construction
variant() { initialize(); }
variant(int v) { initialize(large(v)); }
variant(unsigned int v) { initialize(large(v)); }
variant(large v) { initialize(v); }
variant(bool v) { initialize(v); }
variant(double v) { initialize(v); }
variant(const char* v) { initialize(v); }
variant(const string& v) { initialize(v); }
variant(component* v) { initialize(v); }
variant(const variant& v) { initialize(v); }
~variant() { finalize(); }
// assignment
variant& operator= (int v) { assign(large(v)); return *this; }
variant& operator= (unsigned int v) { assign(large(v)); return *this; }
variant& operator= (large v) { assign(v); return *this; }
variant& operator= (bool v) { assign(v); return *this; }
variant& operator= (double v) { assign(v); return *this; }
variant& operator= (const char* v) { assign(v); return *this; }
variant& operator= (const string& v) { assign(v); return *this; }
variant& operator= (component* v) { assign(v); return *this; }
variant& operator= (const variant& v) { assign(v); return *this; }
// typecast
operator int() const;
operator unsigned int() const;
operator long() const;
operator unsigned long() const;
operator large() const;
operator bool() const;
operator double() const;
operator string() const;
operator component*() const;
// comparison
bool operator== (const variant& v) const { return equal(v); }
bool operator!= (const variant& v) const { return !equal(v); }
// typification
ptpublic friend void ptdecl clear(variant&);
friend int vartype(const variant& v);
friend bool isnull(const variant& v);
friend bool isint(const variant& v);
friend bool isbool(const variant& v);
friend bool isfloat(const variant& v);
friend bool isstring(const variant& v);
friend bool isarray(const variant& v);
friend bool isobject(const variant& v);
friend bool iscompound(const variant& v);
// array manipulation
ptpublic friend void ptdecl aclear(variant&);
ptpublic friend variant ptdecl aclone(const variant&);
ptpublic friend const variant& ptdecl get(const variant&, const string& key);
ptpublic friend const variant& ptdecl get(const variant&, large key);
ptpublic friend void ptdecl put(variant&, const string& key, const variant& item);
ptpublic friend void ptdecl put(variant&, large key, const variant& item);
ptpublic friend void ptdecl del(variant&, const string& key);
ptpublic friend void ptdecl del(variant&, large key);
ptpublic friend void ptdecl add(variant & v, const variant & var);
// indexed access to arrays
ptpublic friend int ptdecl alength(const variant&);
ptpublic friend void ptdecl apack(variant&);
ptpublic friend bool ptdecl anext(const variant& a, int&, variant& item);
ptpublic friend bool ptdecl anext(const variant& a, int&, variant& item, string& key);
ptpublic friend bool ptdecl anext(const variant& a, int&, variant& item, variant& key);
ptpublic friend int ptdecl aadd(variant&, const variant& item);
ptpublic friend void ptdecl aput(variant&, int index, const variant& item);
ptpublic friend void ptdecl ains(variant&, int index, const variant& item);
ptpublic friend void ptdecl adel(variant&, int index);
ptpublic friend const variant& ptdecl aget(const variant&, int index);
ptpublic friend string ptdecl akey(const variant&, int index);
const variant& operator[](const char* key) const { return get(*this, string(key)); }
const variant& operator[](const string& key) const { return get(*this, key); }
const variant& operator[](large key) const { return get(*this, key); }
// 'manual' initialization/finalization, undocumented. use with care!
friend void initialize(variant& v);
friend void initialize(variant& v, large i);
friend void initialize(variant& v, int i);
friend void initialize(variant& v, unsigned int i);
friend void initialize(variant& v, bool i);
friend void initialize(variant& v, double i);
friend void initialize(variant& v, const char* i);
friend void initialize(variant& v, const string& i);
friend void initialize(variant& v, component* i);
friend void initialize(variant& v, const variant& i);
friend void finalize(variant& v);
};
typedef variant* pvariant;
inline int vartype(const variant& v) { return v.tag; }
inline bool isnull(const variant& v) { return v.tag == VAR_NULL; }
inline bool isint(const variant& v) { return v.tag == VAR_INT; }
inline bool isbool(const variant& v) { return v.tag == VAR_BOOL; }
inline bool isfloat(const variant& v) { return v.tag == VAR_FLOAT; }
inline bool isstring(const variant& v) { return v.tag == VAR_STRING; }
inline bool isarray(const variant& v) { return v.tag == VAR_ARRAY; }
inline bool isobject(const variant& v) { return v.tag == VAR_OBJECT; }
inline bool iscompound(const variant& v) { return v.tag >= VAR_COMPOUND; }
inline void initialize(variant& v) { v.initialize(); }
inline void initialize(variant& v, large i) { v.initialize(i); }
inline void initialize(variant& v, int i) { v.initialize(large(i)); }
inline void initialize(variant& v, unsigned int i) { v.initialize(large(i)); }
inline void initialize(variant& v, bool i) { v.initialize(i); }
inline void initialize(variant& v, double i) { v.initialize(i); }
inline void initialize(variant& v, const char* i) { v.initialize(i); }
inline void initialize(variant& v, const string& i) { v.initialize(i); }
inline void initialize(variant& v, component* i) { v.initialize(i); }
inline void initialize(variant& v, const variant& i) { v.initialize(i); }
inline void finalize(variant& v) { if (v.tag >= VAR_COMPOUND) v.finalize(); }
ptpublic extern const variant nullvar;
// variant exception class; may be thrown when a variant
// is being typecast'ed to 32-bit int and the value is
// out of range
class ptpublic evariant: public exception
{
protected:
public:
evariant(const char* msg): exception(msg) {}
evariant(const string& msg): exception(msg) {}
virtual ~evariant();
};
// -------------------------------------------------------------------- //
// --- pre-2.0 compatibility declarations ----------------------------- //
// -------------------------------------------------------------------- //
#ifdef PTYPES19_COMPAT
// ptypes-1.9 objlist and strlist: accept only 'unknown' and
// derivatives as a base type
class ptpublic objlist: public tobjlist<unknown>
{
public:
objlist(bool ownobjects = false);
virtual ~objlist();
};
inline int length(const _objlist& s) { return s.get_count(); }
inline void setlength(_objlist& s, int newcount) { s.set_count(newcount); }
inline void pack(_objlist& s) { s.pack(); }
inline void clear(_objlist& s) { s.clear(); }
inline int push(_objlist& s, unknown* obj) { s.add(obj); return length(s) - 1; }
inline unknown* top(const _objlist& s) { return (unknown*)s.top(); }
inline void ins(_objlist& s, int i, unknown* obj) { s.ins(i, obj); }
inline int add(_objlist& s, unknown* obj) { s.add(obj); return length(s) - 1; }
inline void put(_objlist& s, int i, unknown* obj) { s.put(i, obj); }
inline unknown* get(const _objlist& s, int i) { return (unknown*)s[i]; }
inline unknown* pop(_objlist& s) { return (unknown*)s.pop(); }
inline void del(_objlist& s, int i) { s.del(i); }
inline int indexof(const _objlist& s, unknown* obj) { return s.indexof(obj); }
class ptpublic strlist: public tstrlist<unknown>
{
public:
strlist(int flags = 0);
virtual ~strlist();
};
inline int length(const _strlist& s) { return s.get_count(); }
inline void clear(_strlist& s) { s.clear(); }
inline void pack(_strlist& s) { s.pack(); }
inline bool search(const _strlist& s, const char* key, int& i) { return s.search(key, i); }
inline void ins(_strlist& s, int i, const string& key, unknown* obj) { s.ins(i, key, obj); }
inline int add(_strlist& s, const string& key, unknown* obj) { return s.add(key, obj); }
inline void put(_strlist& s, int i, const string& key, unknown* obj) { s.put(i, key, obj); }
inline void put(_strlist& s, int i, unknown* obj) { s.put(i, obj); }
inline unknown* get(const _strlist& s, int i) { return (unknown*)s[i]; }
inline const string& getstr(const _strlist& s, int i) { return s.getkey(i); }
inline void del(_strlist& s, int i) { s.del(i); }
inline int find(const _strlist& s, const char* key) { return s.indexof(key); }
inline int indexof(const _strlist& s, unknown* obj) { return s.indexof(obj); }
// ptypes-1.9 strmap: now replaced with _strlist(SL_SORTED)
class ptpublic strmap: public tstrlist<unknown>
{
public:
strmap(int flags = 0);
virtual ~strmap();
};
inline void put(strmap& m, const string& key, unknown* obj) { m.put(key, obj); }
inline unknown* get(const strmap& m, const char* key) { return m[key]; }
inline void del(strmap& m, const char* key) { m.del(key); }
template <class X> class tstrmap: public strmap
{
public:
tstrmap(): strmap() {}
tstrmap(int iflags): strmap(iflags) {}
friend inline X* get(const tstrmap& m, const char* str) { return (X*)PTYPES_NAMESPACE::get((const strmap&)m, str); }
friend inline void put(tstrmap& m, const string& str, X* obj) { unknown* t = obj; PTYPES_NAMESPACE::put(m, str, t); }
X* operator[] (const char* str) const { return (X*)PTYPES_NAMESPACE::get(*this, str); }
};
// ptypes-1.9 textmap interface
inline int length(const textmap& m) { return m.get_count(); }
inline void clear(textmap& m) { m.clear(); }
inline const string& get(const textmap& m, const string& k) { return m.get(k); }
inline void put(textmap& m, const string& k, const string& v) { m.put(k, v); }
inline void del(textmap& m, const string& k) { m.del(k); }
#endif // PTYPES19_COMPAT
#ifdef _MSC_VER
#pragma warning(pop)
#pragma pack(pop)
#endif
PTYPES_END
#endif // __PTYPES_H__
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<html>
<head>
<title>C++ Portable Types Library (PTypes) Version 2.1</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="doc/styles.css">
</head>
<body bgcolor="#FFFFFF" leftmargin="40" marginwidth="40">
<img src="doc/title-21.png" width="253" height="39" alt="C++ Portable Types Library (PTypes) Version 2.1">
<hr size="1" noshade>
<blockquote>
<p align="right">The purpose of software engineering&nbsp;<br>
is to manage complexity, not to create it.<br>
<i>Bill Catambay</i></p>
</blockquote>
<p> <b>PTypes</b> (C++ Portable Types Library) is a simple alternative to the
STL that includes multithreading and networking. It defines dynamic strings, variants,
character sets, lists and other basic data types along with portable thread and
synchronization objects, IP sockets and named pipes. Its main `target audience'
is developers of complex network daemons, robots or non-visual client/server applications
of any kind.</p>
<p>PTypes defines simple and intuitive interfaces and differs from the STL in
fairly moderate use of templates. The library is portable across many modern operating
systems (currently Linux, MacOS X, SunOS, FreeBSD, HP-UX and Windows). All platform-dependent
issues are hidden inside. A simple web server called wshare is included in the
package to demonstrate the full power of the library.</p>
<p>And finally, PTypes is open and free. </p>
<ul>
<li>
<p><a href="doc/index.html">Documentation</a><br>
The documentation is available both on-line and off-line, i.e. as a part of the
downloadable package. You may want to take a look at the <a href="doc/intro.html">Introduction</a>
first.</p>
</li>
</ul>
<ul>
<li>
<p><a href="LICENSE">License</a><br>
PTypes is a free library and is covered by a simple license known as &quot;zlib/libpng
License&quot;. It grants full freedom to use the library for commercial, educational
or any other purpose except that you can not change its name and/or the copyright
notice and redistribute it as your own work.</p>
</li>
</ul>
<ul>
<li>
<p><a href="http://www.melikyan.com/ptypes/ptypes-2.1.1.tar.gz">Download PTypes
2.1.1</a>: <a href="http://www.melikyan.com/ptypes/ptypes-2.1.1.tar.gz">[primary
site]</a>&nbsp;&nbsp;<a href="http://prdownloads.sourceforge.net/ptypes/ptypes-2.1.1.tar.gz">[from
SourceForge.net]</a><br>
Although the text files in this package are in UNIX format, they can be displayed
and edited in most non-UNIX development environments. No binaries are currently
available.</p>
</li>
</ul>
<ul>
<li>
<p><a href="http://freshmeat.net/projects/ptypes/">Subscribe to new releases</a><br>
Become a freshmeat.net user and subscribe to the future announcements about PTypes.
(freshmeat itself is a huge repository of open-source software.)</p>
</li>
</ul>
<ul>
<li>
<p><a href="http://sourceforge.net/projects/ptypes/">Discussion forum and bug
tracking</a><br>
Post your questions, comments, feature requests and bug reports through PTypes
project management page at SourceForge.net.</p>
</li>
</ul>
<p>The original location of this library is <a href="http://www.melikyan.com/ptypes/">http://www.melikyan.com/ptypes/</a></p>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><hr size="1" noshade></td>
</tr>
<tr>
<td>&copy; 2001-2007 <a href="http://www.melikyan.com/hovik/">Hovik Melikyan</a></td>
</tr>
</table>
</body>
</html>
src/Makefile.Darwin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for MacOS X (Darwin), called from ../Makefile
#
CXX = c++
OS_CXXOPTS_ST = -Wall -Wno-long-double -fno-common
OS_CXXOPTS = $(OS_CXXOPTS_ST) -fPIC
LIBTOOL = $(CXX) -dynamiclib
SOSTRIP = test
SOEXT = dylib
SOINSTOPT = -install_name /usr/lib/$(SOREALNAME)
PREFIX = /usr
include Makefile.common
src/Makefile.FreeBSD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for FreeBSD, called from ../Makefile
#
CXX = g++
OS_CXXOPTS_ST = -Wall
OS_CXXOPTS = $(OS_CXXOPTS_ST) -pthread -fPIC
# OS_LDLIBS = -lc_r
LIBTOOL = $(CXX) -shared -pthread
SOSTRIP = strip
SOEXT = so
SOINSTOPT = -h $(SOREALNAME)
PREFIX = /usr/local
include Makefile.common
src/Makefile.HP-UX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for HP-UX, called from ../Makefile
#
CXX = aCC
OS_CXXOPTS_ST = -z -ext -D_HPUX_SOURCE -D_FILE_OFFSET_BITS=64
OS_CXXOPTS = $(OS_CXXOPTS_ST) -mt +z
# OS_LDLIBS_ST
OS_LDLIBS = -lrt
LIBTOOL = $(CXX) -b -mt
SOSTRIP = strip
SOEXT = sl
SOINSTOPT = -Wl,+h,$(SOREALNAME)
PREFIX = /usr/local
include Makefile.common
src/Makefile.Linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for Linux, called from ../Makefile
#
CXX = g++
OS_CXXOPTS_ST = -Wall -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
OS_CXXOPTS = $(OS_CXXOPTS_ST) -pthread -fPIC
LIBTOOL = $(CXX) -shared -pthread
SOSTRIP = strip
SOEXT = so
SOINSTOPT = -Xlinker -soname -Xlinker $(SOREALNAME)
PREFIX = /usr
include Makefile.common
src/Makefile.SunOS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for SunOS, called from ../Makefile
#
CXX = g++
AS = as
OS_CXXOPTS_ST = -Wall -D_FILE_OFFSET_BITS=64
OS_CXXOPTS = $(OS_CXXOPTS_ST) -D_REENTRANT -fPIC
OS_LDLIBS_ST = -lsocket -lnsl -lposix4
OS_LDLIBS = $(OS_LDLIBS_ST) -lpthread
LIBTOOL = $(CXX) -shared
SOSTRIP = strip
SOEXT = so
SOINSTOPT = -h $(SOREALNAME)
PREFIX = /usr/local
EXTRA_OBJS = mt/patomic.sparc.o
ASOPTS = -xarch=v8plus
mt/patomic.sparc.o: patomic.sparc.s
$(AS) $(ASOPTS) -o $@ patomic.sparc.s
include Makefile.common
src/Makefile.common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for all platforms, called automatically from
# Makefile.<platform>
#
.SUFFIXES:.cxx .o
AR = ar cru
RANLIB = ranlib
DDEBUG = -DDEBUG
INCDIR = ../include
CXXOPTS = $(OS_CXXOPTS) $(DDEBUG) -I$(INCDIR) -O2
LDLIBS = $(OS_LDLIBS)
CXXOPTS_ST = -DPTYPES_ST $(OS_CXXOPTS_ST) $(DDEBUG) -I$(INCDIR) -O2
LDLIBS_ST = $(OS_LDLIBS_ST)
LIBNAME = libptypes.a
LIBNAME_ST = libptypesn.a
LIBDEST = ../lib
SOBASENAME = libptypes
SONAME = $(SOBASENAME).$(SOEXT)
SOVER = 21
SOREALNAME = $(SOBASENAME).$(SOEXT).$(SOVER)
SODEST = ../so
LIBOBJS = mt/pversion.o mt/pmem.o mt/pfatal.o mt/pstring.o mt/pcset.o mt/pcsetdbg.o \
mt/pstrmanip.o mt/pstrutils.o mt/pstrconv.o mt/pstrtoi.o mt/pstrcase.o mt/ptime.o \
mt/punknown.o mt/pcomponent.o mt/pexcept.o mt/ppodlist.o mt/pobjlist.o mt/pstrlist.o mt/ptextmap.o \
mt/patomic.o mt/pasync.o mt/psemaphore.o mt/pthread.o mt/pmsgq.o mt/ptimedsem.o \
mt/prwlock.o mt/ptrigger.o mt/pmtxtable.o mt/pvariant.o \
mt/piobase.o mt/pinstm.o mt/pinfile.o mt/ppipe.o mt/pinmem.o mt/poutmem.o \
mt/pintee.o mt/poutstm.o mt/poutfile.o mt/pinfilter.o mt/poutfilter.o mt/pmd5.o \
mt/pputf.o mt/pstdio.o mt/pfdxstm.o mt/pnpipe.o mt/pnpserver.o \
mt/pipbase.o mt/pipsvbase.o mt/pipstm.o mt/pipstmsv.o mt/pipmsg.o mt/pipmsgsv.o \
mt/punit.o \
$(EXTRA_OBJS)
LIBOBJS_ST = st/pversion.o st/pmem.o st/pfatal.o st/pstring.o st/pcset.o st/pcsetdbg.o \
st/pstrmanip.o st/pstrutils.o st/pstrconv.o st/pstrtoi.o st/pstrcase.o st/ptime.o \
st/punknown.o st/pcomponent.o st/pexcept.o st/ppodlist.o st/pobjlist.o st/pstrlist.o st/ptextmap.o \
st/patomic.o st/pvariant.o \
st/piobase.o st/pinstm.o st/pinfile.o st/ppipe.o st/pinmem.o st/poutmem.o \
st/pintee.o st/poutstm.o st/poutfile.o st/pinfilter.o st/poutfilter.o st/pmd5.o \
st/pputf.o st/pstdio.o st/pfdxstm.o st/pnpipe.o st/pnpserver.o \
st/pipbase.o st/pipsvbase.o st/pipstm.o st/pipstmsv.o st/pipmsg.o st/pipmsgsv.o \
$(EXTRA_OBJS_ST)
HLEVEL1= $(INCDIR)/pport.h
HLEVEL2= $(HLEVEL1) $(INCDIR)/ptypes.h $(INCDIR)/pasync.h $(INCDIR)/ptime.h
HLEVEL3= $(HLEVEL2) $(INCDIR)/pstreams.h
HLEVEL4= $(HLEVEL3) $(INCDIR)/pinet.h
HALL= $(HLEVEL4)
all: mtlib shlib stlib ptypes_test ptypesn_test
mtlib: mt $(LIBNAME)
shlib: mt $(SOREALNAME)
stlib: st $(LIBNAME_ST)
#
# libptypes
#
$(LIBNAME): $(LIBOBJS)
$(AR) $@ $(LIBOBJS)
$(RANLIB) $@
mkdir -p $(LIBDEST) ; cp $@ $(LIBDEST)/
$(SOREALNAME): $(LIBOBJS)
$(LIBTOOL) $(LIBOBJS) $(LDLIBS) $(SOINSTOPT) -o $@
rm -f $(SONAME) ; ln -s $@ $(SONAME)
mkdir -p $(SODEST) ; cp $@ $(SODEST)/
cd $(SODEST) ; rm -f $(SONAME) ; ln -s $@ $(SONAME) ; $(SOSTRIP) $@
$(LIBNAME_ST): $(LIBOBJS_ST)
$(AR) $@ $(LIBOBJS_ST)
$(RANLIB) $@
mkdir -p $(LIBDEST) ; cp $@ $(LIBDEST)/
mt:
if [ ! -d mt ] ; then mkdir mt ; fi
st:
if [ ! -d st ] ; then mkdir st ; fi
#
# multithreaded compilation
#
mt/pversion.o: pversion.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS) -o $@ pversion.cxx
mt/pmem.o: pmem.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS) -o $@ pmem.cxx
mt/pfatal.o: pfatal.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS) -o $@ pfatal.cxx
mt/pstring.o: pstring.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pstring.cxx
mt/pcset.o: pcset.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pcset.cxx
mt/pcsetdbg.o: pcsetdbg.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pcsetdbg.cxx
mt/pstrmanip.o: pstrmanip.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrmanip.cxx
mt/pstrutils.o: pstrutils.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrutils.cxx
mt/pstrconv.o: pstrconv.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrconv.cxx
mt/pstrtoi.o: pstrtoi.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrtoi.cxx
mt/pstrcase.o: pstrcase.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrcase.cxx
mt/ptime.o: ptime.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ ptime.cxx
mt/punknown.o: punknown.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ punknown.cxx
mt/pcomponent.o: pcomponent.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pcomponent.cxx
mt/pexcept.o: pexcept.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pexcept.cxx
mt/ppodlist.o: ppodlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ ppodlist.cxx
mt/pobjlist.o: pobjlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pobjlist.cxx
mt/pstrlist.o: pstrlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pstrlist.cxx
mt/ptextmap.o: ptextmap.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ ptextmap.cxx
mt/patomic.o: patomic.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ patomic.cxx
mt/pasync.o: pasync.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pasync.cxx
mt/psemaphore.o: psemaphore.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ psemaphore.cxx
mt/pthread.o: pthread.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pthread.cxx
mt/pmsgq.o: pmsgq.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pmsgq.cxx
mt/ptimedsem.o: ptimedsem.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ ptimedsem.cxx
mt/prwlock.o: prwlock.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ prwlock.cxx
mt/ptrigger.o: ptrigger.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ ptrigger.cxx
mt/pmtxtable.o: pmtxtable.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pmtxtable.cxx
mt/pvariant.o: pvariant.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS) -o $@ pvariant.cxx
mt/piobase.o: piobase.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ piobase.cxx
mt/pinstm.o: pinstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pinstm.cxx
mt/pinfile.o: pinfile.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pinfile.cxx
mt/ppipe.o: ppipe.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ ppipe.cxx
mt/pintee.o: pintee.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pintee.cxx
mt/pinmem.o: pinmem.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pinmem.cxx
mt/poutmem.o: poutmem.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ poutmem.cxx
mt/poutstm.o: poutstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ poutstm.cxx
mt/poutfile.o: poutfile.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ poutfile.cxx
mt/pinfilter.o: pinfilter.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pinfilter.cxx
mt/poutfilter.o: poutfilter.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ poutfilter.cxx
mt/pmd5.o: pmd5.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pmd5.cxx
mt/pputf.o: pputf.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pputf.cxx
mt/pstdio.o: pstdio.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pstdio.cxx
mt/pfdxstm.o: pfdxstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pfdxstm.cxx
mt/pnpipe.o: pnpipe.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pnpipe.cxx
mt/pnpserver.o: pnpserver.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ pnpserver.cxx
mt/pipbase.o: pipbase.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipbase.cxx
mt/pipsvbase.o: pipsvbase.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipsvbase.cxx
mt/pipstm.o: pipstm.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipstm.cxx
mt/pipstmsv.o: pipstmsv.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipstmsv.cxx
mt/pipmsg.o: pipmsg.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipmsg.cxx
mt/pipmsgsv.o: pipmsgsv.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS) -o $@ pipmsgsv.cxx
mt/punit.o: punit.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS) -o $@ punit.cxx
#
# single-threaded compilation
#
st/pversion.o: pversion.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS_ST) -o $@ pversion.cxx
st/pmem.o: pmem.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS_ST) -o $@ pmem.cxx
st/pfatal.o: pfatal.cxx $(HLEVEL1)
$(CXX) -c $(CXXOPTS_ST) -o $@ pfatal.cxx
st/pstring.o: pstring.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstring.cxx
st/pcset.o: pcset.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pcset.cxx
st/pcsetdbg.o: pcsetdbg.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pcsetdbg.cxx
st/pstrmanip.o: pstrmanip.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrmanip.cxx
st/pstrutils.o: pstrutils.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrutils.cxx
st/pstrconv.o: pstrconv.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrconv.cxx
st/pstrtoi.o: pstrtoi.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrtoi.cxx
st/pstrcase.o: pstrcase.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrcase.cxx
st/ptime.o: ptime.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ ptime.cxx
st/punknown.o: punknown.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ punknown.cxx
st/pcomponent.o: pcomponent.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pcomponent.cxx
st/pexcept.o: pexcept.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pexcept.cxx
st/ppodlist.o: ppodlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ ppodlist.cxx
st/pobjlist.o: pobjlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pobjlist.cxx
st/pstrlist.o: pstrlist.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstrlist.cxx
st/ptextmap.o: ptextmap.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ ptextmap.cxx
st/patomic.o: patomic.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ patomic.cxx
st/pvariant.o: pvariant.cxx $(HLEVEL2)
$(CXX) -c $(CXXOPTS_ST) -o $@ pvariant.cxx
st/piobase.o: piobase.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ piobase.cxx
st/pinstm.o: pinstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pinstm.cxx
st/pinfile.o: pinfile.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pinfile.cxx
st/ppipe.o: ppipe.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ ppipe.cxx
st/pintee.o: pintee.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pintee.cxx
st/pinmem.o: pinmem.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pinmem.cxx
st/poutmem.o: poutmem.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ poutmem.cxx
st/poutstm.o: poutstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ poutstm.cxx
st/poutfile.o: poutfile.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ poutfile.cxx
st/pinfilter.o: pinfilter.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pinfilter.cxx
st/poutfilter.o: poutfilter.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ poutfilter.cxx
st/pmd5.o: pmd5.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pmd5.cxx
st/pputf.o: pputf.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pputf.cxx
st/pstdio.o: pstdio.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pstdio.cxx
st/pfdxstm.o: pfdxstm.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pfdxstm.cxx
st/pnpipe.o: pnpipe.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pnpipe.cxx
st/pnpserver.o: pnpserver.cxx $(HLEVEL3)
$(CXX) -c $(CXXOPTS_ST) -o $@ pnpserver.cxx
st/pipbase.o: pipbase.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipbase.cxx
st/pipsvbase.o: pipsvbase.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipsvbase.cxx
st/pipstm.o: pipstm.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipstm.cxx
st/pipstmsv.o: pipstmsv.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipstmsv.cxx
st/pipmsg.o: pipmsg.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipmsg.cxx
st/pipmsgsv.o: pipmsgsv.cxx $(HLEVEL4)
$(CXX) -c $(CXXOPTS_ST) -o $@ pipmsgsv.cxx
#
# libptypes test program
#
mt/ptypes_test.o: ptypes_test.cxx $(HALL)
$(CXX) -c $(CXXOPTS) -o $@ ptypes_test.cxx
ptypes_test: mt/ptypes_test.o $(LIBNAME)
$(CXX) $(CXXOPTS) mt/ptypes_test.o -L./ libptypes.a $(LDLIBS) -o $@
st/ptypes_test.o: ptypes_test.cxx $(HALL)
$(CXX) -c $(CXXOPTS_ST) -o $@ ptypes_test.cxx
ptypesn_test: st/ptypes_test.o $(LIBNAME)
$(CXX) $(CXXOPTS_ST) st/ptypes_test.o -L./ libptypesn.a $(LDLIBS_ST) -o $@
#
# clean
#
clean: clean-src
rm -f $(LIBDEST)/$(LIBNAME) $(LIBDEST)/$(LIBNAME_ST)
rm -f $(SODEST)/$(SONAME) $(SODEST)/$(SOREALNAME)
clean-src:
rm -rf mt st
rm -f $(LIBNAME) $(LIBNAME_ST) $(SONAME) $(SOREALNAME)
rm -f core *.core core.*
rm -f ptypes_test ptypesn_test ptypes_test.exe ptypesn_test.exe
rm -f stmtest.txt
#
# install
#
install: $(LIBNAME) $(SOREALNAME) ${LIBNAME_ST}
@echo ; echo "##### Installing header files in ${PREFIX}/include/ptypes"
mkdir -p ${PREFIX}/include/ptypes
install -m 444 ${INCDIR}/*.h ${PREFIX}/include/ptypes
@echo ; echo "##### Installing libraries (libptypes*) in ${PREFIX}/lib"
mkdir -p ${PREFIX}/lib
install -m 444 $(LIBDEST)/$(LIBNAME) $(LIBDEST)/$(LIBNAME_ST) ${PREFIX}/lib
install -m 444 $(SODEST)/$(SOREALNAME) ${PREFIX}/lib
cd ${PREFIX}/lib ; rm -f ${SONAME} ; ln -s ${SOREALNAME} ${SONAME}
@echo ; echo "##### Installing documentation in ${PREFIX}/share/doc/ptypes/doc"
mkdir -p ${PREFIX}/share/doc/ptypes/doc
cd .. ; install -m 444 LICENSE index.html ${PREFIX}/share/doc/ptypes
cd ../doc ; tar cf - * | tar xf - -C ${PREFIX}/share/doc/ptypes/doc
uninstall:
rm -rf ${PREFIX}/include/ptypes
cd ${PREFIX}/lib ; rm -f $(LIBNAME) $(LIBNAME_ST) $(SONAME) $(SOREALNAME)
rm -rf ${PREFIX}/share/doc/ptypes
src/pasync.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <stdlib.h>
# include <unistd.h>
# include <pthread.h>
# ifdef __sun__
# include <poll.h>
# endif
#endif
#include "pasync.h"
PTYPES_BEGIN
void ptdecl psleep(uint milliseconds)
{
#if defined(WIN32)
Sleep(milliseconds);
#elif defined(__sun__)
poll(0, 0, milliseconds);
#else
usleep(milliseconds * 1000);
#endif
}
pthread_id_t ptdecl pthrself()
{
#ifdef WIN32
return (int)GetCurrentThreadId();
#else
return pthread_self();
#endif
}
bool ptdecl pthrequal(pthread_id_t id)
{
#ifdef WIN32
return GetCurrentThreadId() == (uint)id;
#else
return pthread_equal(pthread_self(), id);
#endif
}
PTYPES_END
src/patomic.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#endif
#include "ptypes.h"
#include "pasync.h" // for pmemlock*
PTYPES_BEGIN
#ifdef PTYPES_ST
// single-threaded version
int __PFASTCALL pexchange(int* target, int value)
{
int r = *target;
*target = value;
return r;
}
void* __PFASTCALL pexchange(void** target, void* value)
{
void* r = *target;
*target = value;
return r;
}
int __PFASTCALL pincrement(int* target)
{
return ++(*target);
}
int __PFASTCALL pdecrement(int* target)
{
return --(*target);
}
#else
// multi-threaded version
#if defined(__GNUC__) && (defined(__i386__) || defined(__I386__))
# define GCC_i386
#elif defined(__GNUC__) && defined(__ppc__)
# define GCC_PPC
#elif defined(_MSC_VER) && defined(_M_IX86)
# define MSC_i386
#elif defined(__BORLANDC__) && defined(_M_IX86)
# define BCC_i386
#elif defined(__GNUC__) && defined(__sparc__) && !defined(__arch64__)
# define GCC_sparc
#endif
#if defined(MSC_i386) || defined(BCC_i386)
//
// atomic operations for Microsoft C or Borland C on Windows
//
#if defined(_MSC_VER)
# pragma warning (disable: 4035)
#elif defined(__BORLANDC__)
# pragma warn -rvl
#endif
// !!! NOTE
// the following functions implement atomic exchange/inc/dec on
// windows. they are dangerous in that they rely on the calling
// conventions of MSVC and BCC. the first one passes the first
// two arguments in ECX and EDX, and the second one - in EAX and
// EDX.
int __PFASTCALL pincrement(int*)
{
__asm
{
#ifdef BCC_i386
mov ecx,eax
#endif
mov eax,1;
lock xadd [ecx],eax;
inc eax
}
}
int __PFASTCALL pdecrement(int*)
{
__asm
{
#ifdef BCC_i386
mov ecx,eax
#endif
mov eax,-1;
lock xadd [ecx],eax;
dec eax
}
}
int __PFASTCALL pexchange(int*, int)
{
__asm
{
#ifdef BCC_i386
xchg eax,edx;
lock xchg eax,[edx];
#else
mov eax,edx;
lock xchg eax,[ecx];
#endif
}
}
void* __PFASTCALL pexchange(void**, void*)
{
__asm
{
#ifdef BCC_i386
xchg eax,edx;
lock xchg eax,[edx];
#else
mov eax,edx;
lock xchg eax,[ecx];
#endif
}
}
#elif defined(GCC_i386)
//
// GNU C compiler on any i386 platform (actually 486+ for xadd)
//
int pexchange(int* target, int value)
{
__asm__ __volatile ("lock ; xchgl (%1),%0" : "+r" (value) : "r" (target));
return value;
}
void* pexchange(void** target, void* value)
{
__asm__ __volatile ("lock ; xchgl (%1),%0" : "+r" (value) : "r" (target));
return value;
}
int pincrement(int* target)
{
int temp = 1;
__asm__ __volatile ("lock ; xaddl %0,(%1)" : "+r" (temp) : "r" (target));
return temp + 1;
}
int pdecrement(int* target)
{
int temp = -1;
__asm__ __volatile ("lock ; xaddl %0,(%1)" : "+r" (temp) : "r" (target));
return temp - 1;
}
#elif defined(GCC_PPC)
//
// GNU C compiler on any PPC platform
//
int pexchange(int* target, int value)
{
int temp;
__asm__ __volatile (
"1: lwarx %0,0,%1\n\
stwcx. %2,0,%1\n\
bne- 1b\n\
isync"
: "=&r" (temp)
: "r" (target), "r" (value)
: "cc", "memory"
);
return temp;
}
void* pexchange(void** target, void* value)
{
void* temp;
__asm__ __volatile (
"1: lwarx %0,0,%1\n\
stwcx. %2,0,%1\n\
bne- 1b\n\
isync"
: "=&r" (temp)
: "r" (target), "r" (value)
: "cc", "memory"
);
return temp;
}
int pincrement(int* target)
{
int temp;
__asm__ __volatile (
"1: lwarx %0,0,%1\n\
addic %0,%0,1\n\
stwcx. %0,0,%1\n\
bne- 1b\n\
isync"
: "=&r" (temp)
: "r" (target)
: "cc", "memory"
);
return temp;
}
int pdecrement(int* target)
{
int temp;
__asm__ __volatile (
"1: lwarx %0,0,%1\n\
addic %0,%0,-1\n\
stwcx. %0,0,%1\n\
bne- 1b\n\
isync"
: "=&r" (temp)
: "r" (target)
: "cc", "memory"
);
return temp;
}
#elif defined GCC_sparc
//
// GNU C compiler on SPARC in 32-bit mode (pointers are 32-bit)
//
// assembly routines defined in patomic.sparc.s
// we currently don't use CAS in the library, but let it be there
extern "C" {
int __patomic_add(volatile int* __mem, int __val);
int __patomic_swap(volatile int* __mem, int __val);
int __patomic_cas(volatile int* __mem, int __expected, int __newval);
}
#define __patomic_swap_p(mem,val) \
(void*)(__patomic_swap((int*)(mem), (int)(val)))
int pexchange(int* target, int value)
{
return __patomic_swap(target, value);
}
void* pexchange(void** target, void* value)
{
return __patomic_swap_p(target, value);
}
int pincrement(int* target)
{
return __patomic_add(target, 1);
}
int pdecrement(int* target)
{
return __patomic_add(target, -1);
}
#else
//
// other platforms: mutex locking
//
int pexchange(int* target, int value)
{
pmemlock* m = pgetmemlock(target);
pmementer(m);
int r = *target;
*target = value;
pmemleave(m);
return r;
}
void* pexchange(void** target, void* value)
{
pmemlock* m = pgetmemlock(target);
pmementer(m);
void* r = *target;
*target = value;
pmemleave(m);
return r;
}
int pincrement(int* target)
{
pmemlock* m = pgetmemlock(target);
pmementer(m);
int r = ++(*target);
pmemleave(m);
return r;
}
int pdecrement(int* target)
{
pmemlock* m = pgetmemlock(target);
pmementer(m);
int r = --(*target);
pmemleave(m);
return r;
}
#endif
#endif
PTYPES_END
src/patomic.sparc.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.section ".text"
.align 4
.global __patomic_add
.type __patomic_add, #function
__patomic_add:
ld[%o0], %o2
1:
add%o2, %o1, %o3
cas[%o0], %o2, %o3
cmp%o2, %o3
bne,a,pn %icc, 1b
mov%o3, %o2
retl
add%o2, %o1, %o0! return new value
.size __patomic_add, .-__patomic_add
.section ".text"
.align 4
.global __patomic_swap
.type __patomic_swap, #function
__patomic_swap:
ld[%o0], %o2
1:
mov%o1, %o3
cas[%o0], %o2, %o3
cmp%o2, %o3
bne,a,pn %icc, 1b
mov%o3, %o2
retl
mov%o3, %o0
.size __patomic_swap, .-__patomic_swap
.section ".text"
.align 4
.global __patomic_cas
.type __patomic_cas, #function
__patomic_cas:
cas [%o0], %o1, %o2
retl
mov %o2, %o0
.size __patomic_cas, .-__patomic_cas
src/pcomponent.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
component::component()
: unknown(), refcount(0), freelist(nil), typeinfo(nil) {}
component::~component()
{
if (freelist != nil)
{
for (int i = 0; i < freelist->get_count(); i++)
(*freelist)[i]->freenotify(this);
delete freelist;
freelist = nil;
}
}
void component::freenotify(component*)
{
}
void component::addnotification(component* obj)
{
if (freelist == nil)
freelist = new tobjlist<component>(false);
freelist->add(obj);
}
void component::delnotification(component* obj)
{
int i = -1;
if (freelist != nil)
{
i = freelist->indexof(obj);
if (i >= 0) {
freelist->del(i);
if (freelist->get_count() == 0)
{
delete freelist;
freelist = nil;
}
}
}
if (i == -1)
fatal(CRIT_FIRST + 1, "delnotification() failed: no such object");
}
int component::classid()
{
return CLASS_UNDEFINED;
}
component* ptdecl addref(component* c)
{
if (c != nil)
#ifdef PTYPES_ST
c->refcount++;
#else
pincrement(&c->refcount);
#endif
return c;
}
bool ptdecl release(component* c)
{
if (c != nil)
{
#ifdef PTYPES_ST
if (--c->refcount == 0)
#else
if (pdecrement(&c->refcount) == 0)
#endif
delete c;
else
return false;
}
return true;
}
PTYPES_END
src/pcset.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
typedef int* pint;
static uchar lbitmask[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
static uchar rbitmask[8] = {0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
void cset::include(char min, char max)
{
if (uchar(min) > uchar(max))
return;
int lidx = uchar(min) / 8;
int ridx = uchar(max) / 8;
uchar lbits = lbitmask[uchar(min) % 8];
uchar rbits = rbitmask[uchar(max) % 8];
if (lidx == ridx)
{
data[lidx] |= lbits & rbits;
}
else
{
data[lidx] |= lbits;
for (int i = lidx + 1; i < ridx; i++)
data[i] = -1;
data[ridx] |= rbits;
}
}
char hex4(char c)
{
if (c >= 'a')
return uchar(c - 'a' + 10);
else if (c >= 'A')
return uchar(c - 'A' + 10);
else
return char(c - '0');
}
static uchar parsechar(const char*& p)
{
uchar ret = *p;
if (ret == _csetesc) {
p++;
ret = *p;
if ((ret >= '0' && ret <= '9') || (ret >= 'a' && ret <= 'f') || (ret >= 'A' && ret <= 'F')) {
ret = hex4(ret);
p++;
if (*p != 0)
ret = uchar((ret << 4) | hex4(*p));
}
}
return ret;
}
void cset::assign(const char* p)
{
if (*p == '*' && *(p + 1) == 0)
fill();
else
{
clear();
for (; *p != 0; p++) {
uchar left = parsechar(p);
if (*(p + 1) == '-') {
p += 2;
uchar right = parsechar(p);
include(left, right);
}
else
include(left);
}
}
}
void cset::unite(const cset& s)
{
for(int i = 0; i < _csetwords; i++)
*(pint(data) + i) |= *(pint(s.data) + i);
}
void cset::subtract(const cset& s)
{
for(int i = 0; i < _csetwords; i++)
*(pint(data) + i) &= ~(*(pint(s.data) + i));
}
void cset::intersect(const cset& s)
{
for(int i = 0; i < _csetwords; i++)
*(pint(data) + i) &= *(pint(s.data) + i);
}
void cset::invert()
{
for(int i = 0; i < _csetwords; i++)
*(pint(data) + i) = ~(*(pint(data) + i));
}
bool cset::le(const cset& s) const
{
for (int i = 0; i < _csetwords; i++)
{
int w1 = *(pint(data) + i);
int w2 = *(pint(s.data) + i);
if ((w2 | w1) != w2)
return false;
}
return true;
}
PTYPES_END
src/pcsetdbg.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
static char hexchar(uchar c)
{
if (c < 10)
return char(c + '0');
else
return char(c - 10 + 'a');
}
inline bool isprintable(uchar c)
{
return ((c >= ' ') && (c < 127));
}
static string showmember(uchar c)
{
if ((c == '-') || (c == '~'))
return string('~') + string(c);
else if (isprintable(c))
return c;
else
{
string ret = "~ ";
ret[1] = hexchar(uchar(c >> 4));
ret[2] = hexchar(uchar(c & 0x0f));
return ret;
}
}
string ptdecl asstring(const cset& s)
{
string ret;
int l = -1, r = -1;
for(int i = 0; i <= _csetbits; i++)
{
if (i < _csetbits && uchar(i) & s)
{
if (l == -1)
l = i;
else
r = i;
}
else if (l != -1)
{
concat(ret, showmember(uchar(l)));
if (r != -1) {
if (r > l + 1)
concat(ret, '-');
concat(ret, showmember(uchar(r)));
}
l = -1;
r = -1;
}
}
return ret;
}
PTYPES_END
src/pexcept.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
exception::exception(const char* imsg)
: message(imsg)
{
}
exception::exception(const string& imsg)
: message(imsg)
{
}
exception::~exception()
{
}
PTYPES_END
src/pfatal.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pport.h"
#if defined(WIN32) && !defined(NO_CRIT_MSGBOX)
# include <windows.h>
# define CRIT_MSGBOX
#endif
PTYPES_BEGIN
static void ptdecl defhandler(int code, const char* msg)
{
#ifdef CRIT_MSGBOX
char buf[2048];
_snprintf(buf, sizeof(buf) - 1, "Fatal [%05x]: %s", code, msg);
MessageBox(0, buf, "Internal error", MB_OK | MB_ICONSTOP);
#else
fprintf(stderr, "\nInternal [%04x]: %s\n", code, msg);
#endif
}
static _pcrithandler crith = defhandler;
_pcrithandler ptdecl getcrithandler()
{
return crith;
}
_pcrithandler ptdecl setcrithandler(_pcrithandler newh)
{
_pcrithandler ret = crith;
crith = newh;
return ret;
}
void ptdecl fatal(int code, const char* msg)
{
if (crith != nil)
(*crith)(code, msg);
exit(code);
}
PTYPES_END
src/pfdxstm.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
#ifdef _MSC_VER
// disable "'this' : used in base member initializer list" warning
# pragma warning (disable: 4355)
#endif
fdxoutstm::fdxoutstm(int ibufsize, fdxstm* iin)
: outstm(false, ibufsize), in(iin) {}
fdxoutstm::~fdxoutstm() {}
void fdxoutstm::chstat(int newstat)
{
outstm::chstat(newstat);
if (newstat == IO_WRITING)
in->chstat(newstat);
}
int fdxoutstm::uerrno()
{
return in->uerrno();
}
const char* fdxoutstm::uerrmsg(int code)
{
return in->uerrmsg(code);
}
string fdxoutstm::get_streamname()
{
return in->get_streamname();
}
void fdxoutstm::doopen()
{
}
void fdxoutstm::doclose()
{
if (in->active)
in->close();
}
int fdxoutstm::dorawwrite(const char* buf, int count)
{
return in->dorawwrite(buf, count);
}
fdxstm::fdxstm(int ibufsize)
: instm(ibufsize), out(ibufsize, this)
{
out.in = this;
addref(&out);
}
fdxstm::~fdxstm() {}
int fdxstm::classid()
{
return CLASS2_FDX;
}
void fdxstm::flush()
{
if (out.active)
out.flush();
}
int fdxstm::dorawwrite(const char* buf, int count)
{
if (handle == invhandle)
return -1;
#ifdef WIN32
unsigned long ret;
if (!WriteFile(HANDLE(handle), buf, count, &ret, nil))
{
error(uerrno(), "Couldn't write");
ret = uint(-1);
}
#else
int ret;
if ((ret = ::write(handle, buf, count)) < 0)
error(uerrno(), "Couldn't write");
#endif
return ret;
}
void fdxstm::set_bufsize(int newval)
{
instm::set_bufsize(newval);
out.set_bufsize(newval);
}
void fdxstm::open()
{
instm::open();
out.open();
}
void fdxstm::close()
{
instm::close();
out.close();
}
void fdxstm::cancel()
{
instm::cancel();
out.cancel();
}
large fdxstm::tellx(bool forin)
{
if (forin)
return instm::tellx();
else
return out.tellx();
}
PTYPES_END
src/pinfile.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <fcntl.h>
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
// *BSD hack
#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
infile::infile()
: instm(), filename(), syshandle(invhandle), peerhandle(invhandle) {}
infile::infile(const char* ifn)
: instm(), filename(ifn), syshandle(invhandle), peerhandle(invhandle) {}
infile::infile(const string& ifn)
: instm(), filename(ifn), syshandle(invhandle), peerhandle(invhandle) {}
infile::~infile()
{
close();
}
int infile::classid()
{
return CLASS2_INFILE;
}
string infile::get_streamname()
{
return filename;
}
void infile::doopen()
{
if (syshandle != invhandle)
handle = syshandle;
else
{
#ifdef WIN32
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
handle = int(CreateFile(filename, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0));
#else
handle = ::open(filename, O_RDONLY | O_LARGEFILE);
#endif
if (handle == invhandle)
error(uerrno(), "Couldn't open");
}
}
void infile::doclose()
{
instm::doclose();
syshandle = invhandle;
peerhandle = invhandle;
}
PTYPES_END
src/pinfilter.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#include "pstreams.h"
PTYPES_BEGIN
string infilter::get_errstmname()
{
if (stm == nil)
return get_streamname();
else
return get_streamname() + ": " + stm->get_errstmname();
}
void infilter::copytobuf(string& s)
{
int n = imin(savecount, length(s));
if (n > 0)
{
memcpy(savebuf, pconst(s), n);
savebuf += n;
savecount -= n;
if (n == savecount)
clear(s);
else
del(s, 0, n);
}
}
void infilter::copytobuf(pconst& buf, int& count)
{
int n = imin(savecount, count);
if (n > 0)
{
memcpy(savebuf, buf, n);
savebuf += n;
savecount -= n;
buf += n;
count -= n;
}
}
bool infilter::copytobuf(char c)
{
if (savecount > 0) {
*savebuf = c;
savebuf++;
savecount--;
return true;
}
else
return false;
}
infilter::infilter(instm* istm, int ibufsize)
: instm(ibufsize), stm(istm), savebuf(nil), savecount(0)
{
if (stm != nil)
stm->addnotification(this);
}
infilter::~infilter()
{
if (stm != nil)
stm->delnotification(this);
}
void infilter::freenotify(component* sender)
{
if (sender == stm)
{
stm = nil;
close();
}
}
void infilter::doopen()
{
if (stm != nil && !stm->get_active())
stm->open();
}
void infilter::doclose()
{
savebuf = nil;
savecount = 0;
clear(postponed);
}
void infilter::set_stm(instm* istm)
{
close();
if (stm != nil)
stm->delnotification(this);
stm = istm;
if (stm != nil)
stm->addnotification(this);
}
int infilter::dorawread(char* buf, int count)
{
savebuf = buf;
savecount = count;
if (!isempty(postponed))
copytobuf(postponed);
if (savecount > 0 && stm != nil)
dofilter();
return count - savecount;
}
void infilter::post(const char* buf, int count)
{
if (count > 0)
{
copytobuf(buf, count);
if (count > 0)
concat(postponed, buf, count);
}
}
void infilter::post(string s)
{
if (!isempty(s))
{
copytobuf(s);
if (!isempty(s))
concat(postponed, s);
}
}
void infilter::post(const char* s)
{
post(s, strlen(s));
}
void infilter::post(char c)
{
if (!copytobuf(c))
concat(postponed, c);
}
PTYPES_END
src/pinmem.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pstreams.h"
PTYPES_BEGIN
inmemory::inmemory(const string& imem)
: instm(length(imem)), mem(imem)
{
}
inmemory::~inmemory()
{
close();
}
int inmemory::classid()
{
return CLASS2_INMEMORY;
}
void inmemory::bufalloc()
{
bufdata = pchar(pconst(mem));
abspos = bufsize = bufend = length(mem);
}
void inmemory::buffree()
{
bufclear();
bufdata = nil;
}
void inmemory::bufvalidate()
{
eof = bufpos >= bufend;
}
void inmemory::doopen()
{
}
void inmemory::doclose()
{
}
large inmemory::doseek(large, ioseekmode)
{
// normally shouldn't reach this point, because seek is
// supposed to happen within the I/O buffer
return -1;
}
int inmemory::dorawread(char*, int)
{
return 0;
}
string inmemory::get_streamname()
{
return "mem";
}
large inmemory::seekx(large newpos, ioseekmode mode)
{
if (mode == IO_END)
{
newpos += bufsize;
mode = IO_BEGIN;
}
return instm::seekx(newpos, mode);
}
void inmemory::set_strdata(const string& data)
{
close();
mem = data;
}
PTYPES_END
src/pinstm.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <errno.h>
#include <string.h>
#include <limits.h>
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
instm::instm(int ibufsize): iobase(ibufsize)
{
}
instm::~instm()
{
}
int instm::classid()
{
return CLASS_INSTM;
}
int instm::dorawread(char* buf, int count)
{
if (handle == invhandle)
return -1;
#ifdef WIN32
unsigned long ret;
if (!ReadFile(HANDLE(handle), buf, count, &ret, nil))
#else
int ret;
if ((ret = ::read(handle, buf, count)) < 0)
#endif
{
int e = uerrno();
if (e == EPIPE)
ret = 0;
else
error(e, "Couldn't read");
}
return ret;
}
int instm::rawread(char* buf, int count)
{
requireactive();
try
{
int ret = dorawread(buf, count);
if (ret <= 0) {
ret = 0;
eof = true;
chstat(IO_EOF);
}
else
{
abspos += ret;
chstat(IO_READING);
}
return ret;
}
catch (estream*)
{
eof = true;
chstat(IO_EOF);
throw;
}
}
large instm::tellx()
{
return abspos - bufend + bufpos;
}
void instm::bufvalidate()
{
requirebuf();
bufclear();
bufend = rawread(bufdata, bufsize);
}
large instm::seekx(large newpos, ioseekmode mode)
{
if (bufdata != 0 && mode != IO_END)
{
if (mode == IO_CURRENT)
{
newpos += tellx();
mode = IO_BEGIN;
}
// see if it is possible to seek within the buffer
large newbufpos = newpos - (abspos - bufend);
if (newbufpos >= 0 && newbufpos <= bufend)
{
bufpos = (int)newbufpos;
eof = false;
return tellx();
}
}
// if IO_END or if not possible to seek within the buffer
return iobase::seekx(newpos, mode);
}
bool instm::get_eof()
{
if (!eof && bufdata != 0 && bufpos >= bufend)
bufvalidate();
return eof;
}
int instm::get_dataavail()
{
get_eof();
return bufend - bufpos;
}
char instm::preview()
{
if (!eof && bufpos >= bufend)
bufvalidate();
if (eof)
return eofchar;
return bufdata[bufpos];
}
void instm::putback()
{
requireactive();
if (bufpos == 0)
fatal(CRIT_FIRST + 14, "putback() failed");
bufpos--;
eof = false;
}
bool instm::get_eol()
{
char c = preview();
return (eof || c == 10 || c == 13);
}
void instm::skipeol()
{
switch (preview())
{
case 10:
get();
break;
case 13:
get();
if (preview() == 10)
get();
break;
}
}
char instm::get()
{
char ret = preview();
if (!eof)
bufpos++;
return ret;
}
string instm::token(const cset& chars, int limit)
{
requirebuf();
string ret;
while (!get_eof())
{
char* b = bufdata + bufpos;
char* e = bufdata + bufend;
char* p = b;
while (p < e && (*p & chars))
p++;
int n = p - b;
limit -= n;
if (limit < 0)
{
bufpos += n + limit;
error(ERANGE, "Token too long");
}
concat(ret, b, n);
bufpos += n;
if (p < e)
break;
}
return ret;
}
string instm::token(const cset& chars)
{
return token(chars, INT_MAX);
}
static cset linechars = cset("*") - cset("~0a~0d");
string instm::line(int limit)
{
string ret = token(linechars, limit);
skipeol();
return ret;
}
string instm::line()
{
string ret = token(linechars, INT_MAX);
skipeol();
return ret;
}
int instm::token(const cset& chars, char* buf, int count)
{
requirebuf();
int ret = 0;
while (count > 0 && !get_eof())
{
char* b = bufdata + bufpos;
char* e = b + imin(count, bufend - bufpos);
char* p = b;
while (p < e && (*p & chars))
p++;
int n = p - b;
memcpy(buf, b, n);
buf += n;
ret += n;
count -= n;
bufpos += n;
if (p < e)
break;
}
return ret;
}
int instm::line(char* buf, int size, bool eateol)
{
int ret = token(linechars, buf, size);
if (eateol)
skipeol();
return ret;
}
int instm::read(void* buf, int count)
{
int ret = 0;
if (bufdata == 0)
ret = rawread(pchar(buf), count);
else
{
while (count > 0 && !get_eof())
{
int n = imin(count, bufend - bufpos);
memcpy(buf, bufdata + bufpos, n);
buf = pchar(buf) + n;
ret += n;
count -= n;
bufpos += n;
}
}
return ret;
}
int instm::skip(int count)
{
int ret = 0;
requirebuf();
while (count > 0 && !get_eof())
{
int n = imin(count, bufend - bufpos);
ret += n;
count -= n;
bufpos += n;
}
return ret;
}
int instm::skiptoken(const cset& chars)
{
int ret = 0;
requirebuf();
while (!get_eof())
{
char* b = bufdata + bufpos;
char* e = bufdata + bufend;
char* p = b;
while (p < e && (*p & chars))
p++;
int n = p - b;
bufpos += n;
ret += n;
if (p < e)
break;
}
return ret;
}
void instm::skipline(bool eateol)
{
if (!get_eol())
skiptoken(linechars);
if (eateol)
skipeol();
}
PTYPES_END
src/pintee.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pstreams.h"
PTYPES_BEGIN
intee::intee(instm* istm, const char* ifn, bool iappend)
: infilter(istm, -1), file(ifn, iappend)
{
}
intee::intee(instm* istm, const string& ifn, bool iappend)
: infilter(istm, -1), file(ifn, iappend)
{
}
intee::~intee()
{
close();
}
void intee::doopen()
{
infilter::doopen();
file.open();
}
void intee::doclose()
{
file.close();
infilter::doclose();
}
void intee::dofilter()
{
int count = stm->read(savebuf, savecount);
if (count > 0)
{
file.write(savebuf, count);
savebuf += count;
savecount -= count;
}
}
string intee::get_streamname()
{
return "tee: " + file.get_filename();
}
PTYPES_END
src/piobase.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <errno.h>
#include <limits.h>
#ifdef WIN32
# include <windows.h>
#else
# include <signal.h>
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
/*
Known UNIX error codes:
EPERM 1 Not owner
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 I/O error
ENXIO 6 No such device or address
E2BIG 7 Argument list too long
ENOEXEC 8 Exec format error
EBADF 9 Bad file number
ECHILD 10 No spawned processes
EAGAIN 11 No more processes; not enough memory; maximum nesting level reached
ENOMEM 12 Not enough memory
EACCES 13 Permission denied
EFAULT 14 Bad address
ENOTBLK 15 Block device required
EBUSY 16 Mount device busy
EEXIST 17 File exists
EXDEV 18 Cross-device link
ENODEV 19 No such device
ENOTDIR 20 Not a directory
EISDIR 21 Is a directory
EINVAL 22 Invalid argument
ENFILE 23 File table overflow
EMFILE 24 Too many open files
ENOTTY 25 Not a teletype
ETXTBSY 26 Text file busy
EFBIG 27 File too large
ENOSPC 28 No space left on device
ESPIPE 29 Illegal seek
EROFS 30 Read-only file system
EMLINK 31 Too many links
EPIPE 32 Broken pipe
EDOM 33 Math argument
ERANGE 34 Result too large
EUCLEAN 35 File system needs cleaning
EDEADLK 36 Resource deadlock would occur
EDEADLOCK 36 Resource deadlock would occur
*/
#ifndef WIN32
static class _io_init
{
public:
_io_init();
} _io_init_inst;
_io_init::_io_init()
{
// We don't like broken pipes. PTypes will throw an exception instead.
signal(SIGPIPE, SIG_IGN);
}
#endif
int ptdecl unixerrno()
{
#ifdef WIN32
switch(GetLastError())
{
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND: return ENOENT;
case ERROR_TOO_MANY_OPEN_FILES: return EMFILE;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION: return EACCES;
case ERROR_INVALID_HANDLE: return EBADF;
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_OUTOFMEMORY: return ENOMEM;
case ERROR_INVALID_DRIVE: return ENODEV;
case ERROR_WRITE_PROTECT: return EROFS;
case ERROR_FILE_EXISTS: return EEXIST;
case ERROR_BROKEN_PIPE: return EPIPE;
case ERROR_DISK_FULL: return ENOSPC;
case ERROR_SEEK_ON_DEVICE: return ESPIPE;
default: return EIO;
}
#else
return errno;
#endif
}
//
// This function gives error messages for most frequently occurring
// IO errors. If the function returns NULL a generic message
// can be given, e.g. "I/O error". See also iobase::get_errormsg()
//
const char* ptdecl unixerrmsg(int code)
{
switch(code)
{
case EBADF: return "Invalid file descriptor";
case ESPIPE: return "Can not seek on this device";
case ENOENT: return "No such file or directory";
case EMFILE: return "Too many open files";
case EACCES: return "Access denied";
case ENOMEM: return "Not enough memory";
case ENODEV: return "No such device";
case EROFS: return "Read-only file system";
case EEXIST: return "File already exists";
case ENOSPC: return "Disk full";
case EPIPE: return "Broken pipe";
case EFBIG: return "File too large";
default: return nil;
}
}
estream::estream(iobase* ierrstm, int icode, const char* imsg)
: exception(imsg), code(icode), errstm(ierrstm) {}
estream::estream(iobase* ierrstm, int icode, const string& imsg)
: exception(imsg), code(icode), errstm(ierrstm) {}
estream::~estream() {}
int defbufsize = 8192;
int stmbalance = 0;
iobase::iobase(int ibufsize)
: component(), active(false), cancelled(false), eof(true),
handle(invhandle), abspos(0), bufsize(0), bufdata(nil), bufpos(0), bufend(0),
stmerrno(0), deferrormsg(), status(IO_CREATED), onstatus(nil)
{
if (ibufsize < 0)
bufsize = defbufsize;
else
bufsize = ibufsize;
}
iobase::~iobase()
{
}
void iobase::bufalloc()
{
if (bufdata != nil)
fatal(CRIT_FIRST + 13, "(ptypes internal) invalid buffer allocation");
bufdata = (char*)memalloc(bufsize);
}
void iobase::buffree()
{
bufclear();
memfree(bufdata);
bufdata = 0;
}
void iobase::chstat(int newstat)
{
status = newstat;
if (onstatus != nil)
(*onstatus)(this, newstat);
}
void iobase::errstminactive()
{
error(EIO, "Stream inactive");
}
void iobase::errbufrequired()
{
fatal(CRIT_FIRST + 11, "Internal: buffer required");
}
int iobase::convertoffset(large offs)
{
if (offs < 0 || offs > INT_MAX)
error(EFBIG, "File offset value too large");
return (int)offs;
}
void iobase::open()
{
cancel();
chstat(IO_OPENING);
abspos = 0;
cancelled = false;
eof = false;
stmerrno = 0;
clear(deferrormsg);
active = true;
stmbalance++;
bufalloc();
doopen();
chstat(IO_OPENED);
}
void iobase::close()
{
if (!active)
return;
stmbalance--;
try
{
if (bufdata != 0 && !cancelled)
flush();
doclose();
}
catch(estream* e)
{
delete e;
}
buffree();
active = false;
eof = true;
chstat(IO_CLOSED);
}
void iobase::cancel()
{
cancelled = true;
close();
}
large iobase::seekx(large newpos, ioseekmode mode)
{
if (!active)
errstminactive();
flush();
large ret = doseek(newpos, mode);
if (ret < 0)
error(ESPIPE, "Seek failed");
bufclear();
eof = false;
abspos = ret;
return ret;
}
void iobase::flush()
{
}
large iobase::doseek(large newpos, ioseekmode mode)
{
if (handle == invhandle)
{
error(ESPIPE, "Can't seek on this device");
return -1;
}
#ifdef WIN32
static int wmode[3] = {FILE_BEGIN, FILE_CURRENT, FILE_END};
LARGE_INTEGER li;
li.QuadPart = newpos;
li.LowPart = SetFilePointer(HANDLE(handle), li.LowPart, &li.HighPart, wmode[mode]);
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
return -1;
return li.QuadPart;
#else
static int umode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
return lseek(handle, newpos, umode[mode]);
#endif
}
void iobase::doclose()
{
#ifdef WIN32
CloseHandle(HANDLE(pexchange(&handle, invhandle)));
#else
::close(pexchange(&handle, invhandle));
#endif
}
void iobase::set_active(bool newval)
{
if (newval != active)
if (newval)
open();
else
close();
}
void iobase::set_bufsize(int newval)
{
if (active)
fatal(CRIT_FIRST + 12, "Cannot change buffer size while stream is active");
if (newval < 0)
bufsize = defbufsize;
else
bufsize = newval;
}
string iobase::get_errstmname()
{
return get_streamname();
}
const char* iobase::uerrmsg(int code)
{
return unixerrmsg(code);
}
int iobase::uerrno()
{
return unixerrno();
}
string iobase::get_errormsg()
{
string s = uerrmsg(stmerrno);
if (isempty(s))
s = deferrormsg;
if (pos('[', s) >= 0 && *(pconst(s) + length(s) - 1) == ']')
return s;
string e = get_errstmname();
if (isempty(e))
return s;
return s + " [" + e + ']';
}
#ifdef _MSC_VER
// disable "unreachable code" warning for throw (known compiler bug)
# pragma warning (disable: 4702)
#endif
void iobase::error(int code, const char* defmsg)
{
eof = true;
stmerrno = code;
deferrormsg = defmsg;
throw new estream(this, code, get_errormsg());
}
PTYPES_END
src/pipbase.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <signal.h>
# include <time.h>
#endif
#include <stdio.h> // for snprintf
#include "pinet.h"
#ifndef PTYPES_ST
# include "pasync.h" // for mutex
#endif
PTYPES_BEGIN
//
// reentrant gehostby*() mess
//
#if defined(PTYPES_ST)
# define USE_GETHOSTBY
#else
# if defined(WIN32) || defined(__hpux)
# define USE_GETHOSTBY
# elif defined(__FreeBSD__) || defined(__DARWIN__)
# define USE_GETIPNODEBY
# elif defined(linux)
# define USE_GETHOSTBY_R6
# elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
# define USE_LOCKED_GETHOSTBY
# else // hopefully the Sun-style call will work on all other systems as well
# define USE_GETHOSTBY_R5
# endif
#endif
#define GETHOSTBY_BUF_SIZE 4096
//
// sockets init/startup
//
// usockerrno() is used in all socket classes anyway, so this module
// along with the initialization code below will always be linked to
// a networking program
#ifdef WIN32
static class _sock_init
{
public:
_sock_init();
~_sock_init();
} _init;
_sock_init::_sock_init()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup(wVersionRequested, &wsaData);
if ( err != 0 )
fatal(CRIT_FIRST + 50, "WinSock initialization failure");
if ( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0 )
fatal(CRIT_FIRST + 51, "WinSock version mismatch (2.0 or compatible required)");
}
_sock_init::~_sock_init()
{
WSACleanup();
}
#endif
//
// internet address
//
ipaddress ipnone = uint(0xffffffff);
ipaddress ipany = INADDR_ANY;
ipaddress ipbcast = INADDR_BROADCAST;
ipaddress::ipaddress(int a, int b, int c, int d)
{
data[0] = uchar(a);
data[1] = uchar(b);
data[2] = uchar(c);
data[3] = uchar(d);
}
//
// peer info
//
ippeerinfo::ippeerinfo()
: ip(ipnone), host(), port(0)
{
}
ippeerinfo::ippeerinfo(ipaddress iip, const string& ihost, int iport)
: ip(iip), host(ihost), port(iport)
{
}
ipaddress ippeerinfo::get_ip()
{
if (ip == ipnone && !isempty(host))
{
ip = ulong(phostbyname(host));
if (ip == ipnone)
notfound();
}
return ip;
}
string ippeerinfo::get_host()
{
if (!isempty(host))
return host;
if (ip == ipnone || ip == ipany || ip == ipbcast)
return nullstring;
host = phostbyaddr(ip);
if (isempty(host))
notfound();
return host;
}
void ippeerinfo::clear()
{
ip = ipnone;
PTYPES_NAMESPACE::clear(host);
port = 0;
}
string ippeerinfo::asstring(bool showport) const
{
string t;
if (!isempty(host))
t = host;
else if (ip == ipany)
t = '*';
else if (ip == ipnone)
t = '-';
else
t = iptostring(ip);
if (showport && port != 0)
t += ':' + itostring(port);
return t;
}
//
// internet utilities
//
int ptdecl usockerrno()
{
#ifdef WIN32
return WSAGetLastError();
#else
return errno;
#endif
}
const char* ptdecl usockerrmsg(int code)
{
switch(code)
{
// only minimal set of most frequent/expressive errors; others go as "I/O error"
case ENOTSOCK: return "Invalid socket descriptor";
case EMSGSIZE: return "Message too long";
case ENOPROTOOPT:
case EPROTONOSUPPORT:
// case EPFNOSUPPORT:
case EAFNOSUPPORT: return "Protocol or address family not supported";
case EADDRINUSE: return "Address already in use";
case EADDRNOTAVAIL: return "Address not available";
case ENETDOWN: return "Network is down";
case ENETUNREACH: return "Network is unreachable";
case ECONNRESET: return "Connection reset by peer";
case ETIMEDOUT: return "Operation timed out";
case ECONNREFUSED: return "Connection refused";
// case EHOSTDOWN: return "Host is down";
case EHOSTUNREACH: return "No route to host";
// we always translate h_errno to ENOENT and simply show "host not found"
case ENOENT: return "Host not found";
default: return unixerrmsg(code);
}
}
string ptdecl iptostring(ipaddress ip)
{
char buf[16];
snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
uint(ip[0]), uint(ip[1]), uint(ip[2]), uint(ip[3]));
return string(buf);
}
#if defined(USE_LOCKED_GETHOSTBY)
static mutex hplock;
#endif
ipaddress ptdecl phostbyname(const char* name)
{
ipaddress ip;
hostent* hp;
if ((ip = ::inet_addr(name)) != ipnone)
{
if (ip[3] == 0) // network address?
return ipnone;
}
else
{
#if defined(USE_GETHOSTBY)
if ((hp = ::gethostbyname(name)) != nil)
#elif defined(USE_LOCKED_GETHOSTBY)
hplock.enter();
if ((hp = ::gethostbyname(name)) != nil)
#elif defined(USE_GETIPNODEBY)
int herrno;
if ((hp = ::getipnodebyname(name, AF_INET, 0, &herrno)) != nil)
#elif defined(USE_GETHOSTBY_R6)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((::gethostbyname_r(name, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)
#elif defined(USE_GETHOSTBY_R5)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((hp = ::gethostbyname_r(name, &result, buf, sizeof(buf), &herrno)) != nil)
#endif
{
if (hp->h_addrtype == AF_INET)
memcpy(ip.data, hp->h_addr, sizeof(ip.data));
#ifdef USE_GETIPNODEBY
freehostent(hp);
#endif
}
#if defined(USE_LOCKED_GETHOSTBY)
hplock.leave();
#endif
}
return ip;
}
string ptdecl phostbyaddr(ipaddress ip)
{
hostent* hp;
string r;
#if defined(USE_GETHOSTBY)
if ((hp = ::gethostbyaddr(pconst(ip.data), sizeof(ip.data), AF_INET)) != nil)
#elif defined(USE_LOCKED_GETHOSTBY)
hplock.enter();
if ((hp = ::gethostbyaddr(pconst(ip.data), sizeof(ip.data), AF_INET)) != nil)
#elif defined(USE_GETIPNODEBY)
int herrno;
if ((hp = ::getipnodebyaddr(pconst(ip.data), sizeof(ip.data), AF_INET, &herrno)) != nil)
#elif defined(USE_GETHOSTBY_R6)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((::gethostbyaddr_r(pconst(ip.data), sizeof(ip.data), AF_INET, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)
#elif defined(USE_GETHOSTBY_R5)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((hp = ::gethostbyaddr_r(pconst(ip.data), sizeof(ip.data), AF_INET, &result, buf, sizeof(buf), &herrno)) != nil)
#endif
{
r = hp->h_name;
#ifdef USE_GETIPNODEBY
freehostent(hp);
#endif
}
#if defined(USE_LOCKED_GETHOSTBY)
hplock.leave();
#endif
return r;
}
string ptdecl phostcname(const char* name)
{
hostent* hp;
string r;
#if defined(USE_GETHOSTBY)
if ((hp = ::gethostbyname(name)) != nil)
#elif defined(USE_LOCKED_GETHOSTBY)
hplock.enter();
if ((hp = ::gethostbyname(name)) != nil)
#elif defined(USE_GETIPNODEBY)
int herrno;
if ((hp = ::getipnodebyname(name, AF_INET, 0, &herrno)) != nil)
#elif defined(USE_GETHOSTBY_R6)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((::gethostbyname_r(name, &result, buf, sizeof(buf), &hp, &herrno) == 0) && hp)
#elif defined(USE_GETHOSTBY_R5)
int herrno;
hostent result;
char buf[GETHOSTBY_BUF_SIZE];
if ((hp = ::gethostbyname_r(name, &result, buf, sizeof(buf), &herrno)) != nil)
#endif
{
r = hp->h_name;
#ifdef USE_GETIPNODEBY
freehostent(hp);
#endif
}
#if defined(USE_LOCKED_GETHOSTBY)
hplock.leave();
#endif
return r;
}
bool ptdecl psockwait(int handle, int timeout)
{
#ifdef _MSC_VER
// disable "condition always true" warning caused by Microsoft's FD_SET macro
# pragma warning (disable: 4127)
#endif
if (handle < 0)
return false;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET((uint)handle, &readfds);
timeval t;
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
return ::select(FD_SETSIZE, &readfds, nil, nil, (timeout < 0) ? nil : &t) > 0;
}
bool ptdecl psockname(int handle, ippeerinfo& p)
{
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
psocklen addrlen = sizeof(sa);
if (getsockname(handle, (sockaddr*)&sa, &addrlen) != 0)
return false;
if (sa.sin_family != AF_INET)
return false;
p.ip = sa.sin_addr.s_addr;
p.port = ntohs(sa.sin_port);
return true;
}
#ifdef _MSC_VER
// disable "unreachable code" warning for throw (known compiler bug)
# pragma warning (disable: 4702)
#endif
void ippeerinfo::notfound()
{
string t = usockerrmsg(ENOENT);
throw new estream(nil, ENOENT, t + " [" + asstring(false) + ']');
}
PTYPES_END
src/pipmsg.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <time.h>
#endif
#include "pinet.h"
PTYPES_BEGIN
//
// ipmessage: IPv4 UDP message class
//
ipmessage::ipmessage()
: unknown(), ippeerinfo(ipnone, nullstring, 0), handle(invhandle) {}
ipmessage::ipmessage(ipaddress iip, int iport)
: unknown(), ippeerinfo(iip, nullstring, iport), handle(invhandle) {}
ipmessage::ipmessage(const char* ihost, int iport)
: unknown(), ippeerinfo(ipnone, ihost, iport), handle(invhandle) {}
ipmessage::ipmessage(const string& ihost, int iport)
: unknown(), ippeerinfo(ipnone, ihost, iport), handle(invhandle) {}
ipmessage::~ipmessage()
{
close();
}
void ipmessage::set_ip(ipaddress iip)
{
ip = iip;
PTYPES_NAMESPACE::clear(host);
}
void ipmessage::set_host(const string& ihost)
{
host = ihost;
ip = 0;
}
void ipmessage::set_host(const char* ihost)
{
host = ihost;
ip = 0;
}
void ipmessage::set_port(int iport)
{
port = iport;
}
ipaddress ipmessage::get_myip()
{
ippeerinfo p;
if (!psockname(handle, p))
error(usockerrno(), "Couldn't get my IP");
return p.get_ip();
}
int ipmessage::get_myport()
{
ippeerinfo p;
if (!psockname(handle, p))
error(usockerrno(), "Couldn't get my port number");
return p.get_port();
}
void ipmessage::close()
{
if (handle != invhandle)
::closesocket(pexchange(&handle, invhandle));
}
void ipmessage::open()
{
close();
if ((handle = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0)
error(usockerrno(), "Couldn't create socket");
// allow broadcasts
int one = 1;
if (::setsockopt(handle, SOL_SOCKET, SO_BROADCAST, (sockval_t)&one, sizeof(one)) != 0)
error(usockerrno(), "Couldn't enable broadcasts");
sockopt(handle);
}
void ipmessage::sockopt(int)
{
}
bool ipmessage::waitfor(int timeout)
{
return psockwait(handle, timeout);
}
void ipmessage::send(const char* buf, int count)
{
if (handle == invhandle)
open();
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(ushort(get_port()));
sa.sin_addr.s_addr = get_ip();
if (sendto(handle, buf, count, 0, (sockaddr*)&sa, sizeof(sa)) < 0)
error(usockerrno(), "Couldn't write");
}
int ipmessage::receive(char* buf, int count, ipaddress& src)
{
if (handle == invhandle)
error(EINVAL, "Couldn't read"); // must send() first
sockaddr_in sa;
psocklen fromlen = sizeof(sa);
int result = ::recvfrom(handle, buf, count, 0, (sockaddr*)&sa, &fromlen);
if (result < 0)
error(usockerrno(), "Couldn't read");
src = sa.sin_addr.s_addr;
return result;
}
int ipmessage::receive(char* buf, int count)
{
ipaddress src;
return receive(buf, count, src);
}
string ipmessage::receive(int max, ipaddress& src)
{
string result;
setlength(result, max);
int numread = receive(pchar(pconst(result)), max, src);
setlength(result, numread);
return result;
}
string ipmessage::receive(int max)
{
ipaddress src;
return receive(max, src);
}
#ifdef _MSC_VER
// disable "unreachable code" warning for throw (known compiler bug)
# pragma warning (disable: 4702)
#endif
void ipmessage::error(int code, const char* msg)
{
string s = usockerrmsg(code);
if (isempty(s))
s = msg;
throw new estream(nil, code, s + " [" + ippeerinfo::asstring(true) + ']');
}
PTYPES_END
src/pipmsgsv.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <time.h>
#endif
#include "pinet.h"
PTYPES_BEGIN
//
// ipmsgserver: IPv4 UDP socket server
//
ipmsgserver::ipmsgserver()
: ipsvbase(SOCK_DGRAM), ippeerinfo(), handle(invhandle)
{
}
ipmsgserver::~ipmsgserver()
{
close();
}
void ipmsgserver::dobind(ipbindinfo* b)
{
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(ushort(b->get_port()));
sa.sin_addr.s_addr = b->get_ip();
if (::bind(b->handle, (sockaddr*)&sa, sizeof(sa)) != 0)
error(*b, usockerrno(), "Couldn't bind address");
}
void ipmsgserver::close()
{
if (!active)
return;
ipsvbase::close();
handle = invhandle;
ippeerinfo::clear();
}
bool ipmsgserver::poll(int i, int timeout)
{
if (!active)
open();
return dopoll(&i, timeout);
}
int ipmsgserver::receive(char* buf, int count)
{
if (!active)
open();
ippeerinfo::clear();
// determine which socket has pending data
int i = -1;
if (!dopoll(&i, -1))
error(*this, EINVAL, "Couldn't read");
ipbindinfo* b = (ipbindinfo*)addrlist[i];
handle = b->handle;
// read data
sockaddr_in sa;
psocklen len = sizeof(sa);
int result = ::recvfrom(handle, buf, count, 0, (sockaddr*)&sa, &len);
if (result < 0)
error(*b, usockerrno(), "Couldn't read");
// set up peer ip and port
ip = sa.sin_addr.s_addr;
port = ntohs(sa.sin_port);
return result;
}
string ipmsgserver::receive(int max)
{
string result;
setlength(result, max);
int numread = receive(pchar(pconst(result)), max);
setlength(result, numread);
return result;
}
void ipmsgserver::send(const char* buf, int count)
{
if (!active || handle == invhandle || ip == ipnone)
error(*this, EINVAL, "Couldn't write"); // must receive() first
sendto(buf, count, get_ip(), get_port());
}
void ipmsgserver::sendto(const char* buf, int count, ipaddress ip, int port)
{
if (!active || handle == invhandle || ip == ipnone)
error(*this, EINVAL, "Couldn't write"); // must receive() first
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(ushort(port));
sa.sin_addr.s_addr = ip;
if (::sendto(handle, buf, count, 0, (sockaddr*)&sa, sizeof(sa)) < 0)
error(*this, usockerrno(), "Couldn't write");
}
PTYPES_END
src/pipstm.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <time.h>
#endif
#include "pinet.h"
PTYPES_BEGIN
//
// internet (ipv4) socket
//
ipstream::ipstream()
: fdxstm(), ippeerinfo(0, nullstring, 0), svsocket(invhandle) {}
ipstream::ipstream(ipaddress iip, int iport)
: fdxstm(), ippeerinfo(iip, nullstring, iport), svsocket(invhandle) {}
ipstream::ipstream(const char* ihost, int iport)
: fdxstm(), ippeerinfo(ipnone, ihost, iport), svsocket(invhandle) {}
ipstream::ipstream(const string& ihost, int iport)
: fdxstm(), ippeerinfo(ipnone, ihost, iport), svsocket(invhandle) {}
ipstream::~ipstream()
{
cancel();
}
int ipstream::classid()
{
return CLASS3_IPSTM;
}
int ipstream::uerrno()
{
return usockerrno();
}
const char* ipstream::uerrmsg(int code)
{
return usockerrmsg(code);
}
string ipstream::get_streamname()
{
return ippeerinfo::asstring(true);
}
void ipstream::set_ip(ipaddress iip)
{
close();
ip = iip;
PTYPES_NAMESPACE::clear(host);
}
void ipstream::set_host(const string& ihost)
{
close();
host = ihost;
ip = ipnone;
}
void ipstream::set_host(const char* ihost)
{
close();
host = ihost;
ip = ipnone;
}
void ipstream::set_port(int iport)
{
close();
port = iport;
}
void ipstream::doopen()
{
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
if (svsocket != invhandle)
{
psocklen addrlen = sizeof(sa);
// open an active server socket and assign ip and host fields
chstat(IO_CONNECTING);
// the last parameter of accept() can be either int* or uint*
// depending on the target platform :(
if ((handle = ::accept(svsocket, (sockaddr*)&sa, &addrlen)) < 0)
error(uerrno(), "Couldn't create socket");
chstat(IO_CONNECTED);
if (sa.sin_family != AF_INET)
error(EAFNOSUPPORT, "Address family not supported");
PTYPES_NAMESPACE::clear(host);
ip = sa.sin_addr.s_addr;
port = ntohs(sa.sin_port);
}
else
{
sa.sin_family = AF_INET;
sa.sin_port = htons(ushort(get_port()));
chstat(IO_RESOLVING);
sa.sin_addr.s_addr = get_ip(); // force to resolve the address if needed
chstat(IO_RESOLVED);
// open a client socket
if ((handle = ::socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
error(uerrno(), "Couldn't create socket");
// a chance to set up extra socket options
sockopt(handle);
chstat(IO_CONNECTING);
if (::connect(handle, (sockaddr*)&sa, sizeof(sa)) < 0)
{
int e = uerrno();
closehandle();
error(e, "Couldn't connect to remote host");
}
chstat(IO_CONNECTED);
}
}
void ipstream::sockopt(int)
{
}
void ipstream::closehandle()
{
::closesocket(pexchange(&handle, invhandle));
}
large ipstream::doseek(large, ioseekmode)
{
return -1;
}
void ipstream::doclose()
{
svsocket = invhandle;
if (!cancelled)
::shutdown(handle, SHUT_RDWR);
closehandle();
}
#ifdef WIN32
int ipstream::dorawread(char* buf, int count)
{
int ret;
if ((ret = ::recv(handle, buf, count, 0)) == -1)
error(uerrno(), "Couldn't read");
return ret;
}
int ipstream::dorawwrite(const char* buf, int count)
{
int ret;
if ((ret = ::send(handle, buf, count, 0)) == -1)
error(uerrno(), "Couldn't write");
return ret;
}
#endif
bool ipstream::waitfor(int timeout)
{
if (!active)
errstminactive();
if (bufsize > 0 && bufend > bufpos)
return true;
return psockwait(handle, timeout);
}
ipaddress ipstream::get_myip()
{
if (!active)
errstminactive();
ippeerinfo p;
if (!psockname(handle, p))
error(uerrno(), "Couldn't get my IP");
return p.get_ip();
}
int ipstream::get_myport()
{
if (!active)
errstminactive();
ippeerinfo p;
if (!psockname(handle, p))
error(uerrno(), "Couldn't get my port number");
return p.get_port();
}
PTYPES_END
src/pipstmsv.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <time.h>
#endif
#include "pinet.h"
PTYPES_BEGIN
//
// ipstmserver
//
ipstmserver::ipstmserver()
: ipsvbase(SOCK_STREAM)
{
}
ipstmserver::~ipstmserver()
{
close();
}
void ipstmserver::dobind(ipbindinfo* b)
{
#ifndef WIN32
// set SO_REAUSEADDR to true, unix only. on windows this option causes
// the previous owner of the socket to give up, which is not desirable
// in most cases, neither compatible with unix.
int one = 1;
if (::setsockopt(b->handle, SOL_SOCKET, SO_REUSEADDR,
(sockval_t)&one, sizeof(one)) != 0)
error(*b, usockerrno(), "Can't reuse local address");
#endif
// set up sockaddr_in and try to bind it to the socket
sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(ushort(b->get_port()));
sa.sin_addr.s_addr = b->get_ip();
if (::bind(b->handle, (sockaddr*)&sa, sizeof(sa)) != 0)
error(*b, usockerrno(), "Couldn't bind address");
if (::listen(b->handle, SOMAXCONN) != 0)
error(*b, usockerrno(), "Couldn't listen on socket");
}
bool ipstmserver::poll(int i, int timeout)
{
if (!active)
open();
return dopoll(&i, timeout);
}
bool ipstmserver::serve(ipstream& client, int i, int timeout)
{
if (!active)
open();
client.cancel();
if (dopoll(&i, timeout))
{
// connect the ipstream object to the client requesting the connection
client.svsocket = get_addr(i).handle;
client.open();
return true;
}
return false;
}
PTYPES_END
src/pipsvbase.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <winsock2.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <time.h>
#endif
#include "pinet.h"
PTYPES_BEGIN
//
// ipbindinfo
//
ipbindinfo::ipbindinfo(ipaddress iip, const string& ihost, int iport)
: unknown(), ippeerinfo(iip, ihost, iport), handle(invhandle)
{
}
ipbindinfo::~ipbindinfo()
{
}
//
// ipsvbase
//
ipsvbase::ipsvbase(int isocktype)
: socktype(isocktype), active(false), addrlist(true) {}
ipsvbase::~ipsvbase()
{
close();
}
void ipsvbase::error(ippeerinfo& p, int code, const char* defmsg)
{
string msg = usockerrmsg(code);
if (isempty(msg))
msg = defmsg;
msg += " [" + p.asstring(true) + ']';
throw new estream(nil, code, msg);
}
int ipsvbase::bind(ipaddress ip, int port)
{
close();
addrlist.add(new ipbindinfo(ip, nullstring, port));
return addrlist.get_count() - 1;
}
int ipsvbase::bindall(int port)
{
close();
return bind(ipany, port);
}
void ipsvbase::clear()
{
close();
addrlist.clear();
}
void ipsvbase::open()
{
close();
if (addrlist.get_count() == 0)
fatal(CRIT_FIRST + 52, "No addresses specified to bind to");
active = true;
for (int i = 0; i < addrlist.get_count(); i++)
{
ipbindinfo* b = addrlist[i];
b->handle = ::socket(AF_INET, socktype, 0);
if (b->handle < 0)
error(*b, usockerrno(), "Couldn't create socket");
sockopt(b->handle);
dobind(b);
}
}
void ipsvbase::close()
{
if (!active)
return;
for (int i = 0; i < addrlist.get_count(); i++)
{
ipbindinfo* b = addrlist[i];
::closesocket(pexchange(&b->handle, invhandle));
}
active = false;
}
bool ipsvbase::dopoll(int* i, int timeout)
{
fd_set set;
setupfds(&set, *i);
timeval t;
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
if (::select(FD_SETSIZE, &set, nil, nil, (timeout < 0) ? nil : &t) > 0)
{
if (*i >= 0)
return true;
// if the user selected -1 (all), find the socket which has a pending connection
// and assign it to i
for (int j = 0; j < addrlist.get_count(); j++)
if (FD_ISSET(uint(addrlist[j]->handle), &set))
{
*i = j;
return true;
}
}
return false;
}
void ipsvbase::setupfds(void* set, int i)
{
#ifdef _MSC_VER
// disable "condition always true" warning caused by Microsoft's FD_SET macro
# pragma warning (disable: 4127)
#endif
FD_ZERO((fd_set*)set);
if (i >= 0)
{
int h = get_addr(i).handle;
if (h >= 0)
FD_SET((uint)h, (fd_set*)set);
}
else
for (i = 0; i < addrlist.get_count(); i++)
{
int h = addrlist[i]->handle;
if (h >= 0)
FD_SET((uint)h, (fd_set*)set);
}
}
void ipsvbase::sockopt(int)
{
}
PTYPES_END
src/pmd5.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
/*
* Derived from L. Peter Deutsch's independent implementation
* of MD5 (RFC1321). The original copyright notice follows.
* This file is a concatenation of the original md5.h and
* md5.c and contains PTypes' MD5 wrapper class at the bottom.
*/
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#include <string.h>
#include "pstreams.h"
PTYPES_BEGIN
//
// --- md5.h ---------------------------------------------------------------
//
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
//
// typedef unsigned char md5_byte_t; /* 8-bit byte */
// typedef unsigned int md5_word_t; /* 32-bit word */
//
// /* Define the state of the MD5 Algorithm. */
// typedef struct md5_state_s {
// md5_word_t count[2];/* message length in bits, lsw first */
// md5_word_t abcd[4];/* digest buffer */
// md5_byte_t buf[64];/* accumulate block */
// } md5_state_t;
//
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
//
// --- md5.c ---------------------------------------------------------------
//
#undef BYTE_ORDER/* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0/* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else/* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0/* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf;/* (dynamic only) */
# else
# define xbuf X/* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
//
// --- PTypes' wrapper class -----------------------------------------------
//
outmd5::outmd5(outstm* istm): outfilter(istm, 0)
{
memset(&ctx, 0, sizeof ctx);
memset(digest, 0, sizeof digest);
}
outmd5::~outmd5()
{
close();
}
void outmd5::doopen()
{
outfilter::doopen();
memset(digest, 0, sizeof digest);
md5_init(&ctx);
}
void outmd5::doclose()
{
md5_finish(&ctx, (unsigned char*)digest);
outfilter::doclose();
}
int outmd5::dorawwrite(const char* buf, int count)
{
if (count > 0)
{
md5_append(&ctx, (const unsigned char*)buf, (unsigned)count);
if (stm != nil)
stm->write(buf, count);
return count;
}
else
return 0;
}
string outmd5::get_streamname()
{
return "MD5";
}
string outmd5::get_digest()
{
close();
string result;
// the first 120 bits are divided into 24-bit portions;
// each portion is represented with 4 characters from the base64 set
for (int i = 0; i <= 12; i += 3)
{
long v = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2];
result += itostring(large(v), 64, 4);
}
// the last byte is complemented with 4 zero bits to form
// the last two base64 characters
return result + itostring(large(digest[15] << 4), 64, 2);
}
PTYPES_END
src/pmem.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include "pport.h"
PTYPES_BEGIN
const int quant = 64;
const int qmask = ~63;
const int quant2 = 4096;
const int qmask2 = ~4095;
// dynamic reallocation policy for strings and lists
int ptdecl memquantize(int a)
{
if (a <= 16)
return 16;
if (a <= 32)
return 32;
else if (a <= 2048)
return (a + quant - 1) & qmask;
else
return (a + quant2 - 1) & qmask2;
}
void ptdecl memerror()
{
fatal(CRIT_FIRST + 5, "Not enough memory");
}
void* ptdecl memalloc(uint a)
{
if (a == 0)
return nil;
else
{
void* p = malloc(a);
if (p == nil)
memerror();
return p;
}
}
void* ptdecl memrealloc(void* p, uint a)
{
if (a == 0)
{
memfree(p);
return nil;
}
else if (p == nil)
return memalloc(a);
else
{
p = realloc(p, a);
if (p == nil)
memerror();
return p;
}
}
void ptdecl memfree(void* p)
{
if (p != nil)
free(p);
}
PTYPES_END
src/pmsgq.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pasync.h"
PTYPES_BEGIN
static void msgerror()
{
fatal(CRIT_FIRST + 42, "Invalid message object");
}
message::message(int iid, pintptr iparam)
: next(nil), sync(nil), id(iid), param(iparam), result(0)
{
}
message::~message()
{
}
jobqueue::jobqueue(int ilimit)
: limit(ilimit), head(nil), tail(nil), qcount(0), sem(0), ovrsem(ilimit), qlock()
{
}
jobqueue::~jobqueue()
{
purgequeue();
}
bool jobqueue::enqueue(message* msg, int timeout)
{
if (msg == nil)
msgerror();
if (!ovrsem.wait(timeout))
return false;
qlock.enter();
msg->next = nil;
if (head != nil)
head->next = msg;
head = msg;
if (tail == nil)
tail = msg;
qcount++;
qlock.leave();
sem.post();
return true;
}
bool jobqueue::push(message* msg, int timeout)
{
if (msg == nil)
msgerror();
if (!ovrsem.wait(timeout))
return false;
qlock.enter();
msg->next = tail;
tail = msg;
if (head == nil)
head = msg;
qcount++;
qlock.leave();
sem.post();
return true;
}
message* jobqueue::dequeue(bool safe, int timeout)
{
if (!sem.wait(timeout))
return nil;
if (safe)
qlock.enter();
message* msg = tail;
tail = msg->next;
qcount--;
if (tail == nil)
head = nil;
if (safe)
qlock.leave();
ovrsem.post();
return msg;
}
void jobqueue::purgequeue()
{
qlock.enter();
while (get_count() > 0)
delete dequeue(false);
qlock.leave();
}
bool jobqueue::post(message* msg, int timeout)
{
return enqueue(msg, timeout);
}
bool jobqueue::post(int id, pintptr param, int timeout)
{
return post(new message(id, param), timeout);
}
bool jobqueue::posturgent(message* msg, int timeout)
{
return push(msg, timeout);
}
bool jobqueue::posturgent(int id, pintptr param, int timeout)
{
return posturgent(new message(id, param), timeout);
}
message* jobqueue::getmessage(int timeout)
{
return dequeue(true, timeout);
}
msgqueue::msgqueue(int ilimit)
: jobqueue(ilimit), thrlock(), owner(0), quit(false)
{
}
msgqueue::~msgqueue()
{
}
void msgqueue::takeownership()
{
if (owner != pthrself())
{
thrlock.enter(); // lock forever
//if (owner != 0)
// fatal(CRIT_FIRST + 45, "Ownership of the message queue already taken");
owner = pthrself();
}
}
pintptr msgqueue::finishmsg(message* msg)
{
if (msg != nil)
{
pintptr result = msg->result;
// if the message was sent by send(),
// just signale the semaphore
if (msg->sync != nil)
msg->sync->post();
// otherwise finish it
else
delete msg;
return result;
}
else
return 0;
}
pintptr msgqueue::send(message* msg)
{
if (msg == nil)
msgerror();
try
{
// if we are in the main thread,
// immediately handle the msg
if (pthrequal(owner))
handlemsg(msg);
// if this is called from a concurrent thread,
// sync through a semaphore
else
{
if (msg->sync != nil)
msgerror();
semaphore sync(0);
msg->sync = &sync;
push(msg);
msg->sync->wait();
msg->sync = 0;
}
}
catch (...)
{
finishmsg(msg);
throw;
}
return finishmsg(msg);
}
pintptr msgqueue::send(int id, pintptr param)
{
return send(new message(id, param));
}
void msgqueue::processone()
{
takeownership();
message* msg = dequeue();
try
{
handlemsg(msg);
}
catch(...)
{
finishmsg(msg);
throw;
}
finishmsg(msg);
}
void msgqueue::processmsgs()
{
while (!quit && get_count() > 0)
processone();
}
void msgqueue::run()
{
quit = false;
do
{
processone();
}
while (!quit);
}
void msgqueue::handlemsg(message* msg)
{
msghandler(*msg);
}
void msgqueue::defhandler(message& msg)
{
switch(msg.id)
{
case MSG_QUIT:
quit = true;
break;
}
}
PTYPES_END
src/pmtxtable.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pasync.h"
PTYPES_BEGIN
pmemlock _mtxtable[_MUTEX_HASH_SIZE] // currently 29
#ifndef WIN32
= {
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT, _MTX_INIT,
_MTX_INIT
}
#endif
;
PTYPES_END
src/pnpipe.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/un.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
#ifdef WIN32
string ptdecl namedpipe::realpipename(const string& pipename, const string& svrname)
{
if (isempty(pipename))
return nullstring;
string realname = pipename;
if (*pconst(pipename) == '/')
{
int i = rpos('/', realname);
del(realname, 0, i + 1);
}
string s;
if (isempty(svrname))
s = '.';
else
s = svrname;
return "\\\\" + s + "\\pipe\\" + realname;
}
#else
string ptdecl namedpipe::realpipename(const string& pipename)
{
if (isempty(pipename))
return nullstring;
if (*pconst(pipename) == '/')
return pipename;
else
return DEF_NAMED_PIPES_DIR + pipename;
}
bool namedpipe::setupsockaddr(const string& pipename, void* isa)
{
sockaddr_un* sa = (sockaddr_un*)isa;
memset(sa, 0, sizeof(sockaddr_un));
sa->sun_family = AF_UNIX;
#ifdef __FreeBSD__
sa->sun_len = length(pipename);
#endif
// copy the path name into the sockaddr structure, 108 chars max (?)
if (length(pipename) + 1 > (int)sizeof(sa->sun_path))
return false;
strcpy(sa->sun_path, pipename);
return true;
}
#endif
namedpipe::namedpipe()
: fdxstm(), pipename(), svhandle(invhandle)
{
initovr();
}
namedpipe::namedpipe(const string& ipipename)
: fdxstm(), pipename(), svhandle(invhandle)
{
pipename = realpipename(ipipename);
initovr();
}
#ifdef WIN32
namedpipe::namedpipe(const string& ipipename, const string& servername)
: fdxstm(), pipename(), svhandle(invhandle)
{
pipename = realpipename(ipipename, servername);
initovr();
}
void namedpipe::initovr()
{
ovr.hEvent = CreateEvent(0, false, false, 0);
}
#endif
namedpipe::~namedpipe()
{
cancel();
#ifdef WIN32
CloseHandle(ovr.hEvent);
#endif
}
int namedpipe::classid()
{
return CLASS3_NPIPE;
}
string namedpipe::get_streamname()
{
return pipename;
}
void namedpipe::set_pipename(const string& newvalue)
{
close();
pipename = realpipename(newvalue);
}
void namedpipe::set_pipename(const char* newvalue)
{
close();
pipename = realpipename(newvalue);
}
large namedpipe::doseek(large, ioseekmode)
{
return -1;
}
void namedpipe::doopen()
{
#ifdef WIN32
if (svhandle != invhandle)
handle = svhandle;
else
{
int tries = DEF_PIPE_OPEN_RETRY;
int delay = DEF_PIPE_OPEN_TIMEOUT / 2;
retry:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
handle = int(CreateFile(pipename, GENERIC_READ | GENERIC_WRITE,
0, &sa, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0));
if (handle == invhandle)
{
if (GetLastError() == ERROR_PIPE_BUSY)
{
if (--tries > 0)
{
delay *= 2;
Sleep(delay);
goto retry;
}
else
error(EIO, "Pipe busy");
}
else
error(uerrno(), "Couldn't open named pipe");
}
}
#else
if (svhandle != invhandle)
{
if ((handle = ::accept(svhandle, 0, 0)) < 0)
error(uerrno(), "Couldn't create local socket");
}
else
{
sockaddr_un sa;
if (!setupsockaddr(pipename, &sa))
error(ERANGE, "Socket name too long");
// cteate a client socket
if ((handle = ::socket(sa.sun_family, SOCK_STREAM, 0)) < 0)
error(uerrno(), "Couldn't create local socket");
// ... and connect to the local socket
if (::connect(handle, (sockaddr*)&sa, sizeof(sa)) < 0)
{
int e = uerrno();
doclose();
error(e, "Couldn't connect to local socket");
}
}
#endif
}
#ifdef WIN32
int namedpipe::dorawread(char* buf, int count)
{
unsigned long ret = uint(-1);
ovr.Offset = 0;
ovr.OffsetHigh = 0;
if (!ReadFile(HANDLE(handle), buf, count, &ret, &ovr))
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (WaitForSingleObject(ovr.hEvent, DEF_PIPE_TIMEOUT) == WAIT_TIMEOUT)
error(EIO, "Timed out");
if (!GetOverlappedResult(HANDLE(handle), &ovr, &ret, false))
error(uerrno(), "Couldn't read");
}
else
error(uerrno(), "Couldn't read");
}
return ret;
}
int namedpipe::dorawwrite(const char* buf, int count)
{
unsigned long ret = uint(-1);
ovr.Offset = 0;
ovr.OffsetHigh = 0;
if (!WriteFile(HANDLE(handle), buf, count, &ret, &ovr))
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (WaitForSingleObject(ovr.hEvent, DEF_PIPE_TIMEOUT) == WAIT_TIMEOUT)
error(EIO, "Timed out");
if (!GetOverlappedResult(HANDLE(handle), &ovr, &ret, false))
error(uerrno(), "Couldn't write");
}
else
error(uerrno(), "Couldn't write");
}
return ret;
}
#endif
void namedpipe::doclose()
{
#ifdef WIN32
if (svhandle != invhandle)
DisconnectNamedPipe(HANDLE(handle));
#endif
svhandle = invhandle;
fdxstm::doclose();
}
void namedpipe::flush()
{
#ifdef WIN32
if (!cancelled)
FlushFileBuffers(HANDLE(handle));
#endif
fdxstm::flush();
}
PTYPES_END
src/pnpserver.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/un.h>
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
npserver::npserver(const string& ipipename)
: pipename(), handle(invhandle), active(false)
{
pipename = namedpipe::realpipename(ipipename);
}
npserver::~npserver()
{
close();
}
void npserver::error(int code, const char* defmsg)
{
string msg = unixerrmsg(code);
if (isempty(msg))
msg = defmsg;
msg += " [" + pipename + ']';
throw new estream(nil, code, msg);
}
#ifdef WIN32
void npserver::openinst()
{
// called once at startup and then again, after
// each client connection. strange logic, to say the least...
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
handle = (int)CreateNamedPipe(pipename,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
DEF_PIPE_SYSTEM_BUF_SIZE, DEF_PIPE_SYSTEM_BUF_SIZE,
DEF_PIPE_TIMEOUT, &sa);
if (handle == invhandle)
error(unixerrno(), "Couldn't create");
}
void npserver::closeinst()
{
CloseHandle(HANDLE(pexchange(&handle, invhandle)));
}
#endif
void npserver::open()
{
close();
#ifdef WIN32
openinst();
#else
sockaddr_un sa;
if (!namedpipe::setupsockaddr(pipename, &sa))
error(ERANGE, "Socket name too long");
if ((handle = ::socket(sa.sun_family, SOCK_STREAM, 0)) < 0)
error(unixerrno(), "Couldn't create local socket");
unlink(pipename);
if (::bind(handle, (sockaddr*)&sa, sizeof(sa)) != 0)
error(unixerrno(), "Couldn't bind local socket");
if (::listen(handle, SOMAXCONN) != 0)
error(unixerrno(), "Couldn't listen on local socket");
#endif
active = true;
}
void npserver::close()
{
if (active)
{
active = false;
#ifdef WIN32
closeinst();
#else
::close(pexchange(&handle, invhandle));
unlink(pipename);
#endif
}
}
bool npserver::serve(namedpipe& client, int timeout)
{
if (!active)
open();
client.cancel();
#ifdef WIN32
client.ovr.Offset = 0;
client.ovr.OffsetHigh = 0;
bool result = ConnectNamedPipe(HANDLE(handle), &client.ovr) ?
true : (GetLastError() == ERROR_PIPE_CONNECTED);
if (!result && GetLastError() == ERROR_IO_PENDING)
{
if (WaitForSingleObject(client.ovr.hEvent, timeout) == WAIT_TIMEOUT)
return false;
unsigned long ret;
if (!GetOverlappedResult(HANDLE(handle), &client.ovr, &ret, false))
error(unixerrno(), "Couldn't read");
result = true;
}
if (result)
{
client.svhandle = handle;
client.pipename = pipename;
openinst();
client.open();
return true;
}
else
error(unixerrno(), "Couldn't connect to client");
return false;
#else
fd_set set;
FD_ZERO(&set);
FD_SET((uint)handle, &set);
timeval t;
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
if (::select(FD_SETSIZE, &set, nil, nil, (timeout < 0) ? nil : &t) > 0)
{
client.svhandle = handle;
client.pipename = pipename;
client.open();
return true;
}
return false;
#endif
}
PTYPES_END
src/pobjlist.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
_objlist::_objlist()
: tpodlist<void*,true>()
{
memset(&config, 0, sizeof(config));
}
_objlist::_objlist(bool ownobjects)
: tpodlist<void*,true>()
{
memset(&config, 0, sizeof(config));
config.ownobjects = ownobjects;
}
_objlist::~_objlist()
{
}
void _objlist::dofree(void*)
{
fatal(CRIT_FIRST + 38, "ptrlist::dofree() not defined");
}
int _objlist::compare(const void*, const void*) const
{
fatal(CRIT_FIRST + 38, "ptrlist::compare() not defined");
return 0;
}
void _objlist::dofree(int index, int num)
{
void** p = (void**)list + index;
while (--num >= 0)
dofree(*p++);
}
void _objlist::doput(int index, void* obj)
{
void** p = (void**)list + index;
if (config.ownobjects)
dofree(*p);
*p = obj;
}
void _objlist::dodel(int index)
{
if (config.ownobjects)
dofree(doget(index));
tpodlist<void*, true>::dodel(index);
}
void _objlist::dodel(int index, int delcount)
{
if (config.ownobjects)
{
if (index + delcount > count)
delcount = count - index;
dofree(index, delcount);
}
tpodlist<void*, true>::dodel(index, delcount);
}
void _objlist::set_count(int newcount)
{
if (newcount < count && config.ownobjects)
{
if (newcount < 0)
newcount = 0;
dofree(newcount, count - newcount);
}
_podlist::set_count(newcount, true);
}
void* _objlist::dopop()
{
void* t = doget(--count);
if (count == 0)
set_capacity(0);
return t;
}
bool _objlist::search(const void* key, int& index) const
{
int l, h, i, c;
bool ret = false;
l = 0;
h = count - 1;
while (l <= h)
{
i = (l + h) / 2;
c = compare(key, doget(i));
if (c > 0)
l = i + 1;
else
{
h = i - 1;
if (c == 0)
{
ret = true;
if (!config.duplicates)
l = i;
}
}
}
index = l;
return ret;
}
int _objlist::indexof(void* obj) const
{
for (int i = 0; i < count; i++)
if (doget(i) == obj)
return i;
return -1;
}
#ifdef PTYPES19_COMPAT
objlist::objlist(bool ownobjects): tobjlist<unknown>(ownobjects) {}
objlist::~objlist() {}
#endif
PTYPES_END
src/poutfile.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "errno.h"
#ifdef WIN32
# include <windows.h>
#else
# include <fcntl.h>
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
// *BSD hack
#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
outfile::outfile()
: outstm(), filename(), syshandle(invhandle), peerhandle(invhandle),
umode(0644), append(false) {}
outfile::outfile(const char* ifn, bool iappend)
: outstm(), filename(ifn), syshandle(invhandle), peerhandle(invhandle),
umode(0644), append(iappend) {}
outfile::outfile(string const& ifn, bool iappend)
: outstm(), filename(ifn), syshandle(invhandle), peerhandle(invhandle),
umode(0644), append(iappend) {}
outfile::~outfile()
{
close();
}
int outfile::classid()
{
return CLASS2_OUTFILE;
}
string outfile::get_streamname()
{
return filename;
}
void outfile::doopen()
{
if (syshandle != invhandle)
handle = syshandle;
else
{
#ifdef WIN32
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
handle = int(CreateFile(filename, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
(append ? OPEN_ALWAYS : CREATE_ALWAYS), 0, 0));
#else
handle = ::open(filename,
O_WRONLY | O_CREAT | O_LARGEFILE | (append ? 0 : O_TRUNC), umode);
#endif
if (handle == invhandle)
error(uerrno(), "Couldn't open");
if (append)
if (doseek(0, IO_END) == -1)
error(uerrno(), "Couldn't seek to end of file");
}
}
void outfile::flush()
{
outstm::flush();
#ifdef WIN32
FlushFileBuffers(HANDLE(handle));
#endif
}
void outfile::doclose()
{
outstm::doclose();
syshandle = invhandle;
peerhandle = invhandle;
}
PTYPES_END
src/poutfilter.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#include "pstreams.h"
PTYPES_BEGIN
outfilter::outfilter(outstm* istm, int ibufsize)
: outstm(false, ibufsize), stm(istm)
{
if (stm != nil)
stm->addnotification(this);
}
outfilter::~outfilter()
{
if (stm != nil)
stm->delnotification(this);
}
void outfilter::freenotify(component* sender)
{
if (sender == stm)
{
stm = nil;
close();
}
}
void outfilter::doopen()
{
if (stm != nil && !stm->get_active())
stm->open();
}
void outfilter::doclose()
{
}
string outfilter::get_errstmname()
{
if (stm == nil)
return get_streamname();
else
return get_streamname() + ": " + stm->get_errstmname();
}
void outfilter::set_stm(outstm* istm)
{
close();
if (stm != nil)
stm->delnotification(this);
stm = istm;
if (stm != nil)
stm->addnotification(this);
}
PTYPES_END
src/poutmem.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pstreams.h"
PTYPES_BEGIN
outmemory::outmemory(int ilimit)
: outstm(false, 0), mem(), limit(ilimit)
{
}
outmemory::~outmemory()
{
close();
}
int outmemory::classid()
{
return CLASS2_OUTMEMORY;
}
void outmemory::doopen()
{
}
void outmemory::doclose()
{
clear(mem);
}
large outmemory::doseek(large newpos, ioseekmode mode)
{
large pos;
switch (mode)
{
case IO_BEGIN:
pos = newpos;
break;
case IO_CURRENT:
pos = abspos + newpos;
break;
default: // case IO_END:
pos = length(mem) + newpos;
break;
}
if (limit >= 0 && pos > limit)
pos = limit;
return pos;
}
int outmemory::dorawwrite(const char* buf, int count)
{
if (count <= 0)
return 0;
if (limit >= 0 && abspos + count > limit)
{
count = limit - (int)abspos;
if (count <= 0)
return 0;
}
// the string reallocator takes care of efficiency
if ((int)abspos + count > length(mem))
setlength(mem, (int)abspos + count);
memcpy(pchar(pconst(mem)) + (int)abspos, buf, count);
return count;
}
string outmemory::get_streamname()
{
return "mem";
}
string outmemory::get_strdata()
{
if (!active)
errstminactive();
return mem;
}
PTYPES_END
src/poutstm.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
outstm::outstm(bool iflusheol, int ibufsize)
: iobase(ibufsize), flusheol(iflusheol) {}
outstm::~outstm()
{
}
int outstm::classid()
{
return CLASS_OUTSTM;
}
int outstm::dorawwrite(const char* buf, int count)
{
if (handle == invhandle)
return -1;
#ifdef WIN32
unsigned long ret;
if (!WriteFile(HANDLE(handle), buf, count, &ret, nil))
{
error(uerrno(), "Couldn't write");
ret = uint(-1);
}
#else
int ret;
if ((ret = ::write(handle, buf, count)) < 0)
error(uerrno(), "Couldn't write");
#endif
return ret;
}
int outstm::rawwrite(const char* buf, int count)
{
if (!active)
errstminactive();
try
{
int ret = dorawwrite(buf, count);
if (ret < 0)
ret = 0;
else
abspos += ret;
chstat(IO_WRITING);
if (ret < count)
{
eof = true;
chstat(IO_EOF);
}
return ret;
}
catch (estream*)
{
eof = true;
chstat(IO_EOF);
throw;
}
}
void outstm::bufvalidate()
{
if (!active)
errstminactive();
if (bufend > 0)
rawwrite(bufdata, bufend);
bufclear();
}
large outstm::seekx(large newpos, ioseekmode mode)
{
if (bufdata != 0 && mode != IO_END)
{
large pos;
if (mode == IO_BEGIN)
pos = newpos;
else
pos = tellx() + newpos;
pos -= abspos;
if (pos >= 0 && pos <= bufpos)
{
bufpos = (int)pos;
eof = false;
return tellx();
}
}
return iobase::seekx(newpos, mode);
}
bool outstm::canwrite()
{
if (bufdata != 0 && bufpos >= bufsize)
{
bufvalidate();
return bufend < bufsize;
}
else
return true;
}
void outstm::flush()
{
if (bufdata != 0 && stmerrno == 0)
bufvalidate();
}
void outstm::put(char c)
{
if (!active)
errstminactive();
if (bufdata == 0)
rawwrite(&c, 1);
else if (canwrite())
{
bufdata[bufpos] = c;
bufadvance(1);
if (c == 10 && flusheol)
flush();
}
}
int outstm::write(const void* buf, int count)
{
if (!active)
errstminactive();
int ret = 0;
if (bufdata == 0)
ret = rawwrite(pconst(buf), count);
else
{
while (count > 0 && canwrite())
{
int n = imin(count, bufsize - bufpos);
memcpy(bufdata + bufpos, buf, n);
ret += n;
count -= n;
buf = pconst(buf) + n;
bufadvance(n);
}
}
return ret;
}
void outstm::put(const char* str)
{
if (str != nil)
write(str, hstrlen(str));
}
void outstm::put(const string& str)
{
write(pconst(str), length(str));
}
void outstm::putline(const char* s)
{
put(s);
puteol();
}
void outstm::putline(const string& s)
{
put(s);
puteol();
}
void outstm::puteol()
{
#ifdef WIN32
put(13);
#endif
put(10);
}
PTYPES_END
src/ppipe.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
#include "pstreams.h"
PTYPES_BEGIN
void infile::pipe(outfile& out)
{
#ifdef WIN32
SECURITY_ATTRIBUTES sa;
HANDLE h[2];
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&h[0], &h[1], &sa, 0))
#else
int h[2];
if (::pipe(h) != 0)
#endif
error(uerrno(), "Couldn't create a local pipe");
set_syshandle(int(h[0]));
peerhandle = int(h[1]);
out.set_syshandle(int(h[1]));
out.peerhandle = int(h[0]);
open();
out.open();
}
PTYPES_END
src/ppodlist.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
void _podlist::idxerror()
{
fatal(CRIT_FIRST + 30, "List index out of bounds");
}
_podlist::_podlist(int iitemsize)
: list(0), count(0), capacity(0), itemsize(iitemsize)
{
if (itemsize <= 0 || itemsize > 255)
fatal(CRIT_FIRST + 37, "Invalid item size for podlist");
}
_podlist::~_podlist()
{
set_count(0);
}
void _podlist::set_capacity(int newcap)
{
if (newcap != capacity)
{
if (newcap < count)
fatal(CRIT_FIRST + 36, "List capacity can't be smaller than count");
list = memrealloc(list, newcap * itemsize);
capacity = newcap;
}
}
void _podlist::grow()
{
if (capacity > count)
return;
set_capacity(capacity == 0 ? 4 : ((capacity + 1) / 2) * 3);
}
void _podlist::set_count(int newcount, bool zero)
{
if (newcount > count)
{
if (newcount > capacity)
set_capacity(newcount);
if (zero)
memset(doget(count), 0, (newcount - count) * itemsize);
count = newcount;
}
else if (newcount < count)
{
if (newcount < 0)
// wrong newcount: we don't want to generate an error here.
// instead, we'll set count to 0 and wait until some other
// operation raises an error
newcount = 0;
count = newcount;
if (count == 0)
set_capacity(0);
}
}
// doXXX() methods do not perform bounds checking; used internally
// where index is guaranteed to be valid
void* _podlist::doins(int index)
{
grow();
pchar s = pchar(doget(index));
if (index < count)
memmove(s + itemsize, s, (count - index) * itemsize);
count++;
return s;
}
void _podlist::doins(int index, const _podlist& t)
{
if (&t == this)
return;
if (index == count)
add(t);
else
{
if (itemsize != t.itemsize)
fatal(CRIT_FIRST + 35, "Incompatible list");
if (t.count == 0)
return;
int ocnt = count;
set_count(ocnt + t.count);
pchar s = pchar(doget(index));
memmove(s + t.count * itemsize, s, (ocnt - index) * itemsize);
memcpy(s, t.list, t.count * itemsize);
}
}
void* _podlist::add()
{
grow();
return doget(count++);
}
void _podlist::add(const _podlist& t)
{
if (count == 0)
operator =(t);
else
{
if (itemsize != t.itemsize)
fatal(CRIT_FIRST + 35, "Incompatible list");
int ocnt = count;
int tcnt = t.count;
set_count(ocnt + tcnt);
memcpy(doget(ocnt), t.list, tcnt * itemsize);
}
}
_podlist& _podlist::operator =(const _podlist& t)
{
if (&t != this)
{
if (itemsize != t.itemsize)
fatal(CRIT_FIRST + 35, "Incompatible list");
set_count(t.count);
pack();
memcpy(list, t.list, count * itemsize);
}
return *this;
}
void _podlist::dodel(int index)
{
count--;
if (index < count)
{
pchar s = pchar(doget(index));
memmove(s, s + itemsize, (count - index) * itemsize);
}
else if (count == 0)
set_capacity(0);
}
void _podlist::dodel(int index, int delcount)
{
if (delcount <= 0)
return;
if (index + delcount > count)
delcount = count - index;
count -= delcount;
if (index < count)
{
pchar s = pchar(doget(index));
memmove(s, s + delcount * itemsize, (count - index) * itemsize);
}
else if (count == 0)
set_capacity(0);
}
void _podlist::dopop()
{
if (--count == 0)
set_capacity(0);
}
PTYPES_END
src/pputf.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "ptypes.h"
#include "pstreams.h"
#include "pinet.h" // for ipaddress type
#include "ptime.h" // for dttotm()
#ifndef PTYPES_ST
#include "pasync.h" // for mutex locking in logfile::vputf()
#endif
PTYPES_BEGIN
// %t and %T formats
char* shorttimefmt = "%d-%b-%Y %X";
char* longtimefmt = "%a %b %d %X %Y";
static cset fmtopts = " #+~-0-9.";
enum fmt_type_t
{
FMT_NONE,
FMT_CHAR,
FMT_SHORT,
FMT_INT,
FMT_LONG,
FMT_LARGE,
FMT_STR,
FMT_PTR,
FMT_DOUBLE,
FMT_LONG_DOUBLE,
FMT_IPADDR,
FMT_TIME,
FMT_LONGTIME
};
void outstm::vputf(const char* fmt, va_list va)
{
const char* p = fmt;
while (*p != 0)
{
// write out raw data between format specifiers
const char* e = strchr(p, '%');
if (e == 0)
e = p + strlen(p);
if (e > p)
write(p, e - p);
if (*e != '%')
break;
e++;
if (*e == '%')
{
// write out a single '%'
put('%');
p = e + 1;
continue;
}
// build a temporary buffer for the conversion specification
char fbuf[128];
fbuf[0] = '%';
char* f = fbuf + 1;
bool modif = false;
// formatting flags and width specifiers
while (*e & fmtopts && uint(f - fbuf) < sizeof(fbuf) - 5)
{
*f++ = *e++;
modif = true;
}
// prefixes
fmt_type_t fmt_type = FMT_NONE;
switch(*e)
{
case 'h':
fmt_type = FMT_SHORT;
*f++ = *e++;
break;
case 'L':
fmt_type = FMT_LONG_DOUBLE;
*f++ = *e++;
break;
case 'l':
e++;
if (*e == 'l')
{
#if defined(_MSC_VER) || defined(__BORLANDC__)
*f++ = 'I';
*f++ = '6';
*f++ = '4';
#else
*f++ = 'l';
*f++ = 'l';
#endif
e++;
fmt_type = FMT_LARGE;
}
else
{
*f++ = 'l';
fmt_type = FMT_LONG;
}
break;
}
// format specifier
switch(*e)
{
case 'c':
fmt_type = FMT_CHAR;
*f++ = *e++;
break;
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if (fmt_type < FMT_SHORT || fmt_type > FMT_LARGE)
fmt_type = FMT_INT;
*f++ = *e++;
break;
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
if (fmt_type != FMT_LONG_DOUBLE)
fmt_type = FMT_DOUBLE;
*f++ = *e++;
break;
case 's':
fmt_type = FMT_STR;
*f++ = *e++;
break;
case 'p':
fmt_type = FMT_PTR;
*f++ = *e++;
break;
case 'a':
fmt_type = FMT_IPADDR;
*f++ = *e++;
break;
case 't':
fmt_type = FMT_TIME;
*f++ = *e++;
break;
case 'T':
fmt_type = FMT_LONGTIME;
*f++ = *e++;
break;
}
if (fmt_type == FMT_NONE)
break;
*f = 0;
// some formatters are processed here 'manually',
// while others are passed to snprintf
char buf[4096];
int s = 0;
switch(fmt_type)
{
case FMT_NONE:
break; // to avoid compiler warning
case FMT_CHAR:
if (modif)
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,int));
else
put(char(va_arg(va,int)));
break;
case FMT_SHORT:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,int));
break;
case FMT_INT:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,int));
break;
case FMT_LONG:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,long));
break;
case FMT_LARGE:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,large));
break;
case FMT_STR:
if (modif)
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,char*));
else
put(va_arg(va,const char*));
break;
case FMT_PTR:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,void*));
break;
case FMT_DOUBLE:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,double));
break;
case FMT_LONG_DOUBLE:
s = snprintf(buf, sizeof(buf), fbuf, va_arg(va,long double));
break;
case FMT_IPADDR:
{
ipaddress ip = va_arg(va,long);
s = snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
uint(ip[0]), uint(ip[1]), uint(ip[2]), uint(ip[3]));
}
break;
case FMT_TIME:
case FMT_LONGTIME:
{
char* fmt = fmt_type == FMT_TIME ? shorttimefmt : longtimefmt;
struct tm t;
datetime dt = va_arg(va,large);
if (dt < 0)
dt = 0;
s = strftime(buf, sizeof(buf), fmt, dttotm(dt, t));
}
break;
}
if (s > 0)
write(buf, s);
p = e;
}
}
void outstm::putf(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
vputf(fmt, va);
va_end(va);
}
void fdxstm::putf(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
out.vputf(fmt, va);
va_end(va);
}
void logfile::vputf(const char* fmt, va_list va)
{
#ifndef PTYPES_ST
scopelock sl(lock);
#endif
outfile::vputf(fmt, va);
}
void logfile::putf(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
vputf(fmt, va);
va_end(va);
}
PTYPES_END
src/prwlock.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <pthread.h>
#endif
#include "pasync.h"
PTYPES_BEGIN
static void rwlock_fail()
{
fatal(CRIT_FIRST + 41, "rwlock failed");
}
inline void rwlock_syscheck(int r)
{
if (r != 0)
rwlock_fail();
}
#ifdef __PTYPES_RWLOCK__
# ifdef WIN32
//
// this implementation of the read/write lock is derived
// from Apache Portable Runtime (APR) source, which
// in turn was originally based on an erroneous (or just
// incomplete?) example in one of the MSDN technical articles.
//
rwlock::rwlock()
: mutex(), readcnt(-1), writecnt(0)
{
reading = CreateEvent(0, true, false, 0);
finished = CreateEvent(0, false, true, 0);
if (reading == 0 || finished == 0)
rwlock_fail();
}
rwlock::~rwlock()
{
CloseHandle(reading);
CloseHandle(finished);
}
void rwlock::rdlock()
{
if (pincrement(&readcnt) == 0)
{
WaitForSingleObject(finished, INFINITE);
SetEvent(reading);
}
WaitForSingleObject(reading, INFINITE);
}
void rwlock::wrlock()
{
mutex::enter();
WaitForSingleObject(finished, INFINITE);
writecnt++;
}
void rwlock::unlock()
{
if (writecnt != 0)
{
writecnt--;
SetEvent(finished);
mutex::leave();
}
else if (pdecrement(&readcnt) < 0)
{
ResetEvent(reading);
SetEvent(finished);
}
}
# else // !defined(WIN32)
//
// for other platforms that lack POSIX rwlock we implement
// the rwlock object using POSIX condvar. the code below
// is based on Sean Burke's algorithm posted in
// comp.programming.threads.
//
rwlock::rwlock()
: locks(0), writers(0), readers(0)
{
rwlock_syscheck(pthread_mutex_init(&mtx, 0));
rwlock_syscheck(pthread_cond_init(&readcond, 0));
rwlock_syscheck(pthread_cond_init(&writecond, 0));
}
rwlock::~rwlock()
{
pthread_cond_destroy(&writecond);
pthread_cond_destroy(&readcond);
pthread_mutex_destroy(&mtx);
}
void rwlock::rdlock()
{
pthread_mutex_lock(&mtx);
readers++;
while (locks < 0)
pthread_cond_wait(&readcond, &mtx);
readers--;
locks++;
pthread_mutex_unlock(&mtx);
}
void rwlock::wrlock()
{
pthread_mutex_lock(&mtx);
writers++;
while (locks != 0)
pthread_cond_wait(&writecond, &mtx);
locks = -1;
writers--;
pthread_mutex_unlock(&mtx);
}
void rwlock::unlock()
{
pthread_mutex_lock(&mtx);
if (locks > 0)
{
locks--;
if (locks == 0)
pthread_cond_signal(&writecond);
}
else
{
locks = 0;
if (readers != 0)
pthread_cond_broadcast(&readcond);
else
pthread_cond_signal(&writecond);
}
pthread_mutex_unlock(&mtx);
}
# endif // !defined(WIN32)
#else// !defined(__PTYPES_RWLOCK__)
//
// for other systems we declare a fully-inlined rwlock
// object in pasync.h
//
rwlock::rwlock()
{
rwlock_syscheck(pthread_rwlock_init(&rw, 0));
}
#endif
PTYPES_END
src/psemaphore.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <errno.h>
#ifdef WIN32
# include <windows.h>
#else
# include <pthread.h>
#endif
#include "pasync.h"
PTYPES_BEGIN
#ifndef __SEM_TO_TIMEDSEM__
static void sem_fail()
{
fatal(CRIT_FIRST + 41, "Semaphore failed");
}
semaphore::semaphore(int initvalue)
{
if (sem_init(&handle, 0, initvalue) != 0)
sem_fail();
}
semaphore::~semaphore()
{
sem_destroy(&handle);
}
void semaphore::wait()
{
int err;
do {
err = sem_wait(&handle);
} while (err == -1 && errno == EINTR);
if (err != 0)
sem_fail();
}
void semaphore::post()
{
if (sem_post(&handle) != 0)
sem_fail();
}
#else
int _psemaphore_dummy_symbol; // avoid ranlib's warning message
#endif
PTYPES_END
src/pstdio.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pport.h"
#include "pstreams.h"
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
PTYPES_BEGIN
infile pin;
logfile pout;
logfile perr;
outnull pnull;
static class _stdio_init
{
public:
_stdio_init();
} _stdio_init_inst;
#ifdef WIN32
static HANDLE DuplicateSysHandle(DWORD stdh)
{
HANDLE hold = GetStdHandle(stdh);
HANDLE hnew = 0;
DuplicateHandle(GetCurrentProcess(), hold, GetCurrentProcess(),
&hnew, 0, true, DUPLICATE_SAME_ACCESS);
return hnew;
}
#endif
_stdio_init::_stdio_init()
{
#ifdef WIN32
pin.set_syshandle(int(DuplicateSysHandle(STD_INPUT_HANDLE)));
pout.set_syshandle(int(DuplicateSysHandle(STD_OUTPUT_HANDLE)));
perr.set_syshandle(int(DuplicateSysHandle(STD_ERROR_HANDLE)));
#else
pin.set_syshandle(::dup(STDIN_FILENO));
pout.set_syshandle(::dup(STDOUT_FILENO));
perr.set_syshandle(::dup(STDERR_FILENO));
#endif
pin.set_bufsize(4096);
pin.open();
pout.open();
perr.open();
pnull.open();
// prevent others from freeing these objects, if assigned to a variant.
// will need to handle reference counting for static objects better. any ideas?
addref(&pin);
addref(&pout);
addref(&perr);
addref(&pnull);
// this is to show objalloc = 0 at program exit
objalloc -= 4;
}
//
// null output stream
//
outnull::outnull()
: outstm(0)
{
}
outnull::~outnull()
{
close();
}
int outnull::dorawwrite(const char*, int)
{
return 0;
}
void outnull::doopen()
{
}
void outnull::doclose()
{
}
string outnull::get_streamname()
{
return "<null>";
}
//
// logfile - file output with thread-safe putf()
//
logfile::logfile(): outfile()
{
set_bufsize(0);
}
logfile::logfile(const char* ifn, bool iappend): outfile(ifn, iappend)
{
set_bufsize(0);
}
logfile::logfile(const string& ifn, bool iappend): outfile(ifn, iappend)
{
set_bufsize(0);
}
logfile::~logfile()
{
}
int logfile::classid()
{
return CLASS3_LOGFILE;
}
PTYPES_END
src/pstrcase.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
string ptdecl lowercase(const char* p)
{
// we rely on the function locase() which converts one single
// character to lower case. all locale specific things can be
// settled down in the future releases.
string r;
if (p != nil)
{
char* d = setlength(r, strlen(p));
while (*p != 0)
*d++ = locase(*p++);
}
return r;
}
string ptdecl lowercase(const string& s)
{
// this function does practically nothing if the string s
// contains no uppercase characters. once an uppercase character
// is encountered, the string is copied to another buffer and the
// rest is done as usual.
string r = s;
// a trick to get a non-const pointer without making
// the string unique
char* p = pchar(pconst(r));
bool u = false;
int i = 0;
while (*p != 0)
{
char c = locase(*p);
// if the character went lowercase...
if (c != *p)
{
// if the resulting string r is not unique yet...
if (!u)
{
// ... make it unique and adjust the pointer p accordingly
// this is done only once.
p = unique(r) + i;
u = true;
}
*p = c;
}
p++;
i++;
}
return r;
}
PTYPES_END
src/pstrconv.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#include "ptypes.h"
PTYPES_BEGIN
static char* _itobase(large value, char* buf, int base, int& len, bool _signed)
{
// internal conversion routine: converts the value to a string
// at the end of the buffer and returns a pointer to the first
// character. this is to get rid of copying the string to the
// beginning of the buffer, since finally the string is supposed
// to be copied to a dynamic string in itostring(). the buffer
// must be at least 65 bytes long.
static char digits[65] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char* pdigits;
if (base > 36)
pdigits = digits; // start from '.'
else
pdigits = digits + 2; // start from '0'
int i = 64;
buf[i] = 0;
bool neg = false;
ularge v = value;
if (_signed && base == 10 && value < 0)
{
v = -value;
// since we can't handle the lowest signed 64-bit value, we just
// return a built-in string.
if (large(v) < 0) // the LLONG_MIN negated results in the same value
{
len = 20;
return "-9223372036854775808";
}
neg = true;
}
do
{
buf[--i] = pdigits[uint(v % base)];
v /= base;
} while (v > 0);
if (neg)
buf[--i] = '-';
len = 64 - i;
return buf + i;
}
static void _itobase2(string& result, large value, int base, int width, char padchar, bool _signed)
{
if (base < 2 || base > 64)
{
clear(result);
return;
}
char buf[65]; // the longest possible string is when base=2
int reslen;
char* p = _itobase(value, buf, base, reslen, _signed);
if (width > reslen)
{
if (padchar == 0)
{
// default pad char
if (base == 10)
padchar = ' ';
else if (base > 36)
padchar = '.';
else
padchar = '0';
}
setlength(result, width);
bool neg = *p == '-';
width -= reslen;
memset(pchar(pconst(result)) + neg, padchar, width);
memcpy(pchar(pconst(result)) + width + neg, p + neg, reslen - neg);
if (neg)
*pchar(pconst(result)) = '-';
}
else
assign(result, p, reslen);
}
string ptdecl itostring(large value, int base, int width, char padchar)
{
string result;
_itobase2(result, value, base, width, padchar, true);
return result;
}
string ptdecl itostring(ularge value, int base, int width, char padchar)
{
string result;
_itobase2(result, value, base, width, padchar, false);
return result;
}
string ptdecl itostring(int value, int base, int width, char padchar)
{
string result;
_itobase2(result, large(value), base, width, padchar, true);
return result;
}
string ptdecl itostring(uint value, int base, int width, char padchar)
{
string result;
_itobase2(result, ularge(value), base, width, padchar, false);
return result;
}
string ptdecl itostring(large v) { return itostring(v, 10, 0, ' '); }
string ptdecl itostring(ularge v) { return itostring(v, 10, 0, ' '); }
string ptdecl itostring(int v) { return itostring(large(v), 10, 0, ' '); }
string ptdecl itostring(uint v) { return itostring(ularge(v), 10, 0, ' '); }
PTYPES_END
src/pstring.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ptypes.h"
#include "ptime.h" // nowstring() is defined in this module
PTYPES_BEGIN
const int strrecsize = sizeof(_strrec);
static void stringoverflow()
{
fatal(CRIT_FIRST + 21, "String overflow");
}
void string::idxerror()
{
fatal(CRIT_FIRST + 20, "String index overflow");
}
int stralloc;
char emptystrbuf[strrecsize + 4];
char* emptystr = emptystrbuf + strrecsize;
string nullstring;
inline int quantize(int numchars)
{
return memquantize(numchars + 1 + strrecsize);
}
void string::_alloc(int numchars)
{
if (numchars <= 0)
stringoverflow();
size_t a = quantize(numchars);
#ifdef DEBUG
stralloc += a;
#endif
data = (char*)(memalloc(a)) + strrecsize;
STR_LENGTH(data) = numchars;
STR_REFCOUNT(data) = 1;
data[numchars] = 0;
}
void string::_realloc(int numchars)
{
if (numchars <= 0 || STR_LENGTH(data) <= 0)
stringoverflow();
int a = quantize(numchars);
int b = quantize(STR_LENGTH(data));
if (a != b)
{
#ifdef DEBUG
stralloc += a - b;
#endif
data = (char*)(memrealloc(data - strrecsize, a)) + strrecsize;
}
STR_LENGTH(data) = numchars;
data[numchars] = 0;
}
inline void _freestrbuf(char* data)
{
#ifdef DEBUG
stralloc -= quantize(STR_LENGTH(data));
#endif
memfree((char*)(STR_BASE(data)));
}
void string::_free()
{
_freestrbuf(data);
data = emptystr;
}
void string::initialize(const char* sc, int initlen)
{
if (initlen <= 0 || sc == nil)
data = emptystr;
else
{
_alloc(initlen);
memmove(data, sc, initlen);
}
}
void string::initialize(const char* sc)
{
initialize(sc, hstrlen(sc));
}
void string::initialize(char c)
{
_alloc(1);
data[0] = c;
}
void string::initialize(const string& s)
{
data = s.data;
#ifdef PTYPES_ST
STR_REFCOUNT(data)++;
#else
pincrement(&STR_REFCOUNT(data));
#endif
}
void string::finalize()
{
if (STR_LENGTH(data) != 0)
{
#ifdef PTYPES_ST
if (--STR_REFCOUNT(data) == 0)
#else
if (pdecrement(&STR_REFCOUNT(data)) == 0)
#endif
_freestrbuf(data);
data = emptystr;
}
}
char* ptdecl unique(string& s)
{
if (STR_LENGTH(s.data) > 0 && STR_REFCOUNT(s.data) > 1)
{
char* odata = s.data;
s._alloc(STR_LENGTH(s.data));
memcpy(s.data, odata, STR_LENGTH(s.data));
#ifdef PTYPES_ST
STR_REFCOUNT(odata)--;
#else
if (pdecrement(&STR_REFCOUNT(odata)) == 0)
_freestrbuf(odata);
#endif
}
return s.data;
}
char* ptdecl setlength(string& s, int newlen)
{
if (newlen < 0)
return nil;
int curlen = STR_LENGTH(s.data);
// if becoming empty
if (newlen == 0)
s.finalize();
// if otherwise s was empty before
else if (curlen == 0)
s._alloc(newlen);
// if length is not changing, return a unique string
else if (newlen == curlen)
unique(s);
// non-unique reallocation
else if (STR_REFCOUNT(s.data) > 1)
{
char* odata = s.data;
s._alloc(newlen);
memcpy(s.data, odata, imin(curlen, newlen));
#ifdef PTYPES_ST
STR_REFCOUNT(odata)--;
#else
if (pdecrement(&STR_REFCOUNT(odata)) == 0)
_freestrbuf(odata);
#endif
}
// unique reallocation
else
s._realloc(newlen);
return s.data;
}
void string::assign(const char* sc, int initlen)
{
if (STR_LENGTH(data) > 0 && initlen > 0 && STR_REFCOUNT(data) == 1)
{
// reuse data buffer if unique
_realloc(initlen);
memmove(data, sc, initlen);
}
else
{
finalize();
if (initlen == 1)
initialize(sc[0]);
else if (initlen > 1)
initialize(sc, initlen);
}
}
void string::assign(const char* sc)
{
assign(sc, hstrlen(sc));
}
void string::assign(char c)
{
assign(&c, 1);
}
void string::assign(const string& s)
{
if (data != s.data)
{
finalize();
initialize(s);
}
}
string ptdecl dup(const string& s)
{
// dup() only reads the data pointer so it is thread-safe
return string(s.data);
}
string ptdecl nowstring(const char* fmt, bool utc)
{
char buf[128];
time_t longtime;
time(&longtime);
#if defined(PTYPES_ST) || defined(WIN32)
tm* t;
if (utc)
t = gmtime(&longtime);
else
t = localtime(&longtime);
int r = strftime(buf, sizeof(buf), fmt, t);
#else
tm t;
if (utc)
gmtime_r(&longtime, &t);
else
localtime_r(&longtime, &t);
int r = strftime(buf, sizeof(buf), fmt, &t);
#endif
buf[r] = 0;
return string(buf);
}
PTYPES_END
src/pstrlist.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
typedef _stritem* pstritem;
void _strlist::sortederror()
{
fatal(CRIT_FIRST + 32, "Operation not allowed on sorted string lists");
}
void _strlist::notsortederror()
{
fatal(CRIT_FIRST + 33, "Search only allowed on sorted string lists");
}
void _strlist::duperror()
{
fatal(CRIT_FIRST + 34, "Duplicate items not allowed in this string list");
}
_strlist::_strlist(int flags)
: tobjlist<_stritem>(true)
{
if ((flags & SL_SORTED) != 0)
config.sorted = 1;
if ((flags & SL_DUPLICATES) != 0)
config.duplicates = 1;
if ((flags & SL_CASESENS) != 0)
config.casesens = 1;
if ((flags & SL_OWNOBJECTS) != 0)
config.ownslobjects = 1;
}
_strlist::~_strlist()
{
}
void _strlist::dofree(void* item)
{
if (config.ownslobjects)
dofreeobj(pstritem(item)->obj);
delete pstritem(item);
}
void _strlist::dofreeobj(void*)
{
fatal(CRIT_FIRST + 38, "strlist::dofree() not defined");
}
int _strlist::compare(const void* key, const void* item) const
{
if (config.casesens)
return strcmp(pconst(key), pstritem(item)->key);
else
return strcasecmp(pconst(key), pstritem(item)->key);
}
void _strlist::doins(int index, const string& key, void* obj)
{
tobjlist<_stritem>::ins(index, new _stritem(key, obj));
}
void _strlist::doput(int index, const string& key, void* obj)
{
if (config.sorted)
sortederror();
_stritem* p = doget(index);
if (config.ownslobjects)
dofreeobj(p->obj);
p->key = key;
p->obj = obj;
}
void _strlist::doput(int index, void* obj)
{
_stritem* p = doget(index);
if (config.ownslobjects)
dofreeobj(p->obj);
p->obj = obj;
}
int _strlist::put(const string& key, void* obj)
{
if (!config.sorted)
notsortederror();
if (config.duplicates)
duperror();
int index;
if (search(key, index))
{
if (obj == nil)
dodel(index);
else
doput(index, obj);
}
else if (obj != nil)
doins(index, key, obj);
return index;
}
int _strlist::add(const string& key, void* obj)
{
int index;
if (config.sorted)
{
if (search(key, index) && !config.duplicates)
duperror();
}
else
index = count;
doins(index, key, obj);
return index;
}
void* _strlist::operator [](const char* key) const
{
if (!config.sorted)
notsortederror();
int index;
if (search(key, index))
return dogetobj(index);
else
return nil;
}
int _strlist::indexof(const char* key) const
{
if (config.sorted)
{
int index;
if (search(key, index))
return index;
}
else
{
for (int i = 0; i < count; i++)
if (compare(key, doget(i)) == 0)
return i;
}
return -1;
}
int _strlist::indexof(void* obj) const
{
for (int i = 0; i < count; i++)
if (pstritem(doget(i))->obj == obj)
return i;
return -1;
}
//
// strmap
//
#ifdef PTYPES19_COMPAT
strlist::strlist(int flags): tstrlist<unknown>(flags) {}
strlist::~strlist() {}
strmap::strmap(int flags)
: tstrlist<unknown>((flags | SL_SORTED) & ~SL_DUPLICATES)
{
}
strmap::~strmap()
{
}
#endif
PTYPES_END
src/pstrmanip.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h> // for INT_MAX
#include "ptypes.h"
PTYPES_BEGIN
void string::initialize(const char* s1, int len1, const char* s2, int len2)
{
if (len1 <= 0)
initialize(s2, len2);
else if (len2 <= 0)
initialize(s1, len1);
else
{
_alloc(len1 + len2);
memcpy(data, s1, len1);
memcpy(data + len1, s2, len2);
}
}
void ptdecl concat(string& s, const char* sc, int catlen)
{
if (length(s) == 0)
s.assign(sc, catlen);
else if (catlen > 0)
{
int oldlen = length(s);
// we must check this before calling setlength(), since
// the buffer pointer may be changed during reallocation
if (s.data == sc)
{
setlength(s, oldlen + catlen);
memmove(s.data + oldlen, s.data, catlen);
}
else
{
setlength(s, oldlen + catlen);
memmove(s.data + oldlen, sc, catlen);
}
}
}
void ptdecl concat(string& s, const char* sc)
{
concat(s, sc, hstrlen(sc));
}
void ptdecl concat(string& s, char c)
{
if (length(s) == 0)
s.assign(c);
else
{
setlength(s, length(s) + 1);
s.data[length(s) - 1] = c;
}
}
void ptdecl concat(string& s, const string& s1)
{
if (length(s) == 0)
s = s1;
else if (length(s1) > 0)
concat(s, s1.data, length(s1));
}
bool ptdecl contains(const char* s1, int s1len, const string& s, int at)
{
return (s1len >= 0) && (at >= 0) && (at + s1len <= length(s))
&& (s1len == 0 || memcmp(s.data + at, s1, s1len) == 0);
}
bool ptdecl contains(const char* s1, const string& s, int at)
{
return contains(s1, hstrlen(s1), s, at);
}
bool ptdecl contains(char s1, const string& s, int at)
{
return (at >= 0) && (at < length(s)) && (s.data[at] == s1);
}
bool ptdecl contains(const string& s1, const string& s, int at)
{
return contains(s1.data, length(s1), s, at);
}
string string::operator+ (const char* sc) const
{
if (length(*this) == 0)
return string(sc);
else
return string(data, length(*this), sc, hstrlen(sc));
}
string string::operator+ (char c) const
{
if (length(*this) == 0)
return string(c);
else
return string(data, length(*this), &c, 1);
}
string string::operator+ (const string& s) const
{
if (length(*this) == 0)
return s;
else if (length(s) == 0)
return *this;
else
return string(data, length(*this), s.data, length(s));
}
string ptdecl operator+ (const char* sc, const string& s)
{
if (length(s) == 0)
return string(sc);
else
return string(sc, hstrlen(sc), s.data, length(s));
}
string ptdecl operator+ (char c, const string& s)
{
if (length(s) == 0)
return string(c);
else
return string(&c, 1, s.data, length(s));
}
bool string::operator== (const string& s) const
{
return (length(*this) == length(s))
&& ((length(*this) == 0) || (memcmp(data, s.data, length(*this)) == 0));
}
bool string::operator== (char c) const
{
return (length(*this) == 1) && (data[0] == c);
}
string ptdecl copy(const string& s, int from, int cnt)
{
string t;
if (length(s) > 0 && from >= 0 && from < length(s))
{
int l = imin(cnt, length(s) - from);
if (from == 0 && l == length(s))
t = s;
else if (l > 0)
{
t._alloc(l);
memmove(t.data, s.data + from, l);
t.data[l] = 0;
}
}
return t;
}
string ptdecl copy(const string& s, int from)
{
return copy(s, from, INT_MAX);
}
void ptdecl ins(const char* s1, int s1len, string& s, int at)
{
int curlen = length(s);
if (s1len > 0 && at >= 0 && at <= curlen)
{
if (curlen == 0)
s.assign(s1, s1len);
else
{
setlength(s, curlen + s1len);
int t = length(s) - at - s1len;
char* p = s.data + at;
if (t > 0)
memmove(p + s1len, p, t);
memmove(p, s1, s1len);
}
}
}
void ptdecl ins(const char* sc, string& s, int at)
{
ins(sc, hstrlen(sc), s, at);
}
void ptdecl ins(char c, string& s, int at)
{
ins(&c, 1, s, at);
}
void ptdecl ins(const string& s1, string& s, int at)
{
ins(s1.data, length(s1), s, at);
}
void ptdecl del(string& s, int from, int cnt)
{
int l = length(s);
int d = l - from;
if (from >= 0 && d > 0 && cnt > 0)
{
if (cnt < d)
{
unique(s);
memmove(s.data + from, s.data + from + cnt, d - cnt);
}
else
cnt = d;
setlength(s, l - cnt);
}
}
void ptdecl del(string& s, int from)
{
setlength(s, from);
}
int ptdecl pos(const char* sc, const string& s)
{
const char* t = (char*)strstr(s.data, sc);
return (t == NULL ? (-1) : (t - s.data));
}
int ptdecl pos(char c, const string& s)
{
const char* t = (char*)strchr(s.data, c);
return (t == NULL ? (-1) : (t - s.data));
}
int ptdecl rpos(char c, const string& s)
{
const char* t = (char*)strrchr(s.data, c);
return (t == NULL ? (-1) : (t - s.data));
}
PTYPES_END
src/pstrtoi.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#include "ptypes.h"
PTYPES_BEGIN
static void throw_conv(const char* p);
static void throw_overflow(const char* p);
large ptdecl stringtoi(const char* p)
{
if (p == 0)
return -1;
if (*p == 0)
return -1;
large r = 0;
do
{
char c = *p++;
if (c < '0' || c > '9')
return -1; // invalid character
large t = r * 10;
if (t < r)
return -1; // overflow
t += c - '0';
if (t < r)
return -1; // overflow
r = t;
} while (*p != 0);
return r;
}
econv::~econv()
{
}
ularge ptdecl stringtoue(const char* str, int base)
{
if (str == 0)
throw_conv(str);
if (*str == 0 || base < 2 || base > 64)
throw_conv(str);
const char* p = str;
ularge result = 0;
do
{
int c = *p++;
if (c >= 'a')
{
// for the numeration bases that use '.', '/', digits and
// uppercase letters the letter case is insignificant.
if (base <= 38)
c -= 'a' - '9' - 1;
else // others use both upper and lower case letters
c -= ('a' - 'Z' - 1) + ('A' - '9' - 1);
}
else if (c > 'Z')
throw_conv(str);
else if (c >= 'A')
c -= 'A' - '9' - 1;
else if (c > '9')
throw_conv(str);
c -= (base > 36) ? '.' : '0';
if (c < 0 || c >= base)
throw_conv(str);
ularge t = result * uint(base);
if (t / base != result)
throw_overflow(str);
result = t;
t = result + uint(c);
if (t < result)
throw_overflow(str);
result = t;
} while (*p != 0);
return result;
}
large ptdecl stringtoie(const char* str)
{
if (str == 0)
throw_conv(str);
bool neg = *str == '-';
ularge result = stringtoue(str + int(neg), 10);
if (result > (ularge(LARGE_MAX) + uint(neg)))
throw_overflow(str);
if (neg)
return - large(result);
else
return large(result);
}
#ifdef _MSC_VER
// disable "unreachable code" warning for throw (known compiler bug)
# pragma warning (disable: 4702)
#endif
static void throw_conv(const char* p)
{
throw new econv("Invalid number: '" + string(p) + '\'');
}
static void throw_overflow(const char* p)
{
throw new econv("Out of range: '" + string(p) + '\'');
}
PTYPES_END
src/pstrutils.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <string.h>
#include "ptypes.h"
PTYPES_BEGIN
string ptdecl fill(int width, char pad)
{
string res;
if (width > 0) {
setlength(res, width);
memset(pchar(pconst(res)), pad, length(res));
}
return res;
}
string ptdecl pad(const string& s, int width, char c, bool left)
{
int len = length(s);
if (len < width && width > 0)
{
string res;
setlength(res, width);
if (left)
{
if (len > 0)
memcpy(pchar(pconst(res)), pconst(s), len);
memset(pchar(pconst(res)) + len, c, width - len);
}
else
{
memset(pchar(pconst(res)), c, width - len);
if (len > 0)
memcpy(pchar(pconst(res)) + width - len, pconst(s), len);
}
return res;
}
else
return s;
}
PTYPES_END
src/ptextmap.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
typedef _textitem* ptextitem;
textmap::textmap(bool casesens)
: tobjlist<_textitem>(true)
{
config.sorted = true;
config.casesens = casesens;
}
textmap::~textmap()
{
}
int textmap::compare(const void* key, const void* item) const
{
if (config.casesens)
return strcmp(pconst(key), ptextitem(item)->key);
else
return strcasecmp(pconst(key), ptextitem(item)->key);
}
const string& textmap::get(const char* key) const
{
int index;
if (search(key, index))
return dogetvalue(index);
else
return nullstring;
}
int textmap::put(const string& key, const string& value)
{
int index;
if (search(pconst(key), index))
{
if (isempty(value))
dodel(index);
else
doget(index)->value = value;
}
else if (!isempty(value))
doins(index, new _textitem(key, value));
return index;
}
int textmap::indexof(const char* key) const
{
int index;
if (search(key, index))
return index;
else
return -1;
}
PTYPES_END
src/pthread.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <process.h>
#else
# include <pthread.h>
#endif
#include "pasync.h"
PTYPES_BEGIN
thread::thread(bool iautofree)
:
#ifdef WIN32
id(0),
#endif
handle(0), autofree(iautofree),
running(0), signaled(0), finished(0), freed(0),
reserved(0), relaxsem(0)
{
}
thread::~thread()
{
if (pexchange(&freed, 1) != 0)
return;
#ifdef WIN32
if (autofree)
// MSDN states this is not necessary, however, without closing
// the handle debuggers show an obvious handle leak here
CloseHandle(handle);
#else
// though we require non-autofree threads to always call waitfor(),
// the statement below is provided to cleanup thread resources even
// if waitfor() was not called.
if (!autofree && running)
pthread_detach(handle);
#endif
}
void thread::signal()
{
if (pexchange(&signaled, 1) == 0)
relaxsem.post();
}
void thread::waitfor()
{
if (pexchange(&freed, 1) != 0)
return;
if (pthrequal(get_id()))
fatal(CRIT_FIRST + 47, "Can not waitfor() on myself");
if (autofree)
fatal(CRIT_FIRST + 48, "Can not waitfor() on an autofree thread");
#ifdef WIN32
WaitForSingleObject(handle, INFINITE);
CloseHandle(handle);
#else
pthread_join(handle, nil);
// detaching after 'join' is not required (or even do harm on some systems)
// except for HPUX. we don't support HPUX yet.
// pthread_detach(handle);
#endif
handle = 0;
}
#ifdef WIN32
unsigned _stdcall _threadproc(void* arg)
{
#else
void* _threadproc(void* arg)
{
#endif
thread* thr = (thread*)arg;
#ifndef WIN32
if (thr->autofree)
// start() does not assign the handle for autofree threads
thr->handle = pthread_self();
#endif
try
{
thr->execute();
}
catch(exception*)
{
_threadepilog(thr);
throw;
}
_threadepilog(thr);
return 0;
}
void _threadepilog(thread* thr)
{
try
{
thr->cleanup();
}
catch(exception* e)
{
delete e;
}
pexchange(&thr->finished, 1);
if (thr->autofree)
delete thr;
}
void thread::start()
{
if (pexchange(&running, 1) == 0)
{
#ifdef WIN32
handle = (HANDLE)_beginthreadex(nil, 0, _threadproc, this, 0, &id);
if (handle == 0)
fatal(CRIT_FIRST + 40, "CreateThread() failed");
#else
pthread_t temp_handle;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
autofree ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE);
if (pthread_create(autofree ? &temp_handle : &handle,
&attr, _threadproc, this) != 0)
fatal(CRIT_FIRST + 40, "pthread_create() failed");
pthread_attr_destroy(&attr);
#endif
}
}
void thread::cleanup()
{
}
PTYPES_END
src/ptime.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
// altzone fix for Sun/GCC 3.2. any better ideas?
#if defined(__sun__) && defined(__GNUC__) && defined(_XOPEN_SOURCE)
# undef _XOPEN_SOURCE
#endif
#ifdef WIN32
# include <windows.h>
#else
# include <sys/time.h>
#endif
#include <time.h>
#include <string.h>
#include "ptime.h"
PTYPES_BEGIN
datetime ptdecl mkdt(int days, int msecs)
{
return large(days) * _msecsmax + msecs;
}
bool ptdecl isvalid(datetime d)
{
return d >= 0 && d < _datetimemax;
}
bool ptdecl isleapyear(int year)
{
return year > 0 && year % 4 == 0
&& (year % 100 != 0 || year % 400 == 0);
}
int ptdecl daysinmonth(int year, int month)
{
if (month < 1 || month > 12)
return 0;
static const int mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int res = mdays[month - 1];
if (month == 2)
if (isleapyear(year))
res++;
return res;
}
int ptdecl daysinyear(int year, int month)
{
if (month < 1 || month > 12)
return 0;
static const int ndays[12] = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int res = ndays[month - 1];
if (month > 1)
if (isleapyear(year))
res++;
return res;
}
int ptdecl dayofweek(datetime d)
{
return (days(d) + 1) % 7;
}
bool ptdecl isdatevalid(int year, int month, int day)
{
return year >= 1 && year <= 9999
&& month >= 1 && month <= 12
&& day >= 1 && day <= daysinmonth(year, month);
}
datetime ptdecl encodedate(int year, int month, int day)
{
if (!isdatevalid(year, month, day))
return invdatetime;
int y = year - 1;
return mkdt(day // days in this month
+ daysinyear(year, month - 1) // plus days since the beginning of the year
+ y * 365 // plus "pure" days
+ y / 4 - y / 100 + y / 400 // plus leap year correction
- 1, 0); // ... minus one (guess why :)
}
bool ptdecl decodedate(datetime date, int& year, int& month, int& day)
{
int d = days(date);
if (d < 0 || d >= _daysmax) // allowed date range is 01/01/0001 - 12/31/9999
{
year = 0;
month = 0;
day = 0;
return false;
}
const int d1 = 365; // number of days in 1 year
const int d4 = d1 * 4 + 1; // ... in 4 year period
const int d100 = d4 * 25 - 1; // ... in 100 year period
const int d400 = d100 * 4 + 1; // ... in 400 year period
year = (d / d400) * 400 + 1;
d %= d400;
int t = d / d100;
d %= d100;
if (t == 4)
{
t--;
d += d100;
}
year += t * 100;
year += (d / d4) * 4;
d %= d4;
t = d / d1;
d %= d1;
if (t == 4)
{
t--;
d += d1;
}
year += t;
month = d / 29; // approximate month no. (to avoid loops)
if (d < daysinyear(year, month)) // month no. correction
month--;
day = d - daysinyear(year, month) + 1;
month++;
return true;
}
bool ptdecl istimevalid(int hour, int min, int sec, int msec)
{
return hour >= 0 && hour < 24
&& min >= 0 && min < 60
&& sec >= 0 && sec < 60
&& msec >= 0 && msec < 1000;
}
datetime ptdecl encodetime(int hour, int min, int sec, int msec)
{
large res = large(hour) * 3600000 + large(min) * 60000 + large(sec) * 1000 + msec;
if (!isvalid(res))
res = invdatetime;
return res;
}
bool ptdecl decodetime(datetime t, int& hour, int& min, int& sec, int& msec)
{
if (!isvalid(t))
{
hour = 0;
min = 0;
sec = 0;
msec = 0;
return false;
}
int m = msecs(t);
hour = m / 3600000;
m %= 3600000;
min = m / 60000;
m %= 60000;
sec = m / 1000;
msec = m % 1000;
return true;
}
bool ptdecl decodetime(datetime t, int& hour, int& min, int& sec)
{
int msec;
return decodetime(t, hour, min, sec, msec);
}
tm* ptdecl dttotm(datetime dt, tm& t)
{
memset(&t, 0, sizeof(tm));
if (!decodedate(dt, t.tm_year, t.tm_mon, t.tm_mday)
|| !decodetime(dt, t.tm_hour, t.tm_min, t.tm_sec))
return nil;
t.tm_mon--;
t.tm_yday = daysinyear(t.tm_year, t.tm_mon) + t.tm_mday - 1;
t.tm_wday = dayofweek(dt);
t.tm_year -= 1900;
return &t;
}
string ptdecl dttostring(datetime dt, const char* fmt)
{
char buf[128];
tm t;
int r = strftime(buf, sizeof(buf), fmt, dttotm(dt, t));
buf[r] = 0;
return string(buf);
}
datetime ptdecl now(bool utc)
{
#ifdef WIN32
SYSTEMTIME t;
if (utc)
GetSystemTime(&t);
else
GetLocalTime(&t);
return encodedate(t.wYear, t.wMonth, t.wDay) +
encodetime(t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
#else // Unix
// we can't use localtime() and gmtime() here as they don't return
// milliseconds which are needed for our datetime format. instead,
// we call gettimeofday() which have microsecond precision, and then
// adjust the time according to timzone info returned by localtime()
// on BSD and Linux, and global variables altzone/timezone on SunOS.
// NOTE: at the moment of passing the DST adjustment (twice a year)
// the local time value returned by now() may be incorrect.
// the application should call tzupdate() from time to time if it
// is supposed to be running infinitely, e.g. if it's a daemon.
// always rely on UTC time inside your application whenever possible.
timeval tv;
gettimeofday(&tv, nil);
int edays = tv.tv_sec / 86400 // days since Unix "Epoch", i.e. 01/01/1970
+ 719162; // plus days between 01/01/0001 and Unix Epoch
int esecs = tv.tv_sec % 86400; // the remainder, i.e. seconds since midnight
datetime res = mkdt(edays, esecs * 1000 + tv.tv_usec / 1000);
if (!utc)
res += tzoffset() * 60 * 1000;
return res;
#endif
}
void ptdecl tzupdate()
{
tzset();
}
int ptdecl tzoffset()
{
#if defined(WIN32)
TIME_ZONE_INFORMATION tz;
DWORD res = GetTimeZoneInformation(&tz);
if ((res == TIME_ZONE_ID_DAYLIGHT) && (tz.DaylightDate.wMonth != 0))
return - (tz.Bias + tz.DaylightBias);
else
return - tz.Bias;
#else // UNIX
time_t t0 = time(0);
#if defined(__sun__)
#ifdef PTYPES_ST
// localtime_r() is not available without -D_REENTRANT
tm* t = localtime(&t0);
if(t->tm_isdst != 0 && daylight != 0)
#else
tm t;
localtime_r(&t0, &t);
if(t.tm_isdst != 0 && daylight != 0)
#endif
return - altzone / 60;
else
return - timezone / 60;
#elif defined(__CYGWIN__)
time_t local_time = time(NULL);
tm gt;
gmtime_r(&local_time, &gt);
time_t gmt_time = mktime(&gt);
return (local_time - gmt_time) / 60;
#elif defined(__hpux)
tm local;
localtime_r(&t0, &local);
local.tm_isdst = 0;
time_t t1 = mktime(&local);
return - (timezone - (t1 - t0)) / 60;
#else // other UNIX
tm t;
localtime_r(&t0, &t);
return t.tm_gmtoff / 60;
#endif
#endif
}
datetime ptdecl utodatetime(time_t u)
{
return _unixepoch + large(u) * 1000;
}
PTYPES_END
src/ptimedsem.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <pthread.h>
# include <errno.h>
#endif
#include "pasync.h"
PTYPES_BEGIN
static void tsem_fail()
{
fatal(CRIT_FIRST + 41, "Timed semaphore failed");
}
#ifdef WIN32
timedsem::timedsem(int initvalue)
{
handle = CreateSemaphore(nil, initvalue, 65535, nil);
if (handle == 0)
tsem_fail();
}
timedsem::~timedsem()
{
CloseHandle(handle);
}
bool timedsem::wait(int timeout)
{
uint r = WaitForSingleObject(handle, timeout);
if (r == WAIT_FAILED)
tsem_fail();
return r != WAIT_TIMEOUT;
}
void timedsem::post()
{
if (ReleaseSemaphore(handle, 1, nil) == 0)
tsem_fail();
}
#else
inline void tsem_syscheck(int r)
{
if (r != 0)
tsem_fail();
}
timedsem::timedsem(int initvalue)
: unknown(), count(initvalue)
{
tsem_syscheck(pthread_mutex_init(&mtx, 0));
tsem_syscheck(pthread_cond_init(&cond, 0));
}
timedsem::~timedsem()
{
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mtx);
}
bool timedsem::wait(int timeout)
{
pthread_mutex_lock(&mtx);
while (count <= 0)
{
if (timeout >= 0)
{
timespec abs_ts;
timeval cur_tv;
gettimeofday(&cur_tv, NULL);
abs_ts.tv_sec = cur_tv.tv_sec + timeout / 1000;
abs_ts.tv_nsec = cur_tv.tv_usec * 1000
+ (timeout % 1000) * 1000000;
int rc = pthread_cond_timedwait(&cond, &mtx, &abs_ts);
if (rc == ETIMEDOUT) {
pthread_mutex_unlock(&mtx);
return false;
}
}
else
pthread_cond_wait(&cond, &mtx);
}
count--;
pthread_mutex_unlock(&mtx);
return true;
}
void timedsem::post()
{
pthread_mutex_lock(&mtx);
count++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx);
}
#endif
PTYPES_END
src/ptrigger.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifdef WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <pthread.h>
# include <errno.h>
#endif
#include "pasync.h"
PTYPES_BEGIN
static void trig_fail()
{
fatal(CRIT_FIRST + 41, "Trigger failed");
}
#ifdef WIN32
trigger::trigger(bool autoreset, bool state)
{
handle = CreateEvent(0, !autoreset, state, 0);
if (handle == 0)
trig_fail();
}
#else
inline void trig_syscheck(int r)
{
if (r != 0)
trig_fail();
}
trigger::trigger(bool iautoreset, bool istate)
: state(int(istate)), autoreset(iautoreset)
{
trig_syscheck(pthread_mutex_init(&mtx, 0));
trig_syscheck(pthread_cond_init(&cond, 0));
}
trigger::~trigger()
{
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mtx);
}
void trigger::wait()
{
pthread_mutex_lock(&mtx);
while (state == 0)
pthread_cond_wait(&cond, &mtx);
if (autoreset)
state = 0;
pthread_mutex_unlock(&mtx);
}
void trigger::post()
{
pthread_mutex_lock(&mtx);
state = 1;
if (autoreset)
pthread_cond_signal(&cond);
else
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mtx);
}
void trigger::reset()
{
state = 0;
}
#endif
PTYPES_END
src/ptypes_test.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "pport.h"
#include "ptypes.h"
#include "pstreams.h"
#include "pinet.h"
#include "ptime.h"
#ifndef PTYPES_ST
#include "pasync.h"
#endif
USING_PTYPES
void passert(bool cond)
{
if (!cond)
{
fatal(0xa3, "*** ASSERTION FAILED ***");
}
}
void showstr(const char* shouldbe, const char* is)
{
passert(strcmp(shouldbe, is) == 0);
pout.putf("[%s] %s\n", shouldbe, is);
}
void showstr(const char* shouldbe, const string& is)
{
showstr(shouldbe, pconst(is));
}
void showhex(const char* shouldbe, const char* is, int islen)
{
string s;
int i;
for (i = 0; i < islen; i++)
s += itostring((unsigned char)is[i], 16, 2);
s = lowercase(s);
showstr(shouldbe, s);
}
void showint(int shouldbe, int is)
{
passert(shouldbe == is);
pout.putf("[%d] %d\n", shouldbe, is);
}
void showint(large shouldbe, large is)
{
passert(shouldbe == is);
pout.putf("[%lld] %lld\n", shouldbe, is);
}
void showchar(char shouldbe, char is)
{
passert(shouldbe == is);
pout.putf("[%c] %c\n", shouldbe, is);
}
//
// string test
//
void const_string_call(const string& s)
{
showchar('R', s[2]);
}
void string_test1()
{
pout.put("\n--- STRING CLASS\n");
static char strbuf[10] = "STRING";
char c = 'A';
string s1 = "string";
s1 = s1;
s1 += s1;
del(s1, 6, 6);
string s2 = s1;
string s3;
string s4(strbuf, strlen(strbuf));
string s5 = 'A';
string s6 = c;
showstr("string", s1);
showstr(s1, s2);
showstr("", s3);
showstr("STRING", s4);
const_string_call(s4);
showchar('I', s4[3]);
showint(6, length(s4));
showint(2, refcount(s1));
clear(s2);
showint(1, refcount(s1));
s2 = s1;
unique(s1);
showint(1, refcount(s1));
setlength(s1, 64);
string s7 = s1;
setlength(s1, 3);
showstr("str", s1);
showstr("strING", s1 += copy(s4, 3, 3));
del(s1, 3, 3);
showstr("str", s1);
ins("ing", s1, 0);
showstr("ingstr", s1);
s2 = "str" + s1 + "ing";
showstr("stringstring", s2);
s3 = s2;
s3 = "strungstrung";
s3 = s2;
s3 = "strung";
del(s3, 4);
showstr("stru", s3);
s2 = "str" + s1;
s2 = s1 + "str";
s2 += "str";
s2 = 's' + s1;
s2 = s1 + 's';
s2 += 's';
s2 = c + s1;
s2 = s1 + c;
s2 += c;
s2 = 'a';
s2 = c;
}
void string_test2()
{
pout.put("\n--- STRING CLASS\n");
string s1 = "ingstr";
string s2 = "stringstring";
string s4 = "STRING";
showint(1, pos('t', s2));
showint(2, pos("ri", s2));
showint(3, pos(s1, s2));
showint(1, contains("tr", s2, 1));
showint(0, contains("tr", s2, 2));
showint(1, s4 == "STRING");
showint(1, "STRING" == s4);
showchar('R', s4[2]);
string s5 = 'A';
showint(1, s5 == 'A');
showint(1, 'A' == s5);
showstr("123456789", itostring(123456789));
showstr("123", itostring(char(123)));
showstr("-000123", itostring(-123, 10, 7, '0'));
showstr("0ABCDE", itostring(0xabcde, 16, 6));
showstr("-9223372036854775808", itostring(LARGE_MIN));
showstr("18446744073709551615", itostring(ULARGE_MAX));
showint(1234, (int)stringtoi("1234"));
showint(large(0x15AF), stringtoue("15AF", 16));
showint(LARGE_MAX, stringtoue("5zzzzzzzzzz", 64));
try
{
// out of range by 1
stringtoue("18446744073709551616", 10);
fatal(0xb0, "Conversion overflow not detected");
}
catch (econv* e)
{
showstr("Out of range: '18446744073709551616'", e->get_message());
delete e;
}
showint(large(123), stringtoie("123"));
showint(large(-123), stringtoie("-123"));
showint(LARGE_MIN, stringtoie("-9223372036854775808"));
showint(LARGE_MAX, stringtoie("9223372036854775807"));
try
{
// out of range by 1
stringtoie("9223372036854775808");
fatal(0xb0, "Conversion overflow not detected");
}
catch (econv* e)
{
showstr("Out of range: '9223372036854775808'", e->get_message());
delete e;
}
showstr("abcabc", lowercase(s1 = "aBCAbc"));
showstr("abcabc", lowercase(s1));
}
void string_benchmarks()
{
pout.put("\n--- STRING BENCHMARKS\n");
int i;
string s1 = "string";
string s2;
// for the first time we run the test to let the VM settle down and stop swapping
for (i = 0; i < 156000; i++)
s2 += s1;
// here is the actual test
clear(s2);
datetime start = now();
for (i = 0; i < 156000; i++)
s2 += s1;
datetime diff = now() - start;
pout.putf("Performance index compared to WinNT on P3/800MHz (smaller = better):\n%.3f\n", diff / 1000.0);
}
//
// cset test
//
void cset_test()
{
pout.put("\n--- CSET CLASS\n");
cset s1 = "~09~0a~0d~F0 A-Z~~";
cset s2 = "A-F";
char c = 'B';
showstr("~09~0a~0d A-Z~~~f0", asstring(s1));
s1 -= char(0xf0);
s1 -= cset("~00-~20");
showstr("A-Z~~", asstring(s1));
s1 -= s2;
showstr("G-Z~~", asstring(s1));
s1 += s2;
s1 += ' ';
showstr(" A-Z~~", asstring(s1));
showint(1, s2 == cset("A-F"));
showint(1, s2 <= s1);
s1 -= 'A';
s1 -= c;
showint(0, s2 <= s1);
s1 = s1 + char(0xf1);
showint(1, char(0xf1) & s1);
showint(0, char(0xf2) & s1);
}
//
// podlist
//
void const_podlist_test(const tpodlist<int, true>& p)
{
// int& i = p[0];
showint(7, p[1]);
}
void podlist_test()
{
pout.put("\n--- PODLIST\n");
tpodlist<int, true> p;
p.add() = 6;
p.add(8);
p.ins(1, 7);
showint(7, p[1]);
const_podlist_test(p);
showint(3, p.get_count());
p.set_count(5);
p.ins(5) = 10;
showint(10, p.top());
p.pop();
tpodlist<int, true> p1;
p1.add(p);
p1.pop();
p1.add(p);
}
//
// ptrlist
//
struct known: public unknown
{
int value;
known(int ivalue): value(ivalue) {}
};
typedef tobjlist<known> knownlist;
string ol_asstring(const knownlist& s)
{
string ret = "{";
for (int i = 0; i < s.get_count(); i++) {
if (i > 0)
concat(ret, ", ");
ret += itostring(s[i]->value);
}
concat(ret, '}');
return ret;
}
void ptrlist_test()
{
pout.put("\n--- PTRLIST\n");
knownlist s1(true);
known* obj;
s1.add(new known(10));
s1.ins(0, new known(5));
s1.ins(2, obj = new known(20));
s1.add(new known(30));
s1.add(new known(40));
s1.put(4, new known(45));
s1.del(4);
s1.del(1);
s1[0];
showint(3, s1.get_count());
showint(1, s1.indexof(obj));
showstr("{5, 20, 30}", ol_asstring(s1));
s1.clear();
showstr("{}", ol_asstring(s1));
}
//
// strlist
//
typedef tstrlist<known> knownstrlist;
string sl_asstring(const knownstrlist& s)
{
string ret = "{";
for (int i = 0; i < s.get_count(); i++)
{
if (i > 0)
concat(ret, ", ");
ret += s.getkey(i) + ":" + itostring(s[i]->value);
}
concat(ret, '}');
return ret;
}
void strlist_test()
{
pout.put("\n--- STRLIST\n");
knownstrlist s1(SL_OWNOBJECTS);
known* obj;
s1.add("ten", new known(10));
s1.ins(0, "five", new known(5));
s1.ins(2, "twenty", obj = new known(20));
s1.add("thirty", new known(30));
s1.add("forty", new known(40));
s1.put(4, "forty five", new known(45));
s1.del(4);
s1.del(1);
showint(3, s1.get_count());
showint(1, s1.indexof(obj));
showint(2, s1.indexof("thirty"));
showint(2, s1.indexof("THIRTY"));
showint(-1, s1.indexof("forty"));
showstr("{five:5, twenty:20, thirty:30}", sl_asstring(s1));
knownstrlist s2(SL_OWNOBJECTS | SL_SORTED | SL_CASESENS);
s2.add("five", new known(5));
s2.add("ten", new known(10));
s2.add("twenty", new known(20));
s2.add("thirty", new known(30));
s2.add("forty", new known(40));
showint(5, s2.get_count());
showint(3, s2.indexof("thirty"));
showint(-1, s2.indexof("THIRTY"));
showint(-1, s2.indexof("hovik"));
showstr("{five:5, forty:40, ten:10, thirty:30, twenty:20}", sl_asstring(s2));
s2.clear();
showstr("{}", sl_asstring(s2));
tstrlist<known> s3(SL_OWNOBJECTS | SL_SORTED | SL_DUPLICATES);
s3.add("a", nil);
s3.add("b", nil);
s3.add("b", nil);
s3.add("b", nil);
s3.add("b", nil);
s3.add("b", nil);
s3.add("b", nil);
s3.add("c", nil);
showint(1, s3.indexof("b"));
s3.del(1, 2);
tstrlist<known> s(SL_OWNOBJECTS | SL_SORTED);
s.put("five", new known(5));
s.put("ten", new known(10));
s.put("twenty", new known(20));
s.put("thirty", new known(30));
s.put("forty", new known(40));
showint(20, s["twenty"]->value);
showint(0, pintptr(s["hovik"]));
showint(5, s.get_count());
s.put("twenty", nil);
showint(4, s.get_count());
}
//
// textmap
//
void textmap_test()
{
pout.put("\n--- TEXTMAP CLASS\n");
textmap c;
c.put("name1", "value1");
c.put("name2", "value2");
c.put("name1", "value3");
showstr("name2", c.getkey(1));
c.put("name2", "");
showint(1, c.get_count());
showstr("value3", c["name1"]);
showstr("", c["name2"]);
}
//
// streams
//
char buf1[] = "This is a test.";
char buf2[] = "The file should contain readable text.";
const char* fname = "stmtest.txt";
void outfile_test()
{
pout.put("\n--- OUTFILE CLASS\n");
showint(8, sizeof(off_t));
outfile f(fname, false);
f.set_umode(0600);
f.set_bufsize(3);
f.open();
f.put(buf1[0]);
f.put(buf1[1]);
f.put("is is a TEST.");
f.seek(-5, IO_END);
f.put("tes*/");
f.seek(13);
f.put("t.");
f.puteol();
f.close();
f.set_append(true);
f.open();
f.write(buf2, strlen(buf2));
f.puteol();
f.close();
pnull.put("This should go to nowhere I");
pnull.put("This should go to nowhere II");
}
void infile_test()
{
pout.put("\n--- INFILE CLASS\n");
compref<instm> f = &pin;
f = new infile(fname);
f->set_bufsize(3);
char temp[4];
f->open();
pout.putf("%c", f->get());
pout.putf("%s\n", pconst(f->line()));
f->read(temp, sizeof temp - 1);
temp[sizeof temp - 1] = 0;
pout.putf("%s", temp);
f->get();
f->putback();
pout.putf("%s", pconst(f->token(cset("~20-~FF"))));
f->preview();
if (f->get_eol())
{
f->skipline();
pout.put("\n");
}
if (f->get_eof())
pout.put("EOF\n");
// f.error(1, "Test error message");
}
void mem_test()
{
pout.put("\n--- OUT/IN MEMORY CLASS\n");
{
outmemory m(12);
m.open();
m.put("MEMOry");
m.put(" c");
m.put("lass is working");
m.seek(1);
m.put("emo");
showstr("Memory class", m.get_strdata());
// try reuse
m.open();
m.put("memory");
showstr("memory", m.get_strdata());
}
{
inmemory m("");
m.open();
showstr("", m.token("*"));
m.set_strdata("gArbaGe");
m.open();
// try reuse
m.set_strdata("string strong");
m.set_bufsize(2); // has no effect
m.open();
showstr("string", m.token("a-z"));
m.seek(-6, IO_END);
showstr("strong", m.token("a-z"));
}
}
#ifndef PTYPES_ST
//
// multithreading
//
//
// rwlock test
//
const int rw_max_threads = 30;
const int rw_max_tries = 30;
const int rw_max_delay = 20;
const int rw_rw_ratio = 5;
const bool rw_swap = false;
class rwthread: public thread
{
protected:
virtual void execute();
public:
rwthread(): thread(false) {}
virtual ~rwthread() { waitfor(); }
};
rwlock rw;
int reader_cnt = 0;
int writer_cnt = 0;
int total_writers = 0;
int total_readers = 0;
int max_readers = 0;
int prand(int max)
{
return rand() % max;
}
void rwthread::execute()
{
for(int i = 0; i < rw_max_tries; i++)
{
psleep(prand(rw_max_delay));
bool writer = prand(rw_rw_ratio) == 0;
if (writer ^ rw_swap)
{
rw.wrlock();
pout.put('w');
if (pincrement(&writer_cnt) > 1)
fatal(0xa0, "Writer: Huh?! Writers in here?");
pincrement(&total_writers);
}
else
{
rw.rdlock();
pout.put('.');
int t;
if ((t = pincrement(&reader_cnt)) > max_readers)
max_readers = t;
if (writer_cnt > 0)
fatal(0xa1, "Reader: Huh?! Writers in here?");
pincrement(&total_readers);
}
psleep(prand(rw_max_delay));
if (writer ^ rw_swap)
pdecrement(&writer_cnt);
else
pdecrement(&reader_cnt);
rw.unlock();
}
}
void rwlock_test()
{
// #ifdef __PTYPES_RWLOCK__
pout.put("\n--- RWLOCK\n");
rwthread* threads[rw_max_threads];
srand((unsigned)time(0));
int i;
for(i = 0; i < rw_max_threads; i++)
{
threads[i] = new rwthread();
threads[i]->start();
}
for(i = 0; i < rw_max_threads; i++)
delete threads[i];
pout.putf("\nmax readers: %d\n", max_readers);
pout.putline("do writers 'starve'?");
// #endif
}
//
// jobqueue test ----------------------------------------------------------
//
const int MSG_MYJOB = MSG_USER + 1;
const int NUM_JOB_THREADS = 3;
class jobthread: public thread
{
protected:
int id;
jobqueue* jq;
virtual void execute();
public:
jobthread(int iid, jobqueue* ijq): thread(false), id(iid), jq(ijq) {}
~jobthread() { waitfor(); }
};
void jobthread::execute()
{
bool quit = false;
while (!quit)
{
message* m = jq->getmessage();
try
{
switch (m->id)
{
case MSG_MYJOB:
// ... do the job ...
psleep(prand(10));
// report
pout.putf("Thread %d finished the job (param=%d)\n", id, m->param);
break;
case MSG_QUIT:
quit = true;
break;
}
}
catch(...)
{
// the message object must be freed!
delete m;
throw;
}
delete m;
}
}
void jobqueue_test()
{
pout.put("\n--- JOBQUEUE\n");
jobqueue jq(3);
tobjlist<jobthread> threads(true);
srand((unsigned)time(0));
// create the thread pool and start all threads
int i;
for(i = 0; i < NUM_JOB_THREADS; i++)
{
jobthread* j = new jobthread(i + 1, &jq);
j->start();
threads.add(j);
}
// post jobs for processing
jq.post(MSG_MYJOB, 1);
jq.post(MSG_MYJOB, 2);
jq.post(MSG_MYJOB, 3);
jq.post(MSG_MYJOB, 4);
jq.post(MSG_MYJOB, 5);
jq.post(MSG_MYJOB, 6);
jq.post(MSG_MYJOB, 7);
jq.post(MSG_MYJOB, 8);
// terminate all threads
for(i = 0; i < NUM_JOB_THREADS; i++)
jq.post(MSG_QUIT);
// threads are being waitfor()'ed and destroyed
// automatically by the list object
}
//
// msgqueue test ----------------------------------------------------------
//
const int MSG_DIAG = MSG_USER + 1;
//
// msgqueue test
//
//
// class diagmessage
//
class diagmessage: public message
{
protected:
string module;
string diagstr;
friend class diagthread;
public:
diagmessage(string imodule, string idiagstr)
: message(MSG_DIAG), module(imodule),
diagstr(idiagstr) {}
};
//
// class diagthread
//
class diagthread: public thread, protected msgqueue
{
protected:
virtual void execute(); // override thread::execute()
virtual void cleanup(); // override thread::cleanup()
virtual void msghandler(message& msg); // override msgqueue::msghandler()
public:
diagthread(): thread(false), msgqueue() { }
void postdiag(string module, string diagstr);
void postquit();
};
void diagthread::postdiag(string module, string diagstr)
{
msgqueue::post(new diagmessage(module, diagstr));
}
void diagthread::postquit()
{
msgqueue::post(MSG_QUIT);
}
void diagthread::execute()
{
// starts message queue processing; calls
// msghandler for each message
msgqueue::run();
}
void diagthread::cleanup()
{
}
void diagthread::msghandler(message& msg)
{
switch (msg.id)
{
case MSG_DIAG:
{
diagmessage& m = (diagmessage&)msg;
pout.putf("%s: %s\n", pconst(m.module), pconst(m.diagstr));
}
break;
default:
defhandler(msg);
}
}
//
// class testthread
//
class testthread: public thread
{
protected:
diagthread* diag;
string myname;
virtual void execute();
virtual void cleanup();
public:
semaphore sem;
timedsem tsem;
testthread(diagthread* idiag)
: thread(false), diag(idiag), myname("testthread"), sem(0), tsem(0) {}
};
void testthread::execute()
{
diag->postdiag(myname, "starts and enters sleep for 1 second");
psleep(1000);
diag->postdiag(myname, "signals the timed semaphore");
tsem.post();
diag->postdiag(myname, "releases the simple semaphore");
sem.post();
diag->postdiag(myname, "enters sleep for 1 more second");
psleep(1000);
}
void testthread::cleanup()
{
diag->postdiag(myname, "terminates");
}
int thread_test()
{
pout.put("\n--- THREAD AND SEMAPHORE CLASSES\n");
int v = 0;
showint(0, pexchange(&v, 5));
showint(5, pexchange(&v, 10));
void* pv = 0;
passert(pexchange(&pv, &v) == 0);
passert(pexchange(&pv, 0) == &v);
showint(11, pincrement(&v));
showint(10, pdecrement(&v));
diagthread diag;
testthread thr(&diag);
string myname = "main";
diag.start();
thr.start();
diag.postdiag(myname, "waits 5 secs for the timed semaphore (actually wakes up after a second)");
thr.tsem.wait(5000); // must exit after 1 second instead of 5
diag.postdiag(myname, "waits for the semaphore");
thr.sem.wait();
diag.postdiag(myname, "now waits for testthread to terminate");
thr.waitfor();
diag.postquit();
diag.waitfor();
return 0;
}
//
// trigger test
//
class trigthread: public thread
{
protected:
diagthread* diag;
string myname;
virtual void execute();
public:
trigger trig;
trigthread(diagthread* idiag)
: thread(false), diag(idiag), myname("trigthread"), trig(true, false) {}
virtual ~trigthread() { waitfor(); }
};
void trigthread::execute()
{
diag->postdiag(myname, "waits on the trigger");
trig.wait();
psleep(2000);
diag->postdiag(myname, "waits on the trigger");
trig.wait();
diag->postdiag(myname, "terminates");
}
int trigger_test()
{
pout.put("\n--- TRIGGER\n");
diagthread diag;
trigthread thr(&diag);
string myname = "main";
diag.start();
thr.start();
psleep(1000);
diag.postdiag(myname, "posts the trigger");
thr.trig.post();
psleep(1000);
diag.postdiag(myname, "posts the trigger again");
thr.trig.post();
thr.waitfor();
diag.postquit();
diag.waitfor();
return 0;
}
#endif // PTYPES_ST
//
// md5 test
//
static md5_digest digest;
char* md5str(string data)
{
outmd5 m;
m.open();
m.put(data);
memcpy(digest, m.get_bindigest(), sizeof(md5_digest));
return (char*)digest;
}
string cryptpw(string username, string password)
{
outmd5 m;
m.open();
m.put(username);
m.put(password);
m.close();
return m.get_digest();
}
void md5_test()
{
pout.put("\n--- MD5 OUTPUT STREAM\n");
// MD5 test suite from RFC1321
showhex("d41d8cd98f00b204e9800998ecf8427e", md5str(""), md5_digsize);
showhex("0cc175b9c0f1b6a831c399e269772661", md5str("a"), md5_digsize);
showhex("900150983cd24fb0d6963f7d28e17f72", md5str("abc"), md5_digsize);
showhex("f96b697d7cb7938d525a2f31aaf161d0", md5str("message digest"), md5_digsize);
showhex("c3fcd3d76192e4007dfb496cca67e13b", md5str("abcdefghijklmnopqrstuvwxyz"), md5_digsize);
showhex("d174ab98d277d9f5a5611c2c9f419d9f", md5str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), md5_digsize);
showhex("57edf4a22be3c955ac49da2e2107b67a", md5str("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), md5_digsize);
showstr("t0htL.C9vunX8SPPsJjDmk", cryptpw("hovik", "myfavoritelonglonglongpassword"));
}
//
// outstm::putf() test
//
void putf_test()
{
pout.put("\n--- PUTF TEST\n");
outmemory m;
m.open();
m.putf("%s, %c, %d, %llx", "string", 'A', 1234, large(-1));
showstr("string, A, 1234, ffffffffffffffff", m.get_strdata());
m.open();
m.putf(" %%, %#o, %+010d", 0765, -3);
showstr(" %, 0765, -000000003", m.get_strdata());
}
//
// pinet/socket tests
//
void inet_test1()
{
try
{
pout.put("\n--- INET SOCKET & UTILITIES\n");
ipaddress ip(127, 0, 0, 1);
// as a test target host we use the one that would never be down! :)
string testname = "www.apache.org";
ip = phostbyname(testname);
string ips = iptostring(ip);
pout.putf("IP address of %s: %s\n", pconst(testname), (ip == ipnone) ? "failed" : pconst(ips));
if (ip != ipnone)
{
string hs = phostbyaddr(ip);
pout.putf("Name of %s: %s\n", pconst(ips), pconst(hs));
}
pout.putf("Canonical name of your local www: %s\n", pconst(phostcname("www")));
testname = "www.melikyan.com";
pout.putf("\nTrying %s:80...\n", pconst(testname));
ipstream s(testname, 80);
const char* request =
"GET /ptypes/test.txt HTTP/1.1\r\n"
"Accept: * /*\r\n"
"User-Agent: ptypes_test/2.1\r\n"
"Host: www.melikyan.com\r\n"
"Connection: close\r\n\r\n";
s.open();
s.put(request);
s.flush();
while (!s.get_eof())
{
char buf[16];
int r = s.read(buf, sizeof(buf));
pout.write(buf, r);
}
pout.put("\n");
s.close();
}
catch(estream* e)
{
perr.putf("Socket error: %s\n", pconst(e->get_message()));
delete e;
}
}
#ifndef PTYPES_ST
const int testport = 8085;
class svthread: public thread, protected ipstmserver
{
protected:
virtual void execute(); // override thread::execute()
virtual void cleanup(); // override thread::cleanup()
public:
svthread(): thread(false) {}
virtual ~svthread();
};
svthread::~svthread()
{
waitfor();
}
void svthread::execute()
{
ipstream client; // a socket object to communicate with the client
try
{
bindall(testport); // listen to all local addresses on port 8081
serve(client); // wait infinitely for a connection request
if (client.get_active())
{
// read one line from the stream; note that theoretically the line can be long,
// so calling client.line(buf, sizeof(buf)) here is a much better idea
string req = lowercase(client.line());
if (req == "hello")
{
// try to reverse-lookup the client's IP
string host = phostbyaddr(client.get_ip());
if (isempty(host))
host = iptostring(client.get_ip());
// now send our greeting to the client
client.putf("Hello, %s (%a), nice to see you!\n",
pconst(host), long(client.get_ip()));
client.flush();
}
// close() should be called explicitly to shut down the socket
// *gracefully*; otherwise ipstream's destructor may close the
// socket but in a less polite manner
client.close();
}
}
catch(estream* e)
{
perr.putf("Server error: %s\n", pconst(e->get_message()));
delete e;
}
// a real server could enter an infinite loop serving requests
// and producing separate threads for each connection
}
void svthread::cleanup()
{
}
void inet_test2()
{
pout.put("\n--- INET CLIENT/SERVER\n");
// we run the server in a separate thread in order to be able
// to imitate a client connection from the main thread
svthread server;
pout.put("\nStarting the server thread...\n");
server.start(); // it's that easy! :)
// sleep some time to let the server start its job
psleep(1000);
try
{
// now create a client socket and send a greeting to our server
ipstream client(ipaddress(127, 0, 0, 1), testport);
client.open();
pout.put("Sending a request to the server...\n");
client.putline("Hello");
client.flush();
string rsp = client.line();
pout.putf("Received: %s\n", pconst(rsp));
pout.putf("My address and port: %s:%d\n",
pconst(iptostring(client.get_myip())), client.get_myport());
client.close();
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
}
//
// UDP test
//
class msgsvthread: public thread
{
protected:
void execute();
public:
msgsvthread(): thread(false) {}
virtual ~msgsvthread() { waitfor(); }
};
void msgsvthread::execute()
{
ipmsgserver s;
s.bindall(testport);
try
{
string req = s.receive(1024);
pout.putf("Server received: %s\n", pconst(req));
string rsp = "gotcha";
s.send(rsp);
}
catch(estream* e)
{
perr.putf("Server error: %s\n", pconst(e->get_message()));
delete e;
}
}
void inet_test3()
{
pout.put("\n--- INET MESSAGE CLIENT/SERVER\n");
msgsvthread sv;
sv.start();
psleep(1000);
ipmessage m(ipbcast /* ipaddress(127, 0, 0, 1) */, testport);
try
{
string msg = "hello";
m.send(msg);
string rsp = m.receive(1024);
pout.putf("Client received: %s\n", pconst(rsp));
}
catch(estream* e)
{
perr.putf("Client error: %s\n", pconst(e->get_message()));
delete e;
}
}
//
// named pipes test
//
#define TEST_PIPE "ptypes.test"
class npthread: public thread, protected npserver
{
protected:
virtual void execute();
virtual void cleanup();
public:
npthread(): thread(false), npserver(TEST_PIPE) {}
virtual ~npthread();
};
npthread::~npthread()
{
waitfor();
}
void npthread::execute()
{
namedpipe client;
try
{
serve(client);
if (client.get_active())
{
string req = lowercase(client.line());
if (req == "hello")
{
client.putline("Hello, nice to see you!");
client.flush();
}
client.close();
}
}
catch(estream* e)
{
perr.putf("Pipe server error: %s\n", pconst(e->get_message()));
delete e;
}
}
void npthread::cleanup()
{
}
void pipe_test()
{
npthread server;
pout.put("\n--- NAMED PIPES\n");
pout.put("Starting the pipe server thread...\n");
server.start();
psleep(1000);
namedpipe client(TEST_PIPE);
try
{
client.open();
pout.put("Sending a request to the server...\n");
client.putline("Hello");
client.flush();
string rsp = client.line();
pout.putf("Received: %s\n", pconst(rsp));
client.close();
}
catch(estream* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
}
#endif // PTYPES_ST
//
// date/time/calendar
//
void time_test()
{
pout.put("\n--- DATE/TIME/CALENDAR\n");
tzupdate();
int year, month, day;
datetime d = encodedate(9999, 12, 31);
decodedate(d, year, month, day);
d = encodedate(1970, 1, 1);
decodedate(d, year, month, day);
datetime dt;
dt = invdatetime;
int hour, min, sec, msec;
dt = encodetime(23, 59, 59, 998);
decodetime(dt, hour, min, sec, msec);
dt = encodedate(2001, 8, 27) + encodetime(14, 33, 10);
d = encodedate(2001, 8, 28) + encodetime(14, 33, 10, 500);
dayofweek(dt);
dt = now(false);
pout.putf("Local time: %s\n", pconst(dttostring(dt, "%x %X %Z")));
datetime utc = now();
pout.putf("UTC time: %t GMT\n", utc);
time_t ut;
time(&ut);
pout.putline(dttostring(utodatetime(ut), "%c"));
int t = tzoffset();
bool neg = t < 0;
if (neg)
t = -t;
pout.putf("Time zone offset: %c%02d%02d\n", neg ? '-' : '+', t / 60, t % 60);
{
// PTypes' birthday (birth moment, if you wish)
datetime d = encodedate(2000, 3, 30) + encodetime(13, 24, 58, 995);
pout.putf("PTypes' birth moment: %T GMT\n", d);
// now see how old is PTypes in days, hours, minutes, etc
datetime diff = now() - d;
int hours, mins, secs, msecs;
decodetime(diff, hours, mins, secs, msecs);
pout.putf("PTypes' life time: %d days %d hours %d minutes %d seconds and %d milliseconds\n",
days(diff), hours, mins, secs, msecs);
#ifndef PTYPES_ST
// measure the difference in milliseconds between two calls to now()
datetime m = now();
psleep(17); // sleep for 17 milliseconds
pout.putf("A 17 millisecond dream lasted actually %d milliseconds\n", int(now() - m));
// this will show the actual precision of the clock on the given platform;
// Windows, f.ex., always shows the difference in 10 msec increments
#endif
}
}
//
// streams documentation example #2
//
const cset letters("_A-Za-z");
const cset digits("0-9");
const cset identchars = letters + digits;
const cset otherchars = !letters;
void doc_example()
{
tstrlist<void*> dic(SL_SORTED);
infile f("../src/ptypes_test.cxx");
try
{
f.open();
while (!f.get_eof())
{
char c = f.preview();
// a C identifier starts with a letter
if (c & letters)
{
// ... and may contain letters and digits
string ident = f.token(identchars);
int i;
if (!dic.search(ident, i))
dic.add(ident, 0);
}
else
f.skiptoken(otherchars);
}
}
catch (estream* e)
{
pout.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
// now print the dictionary
for (int i = 0; i < dic.get_count(); i++)
pout.putline(dic.getkey(i));
}
//
// variant
//
void variant_test()
{
pout.put("\n--- VARIANT\n");
variant v0 = 'A';
variant v1 = short(33);
variant v2 = "456";
variant v3 = int(v1) + int(v2);
variant v4 = string(v1) + " cows";
string s = string(v4);
// s = v4;
variant v5 = new component();
variant v6;
put(v6, 291, v1);
put(v6, "key", v2);
put(v6, "another-key", "another-value");
showstr("33 cows", string(v4));
showint(456, v6["key"]);
showstr("33", string(v1));
showint(1, bool(v6));
v2 = aclone(v6);
v5 = v6;
variant vi;
int i;
for (i = 0; anext(v6, i, vi);)
pout.putf("%d\n", int(vi));
variant v7;
aadd(v7, v1);
aadd(v7, v3);
aadd(v7, v4);
adel(v7, 2);
for (i = 0; i < alength(v7); i++)
pout.putf("%s\n", pconst(string(aget(v7, i))));
}
//
// main
//
int main()
{
try
{
string_test1();
string_test2();
string_benchmarks();
cset_test();
podlist_test();
ptrlist_test();
strlist_test();
textmap_test();
variant_test();
outfile_test();
infile_test();
mem_test();
md5_test();
putf_test();
time_test();
inet_test1();
#ifndef PTYPES_ST
pipe_test();
jobqueue_test();
thread_test();
rwlock_test();
trigger_test();
inet_test2();
inet_test3();
#endif
}
catch (estream* e)
{
perr.putf("\nError: %s\n", pconst(e->get_message()));
exit(1);
delete e;
}
#ifdef DEBUG
if (stralloc != 0 || objalloc != 0)
{
perr.putf("DBG stralloc: %d, objalloc: %d\n", stralloc, objalloc);
fatal(255, "Allocation problems");
}
#endif
return 0;
}
src/punit.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
#include "pasync.h"
#include "pstreams.h"
#ifdef WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
PTYPES_BEGIN
//
// internal thread class for running units asynchronously
//
class unit_thread: public thread
{
protected:
unit* target;
virtual void execute();
public:
unit_thread(unit* itarget);
virtual ~unit_thread();
};
unit_thread::unit_thread(unit* itarget)
: thread(false), target(itarget)
{
start();
}
unit_thread::~unit_thread()
{
waitfor();
}
void unit_thread::execute()
{
target->do_main();
}
//
// unit class
//
unit::unit()
: component(), pipe_next(nil), main_thread(nil),
running(0), uin(&pin), uout(&pout)
{
}
unit::~unit()
{
delete tpexchange<unit_thread>(&main_thread, nil);
}
int unit::classid()
{
return CLASS_UNIT;
}
void unit::main()
{
}
void unit::cleanup()
{
}
void unit::do_main()
{
try
{
if (!uout->get_active())
uout->open();
if (!uin->get_active())
uin->open();
main();
if (uout->get_active())
uout->flush();
}
catch(exception* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
try
{
cleanup();
}
catch(exception* e)
{
perr.putf("Error: %s\n", pconst(e->get_message()));
delete e;
}
if (pipe_next != nil)
uout->close();
}
void unit::connect(unit* next)
{
waitfor();
pipe_next = next;
infile* in = new infile();
outfile* out = new outfile();
next->uin = in;
uout = out;
in->pipe(*out);
}
void unit::waitfor()
{
if (running == 0)
return;
delete tpexchange<unit_thread>(&main_thread, nil);
unit* next = tpexchange<unit>(&pipe_next, nil);
if (next != nil)
{
next->waitfor();
next->uin = &pin;
}
uout = &pout;
running = 0;
}
void unit::run(bool async)
{
if (pexchange(&running, 1) != 0)
return;
if (main_thread != nil)
fatal(CRIT_FIRST + 60, "Unit already running");
if (pipe_next != nil)
pipe_next->run(true);
if (async)
main_thread = new unit_thread(this);
else
{
do_main();
waitfor();
}
}
PTYPES_END
src/punknown.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "ptypes.h"
PTYPES_BEGIN
int objalloc = 0;
PTYPES_END
src/pvariant.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "ptypes.h"
PTYPES_BEGIN
const variant nullvar;
struct _varitem
{
string key;
variant var;
_varitem(const string& ikey, const variant& ivar): key(ikey), var(ivar) {}
};
typedef _varitem* pvaritem;
class ptpublic _varray: protected tobjlist<_varitem>
{
protected:
int refcount;
virtual int compare(const void* key, const void* item) const;
friend class variant;
public:
_varray();
_varray(const _varray& a);
virtual ~_varray();
int get_count() { return tobjlist<_varitem>::get_count(); }
void clear() { tobjlist<_varitem>::clear(); }
void pack() { tobjlist<_varitem>::pack(); }
_varitem* doget(int index) const { return tobjlist<_varitem>::doget(index); }
const variant& get(int index) const { if (unsigned(index) < unsigned(count)) return doget(index)->var; else return nullvar; }
const string& getkey(int index) const { if (unsigned(index) < unsigned(count)) return doget(index)->key; else return nullstring; }
const variant& get(const char* key) const;
int put(const string& key, const variant& var);
void put(int index, const variant& var) { if (unsigned(index) < unsigned(count)) doget(index)->var = var; }
void ins(int index, const variant& var) { if (unsigned(index) < unsigned(count)) doins(index, new _varitem(nullstring, var)); }
int addvar(const variant& var);
void del(int index) { if (unsigned(index) < unsigned(count)) dodel(index); }
void del(const string& key) { put(key, nullstring); }
};
typedef _varray* pvarray;
_varray::_varray()
: tobjlist<_varitem>(true), refcount(0)
{
config.sorted = true;
config.casesens = true;
}
_varray::_varray(const _varray& a)
: tobjlist<_varitem>(true), refcount(0)
{
config.sorted = true;
config.casesens = true;
set_capacity(a.count);
for (int i = 0; i < a.count; i++)
{
_varitem* v = a.doget(i);
doins(i, new _varitem(v->key, v->var));
}
}
_varray::~_varray()
{
}
int _varray::compare(const void* key, const void* item) const
{
if (config.casesens)
return strcmp(pconst(key), pvaritem(item)->key);
else
return strcasecmp(pconst(key), pvaritem(item)->key);
}
const variant& _varray::get(const char* key) const
{
int index;
if (search(key, index))
return doget(index)->var;
else
return nullvar;
}
int _varray::put(const string& key, const variant& var)
{
int index;
if (search(pconst(key), index))
{
if (isnull(var))
dodel(index);
else
doget(index)->var = var;
}
else if (!isnull(var))
doins(index, new _varitem(key, var));
return index;
}
int _varray::addvar(const variant& v)
{
int i;
if (count > 0 && isempty(doget(count - 1)->key))
i = count;
else
i = 0;
doins(i, new _varitem(nullstring, v));
return i;
}
static void vconverr(large v);
static void vfatal()
{
fatal(CRIT_FIRST + 60, "Variant data corrupt");
}
evariant::~evariant()
{
}
void variant::initialize(_varray* a)
{
tag = VAR_ARRAY;
#ifdef PTYPES_ST
a->refcount++;
#else
pincrement(&a->refcount);
#endif
value.a = a;
}
void variant::initialize(component* o)
{
tag = VAR_OBJECT;
value.o = addref(o);
}
void variant::initialize(const variant& v)
{
switch (v.tag)
{
case VAR_NULL:
tag = VAR_NULL;
break;
case VAR_INT:
case VAR_BOOL:
case VAR_FLOAT:
tag = v.tag;
value = v.value;
break;
case VAR_STRING:
initialize(PTR_TO_STRING(v.value.s));
break;
case VAR_ARRAY:
initialize(v.value.a);
break;
case VAR_OBJECT:
initialize(v.value.o);
break;
default:
vfatal();
}
}
void variant::finalize()
{
if (tag >= VAR_COMPOUND)
{
switch (tag)
{
case VAR_STRING:
PTYPES_NAMESPACE::finalize(PTR_TO_STRING(value.s));
break;
case VAR_ARRAY:
#ifdef PTYPES_ST
if (--value.a->refcount == 0)
#else
if (pdecrement(&value.a->refcount) == 0)
#endif
delete value.a;
break;
case VAR_OBJECT:
release(value.o);
break;
default:
vfatal();
}
}
tag = VAR_NULL;
}
void variant::assign(large v) { finalize(); initialize(v); }
void variant::assign(bool v) { finalize(); initialize(v); }
void variant::assign(double v) { finalize(); initialize(v); }
void variant::assign(const char* v) { finalize(); initialize(v); }
void variant::assign(const string& v)
{
if (tag == VAR_STRING)
PTR_TO_STRING(value.s) = v;
else
{
finalize();
initialize(v);
}
}
void variant::assign(_varray* a)
{
if (tag == VAR_ARRAY && value.a == a)
return;
finalize();
initialize(a);
}
void variant::assign(component* o)
{
if (tag == VAR_OBJECT)
{
if (value.o == o)
return;
else
release(value.o);
}
else
finalize();
initialize(o);
}
void variant::assign(const variant& v)
{
switch (v.tag)
{
case VAR_NULL:
finalize();
tag = VAR_NULL;
break;
case VAR_INT:
case VAR_BOOL:
case VAR_FLOAT:
finalize();
tag = v.tag;
value = v.value;
break;
case VAR_STRING:
assign(PTR_TO_STRING(v.value.s));
break;
case VAR_ARRAY:
assign(v.value.a);
break;
case VAR_OBJECT:
assign(v.value.o);
break;
default:
vfatal();
}
}
void ptdecl clear(variant& v)
{
v.finalize();
v.initialize();
}
variant::operator int() const
{
large t = operator large();
if (t < INT_MIN || t > INT_MAX)
vconverr(t);
return int(t);
}
variant::operator unsigned int() const
{
large t = operator large();
if (t < 0 || t > UINT_MAX)
vconverr(t);
return uint(t);
}
variant::operator long() const
{
large t = operator large();
if (t < LONG_MIN || t > LONG_MAX)
vconverr(t);
return int(t);
}
variant::operator unsigned long() const
{
large t = operator large();
if (t < 0 || t > large(ULONG_MAX))
vconverr(t);
return uint(t);
}
variant::operator large() const
{
switch(tag)
{
case VAR_NULL: return 0;
case VAR_INT: return value.i;
case VAR_BOOL: return int(value.b);
case VAR_FLOAT: return int(value.f);
case VAR_STRING:
{
const char* p = PTR_TO_STRING(value.s);
bool neg = *p == '-';
if (neg)
p++;
large t = stringtoi(p);
if (t < 0)
return 0;
else
return neg ? -t : t;
}
case VAR_ARRAY: return value.a->count != 0;
case VAR_OBJECT: return 0;
default: vfatal();
}
return 0;
}
variant::operator bool() const
{
switch(tag)
{
case VAR_NULL: return false;
case VAR_INT: return value.i != 0;
case VAR_BOOL: return value.b;
case VAR_FLOAT: return value.f != 0;
case VAR_STRING: return !isempty((PTR_TO_STRING(value.s)));
case VAR_ARRAY: return value.a->count != 0;
case VAR_OBJECT: return value.o != nil;
default: vfatal();
}
return false;
}
variant::operator double() const
{
switch(tag)
{
case VAR_NULL: return 0;
case VAR_INT: return double(value.i);
case VAR_BOOL: return int(value.b);
case VAR_FLOAT: return value.f;
case VAR_STRING:
{
char* e;
double t = strtod(PTR_TO_STRING(value.s), &e);
if (*e != 0)
return 0;
else
return t;
}
case VAR_ARRAY: return int(value.a->count != 0);
case VAR_OBJECT: return 0;
default: vfatal();
}
return 0;
}
void string::initialize(const variant& v)
{
switch(v.tag)
{
case VAR_NULL: initialize(); break;
case VAR_INT: initialize(itostring(v.value.i)); break;
case VAR_BOOL: if (v.value.b) initialize('1'); else initialize('0'); break;
case VAR_FLOAT:
{
char buf[256];
sprintf(buf, "%g", v.value.f);
initialize(buf);
}
break;
case VAR_STRING: initialize(PTR_TO_STRING(v.value.s)); break;
case VAR_ARRAY: initialize(); break;
case VAR_OBJECT: initialize(); break;
default: vfatal();
}
}
variant::operator string() const
{
// this is a 'dirty' solution to gcc 3.3 typecast problem. most compilers
// handle variant::operator string() pretty well, while gcc 3.3 requires
// to explicitly declare a constructor string::string(const variant&).
// ironically, the presence of both the typecast operator and the constructor
// confuses the MSVC compiler. so the only thing we can do to please all
// those compilers [that "move towards the c++ standard"] is to conditionally
// exclude the constructor string(const variant&). and this is not the whole
// story. i see you are bored with it and i let you go. nobody would ever care
// about this. it just works, though i'm not happy with what i wrote here:
string t;
t.initialize(*this);
return t;
}
variant::operator component*() const
{
if (tag == VAR_OBJECT)
return value.o;
else
return nil;
}
bool variant::equal(const variant& v) const
{
if (tag != v.tag)
return false;
switch (tag)
{
case VAR_NULL: return true;
case VAR_INT: return value.i == v.value.i;
case VAR_BOOL: return value.b == v.value.b;
case VAR_FLOAT: return value.f == v.value.f;
case VAR_STRING: return strcmp(value.s, v.value.s) == 0;
case VAR_ARRAY: return value.a == v.value.a;
case VAR_OBJECT: return value.o == v.value.o;
default: vfatal(); return false;
}
}
static string numkey(large key)
{
return itostring(key, 16, 16, '0');
}
void ptdecl aclear(variant& v)
{
if (v.tag == VAR_ARRAY)
v.value.a->clear();
else
{
v.finalize();
v.initialize(new _varray());
}
}
void ptdecl apack(variant& v)
{
if (v.tag == VAR_ARRAY)
v.value.a->pack();
}
variant ptdecl aclone(const variant& v)
{
if (v.tag == VAR_ARRAY)
return variant(new _varray(*(v.value.a)));
else
return variant(new _varray());
}
int ptdecl alength(const variant& v)
{
if (v.tag == VAR_ARRAY)
return v.value.a->get_count();
else
return 0;
}
const variant& ptdecl get(const variant& v, const string& key)
{
if (v.tag == VAR_ARRAY)
return v.value.a->get(key);
else
return nullvar;
}
const variant& ptdecl get(const variant& v, large key)
{
return get(v, numkey(key));
}
void ptdecl put(variant& v, const string& key, const variant& item)
{
if (v.tag != VAR_ARRAY)
aclear(v);
v.value.a->put(key, item);
}
void ptdecl put(variant& v, large key, const variant& item)
{
put(v, numkey(key), item);
}
void ptdecl del(variant& v, const string& key)
{
if (v.tag == VAR_ARRAY)
v.value.a->del(key);
}
void ptdecl del(variant& v, large key)
{
del(v, numkey(key));
}
bool ptdecl anext(const variant& array, int& index, variant& item)
{
string key;
return anext(array, index, item, key);
}
bool ptdecl anext(const variant& array, int& index, variant& item, string & key)
{
if (array.tag != VAR_ARRAY)
{
clear(item);
return false;
}
if (index < 0 || index >= array.value.a->get_count())
{
clear(item);
return false;
}
item = array.value.a->doget(index)->var;
key = array.value.a->doget(index)->key;
index++;
return true;
}
bool ptdecl anext(const variant& array, int& index, variant& item, variant & key)
{
if (array.tag != VAR_ARRAY)
{
clear(item);
return false;
}
if (index < 0 || index >= array.value.a->get_count())
{
clear(item);
return false;
}
item = array.value.a->doget(index)->var;
key = array.value.a->doget(index)->key;
index++;
return true;
}
void ptdecl add(variant & v, const variant & var)
{
put(v, alength(v), var);
}
int ptdecl aadd(variant& array, const variant& item)
{
if (array.tag != VAR_ARRAY)
aclear(array);
return array.value.a->addvar(item);
}
const variant& ptdecl aget(const variant& array, int index)
{
if (array.tag == VAR_ARRAY)
return array.value.a->get(index);
else
return nullvar;
}
void ptdecl adel(variant& array, int index)
{
if (array.tag == VAR_ARRAY)
array.value.a->del(index);
}
void ptdecl aput(variant& array, int index, const variant& item)
{
if (array.tag == VAR_ARRAY)
array.value.a->put(index, item);
}
void ptdecl ains(variant& array, int index, const variant& item)
{
if (array.tag == VAR_ARRAY)
array.value.a->ins(index, item);
}
#ifdef _MSC_VER
// disable "unreachable code" warning for throw (known compiler bug)
# pragma warning (disable: 4702)
#endif
static void vconverr(large v)
{
throw new evariant("Value out of range: " + itostring(v));
}
PTYPES_END
src/pversion.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "pport.h"
unsigned long __ptypes_version = 0x00020101;
win32/PTypes.sln
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_DLL", "PTypes_DLL.vcxproj", "{181E52DE-3CF7-425B-B24A-E59711635486}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Lib", "PTypes_Lib.vcxproj", "{4A435BFE-D414-4FFA-8364-672A2B7FFF01}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Lib_ST", "PTypes_Lib_ST.vcxproj", "{FB3CDEFD-B016-4EFE-8634-86083A584B04}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Test", "PTypes_Test.vcxproj", "{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Test_ST", "PTypes_Test_ST.vcxproj", "{ADC21731-3254-476F-8D37-8266E1EC293D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wshare", "wshare.vcxproj", "{6B53FB0A-5052-4A7B-8419-7CBF117088EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{181E52DE-3CF7-425B-B24A-E59711635486}.Debug|Win32.ActiveCfg = Debug|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Debug|Win32.Build.0 = Debug|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Release|Win32.ActiveCfg = Release|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Release|Win32.Build.0 = Release|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Debug|Win32.ActiveCfg = Debug|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Debug|Win32.Build.0 = Debug|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Release|Win32.ActiveCfg = Release|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Release|Win32.Build.0 = Release|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Debug|Win32.ActiveCfg = Debug|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Debug|Win32.Build.0 = Debug|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Release|Win32.ActiveCfg = Release|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Release|Win32.Build.0 = Release|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Debug|Win32.ActiveCfg = Debug|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Debug|Win32.Build.0 = Debug|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Release|Win32.ActiveCfg = Release|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Release|Win32.Build.0 = Release|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Debug|Win32.ActiveCfg = Debug|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Debug|Win32.Build.0 = Debug|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Release|Win32.ActiveCfg = Release|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Release|Win32.Build.0 = Release|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Debug|Win32.ActiveCfg = Debug|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Debug|Win32.Build.0 = Debug|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Release|Win32.ActiveCfg = Release|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
win32/PTypes.sln.old
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_DLL", "PTypes_DLL.vcproj", "{181E52DE-3CF7-425B-B24A-E59711635486}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Lib", "PTypes_Lib.vcproj", "{4A435BFE-D414-4FFA-8364-672A2B7FFF01}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Lib_ST", "PTypes_Lib_ST.vcproj", "{FB3CDEFD-B016-4EFE-8634-86083A584B04}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Test", "PTypes_Test.vcproj", "{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}"
ProjectSection(ProjectDependencies) = postProject
{181E52DE-3CF7-425B-B24A-E59711635486} = {181E52DE-3CF7-425B-B24A-E59711635486}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTypes_Test_ST", "PTypes_Test_ST.vcproj", "{ADC21731-3254-476F-8D37-8266E1EC293D}"
ProjectSection(ProjectDependencies) = postProject
{FB3CDEFD-B016-4EFE-8634-86083A584B04} = {FB3CDEFD-B016-4EFE-8634-86083A584B04}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wshare", "wshare.vcproj", "{6B53FB0A-5052-4A7B-8419-7CBF117088EB}"
ProjectSection(ProjectDependencies) = postProject
{4A435BFE-D414-4FFA-8364-672A2B7FFF01} = {4A435BFE-D414-4FFA-8364-672A2B7FFF01}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{181E52DE-3CF7-425B-B24A-E59711635486}.Debug|Win32.ActiveCfg = Debug|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Debug|Win32.Build.0 = Debug|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Release|Win32.ActiveCfg = Release|Win32
{181E52DE-3CF7-425B-B24A-E59711635486}.Release|Win32.Build.0 = Release|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Debug|Win32.ActiveCfg = Debug|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Debug|Win32.Build.0 = Debug|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Release|Win32.ActiveCfg = Release|Win32
{4A435BFE-D414-4FFA-8364-672A2B7FFF01}.Release|Win32.Build.0 = Release|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Debug|Win32.ActiveCfg = Debug|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Debug|Win32.Build.0 = Debug|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Release|Win32.ActiveCfg = Release|Win32
{FB3CDEFD-B016-4EFE-8634-86083A584B04}.Release|Win32.Build.0 = Release|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Debug|Win32.ActiveCfg = Debug|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Debug|Win32.Build.0 = Debug|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Release|Win32.ActiveCfg = Release|Win32
{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}.Release|Win32.Build.0 = Release|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Debug|Win32.ActiveCfg = Debug|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Debug|Win32.Build.0 = Debug|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Release|Win32.ActiveCfg = Release|Win32
{ADC21731-3254-476F-8D37-8266E1EC293D}.Release|Win32.Build.0 = Release|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Debug|Win32.ActiveCfg = Debug|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Debug|Win32.Build.0 = Debug|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Release|Win32.ActiveCfg = Release|Win32
{6B53FB0A-5052-4A7B-8419-7CBF117088EB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
win32/PTypes_DLL.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PTypes_DLL"
ProjectGUID="{181E52DE-3CF7-425B-B24A-E59711635486}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\DLL_Debug"
IntermediateDirectory=".\DLL_Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\DLL_Debug/PTypes_DLL.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PTYPES_DLL_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\DLL_Debug/PTypes_DLL.pch"
AssemblerListingLocation=".\DLL_Debug/"
ObjectFile=".\DLL_Debug/"
ProgramDataBaseFileName=".\DLL_Debug/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1047"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="DLL_Debug/ptypes21.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\DLL_Debug/ptypes21.pdb"
ImportLibrary=".\DLL_Debug/ptypes21.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\DLL_Debug/PTypes_DLL.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\DLL_Release"
IntermediateDirectory=".\DLL_Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\DLL_Release/PTypes_DLL.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PTYPES_DLL_EXPORTS"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\DLL_Release/PTypes_DLL.pch"
AssemblerListingLocation=".\DLL_Release/"
ObjectFile=".\DLL_Release/"
ProgramDataBaseFileName=".\DLL_Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1049"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="DLL_Release/ptypes21.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\DLL_Release/ptypes21.pdb"
GenerateMapFile="true"
MapFileName=".\DLL_Release/ptypes21.map"
ImportLibrary=".\DLL_Release/ptypes21.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\DLL_Release/PTypes_DLL.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir ..\so\&#x0D;&#x0A;copy DLL_Release\ptypes21.lib ..\so\&#x0D;&#x0A;copy DLL_Release\ptypes21.dll ..\so\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Types"
>
<File
RelativePath="..\src\pcomponent.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcset.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcsetdbg.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pexcept.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pfatal.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pobjlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppodlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrcase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrconv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstring.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrmanip.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrtoi.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrutils.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptextmap.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptime.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\punit.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\punknown.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pvariant.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pversion.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Public Headers"
>
<File
RelativePath="..\include\pasync.h"
>
</File>
<File
RelativePath="..\include\pinet.h"
>
</File>
<File
RelativePath="..\include\pport.h"
>
</File>
<File
RelativePath="..\include\pstreams.h"
>
</File>
<File
RelativePath="..\include\ptime.h"
>
</File>
<File
RelativePath="..\include\ptypes.h"
>
</File>
</Filter>
<Filter
Name="Streams"
>
<File
RelativePath="..\src\pfdxstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfile.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfilter.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pintee.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\piobase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmd5.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpipe.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpserver.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfile.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfilter.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppipe.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pputf.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstdio.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Async"
>
<File
RelativePath="..\src\pasync.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\patomic.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmsgq.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmtxtable.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\prwlock.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\psemaphore.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pthread.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptimedsem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptrigger.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Inet"
>
<File
RelativePath="..\src\pipbase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsg.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsgsv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstmsv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipsvbase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Resources"
Filter="*.rc,*.h"
>
<File
RelativePath="dll_version.rc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="resource.h"
>
</File>
</Filter>
<File
RelativePath="..\LICENSE"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/PTypes_DLL.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{181E52DE-3CF7-425B-B24A-E59711635486}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\DLL_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\DLL_Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\DLL_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\DLL_Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\DLL_Debug/PTypes_DLL.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PTYPES_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\DLL_Debug/PTypes_DLL.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\DLL_Debug/</AssemblerListingLocation>
<ObjectFileName>.\DLL_Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\DLL_Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0417</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>DLL_Debug/ptypes21.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\DLL_Debug/ptypes21.pdb</ProgramDatabaseFile>
<ImportLibrary>.\DLL_Debug/ptypes21.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\DLL_Debug/PTypes_DLL.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\DLL_Release/PTypes_DLL.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PTYPES_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\DLL_Release/PTypes_DLL.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\DLL_Release/</AssemblerListingLocation>
<ObjectFileName>.\DLL_Release/</ObjectFileName>
<ProgramDataBaseFileName>.\DLL_Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>DLL_Release/ptypes21.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\DLL_Release/ptypes21.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\DLL_Release/ptypes21.map</MapFileName>
<ImportLibrary>.\DLL_Release/ptypes21.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\DLL_Release/PTypes_DLL.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>mkdir ..\so\
copy DLL_Release\ptypes21.lib ..\so\
copy DLL_Release\ptypes21.dll ..\so\
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\pcomponent.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\punit.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pasync.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\patomic.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmsgq.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmtxtable.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\prwlock.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\psemaphore.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pthread.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptimedsem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptrigger.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h" />
<ClInclude Include="..\include\pinet.h" />
<ClInclude Include="..\include\pport.h" />
<ClInclude Include="..\include\pstreams.h" />
<ClInclude Include="..\include\ptime.h" />
<ClInclude Include="..\include\ptypes.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="dll_version.rc">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/PTypes_DLL.vcxproj.filters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Types">
<UniqueIdentifier>{03b5f83a-8831-4a02-b142-3dea413bd4cf}</UniqueIdentifier>
</Filter>
<Filter Include="Public Headers">
<UniqueIdentifier>{00cde44f-153d-41d7-ad67-0291b6987ac0}</UniqueIdentifier>
</Filter>
<Filter Include="Streams">
<UniqueIdentifier>{a8c44998-3031-4332-bc12-4628471b4ef9}</UniqueIdentifier>
</Filter>
<Filter Include="Async">
<UniqueIdentifier>{020aa4dd-587a-492c-99e8-a4b5bf15a2e4}</UniqueIdentifier>
</Filter>
<Filter Include="Inet">
<UniqueIdentifier>{de2eaf6f-0c2e-41d2-8c98-95e92ca1e71b}</UniqueIdentifier>
</Filter>
<Filter Include="Resources">
<UniqueIdentifier>{3248f09b-f155-47b0-be1c-ab36e64d6b44}</UniqueIdentifier>
<Extensions>*.rc,*.h</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pcomponent.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\punit.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pasync.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\patomic.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pmsgq.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pmtxtable.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\prwlock.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\psemaphore.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pthread.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\ptimedsem.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\ptrigger.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pinet.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pport.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pstreams.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptime.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptypes.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="dll_version.rc">
<Filter>Resources</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
</Project>
win32/PTypes_DLL.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
win32/PTypes_Lib.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PTypes_Lib"
ProjectGUID="{4A435BFE-D414-4FFA-8364-672A2B7FFF01}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_LIB;NDEBUG;WIN32"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/PTypes_Lib.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="Release\ptypes.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/PTypes_Lib.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir ..\lib\&#x0D;&#x0A;copy Release\ptypes.lib ..\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_LIB;_DEBUG;WIN32"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\Debug/PTypes_Lib.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="Debug\ptypes.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/PTypes_Lib.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Types"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pcomponent.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcset.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcsetdbg.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pexcept.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pfatal.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmem.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pobjlist.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppodlist.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrcase.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrconv.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstring.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrlist.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrmanip.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrtoi.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrutils.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptextmap.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptime.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\punit.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\punknown.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pvariant.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pversion.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Public Headers"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\include\pasync.h"
>
</File>
<File
RelativePath="..\include\pinet.h"
>
</File>
<File
RelativePath="..\include\pport.h"
>
</File>
<File
RelativePath="..\include\pstreams.h"
>
</File>
<File
RelativePath="..\include\ptime.h"
>
</File>
<File
RelativePath="..\include\ptypes.h"
>
</File>
</Filter>
<Filter
Name="Streams"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pfdxstm.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfile.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfilter.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinmem.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinstm.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pintee.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\piobase.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmd5.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpipe.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpserver.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfile.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfilter.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutmem.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutstm.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppipe.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pputf.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstdio.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Async"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pasync.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\patomic.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmsgq.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmtxtable.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\prwlock.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\psemaphore.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pthread.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptimedsem.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptrigger.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Inet"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pipbase.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsg.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsgsv.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstm.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstmsv.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipsvbase.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<File
RelativePath="..\LICENSE"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/PTypes_Lib.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4A435BFE-D414-4FFA-8364-672A2B7FFF01}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_LIB;NDEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/PTypes_Lib.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>Release\ptypes.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/PTypes_Lib.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>mkdir ..\lib\
copy Release\ptypes.lib ..\lib\
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_LIB;_DEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/PTypes_Lib.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>Debug\ptypes.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/PTypes_Lib.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\pcomponent.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\punit.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pasync.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\patomic.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmsgq.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmtxtable.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\prwlock.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\psemaphore.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pthread.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptimedsem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptrigger.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h" />
<ClInclude Include="..\include\pinet.h" />
<ClInclude Include="..\include\pport.h" />
<ClInclude Include="..\include\pstreams.h" />
<ClInclude Include="..\include\ptime.h" />
<ClInclude Include="..\include\ptypes.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/PTypes_Lib.vcxproj.filters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Types">
<UniqueIdentifier>{054093b8-d1c6-4f6f-a342-c01d06cac267}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Public Headers">
<UniqueIdentifier>{91444797-eef9-4801-9d5d-7d0a97c25fe5}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Streams">
<UniqueIdentifier>{4d75cde2-1d88-4d28-8935-4c156005ee21}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Async">
<UniqueIdentifier>{458d2fec-26f8-45e5-802a-9df3ccf9c6e5}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Inet">
<UniqueIdentifier>{c8d49101-57f3-4cca-8c34-f2078813bc90}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pcomponent.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\punit.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pasync.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\patomic.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pmsgq.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pmtxtable.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\prwlock.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\psemaphore.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pthread.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\ptimedsem.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\ptrigger.cxx">
<Filter>Async</Filter>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pinet.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pport.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pstreams.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptime.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptypes.h">
<Filter>Public Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
</Project>
win32/PTypes_Lib.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
win32/PTypes_Lib_ST.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PTypes_Lib_ST"
ProjectGUID="{FB3CDEFD-B016-4EFE-8634-86083A584B04}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug_ST"
IntermediateDirectory=".\Debug_ST"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;_LIB;WIN32;PTYPES_ST"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug_ST/PTypes_Lib_ST.pch"
AssemblerListingLocation=".\Debug_ST/"
ObjectFile=".\Debug_ST/"
ProgramDataBaseFileName=".\Debug_ST/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="Debug_ST\ptypesn.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug_ST/PTypes_Lib_ST.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release_ST"
IntermediateDirectory=".\Release_ST"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="NDEBUG;_LIB;WIN32;PTYPES_ST"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release_ST/PTypes_Lib_ST.pch"
AssemblerListingLocation=".\Release_ST/"
ObjectFile=".\Release_ST/"
ProgramDataBaseFileName=".\Release_ST/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="Release_ST\ptypesn.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release_ST/PTypes_Lib_ST.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir ..\lib\&#x0D;&#x0A;copy Release_ST\ptypesn.lib ..\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Types"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\patomic.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcomponent.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcset.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pcsetdbg.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pexcept.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pfatal.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pobjlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppodlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrcase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrconv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstring.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrlist.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrmanip.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrtoi.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstrutils.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptextmap.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ptime.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\punknown.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pvariant.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pversion.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Public Headers"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\include\pasync.h"
>
</File>
<File
RelativePath="..\include\pinet.h"
>
</File>
<File
RelativePath="..\include\pport.h"
>
</File>
<File
RelativePath="..\include\pstreams.h"
>
</File>
<File
RelativePath="..\include\ptime.h"
>
</File>
<File
RelativePath="..\include\ptypes.h"
>
</File>
</Filter>
<Filter
Name="Streams"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pfdxstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfile.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinfilter.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pinstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pintee.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\piobase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pmd5.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpipe.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pnpserver.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfile.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutfilter.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutmem.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\poutstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ppipe.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pputf.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pstdio.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Inet"
Filter="h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\src\pipbase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsg.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipmsgsv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstm.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipstmsv.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\pipsvbase.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<File
RelativePath="..\LICENSE"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/PTypes_Lib_ST.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{FB3CDEFD-B016-4EFE-8634-86083A584B04}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_ST\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_ST\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_ST\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_ST\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;_LIB;WIN32;PTYPES_ST;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug_ST/PTypes_Lib_ST.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug_ST/</AssemblerListingLocation>
<ObjectFileName>.\Debug_ST/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug_ST/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>Debug_ST\ptypesn.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug_ST/PTypes_Lib_ST.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;_LIB;WIN32;PTYPES_ST;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release_ST/PTypes_Lib_ST.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release_ST/</AssemblerListingLocation>
<ObjectFileName>.\Release_ST/</ObjectFileName>
<ProgramDataBaseFileName>.\Release_ST/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>Release_ST\ptypesn.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release_ST/PTypes_Lib_ST.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>mkdir ..\lib\
copy Release_ST\ptypesn.lib ..\lib\
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\patomic.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcomponent.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h" />
<ClInclude Include="..\include\pinet.h" />
<ClInclude Include="..\include\pport.h" />
<ClInclude Include="..\include\pstreams.h" />
<ClInclude Include="..\include\ptime.h" />
<ClInclude Include="..\include\ptypes.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/PTypes_Lib_ST.vcxproj.filters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Types">
<UniqueIdentifier>{9839b624-c96b-4a86-9d06-746bdf6f840e}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Public Headers">
<UniqueIdentifier>{7a1c620f-f7c4-421f-be15-de70f0ca2bc7}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Streams">
<UniqueIdentifier>{7883e225-fd60-42ea-a9c4-0e5f19e0d5b9}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Inet">
<UniqueIdentifier>{78775f48-de12-4f23-a22d-8a940ee7320e}</UniqueIdentifier>
<Extensions>h;cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\patomic.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcomponent.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcset.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pcsetdbg.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pexcept.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfatal.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pmem.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pobjlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ppodlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrcase.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrconv.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstring.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrlist.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrmanip.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrtoi.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pstrutils.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptextmap.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptime.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\punknown.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pvariant.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pversion.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\pfdxstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pinstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pintee.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\piobase.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pmd5.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pnpserver.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfile.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutfilter.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutmem.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\poutstm.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\ppipe.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pputf.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pstdio.cxx">
<Filter>Streams</Filter>
</ClCompile>
<ClCompile Include="..\src\pipbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsg.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipmsgsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstm.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipstmsv.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pinet.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pport.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\pstreams.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptime.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="..\include\ptypes.h">
<Filter>Public Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />
</ItemGroup>
</Project>
win32/PTypes_Lib_ST.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
win32/PTypes_Test.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PTypes_Test"
ProjectGUID="{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\DLL_Debug"
IntermediateDirectory=".\DLL_Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\DLL_Debug/PTypes_Test.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_CONSOLE;_DEBUG;WIN32;PTYPES_DLL"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\DLL_Debug/PTypes_Test.pch"
AssemblerListingLocation=".\DLL_Debug/"
ObjectFile=".\DLL_Debug/"
ProgramDataBaseFileName=".\DLL_Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile=".\DLL_Debug/PTypes_Test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\DLL_Debug/PTypes_Test.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\DLL_Debug/PTypes_Test.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\DLL_Release"
IntermediateDirectory=".\DLL_Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\DLL_Release/PTypes_Test.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_CONSOLE;NDEBUG;WIN32;PTYPES_DLL"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\DLL_Release/PTypes_Test.pch"
AssemblerListingLocation=".\DLL_Release/"
ObjectFile=".\DLL_Release/"
ProgramDataBaseFileName=".\DLL_Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile=".\DLL_Release/PTypes_Test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\DLL_Release/PTypes_Test.pdb"
GenerateMapFile="true"
MapFileName=".\DLL_Release/PTypes_Test.map"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\DLL_Release/PTypes_Test.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\src\ptypes_test.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/PTypes_Test.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A08093B3-4E89-4D19-85FD-D0679E7DC4EA}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\DLL_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\DLL_Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\DLL_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\DLL_Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\DLL_Debug/PTypes_Test.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;_DEBUG;WIN32;PTYPES_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\DLL_Debug/PTypes_Test.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\DLL_Debug/</AssemblerListingLocation>
<ObjectFileName>.\DLL_Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\DLL_Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\DLL_Debug/PTypes_Test.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\DLL_Debug/PTypes_Test.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\DLL_Debug/PTypes_Test.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\DLL_Release/PTypes_Test.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;NDEBUG;WIN32;PTYPES_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\DLL_Release/PTypes_Test.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\DLL_Release/</AssemblerListingLocation>
<ObjectFileName>.\DLL_Release/</ObjectFileName>
<ProgramDataBaseFileName>.\DLL_Release/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\DLL_Release/PTypes_Test.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\DLL_Release/PTypes_Test.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\DLL_Release/PTypes_Test.map</MapFileName>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\DLL_Release/PTypes_Test.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\ptypes_test.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="PTypes_DLL.vcxproj">
<Project>{181e52de-3cf7-425b-b24a-e59711635486}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/PTypes_Test.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
win32/PTypes_Test_ST.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PTypes_Test_ST"
ProjectGUID="{ADC21731-3254-476F-8D37-8266E1EC293D}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release_ST"
IntermediateDirectory=".\Release_ST"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release_ST/PTypes_Test_ST.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_CONSOLE;NDEBUG;WIN32"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release_ST/PTypes_Test_ST.pch"
AssemblerListingLocation=".\Release_ST/"
ObjectFile=".\Release_ST/"
ProgramDataBaseFileName=".\Release_ST/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile=".\Release_ST/PTypes_Test_ST.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release_ST/PTypes_Test_ST.pdb"
GenerateMapFile="true"
MapFileName=".\Release_ST/PTypes_Test_ST.map"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release_ST/PTypes_Test_ST.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug_ST"
IntermediateDirectory=".\Debug_ST"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug_ST/PTypes_Test_ST.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_CONSOLE;_DEBUG;WIN32"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug_ST/PTypes_Test_ST.pch"
AssemblerListingLocation=".\Debug_ST/"
ObjectFile=".\Debug_ST/"
ProgramDataBaseFileName=".\Debug_ST/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile=".\Debug_ST/PTypes_Test_ST.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug_ST/PTypes_Test_ST.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug_ST/PTypes_Test_ST.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\src\ptypes_test.cxx"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="PTYPES_ST"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="PTYPES_ST"
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/PTypes_Test_ST.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{ADC21731-3254-476F-8D37-8266E1EC293D}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_ST\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_ST\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_ST\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_ST\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release_ST/PTypes_Test_ST.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;NDEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release_ST/PTypes_Test_ST.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release_ST/</AssemblerListingLocation>
<ObjectFileName>.\Release_ST/</ObjectFileName>
<ProgramDataBaseFileName>.\Release_ST/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release_ST/PTypes_Test_ST.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release_ST/PTypes_Test_ST.pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release_ST/PTypes_Test_ST.map</MapFileName>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release_ST/PTypes_Test_ST.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\Debug_ST/PTypes_Test_ST.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;_DEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug_ST/PTypes_Test_ST.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug_ST/</AssemblerListingLocation>
<ObjectFileName>.\Debug_ST/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug_ST/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug_ST/PTypes_Test_ST.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug_ST/PTypes_Test_ST.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug_ST/PTypes_Test_ST.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\ptypes_test.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">PTYPES_ST;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">PTYPES_ST;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="PTypes_Lib_ST.vcxproj">
<Project>{fb3cdefd-b016-4efe-8634-86083a584b04}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/PTypes_Test_ST.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
win32/UpgradeLog.XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type='text/xsl' href='_UpgradeReport_Files/UpgradeReport.xslt'?><UpgradeLog>
<Properties><Property Name="Solution" Value="PTypes">
</Property><Property Name="Solution File" Value="C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes.sln">
</Property><Property Name="Date" Value="Sunday, April 14, 2013">
</Property><Property Name="Time" Value="1:34 AM">
</Property></Properties><Event ErrorLevel="0" Project="" Source="PTypes.sln" Description="File successfully backed up as C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes.sln.old">
</Event><Event ErrorLevel="0" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_DLL.vcproj'.">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="0" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="MSB8012: $(TargetName) ('PTypes_DLL') does not match the Linker's OutputFile property value 'DLL_Debug/ptypes21.dll' ('ptypes21') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\DLL_Debug\PTypes_DLL.dll') does not match the Linker's OutputFile property value 'DLL_Debug/ptypes21.dll' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\DLL_Debug/ptypes21.dll') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="MSB8012: $(TargetName) ('PTypes_DLL') does not match the Linker's OutputFile property value 'DLL_Release/ptypes21.dll' ('ptypes21') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\DLL_Release\PTypes_DLL.dll') does not match the Linker's OutputFile property value 'DLL_Release/ptypes21.dll' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\DLL_Release/ptypes21.dll') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="0" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_DLL.vcxproj'.">
</Event><Event ErrorLevel="3" Project="PTypes_DLL" Source="PTypes_DLL.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Lib.vcproj'.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="MSB8012: $(TargetName) ('PTypes_Lib') does not match the Librarian's OutputFile property value 'Release\ptypes.lib' ('ptypes') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Release\PTypes_Lib.lib') does not match the Librarian's OutputFile property value 'Release\ptypes.lib' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Release\ptypes.lib') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="MSB8012: $(TargetName) ('PTypes_Lib') does not match the Librarian's OutputFile property value 'Debug\ptypes.lib' ('ptypes') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Debug\PTypes_Lib.lib') does not match the Librarian's OutputFile property value 'Debug\ptypes.lib' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Debug\ptypes.lib') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="0" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Lib.vcxproj'.">
</Event><Event ErrorLevel="3" Project="PTypes_Lib" Source="PTypes_Lib.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Lib_ST.vcproj'.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="MSB8012: $(TargetName) ('PTypes_Lib_ST') does not match the Librarian's OutputFile property value 'Debug_ST\ptypesn.lib' ('ptypesn') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Debug_ST\PTypes_Lib_ST.lib') does not match the Librarian's OutputFile property value 'Debug_ST\ptypesn.lib' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Debug_ST\ptypesn.lib') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="MSB8012: $(TargetName) ('PTypes_Lib_ST') does not match the Librarian's OutputFile property value 'Release_ST\ptypesn.lib' ('ptypesn') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetName) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Release_ST\PTypes_Lib_ST.lib') does not match the Librarian's OutputFile property value 'Release_ST\ptypesn.lib' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Release_ST\ptypesn.lib') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Lib.OutputFile).">
</Event><Event ErrorLevel="0" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Lib_ST.vcxproj'.">
</Event><Event ErrorLevel="3" Project="PTypes_Lib_ST" Source="PTypes_Lib_ST.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Test.vcproj'.">
</Event><Event ErrorLevel="1" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="0" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\DLL_Debug\PTypes_Test.exe') does not match the Linker's OutputFile property value '.\DLL_Debug/PTypes_Test.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\DLL_Debug/PTypes_Test.exe') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\DLL_Release\PTypes_Test.exe') does not match the Linker's OutputFile property value '.\DLL_Release/PTypes_Test.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\DLL_Release/PTypes_Test.exe') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="0" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Test.vcxproj'.">
</Event><Event ErrorLevel="3" Project="PTypes_Test" Source="PTypes_Test.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Test_ST.vcproj'.">
</Event><Event ErrorLevel="1" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="0" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Release_ST\PTypes_Test_ST.exe') does not match the Linker's OutputFile property value '.\Release_ST/PTypes_Test_ST.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Release_ST/PTypes_Test_ST.exe') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Debug_ST\PTypes_Test_ST.exe') does not match the Linker's OutputFile property value '.\Debug_ST/PTypes_Test_ST.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Debug_ST/PTypes_Test_ST.exe') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="0" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\PTypes_Test_ST.vcxproj'.">
</Event><Event ErrorLevel="3" Project="PTypes_Test_ST" Source="PTypes_Test_ST.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="wshare" Source="wshare.vcproj" Description="Converting project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\wshare.vcproj'.">
</Event><Event ErrorLevel="1" Project="wshare" Source="wshare.vcproj" Description="This application has been updated to include settings related to the User Account Control (UAC) feature of Windows Vista. By default, when run on Windows Vista with UAC enabled, this application is marked to run with the same privileges as the process that launched it. This marking also disables the application from running with virtualization. You can change UAC related settings from the Property Pages of the project.">
</Event><Event ErrorLevel="1" Project="wshare" Source="wshare.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
</Event><Event ErrorLevel="0" Project="wshare" Source="wshare.vcproj" Description="Web deployment to the local IIS server is no longer supported. The Web Deployment build tool has been removed from your project settings.">
</Event><Event ErrorLevel="1" Project="wshare" Source="wshare.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Debug\wshare.exe') does not match the Linker's OutputFile property value '.\Debug/wshare.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Debug/wshare.exe') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="1" Project="wshare" Source="wshare.vcproj" Description="MSB8012: $(TargetPath) ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\.\Release\wshare.exe') does not match the Linker's OutputFile property value '.\Release/wshare.exe' ('C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\Release/wshare.exe') in project configuration 'Release|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).">
</Event><Event ErrorLevel="0" Project="wshare" Source="wshare.vcproj" Description="Done converting to new project file 'C:\Users\nathan\Downloads\ptypes-2.1.1.tar\ptypes-2.1.1\ptypes-2.1.1\win32\wshare.vcxproj'.">
</Event><Event ErrorLevel="3" Project="wshare" Source="wshare.vcproj" Description="Converted">
</Event><Event ErrorLevel="0" Project="" Source="PTypes.sln" Description="Solution converted successfully">
</Event><Event ErrorLevel="3" Project="" Source="PTypes.sln" Description="Converted">
</Event></UpgradeLog>
win32/dll_version.rc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,1,1
PRODUCTVERSION 2,1,1,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "http://www.melikyan.com/ptypes/"
VALUE "FileDescription", "C++ Portable Types Library (PTypes) DLL [MSVC]"
VALUE "FileVersion", "2, 1, 1, 1"
VALUE "InternalName", "ptypes"
VALUE "OriginalFilename", "ptypes21.dll"
VALUE "ProductName", "C++ Portable Types Library (PTypes)"
VALUE "ProductVersion", "2, 1, 1, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
win32/resource.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by dll_version.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
win32/wshare.vcproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="wshare"
ProjectGUID="{6B53FB0A-5052-4A7B-8419-7CBF117088EB}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/wshare.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
PrecompiledHeaderFile=".\Debug/wshare.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1049"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib Advapi32.lib"
OutputFile=".\Debug/wshare.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/wshare.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/wshare.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/wshare.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/wshare.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1049"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib Advapi32.lib"
OutputFile=".\Release/wshare.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/wshare.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/wshare.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir ..\bin\&#x0D;&#x0A;copy Release\wshare.exe ..\bin\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\wshare\clients.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\clients.h"
>
</File>
<File
RelativePath="..\wshare\config.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\config.h"
>
</File>
<File
RelativePath="..\wshare\log.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\log.h"
>
</File>
<File
RelativePath="..\wshare\mimetable.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\mod_about.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\mod_file.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\mod_wstat.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\modules.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\modules.h"
>
</File>
<File
RelativePath="..\wshare\request.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\request.h"
>
</File>
<File
RelativePath="..\wshare\sysutils.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\sysutils.h"
>
</File>
<File
RelativePath="..\wshare\urlutils.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\urlutils.h"
>
</File>
<File
RelativePath="..\wshare\utils.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\wshare\utils.h"
>
</File>
<File
RelativePath="..\wshare\wshare.cxx"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
win32/wshare.vcxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6B53FB0A-5052-4A7B-8419-7CBF117088EB}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\Debug/wshare.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/wshare.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Debug/wshare.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/wshare.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/wshare.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release/wshare.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/wshare.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\Release/wshare.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/wshare.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/wshare.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>mkdir ..\bin\
copy Release\wshare.exe ..\bin\
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\wshare\clients.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\config.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\log.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\mimetable.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\mod_about.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\mod_file.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\mod_wstat.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\modules.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\request.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\sysutils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\urlutils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\utils.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\wshare\wshare.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\wshare\clients.h" />
<ClInclude Include="..\wshare\config.h" />
<ClInclude Include="..\wshare\log.h" />
<ClInclude Include="..\wshare\modules.h" />
<ClInclude Include="..\wshare\request.h" />
<ClInclude Include="..\wshare\sysutils.h" />
<ClInclude Include="..\wshare\urlutils.h" />
<ClInclude Include="..\wshare\utils.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="PTypes_Lib.vcxproj">
<Project>{4a435bfe-d414-4ffa-8364-672a2b7fff01}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
win32/wshare.vcxproj.user
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
wshare/Makefile.Darwin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for MacOS X (Darwin), called from ../Makefile
#
CXX = c++
OS_CXXOPTS = -Wall
include Makefile.common
wshare/Makefile.FreeBSD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for FreeBSD, called from ../Makefile
#
CXX = g++
OS_CXXOPTS = -Wall -pthread
# OS_LDLIBS = -lc_r
include Makefile.common
wshare/Makefile.HP-UX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for HP-UX, called from ../Makefile
#
CXX = aCC
OS_CXXOPTS = -z -ext -mt +z -D_HPUX_SOURCE -D_FILE_OFFSET_BITS=64
OS_LDLIBS = -lrt
include Makefile.common
wshare/Makefile.Linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for Linux, called from ../Makefile
#
CXX = g++
OS_CXXOPTS = -Wall -pthread -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
include Makefile.common
wshare/Makefile.SunOS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for SunOS, called from ../Makefile
#
CXX = g++
OS_CXXOPTS = -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64
OS_LDLIBS = -lpthread -lsocket -lnsl -lrt
include Makefile.common
wshare/Makefile.common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Makefile for all platforms, called automatically from
# Makefile.<platform>
#
.SUFFIXES:.cxx .o
DDEBUG = -DDEBUG
INCDIR = ../include
CXXOPTS = $(OS_CXXOPTS) $(DDEBUG) -I$(INCDIR) -O2
LDLIBS = $(OS_LDLIBS)
BINDEST = ../bin
OBJS = wshare.o request.o clients.o sysutils.o urlutils.o log.o \
mimetable.o config.o utils.o modules.o \
mod_file.o mod_wstat.o mod_about.o
.cxx.o:
$(CXX) -c $(CXXOPTS) $<
all: wshare$(OS_BINEXT)
wshare$(OS_BINEXT): $(OBJS) ../lib/libptypes.a
$(CXX) $(CXXOPTS) $(OBJS) ../lib/libptypes.a $(LDLIBS) -o $@
mkdir -p $(BINDEST) ; cp $@ $(BINDEST)/
strip $(BINDEST)/$@
wshare.o: wshare.cxx clients.h request.h sysutils.h urlutils.h log.h config.h
request.o: request.cxx request.h modules.h clients.h sysutils.h urlutils.h log.h config.h
clients.o: clients.cxx clients.h log.h config.h
sysutils.o: sysutils.cxx sysutils.h utils.h
urlutils.o: urlutils.cxx urlutils.h
utils.o: utils.cxx utils.h sysutils.h urlutils.h config.h
log.o: log.cxx log.h config.h
config.o: config.cxx config.h sysutils.h
mimetable.o: mimetable.cxx config.h
modules.o: modules.cxx modules.h request.h
mod_file.o: mod_file.cxx config.h sysutils.h utils.h request.h clients.h
mod_wstat.o: mod_wstat.cxx config.h utils.h request.h clients.h
mod_about.o: mod_about.cxx config.h utils.h request.h
clean: clean-src
rm -f $(BINDEST)/wshare$(OS_BINEXT)
clean-src:
rm -f *.o
rm -f core *.core
rm -f wshare$(OS_BINEXT)
wshare/clients.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <pasync.h>
#include "config.h"
#include "log.h"
#include "clients.h"
USING_PTYPES
thread_list threads;
int thread_count;
int thread_seq;
datetime started;
thread_list::thread_list(): lock(), count(0), list(0)
{
}
thread_list::~thread_list()
{
memfree(list);
}
void thread_list::set_capacity(int icount)
{
if (list != 0)
fatal(1001, "");
count = icount;
list = (client_thread**)memalloc(sizeof(client_thread*) * count);
memset(list, 0, sizeof(client_thread*) * count);
}
void thread_list::add(client_thread* t)
{
scopewrite _lock(lock);
int i;
for (i = 0; i < count; i++)
if (list[i] == 0)
break;
if (i == count)
fatal(1002, "");
list[i] = t;
}
void thread_list::del(client_thread* t)
{
scopewrite _lock(lock);
int i;
for (i = 0; i < count; i++)
if (list[i] == t)
break;
if (i == count)
fatal(1003, "");
list[i] = 0;
}
client_thread::client_thread(ipstream* iclient)
: thread(true),
request_rec(*iclient, *iclient, iclient->get_ip()),
client(iclient), seq_num(0)
{
pincrement(&thread_count);
}
void client_thread::cleanup()
{
delete client;
threads.del(this);
}
client_thread::~client_thread()
{
pdecrement(&thread_count);
}
void client_thread::execute()
{
seq_num = pincrement(&thread_seq);
threads.add(this);
try
{
while (1)
{
request_rec::respond();
if (!client->get_active())
break;
if (!client->waitfor(DEF_KEEP_ALIVE_TIMEOUT))
break;
if (client->get_eof())
break;
reset_state();
}
}
catch(estream* e)
{
htlog_write(client_ip, req_line, rsp_code, sockout->tellx() - hdr_size, referer);
client->close();
delete e;
}
client->close();
}
wshare/clients.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_CLIENTS_H
#define W_CLIENTS_H
#include <ptime.h>
#include <pasync.h>
#include "request.h"
USING_PTYPES
class client_thread;
class thread_list
{
public:
rwlock lock;
int count;
client_thread** list;
thread_list();
virtual ~thread_list();
void set_capacity(int icount);
void add(client_thread* t);
void del(client_thread* t);
};
class client_thread: public thread, public request_rec
{
protected:
ipstream* client;
int seq_num; // sequential number, pseudo-id
virtual void execute();
virtual void cleanup();
public:
client_thread(ipstream* iclient);
virtual ~client_thread();
int get_seq_num() { return seq_num; }
};
extern thread_list threads;
extern int thread_count;
extern int thread_seq;
extern datetime started;
#endif
wshare/config.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ptypes.h"
#include "config.h"
USING_PTYPES
const char* SERVER_APP_NAME = "wshare/1.3"
#ifdef WIN32
" (Win32)";
#else
" (UNIX)";
#endif
const char* DEF_MIME_TYPE = "text/plain"; // no extension
const char* DEF_BINARY_TYPE = "application/octet-stream"; // for unix binaries with no extension
const char* STD_CSS =
"<style type=text/css>\n"
"<!--\n"
"body{font-family:Verdana,sans-serif;font-size:9pt}\n"
"h3{font-size:13pt}\n"
"pre{font-family:Courier New,cour}\n"
"-->\n"
"</style>\n";
const char* cfg_index_files[] =
{
"index.html",
"Index.html",
"default.htm",
// add your default index files here
NULL // terminator
};
// configurable parameters
string cfg_server_name;
string cfg_document_root;
int cfg_port = DEF_HTTP_PORT;
bool cfg_syslog = true;
bool cfg_dir_indexes = false;
bool cfg_def_index_files = true;
bool cfg_log_referer = true;
bool cfg_file_mtime = true;
bool cfg_daemonize = false;
string cfg_user;
string cfg_group;
string cfg_log_file;
int cfg_max_clients = DEF_MAX_CLIENTS;
int cfg_max_keep_alive = (DEF_MAX_CLIENTS * 2) / 3;
char* myname = "wshare";
static void usage()
{
static const char* usage_str =
"%s, a simple HTTP daemon.\n\n"
"usage: %s [options] document-root\n\n"
" -D daemonize, UNIX only\n"
" -d allow directory indexes\n"
" -g group group ID to run as, UNIX only\n"
" -n num maximum number of simultaneous connections (default: %d)\n"
" -o file-name write HTTP access log to file-name\n"
" -p port-num port number to listen to\n"
" -u user user ID to run as, UNIX only\n"
" -x always show directory indexes (ignore default index files)\n"
"\n";
printf(usage_str, pconst(SERVER_APP_NAME), myname, DEF_MAX_CLIENTS);
exit(255);
}
static int arg_count;
static char** args;
static char* arg_ptr;
static int arg_num;
static char* arg_param()
{
arg_ptr++;
if (*arg_ptr == 0)
{
if (++arg_num >= arg_count)
usage();
arg_ptr = args[arg_num];
}
char* res = arg_ptr;
arg_ptr += strlen(res);
return res;
}
void config_init(int argc, char* argv[])
{
arg_count = argc;
args = argv;
if (arg_count == 1)
usage();
arg_num = 1;
while (arg_num < arg_count)
{
arg_ptr = args[arg_num];
if (*arg_ptr != '-')
{
cfg_document_root = arg_ptr;
arg_num++;
continue;
}
arg_ptr++;
opt2:
switch(*arg_ptr)
{
case 'D': cfg_daemonize = true; arg_ptr++; break;
case 'd': cfg_dir_indexes = true; arg_ptr++; break;
case 'n':
cfg_max_clients = atoi(arg_param());
cfg_max_keep_alive = (cfg_max_clients * 2) / 3;
break;
case 'o': cfg_log_file = arg_param(); break;
case 'p': cfg_port = atoi(arg_param()); break;
case 'x': cfg_def_index_files = false; cfg_dir_indexes = true; arg_ptr++; break;
case 'u': cfg_user = arg_param(); break;
case 'g': cfg_group = arg_param(); break;
default: usage(); break;
}
if (*arg_ptr != 0)
goto opt2;
arg_num++;
}
if (isempty(cfg_document_root))
usage();
}
void config_done()
{
}
wshare/config.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_CONFIG_H
#define W_CONFIG_H
#include <ptypes.h>
USING_PTYPES
// things that can hardly change
#define MAX_TOKEN 4096
#define MAX_REQUEST_URI 4096
#define FILE_BUF_SIZE4096
#define SOCKET_BUF_SIZE 2048
#define DEF_HTTP_PORT 80
#define DEF_KEEP_ALIVE_TIMEOUT 15000
#define DEF_MAX_CLIENTS 30
// we no longer use strftime for HTTP time stamps, since it may
// depend on the system locale. now we build the time stamp
// `manually' instead
// #define HTTP_DATE_FMT "%a, %d %b %Y %H:%M:%S GMT"
// built-in configuration
extern const char* SERVER_APP_NAME; // "wshare/1.2 (system)"
extern const char* DEF_MIME_TYPE; // "text/plain" for files with no extension
// not implemented: extern const char* DEF_BINARY_TYPE; // "application/octet-stream" for unix binaries
extern const char* STD_CSS; // CSS for built-in responses, such like 404 Not found
extern const char* cfg_index_files[]; // index.html, Index.html and default.htm
extern const char* mimetypes[]; // built-in MIME types and extensions (in mimetable.cxx)
// configurable parameters
extern string cfg_document_root; // no default, must be specified through cmdline
extern string cfg_server_name; // default is my nodename
extern int cfg_port; // 80
extern bool cfg_dir_indexes; // allow directory indexes
extern bool cfg_def_index_files; // use default index files index.html, ...
extern string cfg_log_file; // access log file name
extern bool cfg_log_referer; // include referer in log
extern bool cfg_file_mtime; // send `last-modified' for html files
extern int cfg_max_clients; // max number of simultaneous connections, default 30
extern int cfg_max_keep_alive; // max keep-alive clients, currently 2/3 of max_clients
extern bool cfg_syslog; // write the log to stderr or to Unix syslog
extern string cfg_user; // user name to run as on Unix
extern string cfg_group; // group name to run as on Unix
extern bool cfg_daemonize; // daemonize on Unix
extern char* myname; // "wshare", for syslog
void config_init(int argc, char* argv[]);
void config_done();
#ifdef _MSC_VER
// we don't want "conditional expression is constant" warning
# pragma warning (disable: 4127)
#endif
#endif
wshare/log.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdio.h>
#include <stdarg.h>
#ifndef WIN32
# include <syslog.h>
#endif
#include <ptime.h>
#include <pasync.h>
#include "config.h"
#include "log.h"
USING_PTYPES
compref<logfile> htlog;
compref<logfile> errlog;
#ifdef WIN32
# define vsnprintf _vsnprintf
#endif
void log_init()
{
htlog = &perr;
errlog = &perr;
#ifndef WIN32
if (cfg_syslog)
openlog(myname, 0, LOG_USER);
#endif
}
void log_done()
{
#ifndef WIN32
if (cfg_syslog)
closelog();
#endif
}
void syslog_write(log_severity_t pri, const char* fmt, ...)
{
char buf[2048];
va_list va;
va_start(va, fmt);
vsnprintf(buf, sizeof(buf), fmt, va);
#ifndef WIN32
if (cfg_syslog)
{
// syslog is available only on Unix
static int upri[4] = {LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_INFO};
syslog(upri[pri], "%s", buf);
}
#endif
if (errlog != 0)
{
static pconst spri[4] = {"FATAL: ", "Error: ", "", ""};
errlog->putf("%s: %t %s%s\n", myname, now(), spri[pri], buf);
errlog->flush();
}
va_end(va);
}
void htlog_write(ipaddress ip, string request, int code, large size, string referer)
{
if (htlog == 0)
return;
if (isempty(referer))
referer = '-';
int t = tzoffset();
bool neg = t < 0;
if (neg)
t = -t;
string ssize;
if (size < 0)
ssize = '-';
else
ssize = itostring(size);
string sdate = nowstring("%d/%b/%Y:%H:%M:%S", false);
if (cfg_log_referer)
referer = " \"" + referer + '\"';
else
clear(referer);
try
{
htlog->putf("%a - - [%s %c%02d%02d] \"%s\" %d %s%s\n",
long(ip), pconst(sdate), neg ? '-' : '+', t / 60, t % 60,
pconst(request), code, pconst(ssize), pconst(referer));
htlog->flush();
}
catch (estream* e)
{
delete e;
htlog = 0;
syslog_write(SYSLOG_ERROR, "HTTP log disabled due to failed write attempt (daemonized?)");
}
}
wshare/log.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_LOG_H
#define W_LOG_H
#include <ptypes.h>
#include <pinet.h>
USING_PTYPES
enum log_severity_t {SYSLOG_FATAL, SYSLOG_ERROR, SYSLOG_WARNING, SYSLOG_INFO};
extern compref<logfile> htlog; // perr by default
extern compref<logfile> errlog; // perr, until daemonized
void log_init();
void log_done();
void syslog_write(log_severity_t pri, const char* fmt, ...);
void htlog_write(ipaddress ip, string request, int code, large size, string referer);
#endif
wshare/mimetable.awk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
#
# C++ Portable Types Library (PTypes)
# Version 2.1.1 Released 27-Jun-2007
#
# Copyright (C) 2001-2007 Hovik Melikyan
#
# http://www.melikyan.com/ptypes/
#
#
#
# Convert Apache's mime.types file to C++ declaration
#
BEGIN {
printf "//\n// Generated from Apache's mime.types file by mimetypes.awk\n//\n\n\
const char* mimetypes[] = {\n";
}
NF > 1 && substr($0, 0, 1) != "#" {
printf " ";
for (i = 2; i <= NF; i++)
printf "\".%s\", ", $i;
printf "\"%s\",\n", $1;
}
END {
printf " 0,\n};\n";
}
wshare/mimetable.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
//
// Generated from Apache's mime.types file by mimetypes.awk
//
// note that the order was changed later to bring
// more frequently used extensions to the top
const char* mimetypes[] = {
".html", ".htm", "text/html",
".css", "text/css",
".gif", "image/gif",
".jpeg", ".jpg", ".jpe", "image/jpeg",
".png", "image/png",
".js", "application/x-javascript",
".mpga", ".mp2", ".mp3", "audio/mpeg",
".mid", ".midi", ".kar", "audio/midi",
".mpeg", ".mpg", ".mpe", "video/mpeg",
".avi", "video/x-msvideo",
".zip", "application/zip",
".hqx", "application/mac-binhex40",
".xml", ".xsl", "text/xml",
".swf", "application/x-shockwave-flash",
".bin", ".dms", ".lha", ".lzh", ".exe", ".class", ".so", ".dll", "application/octet-stream",
".pdf", "application/pdf",
".asc", ".txt", "text/plain",
".doc", "application/msword",
".rtf", "text/rtf",
".ai", ".eps", ".ps", "application/postscript",
".ez", "application/andrew-inset",
".cpt", "application/mac-compactpro",
".oda", "application/oda",
".smi", ".smil", "application/smil",
".mif", "application/vnd.mif",
".xls", "application/vnd.ms-excel",
".ppt", "application/vnd.ms-powerpoint",
".wbxml", "application/vnd.wap.wbxml",
".wmlc", "application/vnd.wap.wmlc",
".wmlsc", "application/vnd.wap.wmlscriptc",
".bcpio", "application/x-bcpio",
".vcd", "application/x-cdlink",
".pgn", "application/x-chess-pgn",
".cpio", "application/x-cpio",
".csh", "application/x-csh",
".dcr", ".dir", ".dxr", "application/x-director",
".dvi", "application/x-dvi",
".spl", "application/x-futuresplash",
".gtar", "application/x-gtar",
".hdf", "application/x-hdf",
".skp", ".skd", ".skt", ".skm", "application/x-koan",
".latex", "application/x-latex",
".nc", ".cdf", "application/x-netcdf",
".sh", "application/x-sh",
".shar", "application/x-shar",
".sit", "application/x-stuffit",
".sv4cpio", "application/x-sv4cpio",
".sv4crc", "application/x-sv4crc",
".tar", "application/x-tar",
".tcl", "application/x-tcl",
".tex", "application/x-tex",
".texinfo", ".texi", "application/x-texinfo",
".t", ".tr", ".roff", "application/x-troff",
".man", "application/x-troff-man",
".me", "application/x-troff-me",
".ms", "application/x-troff-ms",
".ustar", "application/x-ustar",
".src", "application/x-wais-source",
".xhtml", ".xht", "application/xhtml+xml",
".au", ".snd", "audio/basic",
".aif", ".aiff", ".aifc", "audio/x-aiff",
".m3u", "audio/x-mpegurl",
".ram", ".rm", "audio/x-pn-realaudio",
".rpm", "audio/x-pn-realaudio-plugin",
".ra", "audio/x-realaudio",
".wav", "audio/x-wav",
".pdb", "chemical/x-pdb",
".xyz", "chemical/x-xyz",
".bmp", "image/bmp",
".ief", "image/ief",
".tiff", ".tif", "image/tiff",
".djvu", ".djv", "image/vnd.djvu",
".wbmp", "image/vnd.wap.wbmp",
".ras", "image/x-cmu-raster",
".pnm", "image/x-portable-anymap",
".pbm", "image/x-portable-bitmap",
".pgm", "image/x-portable-graymap",
".ppm", "image/x-portable-pixmap",
".rgb", "image/x-rgb",
".xbm", "image/x-xbitmap",
".xpm", "image/x-xpixmap",
".xwd", "image/x-xwindowdump",
".igs", ".iges", "model/iges",
".msh", ".mesh", ".silo", "model/mesh",
".wrl", ".vrml", "model/vrml",
".rtx", "text/richtext",
".sgml", ".sgm", "text/sgml",
".tsv", "text/tab-separated-values",
".wml", "text/vnd.wap.wml",
".wmls", "text/vnd.wap.wmlscript",
".etx", "text/x-setext",
".qt", ".mov", "video/quicktime",
".mxu", "video/vnd.mpegurl",
".movie", "video/x-sgi-movie",
".ice", "x-conference/x-cooltalk",
0,
};
wshare/mod_about.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "config.h"
#include "utils.h"
#include "request.h"
//
// a sample path handler that responds to http://hostname/.about
// see modules.h and request.h for details
//
void handle_about(request_rec& req)
{
req.keep_alive = false; // we don't know the content length
// all responses must start with begin_response() and end with end_response()
req.begin_response(200, "OK");
// use put_xxx functions (see request.h) to send response headers back to the
// client. these functions do nothing if the request version was HTTP/0.9
req.put_content_type("text/html");
// end_headers() must be called when you're done with the headers.
// if the method was HEAD, it throws an ehttp exception so that the
// rest of your code won't be executed
req.end_headers();
std_html_header(*req.sockout, "about wshare");
// you can write to the client socket using req.sockout, which is an outstm object
req.sockout->putf("<p>%s<br>\n"
"<a href=\"http://www.melikyan.com/ptypes/\">PTypes</a> (C++ Portable Types Library)\n"
"demo program<br>\n"
"written by Hovik Melikyan</p>\n", SERVER_APP_NAME);
std_html_footer(*req.sockout);
// end_response() throws an ehttp exception. the request info is being logged.
req.end_response();
}
wshare/mod_file.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
//
// file handling module; registered as a path handler for '/'
//
#include <limits.h>
#include "config.h"
#include "modules.h"
#include "request.h"
#include "utils.h"
class file_req: public file_request_rec
{
protected:
request_rec* req;
void analyze_uri();
void rsp_dir_index();
void rsp_file();
public:
file_req(request_rec* req);
~file_req();
void respond();
};
file_req::file_req(request_rec* ireq): file_request_rec(), req(ireq)
{
}
file_req::~file_req()
{
}
void file_req::analyze_uri()
{
abs_path = cfg_document_root + '/';
rel_path = '/';
file_type = FT_DIRECTORY;
// analyze path components one by one and stop where the
// component does not exist, or where we see a file, not a
// directory. note, that the request-uri may be longer and
// may contain extra components which are ignored. f.ex.
// the request uri is /dir/file.html/other/stuff/. the
// scan stops at file.html and ignores the rest. this is the
// way apache and most other daemons work.
// besides, we may pass a non-existent path to a registered
// path handler.
for (int p = 0; p < req->path_parts.get_count(); ++p)
{
string s = req->path_parts.getkey(p);
abs_path += s;
rel_path += s;
file_type = get_file_type(abs_path);
if (file_type == FT_DIRECTORY)
{
abs_path += '/';
rel_path += '/';
}
else if (file_type == FT_FILE)
{
file_name = s;
break;
}
else if (file_type == FT_OTHER) // pipe or device
req->rsp_forbidden();
else
req->rsp_not_found();
}
if (file_type == FT_DIRECTORY)
{
// check for the trailing slash and redirect to the canonical
// form if necessary
if (trail_char(req->url.path) != '/')
{
req->url.path += '/';
req->rsp_redirect(urlcreate(req->url));
}
// find the default index file
if (cfg_def_index_files)
{
const char** idx = cfg_index_files;
while (*idx != nil)
{
string t = abs_path + *idx;
if (is_file(t))
{
abs_path = t;
file_type = FT_FILE;
file_name = *idx;
break;
}
idx++;
}
}
}
// other useful info about the object
sym_link = is_symlink(abs_path);
executable = is_executable(abs_path);
if (!isempty(file_name))
{
file_ext = get_file_ext(file_name);
handler_info* h = find_file_handler(file_ext);
if (h != 0)
{
file_callback(h->callback)(*req, *this);
// the handler must throw an ehttp exception
fatal(251, "Internal error 251");
}
}
}
void file_req::rsp_dir_index()
{
if (!cfg_dir_indexes)
req->rsp_dir_index_forbidden();
filist list(SL_SORTED | SL_CASESENS | SL_OWNOBJECTS);
get_directory(list, abs_path, true, 500);
if (list.get_count() == 0)
req->rsp_forbidden();
// we don't know the length of the resulting file
req->keep_alive = false;
req->begin_response(200, "OK");
req->put_content_type("text/html");
req->end_headers();
// build an index HTML page
std_html_header(*req->sockout, "Index of " + rel_path);
req->sockout->put("<hr noshade size=1>\n");
req->sockout->put("<pre>\n");
html_show_file_list(*req->sockout, list);
list.clear();
get_directory(list, abs_path, false, 500);
html_show_file_list(*req->sockout, list);
req->sockout->put("</pre>\n");
std_html_footer(*req->sockout);
req->end_response();
}
void file_req::rsp_file()
{
// .ht* files are forbidden, like with Apache
if (strncmp(file_name, ".ht", 3) == 0)
req->rsp_forbidden();
large fsize64 = get_file_size(abs_path);
if (fsize64 < 0)
req->rsp_not_found();
// test the file for readability
infile f(abs_path);
try
{
f.set_bufsize(0);
f.open();
}
catch(estream* e)
{
delete e;
req->rsp_forbidden();
}
// partial content
large txsize = fsize64;
if (req->partial)
{
if (req->range_max == -1)
req->range_max = fsize64 - 1;
if (req->range_min >= 0 && req->range_min < req->range_max && req->range_max < fsize64)
txsize = req->range_max - req->range_min + 1;
else
req->partial = false;
}
// send headers
datetime fmtime = get_file_mtime(abs_path);
if (req->if_modified != invdatetime && fmtime != invdatetime && fmtime <= req->if_modified)
req->rsp_not_modified();
if (req->partial)
req->begin_response(206, "Partial Content");
else
req->begin_response(200, "OK");
req->put_content_type(get_mimetype(abs_path));
req->put_content_length(txsize);
if (req->partial)
req->put_header("Content-Range",
"bytes " + itostring(req->range_min) + '-' + itostring(req->range_max) + '/' + itostring(fsize64));
if (cfg_file_mtime)
req->put_header("Last-Modified", http_time_stamp(fmtime));
req->end_headers();
// send content
if (req->partial)
f.seekx(req->range_min);
char buf[FILE_BUF_SIZE];
while (txsize > 0)
{
int toread = sizeof(buf);
if (toread > txsize)
toread = (int)txsize;
int r = f.read(buf, toread);
if (r <= 0)
break;
req->sockout->write(buf, r);
txsize -= r;
}
// if for some reason the number of bytes sent does not correspond to the
// promised content length, just close the connection
if (txsize != 0)
req->keep_alive = false;
req->end_response();
}
void file_req::respond()
{
if (req->method != HTTP_GET && req->method != HTTP_HEAD)
req->rsp_bad_method("GET, HEAD");
analyze_uri();
if (file_type == FT_DIRECTORY)
rsp_dir_index();
else if (file_type == FT_FILE)
rsp_file();
else
req->rsp_not_found();
}
void handle_file(request_rec& req)
{
file_req freq(&req);
freq.respond();
}
wshare/mod_wstat.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "config.h"
#include "utils.h"
#include "request.h"
#include "clients.h"
const char* stat_str[STAT_MAX] = {"READ ", "WRITE ", "WAIT "};
static ipaddress localhost(127, 0, 0, 1);
static void show_lifetime(outstm* sockout, datetime t)
{
datetime diff = now() - t;
int d = days(diff);
if (d > 0)
sockout->putf("%dd ", d);
sockout->put(dttostring(diff, "%H:%M:%S"));
}
void handle_wstat(request_rec& req)
{
// only requests from localhost are allowed
if (req.client_ip != localhost)
req.rsp_forbidden();
req.keep_alive = false;
req.begin_response(200, "OK");
req.put_content_type("text/html");
req.end_headers();
std_html_header(*req.sockout, "wshare status report");
req.sockout->put("<pre>\n");
req.sockout->putf(" Requests: %d\n", thread_seq);
req.sockout->put(" Running: ");
show_lifetime(req.sockout, ::started);
req.sockout->put("\n\n");
req.sockout->put(" Client Status Lifetime Request\n");
req.sockout->put("<hr noshade size=1>\n");
for (int i = 0; i < threads.count; i++)
{
if (threads.list[i] == 0)
continue;
// copy all parameters to local vars to free the thread_list mutex earlier
ipaddress tclient_ip = 0;
req_stat_t tstat = STAT_READ;
datetime tstarted = invdatetime;
string treq_line;
{
scoperead _lock(threads.lock);
client_thread* t = threads.list[i];
if (t != 0)
{
tclient_ip = t->client_ip;
tstat = t->stat;
tstarted = t->started;
treq_line = t->req_line;
}
}
if (tclient_ip == 0)
continue;
req.sockout->putf(" %-15s %s", pconst(iptostring(tclient_ip)), stat_str[tstat]);
show_lifetime(req.sockout, tstarted);
req.sockout->put(" ");
html_encode(*req.sockout, treq_line);
req.sockout->put("\n");
}
req.sockout->put("</pre>\n");
std_html_footer(*req.sockout);
req.end_response();
}
wshare/modules.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include "request.h"
#include "modules.h"
USING_PTYPES
static handler_info* method_list;
static handler_info* path_list;
static handler_info* file_list;
handler_info::handler_info(handler_info* inext, void* icallback, const string& iparam)
: next(inext), callback(icallback), param(iparam)
{
}
void add_method_handler(const string& method, method_callback cb)
{
method_list = new handler_info(method_list, (void*)cb, method);
}
void add_path_handler(const string& path, path_callback cb)
{
path_list = new handler_info(path_list, (void*)cb, path);
}
void add_file_handler(const string& ext, file_callback cb)
{
file_list = new handler_info(file_list, (void*)cb, ext);
}
handler_info* find_handler(handler_info* list, const string& param)
{
while (list != 0)
{
if (list->param == param)
return list;
list = list->next;
}
return 0;
}
handler_info* find_method_handler(const string& method)
{
return find_handler(method_list, method);
}
handler_info* find_path_handler(const string& path)
{
return find_handler(path_list, path);
}
handler_info* find_file_handler(const string& ext)
{
return find_handler(file_list, ext);
}
void init_handlers()
{
ADD_PATH_HANDLER("/", handle_file);
ADD_PATH_HANDLER("/.about", handle_about);
ADD_PATH_HANDLER("/.wstat", handle_wstat);
}
wshare/modules.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_MODULES_H
#define W_MODULES_H
#include <ptypes.h>
#include "request.h"
USING_PTYPES
//
// wshare modules API
//
// we currently only support statically linked handlers. all handlers
// receive request_rec& as a parameter and must respond by either
// calling one of the request_rec::rsp_XXX standard functions, or by
// performing some actions and giving the ehttp exception with the HTTP
// response code as a parameter. all public methods and fields of
// request_rec are at your disposal. all rsp_XXX methods throw exceptions
// of type ehttp, so they never return to the caller.
// the following macros must be placed in init_handlers() (modules.cxx)
// for each new handler. the handler callback must exist somewhere and
// must be linked to wshare. these macros declare your callback functions
// as extern's, so you don't need to do it elsewhere.
// there are three types of handlers:
// method handlers are called whenever an unknown HTTP method is found
// in the request line. the rest of input data must be processed by this
// handler. you can call request_rec::parse_XXX if the request is
// HTTP/1.1-like. default methods can be overridden.
#define ADD_METHOD_HANDLER(method,callback) \
extern void callback(request_rec&); \
add_method_handler(method, callback);
// path handlers are called when the request-URI matches the path for a
// registered handler. the request-URI path is checked one path_part at
// a time against the paths given here. the longest match wins:
// ex.: consider the uri path "/stuff/things/widget" matched against
// this handler list:
// "/" --> matches, but not the longest
// "/stuff" --> matches, but not the longest
// "/stuff/things" --> matches, the longest match
// "/stuff/things/gizmo --> doesn't match
// "/stuff/thin" --> doesn't match (partial parts are not matched)
// all request_rec fields up to `parts_used' inclusive contain valid values
// which can be used by this handler. It is also up to the handler to check
// that it can deal with the requested method (GET/HEAD/POST)
// the path parameter must contain the leading slash, and must not
// contain the trailing slash.
#define ADD_PATH_HANDLER(path,callback) \
extern void callback(request_rec&); \
add_path_handler(path, callback);
// file handlers are called for specific file extensions for
// existing files. the ext paramter is the extension this handler
// wishes to handle. the ext parameter must contain the leading dot.
#define ADD_FILE_HANDLER(ext,callback) \
extern void callback(request_rec&); \
add_file_handler(ext, callback);
// all handler functions must be of the following types (depending on the
// handler type):
typedef void (*method_callback)(request_rec& req);
typedef void (*path_callback)(request_rec& req);
typedef void (*file_callback)(request_rec& req, file_request_rec& freq);
//
// internal module management
//
struct handler_info
{
handler_info* next;
void* callback;
string param;
handler_info(handler_info*, void*, const string&);
};
handler_info* find_method_handler(const string& method);
handler_info* find_path_handler(const string& path);
handler_info* find_file_handler(const string& ext);
void init_handlers();
void add_method_handler(const string& method, method_callback);
void add_path_handler(const string& path, path_callback);
void add_file_handler(const string& ext, file_callback);
#endif
wshare/request.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "config.h"
#include "log.h"
#include "utils.h"
#include "sysutils.h"
#include "request.h"
#include "clients.h"
#include "modules.h"
USING_PTYPES
const char* http_version_str[HTTP_VER_MAX] = {"", "HTTP/1.0", "HTTP/1.1", "HTTP/1.1"};
// const char* http_method_str[HTTP_METHOD_MAX] = {"GET", "HEAD", ""};
request_rec::request_rec(instm& isockin, outstm& isockout, ipaddress iclient_ip)
: started(now()), rsp_code(0), stat(STAT_READ), sockin(&isockin), sockout(&isockout), client_ip(iclient_ip),
version(HTTP_VER_10), method(HTTP_GET), method_str(), keep_alive(false), if_modified(invdatetime),
req_line(), uri(), host(), referer(), partial(false), range_min(0), range_max(0), headers(),
url(), path_parts(), user(0),
location(), hdr_size(0)
{
}
void request_rec::reset_state()
{
rsp_code = 0;
version = HTTP_VER_10;
method = HTTP_GET;
clear(method_str);
keep_alive = false;
if_modified = invdatetime;
clear(req_line);
clear(uri);
path_parts.clear();
clear(host);
clear(referer);
partial = false;
range_min = 0;
range_max = 0;
headers.clear();
urlclear(url);
delete user;
user = 0;
clear(location);
hdr_size = 0;
}
request_rec::~request_rec()
{
delete user;
}
void request_rec::put_header(const char* name, const char* value)
{
if (version > HTTP_VER_09)
{
sockout->put(name);
sockout->put(": ");
sockout->put(value);
sockout->put("\r\n");
}
}
void request_rec::put_header(const char* name, const string& value)
{
if (version > HTTP_VER_09)
{
sockout->put(name);
sockout->put(": ");
sockout->put(value);
sockout->put("\r\n");
}
}
void request_rec::put_content_type(const char* mime)
{
put_header("Content-Type", mime);
}
void request_rec::put_content_length(large length)
{
if (method != HTTP_HEAD)
put_header("Content-Length", itostring(length));
}
void request_rec::end_headers()
{
if (version > HTTP_VER_09)
sockout->put("\r\n");
hdr_size = sockout->tell();
if (method == HTTP_HEAD)
end_response();
}
void request_rec::begin_response(int code, const char* msg)
{
rsp_code = code;
stat = STAT_WRITE;
if (version > HTTP_VER_09)
{
sockout->putf("%s %d %s\r\n", http_version_str[version], code, msg);
put_header("Date", http_time_stamp(now(true)));
put_header("Server", SERVER_APP_NAME);
// put_header("Accept-Ranges", "bytes");
if (!isempty(location))
put_header("Location", location);
static const char* sconn[2] = {"close", "keep-alive"};
if (version < HTTP_VER_11)
put_header("Connection", sconn[keep_alive]);
else if (!keep_alive) // HTTP/1.1
put_header("Connection", "close");
}
}
void request_rec::std_response(bool conn_close, int code, const char* msg, const char* descr)
{
if (conn_close)
keep_alive = false;
// we need a memory stream to temporarily store the response
outmemory s(4096);
string smsg = msg;
// write out the standard response page in HTML format
// to the memory stream
s.open();
if (strlen(descr) != 0)
{
std_html_header(s, itostring(code) + ' ' + smsg);
s.put("<p>");
html_encode(s, descr);
s.put("</p>\n");
std_html_footer(s);
}
// send the response
begin_response(code, msg);
if (s.tell() > 0) // some responses do not return any content, e.g. 304
{
put_content_type("text/html");
put_content_length(s.tell());
}
end_headers();
if (s.tell() > 0)
sockout->put(s.get_strdata());
end_response();
}
void request_rec::std_response(bool conn_close, int code, const char* msg, const char* descr, const string& dparam)
{
char buf[1024];
snprintf(buf, sizeof(buf), descr, pconst(dparam));
std_response(conn_close, code, msg, buf);
}
void request_rec::rsp_not_found()
{
std_response(false, 404, "Not found", "The requested object %s was not found on this server.", url.path);
}
void request_rec::rsp_bad_request()
{
std_response(true, 400, "Bad request", "Your browser sent a request that this server could not understand.");
}
void request_rec::rsp_bad_method(const char* ok_methods)
{
put_header("Allow", ok_methods);
std_response(true, 405, "Method not allowed", "Method %s not allowed for this resource", method_str);
}
void request_rec::rsp_uri_too_long()
{
std_response(true, 414, "Request-URI too long", "The request-URI string sent by your browser is too long.");
}
void request_rec::rsp_forbidden()
{
std_response(false, 403, "Forbidden", "You don't have permission to access %s on this server", url.path);
}
void request_rec::rsp_dir_index_forbidden()
{
std_response(false, 403, "Directory index forbidden", "Directory index forbidden: %s", url.path);
}
void request_rec::rsp_redirect(const string& newurl)
{
location = newurl;
std_response(false, 301, "Moved permanently", "The document has moved to %s", newurl);
}
void request_rec::rsp_overloaded()
{
std_response(true, 503, "Service unavailable", "The server is overloaded. Please, try again later.");
}
void request_rec::rsp_not_modified()
{
std_response(false, 304, "Not modified", "");
}
void request_rec::abort_request()
{
#ifdef DEBUG
syslog_write(SYSLOG_WARNING, "Request from %s aborted", pconst(iptostring(client_ip)));
#endif
keep_alive = false;
throw ehttp(0);
}
void request_rec::end_response()
{
throw ehttp(rsp_code);
}
//
// request parsers
//
const cset method_chars = "A-Z";
const cset uri_chars = "~21-~FF";
const cset field_chars = uri_chars - cset(":");
const cset ws_chars = "~20";
string request_rec::get_token(const cset& chars)
{
char buf[MAX_TOKEN];
int bufsize = sockin->token(chars, buf, sizeof(buf));
if (bufsize == 0 || bufsize >= MAX_TOKEN)
rsp_bad_request();
return string(buf, bufsize);
}
string request_rec::get_uri()
{
char buf[MAX_REQUEST_URI];
int bufsize = sockin->token(uri_chars, buf, sizeof(buf));
if (bufsize == 0)
rsp_bad_request();
if (bufsize >= MAX_REQUEST_URI)
rsp_uri_too_long();
return string(buf, bufsize);
}
void request_rec::parse_method()
{
while (!sockin->get_eof() && sockin->get_eol())
sockin->skipline();
method_str = get_token(method_chars);
req_line = method_str;
// try to pass this method to a registered method handler.
// the rest of the request line can be parsed using
// parse_request_line(), if it's HTTP/1.1-like.
handler_info* h = find_method_handler(method_str);
if (h != 0)
{
method_callback(h->callback)(*this);
// the handler must throw an ehttp exception
fatal(252, "Internal error 252");
}
// otherwise use the internal method handlers
else if (method_str == "GET")
method = HTTP_GET;
else if (method_str == "HEAD")
method = HTTP_HEAD;
else if (length(method_str) == 0)
abort_request();
else
rsp_bad_method("GET, HEAD");
}
void request_rec::parse_request_line()
{
if (sockin->skiptoken(ws_chars) == 0)
abort_request();
// read the request URI
uri = get_uri();
req_line += ' ' + uri;
// read the version number, if present
if (sockin->get_eol())
version = HTTP_VER_09;
else
{
string s;
if (sockin->skiptoken(ws_chars) == 0)
abort_request();
s = get_token(uri_chars);
req_line += ' ' + s;
const char* p = s;
if (length(s) < 8 || strncmp(p, "HTTP/1.", 7) != 0)
rsp_bad_request();
if (p[7] == '0')
version = HTTP_VER_10;
else if (p[7] == '1')
version = HTTP_VER_11;
else
version = HTTP_VER_UNKNOWN; // 1.x is ok for us
}
// HTTP/1.1 requires to keep the connection alive by default;
// can be overridden by `Connection:' header
keep_alive = version >= HTTP_VER_11;
if (!sockin->get_eol())
rsp_bad_request();
if (version > HTTP_VER_09)
sockin->skipline();
}
void request_rec::parse_hdr(string& fname, string& fvalue)
{
fname = get_token(field_chars); // read the field name
sockin->skiptoken(ws_chars);
if (sockin->get() != ':') // malformed header (no colon)
rsp_bad_request();
do {
sockin->skiptoken(ws_chars); // skip leading ws chars
do {
if (sockin->get_eol()) // the value may be empty (?)
break;
string t = get_token(uri_chars); // read field value
if (!isempty(fvalue))
fvalue += ' ';
fvalue += t;
if (length(fvalue) > MAX_TOKEN)
rsp_bad_request();
// according to RFC2616 all ws chars inside the field value
// can become a single space
} while (sockin->skiptoken(ws_chars) > 0);
if (!sockin->get_eol())
rsp_bad_request();
sockin->skipline();
} while (sockin->preview() & ws_chars); // see if field value continues on the next line
}
void request_rec::parse_headers()
{
while (!sockin->get_eol())
{
string fname, fvalue;
parse_hdr(fname, fvalue);
fname = lowercase(fname);
if (fname == "host")
host = fvalue;
else if (fname == "connection")
{
fvalue = lowercase(fvalue);
if (fvalue == "close")
keep_alive = false;
else if (fvalue == "keep-alive")
keep_alive = true;
}
else if (fname == "if-modified-since")
{
if_modified = parse_http_date(fvalue);
if (if_modified == invdatetime)
rsp_bad_request();
}
else if (fname == "referer")
referer = fvalue;
else if (fname == "range")
{
if (strncmp(fvalue, "bytes=", 6) == 0)
{
del(fvalue, 0, 6);
const char* p = fvalue;
char* e;
int rmin = strtol(p, &e, 10);
if (*e == '-')
{
p = e + 1;
int rmax = strtol(p, &e, 10);
if (e == p)
rmax = -1;
// we don't support multiple ranges, neither negative ranges
if (*e == 0 && rmin >= 0)
{
partial = true;
range_min = rmin;
range_max = rmax;
}
}
}
}
// other headers go to request_rec::headers for use in
// custom plugins/modules. so called "coalesce" headers
// are not supported yet
else
headers.put(fname, fvalue);
}
// convert the referer URI to relative if on the same host
if (!isempty(referer))
{
string s = "http://" + host;
if (strncmp(s, referer, length(s)) == 0)
del(referer, 0, length(s));
if (isempty(referer))
referer = "/";
}
sockin->skipline();
}
void request_rec::parse_uri()
{
string s = uri;
if (!isurl(uri))
{
// if request URI is just a path
if (*pconst(uri) != '/')
rsp_bad_request();
if (version > HTTP_VER_09 && isempty(host))
rsp_bad_request();
s = "http://" + host + uri;
}
urlcrack(s, url);
// split the path into components
split_path(url.path, path_parts);
}
void request_rec::analyze_uri()
{
// analyze path components one by one and stop at the longest
// match that has a path handler. note that the request-uri
// may be longer and may contain extra components which are
// ignored, but left intact to be used by the handler.
string path = "/";
handler_info* handler = find_path_handler(path);
for (int i = 0; i < path_parts.get_count(); i++)
{
path += path_parts.getkey(i);
handler_info* h = find_path_handler(path);
if (h != 0)
handler = h;
path += "/";
}
if (handler == 0)
rsp_not_found();
path_callback(handler->callback)(*this);
// the handler must throw an ehttp exception
fatal(253, "Internal error 253");
}
void request_rec::respond()
{
try
{
if (thread_count > cfg_max_clients)
rsp_overloaded();
parse_method();
parse_request_line();
parse_headers();
parse_uri();
analyze_uri();
// all branches must throw an ehttp exception
// before reaching this point
fatal(254, "Internal error 254");
}
catch(ehttp e)
{
if (keep_alive)
{
sockout->flush();
stat = STAT_WAIT;
}
else
{
sockin->close();
sockout->close();
}
htlog_write(client_ip, req_line, e.code, sockout->tellx() - hdr_size, referer);
}
}
wshare/request.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_REQUEST_H
#define W_REQUEST_H
#include <ptypes.h>
#include <pstreams.h>
#include <pinet.h>
#include "sysutils.h"
#include "urlutils.h"
USING_PTYPES
enum http_version_t {
HTTP_VER_09,
HTTP_VER_10,
HTTP_VER_11,
HTTP_VER_UNKNOWN,
HTTP_VER_MAX
};
enum http_method_t {
HTTP_GET,
HTTP_HEAD,
HTTP_OTHER,
HTTP_METHOD_MAX
};
enum req_stat_t
{
STAT_READ,
STAT_WRITE,
STAT_WAIT,
STAT_MAX
};
struct ehttp
{
int code;
ehttp(int icode): code(icode) {}
};
class request_rec
{
public:
datetime started;
int rsp_code; // rsp: response code, set through begin_response(), used for logging
req_stat_t stat; // for status requests: READ, WRITE or WAIT (if keep-alive)
instm* sockin; // client input stream
outstm* sockout; // client output stream
ipaddress client_ip; // req: client's IP
http_version_t version; // req/rsp: HTTP version, 0.9, 1.0, 1.1 or 1.*
http_method_t method; // req: HTTP method, currently GET or HEAD
string method_str; // method string, for other method handlers
bool keep_alive; // req/rsp: whether to close the connection; determined
// based on the HTTP version and the "Connection:" header;
// can be forced to false for some response types, e.g. 400 Bad Request
datetime if_modified; // req: "If-modified-since:" if present, invdatetime otherwise
string req_line; // req: the whole request line, e.g. "GET / HTTP/1.1"
string uri; // req: request-URI, as is
string host; // req: "Host:" header, if present
string referer; // req: "Referer:"; may be converted to relative URI
bool partial; // req: partial content requested (see rsp_file())
large range_min; // req: partial content
large range_max; // req: partial content
textmap headers; // other headers
// requested object info
urlrec url; // req: the request-URI parsed and split into components
strlist path_parts; // request-URI path split into components
unknown* user; // user data for custom handlers, freed automatically by ~request_rec()
// helpers for method handlers
string get_token(const cset& chars);
string get_uri();
void parse_request_line(); // ... excluding the method string
void parse_hdr(string& fname, string& fvalue);
void parse_uri(); // sets url and path_parts fields
void analyze_uri(); // sets all fields starting from file_type
// response utilities; headers are not sent if the HTTP version is 0.9
void begin_response(int code, const char* msg);
void put_header(const char* name, const char* value);
void put_header(const char* name, const string& value);
void put_content_type(const char* mime);
void put_content_length(large length);
void end_headers();
void std_response(bool conn_close, int code, const char* msg, const char* descr);
void std_response(bool conn_close, int code, const char* msg, const char* descr, const string& dparam);
// standard responses; all functions of this group raise ehttp exceptions
void rsp_not_found();
void rsp_bad_request();
void rsp_bad_method(const char* ok_methods);
void rsp_uri_too_long();
void rsp_forbidden();
void rsp_dir_index_forbidden();
void rsp_overloaded();
void abort_request();
void rsp_redirect(const string& newurl);
void rsp_not_modified();
void end_response();
protected:
string location; // rsp: add "Location:" header to the response; set through
// rsp_redirect()
int hdr_size; // byte size of response headers; used for logging, to determine
// the actual response content length (see respond())
// request parsers
void parse_method();
void parse_headers();
// the boss
void respond();
// reset the state between requests when keep-alive
void reset_state();
request_rec(instm& isockin, outstm& isockout, ipaddress iclient_ip);
~request_rec();
};
// this structure is created and handled in mod_file, however, we
// declare it here since this information can be passed to the
// file extension handlers.
class file_request_rec
{
public:
file_type_t file_type; // file, directory or other (device or pipe)
bool sym_link; // the object is a symbolic link (Unix only)
bool executable; // the object is executable (binary on Unix, .exe on Windows)
string abs_path; // absolute file path to the requested object
string rel_path; // file path to the requested object relative to document root,
// may not be the same as url.path
string file_name; // file name
string file_ext; // file extension, including the leading dot
file_request_rec(): file_type(FT_ERROR), sym_link(false), executable(false),
abs_path(), rel_path(), file_name(), file_ext() {}
~file_request_rec() {}
};
#endif
wshare/sysutils.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
# include <windows.h>
# include <io.h>
# include <direct.h>
#else
# include <fcntl.h>
# include <unistd.h>
# include <sys/utsname.h>
# include <dirent.h>
# include <limits.h>
# include <sys/param.h>
# include <pwd.h>
# include <grp.h>
#endif
#include <pport.h>
#include "sysutils.h"
#include "utils.h"
USING_PTYPES
void throw_msg(const string& msg)
{
throw new exception(msg);
}
static char* nodename = 0;
static char* username = 0;
char* get_nodename()
{
if (nodename == 0)
{
#ifdef WIN32
char buf[MAX_COMPUTERNAME_LENGTH + 1];
unsigned long bufsize = sizeof(buf);
if (!GetComputerName(buf, &bufsize))
fatal(1001, "GetComputerName() failed");
nodename = strdup(buf);
#else
struct utsname u;
if (uname(&u) < 0)
fatal(1001, "Couldn't get the node name");
nodename = strdup(u.nodename);
#endif
}
return nodename;
}
char* get_username()
{
if (username == 0)
{
#ifdef WIN32
char buf[256 + 1];
unsigned long bufsize = sizeof(buf);
if (!GetUserName(buf, &bufsize))
fatal(1002, "GetUserName() failed");
username = strdup(buf);
#else
struct passwd* pw = getpwuid(getuid());
if (pw == 0)
fatal(1001, "Couldn't get the user name");
username = strdup(pw->pw_name);
#endif
}
return username;
}
#ifdef WIN32
int get_user_id(const char*)
{
return 0;
#else
int get_user_id(const char* user_name)
{
struct passwd* pw = getpwnam(user_name);
if (pw == 0)
return -1;
else
return pw->pw_uid;
#endif
}
#ifdef WIN32
int get_user_gid(const char*)
{
return 0;
#else
int get_user_gid(const char* user_name)
{
struct passwd* pw = getpwnam(user_name);
if (pw == 0)
return -1;
else
return pw->pw_gid;
#endif
}
#ifdef WIN32
int get_group_id(const char*)
{
return 0;
#else
int get_group_id(const char* group_name)
{
struct group* gr = getgrnam(group_name);
if (gr == 0)
return -1;
else
return gr->gr_gid;
#endif
}
#ifdef WIN32
string get_group_name(int)
{
return nullstring;
#else
string get_group_name(int gid)
{
struct group* gr = getgrgid(gid);
if (gr == 0)
return nullstring;
else
return gr->gr_name;
#endif
}
file_type_t get_file_type(const char* name)
{
struct stat st;
if (stat(name, &st) != 0)
return FT_ERROR;
if ((st.st_mode & S_IFDIR) == S_IFDIR)
return FT_DIRECTORY;
if ((st.st_mode & S_IFREG) == S_IFREG)
return FT_FILE;
return FT_OTHER;
}
#ifdef WIN32
bool is_symlink(const char*)
{
return false;
#else
bool is_symlink(const char* name)
{
struct stat st;
if (lstat(name, &st) != 0)
return false;
return (st.st_mode & S_IFLNK) == S_IFLNK;
#endif
}
#ifdef WIN32
bool is_executable(const char* name)
{
return stricmp(get_file_ext(name), ".exe") == 0;
#else
bool is_executable(const char* name)
{
struct stat st;
if (stat(name, &st) != 0)
return false;
return (st.st_mode & S_IXOTH) == S_IXOTH;
#endif
}
large get_file_size(const char* name)
{
#ifdef WIN32
struct __stat64 st;
if (_stat64(name, &st) != 0)
#else
struct stat st;
if (stat(name, &st) != 0)
#endif
return -1;
return st.st_size;
}
datetime get_file_mtime(const char* name)
{
struct stat st;
if (stat(name, &st) != 0)
return invdatetime;
return utodatetime(st.st_mtime);
}
#if defined(__sun__) || defined(__hpux)
int daemon(int nochdir, int noclose) {
int fd;
switch (fork())
{
case -1:
return -1;
case 0:
break;
default:
exit(0);
}
if (setsid() == -1)
return -1;
if (!nochdir)
chdir("/");
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1)
{
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2)
close(fd);
}
return 0;
}
#elif defined WIN32
int daemon(int nochdir, int)
{
if (!nochdir)
chdir("/");
return 0;
}
#endif
#ifdef WIN32
void downgrade(const string&, string&)
{
#else
void downgrade(const string& user, string& group)
{
int uid = get_user_id(user);
if (uid < 0)
throw_msg("Unknown user: " + user);
int gid;
if (isempty(group))
{
gid = get_user_gid(user);
group = get_group_name(gid);
}
else
gid = get_group_id(group);
if (gid < 0)
throw_msg("Unknown group: " + group);
if (setgid(gid) < 0)
throw_msg("Couldn't change effective user/group ID (not root?)");
if (initgroups(user, gid))
throw_msg("initgroups() failed"); // what else can we say here?
if (setuid(uid) < 0)
throw_msg("Couldn't change effective user ID (not root?)");
#endif
}
file_info::file_info(const char* iname, large isize, datetime imodified)
: name(iname), size(isize), modified(imodified) {}
void get_directory(filist& s, string path, bool dirs, int maxfiles)
{
#ifdef WIN32
path += "*.*";
_finddatai64_t f;
int h = _findfirsti64((char*)pconst(path), &f); // this stupid typecast is for BCC
if (h < 0)
return;
do
{
if (((f.attrib & _A_SUBDIR) != 0) == dirs)
{
string t = f.name;
if (t == '.')
continue;
if (dirs)
t += '/';
s.add(t, new file_info(t, f.size, utodatetime(f.time_write)));
}
}
while (_findnexti64(h, &f) == 0 && s.get_count() < maxfiles);
_findclose(h);
#else
if (path != '/' && trail_char(path) == '/')
trunc_trail_char(path);
DIR* dir = opendir(path);
if (dir == 0)
return;
dirent* de;
while ((de = readdir(dir)) != 0 && s.get_count() < maxfiles)
{
string name = de->d_name;
if (name == '.')
continue;
string fullname = path + '/' + name;
#if defined(__sun__) || defined(__hpux) || defined(__CYGWIN__)
file_type_t ft = get_file_type(fullname);
if ((ft == FT_DIRECTORY) != dirs)
continue;
if (ft != FT_DIRECTORY && ft != FT_FILE && !is_symlink(fullname))
continue;
#else
if ((de->d_type == DT_DIR) != dirs)
continue;
if (de->d_type != DT_DIR && de->d_type != DT_REG && de->d_type != DT_LNK)
continue;
#endif
large size = 0;
if (dirs)
name += '/';
else
size = get_file_size(fullname);
datetime mtime = get_file_mtime(fullname);
s.add(name, new file_info(name, size, mtime));
}
closedir(dir);
#endif
}
string absolute_path(const string& rel)
{
string abs;
#ifdef WIN32
setlength(abs, 4096);
char* p = unique(abs);
_fullpath(p, rel, 4096);
while (*p != 0)
{
if (*p == '\\')
*p = '/';
p++;
}
#else
# ifdef PATH_MAX
int path_max = PATH_MAX;
# else
int path_max = pathconf(path, _PC_PATH_MAX);
if (path_max <= 0)
path_max = 4096;
# endif
setlength(abs, path_max);
char* p = unique(abs);
realpath(rel, p);
#endif
return pconst(abs);
}
string get_file_ext(const string& name)
{
const char* e = pconst(name) + length(name);
int len = 0;
while (e > pconst(name) && *e != '.' && *e != '/')
{
e--;
len++;
}
if (*e == '.' && len > 1)
return string(e, len);
else
return emptystr;
}
wshare/sysutils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_SYSUTILS_H
#define W_SYSUTILS_H
#ifndef WIN32
# include <unistd.h>
#endif
#include <pport.h>
#include <ptypes.h>
#include <ptime.h>
USING_PTYPES
enum file_type_t
{
FT_FILE,
FT_DIRECTORY,
FT_OTHER, // device or pipe
FT_ERROR = -1
};
class file_info
{
public:
string name;
large size;
datetime modified;
file_info(const char* iname, large isize, datetime imodified);
};
typedef tstrlist<file_info> filist;
char* get_nodename();
char* get_username();
int get_user_id(const char* user_name);
int get_user_gid(const char* user_name);
int get_group_id(const char* group_name);
string get_group_name(int gid);
file_type_t get_file_type(const char*);
bool is_symlink(const char*);
bool is_executable(const char*);
large get_file_size(const char*);
datetime get_file_mtime(const char*);
void get_directory(filist& s, string path, bool dirs, int maxfiles);
string absolute_path(const string& rel);
string get_file_ext(const string& name);
inline bool is_directory(const char* name) { return get_file_type(name) == FT_DIRECTORY; }
inline bool is_file(const char* name) { return get_file_type(name) == FT_FILE; }
#if defined(__sun__) || defined(__hpux) || defined(WIN32)
int daemon(int nochdir, int noclose);
#endif
void downgrade(const string& user, string& group);
#endif
wshare/urlutils.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <ptypes.h>
#include <pinet.h>
#include "urlutils.h"
USING_PTYPES
char* opt_anonymous_username = "ftp";
char* opt_anonymous_password = "unknown@";
char* opt_default_urlscheme = "http";
static cset schemechars("0-9A-Za-z~-.");
// TODO: make these sets RFC2396-compliant
static cset unsafechars("~00-~20%:/@?#;\\<>+\"'~7F-~FF");
static cset unsafepathchars = unsafechars - '/';
static cset unsafeparamchars = unsafechars;
static cset pathtermchars("~00#?;");
bool isurl(const string& s)
{
const char* p = pconst(s);
const char* b = p;
while (*p & schemechars)
p++;
return p > b && *p == ':';
}
static string urlencode(const string& s, const cset& unsafe)
{
static const char hexchars[17] = "0123456789ABCDEF";
int numunsafe = 0;
const char* p;
for (p = s; *p != 0; p++)
if (*p & unsafe)
numunsafe++;
if (numunsafe == 0)
return s;
string ret;
setlength(ret, length(s) + numunsafe * 2);
p = s;
char* d = unique(ret);
for (; *p != 0; p++, d++)
{
if (*p & unsafe)
{
*d++ = '%';
*d++ = hexchars[*p >> 4];
*d = hexchars[*p & 0x0f];
}
else
*d = *p;
}
return ret;
}
string urlencodepath(const string& path)
{
return urlencode(path, unsafepathchars);
}
static int urldefport(const string& scheme)
{
if (scheme == "http")
return 80;
else if (scheme == "https")
return 443;
else if (scheme == "ftp")
return 21;
else
return 0;
}
urlrec::urlrec()
: scheme(), username(), password(), pwdset(false), host(),
port(0), path(), proto(), query(), fragment() {}
void urlclear(urlrec& u)
{
clear(u.scheme);
clear(u.username);
clear(u.password);
u.pwdset = false;
clear(u.host);
u.port = 0;
clear(u.path);
clear(u.proto);
clear(u.query);
clear(u.fragment);
}
// urlcreate:
// NOTES: if scheme is empty, opt_default_urlscheme is taken; for ftp scheme
// leading '/' in the path component is significant; for all other schemes
// the leading '/' is ignored.
string urlcreate(const urlrec& u)
{
string ret;
string s, p;
// scheme
if (isempty(u.scheme))
s = opt_default_urlscheme;
else
s = lowercase(u.scheme);
if (s[length(s) - 1] == ':')
setlength(s, length(s) - 1);
ret = s + "://";
// username and password
if (!isempty(u.username))
{
ret += urlencode(u.username, unsafechars);
if (u.pwdset)
ret += ':' + urlencode(u.password, unsafechars);
ret += '@';
}
// host name and port number
ret += u.host;
if (u.port != 0 && u.port != urldefport(s))
ret += ':' + itostring(u.port);
// path
ret += '/';
p = u.path;
if (!isempty(p) && p[0] == '/')
{
if (s == "ftp")
ret += "%2F";
del(p, 0, 1);
}
ret += urlencode(p, unsafepathchars);
// params
if (!isempty(u.proto))
ret += ';' + urlencode(u.proto, unsafeparamchars);
if (!isempty(u.query))
ret += '?' + urlencode(u.query, unsafeparamchars);
if (!isempty(u.fragment))
ret += '#' + urlencode(u.fragment, unsafeparamchars);
return ret;
}
// urlcrack:
// Note: no "friendly" URL's! If the URL is invalid the result is undefined.
static int xchartoint(char c)
{
if (c >= 'a')
return c - 'a' + 10;
else if (c >= 'A')
return c - 'A' + 10;
else
return c - '0';
}
static void assignurlstr(string& s, const char* p, const char* end, bool decodeplus = false)
{
if (p >= end)
clear(s);
else
{
setlength(s, end - p);
char* d = unique(s);
for (; p < end; p++, d++)
{
if (*p == '+' && decodeplus)
*d = ' ';
else if (*p == '%')
{
if (++p == end) break;
*d = char(xchartoint(*p) << 4);
if (++p == end) break;
*d |= char(xchartoint(*p));
}
else
*d = *p;
}
setlength(s, d - pconst(s));
}
}
static void crackpath(const char* p, urlrec& u)
{
const char* end = p;
while (!(*end & pathtermchars)) // [#0, '?', '#', ';']
end++;
assignurlstr(u.path, p, end);
// leading '/'
if (u.scheme == "http" || u.scheme == "https")
{
if (isempty(u.path))
u.path = '/';
else if (*pconst(u.path) != '/' && *pconst(u.path) != '~')
ins('/', u.path, 0);
}
// parameters
while (*end != 0)
{
char paramtype = *end;
p = ++end;
while (!(*end & pathtermchars))
end++;
switch(paramtype)
{
case ';':
assignurlstr(u.proto, p, end);
break;
case '?':
assignurlstr(u.query, p, end, true);
break;
case '#':
assignurlstr(u.fragment, p, end);
break;
}
}
}
void urlcrack(const string& s, urlrec& u)
{
urlclear(u);
const char* t;
const char* p = s;
const char* end = p;
// scheme
while (*end & schemechars)
end++;
if (*end != ':' || *(end + 1) != '/' || *(end + 2) != '/')
return; // invalid scheme: we don't want to generate errors
assignurlstr(u.scheme, p, end);
u.scheme = lowercase(u.scheme);
end += 3; // skip '://'
// hostname and possibly username:password
p = end;
while (*end != 0 && *end != '/' && *end != '@')
end++;
// username and possibly password
if (*end == '@')
{
t = p;
while (*t != ':' && *t != '@')
t++;
// password
if (*t == ':')
{
assignurlstr(u.password, t + 1, end);
u.pwdset = true;
}
// username
assignurlstr(u.username, p, t);
end++;
p = end;
while (*end != 0 && *end != '/')
end++;
}
else if (u.scheme == "ftp")
{
u.username = opt_anonymous_username;
u.password = opt_anonymous_password;
u.pwdset = true;
}
// hostname and possibly port number
t = p;
while (*t != 0 && *t != ':' && *t != '/')
t++;
assign(u.host, p, t - p);
// port
if (*t == ':')
{
string s;
assign(s, t + 1, end - t - 1);
u.port = atoi(s);
}
// path
if (*end == '/')
end++;
crackpath(end, u);
}
wshare/urlutils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_URLUTILS_H
#define W_URLUTILS_H
#include <pport.h>
#include <ptypes.h>
USING_PTYPES
//
// URL utilities
//
// URL ::= <scheme>://[<authinfo>][<host>[:<port>]]/[<url-path>][<extra>]
// <authinfo> ::= <user>[:<password>]@
// <extra> ::= [ ;<protocol-params> ] [ ?<query-params> ] [ #<fragment> ]
//
struct urlrec {
string scheme; // 'http', 'ftp', 'file', ...
string username; // for ftp scheme defaults to opt_anonymous_username
string password; // for ftp scheme defaults to opt_anonymous_password
bool pwdset; // empty password and NO password is not the same!
string host; // Internet or NetBIOS host name
int port; // 0 = default for the given scheme
string path; // be careful with the leading '/' (RFC1738)
string proto; // ';'
string query; // '?'
string fragment; // '#'
urlrec();
};
extern char* opt_anonymous_username;
extern char* opt_anonymous_password;
extern char* opt_default_urlscheme;
bool isurl(const string& s);
void urlclear(urlrec& u);
string urlencodepath(const string& path);
string urlcreate(const urlrec& u);
void urlcrack(const string& s, urlrec& u);
#endif
wshare/utils.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <ptypes.h>
#include <ptime.h>
#include "config.h"
#include "sysutils.h"
#include "utils.h"
#include "urlutils.h"
USING_PTYPES
char trail_char(const string& s)
{
if (isempty(s))
return 0;
else
return *(pconst(s) + length(s) - 1);
}
void trunc_trail_char(string& s)
{
if (isempty(s))
return;
else
setlength(s, length(s) - 1);
}
static const cset htchars = "<>&\"~00";
void html_encode(outstm& s, const char* p)
{
while (*p != 0)
{
const char* b = p;
while (!(*p & htchars))
p++;
s.write(b, p - b);
switch (*p)
{
case '<': s.put("&lt;"); break;
case '>': s.put("&gt;"); break;
case '&': s.put("&amp;"); break;
case '"': s.put("&quot;"); break;
case '\xa0': s.put("&nbsp;"); break;
}
if (*p != 0)
p++;
}
}
void std_html_header(outstm& s, const string& title)
{
s.put("<html><head>\n");
s.put("<title>");
html_encode(s, title);
s.put("</title>\n");
s.put(STD_CSS);
s.put("</head><body>\n");
s.put("<h3><br>");
html_encode(s, title);
s.put("</h3>\n");
}
void std_html_footer(outstm& s)
{
s.put("<p><hr noshade size=1>");
s.put(SERVER_APP_NAME);
s.put(" at ");
s.put(cfg_server_name);
if (cfg_port != DEF_HTTP_PORT)
s.put(':' + itostring(cfg_port));
s.put("</p>\n</body></html>\n");
}
void html_show_file_list(outstm& s, const filist& list)
{
const int FSIZE_WIDTH = 5;
for (int i = 0; i < list.get_count(); i++)
{
file_info* f = list[i];
s.put(dttostring(f->modified, "%d-%b-%Y %H:%M"));
s.put(" ");
if (trail_char(f->name) != '/')
{
string t = itostring(f->size);
char c = ' ';
if (length(t) > FSIZE_WIDTH)
{
c = 'k';
t = itostring(f->size / 1024);
if (length(t) > FSIZE_WIDTH)
{
c = 'M';
t = itostring(f->size / 1024 / 1024);
}
}
s.put(pad(t, FSIZE_WIDTH, ' ', false));
s.put(c);
}
else
s.put(" - ");
s.put(" ");
s.put("<a href=\"");
html_encode(s, urlencodepath(f->name));
s.put("\">");
html_encode(s, f->name);
s.put("</a>\r\n");
}
}
//
// splits a URI path into components and builds
// a list of directory names. also resolves './'
// and '../' references
//
void split_path(const char* path, strlist& list)
{
list.clear();
const char* e = path;
if (*e == '/')
e++;
const char* b = e;
while (*b != 0)
{
e = strchr(e, '/');
if (e == nil)
e = path + strlen(path);
if (e > b)
{
string s(b, e - b); // directory name
if (s != '.') // ignore './' self-references
{
if (s == "..") // resolve '../' references
{
if (list.get_count() > 0)
list.del(list.get_count() - 1);
}
else
list.add(s, nil);
}
}
if (*e == '/')
e++;
b = e;
}
}
string get_mimetype(const string& path)
{
string ext = get_file_ext(path);
if (isempty(ext))
if (is_executable(path))
return "application/octet-stream";
else
return DEF_MIME_TYPE;
const char** p = mimetypes;
while (*p != 0)
{
if (**p == '.' && ext == *p)
{
do {
p++;
} while (**p == '.');
return *p;
}
p++;
}
return "application/octet-stream";
}
const cset digits = "0-9";
const cset letters = "A-Za-z";
const cset non_date_chars = cset("~20-~FF") - digits - letters;
static const char* mnames[12] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static const char* downames[7] =
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
datetime parse_http_date(const string& d)
{
string s;
inmemory m(d);
m.open();
m.skiptoken(letters); // day of week
m.skiptoken(non_date_chars);
s = m.token(digits); // day
if (length(s) == 0)
return invdatetime;
int day = atoi(s);
m.skiptoken(non_date_chars);
s = m.token(letters); // month
setlength(s, 3);
int month = 0;
for (int i = 0; i < 12; i++)
{
if (s == mnames[i])
{
month = i + 1;
break;
}
}
if (month == 0)
return invdatetime;
m.skiptoken(non_date_chars);
s = m.token(digits); // year
if (length(s) == 0)
return invdatetime;
int year = atoi(s);
if (year < 50)
year += 2000;
else if (year < 100)
year += 1900;
m.skiptoken(non_date_chars);
int hour = atoi(m.token(digits));
m.get();
int min = atoi(m.token(digits));
m.get();
int sec = atoi(m.token(digits));
return encodedate(year, month, day) + encodetime(hour, min, sec);
}
// #define HTTP_DATE_FMT "%a, %d %b %Y %H:%M:%S GMT"
string http_time_stamp(datetime t)
{
if (t == invdatetime)
t = now(true);
int dow, year, month, day, hour, min, sec;
decodedate(t, year, month, day);
decodetime(t, hour, min, sec);
dow = dayofweek(t);
char buf[128];
snprintf(buf, sizeof(buf), "%s, %02d %s %04d %02d:%02d:%02d GMT",
downames[dow], day, mnames[month - 1], year, hour, min, sec);
return buf;
}
wshare/utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#ifndef W_UTILS_H
#define W_UTILS_H
#include <ptypes.h>
#include <pstreams.h>
#include <ptime.h>
#ifndef W_SYSUTILS_H
# include "sysutils.h"
#endif
USING_PTYPES
char trail_char(const string& s);
void trunc_trail_char(string& s);
void html_encode(outstm& s, const char* p);
void std_html_header(outstm& s, const string& title);
void std_html_footer(outstm& s);
void html_show_file_list(outstm& s, const filist& list);
void split_path(const char* path, strlist& list);
string get_mimetype(const string& path);
datetime parse_http_date(const string& d);
string http_time_stamp(datetime t);
#endif
wshare/wshare.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
*
* C++ Portable Types Library (PTypes)
* Version 2.1.1 Released 27-Jun-2007
*
* Copyright (C) 2001-2007 Hovik Melikyan
*
* http://www.melikyan.com/ptypes/
*
*/
#include <stdlib.h>
#include <limits.h>
#include "config.h"
#include "sysutils.h"
#include "log.h"
#include "utils.h"
#include "urlutils.h"
#include "request.h"
#include "clients.h"
#include "modules.h"
USING_PTYPES
class client_socket: public ipstream
{
public:
client_socket();
};
client_socket::client_socket()
: ipstream()
{
// sets both input and output buffer sizes; some BSD systems
// don't like large output buffers
set_bufsize(SOCKET_BUF_SIZE);
}
void fail(const char* msg)
{
syslog_write(SYSLOG_ERROR, "%s", msg);
exit(2);
}
void run_server()
{
ipstmserver server;
client_socket* client = new client_socket();
threads.set_capacity(cfg_max_clients * 2);
try
{
// listen to all local addresses on cfg_port
server.bindall(cfg_port);
syslog_write(SYSLOG_WARNING, "started, user=%s, port=%d, dir=%s",
get_username(), cfg_port, pconst(cfg_document_root));
// try to listen on socket to give an error message
// before daemonizing
server.poll(-1, 0);
started = now();
// daemonize (has no effect on WIN32)
if (cfg_daemonize)
{
errlog = 0;
daemon(0, 0);
}
// run-as (downgrade process priveleges)
if (!isempty(cfg_user))
{
try
{
downgrade(cfg_user, cfg_group);
}
catch(exception* e)
{
fail(e->get_message());
delete e;
}
syslog_write(SYSLOG_WARNING, "running as %s:%s",
pconst(cfg_user), pconst(cfg_group));
}
while (true)
{
// wait infinitely for a connection request
server.serve(*client);
if (client->get_active())
{
if (thread_count >= cfg_max_clients * 2)
{
// critical situation: the number of threads is twice as
// more than allowed
client->close();
syslog_write(SYSLOG_WARNING, "critical number of clients reached (%d * 2), aborting connection", cfg_max_clients);
}
else
{
// start a new thread for this connection
client_thread* conn = new client_thread(client);
client = 0;
// start and forget; the thread object will free itself
conn->start();
client = new client_socket();
}
}
}
}
catch(estream* e)
{
fail("Server socket error: " + e->get_message());
delete e;
}
}
void config_check()
{
cfg_document_root = absolute_path(cfg_document_root);
if (trail_char(cfg_document_root) == '/')
{
#ifdef WIN32
if (length(cfg_document_root) > 3) // "c:/" or "///" ?
#else
if (length(cfg_document_root) > 1) // "/" ?
#endif
trunc_trail_char(cfg_document_root);
}
if (isempty(cfg_document_root) || !is_directory(cfg_document_root))
fail("Document root directory not found");
if (cfg_port <= 0)
fail("Invalid port number");
if (!isempty(cfg_log_file))
{
htlog = new logfile(cfg_log_file, true);
try
{
htlog->open();
}
catch (estream* e)
{
fail(e->get_message());
delete e;
}
}
else if (cfg_daemonize)
syslog_write(SYSLOG_WARNING, "daemon started without a HTTP access log");
if (cfg_max_clients <= 0)
fail("Invalid maximum number of clients");
}
int main(int argc, char* argv[])
{
cfg_server_name = get_nodename();
config_init(argc, argv);
log_init();
config_check();
init_handlers();
run_server();
// currently we never reach this point
log_done();
config_done();
return 0;
}

Archive Download the corresponding diff file

Branches

Tags

Page rendered in 4.16404s using 14 queries.