/** \file internal_casserializer.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                                              */
/* ----------------------------------------------------------------------- */

//#define DEBUG_VERBOSE
#include "uima/pragmas.hpp"

#include "uima/macros.h"
#include "uima/internal_casserializer.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/result_specification.hpp"
#include "uima/casdefinition.hpp"

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */

using namespace std;
namespace uima {
  namespace internal {


    void CASSerializer::serializeResultSpec(ResultSpecification const & resultSpec,
                                            vector<SerializedCAS::TyNum>& resultSpecTypes,
                                            vector<SerializedCAS::TyNum>& resultSpecFeatures) {
      ResultSpecification::TyTypeOrFeatureSTLSet const & tofSet = resultSpec.getTypeOrFeatureSTLSet();
      ResultSpecification::TyTypeOrFeatureSTLSet::const_iterator cit;
      for (cit = tofSet.begin(); cit != tofSet.end(); ++cit) {
        TypeOrFeature const & tof = *cit;
        if (tof.isType()) {
          Type t = tof.getType();
          assert( t.isValid() );
          resultSpecTypes.push_back( uima::internal::FSPromoter::demoteType(t) );
        } else {
          Feature f = tof.getFeature();
          assert( f.isValid() );
          resultSpecFeatures.push_back( uima::internal::FSPromoter::demoteFeature(f) );
        }
      }
    }


    bool isInterval(uima::lowlevel::TyFSType first, uima::lowlevel::TyFSType last, vector<uima::lowlevel::TyFSType> const & vec) {
      size_t i;
      for (i=0; i<vec.size(); ++i) {
        if (vec[i] != first + i) {
          return false;
        }
      }
      return true;
    }

    CASSerializer::CASSerializer(bool bCopyStrings)
        : iv_bCopyStrings(bCopyStrings) {}

    CASSerializer::~CASSerializer() {}

    UnicodeStringRef CASSerializer::createString(UChar const * cpBuf, size_t uiLen, uima::internal::SerializedCAS & rSerializedCAS) {
      UnicodeStringRef ref(cpBuf, uiLen);
      if (iv_bCopyStrings) {
        return rSerializedCAS.addString(ref);
      }
      return ref;
    }


    void CASSerializer::serializeTypeSystem(uima::internal::CASDefinition const & casDef, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::lowlevel::TypeSystem const & crTypeSystem = casDef.getTypeSystem();
      UnicodeStringRef invalidUSP(rSerializedCAS.iv_emptyString.getBuffer(), rSerializedCAS.iv_emptyString.length());
      assert( invalidUSP.getBuffer() != NULL );
      assert( invalidUSP.length() == 0);

      // 1. inheritance vector
      rSerializedCAS.iv_vecTypeInheritanceTable.clear();
      size_t uiTypeNum = crTypeSystem.getNumberOfTypes() + 1;
      rSerializedCAS.iv_vecTypeInheritanceTable.resize(uiTypeNum, 0);

#ifndef NDEBUG
      vector<uima::lowlevel::TyFSType> vecTypes;
      crTypeSystem.getAllTypes(vecTypes);
      assert( isInterval(1, uiTypeNum, vecTypes) );
      assert( uiTypeNum == vecTypes.size() + 1);
#endif

      size_t i;
      assert( 0 == uima::lowlevel::TypeSystem::INVALID_TYPE );
      assert( 1 == crTypeSystem.getTopType() );
      for (i=2; i<uiTypeNum; ++i) {
        uima::lowlevel::TyFSType tyChild = (uima::lowlevel::TyFSType) i;
        uima::lowlevel::TyFSType tyParent = crTypeSystem.getParentType( tyChild );
        assert( tyParent <rSerializedCAS.iv_vecTypeInheritanceTable.size() );
        rSerializedCAS.iv_vecTypeInheritanceTable[tyChild] =  tyParent;
      }

      // 2. feature intro vector
      rSerializedCAS.iv_vecFeatureDefinitionTable.clear();
      size_t uiFeatureNum = crTypeSystem.getNumberOfFeatures() + 1;

      // leave the first three cells empty
      rSerializedCAS.iv_vecFeatureDefinitionTable.resize(3,0);

#ifndef NDEBUG
      vector<uima::lowlevel::TyFSFeature> vecFeatures;
      crTypeSystem.getAllFeatures(vecFeatures);
      assert( isInterval(1, uiFeatureNum, vecFeatures) );
      assert( uiFeatureNum == vecFeatures.size() + 1);
#endif

      assert( 0 == uima::lowlevel::TypeSystem::INVALID_FEATURE );
      for (i=1; i<uiFeatureNum; ++i) {
        uima::lowlevel::TyFSFeature tyFeat = (uima::lowlevel::TyFSFeature) i;
        UIMA_TPRINT("Adding feature with ID: " << tyFeat );
        UIMA_TPRINT("Adding feature: " << crTypeSystem.getFeatureName(tyFeat) );
        uima::lowlevel::TyFSType tyIntroType = crTypeSystem.getIntroType(tyFeat);
        uima::lowlevel::TyFSType tyRangeType = crTypeSystem.getRangeType(tyFeat);
		int tyMultiRefs = crTypeSystem.isMultipleReferencesAllowed(tyFeat) ? 1 : 0;
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyIntroType );
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyRangeType );
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyMultiRefs );
      }

