#ifndef _xbSTREAM_
#define _xbSTREAM_
/*<<<***************************************************************************
The MIT License (MIT)

Copyright(C) 2013 - 2015 Marc Mirti Mancinelli, Christophe Lardau and Philippe Pamart (xdcube.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
#Title: xbStream
#Project: xdcBase
////////////////////////////////////////////////////////////////////////////////
#Author: Marc MIRTI MANCINELLI
#History:
<15/09/2013: creation.
12/02/2014: this notice inserted.
***************************************************************************>>>*/

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _xbSTREAMITF_
#	include "xbStreamItf.h"
#endif

#ifndef _xbVARIANT_
#	include "xbVARIANT.h"
#endif

#ifndef _xbSECURITY_
#	include "xbSecurity.h"
#endif

//Stream exception
class xbEXPORT __declspec(uuid("{5A39A972-2BB9-4a2a-ADC4-0AFCA486E530}"))
	xbStream:public xbObject,
	public IxbInputStream,public IxbOutputStream,
	public IxbSeekStream,public IStream,public IxbStreamMode,public sIxbLock,public IxbStream,public IxbStreamInfo
{
public:
	xbStream();
	virtual ~xbStream() 
	{
	}

	xbImplObject();

	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(IxbInputStream);
		xbImplInterface(IxbOutputStream);
		xbImplInterface(IxbSeekStream);
		xbImplInterface(IStream);
		xbImplInterface(ISequentialStream);
		xbImplInterface(IxbStreamMode);
		xbImplInterface(sIxbLock);
		xbImplInterface(xbStream);
		xbImplInterface(IxbStream);
		xbImplInterface(IxbStreamInfo);

		return xbObject::GetInterface(riid,ppInterf);
	}

//IxbStreamInfo methods :
	virtual xbString		GetName() const = 0;
	virtual xbString		GetPhysicalName() const = 0;
	virtual bool GetFileTime(FILETIME *pCreationTime, FILETIME *pLastAccessTime, FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required);
	virtual bool SetFileTime(const FILETIME *pCreationTime, const FILETIME *pLastAccessTime, const FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required );
	virtual bool GetFileTime(xbDateTime *pCreationTime, xbDateTime *pLastAccessTime, xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required);
	virtual bool SetFileTime(const xbDateTime *pCreationTime, const xbDateTime *pLastAccessTime, const xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required );
	virtual xbString		GetStreamContentType() const;

//sIxbLock methods :
	virtual void			Lock() const = 0;
	virtual void			Unlock() const = 0;

//IxbInputStream methods :
	virtual bool			CanRead() const = 0;
	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true) = 0;

	virtual IxbInputStream	&operator>>(sIxbStreamable *piObj);
	virtual IxbInputStream	&operator>>(xbStringA *pStr);
	virtual IxbInputStream	&operator>>(xbStringW *pStr);
	virtual IxbInputStream	&operator>>(xbBSTR *pStr);

	virtual ulong			ReadStringA(xbStringA *pStr,xbStringA *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbStringW *pStr,xbStringW *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbBSTR *pStr,xbBSTR *pStopStr = NULL,IxbStreamMode *pMode = NULL);

	IxbInputStreamHelpDcl(uchar,Uchar);
	IxbInputStreamHelpDcl(char,Char);
	IxbInputStreamHelpDcl(wchar,CharW);
	IxbInputStreamHelpDcl(short,Short);
	IxbInputStreamHelpDcl(ushort,Ushort);
	IxbInputStreamHelpDcl(long,Long);
	IxbInputStreamHelpDcl(ulong,Ulong);
	IxbInputStreamHelpDcl(int64,Int64);
	IxbInputStreamHelpDcl(uint64,Uint64);
	IxbInputStreamHelpDcl(GUID,Guid);
	IxbInputStreamHelpDcl(double,Double);

//IxbOutputStream methods :
	virtual bool			CanWrite() const = 0;
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true) = 0;
	virtual uint64			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm);
	virtual ulong			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm,ulong DataLg,bool DataLg_Required = true);

	virtual IxbOutputStream	&operator<<(const sIxbStreamable &iobj);
	virtual IxbOutputStream	&operator<<(const char *pStr);
	virtual IxbOutputStream	&operator<<(const wchar *pStr);
	virtual IxbOutputStream	&operator<<(const xbStringA &str);
	virtual IxbOutputStream	&operator<<(const xbStringW &str);
	virtual IxbOutputStream	&operator<<(const xbBSTR &str);

	virtual ulong			WriteStringA(const xbStringA &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringA(const char *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const xbStringW &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const xbBSTR &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const wchar *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL);

	IxbOutputStreamHelpDcl(uchar,Uchar);
	IxbOutputStreamHelpDcl(char,Char);
	IxbOutputStreamHelpDcl(wchar,CharW);
	IxbOutputStreamHelpDcl(short,Short);
	IxbOutputStreamHelpDcl(ushort,Ushort);
	IxbOutputStreamHelpDcl(long,Long);
	IxbOutputStreamHelpDcl(ulong,Ulong);
	IxbOutputStreamHelpDcl(int64,Int64);
	IxbOutputStreamHelpDcl(uint64,Uint64);
	IxbOutputStreamHelpDcl(GUID,Guid);
	IxbOutputStreamHelpDcl(double,Double);

//IxbSeekStream methods :
	virtual bool			Eof() const = 0;
	virtual bool			Bof() const = 0;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet) = 0;
	virtual ulong			GetPosition() const = 0;
	virtual ulong			SetPosition(ulong pos) = 0;
	virtual ulong			GetLength() const = 0;
	virtual void			SetLength(ulong sz) = 0;
	virtual void			SetEof() = 0;
	xbPropertyRW(ulong,Length);
	xbPropertyRW(ulong,Position);

