/*************************************************************************
 *
 *  $RCSfile: inetstrm.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000/09/18 16:31:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _INETCORESTRM_HXX
#define _INETCORESTRM_HXX "$Revision: 1.1.1.1 $"

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#ifndef _TOOLS_INETMIME_HXX
#include <tools/inetmime.hxx>
#endif

#ifndef _INETCOREMSG_HXX
#include <inet/inetmsg.hxx>
#endif

/*========================================================================
 *
 * INetCoreStream Interface.
 *
 *======================================================================*/
enum INetCoreStreamStatus
{
	INETCORESTREAM_STATUS_LOADED     = -4,
	INETCORESTREAM_STATUS_WOULDBLOCK = -3,
	INETCORESTREAM_STATUS_OK         = -2,
	INETCORESTREAM_STATUS_ERROR      = -1
};

/*
 * INetCoreIStream.
 */
class INetCoreIStream
{
protected:
	sal_Char   *pIBuffer;
	sal_uInt32  nIBufSiz;
	sal_uInt32  nIBufLen;

	virtual int GetData (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx) = 0;

public:
	INetCoreIStream (sal_uInt32 nIBufferSize = 0);
	virtual ~INetCoreIStream (void);

	virtual int Read (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);
};

/*
 * INetCoreOStream.
 */
class INetCoreOStream
{
protected:
	sal_Char   *pOBuffer;
	sal_uInt32  nOBufSiz;
	sal_uInt32  nOBufLen;

	virtual int PutData (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx) = 0;

public:
	INetCoreOStream (sal_uInt32 nOBufferSize = 0);
	virtual ~INetCoreOStream (void);

	virtual int Write (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);
};

/*
 * INetCoreIOStream.
 */
class INetCoreIOStream :
	public INetCoreIStream,
	public INetCoreOStream
{
public:
	INetCoreIOStream (
		sal_uInt32 nIBufferSize = 0,
		sal_uInt32 nOBufferSize = 0);
	virtual ~INetCoreIOStream (void);
};

/*========================================================================
 *
 * INetCoreMessageStream Interface.
 *
 *======================================================================*/
enum INetCoreMessageStreamState
{
	INETCOREMSG_EOL_BEGIN,
	INETCOREMSG_EOL_SCR,
	INETCOREMSG_EOL_FCR,
	INETCOREMSG_EOL_FLF,
	INETCOREMSG_EOL_FSP,
	INETCOREMSG_EOL_FESC
};

/*
 * INetCoreMessageIStream (Message Generator) Interface.
 */
class INetCoreMessageIStream : public INetCoreIStream
{
	sal_uInt32       nIBufSiz;
	sal_Char        *pIBuffer;
	sal_Char        *pIRead;
	sal_Char        *pIWrite;

	INetCoreMessage *pSourceMsg;
	sal_Bool         bHeaderGenerated;

	virtual int GetData (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

protected:
	INetCoreMessageStreamState eIState;

	virtual int GetMsgLine (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL) = 0;

public:
	INetCoreMessageIStream (sal_uInt32 nIBufferSize = 4096);
	virtual ~INetCoreMessageIStream (void);

	INetCoreMessage* GetSourceMessage (void);
	void SetSourceMessage (INetCoreMessage *pMessage);

	void GenerateHeader (sal_Bool bGenerate = sal_True);
	sal_Bool IsHeaderGenerated (void) const;
};

inline INetCoreMessage*
INetCoreMessageIStream::GetSourceMessage (void)
{
	return pSourceMsg;
}

inline void
INetCoreMessageIStream::SetSourceMessage (INetCoreMessage *pMessage)
{
	pSourceMsg = pMessage;
}

inline void INetCoreMessageIStream::GenerateHeader (sal_Bool bGenerate)
{
	bHeaderGenerated = !bGenerate;
}

inline sal_Bool INetCoreMessageIStream::IsHeaderGenerated (void) const
{
	return bHeaderGenerated;
}

/*
 * INetCoreMessageOStream (Message Parser) Interface.
 */
class INetCoreMessageOStream : public INetCoreOStream
{
	INetCoreMessage *pTargetMsg;
	sal_Bool         bHeaderParsed;