#ifndef NDEBUG
      for (i=1; i<vecFeatures.size(); ++i) {
        uima::lowlevel::TyFSFeature tyFeat = vecFeatures[i];
        uima::lowlevel::TyFSType tyIntroType = crTypeSystem.getIntroType(tyFeat);
        uima::lowlevel::TyFSType tyRangeType = crTypeSystem.getRangeType(tyFeat);
		int tyMultiRefs = crTypeSystem.isMultipleReferencesAllowed(tyFeat) ? 1 : 0;
        assert( (tyFeat*2) <rSerializedCAS.iv_vecFeatureDefinitionTable.size() );
        assert( (tyFeat*2+1) <rSerializedCAS.iv_vecFeatureDefinitionTable.size() );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3] == tyIntroType );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3+1] == tyRangeType );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3+2] == tyMultiRefs );
      }
#endif


      // 3. type string table
      rSerializedCAS.iv_vecTypeSymbolTable.resize(uiTypeNum);
      assert( rSerializedCAS.iv_vecTypeSymbolTable.size() == uiTypeNum );
      rSerializedCAS.iv_vecTypeSymbolTable[0] = invalidUSP;
      for (i=1; i<uiTypeNum; ++i) {
        icu::UnicodeString const & crTypeName = crTypeSystem.getTypeName(i);
        UnicodeStringRef pus = createString( crTypeName.getBuffer(), crTypeName.length(), rSerializedCAS);
        rSerializedCAS.iv_vecTypeSymbolTable[i] = pus;
      }

      // 4. feature string and feature offset table
      rSerializedCAS.iv_vecFeatureSymbolTable.resize(uiFeatureNum);
      assert( rSerializedCAS.iv_vecFeatureSymbolTable.size() == uiFeatureNum );
      rSerializedCAS.iv_vecFeatureOffsetTable.resize(uiFeatureNum);
      assert( rSerializedCAS.iv_vecFeatureOffsetTable.size() == uiFeatureNum );
      rSerializedCAS.iv_vecFeatureSymbolTable[0] = invalidUSP;
      rSerializedCAS.iv_vecFeatureOffsetTable[0] = 0;
      for (i=1; i<uiFeatureNum; ++i) {
        uima::lowlevel::TyFSFeature tyFeat = i;
        // string
        icu::UnicodeString const & crFeatureName = crTypeSystem.getFeatureBaseName(tyFeat);
        UnicodeStringRef pus = createString( crFeatureName.getBuffer(), crFeatureName.length(), rSerializedCAS);
        rSerializedCAS.iv_vecFeatureSymbolTable[i] = pus;

        // offset
        rSerializedCAS.iv_vecFeatureOffsetTable[i] = crTypeSystem.getFeatureOffset(tyFeat);
      }

      // 5. type priorities
      rSerializedCAS.iv_vecTypePriorityTable.resize(uiTypeNum-1);
      for (i=1; i<uiTypeNum; ++i) {
        size_t num = crTypeSystem.getTypePriorityNumber((uima::lowlevel::TyFSType) i);
        rSerializedCAS.iv_vecTypePriorityTable[num] = i;
      }

      // 6. string sub types
      vector<uima::lowlevel::TyFSType> stringSubTypes;
      crTypeSystem.getDirectSubTypes( uima::internal::gs_tyStringType,
                                      stringSubTypes );

      rSerializedCAS.iv_stringSubTypes.clear();
      for (i=0; i<stringSubTypes.size(); ++i) {
        rSerializedCAS.iv_stringSubTypes.push_back(stringSubTypes[i]);
      }
      rSerializedCAS.iv_stringSubTypeValues.clear();
      rSerializedCAS.iv_stringSubTypeValuePos.clear();
      for (i=0; i<rSerializedCAS.iv_stringSubTypes.size(); ++i) {
        size_t n = rSerializedCAS.iv_stringSubTypeValues.size();
        rSerializedCAS.iv_stringSubTypeValuePos.push_back(n);

        vector<icu::UnicodeString> const & stringValues = crTypeSystem.getStringsForStringSubtype(rSerializedCAS.iv_stringSubTypes[i]);
        size_t j;
        for (j=0; j<stringValues.size(); ++j) {
          UnicodeStringRef ref(stringValues[j]);
          rSerializedCAS.iv_stringSubTypeValues.push_back( ref );
        }
      }
      assert( rSerializedCAS.iv_stringSubTypes.size() == rSerializedCAS.iv_stringSubTypeValuePos.size() );
    }


