// =====================================================================
/*!
//
//  \file TObjectFile.hh
//  \brief This file contains the TObjectFile class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TObjectFile.hh,v 1.8 2004/03/07 10:30:32 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TObjectFile.hh,v $
//  Revision 1.8  2004/03/07 10:30:32  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.7  2004/01/19 21:09:41  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.6  2003/11/24 07:04:37  goiwai
//  以下のメンバ関数を追加しました.
//  このへんはオフラインむけの関数と考えて下さい.
//  ソケットやメモリに対してこのへんを実装するのは骨が折れそうなので,ファ
//  イルのみへの実装とします.
//
//  Tint GetStreamSize() const;
//  ストリームの全長をバイト単位で返します.
//
//  Tint Size() const;
//  ストリームに含まれるレコードの数を返します.
//
//  Tint FindDataRecord( const Tstring& id, Tint offset = 0 ) const;
//  Tint Find( const Tstring& id, Tint offset = 0 ) const;
//  IDに一致するレコード位置を返します.そのときオフセットもその位置になります.
//
//  Tint FindDataRecord( Tint index, Tint offset = 0 ) const;
//  Tint Find( Tint index, Tint offset = 0 ) const;
//  index番目のレコード位置を返します.そのときオフセットもその位置になります.
//
//  Revision 1.5  2003/11/03 08:35:13  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.4  2003/10/12 13:03:43  goiwai
//  最近できた FileProperty を持たせています.またEOFとエラーの検知のために
//  IsEnd()とIsError()を追加しました.
//
//  Revision 1.3  2003/10/06 17:02:42  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:19:30  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TOBJECTFILE_HH
#define CLDAQ__TOBJECTFILE_HH

#include "Tglobals.h"
#include "TFileProperty.hh"


/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TObjectFile
// \brief This is the TObjectFile class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TObjectFile class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup PersistencyCategory
*/
class TObjectFile
{

  public:
    enum { 
      ERROR = -1
    };

    enum { 
      tSeekBegin = SEEK_SET, 
      tSeekCurrent = SEEK_CUR, 
      tSeekEnd = SEEK_END
    };

  protected:
    Tstring theFileName;
    Tstring theMode;
    TFileStream* theFileStream;
    TFileProperty theFileProperty;

  public:
    TObjectFile( const Tstring& filename, const Tstring& mode );

  protected:
    virtual ~TObjectFile();

  public:
    const Tstring& GetFileName() const;
    const Tstring& GetMode() const;
    TFileStream* GetFileStream() const;
    Tvoid SetFileName( const Tstring& filename );
    Tvoid SetMode( const Tstring& mode );
    const TFileProperty& GetFileProperty() const;

  public:
    //inline const Tvoid* SetFileStream() const;
    Tvoid SetOffset( Tint offset, Tint whence = tSeekCurrent );
    Tint GetOffset();
    Tbool IsEnd() const;
    Tbool IsError() const;

    // とりあえずファイルのみの実装
    //! ファイルサイズをバイトで得る
    Tint GetStreamSize() const;

    //! 何個のレコードからなるか
    Tint Size() const;

    //! 見つかれば id をもつレコードの位置を返す
    Tint FindDataRecord( const Tstring& id, Tint offset = 0 ) const;

    //! 見つかれば index 番目のレコードの位置を返す
    Tint FindDataRecord( Tint index, Tint offset = 0 ) const;

    //! 見つかれば id をもつレコードの位置を返す
    Tint Find( const Tstring& id, Tint offset = 0 ) const;

    //! 見つかれば index 番目のレコードの位置を返す
    Tint Find( Tint index, Tint offset = 0 ) const;

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TObjectFile,0)
#endif

};

inline const Tstring& TObjectFile::GetFileName() const
{ 
  return theFileName;
}

inline const Tstring& TObjectFile::GetMode() const
{ 
  return theMode;
}

inline TFileStream* TObjectFile::GetFileStream() const
{
  return theFileStream;
}

inline Tvoid TObjectFile::SetFileName( const Tstring& filename )
{
  theFileName = filename;
  return;
}

inline Tvoid TObjectFile::SetMode( const Tstring& mode )
{
  // reopenしなくては
  theMode = mode;
  return;
}

inline Tvoid TObjectFile::SetOffset( Tint offset, Tint whence )
{
  fseek( theFileStream, (Tlong)offset, whence );
  return;
}

inline Tint TObjectFile::GetOffset()
{
  return (Tint)( ftell( theFileStream ) );
}

inline const TFileProperty& TObjectFile::GetFileProperty() const
{
  return theFileProperty;
}

inline Tbool TObjectFile::IsEnd() const
{
  return ( feof( theFileStream ) != 0 );
}

inline Tbool TObjectFile::IsError() const
{
  return ( ferror( theFileStream ) != 0 );
}

inline Tint TObjectFile::Find( const Tstring& id, Tint offset ) const
{
  return FindDataRecord( id, offset );
}

inline Tint TObjectFile::Find( Tint index, Tint offset ) const
{
  return FindDataRecord( index, offset );
}

#endif
