blob: 8c4edea5d402e06a3eca503e0e8972100d464423 [file] [log] [blame]
/** \file cas.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/pragmas.hpp"
#include "uima/msg.h"
#include "uima/macros.h"
#include "uima/cas.hpp"
#include "uima/casdefinition.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/typesystem.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/listfs.hpp"
#include "uima/arrayfs.hpp"
#include "uima/lowlevel_typesystem.hpp"
#include "uima/lowlevel_typedefs.hpp"
#include "unicode/unistr.h"
#include "uima/fsfilterbuilder.hpp"
#include "uima/sofaid.hpp"
#include "uima/lowlevel_defaultfsiterator.hpp"
#include "uima/annotator_context.hpp"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
#define UIMA_CAS_NAMESPACE "uima" UIMA_NAMESPACE_SEPARATOR "cas"
#define UIMA_CAS_PFX UIMA_CAS_NAMESPACE UIMA_NAMESPACE_SEPARATOR
#define UIMA_TCAS_NAMESPACE "uima" UIMA_NAMESPACE_SEPARATOR "tcas"
#define UIMA_TCAS_PFX UIMA_TCAS_NAMESPACE UIMA_NAMESPACE_SEPARATOR
#define ANNOTATION UIMA_TCAS_PFX "Annotation"
#define DOCUMENTANNOTATION UIMA_TCAS_PFX "DocumentAnnotation"
#define SOFA "sofa"
#define BEGIN "begin"
#define END "end"
#define LANGUAGE "language"
using namespace std;
namespace uima {
icu::UnicodeString const CAS::ustrCREATOR_ID_CAS(lowlevel::TypeSystem::ustrCREATOR_ID_SYSTEM);
char const * CAS::NAME_SPACE_UIMA_CAS = UIMA_CAS_NAMESPACE;
char const * CAS::TYPE_NAME_TOP = UIMA_CAS_PFX "TOP";
char const * CAS::TYPE_NAME_INTEGER = UIMA_CAS_PFX "Integer";
char const * CAS::TYPE_NAME_STRING = UIMA_CAS_PFX "String";
char const * CAS::TYPE_NAME_FLOAT = UIMA_CAS_PFX "Float";
char const * CAS::TYPE_NAME_LIST_BASE = UIMA_CAS_PFX "ListBase";
char const * CAS::TYPE_NAME_FS_LIST = UIMA_CAS_PFX "FSList";
char const * CAS::TYPE_NAME_EMPTY_FS_LIST = UIMA_CAS_PFX "EmptyFSList";
char const * CAS::TYPE_NAME_NON_EMPTY_FS_LIST = UIMA_CAS_PFX "NonEmptyFSList";
char const * CAS::TYPE_NAME_FLOAT_LIST = UIMA_CAS_PFX "FloatList";
char const * CAS::TYPE_NAME_NON_EMPTY_FLOAT_LIST = UIMA_CAS_PFX "NonEmptyFloatList";
char const * CAS::TYPE_NAME_EMPTY_FLOAT_LIST = UIMA_CAS_PFX "EmptyFloatList";
char const * CAS::TYPE_NAME_INTEGER_LIST = UIMA_CAS_PFX "IntegerList";
char const * CAS::TYPE_NAME_NON_EMPTY_INTEGER_LIST = UIMA_CAS_PFX "NonEmptyIntegerList";
char const * CAS::TYPE_NAME_EMPTY_INTEGER_LIST = UIMA_CAS_PFX "EmptyIntegerList";
char const * CAS::TYPE_NAME_STRING_LIST = UIMA_CAS_PFX "StringList";
char const * CAS::TYPE_NAME_NON_EMPTY_STRING_LIST = UIMA_CAS_PFX "NonEmptyStringList";
char const * CAS::TYPE_NAME_EMPTY_STRING_LIST = UIMA_CAS_PFX "EmptyStringList";
char const * CAS::TYPE_NAME_ARRAY_BASE = UIMA_CAS_PFX "ArrayBase";
char const * CAS::TYPE_NAME_FS_ARRAY = UIMA_CAS_PFX "FSArray";
char const * CAS::TYPE_NAME_FLOAT_ARRAY = UIMA_CAS_PFX "FloatArray";
char const * CAS::TYPE_NAME_INTEGER_ARRAY = UIMA_CAS_PFX "IntegerArray";
char const * CAS::TYPE_NAME_STRING_ARRAY = UIMA_CAS_PFX "StringArray";
char const * CAS::TYPE_NAME_SOFA = UIMA_CAS_PFX "Sofa";
char const * CAS::TYPE_NAME_LOCALSOFA = UIMA_CAS_PFX "Sofa";
char const * CAS::TYPE_NAME_REMOTESOFA = UIMA_CAS_PFX "Sofa";
char const * CAS::FEATURE_BASE_NAME_HEAD = "head";
char const * CAS::FEATURE_BASE_NAME_TAIL = "tail";
char const * CAS::FEATURE_FULL_NAME_FS_LIST_TAIL = UIMA_CAS_PFX "NonEmptyFSList" UIMA_TYPE_FEATURE_SEPARATOR "tail";
char const * CAS::FEATURE_FULL_NAME_FS_LIST_HEAD = UIMA_CAS_PFX "NonEmptyFSList" UIMA_TYPE_FEATURE_SEPARATOR "head";
char const * CAS::FEATURE_BASE_NAME_SOFANUM = "sofaNum";
char const * CAS::FEATURE_BASE_NAME_SOFAID = "sofaID";
char const * CAS::FEATURE_BASE_NAME_SOFAMIME = "mimeType";
char const * CAS::FEATURE_BASE_NAME_SOFAURI = "sofaURI";
char const * CAS::FEATURE_BASE_NAME_SOFASTRING = "sofaString";
char const * CAS::FEATURE_BASE_NAME_SOFAARRAY = "sofaArray";
char const * CAS::TYPE_NAME_BOOLEAN = UIMA_CAS_PFX "Boolean";
char const * CAS::TYPE_NAME_BYTE = UIMA_CAS_PFX "Byte";
char const * CAS::TYPE_NAME_SHORT = UIMA_CAS_PFX "Short";
char const * CAS::TYPE_NAME_LONG = UIMA_CAS_PFX "Long";
char const * CAS::TYPE_NAME_DOUBLE = UIMA_CAS_PFX "Double";
char const * CAS::TYPE_NAME_BOOLEAN_ARRAY = UIMA_CAS_PFX "BooleanArray";
char const * CAS::TYPE_NAME_BYTE_ARRAY = UIMA_CAS_PFX "ByteArray";
char const * CAS::TYPE_NAME_SHORT_ARRAY = UIMA_CAS_PFX "ShortArray";
char const * CAS::TYPE_NAME_LONG_ARRAY = UIMA_CAS_PFX "LongArray";
char const * CAS::TYPE_NAME_DOUBLE_ARRAY = UIMA_CAS_PFX "DoubleArray";
char const * CAS::FEATURE_FULL_NAME_SOFANUM = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaNum";
char const * CAS::FEATURE_FULL_NAME_SOFAID = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaID";
char const * CAS::FEATURE_FULL_NAME_SOFAMIME = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "mimeType";
char const * CAS::FEATURE_FULL_NAME_SOFAURI = UIMA_CAS_PFX "RemoteSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaURI";
char const * CAS::FEATURE_FULL_NAME_SOFASTRING = UIMA_CAS_PFX "LocalSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaString";
char const * CAS::FEATURE_FULL_NAME_SOFAARRAY = UIMA_CAS_PFX "LocalSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaArray";
char const * CAS::INDEXID_SOFA = "SofaIndex";
char const * CAS::NAME_DEFAULT_TEXT_SOFA = "_InitialView";
char const * CAS::NAME_DEFAULT_SOFA = "_InitialView";
char const * CAS::TYPE_NAME_ANNOTATION_BASE = UIMA_CAS_PFX "AnnotationBase";
char const * CAS::TYPE_NAME_ANNOTATION = ANNOTATION;
char const * CAS::TYPE_NAME_DOCUMENT_ANNOTATION = DOCUMENTANNOTATION;
char const * CAS::FEATURE_BASE_NAME_SOFA = SOFA;
char const * CAS::FEATURE_FULL_NAME_SOFA = SOFA UIMA_TYPE_FEATURE_SEPARATOR SOFA;
char const * CAS::FEATURE_BASE_NAME_BEGIN = BEGIN;
char const * CAS::FEATURE_FULL_NAME_BEGIN = ANNOTATION UIMA_TYPE_FEATURE_SEPARATOR BEGIN;
char const * CAS::FEATURE_BASE_NAME_END = END;
char const * CAS::FEATURE_FULL_NAME_END = ANNOTATION UIMA_TYPE_FEATURE_SEPARATOR END;
char const * CAS::FEATURE_BASE_NAME_LANGUAGE = LANGUAGE;
char const * CAS::FEATURE_FULL_NAME_LANGUAGE = DOCUMENTANNOTATION UIMA_TYPE_FEATURE_SEPARATOR LANGUAGE;
char const * CAS::INDEXID_ANNOTATION = "AnnotationIndex";
}
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
/*
* Most of the methods in here use the lowlevel API directly.
*/
namespace uima {
UIMA_EXC_CLASSIMPLEMENT( CouldNotCreateFSOfFinalTypeException, CASException );
UIMA_EXC_CLASSIMPLEMENT( DuplicateSofaNameException, CASException );
UIMA_EXC_CLASSIMPLEMENT( InvalidBaseCasMethod, CASException );
CAS::CAS(uima::internal::CASDefinition & casDefs,
size_t uiFSHeapPageSize,
size_t uiStringHeapPageSize,
size_t uiStringRefHeapPageSize)
: iv_casDefinition( & casDefs ),
iv_typeSystem(NULL),
iv_heap(NULL),
initialSofaCreated(false),
iv_sofaNum(0),
iv_sofaCount(0),
iv_initialView(NULL),
iv_indexRepository(NULL),
iv_filterBuilder(NULL),
iv_componentInfo(NULL),
iv_utDocumentType(uima::lowlevel::TypeSystem::INVALID_TYPE),
iv_utDocumentLangAsIntFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
iv_utDocumentLangAsStrFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
iv_cpDocument(NULL),
iv_uiDocumentLength(0),
iv_copyOfDocument(NULL),
iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
// leave those as assertions, don't throw exceptions
assert( casDefs.getTypeSystem().isCommitted() );
assert( casDefs.getIndexDefinition().isCommitted() );
iv_typeSystem = &casDefs.getTypeSystem();
iv_heap = new uima::lowlevel::FSHeap(casDefs.getTypeSystem(),
uiFSHeapPageSize,
uiStringHeapPageSize,
uiStringRefHeapPageSize);
assert( EXISTS(iv_heap) );
iv_indexRepository = new uima::lowlevel::IndexRepository(casDefs.getIndexDefinition(),
*iv_heap, *this);
assert( EXISTS( iv_indexRepository) );
iv_filterBuilder = new uima::FSFilterBuilder();
assert( EXISTS(iv_filterBuilder) );
isbaseCas = true;
iv_baseCas = this;
isDeletingViews = false;
bOwnsCASDefinition=false;
}
// Constructor used for views
CAS::CAS(CAS* inCas, SofaFS inSofa):
iv_sofaNum(0),
iv_sofaCount(0),
iv_cpDocument(NULL),
iv_uiDocumentLength(0),
iv_copyOfDocument(NULL),
iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
iv_casDefinition = inCas->iv_casDefinition;
iv_typeSystem = inCas->iv_typeSystem;
iv_heap = inCas->iv_heap;
iv_componentInfo = inCas->iv_componentInfo;
iv_utDocumentLangAsIntFeat = uima::lowlevel::TypeSystem::INVALID_FEATURE;
iv_utDocumentLangAsStrFeat = uima::lowlevel::TypeSystem::INVALID_FEATURE;
refreshCachedTypes();
if (inSofa.isValid()) {
lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(inSofa);
iv_sofaNum = iv_heap->getIntValue(tySofa, internal::gs_tySofaNumFeature);
UnicodeStringRef pDoc = iv_heap->getStringValue(tySofa, internal::gs_tySofaStringFeature);
copyDocumentString(pDoc);
} else {
iv_sofaNum = 1;
}
// each view has unique indexRepository
iv_indexRepository = new uima::lowlevel::IndexRepository(iv_casDefinition->getIndexDefinition(),
*iv_heap, *this);
assert( EXISTS(iv_indexRepository) );
if ((int)inCas->iv_sofa2indexMap.size() < iv_sofaNum+1) {
inCas->iv_sofa2indexMap.resize(iv_sofaNum + 1);
}
// map to a Sofa's IR. This map is deleted when the CAS definition may change.
inCas->iv_sofa2indexMap[iv_sofaNum] = iv_indexRepository;
iv_filterBuilder = inCas->iv_filterBuilder;
isbaseCas = false;
iv_baseCas = inCas;
bOwnsCASDefinition = false;
isDeletingViews = false;
}
CAS::CAS(uima::internal::CASDefinition & casDefs,
bool ownsCasDef,
size_t uiFSHeapPageSize,
size_t uiStringHeapPageSize,
size_t uiStringRefHeapPageSize)
: iv_casDefinition( & casDefs ),
iv_typeSystem(NULL),
iv_heap(NULL),
iv_sofaNum(0),
iv_sofaCount(0),
initialSofaCreated(false),
iv_initialView(NULL),
iv_indexRepository(NULL),
iv_filterBuilder(NULL),
iv_componentInfo(NULL),
iv_utDocumentType(uima::lowlevel::TypeSystem::INVALID_TYPE),
iv_utDocumentLangAsIntFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
iv_utDocumentLangAsStrFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
iv_cpDocument(NULL),
iv_uiDocumentLength(0),
iv_copyOfDocument(NULL),
iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
// leave those as assertions, don't throw exceptions
assert( casDefs.getTypeSystem().isCommitted() );
assert( casDefs.getIndexDefinition().isCommitted() );
iv_typeSystem = &casDefs.getTypeSystem();
iv_heap = new uima::lowlevel::FSHeap(casDefs.getTypeSystem(),
uiFSHeapPageSize,
uiStringHeapPageSize,
uiStringRefHeapPageSize);
assert( EXISTS(iv_heap) );
iv_indexRepository = new uima::lowlevel::IndexRepository(casDefs.getIndexDefinition(),
*iv_heap, *this);
assert( EXISTS( iv_indexRepository) );
iv_filterBuilder = new uima::FSFilterBuilder();
assert( EXISTS(iv_filterBuilder) );
isbaseCas = true;
iv_baseCas = this;
bOwnsCASDefinition=ownsCasDef;
isDeletingViews = false;
}
CAS::~CAS() {
//always delete index repository
if (this->iv_indexRepository != NULL) {
delete iv_indexRepository;
iv_indexRepository = NULL;
}
if (this->iv_cpDocument != NULL) {
delete[] this->iv_cpDocument;
this->iv_cpDocument = NULL;
}
//initial call to delete object
if (this->isbaseCas) {
this->iv_baseCas->isDeletingViews = true;
if (this->iv_baseCas->iv_heap != NULL) {
delete this->iv_baseCas->iv_heap;
this->iv_baseCas->iv_heap = NULL;
}
if (iv_baseCas->iv_filterBuilder != NULL) {
delete iv_baseCas->iv_filterBuilder;
iv_baseCas->iv_filterBuilder = NULL;
}
if (this->iv_baseCas->bOwnsCASDefinition ) {
if (this->iv_baseCas->iv_casDefinition != NULL) {
delete this->iv_baseCas->iv_casDefinition;
this->iv_baseCas->iv_casDefinition = NULL;
}
}
map<int, CAS*>::iterator mIter;
map<int,CAS*> mapcopy(this->iv_baseCas->iv_sofa2tcasMap);
for ( mIter = mapcopy.begin( );
mIter != mapcopy.end( ); mIter++ ) {
CAS* tcas = mIter->second;
if ( tcas != NULL) {
delete tcas;
}
//this->iv_baseCas->iv_sofa2tcasMap.clear( );
//this->iv_baseCas->iv_sofa2indexMap.clear();
}
} else {
if (!this->iv_baseCas->isDeletingViews) {
dropView(this->getSofaNum());
this->iv_baseCas->isDeletingViews=true;
delete this->iv_baseCas;
}
}
}
FSFilterBuilder const & CAS::getFSFilterBuilder() const {
assert( EXISTS(iv_filterBuilder) );
return *iv_filterBuilder;
}
TypeSystem const & CAS::getTypeSystem(void) const {
assert( EXISTS(iv_heap) );
return *iv_typeSystem;
}
uima::lowlevel::FSHeap * CAS::getHeap() {
assert( EXISTS(iv_heap) );
return iv_heap;
}
TyErrorId CAS::reset() {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_indexRepository) );
if (!isbaseCas) {
iv_baseCas->reset();
} else {
// reset all views for this CAS
map<int, CAS*>::iterator mIter;
for ( mIter = iv_sofa2tcasMap.begin( ); mIter != iv_sofa2tcasMap.end( ); mIter++ ) {
CAS* tcas = mIter->second;
tcas->iv_cpDocument = NULL;
if (NULL != tcas->iv_copyOfDocument)
delete [] tcas->iv_copyOfDocument;
tcas->iv_copyOfDocument = NULL;
tcas->iv_uiDocumentLength = 0;
tcas->iv_indexRepository->reset();
tcas->iv_tyDocumentAnnotation = uima::lowlevel::FSHeap::INVALID_FS;
}
iv_heap->reset();
iv_baseCas->initialSofaCreated = false;
iv_sofaCount = 1; // for initial view
iv_indexRepository->reset();
}
return UIMA_ERR_NONE;
}
FeatureStructure CAS::createFS(Type const & crType) {
if (!crType.isValid()) {
UIMA_EXC_THROW_NEW(InvalidFSTypeObjectException,
UIMA_ERR_INVALID_FSTYPE_OBJECT,
UIMA_MSG_ID_EXC_INVALID_FSTYPE_OBJECT,
ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_FS),
ErrorInfo::recoverable
);
}
uima::lowlevel::TyFSType tyType = internal::FSPromoter::demoteType(crType);
switch (tyType) {
case uima::internal::gs_tyIntegerType:
case uima::internal::gs_tyFloatType:
case uima::internal::gs_tyStringType:
case uima::internal::gs_tyBooleanType:
case uima::internal::gs_tyByteType:
case uima::internal::gs_tyShortType:
case uima::internal::gs_tyLongType:
case uima::internal::gs_tyDoubleType: {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_COULD_NOT_CREATE_FS_FINAL_TYPE );
errMessage.addParam( crType.getName() );
UIMA_EXC_THROW_NEW(CouldNotCreateFSOfFinalTypeException,
UIMA_ERR_COULD_NOT_CREATE_FS_OF_FINAL_TYPE,
errMessage,
UIMA_MSG_ID_EXCON_CREATING_FS,
ErrorInfo::recoverable
);
}
default:
;
}
// if new FS is annotation type, set the sofa feature
lowlevel::TyFS temp= iv_heap->createFS(tyType);
if (iv_heap->getTypeSystem().subsumes(internal::gs_tyAnnotationType, tyType)) {
iv_heap->setFSValue(temp, internal::gs_tySofaRefFeature,
internal::FSPromoter::demoteFS(getSofa()));
}
return internal::FSPromoter::promoteFS(temp, *this );
}
int CAS::addString(UChar const * cpBuffer, size_t uiLength) {
UnicodeStringRef uls( cpBuffer, uiLength );
int shoff = iv_heap->addString(uls);
return iv_heap->getStringAsFS(shoff);
}
int CAS::addString(icu::UnicodeString const & crString) {
UnicodeStringRef uls( crString.getBuffer(), crString.length() );
int shoff = iv_heap->addString(uls);
return iv_heap->getStringAsFS(shoff);
}
int CAS::addString(const UnicodeStringRef & uls) {
int shoff = iv_heap->addString(uls);
return iv_heap->getStringAsFS(shoff);
}
ArrayFS CAS::createArrayFS(size_t uiLength) {
return ArrayFS::createArrayFS(*this, uiLength);
}
FloatArrayFS CAS::createFloatArrayFS(size_t uiLength) {
return FloatArrayFS::createArrayFS(*this, uiLength);
}
IntArrayFS CAS::createIntArrayFS(size_t uiLength) {
return IntArrayFS::createArrayFS(*this, uiLength);
}
StringArrayFS CAS::createStringArrayFS(size_t uiLength) {
return StringArrayFS::createArrayFS(*this, uiLength);
}
BooleanArrayFS CAS::createBooleanArrayFS(size_t uiLength) {
return BooleanArrayFS::createArrayFS(*this, uiLength);
}
ByteArrayFS CAS::createByteArrayFS(size_t uiLength) {
return ByteArrayFS::createArrayFS(*this, uiLength);
}
ShortArrayFS CAS::createShortArrayFS(size_t uiLength) {
return ShortArrayFS::createArrayFS(*this, uiLength);
}
LongArrayFS CAS::createLongArrayFS(size_t uiLength) {
return LongArrayFS::createArrayFS(*this, uiLength);
}
DoubleArrayFS CAS::createDoubleArrayFS(size_t uiLength) {
return DoubleArrayFS::createArrayFS(*this, uiLength);
}
ListFS CAS::createListFS( ) {
return ListFS::createListFS(*this);
}
FloatListFS CAS::createFloatListFS( ) {
return FloatListFS::createListFS(*this);
}
IntListFS CAS::createIntListFS( ) {
return IntListFS::createListFS(*this);
}
StringListFS CAS::createStringListFS( ) {
return StringListFS::createListFS(*this);
}
/////////////////////////////////////////////////////////////
// index
FSIndexRepository & CAS::getIndexRepository( void ) {
if (isbaseCas) {
invalidBaseCasMethod();
}
assert( EXISTS(iv_indexRepository) );
return *iv_indexRepository;
}
FSIndexRepository const & CAS::getIndexRepository( void ) const {
if (isbaseCas) {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
UIMA_ERR_INVALID_BASE_CAS_METHOD,
errMessage,
UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
ErrorInfo::unrecoverable
);
}
assert( EXISTS(iv_indexRepository) );
return *iv_indexRepository;
}
lowlevel::IndexRepository & CAS::getLowlevelIndexRepository( void ) const {
if (isbaseCas) {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
UIMA_ERR_INVALID_BASE_CAS_METHOD,
errMessage,
UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
ErrorInfo::unrecoverable
);
}
assert( EXISTS(iv_indexRepository) );
return *iv_indexRepository;
}
FSIterator CAS::iterator() {
lowlevel::IndexIterator* it = new uima::lowlevel::DefaultFSIterator(*iv_heap);
return FSIterator(it, this );
}
/////////////////////////////////////////////////////////////////////////////
// Get or Create CAS view for aSofa
CAS* CAS::getView(SofaFS aSofa) {
CAS* aTcas;
int sofaNum = iv_heap->getIntValue(internal::FSPromoter::demoteFS(aSofa), internal::gs_tySofaNumFeature);
map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
if (cit == iv_baseCas->iv_sofa2tcasMap.end()) {
if (sofaNum > iv_baseCas->iv_sofaCount) {
// This sofa must have just been created during binary deserialization
assert(iv_baseCas->iv_sofaCount+1 == sofaNum);
iv_baseCas->iv_sofaCount = sofaNum;
if ( iv_sofaCount+1 > (int) iv_baseCas->iv_sofa2indexMap.size()) {
iv_baseCas->iv_sofa2indexMap.resize(sofaNum + 1);
iv_baseCas->iv_sofa2indexMap[sofaNum] = NULL;
}
}
aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas, aSofa);
assert ( EXISTS(aTcas) );
pair<int, CAS*> p1(sofaNum, aTcas);
iv_baseCas->iv_sofa2tcasMap.insert(p1);
return aTcas;
}
// if (createDocAnn) {
// (*cit).second->setDocumentAnnotationFromSofa( );
// }
if (sofaNum > iv_baseCas->iv_sofaCount) {
// This sofa must have just been created during xcas deserialization
assert(iv_baseCas->iv_sofaCount+1 == sofaNum);
iv_baseCas->iv_sofaCount = sofaNum;
if ( iv_sofaCount+1 > (int) iv_baseCas->iv_sofa2indexMap.size()) {
iv_baseCas->iv_sofa2indexMap.resize(sofaNum + 1);
iv_baseCas->iv_sofa2indexMap[sofaNum] = NULL;
}
}
return (*cit).second;
}
// Get the CAS View from sofaNum value
CAS* CAS::getViewBySofaNum(int sofaNum) {
CAS* aTcas;
map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
if (cit == iv_baseCas->iv_sofa2tcasMap.end()) {
aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas, getSofa(sofaNum));
assert ( EXISTS(aTcas) );
pair<int, CAS*> p1(sofaNum, aTcas);
iv_baseCas->iv_sofa2tcasMap.insert(p1);
return aTcas;
}
return (*cit).second;
}
CAS* CAS::getView(const icu::UnicodeString & localViewName) {
SofaID* sid;
bool deleteSofaID = false;
if (0 != iv_baseCas->iv_componentInfo) {
sid = const_cast<SofaID*> (&iv_baseCas->iv_componentInfo->mapToSofaID(localViewName));
} else {
sid = new SofaID();
deleteSofaID = true;
sid->setSofaId(localViewName);
}
// if this resolves to the Initial View, return view(1)...
// ... as the Sofa for this view may not exist yet
if (0==sid->getSofaId().compare(CAS::NAME_DEFAULT_SOFA)) {
if (deleteSofaID) {
delete sid;
}
return getInitialView();
}
SofaFS as = getSofa(sid->getSofaId());
if (!as.isValid()) {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_NOT_FOUND);
errMessage.addParam( sid->getSofaId());
UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
UIMA_ERR_RESOURCE_NOT_FOUND,
errMessage,
UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
ErrorInfo::unrecoverable
);
}
if (deleteSofaID) {
delete sid;
}
return getView(as);
}
CAS* CAS::createView(icu::UnicodeString const & localViewName) {
// map the input name
SofaID* sid;
bool deleteSofaID = false;
if (0 != iv_baseCas->iv_componentInfo) {
sid = const_cast<SofaID*> (&iv_baseCas->iv_componentInfo->mapToSofaID(localViewName));
} else {
sid = new SofaID();
sid->setSofaId(localViewName);
deleteSofaID = true;
}
// test if this is the reserved name
if ( 0 == sid->getSofaId().compare(UnicodeString(CAS::NAME_DEFAULT_SOFA)) ) {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_ALREADY_EXISTS);
errMessage.addParam( localViewName );
UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
UIMA_ERR_DUPLICATE_EXISTS,
errMessage,
UIMA_MSG_ID_EXCON_CREATING_FS,
ErrorInfo::unrecoverable
);
}
SofaFS newSofa = createSofa(sid->getSofaId(), UnicodeStringRef());
if (deleteSofaID) {
delete sid;
}
return getView(newSofa);
}
UnicodeStringRef CAS::getViewName() {
SofaFS thisSofa = getSofa();
if (thisSofa.isValid()) {
return getSofa().getSofaID();
}
return UnicodeStringRef();
}
void CAS::invalidBaseCasMethod() {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
UIMA_ERR_INVALID_BASE_CAS_METHOD,
errMessage,
UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
ErrorInfo::unrecoverable
);
}
// deprecated version
void CAS::setDocumentText(UChar const * cpDocument, size_t uiLength, bool bCopyToCAS ) {
if (cpDocument == NULL) {
assert( uiLength == 0 );
}
if (bCopyToCAS && ( cpDocument != NULL ) ) {
copyDocumentString(UnicodeStringRef(cpDocument, uiLength));
} else {
iv_cpDocument = cpDocument;
iv_uiDocumentLength = uiLength;
}
SofaFS thisSofa = getSofa();
if (!thisSofa.isValid()) {
thisSofa = createInitialSofa(UnicodeStringRef("text"));
}
thisSofa.setLocalSofaData(UnicodeStringRef(iv_cpDocument, iv_uiDocumentLength));
}
void CAS::setDocumentText(UnicodeStringRef const text) {
if (isbaseCas) {
invalidBaseCasMethod();
}
SofaFS thisSofa = getSofa();
if (!thisSofa.isValid()) {
thisSofa = createInitialSofa(UnicodeStringRef("text"));
}
copyDocumentString(text);
thisSofa.setLocalSofaData(text);
}
// internal use only
void CAS::setDocTextFromDeserializtion(UnicodeStringRef text) {
copyDocumentString(text);
SofaFS thisSofa = getSofa();
assert( thisSofa.isValid() );
thisSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature,
getHeap()->getTypeSystem()), text);
}
void CAS::setSofaDataString(UnicodeStringRef const text, icu::UnicodeString const & mimetype) {
if (isbaseCas) {
invalidBaseCasMethod();
}
SofaFS thisSofa = getSofa();
if (!thisSofa.isValid()) {
thisSofa = createInitialSofa(mimetype);
}
setDocumentText(text);
}
UnicodeStringRef CAS::getDocumentText()const {
if (isbaseCas) {
return UnicodeStringRef();
}
return UnicodeStringRef(iv_cpDocument, iv_uiDocumentLength);
}
void CAS::createDocumentAnnotation() {
if (!isbaseCas) {
assert( EXISTS(iv_heap) );
if (iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS) {
iv_tyDocumentAnnotation = iv_heap->createFS( iv_utDocumentType );
uima::lowlevel::TypeSystem const & ts = iv_heap->getTypeSystem();
Language lang;
int iLangID = (int) lang.asNumber();
uima::lowlevel::TyFSFeature langFeat = ts.getFeatureByFullName(CAS::FEATURE_FULL_NAME_LANGUAGE);
assert( ts.isValidFeature(langFeat) );
int ref = iv_heap->addString( lang.asUnicodeString() );
iv_heap->setStringValue( iv_tyDocumentAnnotation, langFeat, ref);
iv_heap->setFSValue(iv_tyDocumentAnnotation, internal::gs_tySofaRefFeature,
internal::FSPromoter::demoteFS(getSofa()));
}
assert( iv_heap->isValid( iv_tyDocumentAnnotation ) );
assert( iv_heap->resides( iv_tyDocumentAnnotation ) );
}
}
DocumentFS const CAS::getDocumentAnnotation() const {
if (isbaseCas || iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
return DocumentFS();
}
return(DocumentFS)uima::internal::FSPromoter::promoteFS(iv_tyDocumentAnnotation, *this);
}
DocumentFS CAS::getDocumentAnnotation() {
if (isbaseCas) {
assertWithMsg(false, "no DocumentAnnotation in Base CAS!");
return DocumentFS();
}
if ( iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
createDocumentAnnotation();
}
return(DocumentFS)uima::internal::FSPromoter::promoteFS(iv_tyDocumentAnnotation, *this);
}
AnnotationFS CAS::createAnnotation( Type const & type, size_t uiBegin, size_t uiEnd) {
if (isbaseCas) {
assertWithMsg(false, "Cannot create an Annotation in the Base CAS!");
return AnnotationFS();
}
assert(EXISTS(iv_heap));
assert( getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION).subsumes(type) );
if (!type.isValid()) {
UIMA_EXC_THROW_NEW(InvalidFSTypeObjectException,
UIMA_ERR_INVALID_FSTYPE_OBJECT,
UIMA_MSG_ID_EXC_INVALID_FSTYPE_OBJECT,
ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_FS),
ErrorInfo::recoverable );
}
lowlevel::TyFS tyAn = iv_heap->createFS(internal::FSPromoter::demoteType(type));
iv_heap->setFSValue(tyAn, internal::gs_tySofaRefFeature,
internal::FSPromoter::demoteFS(this->getSofa()));
iv_heap->setIntValue(tyAn, internal::gs_tyBeginPosFeature, (int)uiBegin );
iv_heap->setIntValue(tyAn, internal::gs_tyEndPosFeature, (int)uiEnd );
return(AnnotationFS)internal::FSPromoter::promoteFS(tyAn, *this);
}
ANIndex const CAS::getAnnotationIndex(Type const & crType) const {
if (isbaseCas) {
assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
return ANIndex();
}
try {
return(ANIndex)getIndexRepository().getIndex(CAS::INDEXID_ANNOTATION, crType);
} catch ( InvalidIndexIDException & ) {
assertWithMsg(false, "Annotation Index does not exist!");
return ANIndex();
} catch ( WrongFSTypeForIndexException & ) {
assertWithMsg(false, "Annotation Index exists with wrong type!");
return ANIndex();
}
}
ANIndex CAS::getAnnotationIndex(Type const & crType) {
if (isbaseCas) {
assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
return ANIndex();
}
return((CAS const *) this)->getAnnotationIndex(crType);
}
ANIndex CAS::getAnnotationIndex() {
if (isbaseCas) {
assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
return ANIndex();
}
return getAnnotationIndex(iv_heap->getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION));
}
void CAS::setSofaDataArray(FeatureStructure array, icu::UnicodeString const & mime) {
if (isbaseCas) {
invalidBaseCasMethod();
}
SofaFS thisSofa = getSofa();
if (!thisSofa.isValid()) {
thisSofa = createInitialSofa(mime);
}
getSofa().setLocalSofaData(array);
}
FeatureStructure CAS::getSofaDataArray() {
if (isbaseCas) {
assertWithMsg(false, "no Sofa data in Base CAS!");
return FeatureStructure();
}
return getSofa().getLocalFSData();
}
void CAS::setSofaDataURI(icu::UnicodeString const & uri, icu::UnicodeString const & mime) {
if (isbaseCas) {
invalidBaseCasMethod();
}
if (!getSofa().isValid()) {
createInitialSofa(mime);
}
getSofa().setRemoteSofaURI(uri);
}
UnicodeStringRef CAS::getSofaDataURI() {
if (isbaseCas) {
assertWithMsg(false, "no Sofa data in Base CAS!");
return UnicodeStringRef();
}
return getSofa().getSofaURI();
}
SofaDataStream * CAS::getSofaDataStream() {
if (isbaseCas) {
invalidBaseCasMethod();
}
return getSofa().getSofaDataStream();
}
bool CAS::moveToBeginPosition (ANIterator & itOfType, AnnotationFS const & crFsFromAn) {
/* Find begin position of annotation crToFS */
size_t uiBegPosFromAn = crFsFromAn.getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tyBeginPosFeature, iv_heap->getTypeSystem() ));
/* Iterate to the begin position of our given annotation crToFS */
bool bPosIsValid;
size_t uiBegPosOfType;
itOfType.moveToFirst();
while (itOfType.get().isValid()) {
uiBegPosOfType = itOfType.get().getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tyBeginPosFeature, iv_heap->getTypeSystem() ));
if (uiBegPosOfType == uiBegPosFromAn) {
return bPosIsValid = true;
}
itOfType.moveToNext();
if (uiBegPosOfType > uiBegPosFromAn)
return bPosIsValid = false;
}
return bPosIsValid = false;
}
// Drop View from sofaMap
void CAS::dropView(int sofaNum) {
map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
if (cit != iv_baseCas->iv_sofa2tcasMap.end()) {
iv_baseCas->iv_sofa2tcasMap.erase(cit);
}
}
/////////////////////////////////////////////////////////////////////////////
// Sofa utilities
/*
public FSIndexRepositoryImpl getSofaIndexRepository(SofaFS aSofa) {
return (FSIndexRepositoryImpl) sofa2indexMap.get(aSofa);
}
public void setSofaIndexRepository(SofaFS aSofa, FSIndexRepositoryImpl index) {
sofa2indexMap.put(aSofa, index);
}
*/
SofaFS CAS::createLocalSofa(const char* sofaName, const char* mimeType) {
UnicodeString const uName(sofaName, strlen(sofaName), "utf8");
UnicodeString const uMime(mimeType, strlen(mimeType), "utf8");
return createSofa(uName, uMime);
}
SofaFS CAS::createSofa(const SofaID & sofaName, const char* mimeType) {
UnicodeString const uMime(mimeType, strlen(mimeType), "utf8");
return createSofa(sofaName.getSofaId(), uMime);
}
SofaFS CAS::createSofa(UnicodeStringRef const sofaName, UnicodeStringRef const mimeType) {
assert(EXISTS(iv_heap));
if (iv_baseCas->getSofa(sofaName).isValid()) {
ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_ALREADY_EXISTS);
errMessage.addParam( sofaName );
UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
UIMA_ERR_DUPLICATE_EXISTS,
errMessage,
UIMA_MSG_ID_EXCON_CREATING_FS,
ErrorInfo::unrecoverable
);
}
Type sofaT = getTypeSystem().getType(CAS::TYPE_NAME_SOFA);
lowlevel::TyFS tySofa = iv_heap->createFS(internal::FSPromoter::demoteType(sofaT));
SofaFS newSofa = (SofaFS)internal::FSPromoter::promoteFS(tySofa, *this->iv_baseCas);
bumpSofaCount();
newSofa.setIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_heap->getTypeSystem()), iv_baseCas->iv_sofaCount);
newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_heap->getTypeSystem()), sofaName);
if (mimeType.length() > 0) {
newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_heap->getTypeSystem()), mimeType);
}
iv_baseCas->iv_indexRepository->add(tySofa);
return newSofa;
}
SofaFS CAS::getSofa() {
if (iv_sofaNum > 0) {
return getSofa(iv_sofaNum);
}
return SofaFS(FeatureStructure());
}
SofaFS CAS::getSofa(const SofaID & sofaName) {
return getSofa(sofaName.getSofaId());
}
SofaFS CAS::getSofa(char* sofaName) {
UnicodeString const uName(sofaName, strlen(sofaName), "utf8");
return getSofa(uName);
}
SofaFS CAS::getSofa(UnicodeStringRef sofaName) {
FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
FSIterator fsIt = fsIdx.iterator();
while (fsIt.isValid()) {
Feature idFeat =
getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFAID);
UnicodeStringRef sofaID = fsIt.get().getStringValue(idFeat);
if (0 == sofaName.compare(sofaID)) {
return (SofaFS) fsIt.get();
}
fsIt.moveToNext();
}
//HOW TO FAIL HERE? Currently returning an INVALID_FS
return (SofaFS) FeatureStructure();
}
FSIterator CAS::getSofaIterator() {
FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
return fsIdx.iterator();
}
SofaFS CAS::getSofa(int sofaNum) {
FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
FSIterator fsIt = fsIdx.iterator();
while (fsIt.isValid()) {
Feature numFeat =
getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFANUM);
if (sofaNum == fsIt.get().getIntValue(numFeat)) {
return (SofaFS) fsIt.get();
}
fsIt.moveToNext();
}
//HOW TO FAIL HERE? Currently returning an INVALID_FS
return (SofaFS) FeatureStructure();
}
uima::lowlevel::IndexRepository * CAS::getIndexRepositoryForSofa(SofaFS sofa) {
return iv_baseCas->iv_sofa2indexMap[iv_heap->getIntValue(internal::FSPromoter::demoteFS(sofa),
internal::gs_tySofaNumFeature)];
}
// Record a new sofaFS and reserve space in the index map if necessary
void CAS::bumpSofaCount() {
iv_baseCas->iv_sofaCount++;
if ( (iv_baseCas->iv_sofaCount+1) > (int)iv_baseCas->iv_sofa2indexMap.size()) {
// enlarge map and set new entry to NULL
iv_baseCas->iv_sofa2indexMap.resize(iv_baseCas->iv_sofaCount + 1);
iv_baseCas->iv_sofa2indexMap[iv_baseCas->iv_sofaCount] = NULL;
}
}
void CAS::registerView(SofaFS aSofa ) {
lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(aSofa);
iv_sofaNum = iv_heap->getIntValue(tySofa, internal::gs_tySofaNumFeature);
}
void CAS::updateDocumentAnnotation( ) {
SofaFS thisSofa = getSofa();
if (thisSofa.isValid()) {
lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(thisSofa);
UnicodeStringRef pDoc = iv_heap->getStringValue(tySofa, internal::gs_tySofaStringFeature);
if (pDoc.length() > 0) {
copyDocumentString(pDoc);
getDocumentAnnotation(); // create DocumentAnnotation if necessary
iv_heap->setIntValue( iv_tyDocumentAnnotation, uima::internal::gs_tyEndPosFeature,
(int) iv_uiDocumentLength);
// re-index the annotation
iv_indexRepository->remove(iv_tyDocumentAnnotation);
iv_indexRepository->add(iv_tyDocumentAnnotation);
}
}
}
void CAS::pickupDocumentAnnotation( ) {
// called from CAS binary deserialization
ANIndex ai = getAnnotationIndex(iv_heap->getTypeSystem().
getType(CAS::TYPE_NAME_DOCUMENT_ANNOTATION));
ANIterator ait = ai.iterator();
// Not valid if a non-text or remote sofa
if ( ! ait.isValid() ) {
return;
}
iv_tyDocumentAnnotation = internal::FSPromoter::demoteFS(ait.get());
iv_uiDocumentLength = ait.get().getEndPosition();
uima::lowlevel::TyFS sofaAddr = iv_heap->getFSValue(iv_tyDocumentAnnotation, internal::gs_tySofaRefFeature);
UnicodeStringRef pDoc = iv_heap->getStringValue(sofaAddr, internal::gs_tySofaStringFeature);
copyDocumentString(pDoc);
}
// void CAS::updateAndIndexDocumentAnnotation() {
// assert( EXISTS(iv_heap) );
// if( iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
// createDocumentAnnotation();
// }
// assert( iv_heap->resides( iv_tyDocumentAnnotation ) );
// assert( EXISTS( iv_indexRepository ) );
// iv_indexRepository->remove(iv_tyDocumentAnnotation);
// iv_heap->setIntValue( iv_tyDocumentAnnotation, uima::internal::gs_tyEndPosFeature,
// (int) iv_uiDocumentLength);
// iv_heap->setIntValue(iv_tyDocumentAnnotation, uima::internal::gs_tySofaRefFeature,
// (int) this->getSofaNum() );
// iv_indexRepository->add(iv_tyDocumentAnnotation);
// }
void CAS::copyDocumentString(UnicodeStringRef pDoc) {
// must have a 2nd copy of the document because the copy in the stringHeap will
// move when the stringHeap grows, unlike the older segmented heap.
if (pDoc.length() == 0) {
return;
}
if (iv_copyOfDocument)
delete [] iv_copyOfDocument;
size_t len = pDoc.length();
iv_copyOfDocument = new UChar [len + 1];
memcpy(iv_copyOfDocument, pDoc.getBuffer(), 2*len);
// The internal document must be 0 terminated!
iv_copyOfDocument[len] = 0;
iv_cpDocument = iv_copyOfDocument;
iv_uiDocumentLength = len;
}
void CAS::refreshCachedTypes() {
assert( EXISTS(iv_heap) );
iv_utDocumentType =
iv_heap->getTypeSystem().getTypeByName( uima::CAS::TYPE_NAME_DOCUMENT_ANNOTATION );
assert( iv_utDocumentType != uima::lowlevel::TypeSystem::INVALID_TYPE );
iv_utDocumentLangAsStrFeat =
iv_heap->getTypeSystem().getFeatureByBaseName( iv_utDocumentType,
uima::CAS::FEATURE_BASE_NAME_LANGUAGE );
assert( iv_utDocumentLangAsStrFeat != uima::lowlevel::TypeSystem::INVALID_FEATURE );
}
// True if CAS contains one Sofa with special name and without SofaURI or SofaFSData set
bool CAS::isBackwardCompatibleCas() {
if (iv_sofaCount != 1 || !isInitialSofaCreated())
return 0;
Feature idFeat =
getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFAID);
SofaFS initSofa = getSofa(1);
if (initSofa.getLocalFSData().isValid() ||
initSofa.getSofaURI().length() > 0 ) {
return 0;
}
UnicodeStringRef sofaID = getSofa(1).getStringValue(idFeat);
if ( 0 == initSofa.getSofaID().compare(NAME_DEFAULT_SOFA) ) {
return 1;
}
return 0;
}
void CAS::setCurrentComponentInfo(AnnotatorContext* info) {
// always store component info in base CAS
iv_baseCas->iv_componentInfo = info;
}
void CAS::registerInitialSofa() {
iv_baseCas->initialSofaCreated = true;
}
bool CAS::isInitialSofaCreated() {
return iv_baseCas->initialSofaCreated;
}
SofaFS CAS::createInitialSofa(UnicodeStringRef const mimeType) {
if (isInitialSofaCreated()) {
return getSofa(1);
}
Type sofaT = getTypeSystem().getType(CAS::TYPE_NAME_SOFA);
lowlevel::TyFS tySofa = iv_heap->createFS(internal::FSPromoter::demoteType(sofaT));
SofaFS newSofa = (SofaFS)internal::FSPromoter::promoteFS(tySofa, *this->iv_baseCas);
newSofa.setIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_heap->getTypeSystem()), 1);
newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_heap->getTypeSystem()), NAME_DEFAULT_SOFA);
newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_heap->getTypeSystem()), mimeType);
iv_baseCas->iv_indexRepository->add(tySofa);
registerInitialSofa();
return newSofa;
}
CAS* CAS::getInitialView() {
if (iv_baseCas->iv_initialView != 0) {
return iv_baseCas->iv_initialView;
}
// create the initial view, without a Sofa
CAS* aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas);
assert ( EXISTS(aTcas) );
pair<int, CAS*> p1(1, aTcas);
iv_baseCas->iv_sofa2tcasMap.insert(p1);
iv_baseCas->iv_sofaCount = 1;
iv_baseCas->iv_initialView = aTcas;
return aTcas;
}
FSIndexRepository & CAS::getBaseIndexRepository( void ) {
assert( EXISTS(iv_baseCas->iv_indexRepository) );
return *iv_baseCas->iv_indexRepository;
}
CAS & CAS::getCasForTyFS(lowlevel::TyHeapCell tyCell) {
lowlevel::TyFS type = getHeap()->getHeap().getHeapValue(tyCell);
if (type != uima::lowlevel::FSHeap::INVALID_FS &&
getHeap()->getTypeSystem().subsumes(internal::gs_tyAnnotationType,
internal::FSPromoter::demoteType(internal::FSPromoter::promoteFS(tyCell, *this).getType()))) {
// an annotation. Check that sofaNum agrees with current CAS
lowlevel::TyFS annSofaAddr = getHeap()->getFSValue(tyCell, internal::gs_tySofaRefFeature);
if ( annSofaAddr != internal::FSPromoter::demoteFS(getSofa())) {
// does not agree. Get appropriate View for annotation Sofa
int annSofaNum = getHeap()->getIntValue(annSofaAddr, internal::gs_tySofaNumFeature);
return *getViewBySofaNum(annSofaNum);
}
}
return *this;
}
/*****************************************************************************/
/* SofaFS */
/*****************************************************************************/
SofaFS::SofaFS(FeatureStructure const & fs)
: FeatureStructure(fs) {
assert(sizeof(FeatureStructure) == sizeof(SofaFS)); // no additonal data members
}
void SofaFS::setSofaMime(icu::UnicodeString const & aString) {
//TODO FAIL THIS IF MIME ALREADY SET ???
lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(*this);
this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_cas->getHeap()->getTypeSystem()), aString);
return;
}
void SofaFS::setLocalSofaData(FeatureStructure aFS) {
//TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(*this);
iv_cas->getHeap()->setFSValue(tySofa, internal::gs_tySofaArrayFeature,
internal::FSPromoter::demoteFS(aFS));
return;
}
void SofaFS::setLocalSofaData(UnicodeStringRef const aString) {
//TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature,
iv_cas->getHeap()->getTypeSystem()), aString);
int sofaNum = this->getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature,
iv_cas->getHeap()->getTypeSystem()));
iv_cas->getViewBySofaNum(sofaNum)->updateDocumentAnnotation();
return;
}
void SofaFS::setRemoteSofaURI(const char* aURI) {
UnicodeString const ucURI(aURI, strlen(aURI), "utf8");
return setRemoteSofaURI(ucURI);
}
void SofaFS::setRemoteSofaURI(icu::UnicodeString const & aString) {
//TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaURIFeature, iv_cas->getHeap()->getTypeSystem()), aString);
return;
}
UnicodeStringRef SofaFS::getSofaMime() {
return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_cas->getHeap()->getTypeSystem()));
}
UnicodeStringRef SofaFS::getSofaID() {
return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_cas->getHeap()->getTypeSystem()));
}
UnicodeStringRef SofaFS::getSofaURI() {
return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaURIFeature, iv_cas->getHeap()->getTypeSystem()));
}
int SofaFS::getSofaRef() {
return this->getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_cas->getHeap()->getTypeSystem()));
}
FeatureStructure SofaFS::getLocalFSData() {
return this->getFSValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaArrayFeature, iv_cas->getHeap()->getTypeSystem()));
}
UnicodeStringRef SofaFS::getLocalStringData() {
return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature, iv_cas->getHeap()->getTypeSystem()));
}
SofaDataStream * SofaFS::getSofaDataStream() {
Type type = getType();
Feature uriFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFAURI);
Feature stringFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFASTRING);
Feature arrayFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFAARRAY);
if ( !isUntouchedFSValue(uriFeat) ) { //remote sofa
return new RemoteSofaDataStream(*this);
} else if ( !isUntouchedFSValue(stringFeat) ) { //local sofa - data in string
return new LocalSofaDataStream(*this);
} else if ( !isUntouchedFSValue(arrayFeat) ) { //local sofa - data in fs array
return new LocalSofaDataStream(*this);
} else return NULL; //no sofa data set
}
SofaDataStream * SofaFS::getSofaDataStream(FeatureStructure & fs) {
return NULL;
}
/*****************************************************************************/
/* AnnotationFS */
/*****************************************************************************/
AnnotationFS::AnnotationFS(FeatureStructure const & fs)
: FeatureStructure(fs) {
assert(sizeof(FeatureStructure) == sizeof(AnnotationFS)); // no additonal data members
assert(EXISTS(iv_cas));
assert( iv_cas->getHeap()->getTypeSystem().subsumes(iv_cas->getHeap()->getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION),
iv_cas->getHeap()->getType(internal::FSPromoter::demoteFS(fs)) ) );
}
CAS & AnnotationFS::getCAS() {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FSTYPE);
assert(EXISTS(iv_cas));
return *iv_cas;
}
CAS const & AnnotationFS::getCAS() const {
checkValidity(UIMA_MSG_ID_EXCON_GETTING_FSTYPE);
assert(EXISTS(iv_cas));
return *iv_cas;
}
CAS * AnnotationFS::getView() {
assert(EXISTS(iv_cas));
lowlevel::TyFS annSofaAddr = iv_cas->getHeap()->getFSValue(iv_tyFS, internal::gs_tySofaRefFeature);
int annSofaNum = iv_cas->getHeap()->getIntValue(annSofaAddr, internal::gs_tySofaNumFeature);
return iv_cas->getViewBySofaNum(annSofaNum);
}
size_t AnnotationFS::getBeginPosition( void ) const {
assert(EXISTS(iv_cas));
assert(iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyBeginPosFeature) >= 0);
return(size_t)iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyBeginPosFeature);
}
size_t AnnotationFS::getEndPosition( void ) const {
assert(EXISTS(iv_cas));
assert(iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyEndPosFeature) >= 0);
return(size_t)iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyEndPosFeature);
}
UnicodeStringRef AnnotationFS::getCoveredText( void ) const {
if (isValid()) {
AnnotationFS* grr = const_cast<AnnotationFS*>(this);
CAS * myCas = grr->getView();
if (myCas->iv_uiDocumentLength > 0) {
assert( getEndPosition() <= myCas->iv_uiDocumentLength );
size_t uiBegin = getBeginPosition();
UChar const * puc = myCas->iv_cpDocument;
puc += uiBegin;
return UnicodeStringRef( puc, getEndPosition()-uiBegin );
}
}
UIMA_EXC_THROW_NEW(InvalidFSObjectException,
UIMA_ERR_INVALID_FS_OBJECT,
UIMA_MSG_ID_EXC_INVALID_FS_OBJECT,
ErrorMessage(UIMA_MSG_ID_EXCON_GETTING_FEATURE_VALUE),
ErrorInfo::recoverable
);
}
AnnotationFS AnnotationFS::getFirstCoveringAnnotation( Type ofType ) const {
if (!(isValid() && ofType.isValid())) {
return AnnotationFS(); //will be invalid
}
assert(EXISTS(iv_cas));
/* Let's create an Index of Type typeOfType */
ANIterator itOfType(getCAS().getAnnotationIndex(ofType).iterator());
/* Declare an object instance for the covering annotation we are looking for
If we find one, it will be initialized below, if we don't find one,
we return the invalid (because uninitialized) variable */
AnnotationFS fsCoveringAn;
size_t uiBegPosFrom = getBeginPosition();
size_t uiEndPosFrom = getEndPosition();
/* Iterate over all annotations in the ofTypeIdx */
AnnotationFS fsOfTypeAn;
for (itOfType.moveToFirst(); itOfType.isValid(); itOfType.moveToNext()) {
fsOfTypeAn = itOfType.get();
size_t uiBegPosOf = fsOfTypeAn.getBeginPosition();
size_t uiEndPosOf = fsOfTypeAn.getEndPosition();
if ((uiBegPosOf <= uiBegPosFrom ) &&
(uiEndPosOf >= uiEndPosFrom)) {
if (fsOfTypeAn.getType() != getType()) {
fsCoveringAn = fsOfTypeAn;
}
} else {
if (uiBegPosOf > uiBegPosFrom) {
return fsCoveringAn; //shortcut - avoids unecessary iteration
}
}
};
return fsCoveringAn;
}
ANIterator AnnotationFS::subIterator( Type const & crType, EnIteratorAmbiguity enAmbiguous ) const {
return getCAS().getAnnotationIndex(crType).subIterator(*this, enAmbiguous);
}
/*****************************************************************************/
/* DocumentFS */
/*****************************************************************************/
DocumentFS::DocumentFS(FeatureStructure const & fs)
: AnnotationFS(fs) {
assert( EXISTS(iv_cas) );
assert( iv_cas->getHeap()->getTypeSystem().subsumes(
iv_cas->getHeap()->getTypeSystem().getTypeByName(CAS::TYPE_NAME_DOCUMENT_ANNOTATION),
iv_cas->getHeap()->getType(internal::FSPromoter::demoteFS(fs)) ) );
}
Language DocumentFS::getLanguage() const {
assert(EXISTS(iv_cas));
assert( iv_cas->getHeap()->isValid(iv_tyFS) );
if ( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsIntFeat) ) {
int iLangID = iv_cas->getHeap()->getIntValue(iv_tyFS, getCAS().iv_utDocumentLangAsIntFeat);
if (iLangID != 0) {
return Language( iLangID );
}
}
assert( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsStrFeat) );
UnicodeStringRef ustrrefLang = iv_cas->getHeap()->getStringValue(iv_tyFS, getCAS().iv_utDocumentLangAsStrFeat);
return Language( ustrrefLang );
}
void DocumentFS::setLanguage(Language const & lang) {
assert(EXISTS(iv_cas));
assert( iv_cas->getHeap()->isValid(iv_tyFS) );
if ( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsIntFeat) ) {
iv_cas->getHeap()->setIntValue(iv_tyFS, getCAS().iv_utDocumentLangAsIntFeat, lang.asNumber());
}
assert( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsStrFeat) );
int ref = iv_cas->getHeap()->addString( lang.asUnicodeString() );
iv_cas->getHeap()->setStringValue(iv_tyFS, getCAS().iv_utDocumentLangAsStrFeat, ref);
}
/*****************************************************************************/
/* SubIterator */
/*****************************************************************************/
namespace lowlevel {
class SubIterator : public IndexIterator {
protected:
uima::lowlevel::FSHeap * iv_heap;
IndexIterator* iv_pIterator;
size_t iv_uiBegPos;
size_t iv_uiEndPos;
TyFS iv_tyMoveToFirstFS;
public:
SubIterator(uima::lowlevel::FSHeap & heap, size_t uiBeginPos, size_t uiEndPos, IndexIterator* pIterator):
iv_heap(&heap),
iv_pIterator(pIterator),
iv_uiBegPos(uiBeginPos),
iv_uiEndPos(uiEndPos),
iv_tyMoveToFirstFS(0) {
assert( EXISTS(iv_heap) );
TyFSType tyTAN = iv_heap->getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION);
// create the longest possible AN starting at uiBeginPos (must be first of all starting there)
iv_tyMoveToFirstFS = iv_heap->createFS(tyTAN);
iv_heap->setIntValue(iv_tyMoveToFirstFS, uima::internal::gs_tyBeginPosFeature, (int)iv_uiBegPos );
iv_heap->setIntValue(iv_tyMoveToFirstFS, uima::internal::gs_tyEndPosFeature, INT_MAX );
}
SubIterator(uima::lowlevel::FSHeap & heap, TyFS tyAn, IndexIterator* pIterator):
iv_heap(&heap),
iv_pIterator(pIterator),
iv_uiBegPos(iv_heap->getIntValue(tyAn, uima::internal::gs_tyBeginPosFeature)),
iv_uiEndPos(iv_heap->getIntValue(tyAn, uima::internal::gs_tyEndPosFeature)),
iv_tyMoveToFirstFS(tyAn) {}
virtual ~SubIterator() {
assert( EXISTS(iv_pIterator) );
assert( EXISTS(iv_heap) );
delete iv_pIterator;
}
void moveToFirst() {
UIMA_TPRINT("lowlevel::SubIterator::moveToFirst() entered");
assert( EXISTS(iv_pIterator) );
assert( EXISTS(iv_heap) );
iv_pIterator->moveTo( iv_tyMoveToFirstFS );
if (isValid()) {
if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
iv_pIterator->moveToNext();
}
}
}
void moveToNext() {
UIMA_TPRINT("lowlevel::SubIterator::moveToNext() entered");
assert( isValid() );
iv_pIterator->moveToNext();
if (isValid()) {
if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
iv_pIterator->moveToNext();
}
}
}
void moveToPrevious() {
assert( isValid() );
iv_pIterator->moveToPrevious();
if (isValid()) {
if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
iv_pIterator->moveToPrevious();
}
}
}
void moveToLast() {
UIMA_TPRINT("moveToLast() entered");
moveToFirst();
if (!isValid()) {
return;
}
assert( isValid() );
uima::lowlevel::TyFS lastValidFS = uima::lowlevel::FSHeap::INVALID_FS;
while (isValid()) {
lastValidFS = get();
moveToNext();
}
assert( ! isValid() );
assert(lastValidFS != uima::lowlevel::FSHeap::INVALID_FS);
moveTo(lastValidFS);
assert( isValid() );
if (isValid()) {
if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
iv_pIterator->moveToPrevious();
}
}
#ifdef DEBUG_VERBOSE
UIMA_TPRINT("last FS passed over: ");
iv_pFSSystem->getLowlevelFSHeap().printFS(cerr, lastValidFS);
UIMA_TPRINT("last FS: ");
iv_pFSSystem->getLowlevelFSHeap().printFS(cerr, get());
#endif
}
TyFS get() const {
assert( isValid() );
return iv_pIterator->get();
}
TyFSType getTyFSType() const {
assert( isValid() );
return iv_pIterator->getTyFSType();
}
bool isValid() const {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
if (!iv_pIterator->isValid()) {
return false;
}
TyFS fsCurrent = iv_pIterator->get();
size_t uiCurrBegPos = iv_heap->getIntValue(fsCurrent, uima::internal::gs_tyBeginPosFeature);
// true if current begin is between begin and end pos of our span
return(uiCurrBegPos >= iv_uiBegPos && uiCurrBegPos < iv_uiEndPos);
}
IndexIterator* clone() const {
UIMA_TPRINT("lowlevel::SubIterator::clone() entered");
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
// don't call 4-arg constructor here! Pass on the FS to be moved to
IndexIterator * pResult = new SubIterator(*iv_heap, iv_tyMoveToFirstFS, iv_pIterator->clone());
assert( EXISTS(pResult) );
assert( isValid() == pResult->isValid() );
#ifndef NDEBUG
if (isValid()) {
assert( get() == pResult->get() );
}
#endif
return pResult;
}
bool moveTo(TyFS fs) {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
return iv_pIterator->moveTo(fs);
}
}
; // class SubIterator
class UnAmbiguousSubIterator : public SubIterator {
private:
public:
UnAmbiguousSubIterator(uima::lowlevel::FSHeap & heap, size_t uiBeginPos, size_t uiEndPos, IndexIterator* pIterator):
SubIterator(heap, uiBeginPos, uiEndPos, pIterator) {}
UnAmbiguousSubIterator(uima::lowlevel::FSHeap & heap, TyFS tyAn, IndexIterator* pIterator):
SubIterator(heap, tyAn, pIterator) {}
void moveToNext() {
/*
assert( isValid() );
size_t uiLastEndPos = (size_t)iv_pFSSystem->getLowlevelFSHeap().getIntValue(SubIterator::get(), uima::internal::gs_tyEndPosFeature);
size_t uiCurrBeginPos;
do {
SubIterator::moveToNext();
if (!isValid()) {
return;
}
uiCurrBeginPos = iv_pFSSystem->getLowlevelFSHeap().getIntValue(SubIterator::get(), uima::internal::gs_tyBeginPosFeature);
} while (uiCurrBeginPos < uiLastEndPos);
*/
assert( EXISTS(iv_heap) );
assert( isValid() );
size_t uiLastEndPos = (size_t)iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyEndPosFeature);
size_t uiCurrBeginPos;
do {
iv_pIterator->moveToNext();
if (!isValid()) {
return;
}
uiCurrBeginPos = iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyBeginPosFeature);
} while (uiCurrBeginPos < uiLastEndPos);
}
IndexIterator* clone() const {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
return new UnAmbiguousSubIterator(*iv_heap, iv_tyMoveToFirstFS, iv_pIterator->clone());
}
}
; // class UnAmbiguousSubIterator
class UnambiguousIterator : public IndexIterator {
protected:
uima::lowlevel::FSHeap* iv_heap;
IndexIterator* iv_pIterator;
public:
UnambiguousIterator(uima::lowlevel::FSHeap & heap, IndexIterator* pIterator):
iv_heap(&heap),
iv_pIterator(pIterator) {
assert( EXISTS(iv_heap) );
}
virtual ~UnambiguousIterator() {
assert( EXISTS(iv_pIterator) );
assert( EXISTS(iv_heap) );
delete iv_pIterator;
}
void moveToFirst() {
assert( EXISTS(iv_pIterator) );
assert( EXISTS(iv_heap) );
iv_pIterator->moveToFirst();
}
void moveToNext() {
assert( isValid() );
size_t uiLastEndPos = (size_t)iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyEndPosFeature);
size_t uiCurrBeginPos;
do {
iv_pIterator->moveToNext();
if (!isValid()) {
return;
}
uiCurrBeginPos = iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyBeginPosFeature);
} while (uiCurrBeginPos < uiLastEndPos);
}
void moveToPrevious() {
assertWithMsg(false, "Not implemented yet!");
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
);
}
void moveToLast() {
assertWithMsg(false, "Not implemented yet!");
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
);
}
TyFS get() const {
assert( isValid() );
return iv_pIterator->get();
}
TyFSType getTyFSType() const {
assert( isValid() );
return iv_pIterator->getTyFSType();
}
bool isValid() const {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
if (!iv_pIterator->isValid()) {
return false;
}
return true;
}
IndexIterator* clone() const {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
return new UnambiguousIterator(*iv_heap, iv_pIterator->clone());
}
bool moveTo(TyFS fs) {
assert( EXISTS(iv_heap) );
assert( EXISTS(iv_pIterator) );
return iv_pIterator->moveTo(fs);
}
}
; // class UnambiguousIterator
} // namespace lowlevel
ANIterator ANIndex::subIterator( AnnotationFS const & an, EnIteratorAmbiguity enAmbiguous ) const {
checkValidity();
lowlevel::IndexIterator* pitBase = iv_pIndex->createIterator();
assert( EXISTS(pitBase) );
lowlevel::IndexIterator* pitSub;
if (enAmbiguous == enUnambiguous) {
pitSub = new lowlevel::UnAmbiguousSubIterator( iv_indexRepository->getFSHeap(), internal::FSPromoter::demoteFS(an), pitBase);
} else {
assert(enAmbiguous == enAmbiguous);
pitSub = new lowlevel::SubIterator(iv_indexRepository->getFSHeap(), internal::FSPromoter::demoteFS(an), pitBase);
}
assert( EXISTS(pitSub) );
return ANIterator(pitSub, &iv_indexRepository->getCas());
}
ANIterator ANIndex::unambiguousIterator() const {
checkValidity();
lowlevel::IndexIterator* pitBase = iv_pIndex->createIterator();
assert( EXISTS(pitBase) );
lowlevel::IndexIterator* pitSub;
pitSub = new lowlevel::UnambiguousIterator(iv_indexRepository->getFSHeap(), pitBase);
assert( EXISTS(pitSub) );
return ANIterator(pitSub, &iv_indexRepository->getCas());
}
}
/* ----------------------------------------------------------------------- */