229 lines
5.3 KiB
C++
229 lines
5.3 KiB
C++
/*************************************************************************\
|
|
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2002 The Regents of the University of California, as
|
|
* Operator of Los Alamos National Laboratory.
|
|
* EPICS BASE Versions 3.13.7
|
|
* and higher are distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
|
|
// Author: Jim Kowalkowski
|
|
// Date: 6/20/96
|
|
//
|
|
// $Id$
|
|
//
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "epicsTime.h" // define struct timespec if nec
|
|
|
|
#define epicsExportSharedSymbols
|
|
#include "aitTypes.h"
|
|
#include "aitHelpers.h"
|
|
|
|
//
|
|
// 1/1/90 20 yr (5 leap) of seconds
|
|
//
|
|
const unsigned aitTimeStamp::epicsEpochSecPast1970 = 7305 * 86400;
|
|
|
|
void aitString::mallocFailure(void)
|
|
{
|
|
str=(char *)"";
|
|
len=0u;
|
|
bufLen=1u;
|
|
type=aitStrRefConstImortal;
|
|
fprintf(stderr,"aitString: no pool => continuing with zero char str\n");
|
|
}
|
|
|
|
void aitString::dump(const char* p) const
|
|
{
|
|
fprintf(stderr,"<%s>:",p);
|
|
dump();
|
|
}
|
|
|
|
void aitString::dump(void) const
|
|
{
|
|
fprintf(stderr,"this=%p ", this);
|
|
if(str) fprintf(stderr,"string=%p<%s>, ",str,str);
|
|
else fprintf(stderr,"no string present, ");
|
|
fprintf(stderr,"length=%u, ",len);
|
|
fprintf(stderr,"buf length=%u, ",bufLen);
|
|
if(type==aitStrRefConstImortal) fprintf(stderr,"type=Imortal Constant Reference\n");
|
|
else if(type==aitStrRefConst) fprintf(stderr,"type=Constant Reference\n");
|
|
else if(type==aitStrRef) fprintf(stderr,"type=Reference\n");
|
|
else if(type==aitStrCopy) fprintf(stderr,"type=Allocated\n");
|
|
else fprintf(stderr,"type=Invalid\n");
|
|
}
|
|
|
|
aitIndex aitString::compact(aitString* array, aitIndex arraySize,
|
|
void* buf, aitIndex bufSize)
|
|
{
|
|
aitIndex i;
|
|
aitUint32 pos;
|
|
char* ptr=(char*)buf;
|
|
aitString* str=(aitString*)buf;
|
|
|
|
// copy the array first
|
|
pos=sizeof(aitString)*arraySize;
|
|
if(bufSize<pos) return 0;
|
|
|
|
for(i=0;i<arraySize;i++) str[i].init();
|
|
|
|
for(i=0;i<arraySize;i++)
|
|
{
|
|
if((pos+str[i].length())>bufSize) break; // quick exit from loop
|
|
if(array[i].string())
|
|
{
|
|
memcpy(&ptr[pos],array[i].string(),array[i].length()+1u);
|
|
str[i].installBuf(&ptr[pos], array[i].length(), array[i].length()+1u);
|
|
pos+=str[i].length()+1;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
aitUint32 aitString::totalLength(aitString* array, aitIndex arraySize)
|
|
{
|
|
aitIndex i;
|
|
aitUint32 tot;
|
|
|
|
tot=sizeof(aitString)*arraySize;
|
|
for(i=0;i<arraySize;i++)
|
|
tot+=array[i].length()+1; // include the NULL
|
|
|
|
return tot;
|
|
}
|
|
|
|
aitUint32 aitString::stringsLength(aitString* array, aitIndex arraySize)
|
|
{
|
|
aitIndex i;
|
|
aitUint32 tot;
|
|
|
|
for(tot=0,i=0;i<arraySize;i++)
|
|
tot+=array[i].length()+1; // include the NULL
|
|
|
|
return tot;
|
|
}
|
|
|
|
int aitString::copy(const char* p, unsigned newStrLength, unsigned bufSizeIn)
|
|
{
|
|
if (newStrLength>=bufSizeIn) {
|
|
return -1;
|
|
}
|
|
|
|
if (this->type==aitStrRefConst || this->type==aitStrRefConstImortal
|
|
|| bufSizeIn>this->bufLen) {
|
|
|
|
char *pStrNew;
|
|
pStrNew = new char [bufSizeIn];
|
|
if (!pStrNew) {
|
|
mallocFailure();
|
|
return -1;
|
|
}
|
|
if (this->type==aitStrCopy) {
|
|
delete [] this->str;
|
|
}
|
|
this->str = pStrNew;
|
|
this->bufLen = bufSizeIn;
|
|
this->type = aitStrCopy;
|
|
}
|
|
// test above verifies that bufLen exceeds
|
|
// length of p
|
|
strncpy (this->str,p,this->bufLen);
|
|
this->len = newStrLength;
|
|
return 0;
|
|
}
|
|
|
|
int aitString::init(const char* p, aitStrType typeIn, unsigned strLengthIn, unsigned bufSizeIn)
|
|
{
|
|
int rc;
|
|
|
|
this->init();
|
|
switch (typeIn) {
|
|
case aitStrCopy:
|
|
rc = this->copy(p, strLengthIn, bufSizeIn);
|
|
break;
|
|
case aitStrRef:
|
|
rc = this->installBuf(p, strLengthIn, bufSizeIn);
|
|
break;
|
|
case aitStrRefConst:
|
|
rc = this->installConstBuf(p, strLengthIn, bufSizeIn);
|
|
break;
|
|
case aitStrRefConstImortal:
|
|
rc = this->installConstImortalBuf(p, strLengthIn, bufSizeIn);
|
|
break;
|
|
default:
|
|
rc=-1;
|
|
break;
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
aitTimeStamp::operator struct epicsTimeStamp () const
|
|
{
|
|
epicsTimeStamp ts;
|
|
|
|
if (this->tv_sec>aitTimeStamp::epicsEpochSecPast1970) {
|
|
ts.secPastEpoch = this->tv_sec - aitTimeStamp::epicsEpochSecPast1970;
|
|
ts.nsec = this->tv_nsec;
|
|
}
|
|
else {
|
|
ts.secPastEpoch = 0;
|
|
ts.nsec = 0;
|
|
}
|
|
return ts;
|
|
}
|
|
|
|
void aitTimeStamp::get (struct epicsTimeStamp &ts) const
|
|
{
|
|
if (this->tv_sec>aitTimeStamp::epicsEpochSecPast1970) {
|
|
ts.secPastEpoch = this->tv_sec - aitTimeStamp::epicsEpochSecPast1970;
|
|
ts.nsec = this->tv_nsec;
|
|
}
|
|
else {
|
|
ts.secPastEpoch = 0;
|
|
ts.nsec = 0;
|
|
}
|
|
}
|
|
|
|
aitTimeStamp::aitTimeStamp (const struct epicsTimeStamp &ts)
|
|
{
|
|
this->tv_sec = ts.secPastEpoch + aitTimeStamp::epicsEpochSecPast1970;
|
|
this->tv_nsec = ts.nsec;
|
|
}
|
|
|
|
aitTimeStamp aitTimeStamp::operator = (const struct epicsTimeStamp &rhs)
|
|
{
|
|
this->tv_sec = rhs.secPastEpoch + aitTimeStamp::epicsEpochSecPast1970;
|
|
this->tv_nsec = rhs.nsec;
|
|
return *this;
|
|
}
|
|
|
|
aitTimeStamp::operator struct timespec () const
|
|
{
|
|
struct timespec ts;
|
|
ts.tv_sec = (unsigned long) this->tv_sec;
|
|
ts.tv_nsec = (unsigned long) this->tv_nsec;
|
|
return ts;
|
|
}
|
|
|
|
void aitTimeStamp::get (struct timespec &ts) const
|
|
{
|
|
ts.tv_sec = (unsigned long) this->tv_sec;
|
|
ts.tv_nsec = (unsigned long) this->tv_nsec;
|
|
}
|
|
|
|
aitTimeStamp::aitTimeStamp (const struct timespec &ts)
|
|
{
|
|
this->tv_sec = (aitUint32) ts.tv_sec;
|
|
this->tv_nsec = (aitUint32) ts.tv_nsec;
|
|
}
|
|
|
|
aitTimeStamp aitTimeStamp::operator = (const struct timespec &rhs)
|
|
{
|
|
this->tv_sec = (aitUint32) rhs.tv_sec;
|
|
this->tv_nsec = (aitUint32) rhs.tv_nsec;
|
|
return *this;
|
|
}
|