/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#include <OPENR/RCRegion.h>

#include "../headers/AperiosSharedMem.h"

SharedMemRegion::SharedMemRegion() :
  region(NULL)
{
}

SharedMemRegion::~SharedMemRegion() {
  release();
}

void
SharedMemRegion::init(int size) {
  // round the memory size to a number of pages for good measure
  sError error;
  size_t page_size;
  error = GetPageSize(&page_size);
  if (error != sSUCCESS) {
    cout << "error: " << error << " getting page size in SharedMem" << endl;
    page_size = 4096;
  }

  int new_size,num_pages;
  num_pages = (size+page_size-1)/page_size;
  new_size = num_pages*page_size;

  //cout << "req" << size << "new" << new_size << "ps" << page_size << endl;
  
  region = new RCRegion(new_size);
}

void
SharedMemRegion::init(MsgForm info) {
  region = cloneMsgForm(info);
  region->AddReference();
}

void
SharedMemRegion::release() {
  if(region)
    region->RemoveReference();
  region = NULL;
}

SharedMemRegion::MsgForm
SharedMemRegion::getMsgForm() {
  return region;
}

void *
SharedMemRegion::getBase() {
  if(region!=NULL) {
    return (void *)region->Base();
  } else {
    return NULL;
  }
}

void *
SharedMemRegion::getData() {
  return getBase();
}

bool
SharedMemRegion::validData() {
  return region!=NULL;
}

SharedMemRegion &
SharedMemRegion::operator=(const SharedMemRegion &x) {
  region = x.region;
  if(region!=NULL)
    region->AddReference();
  return *this;
}

SharedMemRegion::MsgForm
SharedMemRegion::cloneMsgForm(const MsgForm &y) {
  if(y!=NULL)
    y->AddReference();
  return y;
}

void
SMMSharedMemRegion::init(MsgForm info) {
  SharedMemRegion::init(info);
}

static const int ReserveSpace = 8;

void
SMMSharedMemRegion::init(int size) {
  SharedMemRegion::init(size+ReserveSpace);
}

void *
SMMSharedMemRegion::getData() {
  void *base;
  base = getBase();
  base = (void *)(((char *)base) + ReserveSpace);
  return base;
}

void
SMMSharedMemRegion::setId(int id) {
  void *base;
  base = getBase();
  *((int *)base) = id;
}

int
SMMSharedMemRegion::getId() {
  void *base;
  base = getBase();
  return *((int *)base);
}
