blob: fd5a85d05936d8543ccee5e3b148c89e69bc4ae1 [file] [log] [blame]
/** \file arrayfs.cpp .
-----------------------------------------------------------------------------
* 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.
-----------------------------------------------------------------------------
Description:
-----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/arrayfs.hpp"
#include "uima/featurestructure.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/msg.h"
#include "uima/internal_fspromoter.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "uima/internal_fsvalue_accessors.hpp"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
namespace uima {
/* ----------------------------------------------------------------------- */
/* Exceptions Implementation */
/* ----------------------------------------------------------------------- */
UIMA_EXC_CLASSIMPLEMENT(FSIsNotArrayException, CASException);
UIMA_EXC_CLASSIMPLEMENT(FSArrayOutOfBoundsException, CASException);
/* ----------------------------------------------------------------------- */
/* Tool Functions Implementation */
/* ----------------------------------------------------------------------- */
void checkArray(const uima::lowlevel::TyFSType ARRAY_TYPE, lowlevel::TyFS tyFS, uima::lowlevel::FSHeap * pFSSystem, TyMessageId tyContext) {
assert(EXISTS(pFSSystem));
if (pFSSystem->getType( tyFS) != ARRAY_TYPE ) {
UIMA_EXC_THROW_NEW(FSIsNotArrayException,
UIMA_ERR_FS_IS_NOT_ARRAY,
UIMA_MSG_ID_EXC_FS_IS_NOT_ARRAY,
ErrorMessage(tyContext),
ErrorInfo::recoverable
);
}
}
void checkArraySize(lowlevel::TyFS tyFS, uima::lowlevel::FSHeap * pFSSystem, size_t n, TyMessageId tyContext) {
size_t uiSize = pFSSystem->getArraySize(tyFS);
if (n >= uiSize) {
ErrorMessage err(UIMA_MSG_ID_EXC_ARRAY_OUT_OF_BOUNDS);
err.addParam(n);
err.addParam(uiSize);
UIMA_EXC_THROW_NEW(FSArrayOutOfBoundsException,
UIMA_ERR_FS_ARRAY_OUT_OF_BOUNDS,
err,
ErrorMessage(tyContext),
ErrorInfo::recoverable
);
}
}
/* ----------------------------------------------------------------------- */
/* BasicArrayFS */
/* ----------------------------------------------------------------------- */
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS(lowlevel::TyFS anFS, uima::CAS & rFSSystem, bool bDoChecks) :
FeatureStructure(anFS, rFSSystem) {
if (bDoChecks) {
checkValidity(UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
checkArray(ARRAY_TYPE, iv_tyFS, iv_cas->getHeap(), UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
}
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS() :
FeatureStructure() {}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
BasicArrayFS<T, ARRAY_TYPE>::BasicArrayFS( FeatureStructure const & fs) :
FeatureStructure(fs) {
// don't do checks here, exceptions should only be thrown
// when accessing an invalid object
if (isValid()) {
checkArray(ARRAY_TYPE, iv_tyFS, iv_cas->getHeap(), UIMA_MSG_ID_EXCON_CREATING_ARRAYFS);
}
// we should not have any additional members
assert(sizeof(BasicArrayFS) == sizeof(FeatureStructure));
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
T BasicArrayFS<T, ARRAY_TYPE>::get(size_t n) const {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
checkArraySize(iv_tyFS, iv_cas->getHeap(), n, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
T result;
if (typecode == uima::internal::gs_tyIntArrayType ||
typecode == uima::internal::gs_tyFloatArrayType ||
typecode == uima::internal::gs_tyStringArrayType ||
typecode == uima::internal::gs_tyFSArrayType) {
lowlevel::TyHeapCell* pArray = iv_cas->getHeap()->getCArrayFromFS(iv_tyFS);
uima::internal::fromHeapCellTempl(pArray[n], *iv_cas, result );
} else {
size_t pos = iv_cas->getHeap()->getArrayOffset(iv_tyFS) + n;
uima::internal::fromHeapCellTempl(pos, *iv_cas, result );
}
return result;
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
void BasicArrayFS<T, ARRAY_TYPE>::set(size_t n, T const & val) {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
checkArraySize(iv_tyFS, iv_cas->getHeap(), n, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
if (typecode == uima::internal::gs_tyIntArrayType ||
typecode == uima::internal::gs_tyFloatArrayType ||
typecode == uima::internal::gs_tyStringArrayType ||
typecode == uima::internal::gs_tyFSArrayType) {
lowlevel::TyHeapCell* pArray = iv_cas->getHeap()->getCArrayFromFS(iv_tyFS);
uima::lowlevel::TyHeapCell result = uima::internal::toHeapCellTempl(val, *iv_cas->getHeap(),0);
pArray[n] = result;
} else {
size_t pos = iv_cas->getHeap()->getArrayOffset(iv_tyFS) + n;
uima::lowlevel::TyHeapCell result = uima::internal::toHeapCellTempl(val, *iv_cas->getHeap(),pos);
}
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
size_t BasicArrayFS<T, ARRAY_TYPE>::size() const {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_ARRAYSIZE_FROM_FS);
return iv_cas->getHeap()->getArraySize(iv_tyFS);
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
void BasicArrayFS<T, ARRAY_TYPE>::copyToArray(
size_t uiStart,
size_t uiEnd,
T* destArray,
size_t uiDestOffset) const {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
checkArraySize(iv_tyFS, iv_cas->getHeap(), uiEnd - uiStart - 1 , UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
size_t srcOffset = uiStart;
size_t numelements = uiEnd-uiStart;
size_t destOffset = uiDestOffset;
if (typecode== uima::internal::gs_tyIntArrayType ||
typecode== uima::internal::gs_tyFloatArrayType ) {
iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(uima::lowlevel::TyHeapCell*) destArray,destOffset,numelements);
} else if(typecode== uima::internal::gs_tyByteArrayType ||
typecode== uima::internal::gs_tyBooleanArrayType) {
iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(char*) destArray,destOffset,numelements);
} else if(typecode== uima::internal::gs_tyShortArrayType ) {
iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(short*) destArray,destOffset,numelements);
} else if(typecode== uima::internal::gs_tyLongArrayType ||
typecode== uima::internal::gs_tyDoubleArrayType) {
iv_cas->getHeap()->copyToArray( srcOffset,iv_tyFS,(INT64*) destArray,destOffset,numelements);
} else {
assertWithMsg(false, "Not yet implemented");
UIMA_EXC_THROW_NEW(NotYetImplementedException,
UIMA_ERR_NOT_YET_IMPLEMENTED,
UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
ErrorInfo::unrecoverable
);
}
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
void BasicArrayFS<T, ARRAY_TYPE>::copyFromArray(
T const * sourceArray,
size_t uiStart,
size_t uiEnd,
size_t uiOffset) {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
checkArraySize(iv_tyFS, iv_cas->getHeap(), uiEnd - uiStart - 1, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
size_t srcOffset = uiStart;
size_t numelements = uiEnd-uiStart;
size_t destOffset = uiOffset;
checkArraySize(iv_tyFS, iv_cas->getHeap(), destOffset+numelements-1, UIMA_MSG_ID_EXCON_GETTING_FS_FROM_ARRAY);
uima::lowlevel::TyFSType typecode = iv_cas->getHeap()->getType(iv_tyFS);
if (typecode== uima::internal::gs_tyIntArrayType ||
typecode== uima::internal::gs_tyFloatArrayType ) {
iv_cas->getHeap()->copyFromArray( (uima::lowlevel::TyHeapCell *) sourceArray, srcOffset, iv_tyFS, destOffset, numelements);
}
else if(typecode== uima::internal::gs_tyByteArrayType ||
typecode== uima::internal::gs_tyBooleanArrayType ) {
iv_cas->getHeap()->copyFromArray( (char *) sourceArray, srcOffset, iv_tyFS, destOffset, numelements);
}
else if(typecode== uima::internal::gs_tyShortArrayType) {
iv_cas->getHeap()->copyFromArray( (short *) sourceArray, srcOffset, iv_tyFS, destOffset, numelements);
}
else if(typecode== uima::internal::gs_tyLongArrayType ||
typecode == uima::internal::gs_tyDoubleArrayType ) {
iv_cas->getHeap()->copyFromArray( (INT64 *) sourceArray, srcOffset, iv_tyFS, destOffset, numelements);
}
else {
assertWithMsg(false, "Not yet implemented");
UIMA_EXC_THROW_NEW(NotYetImplementedException,
UIMA_ERR_NOT_YET_IMPLEMENTED,
UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
ErrorInfo::unrecoverable
);
}
}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
void BasicArrayFS<T, ARRAY_TYPE>::copyToArray(
size_t srcOffset, T * destArray, size_t destOffset, size_t length)
const {
copyToArray(srcOffset, srcOffset + length, destArray, destOffset );
}
// template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
//void BasicArrayFS<T, ARRAY_TYPE>::copyFromArray(
// T const * srcArray, size_t srcOffset, size_t destOffset, size_t length) {
//copyFromArray(srcArray, srcOffset, srcOffset + length, destOffset);
//}
template< class T, const uima::lowlevel::TyFSType ARRAY_TYPE >
/*static*/ BasicArrayFS<T, ARRAY_TYPE> BasicArrayFS<T, ARRAY_TYPE>::createArrayFS( CAS & cas, size_t uiSize, bool bIsPermanent) {
assertWithMsg( sizeof(FeatureStructure::TyArrayElement) == sizeof(lowlevel::TyHeapCell), "Port required");
uima::lowlevel::FSHeap & heap = *uima::internal::FSPromoter::getFSHeap(cas);
lowlevel::TyFS tyFS = heap.createArrayFS(ARRAY_TYPE, uiSize);
return BasicArrayFS(internal::FSPromoter::promoteFS( tyFS, cas ));
}
// explicit instantiation
template class BasicArrayFS< FeatureStructure, internal::gs_tyFSArrayType >;
// explicit instantiation
template class BasicArrayFS< float, internal::gs_tyFloatArrayType >;
// explicit instantiation
template class BasicArrayFS< int, internal::gs_tyIntArrayType >;
// explicit instantiation
template class BasicArrayFS< UnicodeStringRef, internal::gs_tyStringArrayType >;
// explicit instantiation
template class BasicArrayFS< bool, internal::gs_tyBooleanArrayType >;
template class BasicArrayFS< char, internal::gs_tyByteArrayType >;
template class BasicArrayFS< short, internal::gs_tyShortArrayType >;
template class BasicArrayFS< INT64, internal::gs_tyLongArrayType >;
template class BasicArrayFS< double, internal::gs_tyDoubleArrayType >;
} // namespace uima
/* ----------------------------------------------------------------------- */
/* <EOF> */