//=-- FileStreamPlugin.h - This class encapulates a general FileStream  ------=
//
//  This class provides an abstraction over the file concept.  An 
//  object of this type may perform [de]compression/[de]cryption 
//  functionality transparent to the user of the FileStream class.  
//  Call the FileStreamPlugin::OpenFileStream function, or the 
//  FileStreamPlugin::CreatePlugin method, if you know the precise 
//  plugin type that is needed.
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner
//=---------------------------------------------------------------------------=

#ifndef FILESTREAMPLUGIN_H
#define FILESTREAMPLUGIN_H

#include "Plugin.h"
class Serialize;
template <class T> class LinkedList;

struct FileStreamInfo {
  const char *Filename;
  int OpenCode;

  FileStreamInfo(const char *FN, int OC) {
    Filename = FN; OpenCode = OC;
  }
};

class MSAPI FileStreamPlugin : public Plugin {
public :
  FileStreamPlugin(const String &name) : Plugin(name) {}

  // seek - Seek the file to the specified position, return 0 if successful,
  // true if seek failed.
  //
  virtual int seek(long Position, int From = SeekSet) = 0;

  virtual FileStreamPlugin *getline(char *Buffer, int BufferLength, 
                                    char Delimiter = '\n') = 0;
  virtual long tell() = 0;
  virtual int eof() = 0;

  enum OpenCodes {
    OPEN_READ, OPEN_WRITE, OPEN_CREATE
  };

  enum SeekCodes { // Set to correspond to SEEK_SET and friends...
    SeekSet = 0, SeekCur = 1, SeekEnd = 2
  };

  inline static PluginType GetPluginType() { 
    return Plugin::FILE_STREAM_PLUGIN; 
  }

  // Provide a convenient way to create AccessLogPlugin objects...
  inline static FileStreamPlugin *CreatePlugin(const String &Name) {
    return (FileStreamPlugin *)Plugin::CreatePlugin(GetPluginType(), Name);
  }

  // User Calls this...
  static FileStreamPlugin *OpenFileStream(const char *Filename, int OpenCode) {
    FileStreamInfo I(Filename, OpenCode);
    return (FileStreamPlugin *)Plugin::CreatePlugin(GetPluginType(), &I);
  }
};



// Template FileStreamPluginImpl class:
//
// Implementation tool for implementing FileStreamPlugin classes.  This defines
// functions that are call the FileStream's constructor...
//
template <class SubClass>
class FileStreamPluginImpl : public PluginTemplate<FileStreamPlugin,SubClass> {
public :

  // CreateInstanceData - Specify how to create a plugin when instance data
  // is present.
  static Plugin *CreateInstanceData(void *Data) {
    FileStreamInfo *FSI = (FileStreamInfo *)Data;
    int CreateError = 0;

    SubClass *P = new SubClass(FSI->Filename, FSI->OpenCode, CreateError);
    if (CreateError) {
      delete P;
      return 0;
    }

    return P;
  }

  // By default, FileStreamPlugins specify their priority.  The default value,
  // which should probably be overriden, is 1000, the lowest priority.
  inline static int GetPriority() { return 1000; }
};

#endif
