//=========================================================================
// Summary  : */
// Filename : SharedData.h
// Author   : */
// Project  : */
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#ifndef _SHAREDDATA_H
#define _SHAREDDATA_H

#include <string.h>
#include "semaphore.h"
#include "ourTypes.h"
#include "Exception.h"

/*
CLASS 
SharedData

DESCRIPTION
SharedData is the base class for objects which provide an 
object-oriented interface to shared memory-based IPC.

AUTHOR
Tom O'Reilly
*/
class SharedData {

public:

  ///////////////////////////////////////////////////////////////////
  // AccessError is thrown when read or write is attempted without
  // appropriate Access permission.
  class AccessError : public Exception {
  public:
    AccessError(char *errorMsg) : Exception(errorMsg) {
    }
  };

  ///////////////////////////////////////////////////////////////////
  // Data access types
  enum Access {
    NoAccess, Read, Write, ReadWrite
  };

  ///////////////////////////////////////////////////////////////////
  // Constructor
  SharedData(const char *name, 
	     int nDataBytes,
	     Access access = NoAccess,
	     Boolean init = False);


  ///////////////////////////////////////////////////////////////////
  // Destructor
  virtual ~SharedData();


  ///////////////////////////////////////////////////////////////////
  // Return object name
  const char *name() {
    return _name;
  }

  ///////////////////////////////////////////////////////////////////
  // Print accessibility to shared data
  void printAccess();

  ///////////////////////////////////////////////////////////////////
  // Return size of data map in bytes
  int mapSize() {
    return _mapSize;
  }

protected:

  ///////////////////////////////////////////////////////////////////
  // Read from shared memory
  // [output] data: mapSize() bytes are copied here
  virtual void read(void *data) 
       throw (AccessError);

  ///////////////////////////////////////////////////////////////////
  // Write to shared memory
  // [input] data: mapSize() bytes are copied from here
  virtual void write(void *data) 
       throw (AccessError);

  ///////////////////////////////////////////////////////////////////
  // Get direct access to shared memory block.  VERY DANGEROUS.
  void* getAddress() { return _mapAddr; };
  friend class ModemFork;


  ///////////////////////////////////////////////////////////////////
  // Protection flags used by mmap() for specified SharedData::Access
  static int mmapProtectFlags(Access access);

private:

  ///////////////////////////////////////////////////////////////////
  // Release all resources
  void cleanup();

  ///////////////////////////////////////////////////////////////////
  // Initialize shared memory
  void initShm();

  ///////////////////////////////////////////////////////////////////
  // Map the shared data memory with specified name (used for semaphore
  // and data maps)
  void* map(const char *mapName, int mapSize, 
	   Access access, Boolean init);

  // Object name
  const char *_name;
  const char *_protectSemName;

  Boolean _init;

  // Access permission
  Access _access;

  // Pointer to "data protection" semaphore
  sem_t *_protectSem;

  // Size of data (bytes)
  int _mapSize;

  // Pointer to shared memory data segment
  void *_mapAddr;
};


#endif

