#ifndef DISSECTOR_H
#define DISSECTOR_H

#include <string>
#include <list>
#include "DispatchInfo.h"

#ifdef _MSC_VER
typedef int ssize_t;
#endif

class Dissector {
  
 public:
  Dissector();
  virtual ~Dissector();
  virtual Dissector * Clone() const = 0;
  virtual bool Dissect(const unsigned char * pData, const ssize_t nDataLen) = 0;
  virtual bool NeedReassembly() const = 0;
  virtual bool Reassemble(Dissector * pDissector, ProtocolInfo * pProtocolInfo);
  virtual const EProtocolType GetUpperLayerType() const = 0;
  virtual void SaveResult(DispatchInfo & info) const;
  virtual bool IsPacketValid() const;
  virtual bool FinishDissection();
  virtual bool CreatesUnprocessedData() const;
  bool ContainsUnprocessedData();
  std::pair<const unsigned char *, ssize_t> GetUnprocessedData() const;
  void SetProtocolInfo(ProtocolInfo * pInfo);
  ProtocolInfoElement * GetLayerInfo() const;
 protected:
  void SaveLayerInfo();
  virtual ProtocolInfoElement * CreateLayerInfo() = 0;
  void SavePayload(const unsigned char * pData, ssize_t nPayloadSize);
  void AllocPayload(ssize_t nPayloadSize);
  void SetPayloadAt(const unsigned char * pSrcData, ssize_t nSrcSize, int nOffset);
  void AppendPayload(Dissector * pSrc);
  unsigned char * GetPayload() const;
  ssize_t GetPayloadSize() const;
  std::pair<unsigned char *, ssize_t> DetachData();  
  void SeparateUnprocessedData(int nNewPayloadSize);
  ProtocolInfo * GetProtocolInfo() const;
  bool MatchProtocolInfo(ProtocolInfo * pInfo) const;
 private:
  unsigned char * m_pPayload, * m_pUnprocessedData;
  ssize_t m_nPayloadSize, m_nUnprocessedSize;
  ProtocolInfoElement * m_pLayerInfo;
  ProtocolInfo * m_pProtocolInfo;
};

#endif
