/*******************************************************************************
 *	BRefData.cc		Referenced data storage
 *				T.Barnaby,	Beam Ltd,	6/10/94
 *******************************************************************************
 */
extern "C" {
#include <stdlib.h>
#include <string.h>
}
#include	<BRefData.h>

#define	DEBUG	0

#define CHUNK	16

BRefData::BRefData(){
#if DEBUG
printf("BRefData::BRefData: (%x)\n", this);
#endif
	oData = 0;
	oLen = 0;
	oSize = 0;
	oRefCount = 1;
}

BRefData::BRefData(int len){
#if DEBUG
printf("BRefData::BRefData(int): (%x)\n", this);
#endif
	oData = 0;
	oLen = 0;
	oSize = 0;
	oRefCount = 1;
	setLen(len);
}

BRefData::BRefData(const BRefData& refData){
#if DEBUG
printf("BRefData::BRefData(BRefData&): (%x)\n", this);
#endif
	oLen = refData.oLen;
	oSize = refData.oSize;
	oData = malloc(oSize);
	memcpy(oData, refData.oData, oLen);
	oRefCount = 1;
}

BRefData& BRefData::operator=(BRefData& refData){
#if DEBUG
printf("BRefData::operator=: (%x)\n", this);
#endif
	free(oData);
	oLen = refData.oLen;
	oSize = refData.oSize;
	oData = malloc(oSize);
	memcpy(oData, refData.oData, oLen);
	oRefCount = 1;
	return *this;
}

BRefData::~BRefData(){
#if DEBUG
printf("BRefData::~BRefData: %x\n", this);
#endif
	free(oData);
	oRefCount = 0;
}

BRefData* BRefData::copy(){
	BRefData*	r = this;

#if DEBUG
printf("BRefData::Copy %x\n", this);
#endif
	if(oRefCount != 1){
		r = new BRefData(*this);
		deleteRef();
	}
	return r;
}

BRefData* BRefData::addRef(){
#if DEBUG
printf("BRefData::AddRef: (%x) %d\n", this, oRefCount);
#endif
	oRefCount++;
	return this;
}

int BRefData::deleteRef(){
#if DEBUG
printf("BRefData::DeleteRef: (%x) %d\n", this, oRefCount);
#endif
	oRefCount--;
	if(oRefCount == 0){
		free(oData);
		oLen = 0;
		oSize = 0;
		oData = 0;
	}
	return oRefCount;
}

#ifdef ZAP
void* BRefData::data(){
	return oData;
}
int BRefData::len(){
	return oLen;
}
#endif

void BRefData::setLen(int len){
#if DEBUG
printf("BRefData::SetLen (%x) %d\n", this, len);
#endif
	if(len > oSize){
		oSize = len + CHUNK - 1;
		oSize = (oSize / CHUNK) * CHUNK;
		if(oData)
			oData = realloc(oData, oSize);
		else
			oData = malloc(oSize);
	}
	oLen = len;
}