#if defined( _MSC_VER )
// locally disable warning about conversion from 'uima::internal::SerializedCAS::TyNum' to 'const int', possible loss of data
#  pragma warning( disable: 4244 )
#endif
    void CASSerializer::serializeIndexDefinition(uima::internal::CASDefinition const & casdef, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::lowlevel::IndexDefinition const & indexDef = casdef.getIndexDefinition();

      vector<uima::lowlevel::IndexDefinition::TyIndexID> vecIndexIDs;

      indexDef.getAllIndexIDs(vecIndexIDs);
      size_t uiIndexNum = vecIndexIDs.size();
      rSerializedCAS.iv_vecIndexIDTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecComparatorStartTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecIndexKindTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecComparatorDefinitionTable.clear();

      size_t i;
      for (i=0; i<uiIndexNum; ++i) {
        uima::lowlevel::IndexDefinition::TyIndexID const & crIndexID = vecIndexIDs[i];
        rSerializedCAS.iv_vecIndexIDTable[i] = createString( crIndexID.getBuffer(),
                                               crIndexID.length(), rSerializedCAS);
        rSerializedCAS.iv_vecIndexKindTable[i] = indexDef.getIndexKind( crIndexID );
        UIMA_TPRINT("Index ID: " << crIndexID );
        // start of the next comparator definition
        // is at the end of rSerializedCAS.iv_vecComparatorDefinitionTable
        rSerializedCAS.iv_vecComparatorStartTable[i] = rSerializedCAS.iv_vecComparatorDefinitionTable.size();

        // add type of the index
        uima::lowlevel::TyFSType indexType = indexDef.getTypeForIndex(crIndexID);
        // add type of the comparator (even if the index has none)
        rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( indexType );

        uima::lowlevel::IndexComparator const * pComparator = indexDef.getComparator( crIndexID );
        if ( pComparator != NULL ) {
          UIMA_TPRINT(" Index has comparator!");
          assert( pComparator->getType() == indexType );
          // serialize comparator
          vector<uima::lowlevel::TyFSFeature> const & crKeyFeatures = pComparator->getKeyFeatures();
          vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> const & crCompOps = pComparator->getComparisonOps();
          assert( crKeyFeatures.size() == crCompOps.size() );
          // add all key features
          size_t j;
          for (j=0; j<crKeyFeatures.size(); ++j) {
            rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( (SerializedCAS::TyNum) crKeyFeatures[j] );
            rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( (SerializedCAS::TyNum) crCompOps[j] );
          }
        }
      }
    }

