// 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_dc_common_file_h
#define hg_dc_common_file_h

#include "smartptr.h"

#include <hyperg/utils/list.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 boolean 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 boolean doIt() = 0 ;
} ;

DLListdeclare (FileCloseCallbackList, FileCloseCallback)



// <class> 
//  
// Name:             File
// 
// 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 File : virtual public RefCounted {
public:
   virtual ~File() ;
   virtual boolean close() ;
   
   void attach (int fd, boolean close) ;

   int fd() const { return fd_; }

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

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

   int errno() const { return errno_; }
   
   // a registered callback will be deleted once it is called
   static void registerCallback (FileCloseCallback*) ;
   
   static int instances() { return instances_; }

protected:
   File() ;
   File (int fd, boolean close) ;

   void set_fd_(int fd) { fd_ = fd; }
   boolean get_close_() const { return close_; }
   void set_close_(boolean b) { close_ = b; }
   void set_errno_(int e) { errno_ = e; }

private:
   int fd_ ;
   boolean close_ ;
   int errno_ ;

   static FileCloseCallbackList callbacks_ ;
   static int instances_ ;

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

SmartPtrdeclare (FilePtr, File) 



#endif
