//-------------------------------------------------------------------
//
//  For conditions of distribution and use, see copyright notice
//  in Flashpix.h 
// 
//  Copyright (c) 1999 Digital Imaging Group, Inc.
// 
//  Contents:       Stream header for mstream project
//
//  Classes:        CSStream - single linear stream for MSF
//
//--------------------------------------------------------------------



#ifndef __STREAM_HXX__
#define __STREAM_HXX__

#include "msf.hxx"
#include "handle.hxx"
#include "entry.hxx"

//+---------------------------------------------------------------------------
//
//  Class:  CStreamCache (stmc)
//
//  Purpose:  Cache for stream optimization
//
//  Interface:  See below.
//
//----------------------------------------------------------------------------

class CStreamCache
{
public:
    inline CStreamCache();
    
    inline void SetCache(ULONG ulOffset, SECT sect);
    inline ULONG GetOffset(void) const;
    inline SECT GetSect(void) const;
    
private:
    ULONG _ulOffset;
    SECT  _sect;
};


//+---------------------------------------------------------------------------
//
//  Member: CStreamCache::CStreamCache, public
//
//  Synopsis: CStreamCache constructor
//
//----------------------------------------------------------------------------

inline CStreamCache::CStreamCache()
{
    _ulOffset = MAX_ULONG;
    _sect = ENDOFCHAIN;
}


//+---------------------------------------------------------------------------
//
//  Member: CStreamCache::SetCache, public
//
//  Synopsis: Set the cache information
//
//  Arguments:  [ulOffset] -- Offset into chain
//              [sect] -- Sect at that offset
//
//----------------------------------------------------------------------------

inline void CStreamCache::SetCache(ULONG ulOffset, SECT sect)
{
    _ulOffset = ulOffset;
    _sect = sect;
}

//+---------------------------------------------------------------------------
//
//  Member: CStreamCache::GetOffset, public
//
//  Synopsis: Return offset
//
//----------------------------------------------------------------------------

inline ULONG CStreamCache::GetOffset(void) const
{
    return _ulOffset;
}


//+---------------------------------------------------------------------------
//
//  Member: CStreamCache::GetSect, public
//
//  Synopsis: Return sect
//
//----------------------------------------------------------------------------

inline SECT CStreamCache::GetSect(void) const
{
    return _sect;
}


//+----------------------------------------------------------------------
//
//      Class:      CDirectStream (ds)
//
//      Purpose:    Direct stream class
//
//      Notes:
//
//-----------------------------------------------------------------------

class CDirectStream: public PEntry
{

public:
    CDirectStream(DFLUID dl);
    void InitSystem( CMStream *pms,
                     SID sid,
                     ULONG cbSize);
    SCODE Init( CStgHandle *pstgh,
                CDfName const *pdfn,
                BOOL const fCreate);
    virtual ~CDirectStream();

    void AddRef();
    
    inline void DecRef();
    
    void Release();


    SCODE ReadAt( ULONG ulOffset,
                  VOID HUGEP *pBuffer,
                  ULONG ulCount,
                  ULONG STACKBASED *pulRetval);
    SCODE WriteAt( ULONG ulOffset,
                   VOID const HUGEP *pBuffer,
                   ULONG ulCount,
                   ULONG STACKBASED *pulRetval);
    
    SCODE SetSize(ULONG ulNewSize);
    void GetSize(ULONG *pulSize);

    // PEntry
    virtual SCODE GetTime(WHICHTIME wt, TIME_T *ptm);
    virtual SCODE SetTime(WHICHTIME wt, TIME_T tm);


    inline CStmHandle *GetHandle(void);

private:
    CStmHandle _stmh;
    CStreamCache _stmc;
    ULONG    _ulSize;
    ULONG    _ulOldSize;

    LONG _cReferences;

#ifdef _MSC_VER
#pragma warning(disable:4512)
// default assignment operator could not be generated since we have a const
// member variable (of PEntry). This is okay since we are not using 
// the assignment operator anyway.
#endif // MSC_VER
};

#ifdef _MSC_VER
#pragma warning(default:4512)
#endif // _MSC_VER

//+---------------------------------------------------------------------------
//
//  Member: CDirectStream::GetHandle, public
//
//  Synopsis: Returns a pointer to the stream handle
//
//----------------------------------------------------------------------------

inline CStmHandle *CDirectStream::GetHandle(void)
{
    return &_stmh;
}

//+---------------------------------------------------------------------------
//
//  Member: CDirectStream::DecRef, public
//
//  Synopsis: Decrements the ref count
//
//----------------------------------------------------------------------------

inline void CDirectStream::DecRef()
{
    AtomicDec(&_cReferences);
}

#endif  //__SSTREAM_HXX__