//IxbStreamMode methods :
	virtual xbFormatMode	GetFormat() const;
	virtual void			SetFormat(xbFormatMode mode);

	virtual bool			GetCRLFasLF() const;
	virtual void			SetCRLFasLF(bool bFlg);

	virtual ulong			GetStreamTextCP() const;
	virtual void			SetStreamTextCP(ulong cp);

	virtual ulong			GetAppTextCP() const;
	virtual void			SetAppTextCP(ulong cp);

	virtual	ulong			FindLineSepA(ulong startpos,const char *pStr,ulong StrLg,long *pSepLg) const;
	virtual	ulong			FindLineSepW(ulong startpos,const wchar *pStr,ulong StrLg,long *pSepLg) const;

	virtual void			ReadTextBOM(xbTextBOMtype *pbBOMtype = NULL);
	virtual void			WriteTextBOM(xbTextBOMtype BOMtype = xbTextBOM_default);
	virtual xbTextBOMtype	GetTextBOMtype() const;
	virtual void			SetTextBOMtype(xbTextBOMtype BOMtype);

	xbPropertyRW(xbFormatMode,Format);
	xbPropertyRW(bool,CRLFasLF);
	xbPropertyRW(ulong,StreamTextCP);
	xbPropertyRW(ulong,AppTextCP);
	xbPropertyRW(xbTextBOMtype,TextBOMtype);

//ISequentialStream methods :
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read( 
        /* [length_is][size_is][out] */ void __RPC_FAR *pv,
        /* [in] */ ULONG cb,
        /* [out] */ ULONG __RPC_FAR *pcbRead);
    
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Write( 
        /* [size_is][in] */ const void __RPC_FAR *pv,
        /* [in] */ ULONG cb,
        /* [out] */ ULONG __RPC_FAR *pcbWritten);

