(If you do not see the frame version
of
this page with a table of contents in the left frame, click here.)
A Sample Software Library
Introduction
The libraries on this website currently consist of the source files for
farVIEW XPath support and for farVIEW's TCP/IP communications. All code
in this library was written by Paul J. Medlock and is copyright
©2000-2017
by Paul J. Medlock. This library is provided as-is. Please read the Electronic
License Agreement before perusing the code here.
You can download the C++ source files described here.
The XPath Module
The XPath source files, along with the W3C
Recommendation, contain what documentation I have.
The XPath module provides five public interfaces (shown below in farSlang):
SelectSingleNode:CNode(node:
CNode,
path$)
SelectNodes:CNodeList(node:
CNode,
path$)
Evaluate:CXPathItem(node: CNode,
path$)
Error#
Parse$(path$) -- for debugging
where
node is a node in a valid XML document
path$ is a (valid) XPath expresssion
The Comm Library
The multi-threaded communications class library included here provides
a simple, yet flexible TCP/IP interface for applications written in
C++.
The code supports client, server, and peer-to-peer applications using
the
HTTP specification or variations. An application can use the hooks
provided
by the library to encrypt/decrypt and authenticate messages, to easily
implement HTTP server-side handler modules and Remote-Procedure-Call
servers,
and to connect to other application-specific servers.
The library contains five main classes:
-
A user interface class, called CComm,
which
provides communication between the user code and the communication
threads.
-
A session handler class derived from the CThread
class, called CSession, which
communicates
with a remote correspondent, either as a server or as a client. The
CSession
class is designed to allow to be overridden with a derived class to
provide
application-specific server-side and client-side behaviors.
-
A socket listener class derived from the CThread class, called CListen,
which listens for client request messages to spawn server-side CSession
handlers.
-
A socket handler class, providing a “low-level” interface to the
WinSock/Socks
software, called CSocket.
-
And a set of thread and signal classes, providing platform-dependent
multi-tasking
support for the communication classes.
These classes reside in the files comm.h, comm.cpp,
socket.h,
socket.cpp,
thread.h,and
thread.cpp.
There are several communication support classes, mostly acting as
wrappers
to simplify the communication between the user threads and the session
threads. One special support class, however, is CCommResult.
Objects of this class are passed by the user calling thread along with
request parameters and used by the communication thread to synchronize
and communicate results back to the user thread.
The basic operation paradigm is as follows:
-
The user thread creates a CCommResult object and passes it, along with
specific request parameters to the appropriate CComm method. The user
specifies
synchronous or asynchronous behavior when creating the CCommResult
object.
-
The specified CComm request handler method wraps the request within a
carrier
object and enqueues the object into the session handler’s input request
port. The method then waits on the CCommResult object. Upon regaining
control,
it returns to the calling user thread code.
-
The specified session handler dequeues the request, processes it, and
releases
the CCommResult object.
The Comm Interface
The CComm class provides six simple interface methods to control the
communication
package:
-
OpenComm – engages the
communication package.
If a listener is specified, a CListen thread object is created and
started.
-
CloseComm – disengages the
communication
package. Disconnects all sessions and the listener from WinSock/Socks.
-
OpenSession – creates a CSession
thread
object associating it with a specified identifier.
-
CloseSession – disconnects the
specified
CSession thread object and destroys it.
-
SendMessage – sends the
specified message
via the specified CSession thread object. If the message needs to be
encrypted
(and authenticated), that is done automatically by the CSession thread
before the message is sent.
-
ReceiveMessage – receives a
message,
decrypts and authenticates it. Returns the message to the user thread.
A special case of this operation is provided to support the initial
connection
when the CSession object is created by the CListen object. To handle an
initial client message.
Client Sample Code
The following example C++ code sends a request to an HTTP server and
gets
a response. (Note that error checking is omitted for clarity.)
PCStrList
CClient::getDoc(RPCComm _comm,
Pchar _URL, ushort _port) {
char
sessionID[sizeString];
GetID(sessionID, sizeString);
PCCommResult
result
= new CCommResult(true); // wait for completion
// Open a
session with
the specified server
if
(!_comm->OpenSession(sessionID,
_URL, _port, "", result))
return 0;
// Send a
GET request
to the server
PCAtom body;
if
(!_comm->SendMessage(sessionID,
"HTTP",
"GET",
"",
body,
keepalive,
result)) {
_comm->CloseSession(sessionID, result);
return 0;
}
// Receive
the server's
response
if
(!_comm->ReceiveMessage(sessionID,
result)) {
_comm->CloseSession(sessionID, result);
return 0;
}
// Close
the session
_comm->CloseSession(sessionID,
result);
// Return
the document
return
TYPECAST(result->GetBody(),
StrList);
} // getDoc
|
Server Sample Code
To build a server using the library, derive a class from CSession,
overriding
the CSession::doRequest() method. The header and the body of the
request message
are provided as parameters. The following C++ code processes a request,
returning its response in the variable list, and terminates the
server session thread.
bool
CServer::doRequest(RPCStrList _headers,
RPCAtom _body) {
// Process the
request
to obtain the results in list
// ... (the
details)
// Send the
response
to the client
PCBlock sig;
// signature
block - not used for HTTP
PCAtom
lt
= TYPECAST(list, Atom);
PCItem sndMsg
= new
CSendMessage(sessionID,
"ACK",
"",
"200 OK",
"text/xml",
sig,
lt,
closeConnect);
PCCommResult
result
= new CCommResult(true); // wait for completion
PCItem sndCmd
= new
CCommCmmd('SM', sndMsg, result);
GetPort()->Send(sndCmd);
// post the sendMessage request
// Shut the
session
down
PCItem endMsg
= new
CReceiveMessage(id, false);
PCItem endCmd
= new
CCommCmmd('Q', endMsg, result);
GetPort()->Send(endCmd);
// post the quitSession request
return true;
} // doRequest
|
EndNotes
Encryption/authentication services are provided by a separate
subsystem.
There are a number of other classes in the library within which this
communication package resides, including a complete Level 1 DOM and a
run-time
for an object-oriented programming language that I developed, called farSlang,
which includes a recursive-descent compiler and an interpreter.
The classes in this library are built on a base class (CAtom) that
implements
smart pointers, so objects are deleted implicitly.