void XCASDeserializerHandler::readFS()

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;

  }