	virtual int PutData (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

protected:
	INetCoreMessageStreamState eOState;

	virtual int PutMsgLine (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL) = 0;

public:
	INetCoreMessageOStream (sal_uInt32 nOBufSiz = 4096);
	virtual ~INetCoreMessageOStream (void);

	INetCoreMessage* GetTargetMessage (void);
	void SetTargetMessage (INetCoreMessage *pMessage);

	void ParseHeader (sal_Bool bParse = sal_True);
	sal_Bool IsHeaderParsed (void) const;
};

inline INetCoreMessage*
INetCoreMessageOStream::GetTargetMessage (void)
{
	return pTargetMsg;
}

inline void
INetCoreMessageOStream::SetTargetMessage (INetCoreMessage *pMessage)
{
	pTargetMsg = pMessage;
}

inline void INetCoreMessageOStream::ParseHeader (sal_Bool bParse)
{
	bHeaderParsed = !bParse;
}

inline sal_Bool INetCoreMessageOStream::IsHeaderParsed (void) const
{
	return bHeaderParsed;
}

/*
 * INetCoreMessageIOStream.
 */
class INetCoreMessageIOStream :
	public INetCoreMessageIStream,
	public INetCoreMessageOStream
{
public:
	INetCoreMessageIOStream (
		sal_uInt32 nIBufSiz = 2048,
		sal_uInt32 nOBufSiz = 2048);
	virtual ~INetCoreMessageIOStream (void);
};

/*=========================================================================
 *
 * INetCoreRFC822MessageStream Interface.
 *
 *=======================================================================*/
enum INetCoreRFC822MessageStreamState
{
	INETCOREMSG_RFC822_BEGIN = 0,
	INETCOREMSG_RFC822_END,
	INETCOREMSG_RFC822_CHECK,
	INETCOREMSG_RFC822_JUNK,

	// Intermediate states.
	INETCOREMSG_RFC822_TOKEN_RE,
	INETCOREMSG_RFC822_TOKEN_RETURNMINUS,
	INETCOREMSG_RFC822_TOKEN_XMINUS,
	INETCOREMSG_RFC822_LETTER_C,
	INETCOREMSG_RFC822_LETTER_S,

	// Headers recognized.
	INETCOREMSG_RFC822_BCC,
	INETCOREMSG_RFC822_CC,
	INETCOREMSG_RFC822_COMMENTS,
	INETCOREMSG_RFC822_DATE,
	INETCOREMSG_RFC822_ENCODING,
	INETCOREMSG_RFC822_FROM,
	INETCOREMSG_RFC822_IN_REPLY_TO,
	INETCOREMSG_RFC822_KEYWORDS,
	INETCOREMSG_RFC822_MESSAGE_ID,
	INETCOREMSG_RFC822_RECEIVED,
	INETCOREMSG_RFC822_REFERENCES,
	INETCOREMSG_RFC822_REPLY_TO,
	INETCOREMSG_RFC822_RETURN_PATH,
	INETCOREMSG_RFC822_RETURN_RECEIPT_TO,
	INETCOREMSG_RFC822_SENDER,
	INETCOREMSG_RFC822_SUBJECT,
	INETCOREMSG_RFC822_TO,
	INETCOREMSG_RFC822_X_MAILER,
	INETCOREMSG_RFC822_X_PRIORITY
};

class INetCoreRFC822MessageStream : public INetCoreMessageIOStream
{
	INetCoreRFC822MessageStreamState eState;
	INetCoreRFC822MessageStreamState eOkState;

	sal_uInt32 nMsgBufSiz;
	sal_Char  *pMsgBuffer;
	sal_Char  *pMsgRead;
	sal_Char  *pMsgWrite;

protected:
	static ByteString ConvertFrom7Bit (const ByteString &rFieldBody);

	static int  GenerateHeaderField (
		const sal_Char            *pFieldName,
		const ByteString          &rFieldBody,
		INetMIME::HeaderFieldType  eType,
		sal_Char   *pData,
		sal_uInt32  nSize,
		sal_uInt32  nLimit = INetMIME::SOFT_LINE_LENGTH_LIMIT);

