Michael Farr - 2002-01-02

I just finished Uni ... that should explain my idealistic attitude.  I have also working as a programmer for 3 years.  I have been using CommonC++ for a while, but decided to rewrite part of it ... possibly due to poor understanding on my part.  I have also written some new stuff on top of it that I'd like some feedback on.  If part/all of this communication is out of place/doesnt make sence ... erm tell me how to do better.

Subject to limitations of my own lack of understanding (or misunderstanding), I have some dislikes with CommonC++ (just keep in mind I think that its a really cool library) and wanted some feedback on these dislikes.  Basically I need some questions answered to continue learning.

1.  What is with TCPSocket being friends with TCPStream, SocketPort and tcpstream?  These classes seem too only need this "friendship" to do a get access to "so" ... when class Socket could have some useful functions like Accept() written for it.  I realise there are some platform dependency issues with that ... but are there any other reasons?  I found this to be irritating when I went to create my own TCPStream-like object and had write a Socket::Accept call myself.

2.    Why does TCPStream need to cache everything with std::io stuff?  Isn't the operating system supposed to do that, aren't we doubling our memory bandwidth requirements? 

3. Why is there only one read function avaliable with class Socket (Readline)?  Wouldn' it be a good idea to have some read(void *, size_t)/write(void *, size_t) type functions that dont do character swappy things?

4. Why is there no common interface between TCPSreams style interface and the Buffer/Pipe interface.  (I thought the individual interfaces were too high level)

5. sometimes size_t (unsigned) is used and then functions like FixedBuffer::OnWait(void *data) return an int ... isn't that conveluted?

I have tried to get around those issues myself, and have been ... moderatly successful <flame shield attached>.  I did some remodelling and created some new classes and concepts (not really new, but not used here previously). 

1.  I created a common interface for Reading and Writing data I; I used this interface with "class Buffer" and "class TCPStream".  Its a fairly immature class, but I managed to get it to do some funky stuff.
protected:
    virtual size_t Peek(void *wt_pvBuffer, const size_t ct_zReadSize) = 0;
    virtual size_t Read(void *wt_pvBuffer, const size_t ct_zReadSize, const timeout_t ct_Timeout) = 0;
    virtual size_t Write(const void *ct_pvBuffer, const size_t ct_zReadSize) = 0;

    virtual void ReadWaitLock() = 0;
    virtual void ReadWaitUnLock() = 0;
    virtual bool ReadNoWaitLock() = 0;
    virtual void ReadNoWaitUnLock() = 0;
    virtual bool WriteLockNoWait() = 0;
    virtual void WriteUnLock() = 0;

public:
    MessageInterface(const timeout_t ct_Timeout);
    ~MessageInterface();
    size_t ReadWait(void *wt_pvBuffer, const size_t ct_zReadSize);
    size_t WriteNoWait(const void *ct_pvBuffer, const size_t ct_zReadSize);
    void SetTimeout(const timeout_t ct_Timeout);
    timeout_t GetTimeout();
   
2.  I create a new class called MCommand, which is composed of another new class called MVariant, this allowed me to extend this interface to allow these functions:
protected:
    size_t ReadIntoFile(std::string & wr_strFilePath);
    size_t WriteFromFile(const std::string & cr_strSourceFilePath, const std::string & cr_strReturnFilePath);
    size_t ReadRawToFile(const std::string cr_strFilePath, const size_t ct_zFileSize);
    size_t WriteRawFromFile(const std::string cr_strFilePath, const size_t ct_zFileSize);
    size_t ReadVariant(class MVariant & wr_MVariant);
    size_t WriteVariant(const MVariant & cr_MVariant);
public:
    size_t ReadWaitCommand(class MCommand & wr_MCommand);
    size_t WriteWaitCommand(const MCommand & cr_MCommand);

An MCommand (M for messaging type of class) allows the stream to communicate with Command(param1, param2) type of message.  A simple example
of a Command I have created is
    wr_MCommand.CreateArchive(string Path, string Filter)
    This message can be interpreted to a remote or local host to create an compressed volume (with libtar/libbzip2) and send it back via
    wr_MCommand.GetType() = CREATE_ARCHIVE
    wr_MCommand[0].GetString() = Path
    wr_MCommand[1].GetString() = Filter

3. The new version of Buffer I wrote that the new interfae still enable FixedBuffer to work the same

4. The new version of TCPStream still enabled tcpstream to work the same ... although without the public std::streambuf, public std::iostream mentality.

5. Erm, there are other things that I am doing with this library on a higher level ... but are even more irrelevant.

6. One last thing.  I made the TCPSession object be composed of TCP session (rather than is-a) and made it an is-a Buffer.  This way the application can send messges to the TCP session ... I really dont know what use the TCPSession object is supposed to be without a two way interface.  I create an object called TCPWatchDog that increments a semaphore when messages come in, and the TCPSession responds to semaphore increments (using WaitForMultipleObjects in win32 ... I think I can keep the same interface in unix ... but haven't done it yet).

Notes:

1. Why didn't I use XML for the command structure?  Firstly XML is very cool, and I have used libXML as the parser for 2 separate projects I have worked on.  LibXML profivides fairly efficienct memory handling, and is pretty quick.  In __this case__ the flexibility of XML is worthless and would unnessesarily reduce the speed of the stream.  XML is also inherently hierarchical by nature and there are no hierarchical things in this system.  The system I have produced is equally capable of dealing with endianess, floating point format and provides a more extensible interface for a non-hierarchial system ... and its fast, doesnt' require double copying of memory/character interpretation etc .. and has less data formatting overhead.

2. I can provide UML documentation and other stuff on what I am trying to achive if anyone is interested, otherwise any guidance at all would be really useful