//IStream methods :
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Seek( 
        /* [in] */ LARGE_INTEGER dlibMove,
        /* [in] */ DWORD dwOrigin,
        /* [out] */ ULARGE_INTEGER __RPC_FAR *plibNewPosition);
    
    virtual HRESULT STDMETHODCALLTYPE SetSize( 
        /* [in] */ ULARGE_INTEGER libNewSize);
    
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( 
        /* [unique][in] */ IStream __RPC_FAR *pstm,
        /* [in] */ ULARGE_INTEGER cb,
        /* [out] */ ULARGE_INTEGER __RPC_FAR *pcbRead,
        /* [out] */ ULARGE_INTEGER __RPC_FAR *pcbWritten);
    
    virtual HRESULT STDMETHODCALLTYPE Commit( 
        /* [in] */ DWORD grfCommitFlags);
    
    virtual HRESULT STDMETHODCALLTYPE Revert( void);
    
    virtual HRESULT STDMETHODCALLTYPE LockRegion( 
        /* [in] */ ULARGE_INTEGER libOffset,
        /* [in] */ ULARGE_INTEGER cb,
        /* [in] */ DWORD dwLockType);
    
    virtual HRESULT STDMETHODCALLTYPE UnlockRegion( 
        /* [in] */ ULARGE_INTEGER libOffset,
        /* [in] */ ULARGE_INTEGER cb,
        /* [in] */ DWORD dwLockType);
    
    virtual HRESULT STDMETHODCALLTYPE Stat( 
        /* [out] */ STATSTG __RPC_FAR *pstatstg,
        /* [in] */ DWORD grfStatFlag);
    
    virtual HRESULT STDMETHODCALLTYPE Clone( 
        /* [out] */ IStream __RPC_FAR *__RPC_FAR *ppstm);

	//IxbStream
	virtual bool	Clone(xbAccessMode om,xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
	virtual bool	Clone(xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
protected:
	bool			m_bCRLFasLF;
	xbFormatMode	m_format;
	ulong			m_streamTextCP,m_appTextCP;
	xbTextBOMtype	m_textBomType;
};

#define xbStreamWithCache_BUFFERSZ	1024
enum xbStreamWithCacheMode
{
	xbStreamWithCacheMode_Noop,
	xbStreamWithCacheMode_Read,
	xbStreamWithCacheMode_Write
};

class xbStreamWithCache;
struct xbEXPORT xbStreamWithCacheSt
{
	ulong					m_bufferSize;
	xbStreamWithCacheMode	m_mode;
	uchar					*m_pBuffer;
	ulong					m_bufferBusyLg,m_bufferBusyPos;
	xbStreamWithCacheSt()
	{
		m_mode = xbStreamWithCacheMode_Noop;
		m_pBuffer = NULL;
		m_bufferBusyLg = 0;
		m_bufferBusyPos = 0;
	}
	~xbStreamWithCacheSt()
	{
		eProtectTrace(bufferFree(););
	}
	void bufferEmpty()
	{
		m_mode = xbStreamWithCacheMode_Noop;
		m_bufferBusyLg = 0;
		m_bufferBusyPos = 0;
	}
	void bufferFree()
	{
		uchar *pBuf = m_pBuffer;
		if (!pBuf)
			return;
		m_pBuffer = NULL;
		g_xbEngineCenter.m_heap.Free(pBuf);
	}
	uchar *bufferAlloc()
	{
		uchar *pBuf = m_pBuffer;
		if (pBuf)
			return pBuf;
		m_pBuffer = pBuf = (uchar*)g_xbEngineCenter.m_heap.xbAlloc(m_bufferSize);
		return pBuf; 
	}
	uchar *bufferReadFeed()
	{
		xbRdbgAssert(m_mode != xbStreamWithCacheMode_Write);
		m_mode = xbStreamWithCacheMode_Read;
		m_bufferBusyLg = 0;
		m_bufferBusyPos = 0;
		return bufferAlloc();
	}
	void bufferReadFeedLength(ulong cByte)
	{
		xbRdbgAssert(m_bufferBusyPos == 0);
		m_bufferBusyLg = cByte;
	}
	ulong bufferRead(uchar *pData,ulong DataLg)
	{
		if (!DataLg)
			return 0;
		ulong staying = m_bufferBusyLg - m_bufferBusyPos;
		if (!staying)
			return 0;
		if (DataLg > staying)
			DataLg = staying;

		memcpy(pData,m_pBuffer+m_bufferBusyPos,DataLg);
		m_bufferBusyPos += DataLg;
		return DataLg;
	}
	void bufferReadReseek(xbStreamWithCache *pStm);
	ulong bufferReadBusyLength()
	{
		return m_bufferBusyLg - m_bufferBusyPos;
	}
	uchar *bufferReadBusy()
	{
		return m_pBuffer+m_bufferBusyPos;
	}
	ulong bufferReadComplete(uchar **ppData,ulong *pDataLg)
	{
		ulong staying = m_bufferBusyLg - m_bufferBusyPos;
		xbRdbgAssert(staying != 0);
		if (!staying)
		{
			*ppData = m_pBuffer;
			*pDataLg = m_bufferSize;
			return 0;
		}
		::memmove(m_pBuffer,m_pBuffer+m_bufferBusyPos,staying);
		m_bufferBusyPos = 0;
		m_bufferBusyLg = staying;

		*ppData = m_pBuffer + staying;
		*pDataLg = m_bufferSize - staying;

		return staying;
	}
	void bufferReadBusyDone(ulong cByte)
	{
		m_bufferBusyPos += cByte;
		xbRdbgAssert(m_bufferBusyPos <= m_bufferBusyLg);
	}

	ulong bufferWrite(const uchar *pData,ulong DataLg)
	{
		if (!DataLg)
			return 0;
		xbRdbgAssert(m_mode != xbStreamWithCacheMode_Read);
		if (m_mode != xbStreamWithCacheMode_Write)
		{
			m_mode = xbStreamWithCacheMode_Write;
			m_bufferBusyLg = 0;
			m_bufferBusyPos = 0;
			bufferAlloc();
		}
		ulong staying = m_bufferSize - m_bufferBusyPos;
		if (!staying)
			return 0;
		if (DataLg > staying)
			DataLg = staying;
		memcpy(m_pBuffer+m_bufferBusyPos,pData,DataLg);
		m_bufferBusyPos += DataLg;
		return DataLg;
	}
	void bufferWriteFlush(xbStreamWithCache *pStm,bool bWriteContinue = false);

	long getSubPosition() const
	{
		if (m_mode == xbStreamWithCacheMode_Read)
			return -long(m_bufferBusyLg) + long(m_bufferBusyPos);
		if (m_mode == xbStreamWithCacheMode_Write)
			return long(m_bufferBusyPos);
		xbRdbgAssert(m_mode == xbStreamWithCacheMode_Noop);
		return 0;
	}
};

class xbEXPORT __declspec(uuid("{71AD13D6-35A1-40ba-9E58-653C142D985C}"))
	xbStreamWithCache:public xbStream
{
public:
	xbStreamWithCache() {m_cache.m_bufferSize = xbStreamWithCache_BUFFERSZ;}
	~xbStreamWithCache()
	{
		xbRdbgAssert(m_cache.m_mode != xbStreamWithCacheMode_Write); //Si assert -> flush pas fait...
	}
	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(xbStreamWithCache);
		return xbStream::GetInterface(riid,ppInterf);
	}
	virtual ulong GetCacheSize() const {return m_cache.m_bufferSize;}
	virtual void SetCacheSize(ulong cByte);
	/*virtual*/ void CacheFlush();
	/*virtual*/ void CacheFlushRW(bool bNoReadSeek = false);

	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true);
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true);

