blob: f5f031bf85da4a37c811ba1e28b265504357c472 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: ComplexObject.cpp
* Description: This file defines a Message Pattern
* to facilitate the future extension and maintenance
* Created: 12/5/2000
* Language: C++
*
*
*****************************************************************************
*/
#include "NAMemory.h"
#include "NAAssert.h"
#include "IpcMessageObj.h"
#include "str.h"
#include "NAVersionedObject.h"
#include "ComplexObject.h"
#include <iostream>
// begin abstract class definitions
// MessageOperator methods
MessageOperator::MessageOperator() {}
MessageOperator::~MessageOperator() {}
// ObjectContainer methods
ObjectContainer::ObjectContainer() {}
ObjectContainer::~ObjectContainer() {}
// InputContainer methods
InputContainer::InputContainer() {}
InputContainer::~InputContainer() {}
// OutputContainer methods
OutputContainer::OutputContainer() {}
OutputContainer::~OutputContainer() {}
// ComplexObject methods
ComplexObject::ComplexObject(NAMemory *heap, ComplexObjectType type) :
heap_(heap), type_(type) {}
ComplexObject::~ComplexObject(){}
// Subclass of ComplexObject can override to change the Pack, UnPacker,
// and Lengther behavior, for instance, starts to use a different heap
// by passng a new UnPacker object.
void ComplexObject::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
sharedOperationSequence(packer, input, output);
}
void ComplexObject::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
sharedOperationSequence(unPacker, input, output);
}
void ComplexObject::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
sharedOperationSequence(lengther, input, output);
}
void ComplexObject::baseOperation(MessageOperator *msgOp, InputContainer *input,
OutputContainer *output){
EnumObjectContainer enumObjWrap(&type_);
msgOp->execute(&enumObjWrap, input, output);
}
NAMemory * ComplexObject::getHeap() { return heap_; }
void ComplexObject::operator delete(void *p){
if(p){
NAMemory *heap = ((ComplexObject *)p)->getHeap();
if(heap){
heap->deallocateMemory(p);
}
else{
::delete((ComplexObject *)p);
}
}
}
ComplexObjectType ComplexObject::getType() { return type_; }
// factory method for all Complex Objects, based on the type id in buffer
// return NULL for now.
ComplexObject * ComplexObject::manufacture(NAMemory *heap, char *bufferPtr,
ComplexObjectFactory *factory){
ComplexObjectType type = InvalidComplexObjectType;
EnumObjectContainer enumObjWrap(&type);
UnPacker unPacker(heap, factory);
UnPackerInput unPackerInput(bufferPtr);
UnPackerOutput unPackerOutput;
enumObjWrap.unPack(&unPacker, &unPackerInput, &unPackerOutput); // get the type description
switch(type){
case EmptyComplexObjectType:
return new (heap) EmptyComplexObject(heap);
default:
return factory->manufacture(heap, type); // forward to extension
}
}
// end of abstract class definitions
// begin stack-allocated objects
// In principle, Packer, UnPacker and Lengther classes should ues singleton
// Pattern, However, NSK security does not allow global variables.
// Packer related class definitions
// Packer definitions
Packer::Packer() {}
Packer::~Packer() {}
void Packer::execute(ObjectContainer *objWrap, InputContainer *input,
OutputContainer *output)
{
objWrap->pack(this, (PackerInput *)input, (PackerOutput *)output);
}
void Packer::setInputOutputForNextOperation(InputContainer *input,
OutputContainer *output){
char * bufferPtr = ((PackerOutput *)output)->getBufferPtr();
((PackerInput *)input)->setBufferPtr(bufferPtr);
IpcMessageObjSize currMsgSize = ((PackerOutput *)output)->getCurrMsgSize();
((PackerInput *)input)->setAccMsgSize(currMsgSize);
}
// PackerInput definitions
PackerInput::PackerInput(char *bufferPtr, IpcMessageObjSize accMsgSize) :
bufferPtr_(bufferPtr), accMsgSize_(accMsgSize) {}
PackerInput::~PackerInput() {}
char * PackerInput::getBufferPtr() { return bufferPtr_; }
IpcMessageObjSize PackerInput::getAccMsgSize() { return accMsgSize_; }
void PackerInput::setBufferPtr(char * bufferPtr) { bufferPtr_ = bufferPtr; }
void PackerInput::setAccMsgSize(IpcMessageObjSize accMsgSize) {
accMsgSize_ = accMsgSize;
}
// PackerOutput
PackerOutput::PackerOutput() :
bufferPtr_(NULL), currMsgSize_(0) {}
PackerOutput::~PackerOutput() {}
char * PackerOutput::getBufferPtr() { return bufferPtr_; }
IpcMessageObjSize PackerOutput::getCurrMsgSize() { return currMsgSize_; }
void PackerOutput::setBufferPtr(char *bufferPtr) { bufferPtr_ = bufferPtr; }
void PackerOutput::setCurrMsgSize(IpcMessageObjSize currMsgSize){
currMsgSize_ = currMsgSize;
}
// UnPacker related class definitions
// UnPacker defintions
UnPacker::UnPacker(NAMemory *heap, ComplexObjectFactory *factory) :
heap_(heap), factory_(factory) {}
UnPacker::~UnPacker() {}
void UnPacker::execute(ObjectContainer *objWrap, InputContainer *input,
OutputContainer *output){
objWrap->unPack(this, (UnPackerInput *)input, (UnPackerOutput *)output);
}
void UnPacker::setInputOutputForNextOperation(InputContainer *input,
OutputContainer *output){
char * bufferPtr = ((UnPackerOutput *)output)->getBufferPtr();
((UnPackerInput *)input)->setBufferPtr(bufferPtr);
}
NAMemory * UnPacker::getHeap() { return heap_; }
ComplexObjectFactory * UnPacker::getFactory() { return factory_; }
// UnPackerInput definitions
UnPackerInput::UnPackerInput(char *bufferPtr) : bufferPtr_(bufferPtr) {}
UnPackerInput::~UnPackerInput() {}
char * UnPackerInput::getBufferPtr() { return bufferPtr_; }
void UnPackerInput::setBufferPtr(char *bufferPtr) { bufferPtr_ = bufferPtr; }
// UnPackerOutput definitions
UnPackerOutput::UnPackerOutput() : bufferPtr_(NULL) {}
UnPackerOutput::~UnPackerOutput() {}
char * UnPackerOutput::getBufferPtr() { return bufferPtr_; }
void UnPackerOutput::setBufferPtr(char *bufferPtr) { bufferPtr_ = bufferPtr; }
// Lengther related class definitions
// Lengther definitions
Lengther::Lengther() {}
Lengther::~Lengther() {}
void Lengther::execute(ObjectContainer *objWrap, InputContainer *input,
OutputContainer *output){
objWrap->length(this, (LengtherInput *)input, (LengtherOutput *)output);
}
void Lengther::setInputOutputForNextOperation(InputContainer *input,
OutputContainer *output){
IpcMessageObjSize currMsgSize = ((LengtherOutput *)output)->getCurrMsgSize();
((LengtherInput *)input)->setAccMsgSize(currMsgSize);
}
// LengtherInput definitions
LengtherInput::LengtherInput(IpcMessageObjSize accMsgSize) :
accMsgSize_(accMsgSize) {}
LengtherInput::~LengtherInput() {}
IpcMessageObjSize LengtherInput::getAccMsgSize() { return accMsgSize_; }
void LengtherInput::setAccMsgSize(IpcMessageObjSize accMsgSize){
accMsgSize_ = accMsgSize;
}
// LengtherOutput definitions
LengtherOutput::LengtherOutput() : currMsgSize_(0) {}
LengtherOutput::~LengtherOutput() {}
IpcMessageObjSize LengtherOutput::getCurrMsgSize() { return currMsgSize_; }
void LengtherOutput::setCurrMsgSize(IpcMessageObjSize currMsgSize){
currMsgSize_ = currMsgSize;
}
// ComplexObjectPtrContainer definitions
ComplexObjectPtrContainer::ComplexObjectPtrContainer(ComplexObjectPtr *objectPtr) :
objectPtr_(objectPtr)
{ BriefAssertion(objectPtr, "a pointer to ComplexObjectPtr should not be NULL"); }
ComplexObjectPtrContainer::~ComplexObjectPtrContainer() {}
ComplexObjectPtr * ComplexObjectPtrContainer::getComplexObjectPtr()
{ return objectPtr_; }
void ComplexObjectPtrContainer::setComplexObjectPtr(ComplexObjectPtr *objectPtr) {
objectPtr_ = objectPtr;
}
void ComplexObjectPtrContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
ComplexObject *object = *objectPtr_;
if(object){
object->pack(packer, input, output);
}
else{
EmptyComplexObject eObj;
eObj.pack(packer, input, output);
}
}
void ComplexObjectPtrContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
ComplexObject *object = *objectPtr_;
if(object){
object->unPack(unPacker, input, output);
}
else{
ComplexObject *plexObj = ComplexObject::manufacture(unPacker->getHeap(),
input->getBufferPtr(), unPacker->getFactory());
BriefAssertion(plexObj, "unable to retrieve ComplexObject from buffer");
plexObj->unPack(unPacker, input, output);
if(plexObj->getType() != EmptyComplexObjectType) {
*objectPtr_ = plexObj;
}
else{
*objectPtr_ = NULL; // *objectPtr_ should already be NULL, this is a nop.
delete (EmptyComplexObject *)plexObj; // overloaded delete method called.
}
}
}
void ComplexObjectPtrContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
ComplexObject *object = *objectPtr_;
if(object){
object->length(lengther, input, output);
}
else{
EmptyComplexObject eObj;
eObj.length(lengther, input, output);
}
}
// CharPtrObjectContainer definitions
CharPtrObjectContainer::CharPtrObjectContainer(CharPtr *charPtr) :
charPtr_(charPtr)
{ BriefAssertion(charPtr, "a pointer to CharPtr should not be NULL"); }
CharPtrObjectContainer::~CharPtrObjectContainer() {}
CharPtr * CharPtrObjectContainer::getCharPtr() {return charPtr_; }
void CharPtrObjectContainer::setCharPtr(CharPtr *charPtr) { charPtr_ = charPtr; }
void CharPtrObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += ::packCharStarIntoBuffer(bufferPtr, *charPtr_);
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void CharPtrObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
const char * bufferPtr = input->getBufferPtr();
::unpackBuffer(bufferPtr, *charPtr_, unPacker->getHeap());
output->setBufferPtr((char *)bufferPtr);
}
void CharPtrObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += packedStringLength();
output->setCurrMsgSize(accMsgSize);
}
IpcMessageObjSize CharPtrObjectContainer::packedStringLength()
{
//
// The string will be preceded by a 4-byte length field and will
// include the null-terminator
//
IpcMessageObjSize result;
result = sizeof(Lng32);
char *s = *charPtr_;
if (s)
{
result += str_len(s) + 1;
}
return result;
}
// Int16ObjectContainer definitions
Int16ObjectContainer::Int16ObjectContainer(Int16 *value) : value_(value)
{ BriefAssertion(value, "a pointer to Int16 should not be NULL"); }
Int16ObjectContainer::~Int16ObjectContainer() {}
Int16* Int16ObjectContainer::getValue() { return value_; }
void Int16ObjectContainer::setValue(Int16* value) { value_ = value; }
void Int16ObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
Int16 data = *value_;
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += packIntoBuffer(bufferPtr, data);
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void Int16ObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
Int16 data;
const char * bufferPtr = input->getBufferPtr();
::unpackBuffer(bufferPtr, data);
output->setBufferPtr((char *)bufferPtr);
*value_ = data;
}
void Int16ObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += sizeof(*value_);
output->setCurrMsgSize(accMsgSize);
}
// IntegerObjectContainer definitions
IntegerObjectContainer::IntegerObjectContainer(Int32 *value) : value_(value)
{ BriefAssertion(value, "a pointer to int should not be NULL"); }
IntegerObjectContainer::~IntegerObjectContainer() {}
Int32* IntegerObjectContainer::getValue() { return value_; }
void IntegerObjectContainer::setValue(Int32* value) { value_ = value; }
void IntegerObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
Int32 data = *value_;
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += packIntoBuffer(bufferPtr, data);
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void IntegerObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
Int32 data;
const char * bufferPtr = input->getBufferPtr();
::unpackBuffer(bufferPtr, data);
output->setBufferPtr((char *)bufferPtr);
*value_ = data;
}
void IntegerObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += sizeof(*value_);
output->setCurrMsgSize(accMsgSize);
}
// LongObjectContainer definitions
LongObjectContainer::LongObjectContainer(Lng32 *value) : value_(value)
{ BriefAssertion(value, "a pointer to int should not be NULL"); }
LongObjectContainer::~LongObjectContainer() {}
Lng32* LongObjectContainer::getValue() { return value_; }
void LongObjectContainer::setValue(Lng32* value) { value_ = value; }
void LongObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
Lng32 data = *value_;
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += packIntoBuffer(bufferPtr, data);
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void LongObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
Lng32 data;
const char * bufferPtr = input->getBufferPtr();
::unpackBuffer(bufferPtr, data);
output->setBufferPtr((char *)bufferPtr);
*value_ = data;
}
void LongObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += sizeof(*value_);
output->setCurrMsgSize(accMsgSize);
}
// EnumObjectContainer definitions
EnumObjectContainer::EnumObjectContainer(ComplexObjectType *value) :
value_(value) {}
EnumObjectContainer::~EnumObjectContainer() {}
ComplexObjectType * EnumObjectContainer::getValue() { return value_; }
void EnumObjectContainer::setValue(ComplexObjectType * value) { value_ = value; }
void EnumObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
ComplexObjectType data = *value_;
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += packIntoBuffer(bufferPtr, data);
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void EnumObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
ComplexObjectType data;
const char * bufferPtr = input->getBufferPtr();
::unpackBuffer(bufferPtr, data);
output->setBufferPtr((char *)bufferPtr);
*value_ = data;
}
void EnumObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
accMsgSize += sizeof(*value_);
output->setCurrMsgSize(accMsgSize);
}
// NopObjectContainer definitions
NopObjectContainer::NopObjectContainer() {}
NopObjectContainer::~NopObjectContainer() {}
void NopObjectContainer::pack(Packer *packer, PackerInput *input,
PackerOutput *output){
char * bufferPtr = input->getBufferPtr();
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
output->setBufferPtr(bufferPtr);
output->setCurrMsgSize(accMsgSize);
}
void NopObjectContainer::unPack(UnPacker *unPacker, UnPackerInput *input,
UnPackerOutput *output){
char * bufferPtr = input->getBufferPtr();
output->setBufferPtr(bufferPtr);
}
void NopObjectContainer::length(Lengther *lengther, LengtherInput *input,
LengtherOutput *output){
IpcMessageObjSize accMsgSize = input->getAccMsgSize();
output->setCurrMsgSize(accMsgSize);
}
// complex object class definitions
// EmptyComplexObject defintions
EmptyComplexObject::EmptyComplexObject(NAMemory *heap) :
ComplexObject(heap, EmptyComplexObjectType) {}
EmptyComplexObject::EmptyComplexObject() :
ComplexObject(NULL, EmptyComplexObjectType) {}
EmptyComplexObject::~EmptyComplexObject() {}
void EmptyComplexObject::freeSubObjects() {}
void EmptyComplexObject::sharedOperationSequence(MessageOperator *msgOp,
InputContainer *input,
OutputContainer *output) {
baseOperation(msgOp, input, output);
}