#ifdef BYEBYEPTRS
    SerializedCAS::TyNum CASSerializer::adjustString(uima::lowlevel::TyHeapCell tyFeatureCell,
        TyStringMap & stringMap,
        uima::internal::SerializedCAS & rSerializedCAS) {
      UIMA_TPRINT("adjustString() entered");
      UChar* * pPointerStringRefHeap = (UChar * *) tyFeatureCell;
      UChar * puc = *pPointerStringRefHeap;
      if (puc == NULL) {
        return 0;
      }
      assert( puc != NULL);
      assert( EXISTS(puc) );
      assert( EXISTS(pPointerStringRefHeap+1) );

      SerializedCAS::TyNum iStrLen = (SerializedCAS::TyNum) * (pPointerStringRefHeap+1);

      ptrdiff_t iStringIndex = 0;

      // try to find the string
      TyStringMap::iterator it = stringMap.lower_bound( puc );
      // if not found
      if (  (it == stringMap.end()) || ( (*it).first != puc ) ) {
        iStringIndex = stringMap.size() + 1;
        // insert new one
        TyStringMap::value_type vt(puc, iStringIndex);
        stringMap.insert(it, vt);
        UIMA_TPRINT("  iStringIndex: " << iStringIndex << ", StringSymblTableSize: " << rSerializedCAS.iv_vecStringSymbolTable.size());
        assert( iStringIndex == rSerializedCAS.iv_vecStringSymbolTable.size() );
        UnicodeStringRef ustrp = createString(puc, iStrLen, rSerializedCAS);
        rSerializedCAS.iv_vecStringSymbolTable.push_back(ustrp);
      } else {
        iStringIndex = (*it).second;
      }

      return iStringIndex;
    }