//IxbInputStream methods :
	virtual IxbInputStream	&operator>>(sIxbStreamable *piObj)
	{
		return xbStream::operator>>(piObj);
	}
	virtual IxbInputStream	&operator>>(xbStringA *pStr);
	virtual IxbInputStream	&operator>>(xbStringW *pStr);
	virtual IxbInputStream	&operator>>(xbBSTR *pStr);

	virtual ulong			ReadStringA(xbStringA *pStr,xbStringA *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbStringW *pStr,xbStringW *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbBSTR *pStr,xbBSTR *pStopStr = NULL,IxbStreamMode *pMode = NULL);

//IxbStreamMode methods
//	virtual void			ReadTextBOM(xbTextBOMtype *pbBOMtype = NULL);

	virtual bool ioMTlock() const {return true;}
protected:
	virtual void throwStreamReadEnd(const xbString &str);
	virtual void throwStreamWriteEnd(const xbString &str);
	virtual ulong noCacheRead(uchar *pData,ulong DataLg) = 0;
	virtual ulong noCacheWrite(const uchar *pData,ulong DataLg) = 0;

	ulong internalReadStringA(xbFormatMode fmtDefault,IxbStreamMode *pMode,xbStringA *pStr,xbStringA *pStopStr);
	ulong internalReadStringW(xbFormatMode fmtDefault,IxbStreamMode *pMode,xbStringW *pStr,xbStringW *pStopStr);
	ulong internalReadStringW(xbFormatMode fmtDefault,IxbStreamMode *pMode,xbBSTR *pStr,xbBSTR *pStopStr);
	ulong internalReadStringTextA(xbStringA *pStr,xbStringA *pStopStr,IxbStreamMode *pMode,xbLock *pLck);
	ulong internalReadStringTextW(xbStringW *pStr,xbStringW *pStopStr,IxbStreamMode *pMode,xbLock *pLck);
	ulong internalReadStringTextW(xbBSTR *pStr,xbBSTR *pStopStr,IxbStreamMode *pMode,xbLock *pLck);

	xbStreamWithCacheSt		m_cache;
	friend xbStreamWithCacheSt;
};

class xbEXPORT __declspec(uuid("{5BEB7D6B-8935-414d-A34E-3FBC3CEF23A5}"))
	xbMemoryStream:public xbStream
{
public:
//xbMemoryStream ctors & dtor
	xbImplCreateObject(xbMemoryStream,IxbStream);
	xbImplCreateObject(xbMemoryStream,xbStream);
	xbImplCreateObject(xbMemoryStream,xbMemoryStream);

	xbMemoryStream(xbAccessMode om = xbAccessRW);
	xbMemoryStream(xbMemoryStream &strm,bool shared,xbAccessMode om = xbAccessRW);//shared -> partage, sinon copie
	virtual ~xbMemoryStream();
	virtual void Create()
	{
		m_bCreated = true;
	}
	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(xbMemoryStream);
		return xbStream::GetInterface(riid,ppInterf);
	}
	void CopyFrom(const xbData &data);
	void CopyTo(xbData *pData) const;
	void Attach(xbData *pData);
	void Detach(xbData *pData); //CAUTION: pData can't be NULL

//MT lock functions (sIxbLock)
	virtual void			Lock() const;
	virtual void			Unlock() const;

//Read functions (IxbInputStream)
	virtual bool			CanRead() const {return m_AccessMode != xbAccessW;}
	virtual char			ReadChar();
	virtual wchar			ReadCharW();
	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true);

//Write functions (IxbOutputStream)
	virtual bool			CanWrite() const {return m_AccessMode != xbAccessR;}
	virtual void			WriteChar(char car);
	virtual void			WriteCharW(wchar car);
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true);

//Seek functions (IxbSeekStream)
	virtual bool			Eof() const;
	virtual bool			Bof() const;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet);
	virtual ulong			GetPosition() const		{return m_CurPos;}
	virtual ulong			SetPosition(ulong pos);
	virtual ulong			GetLength() const			{return ulong(m_pBuf->GetLength());}
	virtual void			SetLength(ulong sz);
	virtual void			SetEof();

//IxbStreamInfo
	virtual xbString		GetName() const {return "xbMemoryStream";}
	virtual xbString		GetPhysicalName() const {return "!xbMemoryStream-noname";}