	virtual int GetMsgLine (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

	virtual int PutMsgLine (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

public:
	INetCoreRFC822MessageStream (sal_uInt32 nMsgBufferSize = 2048);
	virtual ~INetCoreRFC822MessageStream (void);

	INetCoreRFC822Message* GetSourceMessage (void);
	INetCoreRFC822Message* GetTargetMessage (void);

	void SetSourceMessage (INetCoreRFC822Message *pMessage);
	void SetTargetMessage (INetCoreRFC822Message *pMessage);
};

inline INetCoreRFC822Message*
INetCoreRFC822MessageStream::GetSourceMessage (void)
{
	return ((INetCoreRFC822Message*)
			(INetCoreMessageIStream::GetSourceMessage()));
}

inline void
INetCoreRFC822MessageStream::SetSourceMessage (INetCoreRFC822Message *pMessage)
{
	INetCoreMessageIStream::SetSourceMessage (pMessage);
}

inline INetCoreRFC822Message*
INetCoreRFC822MessageStream::GetTargetMessage (void)
{
	return ((INetCoreRFC822Message*)
			(INetCoreMessageOStream::GetTargetMessage()));
}

inline void
INetCoreRFC822MessageStream::SetTargetMessage (INetCoreRFC822Message *pMessage)
{
	INetCoreMessageOStream::SetTargetMessage (pMessage);
}

/*========================================================================
 *
 * INetCoreMIMEMessageStream Interface.
 *
 *======================================================================*/
enum INetCoreMIMEMessageStreamState
{
	INETCOREMSG_MIME_BEGIN = 0,
	INETCOREMSG_MIME_END,
	INETCOREMSG_MIME_CHECK,
	INETCOREMSG_MIME_RFC822,
	INETCOREMSG_MIME_JUNK,

	// Intermediate states.
	INETCOREMSG_MIME_TOKEN_CONTENT,
	INETCOREMSG_MIME_TOKEN_CONTENT_D,
	INETCOREMSG_MIME_TOKEN_CONTENT_T,

	// Headers recognized.
	INETCOREMSG_MIME_VERSION,
	INETCOREMSG_MIME_CONTENT_BASE,
	INETCOREMSG_MIME_CONTENT_DESCRIPTION,
	INETCOREMSG_MIME_CONTENT_DISPOSITION,
	INETCOREMSG_MIME_CONTENT_ID,
	INETCOREMSG_MIME_CONTENT_LOCATION,
	INETCOREMSG_MIME_CONTENT_TYPE,
	INETCOREMSG_MIME_CONTENT_TRANSFER_ENCODING
};

enum INetCoreMIMEMessageStreamEncoding
{
	INETCOREMSG_ENCODING_7BIT,
	INETCOREMSG_ENCODING_8BIT,
	INETCOREMSG_ENCODING_BINARY,
	INETCOREMSG_ENCODING_QUOTED,
	INETCOREMSG_ENCODING_BASE64
};

class INetCoreMIMEMessageStream : public INetCoreRFC822MessageStream
{
	sal_uInt32                         nMsgBufSiz;
	sal_Char                          *pMsgBuffer;
	sal_Char                          *pMsgRead;
	sal_Char                          *pMsgWrite;

	INetCoreMIMEMessageStreamState     eState;
	INetCoreMIMEMessageStreamState     eOkState;

	sal_uInt32                         nChildIndex;
	INetCoreMIMEMessageStream         *pChildStream;

	INetCoreMessageIStream            *pEncodeStream;
	INetCoreMessageOStream            *pDecodeStream;

	INetCoreMIMEMessageStreamEncoding  eEncoding;

	static INetCoreMIMEMessageStreamEncoding GetMsgEncoding (
		const ByteString &rContentType);

protected:
	virtual int GetMsgLine (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx);

	virtual int PutMsgLine (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx);

public:
	INetCoreMIMEMessageStream (sal_uInt32 nMsgBufferSize = 2048);
	virtual ~INetCoreMIMEMessageStream (void);

	INetCoreMIMEMessage* GetSourceMessage (void);
	INetCoreMIMEMessage* GetTargetMessage (void);

	void SetSourceMessage (INetCoreMIMEMessage *pMessage);
	void SetTargetMessage (INetCoreMIMEMessage *pMessage);
};

inline INetCoreMIMEMessage*
INetCoreMIMEMessageStream::GetSourceMessage (void)
{
	return ((INetCoreMIMEMessage*)
			(INetCoreMessageIStream::GetSourceMessage()));
}

inline void
INetCoreMIMEMessageStream::SetSourceMessage (INetCoreMIMEMessage *pMessage)
{
	INetCoreMessageIStream::SetSourceMessage (pMessage);
}

inline INetCoreMIMEMessage*
INetCoreMIMEMessageStream::GetTargetMessage (void)
{
	return ((INetCoreMIMEMessage*)
			(INetCoreMessageOStream::GetTargetMessage()));
}

inline void
INetCoreMIMEMessageStream::SetTargetMessage (INetCoreMIMEMessage *pMessage)
{
	INetCoreMessageOStream::SetTargetMessage (pMessage);
}

/*========================================================================
 *
 * INetCoreNewsMessageStream Interface.
 *
 *======================================================================*/
enum INetCoreNewsMessageStreamState
{
	INETCOREMSG_NEWS_BEGIN = 0,
	INETCOREMSG_NEWS_END,
	INETCOREMSG_NEWS_CHECK,
	INETCOREMSG_NEWS_MIME,
	INETCOREMSG_NEWS_JUNK,

	// Intermediate states.
	INETCOREMSG_NEWS_LETTER_X,

	// Headers recognized.
	INETCOREMSG_NEWS_NEWSGROUPS,
	INETCOREMSG_NEWS_PATH,
	INETCOREMSG_NEWS_APPROVED,
	INETCOREMSG_NEWS_BYTES,
	INETCOREMSG_NEWS_CONTROL,
	INETCOREMSG_NEWS_DISTRIBUTION,
	INETCOREMSG_NEWS_EXPIRES,
	INETCOREMSG_NEWS_FOLLOWUP_TO,
	INETCOREMSG_NEWS_LINES,
	INETCOREMSG_NEWS_ORGANIZATION,
	INETCOREMSG_NEWS_SUMMARY,
	INETCOREMSG_NEWS_XREF,
	INETCOREMSG_NEWS_X_NEWSREADER
};

class INetCoreNewsMessageStream : public INetCoreMIMEMessageStream
{
	INetCoreNewsMessageStreamState eState;
	INetCoreNewsMessageStreamState eOkState;

protected:
	virtual int GetMsgLine (
		sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

	virtual int PutMsgLine (
		const sal_Char *pData, sal_uInt32 nSize, void *pCtx = NULL);

public:
	INetCoreNewsMessageStream (void);
	virtual ~INetCoreNewsMessageStream (void);

	INetCoreNewsMessage* GetSourceMessage (void);
	INetCoreNewsMessage* GetTargetMessage (void);

	void SetSourceMessage (INetCoreNewsMessage *pMessage);
	void SetTargetMessage (INetCoreNewsMessage *pMessage);
};

inline INetCoreNewsMessage*
INetCoreNewsMessageStream::GetSourceMessage (void)
{
	return ((INetCoreNewsMessage*)
			(INetCoreMessageIStream::GetSourceMessage()));
}

inline void
INetCoreNewsMessageStream::SetSourceMessage (INetCoreNewsMessage *pMessage)
{
	INetCoreMessageIStream::SetSourceMessage (pMessage);
}

inline INetCoreNewsMessage*
INetCoreNewsMessageStream::GetTargetMessage (void)
{
	return ((INetCoreNewsMessage*)
			(INetCoreMessageOStream::GetTargetMessage()));
}

inline void
INetCoreNewsMessageStream::SetTargetMessage (INetCoreNewsMessage *pMessage)
{
	INetCoreMessageOStream::SetTargetMessage (pMessage);
}

#endif /* !_INETCORESTRM_HXX */

