Source

winrttb / rttbcap.cpp

Full commit
/*
Daybo Logic Run-Time TarBall Library And Tools
Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
      
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
      
    * Neither the name of the Daybo Logic nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /*HAVE_CONFIG_H*/

#include <assert.h>
#include <stdio.h>

#ifdef HAVE_STRING_H
# include <string.h>
#endif /*HAVE_STRING_H*/

#ifdef RTTB_HDRSTOP
# pragma hdrstop
#endif /*RTTB_HDRSTOP*/

#include "rttb.h" /* Public header for librttb */

#ifndef __cplusplus
# error ("C++ is required to use the RTTB wrapper!")
#endif /*!__cplusplus*/

#define UNSPECIFIED_FILENAME "unspecified_file"
static unsigned int CopyString(const char* Src, char* Dest, size_t MaxSize);


// TRttbContainer
//---------------------------------------------------------------------------
void TRttbContainer::_NoContainer()
{
  if ( _containerName ) {
    delete[] _containerName;
    _containerName = NULL;
  }
}
//---------------------------------------------------------------------------
void TRttbContainer::_NoDefMode()
{
  if ( _defMode ) {
    delete[] _defMode;
    _defMode = NULL;
  }
}
//---------------------------------------------------------------------------
void TRttbContainer::_SetContainerName(const char* ContainerName)
{
  _NoContainer();
  if ( ContainerName ) {
    if ( ContainerName[0] ) {
      _containerName = new char[strlen(ContainerName)+1];
      strcpy(_containerName, ContainerName);
    }
  }
  return;
}
//---------------------------------------------------------------------------
TRttbContainer::TRttbContainer(const char* ContainerName)
 : _containerName(NULL), _defMode(NULL), _assFileCount(0U), DefLooseFirst(RTTB_TRUE)
{
  if ( ContainerName && ContainerName[0] )
    _SetContainerName(ContainerName);
  else
    _SetContainerName(UNSPECIFIED_FILENAME);
  return;
}
//---------------------------------------------------------------------------
TRttbContainer::~TRttbContainer()
{
  _NoContainer();
  _NoDefMode();
  assert ( _assFileCount == 0U ); // All assosiated files should have been destroyed first!
}
//---------------------------------------------------------------------------
unsigned int TRttbContainer::GetContainerName(char* PBuff, size_t MaxSize)
{
  return CopyString(_containerName, PBuff, MaxSize);
}
//---------------------------------------------------------------------------
void TRttbContainer::AssNotify(int Direction)
{
  if ( Direction )
    _assFileCount++;
  else
    _assFileCount--;
}
//---------------------------------------------------------------------------
void TRttbContainer::SetDefMode(const char* NewDefMode)
{
  if ( NewDefMode ) {
    if ( NewDefMode[0] ) {
      if ( strcpy(_defMode, NewDefMode) ) { // Differs?
        _NoDefMode();
        _defMode = new char[strlen(NewDefMode)+1];
        strcpy(_defMode, NewDefMode);
      }
    }
  }
  return;
}
//---------------------------------------------------------------------------
unsigned int TRttbContainer::GetDefMode(char* PBuff, size_t MaxSize)
{
  return CopyString(_defMode, PBuff, MaxSize);
}
//---------------------------------------------------------------------------
static unsigned int CopyString(const char* Src, char* Dest, size_t MaxSize)
{
  unsigned int len;

  if ( !Src )
    return 0U;

  len = (unsigned int)strlen(Src);
  if ( Dest && MaxSize )
    strncpy(Dest, Src, MaxSize);

  return len;
}
//---------------------------------------------------------------------------