//IxbStream
	virtual bool	Clone(xbAccessMode om,xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
	virtual bool	Clone(xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
protected:
	class StBuffer
	{
	public:
		StBuffer()			{m_SharedCnt = 1;}
		long				m_SharedCnt;
		xbData				m_data;
		xbSectShare	m_sect;
		ulong				GetLength() const {return m_data.GetLength();}
		xbHeapNewImpl(StBuffer);
	};
	StBuffer		*m_pBuf;
	long			m_CurPos;
	xbAccessMode	m_AccessMode;

	void		chgBufSz(long size);
	void		growBufIfNecessary(long relsize);
};

class xbEXPORT __declspec(uuid("{7F1C23B5-8273-4be3-A6A1-BA7AF6CB1876}"))
	xbFileStream:public xbStreamWithCache,public IxbLongSeekStream,public IxbLongStream
{
public:
//xbFileStream ctors & dtor
	xbImplCreateObject(xbFileStream,IxbStream);
	xbImplCreateObject(xbFileStream,xbStream);
	xbImplCreateObject(xbFileStream,xbFileStream);
	xbFileStream();
	xbFileStream(const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive);
	xbFileStream(const xbSecurityAttr &attr,const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive);
	virtual ~xbFileStream();
	virtual void Destroy();
	virtual void Create()
	{
		m_bCreated = true;
	}


	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(IxbLongSeekStream);
		xbImplInterface(xbFileStream);
		xbImplInterface(IxbLongStream);
		return xbStreamWithCache::GetInterface(riid,ppInterf);
	}

	xbImplObject();

//xbFileStream dependants functions
	virtual void	Open(const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive);
	virtual void	Open(const xbSecurityAttr &attr,const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive);
	virtual void	Open(const xbSecurityAttr *pAttr,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive);
	virtual void	Close();

//MT lock functions (sIxbLock)
	virtual void			Lock() const;
	virtual void			Unlock() const;

//Read functions (IxbInputStream)
	virtual bool			CanRead() const 
	{
		xbSectLock lck(m_pSectPtr);
		return m_fh != INVALID_HANDLE_VALUE && m_AccessMode != xbAccessW;
	}

	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true)
	{
		return xbStreamWithCache::Read(pData,DataLg,DataLg_Required);
	}
	virtual ulong			ReadStringA(xbStringA *pStr,xbStringA *pStopStr,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::ReadStringA(pStr,pStopStr,pMode);
	}
	virtual ulong			ReadStringW(xbStringW *pStr,xbStringW *pStopStr,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::ReadStringW(pStr,pStopStr,pMode);
	}
	virtual ulong			ReadStringW(xbBSTR *pStr,xbBSTR *pStopStr,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::ReadStringW(pStr,pStopStr,pMode);
	}
	virtual IxbInputStream	&operator>>(sIxbStreamable *piObj)
	{
		return xbStreamWithCache::operator>>(piObj);
	}
	virtual IxbInputStream	&operator>>(xbStringA *pStr)
	{
		return xbStreamWithCache::operator>>(pStr);
	}
	virtual IxbInputStream	&operator>>(xbStringW *pStr)
	{
		return xbStreamWithCache::operator>>(pStr);
	}
	virtual IxbInputStream	&operator>>(xbBSTR *pStr)
	{
		return xbStreamWithCache::operator>>(pStr);
	}
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,char,Char);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,wchar,CharW);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,uchar,Uchar);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,short,Short);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,ushort,Ushort);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,long,Long);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,ulong,Ulong);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,int64,Int64);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,uint64,Uint64);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,GUID,Guid);
	IxbInputStreamHelpDclEx(xbStreamWithCache::Read,double,Double);

//Write functions (IxbOutputStream)
	virtual bool			CanWrite() const
	{
		xbSectLock lck(m_pSectPtr);
		return m_fh != INVALID_HANDLE_VALUE && m_AccessMode != xbAccessR;
	}
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true)
	{
		return xbStreamWithCache::Write(pData,DataLg,DataLg_Required);
	}
	virtual uint64			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm)
	{
		return xbStreamWithCache::WriteStream(pCb,pstm);
	}
	virtual ulong			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm,ulong DataLg,bool DataLg_Required = true)
	{
		return xbStreamWithCache::WriteStream(pCb,pstm,DataLg,DataLg_Required);
	}
	virtual ulong			WriteStringA(const char *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::WriteStringA(pStr,lgStr,bAddLf,pMode);
	}
	virtual ulong			WriteStringW(const wchar *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::WriteStringW(pStr,lgStr,bAddLf,pMode);
	}

	virtual ulong			WriteStringA(const xbStringA &str,bool bAddLf = false,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::WriteStringA(str,bAddLf,pMode);
	}
	virtual ulong			WriteStringW(const xbStringW &str,bool bAddLf = false,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::WriteStringW(str,bAddLf,pMode);
	}
	virtual ulong			WriteStringW(const xbBSTR &str,bool bAddLf = false,IxbStreamMode *pMode = NULL)
	{
		return xbStreamWithCache::WriteStringW(str,bAddLf,pMode);
	}
	virtual IxbOutputStream	&operator<<(const sIxbStreamable &iobj)
	{
		return xbStreamWithCache::operator <<(iobj);
	}
	virtual IxbOutputStream	&operator<<(const xbStringA &str)
	{
		return xbStreamWithCache::operator <<(str);
	}
	virtual IxbOutputStream	&operator<<(const xbStringW &str)
	{
		return xbStreamWithCache::operator <<(str);
	}
	virtual IxbOutputStream	&operator<<(const xbBSTR &str)
	{
		return xbStreamWithCache::operator <<(str);
	}
	virtual IxbOutputStream	&operator<<(const char *pStr)
	{
		return xbStreamWithCache::operator <<(pStr);
	}
	virtual IxbOutputStream	&operator<<(const wchar *pStr)
	{
		return xbStreamWithCache::operator <<(pStr);
	}
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,char,Char);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,wchar,CharW);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,uchar,Uchar);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,short,Short);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,ushort,Ushort);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,long,Long);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,ulong,Ulong);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,int64,Int64);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,uint64,Uint64);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,GUID,Guid);
	IxbOutputStreamHelpDclEx(xbStreamWithCache::Write,double,Double);