#endif

    void CASSerializer::serializeFSHeapAndStringHeap(uima::CAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;

      // copy the FSHeap as is (all offsets and values)
      size_t uiSegmentLength = tyTempHeap.getTopOfHeap();
      uima::lowlevel::TyHeapCell* daHeap = tyTempHeap.getHeapStart();
      rSerializedCAS.iv_vecFSHeapArray.resize(uiSegmentLength);
      // copy the heap (better way to do this?)
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecFSHeapArray[i] = daHeap[i];
      }

      // fill the vector of strings from the StringRefHeap
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      int uiStringRefLength = tyStringRefHeap.getTopOfHeap();
      int j = 1; // point at the first entry
      rSerializedCAS.iv_vecStringSymbolTable.resize(1);
      while (j < uiStringRefLength) {
        UnicodeStringRef ustrp = UnicodeStringRef( tyStringHeap.getHeapStart()+
                                 tyStringRefHeap.getHeapValue(j),
                                 (size_t) tyStringRefHeap.getHeapValue(j+1));
        rSerializedCAS.iv_vecStringSymbolTable.push_back(ustrp);
        j += 2;
      }
    }



    void CASSerializer::serializeHeaps(uima::CAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {

      //serialize the fs heap and string heap
      serializeFSHeapAndStringHeap(crCAS, rSerializedCAS);

      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();

      //8 bit heap
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      size_t uiSegmentLength = ty8BitHeap.getTopOfHeap();
      char* byteHeap = ty8BitHeap.getHeapStart();
      rSerializedCAS.iv_vecByteHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecByteHeapArray[i] = byteHeap[i];
      }

      //16 bit heap
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uiSegmentLength = ty16BitHeap.getTopOfHeap();
      short* shortHeap = ty16BitHeap.getHeapStart();
      rSerializedCAS.iv_vecShortHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecShortHeapArray[i] = shortHeap[i];
      }

      //64 bit heap
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;
      uiSegmentLength = ty64BitHeap.getTopOfHeap();
      INT64* longHeap = ty64BitHeap.getHeapStart();
      rSerializedCAS.iv_vecLongHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecLongHeapArray[i] = longHeap[i];
      }



    }






    //---------------------------------------------------------------------
    // Indexed FS Format
    //
    // Element Size     Number of     Description
    //   (bytes)        Elements
    // ------------     ---------     --------------------------------
    //      4               1         Number of Views in this CAS
    //      4               1         Number of Sofas in base Index Repository = nBase
    //      4             nBase       TyFS array
    //
    //   For each View:
    //      4               1         Number of FS in sofa Index Repository = nFS
    //      4             nFS         TyFS array
    //
    //---------------------------------------------------------------------


    void CASSerializer::serializeIndexedFSs(uima::CAS & crCAS,
                                            vector<uima::internal::SerializedCAS::TyNum> & iv_vecIndexedFSs) {

      uima::internal::CASImpl & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);

      int numViews = crCAS.getBaseCas()->iv_sofaCount;
      iv_vecIndexedFSs.clear();
      iv_vecIndexedFSs.push_back(numViews);

      uima::lowlevel::IndexRepository * crIndexRep =
        (uima::lowlevel::IndexRepository*)&crCASImpl.getBaseIndexRepository();

      for (int view=0; view<=numViews; view++) {
        vector<SerializedCAS::TyNum> perLoopIndexedFSs;
        vector<uima::lowlevel::TyFSType> vecAllTypes;
        perLoopIndexedFSs.clear();
        if (view==0) {
          // First time through is for base CAS index
          // FS returned should only be for SofaFS!
          crIndexRep->getUsedIndexes(vecAllTypes);
        } else {
          // for all views found in the CAS, get new IndexRepository
          crIndexRep = crCASImpl.iv_baseCas->iv_sofa2indexMap[view];
          if (crIndexRep == 0) {
            // no indexed FS for this View, move on
            iv_vecIndexedFSs.push_back(0);
            continue;
          }
          crIndexRep->getUsedIndexes(vecAllTypes);

          //serialize the undefined index FSs
          for (size_t i=0;i < crIndexRep->iv_undefinedindex.size(); i++ ) {
            SerializedCAS::TyNum tyFSHeapIndex = (SerializedCAS::TyNum) crIndexRep->iv_undefinedindex[i];
            perLoopIndexedFSs.push_back(tyFSHeapIndex);
          }
        }

        // serialize index per type
        if ( 0 == vecAllTypes.size() && 0 == perLoopIndexedFSs.size() ) {
          // no indexed FS for this View, move on
          iv_vecIndexedFSs.push_back(0);
          continue;
        }
        for (size_t i=0; i<vecAllTypes.size(); ++i) {
          vector<uima::lowlevel::internal::SingleIndex*> const & crSingleIndexes =
            crIndexRep->getAllSingleIndexesForType(vecAllTypes[i]);
          for (size_t j=0; j<crSingleIndexes.size(); ++j) {
            unique_ptr<uima::lowlevel::IndexIterator> apIt(crSingleIndexes[j]->createIterator());
            for (apIt->moveToFirst(); apIt->isValid(); apIt->moveToNext()) {
              uima::lowlevel::TyHeapCell pHeapCell = (uima::lowlevel::TyHeapCell) apIt->get();
              SerializedCAS::TyNum tyFSHeapIndex =  (SerializedCAS::TyNum) pHeapCell;
              perLoopIndexedFSs.push_back( tyFSHeapIndex );
            }
          }
        }

        // eliminate duplicates
        sort(perLoopIndexedFSs.begin(), perLoopIndexedFSs.end());
        vector<SerializedCAS::TyNum>::iterator end = unique(perLoopIndexedFSs.begin(), perLoopIndexedFSs.end());
        // append indexedFSs from this loop
        iv_vecIndexedFSs.push_back(end - perLoopIndexedFSs.begin());
        iv_vecIndexedFSs.insert(iv_vecIndexedFSs.end(),
                                perLoopIndexedFSs.begin(),
                                end);
      }
    }


    /* no more document in de CAS
          void CASSerializer::serializeDocument(uima::TCAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
             uima::internal::TCASImpl const & crTCASImpl = uima::internal::TCASImpl::promoteCAS(crCAS);
             rSerializedCAS.iv_ulstrDocument = crTCASImpl.getDocumentText();
          }
    */

    void CASSerializer::serializeDefinitions(uima::internal::CASDefinition const & casDef, uima::internal::SerializedCAS & rSerializedCAS) {
      serializeTypeSystem(casDef, rSerializedCAS);
      serializeIndexDefinition(casDef, rSerializedCAS);
    }