// TRttbFile
//---------------------------------------------------------------------------
void TRttbFile::_SetFileName(const char* NewFileName)
{
  if ( _fileName ) {
    delete[] _fileName;
    _fileName = NULL;
  }
  if ( NewFileName ) {
    _fileName = new char[strlen(NewFileName)+1];
    strcpy(_fileName, NewFileName);
  }
  return;
}
//---------------------------------------------------------------------------
void TRttbFile::_InitData()
{
  _handle = RTTB_NULLHANDLE;
  _fileName = NULL;
  lastError = RTTB_ERROR_NOERROR;
  return;
}
//---------------------------------------------------------------------------
TRttbContainer* TRttbFile::GetContainer()
{
  return _container;
}
//---------------------------------------------------------------------------
TRttbFile::TRttbFile(TRttbContainer& AssContainer, const char* FileName)
{
  TRttbFile(&AssContainer, FileName); // Use other constructor
}
//---------------------------------------------------------------------------
TRttbFile::TRttbFile(TRttbContainer* PAssContainer, const char* FileName)
{
  _InitData();

  if ( FileName )
    _SetFileName(FileName);
  else
    _SetFileName(UNSPECIFIED_FILENAME);

  PAssContainer->AssNotify(1); // Tell container it has another open file
  _container = PAssContainer;
}
//---------------------------------------------------------------------------
TRttbFile::~TRttbFile()
{
  if ( IsOpen() )
    Close();
  _SetFileName(NULL);
  _handle = RTTB_NULLHANDLE; // Not strictly neccersary
  _container->AssNotify(0); // Tell container a file object was destroyed
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Seek(long Offset, int Whence)
{
  lastError = rttb_fseek(_handle, Offset, Whence);
  if ( lastError == RTTB_ERROR_NOERROR )
    return RTTB_TRUE;
  return RTTB_FALSE; // Error
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Read(void* Ptr, size_t Size, size_t N)
{
  if ( rttb_fread(Ptr, Size, N, _handle, &lastError) == N )
    return RTTB_TRUE;
  return RTTB_FALSE; // Error
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Eof()
{
  lastError = RTTB_ERROR_NOERROR;
  return (RTTB_BOOL)rttb_feof(_handle);
}
//---------------------------------------------------------------------------
int TRttbFile::GetC()
{
  return rttb_fgetc(_handle, &lastError);
}
//---------------------------------------------------------------------------
char* TRttbFile::GetS(char* S, int size)
{
  lastError = RTTB_ERROR_UNEXPECTED; // LOL!
  printf("NOTICE!  TRttbFile::GetS() - unsupported in librttb-0.0.2!!\n"
         "The method is ignored, Mail Overlord@DayboLogic.co.uk\n");

  return NULL;
}
//---------------------------------------------------------------------------
RTTB_ERROR TRttbFile::GetLastError()
{
  RTTB_ERROR err = lastError;
  lastError = RTTB_ERROR_NOERROR; // This function successful
  return err;
}
//---------------------------------------------------------------------------
unsigned int TRttbFile::GetFileName(char* PBuff, size_t MaxLen)
{
  lastError = RTTB_ERROR_NOERROR;
  return CopyString(_fileName, PBuff, MaxLen);
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::IsOpen()
{
  lastError = RTTB_ERROR_NOERROR;

  if ( _handle )
    return RTTB_TRUE;
  return RTTB_FALSE;
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Close()
{
  if ( _handle ) {
    lastError = rttb_fclose(_handle);
    if ( lastError == RTTB_ERROR_NOERROR )
      return RTTB_TRUE;
    return RTTB_TRUE;
  }
  lastError = RTTB_ERROR_INVHANDLE;
  return RTTB_FALSE;
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Open(short LooseFirst, const char* Mode)
{
  RTTB_BOOL realLooseFirst;
  char* realMode = NULL;
  char* dynamicMode = NULL; // To be deleted
  char* containerName;
  unsigned int containerNameLength;

  if ( _handle ) { /* Whoops, must not have a file handle already */
    lastError = RTTB_ERROR_UNEXPECTED;
    return RTTB_FALSE;
  }

  switch ( LooseFirst ) {
    case 0 : {
      realLooseFirst = RTTB_FALSE;
      break;
    }
    case 1 : {
      realLooseFirst = RTTB_TRUE;
      break;
    }
    default : { // Generally -1
      realLooseFirst = _container->DefLooseFirst;
    }
  }
  if ( Mode ) { // Sent by caller
    if ( Mode[0] )
      realMode = (char*)Mode;
  }
  else { // Not sent by caller
    unsigned int length = _container->GetDefMode(NULL, 0U);
    realMode = new char[++length];
    _container->GetDefMode(realMode, length);
    dynamicMode = realMode; // Mark the buffer for deletion
  }

  // Get the container's name
  containerNameLength = _container->GetContainerName(NULL, 0U);
  containerName = new char[++containerNameLength];
  _container->GetContainerName(containerName, containerNameLength);

  // Call the library
  _handle = rttb_fopen(containerName, _fileName, realMode, realLooseFirst, &lastError);

  // Some cleanups
  delete[] containerName;
  if ( dynamicMode )
    delete[] dynamicMode;

  if ( lastError != RTTB_ERROR_NOERROR ) return RTTB_FALSE;
  return RTTB_TRUE;
}
//---------------------------------------------------------------------------
RTTB_BOOL TRttbFile::Open()
{
  return Open(-1, NULL); // This is just a shortcut
}
//---------------------------------------------------------------------------
long int TRttbFile::FileLength()
{
  long int ret;

  lastError = rttb_filelength(_handle, &ret);
  return ret;
}
//---------------------------------------------------------------------------