in src/cas/xcasdeserializer_handler.cpp [331:507]
void XCASDeserializerHandler::readFS(lowlevel::TyFS addr, const Attributes & attrs, bool toIndex) {
// Hang on address for setting content feature
currentAddr = addr;
int id = -1;
// int sofaRef = -1; // 0 ==> baseCas indexRepository
vector<int>* sofaRef = new vector<int>;
icu::UnicodeString attrName;
icu::UnicodeString attrValue;
bool nameMapping = false;
UChar ubuff[256];
UErrorCode errorCode = U_ZERO_ERROR;
lowlevel::TyFS heapValue = iv_casimpl.getHeap().getType(addr);
// Special handling for Sofas
if (sofaTypeCode == heapValue) {
// create some maps to handle v1 format XCAS ...
// ... where the sofa feature of annotations was an int not a ref
// determine if this is the one and only initial view Sofa
bool isInitialView = false;
int extsz = icu::UnicodeString(CAS::FEATURE_BASE_NAME_SOFAID).extract(ubuff, 256, errorCode);
if (extsz > 256) {
cout << "ACK!" << endl;
}
const UChar* sofaID = attrs.getValue(ubuff);
if (0==UnicodeStringRef(sofaID).compare(icu::UnicodeString("_DefaultTextSofaName"))) {
sofaID = ubuff;
}
// no Sofa mapping for now
// if (iv_ctx != NULL) {
// // Map incoming SofaIDs
// sofaID = iv_ctx->mapToSofaID(sofaID).getSofaId();
// }
if (0==UnicodeStringRef(sofaID).compare(icu::UnicodeString(CAS::NAME_DEFAULT_SOFA))) {
isInitialView = true;
}
// get the sofaNum
extsz = icu::UnicodeString(CAS::FEATURE_BASE_NAME_SOFANUM).extract(ubuff, 256, errorCode);
if (extsz > 256) {
cout << "ACK!" << endl;
}
const UChar* aString = attrs.getValue(ubuff);
int thisSofaNum = atoi(UnicodeStringRef(aString).asUTF8().c_str());
// get the sofa's FeatureStructure id
icu::UnicodeString(ID_ATTR_NAME).extract(ubuff,256, errorCode);
aString = attrs.getValue(ubuff);
int sofaFsId = atoi(UnicodeStringRef(aString).asUTF8().c_str());
// for v1 and v2 formats, create the index map
// ***we assume Sofas are always received in Sofanum order***
// Two scenarios ... the initial view is the first sofa, or not.
// If not, the _indexed values need to be remapped to leave room for the initial view,
// which may or may not be in the received CAS.
if (indexMap.size() == 1) {
if (isInitialView) {
// the first Sofa an initial view
if (thisSofaNum == 2) {
// this sofa was mapped to the initial view
indexMap.push_back(-1); // for this CAS, there should not be a sofanum = 1
indexMap.push_back(1); // map 2 to 1
nextIndex = 2;
} else {
indexMap.push_back(1);
nextIndex = 2;
}
} else {
if (thisSofaNum > 1) {
// the first Sofa not initial, but sofaNum > 1
// must be a v2 format, and sofaNum better be 2
indexMap.push_back(1);
assert (thisSofaNum == 2);
indexMap.push_back(2);
nextIndex = 3;
} else {
// must be v1 format
indexMap.push_back(2);
nextIndex = 3;
}
}
} else {
// if the new Sofa is the initial view, always map to 1
if (isInitialView) {
// the initial view is not the first
// if v2 format, space already reserved in mapping
if (indexMap.size() == thisSofaNum) {
// v1 format, add mapping for initial view
indexMap.push_back(1);
}
} else {
indexMap.push_back(nextIndex);
nextIndex++;
}
}
// Now update the mapping from annotation int to ref values
if (sofaRefMap.size() == thisSofaNum) {
// Sofa received in sofaNum order, add new one
sofaRefMap.push_back(sofaFsId);
} else if ((int)sofaRefMap.size() > thisSofaNum) {
// new Sofa has lower sofaNum than last one
sofaRefMap[thisSofaNum] = sofaFsId;
} else {
// new Sofa has skipped ahead more than 1
sofaRefMap.resize(thisSofaNum + 1);
sofaRefMap[thisSofaNum] = sofaFsId;
}
}
Type type = uima::internal::FSPromoter::promoteType(heapValue, iv_cas->getTypeSystem().getLowlevelTypeSystem());
for (size_t i = 0; i < attrs.getLength(); i++) {
assertWithMsg( sizeof(XMLCh) == sizeof(UChar), "Port required!");
attrName = (UChar*)attrs.getQName(i);
attrValue = (UChar*)attrs.getValue(i);
if (attrName.startsWith("_")) {
if (attrName.compare(ID_ATTR_NAME) == 0) {
id = atoi(UnicodeStringRef(attrValue).asUTF8().c_str());
} else if (attrName.compare(CONTENT_ATTR_NAME) == 0) {
currentContentFeat = attrValue;
} else if (attrName.compare(INDEXED_ATTR_NAME)== 0) {
// if (toIndex)
// { // suppress indexing of document annotation if old CAS
// if (attrValue.compare(TRUE_VALUE) == 0)
// sofaRef = 1;
// else if (!attrValue.compare("false") == 0)
// sofaRef = atoi(uniStr2SingleByteStr(attrValue,"UTF-8").c_str());
// }
char indexes[256];
// we have a problem here if number of indexed views is ridiculously big
strcpy(indexes, UnicodeStringRef(attrValue).asUTF8().c_str());
char* ptr = strtok (indexes," ");
while (ptr != NULL) {
sofaRef->push_back(atoi(ptr));
ptr = strtok (NULL, " ");
}
} else {
handleFeature(type, addr, attrName, attrValue, false);
}
} else {
if (nameMapping && attrName.compare(CAS::FEATURE_BASE_NAME_SOFAID) == 0) {
if (iv_ctx != NULL) {
attrValue = iv_ctx->mapToSofaID(attrValue).getSofaId();
}
}
handleFeature(type, addr, attrName, attrValue, false);
}
}
if (sofaTypeCode == heapValue) {
// If a Sofa, create CAS view to get new indexRepository
SofaFS sofa = (SofaFS) uima::internal::FSPromoter::promoteFS(addr, *iv_cas);
//also add to indexes so we can retrieve the Sofa later
iv_cas->getBaseIndexRepository().addFS(sofa);
CAS * tcas = iv_cas->getView(sofa);
assert ( EXISTS(tcas) );
if (sofa.getSofaRef() == 1) {
iv_cas->registerInitialSofa();
} else {
// add indexRepo for views other than the initial view
lowlevel::IndexRepository * indexRep = iv_cas->getIndexRepositoryForSofa(sofa);
assert ( EXISTS(indexRep) );
indexRepositories.push_back(indexRep);
}
tcasInstances.push_back(tcas);
}
// sofaRef.size()==0 means not indexed
FSInfo * fsInfo = new FSInfo(addr, sofaRef);
if (id < 0) {
idLess.push_back(fsInfo);
} else {
fsTree[id] = fsInfo;
}
iv_state = CONTENT_STATE;
}