#ifdef UIMA_ENABLE_SERIALIZATION_TIMING
#define UIMA_SERIALIZATION_TIMING(x) x
#else
#define UIMA_SERIALIZATION_TIMING(x)
#endif

    void CASSerializer::serializeData(uima::CAS & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
//         serializeDocument(crCAS, rSerializedCAS);
      // serialize indexed FSs first so that the docAnnot can be created if necessary
      UIMA_TPRINT("Serializing indexed FSs");
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.start() );
      serializeIndexedFSs(*crCAS.getBaseCas(), rSerializedCAS.iv_vecIndexedFSs);
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.stop() );
      UIMA_TPRINT("indexed FSs serialized");

      UIMA_TPRINT("serializing all heaps");
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.start() );
      //serializeFSHeapAndStringHeap(*crCAS.getBaseCas(), rSerializedCAS);
      serializeHeaps(*crCAS.getBaseCas(), rSerializedCAS);
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.stop() );
      UIMA_TPRINT("FS heap serialized");
    }

    //---------------------------------------------------------------------
    // Blob Format
    //
    // Element Size     Number of     Description
    //   (bytes)        Elements
    // ------------     ---------     --------------------------------
    //      4               1         Blob key = "UIMA" in utf-8
    //      4               1         Version (currently = 1)
    //      4               1         size of 32-bit FS Heap array = s32H
    //      4             s32H        32-bit FS heap array
    //      4               1         size of 16-bit string Heap array = sSH
    //      2              sSH        16-bit string heap array
    //      4               1         size of string Ref Heap array = sSRH
    //      4             2*sSRH      string ref offsets and lengths
    //      4               1         size of FS index array = sFSI
    //      4             sFSI        FS index array
    //      4               1         size of 8-bit Heap array = s8H
    //      1              s8H        8-bit Heap array
    //      4               1         size of 16-bit Heap array = s16H
    //      2             s16H        16-bit Heap array
    //      4               1         size of 64-bit Heap array = s64H
    //      8             s64H        64-bit Heap array
    //---------------------------------------------------------------------


    // estimate total size of serialized CAS data
    size_t CASSerializer::getBlobSize(uima::CAS & crCAS) {

      // create STL vector of indexed FS so that we can size the output
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.start() );
      serializeIndexedFSs(*crCAS.getBaseCas(), iv_vecIndexedFSs);
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.stop() );

      // get a heap of references
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;

      size_t uiFSHeapLength = tyTempHeap.getTopOfHeap();
      size_t uiStringHeapLength = tyStringHeap.getTopOfHeap();
      size_t uialignedStrLen = 2 * ((uiStringHeapLength + 1)/2);
      size_t uiRefHeapLength = tyStringRefHeap.getTopOfHeap();
      size_t uiIndexedFSLength = iv_vecIndexedFSs.size();
      size_t ui8BitHeapLength = ty8BitHeap.getTopOfHeap();
      size_t uialigned8BitHeapLength = 4 * ((ui8BitHeapLength+3)/4);
      size_t ui16BitHeapLength = ty16BitHeap.getTopOfHeap();
      size_t uialigned16BitHeapLength = 2 * ((ui16BitHeapLength+1)/2);
      size_t ui64BitHeapLength = ty64BitHeap.getTopOfHeap();



      size_t blobSize = 2*4               // key and version
                        + (1 + uiFSHeapLength) * 4        // FSHeap length and data
                        + 1*4 + (uialignedStrLen * 2)  // StringHeap length and data
                        + (1 + uiRefHeapLength) * 4     // StringRefheap length and data
                        + (1 + uiIndexedFSLength) * 4    // Indexed FS length and data
                        + (1*4 + uialigned8BitHeapLength)  // 8 Bit Heap length and data
                        + (1*4 + uialigned16BitHeapLength*2 ) //16 Bit Heap length and data
                        + (1*4 + ui64BitHeapLength*8 );        //64 Bit Heap length and data
      return blobSize;
    }

    // serialize CAS data into single blob format
    size_t CASSerializer::getBlob(uima::CAS & crCAS, void * buffer, size_t maxSize) {

      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.start() );

      // get a heap of references
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;

      size_t uiFSHeapLength = tyTempHeap.getTopOfHeap();
      size_t uiStringHeapLength = tyStringHeap.getTopOfHeap();
      size_t uialignedStrLen = 2 * ((uiStringHeapLength + 1)/2);
      size_t uiRefHeapLength = tyStringRefHeap.getTopOfHeap();
      size_t uiIndexedFSLength = iv_vecIndexedFSs.size();

      size_t ui8BitHeapLength = ty8BitHeap.getTopOfHeap();
      size_t uialigned8BitHeapLength = 4 * ((ui8BitHeapLength+3)/4);
      size_t ui16BitHeapLength = ty16BitHeap.getTopOfHeap();
      size_t uialigned16BitHeapLength = 2 * ((ui16BitHeapLength+1)/2);
      size_t ui64BitHeapLength = ty64BitHeap.getTopOfHeap();

      size_t blobSize = 2*4               // key and version
                        + (1 + uiFSHeapLength) * 4        // FSHeap length and data
                        + 1*4 + (uialignedStrLen * 2)  // StringHeap length and data
                        + (1 + uiRefHeapLength) * 4     // StringRefheap length and data
                        + (1 + uiIndexedFSLength) * 4    // Indexed FS length and data
                        + (1*4 + uialigned8BitHeapLength)  // 8 Bit Heap length and data
                        + (1*4 + uialigned16BitHeapLength*2 ) //16 Bit Heap length and data
                        + (1*4 + ui64BitHeapLength*8 );        //64 Bit Heap length and data


      if (blobSize > maxSize) {
        return 0;             // can't serialize into given buffer
      }

      // copy all data into the blob buffer
      int* intPtr = (int*) buffer;

