/***************************************************************************
 *   Copyright (C) 2003 by Dan Muller                                      *
 *   dan@verliba.cz                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/
#ifndef NSERVERCPROTOCOL_H
#define NSERVERCPROTOCOL_H

#include <vector>
#include "cobj.h"

using namespace std;

namespace nServer
{
	enum { eMSG_UNPARSED=-1 };
	class cMessageParser;
	class cAsyncConn;
	
/**
aBase class for protocols
 
@author Daniel Muller
*/
class cProtocol : public cObj
{
public:
	cProtocol();
	virtual ~cProtocol();
	virtual int TreatMsg(cMessageParser * msg, cAsyncConn *conn) = 0;
	virtual cMessageParser *CreateParser() = 0;
	virtual void DeleteParser(cMessageParser *) = 0;	
};

class cMessageParser : public cObj
{
public:
	cMessageParser(int);
	virtual ~cMessageParser();

	/** parses the string and sets the state variables */
	virtual int Parse() = 0; // must override
	/** splits message to it's important parts and stores their info in the chunkset mChunks */
	virtual bool SplitChunks() = 0; // must override
	
	/** reinitialize the structure */
	virtual void ReInit();
	/** return the n'th chunk (as splited by SplitChunks) function */
	virtual string &ChunkString(unsigned int n);
	
	/** apply the chunkstring ito the main string */
	void ApplyChunk(unsigned int n);
	/** get string */
	string & GetStr();

	
public: // Public attributes
	/** The actual message string */
	string mStr;

	/** the type for message chunks */
	typedef pair<int,int> tChunk;
	typedef vector<tChunk> tChunkList;
	typedef tChunkList::iterator tCLIt;
	typedef vector<string *> tStrPtrList;
	typedef tStrPtrList::iterator tSPLIt;
	/** the list of chunks */
	tChunkList mChunks;
	/** list of string pointers */
	//tStrPtrList mChStrings;
	string *mChStrings;
	/** a bitmap having information about chStringsSet */
	unsigned long mChStrMap;
	
	/** indicates if the message is tooo long so it can't be receved complete */
	bool Overfill;
	/** indicates if the message is completely received */
	bool Received;
	/** error in message indicator */
	bool mError;
	/** parsed message type */
	int mType;
	/** length of the message */
	unsigned mLen;
	unsigned mKWSize;
	
protected:
	/** reduce the chunk from left by amount, cn is the chunk number */
	void ChunkRedLeft(int cn, int amount);
	/** splits message into two chunks by a delimiter adn stores them in the chunklist */
	bool SplitOnTwo(size_t start, const char lim, int cn1, int cn2, size_t len=0,bool left=true);
	/** splits the chunk number "ch" into two chunks by a delimiter adn stores them in the chunklist under numbers cn1 and cn2 */
	bool SplitOnTwo(const char lim, int ch, int cn1, int cn2, bool left=true);
	/** reduce the chunk from right by amount, cn is the chunk number */
	void ChunkRedRight(int cn, int amount);
	/** fill in a given chunk */
	void SetChunk(int,int,int);

protected: // Private methods
	int mMaxChunks;
	
};

};

#endif