//Seek functions (IxbSeekStream, 32 bits seek)
	virtual bool			Eof() const;
	virtual bool			Bof() const;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet);
	virtual ulong			GetPosition() const;
	virtual ulong			SetPosition(ulong pos);
	virtual ulong			GetLength() const;
	virtual void			SetLength(ulong sz);
	virtual void			SetEof();

//Long Seek functions (IxbLongSeekStream, 64 bits seek)
	virtual uint64			LongSeek(int64 pos,xbSeekMode sk = xbSeekSet);
	virtual uint64			GetLongPosition() const;
	virtual uint64			SetLongPosition(uint64 pos);
	virtual uint64			GetLongLength() const;
	virtual void			SetLongLength(uint64 sz);
	xbPropertyRW(uint64,LongLength);
	xbPropertyRW(uint64,LongPosition);

//Divers
	virtual xbString		GetName() const;
	virtual xbString		GetPhysicalName() const {return m_FileName;}

	virtual bool GetFileTime(FILETIME *pCreationTime, FILETIME *pLastAccessTime, FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required);
	virtual bool SetFileTime(const FILETIME *pCreationTime, const FILETIME *pLastAccessTime, const FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required );
	virtual bool GetFileTime(xbDateTime *pCreationTime, xbDateTime *pLastAccessTime, xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required)
	{
		return xbStreamWithCache::GetFileTime(pCreationTime,pLastAccessTime,pLastWriteTime,opm);
	}
	virtual bool SetFileTime(const xbDateTime *pCreationTime, const xbDateTime *pLastAccessTime, const xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required )
	{
		return xbStreamWithCache::SetFileTime(pCreationTime,pLastAccessTime,pLastWriteTime,opm);
	}

