#ifndef __APPLE__
#ifndef NO_SCCS_ID
static char SccsId[ ] = "@(#) sm_buffer.cpp 1.17 5/7/98 16:36:20";
#endif
#endif
#include <stdio.h>
#if !defined(macintosh) && !defined(__APPLE__)
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <string.h>
#ifdef SUNOS
#include <unistd.h> // for SEEK_CUR and SEEK_END
#endif
#include "sm_vdasnacc.h"
#ifndef NDEBUG
#include <iomanip>
#endif
#if defined(macintosh) || defined(__APPLE__)
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
#define SME_SETUP(A) try {
#define SME_THROW(A, B, C) throw(static_cast<SM_RET_VAL>(A))
#define SME_FINISH }
#define SME_CATCH_SETUP catch(SM_RET_VAL) {
#define SME_CATCH_FINISH }
#define SM_RET_VAL long
#define SM_NO_ERROR 0
#define SME_FINISH_CATCH } catch(SM_RET_VAL) {}
#define SME(S) S
#define SM_MEMORY_ERROR memFullErr
#define SM_MISSING_PARAM paramErr
#define SM_FILEIO_ERROR ioErr
#else
#define SME_SETUP(A) do {} while (0)
#define SME_THROW(A, B, C) do {} while (0)
#define SME_FINISH
#define SME_CATCH_SETUP
#define SME_CATCH_FINISH
#define SM_RET_VAL long
#define SM_NO_ERROR 0
#define SME_FINISH_CATCH
#define SME(S) S
#endif
void CSM_Buffer::Clear()
{
m_lSize = 0;
m_pMemory = NULL;
#if !defined(macintosh) && !defined(__APPLE__)
m_pszFN = NULL;
m_pFP = NULL;
#endif
m_pMemFP = NULL;
m_pCache = NULL;
m_lCacheSize = 0;
}
CSM_Buffer::CSM_Buffer()
{
SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
Clear();
if ((m_pMemory = (char *)calloc(1, 1)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SME(SetLength(0));
SME_FINISH_CATCH
}
CSM_Buffer::CSM_Buffer(size_t lSize)
{
SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
Clear();
if ((m_pMemory = (char *)calloc(1, lSize + 1)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SME(SetLength(lSize));
SME_FINISH_CATCH
}
#if !defined(macintosh) && !defined(__APPLE__)
CSM_Buffer::CSM_Buffer(char *pszFileName)
{
SME_SETUP("CSM_Buffer::CSM_Buffer(char*)");
Clear();
if (pszFileName == NULL)
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
if ((m_pszFN = strdup(pszFileName)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SME_FINISH_CATCH
}
#endif
CSM_Buffer::CSM_Buffer(const char *pBuf, SM_SIZE_T lSize)
{
SME_SETUP("CSM_Buffer::CSM_Buffer(char *, size_t)");
Clear();
if (pBuf == NULL)
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
SME(Set(pBuf, lSize));
SME_FINISH_CATCH
}
CSM_Buffer::CSM_Buffer(const CSM_Buffer &b)
{
SME_SETUP("CSM_Buffer::CSM_Buffer(CSM_Buffer&)");
Clear();
SME(ReSet(b));
SME_FINISH_CATCH
}
CSM_Buffer::~CSM_Buffer()
{
if (m_pMemory)
free (m_pMemory);
#if !defined(macintosh) && !defined(__APPLE__)
if (m_pszFN)
free (m_pszFN);
if (m_pFP)
fclose(m_pFP);
#endif
if (m_pCache)
free (m_pCache);
}
SM_SIZE_T CSM_Buffer::Length() const
{
SM_SIZE_T lRet = 0;
SME_SETUP("CSM_Buffer::Length");
#if !defined(macintosh) && !defined(__APPLE__)
if (InFile())
{
struct stat statBuf;
if (stat(m_pszFN, &statBuf) == -1)
{
char szMsg[512];
sprintf(szMsg, "Couldn't stat file %s", m_pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
lRet = statBuf.st_size;
}
else
#endif
{
lRet = m_lSize;
}
SME_FINISH_CATCH
return lRet;
}
void CSM_Buffer::Set(const char *psz)
{
SME_SETUP("CSM_Buffer::Set(char *)");
if (psz == NULL)
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
if (m_pMemory)
free(m_pMemory);
#if !defined(macintosh) && !defined(__APPLE__)
int len = strlen(psz);
m_pMemory = (char*)malloc(len + 1);
if (m_pMemory == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
strcpy(m_pMemory, psz);
SME(SetLength(len));
#else
if ((m_pMemory = strdup(psz)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SME(SetLength(strlen(psz)));
#endif
SME_FINISH_CATCH
}
void CSM_Buffer::Set(const char *p, SM_SIZE_T lSize)
{
SME_SETUP("CSM_Buffer::Set(char *, size_t)");
if (m_pMemory)
free(m_pMemory);
if (p == NULL)
{
m_pMemory = NULL;
SME(SetLength(0));
}
else
{
m_pMemory = (char *)calloc(1, lSize + 1);
if (m_pMemory == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
memcpy(m_pMemory, p, lSize);
SME(SetLength(lSize));
}
SME_FINISH_CATCH
}
char* CSM_Buffer::Alloc(SM_SIZE_T lSize)
{
SME_SETUP("CSM_Buffer::Alloc");
if (m_pCache)
free(m_pCache);
if ((m_pCache = (char *)calloc(1, lSize)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
m_lCacheSize = lSize;
SME_FINISH_CATCH
return m_pCache;
}
void CSM_Buffer::AllocMoreMem(SM_SIZE_T lSize)
{
char *pNew;
SM_SIZE_T lLength = Length();
SME_SETUP("CSM_Buffer::AllocMoreMem");
if ((pNew = (char *)calloc(1, lLength + lSize)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
memcpy(pNew, m_pMemory, lLength);
SetLength(lLength + lSize);
m_pMemFP = pNew + (m_pMemFP - m_pMemory);
free(m_pMemory);
m_pMemory = pNew;
SME_FINISH_CATCH
}
const char* CSM_Buffer::Access() const
{
SME_SETUP("CSM_Buffer::Access");
#if !defined(macintosh) && !defined(__APPLE__)
if (InFile())
{
if (m_pMemory != NULL)
free (m_pMemory);
SME(m_pMemory = Get());
}
#endif
SME_FINISH_CATCH
return m_pMemory;
}
char* CSM_Buffer::Get(SM_SIZE_T &l) const
{
char *pRet = NULL;
SME_SETUP("CSM_Buffer::Get");
SM_SIZE_T lSize = Length();
#if !defined(macintosh) && !defined(__APPLE__)
if (InFile()) {
if ((pRet = (char *)calloc(1, lSize + 1)) == NULL)
SME_THROW(SM_MEMORY_ERROR, "calloc failure", NULL);
if (m_pFP != NULL)
fclose(m_pFP);
if ((m_pFP = fopen(m_pszFN, SM_FOPEN_READ)) == NULL)
{
char szMsg[512];
sprintf(szMsg, "Couldn't open file %s", m_pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
long lRead = fread(pRet, 1, lSize, m_pFP);
if (ferror(m_pFP) != 0)
{
char szMsg[512];
sprintf(szMsg, "Couldn't read file %s", m_pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
fclose(m_pFP);
m_pFP = NULL;
l = lRead; }
else
#endif
{
if (m_pMemory)
{
pRet = (char *)calloc(1, lSize);
memcpy(pRet, m_pMemory, lSize);
l = lSize; }
}
SME_FINISH
SME_CATCH_SETUP
if (pRet != NULL)
{
free(pRet);
pRet = NULL;
}
#if !defined(macintosh) && !defined(__APPLE__)
if (m_pFP != NULL)
{
fclose(m_pFP);
m_pFP = NULL;
}
#endif
SME_CATCH_FINISH
return pRet;
}
long CSM_Buffer::Compare(const CSM_Buffer &b)
{
const char *p1 = NULL;
const char *p2 = NULL;
long lRet = -2;
SME_SETUP("CSM_Buffer::Compare");
if ((p1 = Access()) != NULL)
{
if ((p2 = b.Access()) != NULL)
{
if (Length() == b.Length())
lRet = (long)memcmp(p1, p2, Length());
}
#if !defined(macintosh) && !defined(__APPLE__)
else
if (InFile())
free (p1);
#endif
}
SME_FINISH_CATCH
return lRet;
}
SM_RET_VAL CSM_Buffer::ReSet(const CSM_Buffer &b)
{
char *p;
SM_SIZE_T l;
SME_SETUP("CSM_Buffer::ReSet");
#if !defined(macintosh) && !defined(__APPLE__)
m_pszFNP = NULL;
m_pFP = NULL;
#endif
if (m_pMemory)
free(m_pMemory);
m_pMemory = m_pMemFP = NULL;
SME(SetLength(0));
m_pCache = NULL;
m_lCacheSize = 0;
SME(p = b.Get(l));
SME(Set(p, l));
free(p);
SME_FINISH_CATCH
return SM_NO_ERROR;
}
#if !defined(macintosh) && !defined(__APPLE__)
SM_RET_VAL CSM_Buffer::ConvertFileToMemory()
{
SM_SIZE_T l;
SME_SETUP("CSM_Buffer::ConvertFileToMemory");
if (m_pszFN == NULL)
return SM_NO_ERROR;
SME(m_pMemory = Get(l));
free(m_pszFN);
m_pszFN = NULL;
SME(SetLength(l));
SME_FINISH_CATCH
return SM_NO_ERROR;
}
SM_RET_VAL CSM_Buffer::ConvertMemoryToFile(char *pszFN)
{
SM_SIZE_T lRet = 0;
SME_SETUP("CSM_Buffer::ConvertMemoryToFile");
if (pszFN == NULL)
SME_THROW(SM_NO_FILENAME, NULL, NULL);
if (InFile())
{
if (strcmp(m_pszFN, pszFN) == 0) return SM_NO_ERROR;
else
{
SM_SIZE_T lBytesRead;
SM_SIZE_T lSize=4096;
char *ptr;
FILE *fp=fopen(pszFN, "w");
this->Open(SM_FOPEN_READ);
while ((ptr=this->nRead(lSize, lBytesRead)) != NULL && lBytesRead > 0)
{
fwrite(ptr, 1, lBytesRead, fp);
}
this->Close();
fclose(fp);
return(SM_NO_ERROR);
}
}
if ((m_pFP = fopen(pszFN, SM_FOPEN_WRITE)) == NULL)
{
char szMsg[512];
sprintf(szMsg, "Couldn't stat file %s", pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
SM_SIZE_T lLength = Length();
if ((m_pszFN = strdup(pszFN)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
if ((lRet = fwrite(m_pMemory, 1, lLength, m_pFP)) != lLength)
{
char szMsg[512];
sprintf(szMsg, "Couldn't write file %s", m_pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
fclose(m_pFP);
m_pFP = NULL;
SME_FINISH
SME_CATCH_SETUP
if ((m_pszFN != NULL) && (pszFN != NULL))
{
free(m_pszFN);
m_pszFN = NULL;
}
SME_CATCH_FINISH
return SM_NO_ERROR;
}
#endif
SM_RET_VAL CSM_Buffer::Open(char *pszMode)
{
SME_SETUP("CSM_Buffer::Open");
if (pszMode == NULL)
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
#if !defined(macintosh) && !defined(__APPLE__)
if (!InFile())
#endif
m_pMemFP = m_pMemory; #if !defined(macintosh) && !defined(__APPLE__)
else
if ((m_pFP = fopen(m_pszFN, pszMode)) == NULL)
{
char szMsg[512];
sprintf(szMsg, "Couldn't open file %s", m_pszFN);
SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
}
#endif
SME_FINISH_CATCH
return SM_NO_ERROR;
}
SM_RET_VAL CSM_Buffer::Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin)
{
SM_RET_VAL lRet = SM_NO_ERROR;
SME_SETUP("CSM_Buffer::Seek");
#if !defined(macintosh) && !defined(__APPLE__)
if (!InFile())
#endif
{
char *pSave = m_pMemFP;
if (m_pMemFP == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SM_SIZE_T lLength = Length();
switch (lOrigin)
{
case SEEK_CUR:
m_pMemFP += lOffset;
break;
case SEEK_END:
m_pMemFP = (m_pMemory + lLength - 1) + lOffset;
break;
default: m_pMemFP = m_pMemory + lOffset;
break;
}
if ((m_pMemFP > (m_pMemory + lLength - 1)) ||
(m_pMemFP < m_pMemory))
{
m_pMemFP = pSave;
lRet = -1;
}
}
#if !defined(macintosh) && !defined(__APPLE__)
else
{
if (m_pFP == NULL)
SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
lRet = fseek(m_pFP, lOffset, lOrigin);
}
#endif
SME_FINISH_CATCH
return lRet;
}
void CSM_Buffer::Close()
{
#if !defined(macintosh) && !defined(__APPLE__)
if (m_pFP != NULL)
{
fclose(m_pFP);
m_pFP = NULL;
if (m_pMemory)
{
free(m_pMemory);
m_pMemory = NULL;
}
}
else
#endif
m_pMemFP = NULL;
}
AsnType *CSM_Buffer::Clone() const
{
return new CSM_Buffer;
}
AsnType *CSM_Buffer::Copy() const
{
return new CSM_Buffer (*this);
}
AsnLen CSM_Buffer::BEnc(BUF_TYPE BBuf)
{
char *ptr;
unsigned int jj=0;
SM_SIZE_T lRead=1;
SM_SIZE_T lOffset;
this->Open(SM_FOPEN_READ);
for (jj = 0; jj < this->Length() && lRead > 0; jj += lRead)
{
if (jj == 0) {
lOffset = this->Length() - (this->Length() % 4096);
}
else
lOffset -= 4096;
this->Seek(lOffset, 0);
ptr = this->nRead(4096, lRead);
BBuf.PutSegRvs(ptr, lRead);
}
this->Close();
return this->Length();
}
void CSM_Buffer::Print (ostream &os) const
{
#ifndef NDEBUG
int len = Length();
int i;
os << "{ -- ANY --" << endl;
indentG += stdIndentG;
Indent (os, indentG);
long oFlags = os.flags();
os << hex;
for (i = 0; i < len; i++)
{
os << setw(2) << setfill('0')
<< static_cast<unsigned int>(static_cast<unsigned char>(m_pMemory[i])) << " ";
if (i == len - 1 || i % 16 == 15)
{
int j;
os << " ";
for (j = i > 15 ? i - 15 : 0; j <= i; j++)
{
if (m_pMemory[j] >= 0x20 && m_pMemory[j] < 0x80)
os << m_pMemory[j];
else
os << '.';
}
os << endl;
}
}
os.flags(oFlags);
os << endl;
indentG -= stdIndentG;
Indent (os, indentG);
os << "}";
#endif NDEBUG
}
SM_RET_VAL CSM_Buffer::cRead(char *pBuffer, SM_SIZE_T lSize)
{
SM_RET_VAL lRet = 0;
SME_SETUP("CSM_Buffer::cRead");
if ((pBuffer == NULL) || (lSize <= 0))
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
#if !defined(macintosh) && !defined(__APPLE__)
if (!InFile())
#endif
{
if (m_pMemFP == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SM_SIZE_T lReadSize = lSize;
SM_SIZE_T lLength = Length();
if ((m_pMemFP + lReadSize) > (m_pMemory + lLength))
lReadSize = (m_pMemory + lLength) - m_pMemFP;
memcpy(pBuffer, m_pMemFP, lReadSize);
if (lReadSize > 0)
{
m_pMemFP += lReadSize;
lRet = lReadSize;
}
else
lRet = 0;
}
#if !defined(macintosh) && !defined(__APPLE__)
else
{
if (m_pFP == NULL)
SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
lRet = fread(pBuffer, 1, lSize, m_pFP);
}
#endif
SME_FINISH_CATCH
return lRet;
}
SM_RET_VAL CSM_Buffer::Write(const char *pBuffer, SM_SIZE_T lSize)
{
SM_RET_VAL lRet = 0;
SME_SETUP("CSM_Buffer::Write");
if ((pBuffer == NULL) || (lSize <= 0))
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
#if !defined(macintosh) && !defined(__APPLE__)
if (!InFile())
#endif
{
if (m_pMemFP == NULL)
{
if (m_pMemory == NULL)
{
if ((m_pMemFP = m_pMemory = (char *)calloc(1, lSize)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SetLength(lSize);
}
else
m_pMemFP = m_pMemory;
}
if ((SM_SIZE_T)(((m_pMemory + Length()) - m_pMemFP)) < lSize)
AllocMoreMem(lSize);
memcpy(m_pMemFP, pBuffer, lSize);
m_pMemFP += lSize;
lRet = lSize;
}
#if !defined(macintosh) && !defined(__APPLE__)
else
{
if (m_pFP == NULL)
SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
if ((lRet = fwrite(pBuffer, 1, lSize, m_pFP)) > 0)
SetLength(m_lSize + lRet);
}
#endif
SME_FINISH_CATCH
return lRet;
}
char* CSM_Buffer::nRead(SM_SIZE_T lSize, SM_SIZE_T &lBytesRead)
{
char *pRet = NULL;
SME_SETUP("CSM_Buffer::nRead");
if (lSize <= 0)
SME_THROW(SM_MISSING_PARAM, NULL, NULL);
#if !defined(macintosh) && !defined(__APPLE__)
if (!InFile())
#endif
{
if (m_pMemFP == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
SM_SIZE_T lReadSize = lSize;
SM_SIZE_T lLength = Length();
if ((m_pMemFP + lReadSize) > (m_pMemory + lLength))
lReadSize = (m_pMemory + lLength) - m_pMemFP;
pRet = m_pMemFP;
if (lReadSize > 0)
{
m_pMemFP += lReadSize;
lBytesRead = lReadSize;
}
else
lBytesRead = 0;
}
#if !defined(macintosh) && !defined(__APPLE__)
else
{
if (m_pFP == NULL)
SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
if (m_pMemory != NULL)
free (m_pMemory);
if ((m_pMemory = (char *)calloc(1, lSize + 1)) == NULL)
SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
lBytesRead = fread(m_pMemory, 1, lSize, m_pFP);
pRet = m_pMemory;
}
#endif
SME_FINISH_CATCH
return pRet;
}
void CSM_Buffer::Flush()
{
if (m_pCache != NULL)
{
Write(m_pCache, m_lCacheSize);
free(m_pCache);
m_pCache = NULL;
m_lCacheSize = 0;
}
}