// Change History
// 03/05/04 AV Development: Fix memory leak. Close Seq file buffer when file is closed
// 11/19/03 AV Development: name as std::string, merging ...
// 11/19/03 AV Development: Merge Production version 5

//
// AT_FILE.H -- optimized sequential files (AT_Seq_File), and
//              >4Gb random-access files (AT_Rand_File).
//              Files may be block-aligned, e.g. for CD-ROM
//
// A file must be either read- or write-only, and either random- or sequential.
// Each of these characteristics is represented by a class derived from AT_File;
// concrete classes are dervied by MI therefrom.
//
// Does NOT use exceptions, but bool returns.
//

#ifndef AT_FILE_H
#define AT_FILE_H

#include <string>

#include "base/at_defs.h"
#include "base/at_filetypes.h"
#include "base/AT_PagedMem.h"

#ifdef USE_DLLS
#include "at_error.h"
#endif

#ifdef QUANTILES
#include "at_error.h"
#endif

namespace Xpace
{
  class File;
};

enum AT_File_Type;

// ABC
class SEARCH_DECL AT_File
{
public :
  virtual ~AT_File
    ()
  = 0;

  // is file (in)valid?
  virtual bool operator!
    ()
    const;

  // close file
  virtual bool close
    ();
  // get current file position
  uint64 getPos
    ()
    const;

  // get file size
  virtual uint64 getSize
    ()
    const;

  // get block size (default = 1)
  uint getBlockSize
    ()
    const;

  // align to block size; return offset
  virtual uint64 align
    ()
  = 0;
  // how much space remains in this block?
  uint alignFree             // returns #bytes left in this block
    ()
    const;

  bool getFullName
    (byte *name,
     uint sz)
    const;

  const byte *const fullName
    ()
    const;

  AT_File_Type getType
    ()
    const;

  uint16 getVersion
    ()
    const;

  static uint64 GetFileSize
    (const byte * fname)
  { assert(0); return 0; };

  Xpace::File* x_File;

protected :
  AT_File
    (const byte* fname);

  AT_File
    (const AT_File&);
  AT_File& operator=
    (const AT_File&);

  std::vector<byte> file_name;
};

// ================================== RANDOM-ACCESS FILE ======

class SEARCH_DECL AT_Read_Rand_File : public AT_File                                   
{
public :
  AT_Read_Rand_File
    (AT_String fname,
     AT_File_Type type,
     uint blockSize = 1);

  virtual ~AT_Read_Rand_File
    ();

  // read to buffer
  virtual bool read
    (void *buf,
     uint len);

  // read to buffer from offset
  bool read
    (void   *buf,
     uint64 off,
     uint   len);

  virtual bool seek
    (uint64 pos);

  virtual uint64 align
    ()
  { assert(0); return 0; };
};

class SEARCH_DECL AT_Write_Rand_File : public AT_File
{
protected:
  AT_Write_Rand_File
    (AT_File_Type type,
     uint blockSize = 1);
     
public :
  AT_Write_Rand_File
    (AT_String fname,
     AT_File_Type type,
     uint blockSize = 1,
     bool overwriteExisting = true);

  virtual ~AT_Write_Rand_File
    ();

  virtual bool setHeader
    (uint16 vers,
     uint16 type);  
  virtual bool setVersion
    (uint16 vers);

  virtual bool seek
    (uint64 pos);

  // write from buffer
  virtual bool write
    (const void *const buf,
     uint len);

  // write from buffer to offset
  bool write
    (const void *const buf,
     uint64 off,
     uint len);

  // truncate file
  bool truncate
    ();
  //truncate file to offset
  bool truncate
    (uint64 off);
  virtual uint64 align
    ()
  { assert(0); return 0; };
};

class SEARCH_DECL AT_Read_Seq_File : public AT_File
{
public :
  AT_Read_Seq_File
    (uint maxRead = 0,
     uint bufSize = 65536);

  AT_Read_Seq_File
	 (AT_String fname,
     AT_File_Type type,
	  uint maxRead = 0,
      uint bufSize = 65536);

  virtual bool operator!
    ()
    const;
  /*
  virtual bool reopen
    ();
  */
  bool open
    (AT_String fname,
     AT_File_Type type,
	   uint maxRead = 0,
     uint bufSize = 65536);

  virtual ~AT_Read_Seq_File
	 ();

  // fast read: returns ptr into buffer, 0 on error
  // requires maxRead != 0 on construction
  void *read
	 (uint size = 0);          // if 0, size = maxRead

  virtual bool read   		   // fill in buffer
	 (void *p,
	  uint size);
};

class SEARCH_DECL AT_Write_Seq_File : public AT_File
{
public :
  AT_Write_Seq_File
    (uint blockSize = 1,
     uint bufSize = 65536);

  AT_Write_Seq_File
	 (AT_String fname,
     AT_File_Type type,
     uint blockSize = 1,
     uint bufSize = 65536);

  virtual bool operator!
    ()
    const;

  virtual bool open
    (AT_String fname,
     AT_File_Type type,
     uint bufSize = 65536);

  virtual bool close
    ();
  virtual ~AT_Write_Seq_File
	 ();

  virtual uint64 getSize
    ()
    const;

  virtual bool setHeader
    (uint16 vers,
     uint16 type);
  virtual bool setVersion
    (uint16 vers);

  virtual uint64 align
    ()
  { assert(0); return 0; };

  virtual bool write
	 (const void *const p,
	  uint size);

  // copy file
  bool write
    (AT_Read_Seq_File *f);
};

#endif