//Self methods
	HANDLE GetHandle()
	{
		xbSectLock lck(m_pSectPtr);
		if (m_fh == INVALID_HANDLE_VALUE)
			xbThrow xbEstream(this,"No file opened (GetHandle)");
		return m_fh;
	}
	bool IsClosed() const
	{
		return m_fh == INVALID_HANDLE_VALUE;
	}
	bool IsOpened() const
	{
		return m_fh != INVALID_HANDLE_VALUE;
	}
	bool IsStdHandle() const
	{
		return m_bStdHandle;
	}

	//IxbStream
	virtual bool	Clone(xbAccessMode om,xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
	virtual bool	Clone(xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
protected:
	virtual ulong			onGetFileAttribute() {return FILE_ATTRIBUTE_NORMAL;}
	xbAccessMode	m_AccessMode;
	xbString		m_FileName;
	HANDLE			m_fh;
	bool			m_bStdHandle;

	virtual ulong			noCacheRead(uchar *pData,ulong DataLg);
	virtual ulong			noCacheWrite(const uchar *pData,ulong DataLg);
};

class xbEXPORT __declspec(uuid("{AB11EC6A-B798-467d-A58B-29CBBC576840}")) 
	xbTempStream:public xbFileStream
{
public:
//xbTempStream ctors & dtor
	xbImplCreateObject(xbTempStream,IxbStream);
	xbImplCreateObject(xbTempStream,xbStream);
	xbImplCreateObject(xbTempStream,xbTempStream);
	xbTempStream();
	xbTempStream(bool bOpen,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);
	xbTempStream(const xbSecurityAttr &attr,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);
	virtual ~xbTempStream();
	virtual void Destroy();

	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(xbTempStream);
		return xbFileStream::GetInterface(riid,ppInterf);
	}

//xbTempStream dependants functions
	xbOpMode GetDelFileOpMode() const
	{
		xbSectLock lck(m_pSectPtr);
		return m_delFileOpMode;
	}
	void SetDelFileOpMode(xbOpMode val)
	{
		xbSectLock lck(m_pSectPtr);
		m_delFileOpMode = val;
	}

	virtual void	OpenCreate(xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // if already open -> recreate file
	virtual void	Open(xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);
	virtual void	OpenNew(bool bDelPrevious = true,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);

	virtual void	OpenCreate(bool bTemporaryFile,const xbString &file,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // bTemporaryFile = false -> permanent file (not deleted at end)
	virtual void	Open(bool bTemporaryFile,const xbString &file,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // bTemporaryFile = false -> permanent file (not deleted at end)

	virtual void	OpenCreate(const xbSecurityAttr &attr,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // if already open -> recreate file
	virtual void	Open(const xbSecurityAttr &attr,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);
	virtual void	OpenNew(const xbSecurityAttr &attr,bool bDelPrevious = true,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true);

	virtual void	OpenCreate(const xbSecurityAttr &attr,bool bTemporaryFile,const xbString &file,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // bTemporaryFile = false -> permanent file (not deleted at end)
	virtual void	Open(const xbSecurityAttr &attr,bool bTemporaryFile,const xbString &file,xbWorkMode wm = xbWorkExclusive,xbAccessMode am = xbAccessRW,bool bAlways = true); // bTemporaryFile = false -> permanent file (not deleted at end)
//Divers
	virtual xbString		GetName() const;
protected:
	virtual ulong			onGetFileAttribute() {return m_bTemp?FILE_ATTRIBUTE_TEMPORARY:xbFileStream::onGetFileAttribute();}

	virtual void	Open(const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive)
	{
		xbThrow xbEsys("xbTempStream::Open("+fileName+", ...) : call to this function not allowed");
	}
	virtual void	Open(const xbSecurityAttr &attr,const xbString &fileName,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive)
	{
		xbThrow xbEsys("xbTempStream::Open("+fileName+", ...) : call to this function not allowed");
	}
	virtual void	Open(const xbSecurityAttr *pAttr,xbOpenMode om,xbAccessMode am = xbAccessRW,xbWorkMode wm = xbWorkExclusive)
	{
		xbThrow xbEsys("xbTempStream::Open(...) : call to this function not allowed");
	}
	bool	m_bTemp;
	xbOpMode m_delFileOpMode;
};

class xbEXPORT __declspec(uuid("{946E7DF3-1458-46b1-B5E6-69A76ED32B78}"))
	xbNoLockStream:public xbObjectBase,
	public IxbInputStream,public IxbOutputStream,
	public IxbSeekStream,/*public IxbStreamMode,*/public IxbStream,public IxbStreamInfo
{
public:
	xbNoLockStream() {/*m_bCRLFasLF = true; m_format = xbFormatBinary;*/}
	virtual ~xbNoLockStream() 
	{
	}

	xbImplObject();

	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(IxbInputStream);
		xbImplInterface(IxbOutputStream);
		xbImplInterface(IxbSeekStream);
//		xbImplInterface(IxbStreamMode);
		xbImplInterface(xbNoLockStream);
		xbImplInterface(IxbStream);
		xbImplInterface(IxbStreamInfo);
		return xbObjectBase::GetInterface(riid,ppInterf);
	}

//IxbStreamInfo methods :
	virtual xbString		GetName() const = 0;
	virtual xbString		GetPhysicalName() const = 0;
	virtual bool GetFileTime(FILETIME *pCreationTime, FILETIME *pLastAccessTime, FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required);
	virtual bool SetFileTime(const FILETIME *pCreationTime, const FILETIME *pLastAccessTime, const FILETIME *pLastWriteTime, xbOpMode opm =xbOp_Required );
	virtual bool GetFileTime(xbDateTime *pCreationTime, xbDateTime *pLastAccessTime, xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required);
	virtual bool SetFileTime(const xbDateTime *pCreationTime, const xbDateTime *pLastAccessTime, const xbDateTime *pLastWriteTime, xbOpMode opm =xbOp_Required );
	virtual xbString		GetStreamContentType() const {return xbString();}

//IxbInputStream methods :
	virtual bool			CanRead() const = 0;
	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true) = 0;

	virtual IxbInputStream	&operator>>(sIxbStreamable *piObj);
	virtual IxbInputStream	&operator>>(xbStringA *pStr);
	virtual IxbInputStream	&operator>>(xbStringW *pStr);
	virtual IxbInputStream	&operator>>(xbBSTR *pStr);

	virtual ulong			ReadStringA(xbStringA *pStr,xbStringA *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbStringW *pStr,xbStringW *pStopStr = NULL,IxbStreamMode *pMode = NULL);
	virtual ulong			ReadStringW(xbBSTR *pStr,xbBSTR *pStopStr = NULL,IxbStreamMode *pMode = NULL);

	IxbInputStreamHelpDcl(uchar,Uchar);
	IxbInputStreamHelpDcl(char,Char);
	IxbInputStreamHelpDcl(wchar,CharW);
	IxbInputStreamHelpDcl(short,Short);
	IxbInputStreamHelpDcl(ushort,Ushort);
	IxbInputStreamHelpDcl(long,Long);
	IxbInputStreamHelpDcl(ulong,Ulong);
	IxbInputStreamHelpDcl(int64,Int64);
	IxbInputStreamHelpDcl(uint64,Uint64);
	IxbInputStreamHelpDcl(GUID,Guid);
	IxbInputStreamHelpDcl(double,Double);

//IxbOutputStream methods :
	virtual bool			CanWrite() const = 0;
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true) = 0;
	virtual uint64			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm);
	virtual ulong			WriteStream(sIxbProgress *pCb,IxbInputStream *pstm,ulong DataLg,bool DataLg_Required = true);

	virtual IxbOutputStream	&operator<<(const sIxbStreamable &iobj);
	virtual IxbOutputStream	&operator<<(const char *pStr);
	virtual IxbOutputStream	&operator<<(const wchar *pStr);
	virtual IxbOutputStream	&operator<<(const xbStringA &str);
	virtual IxbOutputStream	&operator<<(const xbStringW &str);
	virtual IxbOutputStream	&operator<<(const xbBSTR &str);

	virtual ulong			WriteStringA(const xbStringA &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringA(const char *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const xbStringW &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const xbBSTR &str,bool bAddLf = false,IxbStreamMode *pMode = NULL);
	virtual ulong			WriteStringW(const wchar *pStr,ulong lgStr,bool bAddLf = false,IxbStreamMode *pMode = NULL);

	IxbOutputStreamHelpDcl(uchar,Uchar);
	IxbOutputStreamHelpDcl(char,Char);
	IxbOutputStreamHelpDcl(wchar,CharW);
	IxbOutputStreamHelpDcl(short,Short);
	IxbOutputStreamHelpDcl(ushort,Ushort);
	IxbOutputStreamHelpDcl(long,Long);
	IxbOutputStreamHelpDcl(ulong,Ulong);
	IxbOutputStreamHelpDcl(int64,Int64);
	IxbOutputStreamHelpDcl(uint64,Uint64);
	IxbOutputStreamHelpDcl(GUID,Guid);
	IxbOutputStreamHelpDcl(double,Double);

//IxbSeekStream methods :
	virtual bool			Eof() const = 0;
	virtual bool			Bof() const = 0;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet) = 0;
	virtual ulong			GetPosition() const = 0;
	virtual ulong			SetPosition(ulong pos) = 0;
	virtual ulong			GetLength() const = 0;
	virtual void			SetLength(ulong sz) = 0;
	virtual void			SetEof() = 0;

	xbPropertyRW(ulong,Length);
	xbPropertyRW(ulong,Position);
//IxbStreamMode methods : not implemented

//IxbStream
	virtual bool	Clone(xbAccessMode om,xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
	virtual bool	Clone(xbRefPtr<IxbStream> *pprStm, xbOpMode opm =xbOp_Required);
};

class xbEXPORT __declspec(uuid("{3F377E00-2877-407c-B436-41E5F1C7FA8A}"))
	xbDataStream:public xbNoLockStream
{
public:
//xbMemoryStream ctors & dtor
	xbDataStream(xbData *pData,xbAccessMode om = xbAccessRW);
	virtual ~xbDataStream();
	virtual void Create()
	{
		m_bCreated = true;
	}
	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(xbDataStream);
		return xbNoLockStream::GetInterface(riid,ppInterf);
	}

	void SetData(xbData *pData,xbAccessMode om) {m_pData = pData;m_AccessMode = om;m_CurPos = 0;}
	xbData *GetData() {return m_pData;}

//Read functions (IxbInputStream)
	virtual bool			CanRead() const {return m_AccessMode != xbAccessW && m_pData;}
	virtual char			ReadChar();
	virtual wchar			ReadCharW();
	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true);

//Write functions (IxbOutputStream)
	virtual bool			CanWrite() const {return m_AccessMode != xbAccessR && m_pData;}
	virtual void			WriteChar(char car);
	virtual void			WriteCharW(wchar car);
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true);

