(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-2008 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:

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:

  1. 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.
  2. 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.
  3. 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:

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.