#if defined(WORDS_BIGENDIAN)
      char key[] = "UIMA";
#else
      char key[] = "AMIU";
#endif
      int version = 1;
      intPtr[0] = ((int*)key)[0];
      intPtr[1] = version;
      intPtr[2] = uiFSHeapLength;
      assert (blobSize > (size_t)((intPtr + 3 + uiFSHeapLength) - (int*)buffer));
      memcpy(intPtr+3, tyTempHeap.getHeapStart(), 4*uiFSHeapLength);
      intPtr += 3 + uiFSHeapLength;

      intPtr[0] = uialignedStrLen;
      assert (blobSize > (size_t)((intPtr + 1 + uiStringHeapLength/2) - (int*)buffer));
      memcpy(intPtr+1, tyStringHeap.getHeapStart(), 2*uiStringHeapLength);
      intPtr += 1 + uialignedStrLen/2;

      intPtr[0] = uiRefHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + uiRefHeapLength) - (int*)buffer));
      memcpy(intPtr+1, tyStringRefHeap.getHeapStart(), 4*uiRefHeapLength);
      intPtr += 1 + uiRefHeapLength;

      intPtr[0] = uiIndexedFSLength;
      assert (blobSize >= (size_t)((intPtr + 1 + uiIndexedFSLength) - (int*)buffer));
      memcpy(intPtr+1, &iv_vecIndexedFSs[0], 4*uiIndexedFSLength);
      intPtr += 1 + uiIndexedFSLength;

      intPtr[0] = uialigned8BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + uialigned8BitHeapLength/4) - (int*)buffer));
      memcpy(intPtr+1, ty8BitHeap.getHeapStart(), ui8BitHeapLength);
      intPtr += 1 + uialigned8BitHeapLength/4;

      intPtr[0] = uialigned16BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + ui16BitHeapLength/2) - (int*)buffer));
      memcpy(intPtr+1, ty16BitHeap.getHeapStart(), 2*ui16BitHeapLength);
      intPtr += 1 + uialigned16BitHeapLength/2;

      intPtr[0] = ui64BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + ui64BitHeapLength*2) - (int*)buffer));
      memcpy(intPtr+1, ty64BitHeap.getHeapStart(), 8*ui64BitHeapLength);

      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.stop() );
      return blobSize;
    }




  }

}


/* ----------------------------------------------------------------------- */



