// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1994
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        file.h
// 
// Purpose:     
// 
// Created:     4 May 95   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// 
// </file> 
#ifndef hg_utils_file_h
#define hg_utils_file_h

#include "smartptr.h"
#include "list.h"
#include "verbose.h"



// <class> 
//  
// Name:             FileCloseCallback
// 
// Purpose:          
// 
// some people may want to be notified when a file number becomes available.
// to achieve that, they must attach a callback of this kind to the statically 
// managed callback list of class File.
// 
// Public Interface: 
// 
// - virtual bool doIt() 
// 
//   returns true if the backcalled object did use the file number,
//   false otherwise (issuing the next callback in the list to be executed instead)
// 
// Description:      
// 
// </class> 
class FileCloseCallback : public DLListNode {
public:
   virtual bool fileClosed() = 0 ;
} ;

DLListdeclare (FileCloseCallbackList, FileCloseCallback) ;



// <class> 
//  
// Name:             HgFile
// 
// Purpose:          
// 
// base class for all classes that encapsulate a file number.
// abstract since it only has a fuzzy meaning of the medium it goes to.
// 
// Public Interface: 
// 
// Description:      
// 
// </class> 
class HgFile : virtual public RefCounted {
public:
   virtual ~HgFile() ;
   virtual bool close() ;
   
   void attach (int fd) ;

   int fd() const { return fd_; }

   int write (const char* buf, int nbytes) ;
   int read (char* buf, int nbytes) ;

   bool ok() const { return fd_>=0; }
   bool operator !() const { return !ok(); }
   operator void*() const { return (void*)ok(); }
   bool closed() const { return fd_<0; }

   // cannot simply call it "errno" because it is a define on some
   // architectures such as Windows NT.
   int errNo() const { return errno_; }
   
   // a registered callback will be deleted once it is called
   static void registerCallback (FileCloseCallback*) ;
   
   static int instances() { return instances_; }

   static Verbose sys_verbose ;

protected:
   HgFile() ;
   HgFile (int fd) ;

   void set_fd_(int fd) { fd_ = fd; }
   bool get_close_() const { return true; }
   void set_errno_(int e) { errno_ = e; }

   static void perror_(const char*) ;

private:
   int fd_ ;
   int errno_ ;

   static FileCloseCallbackList callbacks_ ;
   static int instances_ ;

private:
   HgFile (const HgFile&) {}
   HgFile& operator=(const HgFile&) { return *this; }

public:
   static const char* version3 ;
} ;
static const char* hg_utils_file_version = HgFile::version3 ;

SmartPtrdeclare (HgFilePtr, HgFile) 



#endif