//Seek functions (IxbSeekStream)
	virtual bool			Eof() const;
	virtual bool			Bof() const;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet);
	virtual ulong			GetPosition() const		{return m_CurPos;}
	virtual ulong			SetPosition(ulong pos);
	virtual ulong			GetLength() const			{return ulong(m_pData->GetLength());}
	virtual void			SetLength(ulong sz);
	virtual void			SetEof();

//Divers
	virtual xbString		GetName() const {return "xbDataStream";}
	virtual xbString		GetPhysicalName() const {return "!xbDataStream-noname";}
protected:
	xbData			*m_pData;
	long			m_CurPos;
	xbAccessMode	m_AccessMode;

	void		chgBufSz(long size);
	void		growBufIfNecessary(long relsize);
};

class xbEXPORT __declspec(uuid("{3F377E00-2877-407c-B436-41E5F1C7FA8A}"))
	xbConstStream:public xbNoLockStream
{
public:
//xbMemoryStream ctors & dtor
	xbConstStream(const void *pData,int cByte,xbAccessMode om = xbAccessR);
	virtual ~xbConstStream();
	virtual void Create()
	{
		m_bCreated = true;
	}
	virtual bool GetInterface(REFIID riid, void ** ppInterf)
	{
		xbImplInterface(xbConstStream);
		return xbNoLockStream::GetInterface(riid,ppInterf);
	}

	void SetData(const void *pData,xbint cByte,xbAccessMode om = xbAccessR) 
	{
		m_pData = (const uchar *)pData;
		m_pDataEnd = m_pData + cByte;
		m_pCurPos = (uchar*)m_pData;
		m_AccessMode = om;
	}
	const void *GetData(xbint *pcByte);

//Read functions (IxbInputStream)
	virtual bool			CanRead() const {return m_AccessMode != xbAccessW && m_pData;}
	virtual char			ReadChar();
	virtual wchar			ReadCharW();
	virtual ulong			Read(void *pData,ulong DataLg,bool DataLg_Required = true);

//Write functions (IxbOutputStream)
	virtual bool			CanWrite() const {return m_AccessMode != xbAccessR && m_pData;}
	virtual void			WriteChar(char car);
	virtual void			WriteCharW(wchar car);
	virtual ulong			Write(const void *pData,ulong DataLg,bool DataLg_Required = true);

//Seek functions (IxbSeekStream)
	virtual bool			Eof() const;
	virtual bool			Bof() const;
	virtual ulong			Seek(long pos,xbSeekMode sk = xbSeekSet);
	virtual ulong			GetPosition() const;
	virtual ulong			SetPosition(ulong pos);
	virtual ulong			GetLength() const;
	virtual void			SetLength(ulong sz);
	virtual void			SetEof();

//Divers
	virtual xbString		GetName() const {return "xbConstStream";}
	virtual xbString		GetPhysicalName() const {return "!xbConstStream-noname";}
protected:
	const uchar		*m_pData;
	const uchar		*m_pDataEnd;
	uchar			*m_pCurPos;
	xbAccessMode	m_AccessMode;
};

#endif
