| #ifndef UIMA_LOWLEVEL_FSHEAP_HPP |
| #define UIMA_LOWLEVEL_FSHEAP_HPP |
| |
| /** \file lowlevel_fsheap.hpp . |
| ----------------------------------------------------------------------------- |
| |
| |
| * 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/lowlevel_typesystem.hpp" |
| #include "uima/lowlevel_internal_heap.hpp" |
| |
| #include "uima/internal_typeshortcuts.hpp" |
| #include "uima/cas.hpp" |
| #include "uima/arrayfs.hpp" |
| |
| #ifndef NDEBUG |
| #include <iostream> |
| #endif |
| |
| #include <vector> |
| |
| #if defined( _MSC_VER ) |
| #pragma warning( push ) |
| #pragma warning( disable : 4311 ) |
| #pragma warning( disable : 4312 ) |
| #endif |
| /* ----------------------------------------------------------------------- */ |
| /* Constants */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Forward declarations */ |
| /* ----------------------------------------------------------------------- */ |
| namespace uima { |
| class CAS; |
| class XMLDumpWriter; |
| class LocalSofaDataStream; |
| namespace internal { |
| class CASSerializer; |
| class CASDeserializer; |
| class FSPromoter; |
| } |
| namespace lowlevel { |
| class DefaultFSIterator; |
| } |
| } |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Types / Classes */ |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| namespace uima { |
| namespace lowlevel { |
| |
| /** |
| * The Feature structure heap; |
| * Note: this implementation used to contain temporary and permanent heaps |
| * but the permanent feature has been removed. |
| */ |
| class UIMA_LINK_IMPORTSPEC FSHeap { |
| friend class uima::CAS; |
| friend class uima::internal::CASSerializer; |
| friend class uima::internal::CASDeserializer; |
| friend class uima::internal::FSPromoter; |
| friend class uima::lowlevel::DefaultFSIterator; |
| friend class uima::XCASDeserializerHandler; |
| friend class uima::XmiDeserializerHandler; |
| friend class uima::XMLDumpWriter; |
| friend class uima::LocalSofaDataStream; |
| /* VC++ 8 rejects all these forms of friend declaration |
| so method getCArrayFromFS has been made public |
| #ifdef _MSC_VER |
| friend class uima::BasicArrayFS; |
| #else |
| template<class,const uima::lowlevel::TyFSType> friend class uima::BasicArrayFS; |
| #endif |
| // VC++ 7.1 rejects the "correct" declaration with: |
| // C2888: 'uima::BasicArrayFS' : symbol cannot be defined within namespace 'lowlevel' |
| */ |
| public: |
| typedef enum { |
| PERMANENT, |
| TEMPORARY |
| } |
| EnHeap; |
| |
| private: |
| typedef internal::Heap<TyHeapCell> TyFSHeap; |
| typedef internal::Heap<UChar> TyStringHeap; |
| typedef uima::lowlevel::internal::Heap<TyHeapCell> TyStringRefHeap; |
| |
| typedef uima::lowlevel::internal::Heap<char> Ty8BitHeap; |
| typedef uima::lowlevel::internal::Heap<short> Ty16BitHeap; |
| typedef uima::lowlevel::internal::Heap<INT64> Ty64BitHeap; |
| |
| |
| TyFSHeap iv_clTemporaryHeap; |
| TyStringHeap iv_clTemporaryStringHeap; |
| TyStringRefHeap iv_clTemporaryStringRefHeap; |
| //support for 8, 32, 64 bit heap |
| Ty8BitHeap iv_clTemporary8BitHeap; |
| Ty16BitHeap iv_clTemporary16BitHeap; |
| Ty64BitHeap iv_clTemporary64BitHeap; |
| |
| |
| TypeSystem const & iv_rclTypeSystem; |
| |
| // internal helpers to set feature structures on the heap |
| // without type checking |
| void setFeatureInternal(TyFS, TyFSFeature, TyFS); |
| TyFS getFeatureInternal(TyFS, TyFSFeature) const; |
| |
| /** |
| * helper function to set the string ref heap entry located |
| * at pointerIntoStringRefHeap to point to s. |
| */ |
| void setStringRef(TyFS offsetIntoStringRefHeap, |
| TyFS offsetIntoStringHeap); |
| |
| TyFSHeap& getHeap() { |
| return iv_clTemporaryHeap; |
| } |
| |
| TyStringHeap& getStringHeap() { |
| return iv_clTemporaryStringHeap; |
| } |
| |
| TyStringRefHeap & getStringRefHeap() { |
| return iv_clTemporaryStringRefHeap; |
| } |
| |
| //support for 8, 32, 64 bit heap |
| Ty8BitHeap & get8BitHeap() { |
| return iv_clTemporary8BitHeap; |
| } |
| Ty16BitHeap & get16BitHeap() { |
| return iv_clTemporary16BitHeap; |
| } |
| Ty64BitHeap & get64BitHeap() { |
| return iv_clTemporary64BitHeap; |
| } |
| |
| |
| |
| FSHeap(); |
| FSHeap(FSHeap const &); |
| FSHeap & operator=(FSHeap const &); |
| |
| protected: |
| |
| char const * get8BitArray(TyFS tyFs) const; |
| |
| short const * get16BitArray(TyFS tyFs) const; |
| |
| INT64 const * get64BitArray(TyFS tyFs) const; |
| |
| public: |
| /** |
| * Construct a heap with respect to a type system. |
| * @param numberOfHeapCells initial heap size |
| */ |
| FSHeap(TypeSystem const & rclTypeSystem, |
| size_t uiFSHeapPageSize, |
| size_t uiStringHeapPageSize, |
| size_t uiStringRefHeapPageSize); |
| |
| FSHeap(TypeSystem const & rclTypeSystem, |
| size_t uiFSHeapPageSize, |
| size_t uiStringHeapPageSize, |
| size_t uiStringRefHeapPageSize, |
| size_t uiMinHeapPageSize); |
| |
| |
| ~FSHeap(); |
| |
| static TyFS const INVALID_FS; |
| |
| /** |
| * get the C-style array from an array FS (const version). |
| */ |
| TyHeapCell const * getCArrayFromFS(TyFS) const; //was public |
| |
| |
| /** |
| * get the C-style array from an array FS (non-const version). |
| */ |
| TyHeapCell * getCArrayFromFS(TyFS); |
| |
| /** |
| * Helper function to provide a unique ID for a feature structure |
| * |
| */ |
| TyFS getUniqueID(uima::lowlevel::TyHeapCell const tyFs) const { |
| return tyFs; |
| } |
| |
| /** |
| * check if a feature structure (of a non built-in type) actually lives within this heap. |
| */ |
| bool resides(TyFS tyFS) const { |
| return iv_clTemporaryHeap.resides(tyFS); |
| } |
| |
| /** |
| * check if a feature structure is valid w.r.t. this heap. |
| */ |
| bool isValid(TyFS tyFS) const { |
| // second condition is false if heap was resetted |
| return resides(tyFS) && ( tyFS != (TyFS) TypeSystem::INVALID_TYPE ); |
| } |
| |
| TypeSystem const & getTypeSystem() const { |
| return iv_rclTypeSystem; |
| } |
| |
| /** |
| * erases all data on the specified heap. |
| */ |
| void reset(); |
| |
| /** |
| * create a feature structure of some type. |
| * ("high-end" variant). |
| * @param tyFeatureNumber the number of features for this type |
| */ |
| TyFS createFS(TyFSType tyType, TyFeatureOffset tyFeatureNumber) { |
| assert( iv_rclTypeSystem.isValidType( tyType ) ); |
| assert( tyType != uima::internal::gs_tyIntegerType ); |
| assert( tyType != uima::internal::gs_tyFloatType ); |
| assert( ! iv_rclTypeSystem.subsumes(uima::internal::gs_tyStringType, tyType) ); |
| assert( iv_rclTypeSystem.getFeatureNumber(tyType) == tyFeatureNumber ); |
| TyFSHeap & rtyHeap = getHeap(); |
| TyFS tyResult = rtyHeap.increaseHeap(tyFeatureNumber + 1); |
| rtyHeap.setHeapValue(tyResult,(TyHeapCell) tyType); |
| return tyResult; |
| } |
| |
| /** |
| * create a feature structure on the temporary heap where the size of the type is |
| * already known. |
| */ |
| TyFS createFSWithSize(TyFSType tyType, TyFeatureOffset tyFeatureNumber) { |
| return createFS(tyType, tyFeatureNumber); |
| } |
| |
| /** |
| * create a feature structure of some type. |
| */ |
| TyFS createFS(TyFSType tyType) { |
| TyFeatureOffset tyNum = iv_rclTypeSystem.getFeatureNumber(tyType); |
| return createFS(tyType, tyNum); |
| } |
| |
| /** |
| * create an array fs with size <code>uiSize</code> |
| * on the specified heap. |
| */ |
| TyFS createArrayFS(TyFSType tyType, size_t uiSize) { |
| assert( iv_rclTypeSystem.isValidType( tyType ) ); |
| assert( iv_rclTypeSystem.getFeatureNumber(tyType) == 0 ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, tyType ) ); |
| TyFSHeap & rtyHeap = getHeap(); |
| Ty8BitHeap & rty8BitHeap = get8BitHeap(); |
| Ty16BitHeap & rty16BitHeap = get16BitHeap(); |
| Ty64BitHeap & rty64BitHeap = get64BitHeap(); |
| |
| TyFS tyResult; |
| if (tyType == uima::internal::gs_tyLongArrayType || |
| tyType == uima::internal::gs_tyDoubleArrayType) { |
| |
| tyResult = rtyHeap.increaseHeap(3); |
| TyFS ty64BitHeapResult = rty64BitHeap.increaseHeap(uiSize); |
| rtyHeap.setHeapValue(tyResult, (TyHeapCell) tyType); |
| rtyHeap.setHeapValue(tyResult+1, (TyHeapCell) uiSize); |
| rtyHeap.setHeapValue(tyResult+2, (TyHeapCell) ty64BitHeapResult); |
| } |
| else if (tyType == uima::internal::gs_tyBooleanArrayType || |
| tyType == uima::internal::gs_tyByteArrayType) { |
| |
| tyResult = rtyHeap.increaseHeap(3); |
| TyFS ty8BitHeapResult = rty8BitHeap.increaseHeap(uiSize); |
| rtyHeap.setHeapValue(tyResult, (TyHeapCell) tyType); |
| rtyHeap.setHeapValue(tyResult+1, (TyHeapCell) uiSize); |
| rtyHeap.setHeapValue(tyResult+2, (TyHeapCell) ty8BitHeapResult); |
| } else if (tyType == uima::internal::gs_tyShortArrayType) { |
| |
| tyResult = rtyHeap.increaseHeap(3); |
| TyFS ty16BitHeapResult = rty16BitHeap.increaseHeap(uiSize); |
| rtyHeap.setHeapValue(tyResult, (TyHeapCell) tyType); |
| rtyHeap.setHeapValue(tyResult+1, (TyHeapCell) uiSize); |
| rtyHeap.setHeapValue(tyResult+2, (TyHeapCell) ty16BitHeapResult); |
| } |
| else { |
| // a 32bit type. 1 cell for the type, 1 for length, uiSize many for the array data |
| |
| tyResult = rtyHeap.increaseHeap(2 + uiSize); |
| rtyHeap.setHeapValue(tyResult,(TyHeapCell) tyType); |
| assert( sizeof(INT32) <= sizeof(TyHeapCell) ); |
| rtyHeap.setHeapValue(tyResult+1,(TyHeapCell) uiSize); |
| } |
| return tyResult; |
| } |
| |
| /** |
| * get the <code>Lstring</code> from a feature structure. |
| * Precondition: <code>tyFS</code> must be of type string. |
| */ |
| UnicodeStringRef getFSAsString(TyFS tyFS) const; |
| |
| /** |
| * returns the type of a feature structure. |
| */ |
| TyFSType getType(TyFS tyFs) const; |
| |
| /** |
| * method for fast access of feature values. |
| * Use this in combination with InternalTypeSystem::getFeatureOffset. |
| */ |
| TyFS getFeatureWithOffset(TyFS tyFs, TyFeatureOffset tyOffset) const; |
| |
| /** |
| * method for fast setting of feature values. |
| * Use this in combination with InternalTypeSystem::getFeatureOffset. |
| */ |
| void setFeatureWithOffset(TyFS tyFs, TyFeatureOffset tyOffset, TyFS tyValue); |
| |
| /** |
| * store copy of string on the specified heap. |
| * @return the reference to the copied string. |
| */ |
| int addString(UnicodeStringRef const & uls) { |
| size_t l = uls.length(); |
| TyStringHeap & rtyStringHeap = getStringHeap(); |
| int p = rtyStringHeap.increaseHeap(l + 1); |
| assert( (int)(2*l) == uls.getSizeInBytes() ); |
| memcpy(rtyStringHeap.getHeapStart()+p, uls.getBuffer(), uls.getSizeInBytes() ); |
| return p; |
| } |
| |
| //store long / double value 64 bit heap |
| |
| TyFS addLong(INT64 value) { |
| Ty64BitHeap & rty64BitHeap = get64BitHeap(); |
| TyFS p = rty64BitHeap.increaseHeap(sizeof(INT64) ); |
| rty64BitHeap.setHeapValue(p, value); |
| return p; |
| } |
| |
| TyFS addDouble(double value) { |
| Ty64BitHeap & rty64BitHeap = get64BitHeap(); |
| TyFS p = rty64BitHeap.increaseHeap(sizeof(INT64) ); |
| INT64 int64Val; |
| memcpy(&int64Val, &value, sizeof(INT64)); |
| rty64BitHeap.setHeapValue(p, int64Val); |
| return p; |
| } |
| |
| /** |
| * return copy of string on the stringHeap. |
| * @return the reference to the string. |
| */ |
| UnicodeStringRef getString(int strRef) { |
| // convert from logical string offset to absolute offset into refHeap |
| if (strRef == 0) { |
| return UnicodeStringRef(); |
| } |
| strRef = 1 + 2*(strRef-1); |
| return UnicodeStringRef( iv_clTemporaryStringHeap.getHeapStart()+ |
| iv_clTemporaryStringRefHeap.getHeapValue(strRef), |
| (size_t) iv_clTemporaryStringRefHeap.getHeapValue(strRef+1)); |
| } |
| |
| /** |
| * store a copy of a string on the specified heap. |
| * @return the reference to the copied string. |
| */ |
| int addString(icu::UnicodeString const & uls) { |
| return addString(UnicodeStringRef(uls.getBuffer(), uls.length())); |
| } |
| |
| /** |
| * returns if the feature value tyFeat of feature structure tyFS |
| * was already touched, i.e., used in a setFeature() or getFeature() call. |
| */ |
| bool isUntouchedFSValue(TyFS tyFS, TyFSFeature tyFeat) const; |
| |
| /** |
| * get the value of feature <code>tyFeat</code> on feature structure <code>tyFS</code>. |
| */ |
| TyFS getFSValue(TyFS tyFS, TyFSFeature tyFeat) const; |
| |
| /** |
| * set the feature <code>tyFeat</code> on feature structure <code>tyFS</code> |
| * to value <code>tyValue</code>, |
| */ |
| void setFSValue(TyFS tyFS, TyFSFeature tyFeat, TyFS tyValue); |
| |
| /** |
| * get the size of an array FS. |
| */ |
| size_t getArraySize(TyFS) const; |
| |
| /** |
| * gets the start pos of this array in the appropriate heap |
| * where values of this array type is stored. |
| */ |
| TyHeapCell getArrayOffset(TyFS) const; |
| |
| |
| /*@{*/ |
| /** |
| * @name Conversion Functions. Use only with the set/getFeatureWithOffset methods. |
| */ |
| |
| /** |
| * convert an fs into an integer. |
| */ |
| static int getFSAsInt(TyFS tyFs) { |
| return(int) tyFs; |
| } |
| |
| /** |
| * convert an fs into a float. |
| */ |
| static float getFSAsFloat(TyFS tyFs) { |
| assertWithMsg( sizeof(float) <= sizeof(TyHeapCell), "Port required"); |
| float f; |
| memcpy(&f, &tyFs, 4); |
| return f; |
| } |
| |
| /** |
| * convert an fs into a bool. |
| */ |
| static bool getFSAsBoolean(TyFS tyFs) { |
| if (tyFs==1) |
| return true; |
| else return false; |
| } |
| |
| /** |
| * convert an fs into a byte. |
| */ |
| static char getFSAsByte(TyFS tyFs) { |
| //assertWithMsg( sizeof(float) <= sizeof(TyHeapCell), "Port required"); |
| return (char) tyFs; |
| } |
| |
| /** |
| * convert an fs into a short. |
| */ |
| static short getFSAsShort(TyFS tyFs) { |
| //assertWithMsg( sizeof(float) <= sizeof(TyHeapCell), "Port required"); |
| return (short)tyFs; |
| } |
| |
| |
| inline INT64 getFSAsLong(TyFS tyFS) const { |
| if (tyFS == 0) { |
| return '\n'; |
| } |
| assert( iv_clTemporary64BitHeap.debugIsValidHeapCell(tyFS) ); |
| return (INT64) iv_clTemporary64BitHeap.getHeapValue(tyFS); |
| } |
| |
| inline double getFSAsDouble(TyFS tyFS) const { |
| if (tyFS == 0) { |
| return '\n'; |
| } |
| assert( iv_clTemporary64BitHeap.debugIsValidHeapCell(tyFS) ); |
| INT64 int64Val = iv_clTemporary64BitHeap.getHeapValue(tyFS); |
| double d; |
| memcpy(&d, &int64Val, sizeof(double)); |
| return d; |
| } |
| |
| |
| /** |
| * convert an integer into an fs. |
| */ |
| static TyFS getAsFS(int i) { |
| return(TyFS) i; |
| } |
| |
| /** |
| * convert a float into an fs. |
| */ |
| static TyFS getAsFS(float f) { |
| assertWithMsg( sizeof(float) <= sizeof(TyHeapCell), "Port required"); |
| TyFS tyFs; |
| memcpy(&tyFs, &f, 4); |
| return tyFs; |
| } |
| |
| /** |
| * convert a byte into an fs. |
| */ |
| static TyFS getAsFS(char f) { |
| assertWithMsg( sizeof(char) <= sizeof(TyHeapCell), "Port required"); |
| return (TyFS)f; |
| } |
| |
| /** |
| * convert a short into an fs. |
| */ |
| static TyFS getAsFS(short f) { |
| assertWithMsg( sizeof(short) <= sizeof(TyHeapCell), "Port required"); |
| return (TyFS)f; |
| } |
| |
| /** |
| * convert a byte into an fs. |
| */ |
| static TyFS getAsFS(bool f) { |
| assertWithMsg( sizeof(WORD8) <= sizeof(TyHeapCell), "Port required"); |
| TyFS tyFs = 0; |
| if (f) { |
| tyFs=1; //true |
| } else { |
| tyFs=2; //false |
| } |
| return tyFs; |
| } |
| |
| TyFS getLongAsFS(INT64); |
| TyFS getDoubleAsFS(double); |
| |
| |
| |
| |
| /** |
| * convert a stringRef into an offset into the StringRefHeap. |
| * This method is non-const since an entry on the string ref heap |
| * is created. |
| */ |
| TyFS getStringAsFS(int crStringRef); |
| |
| /*@}*/ |
| |
| /*@{*/ |
| /** |
| * @name Special methods for features with built-in types values. |
| */ |
| void setIntValue(TyFS, TyFSFeature, int); |
| void setFloatValue(TyFS, TyFSFeature, float); |
| void setStringValue(TyFS, TyFSFeature, int strRef); |
| |
| void setByteValue(TyFS, TyFSFeature, char ); |
| void setShortValue(TyFS, TyFSFeature, short ); |
| void setBooleanValue(TyFS, TyFSFeature, bool ); |
| void setLongValue(TyFS, TyFSFeature, INT64 ref); |
| void setDoubleValue(TyFS, TyFSFeature, double); |
| |
| int getIntValue(TyFS, TyFSFeature) const; |
| float getFloatValue(TyFS, TyFSFeature) const; |
| UnicodeStringRef getStringValue(TyFS, TyFSFeature) const; |
| |
| bool getBooleanValue(TyFS,TyFSFeature) const; |
| char getByteValue(TyFS,TyFSFeature) const; |
| short getShortValue(TyFS,TyFSFeature) const; |
| INT64 getLongValue(TyFS,TyFSFeature) const; |
| double getDoubleValue(TyFS,TyFSFeature) const; |
| |
| //methods for setting ArrayFS values in the appropriate heap |
| void setArrayElement(int val, TyHeapCell offset ); |
| void setArrayElement(float val, TyHeapCell offset ); |
| |
| void setArrayElement(char val, TyHeapCell offset ); |
| void setArrayElement(short val, TyHeapCell offset ); |
| void setArrayElement(bool val, TyHeapCell offset ); |
| void setArrayElement(INT64 val, TyHeapCell offset); |
| void setArrayElement(double, TyHeapCell offset); |
| |
| char getByte( TyHeapCell offset ); |
| short getShort(TyHeapCell offset ); |
| bool getBoolean(TyHeapCell offset ); |
| INT64 getLong(TyHeapCell offset); |
| double getDouble(TyHeapCell offset); |
| |
| |
| void copyFromArray(TyHeapCell sourceArray[], size_t srcOffset, TyHeapCell tyCell, size_t destOffset, size_t numelements) { |
| TyHeapCell * ptr = getCArrayFromFS(tyCell); |
| if(ptr!=NULL) { |
| memcpy(ptr + destOffset, sourceArray + srcOffset, numelements*sizeof(TyHeapCell)); |
| } |
| } |
| |
| void copyFromArray(char sourceArray[], size_t srcOffset, TyHeapCell tyCell, size_t destOffset, size_t numelements) { |
| char * ptr = const_cast<char*>(get8BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(ptr + destOffset, sourceArray + srcOffset, numelements); |
| } |
| } |
| |
| void copyFromArray(short sourceArray[], size_t srcOffset, TyHeapCell tyCell, size_t destOffset, size_t numelements) { |
| short * ptr = const_cast<short*>(get16BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(ptr + destOffset, sourceArray + srcOffset, numelements * sizeof(short)); |
| } |
| } |
| |
| void copyFromArray(INT64 sourceArray[], size_t srcOffset, TyHeapCell tyCell, size_t destOffset, size_t numelements) { |
| INT64 * ptr = const_cast<INT64*>(get64BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(ptr + destOffset, sourceArray + srcOffset, numelements * sizeof(INT64)); |
| } |
| } |
| |
| void copyToArray(size_t srcOffset, TyHeapCell tyCell, char destArray[], size_t destOffset, size_t numelements) { |
| char * ptr = const_cast<char*>(get8BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(destArray + destOffset, ptr + srcOffset, numelements); |
| } |
| } |
| |
| void copyToArray(size_t srcOffset, TyHeapCell tyCell, TyHeapCell destArray[], size_t destOffset, size_t numelements) { |
| TyHeapCell * ptr = const_cast<TyHeapCell*>(getCArrayFromFS(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(destArray + destOffset, ptr + srcOffset, numelements*sizeof(TyHeapCell) ); |
| } |
| } |
| |
| void copyToArray(size_t srcOffset, TyHeapCell tyCell, short destArray[], size_t destOffset, size_t numelements) { |
| short * ptr = const_cast<short*>(get16BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(destArray + destOffset, ptr + srcOffset, numelements*sizeof(short) ); |
| } |
| } |
| |
| void copyToArray(size_t srcOffset, TyHeapCell tyCell, INT64 destArray[], size_t destOffset, size_t numelements) { |
| INT64 * ptr = const_cast<INT64*>(get64BitArray(tyCell)); |
| if(ptr!=NULL) { |
| memcpy(destArray + destOffset, ptr + srcOffset, numelements*sizeof(INT64) ); |
| } |
| } |
| |
| |
| /*@}*/ |
| |
| |
| /** |
| * shallow copy of feature structures. |
| * ints, floats, and strings are copied "by-value". |
| * If featnum == 0 the types of <code>tyTarget</code> and <code>tySource</code> should be equal. |
| * Otherwise, just the first featNum features of source are copied to target |
| * (no questions asked). |
| */ |
| void copyFeatures(TyFS tyTarget, TyFS tySource, size_t featNum = 0); |
| |
| /** |
| * print an FS. |
| */ |
| void printFS(std::ostream&, TyFS) const; |
| |
| //#ifndef NDEBUG |
| // debug methods |
| TyHeapCell* getHeapStart() const; |
| bool debugIsValidHeapCell(TyHeapCell) const; |
| bool debugIsConsistent() const; |
| void print(std::ostream&) const; |
| //#endif |
| |
| }; |
| |
| } |
| } |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Implementation */ |
| /* ----------------------------------------------------------------------- */ |
| |
| namespace uima { |
| namespace lowlevel { |
| |
| inline TyFSType FSHeap::getType(TyFS tyFs) const { |
| assert( debugIsValidHeapCell(tyFs) ); |
| TyFSType tyType = (TyFSType) iv_clTemporaryHeap.getHeapValue(tyFs); |
| assert( iv_rclTypeSystem.isValidType(tyType) ); |
| return tyType; |
| } |
| |
| |
| inline TyFS FSHeap::getFeatureWithOffset(TyFS tyFs, TyFeatureOffset tyOffset) const { |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs + tyOffset) ); |
| assert( tyOffset > 0 ); |
| assert( tyOffset <= iv_rclTypeSystem.getFeatureNumber( getType(tyFs) )); |
| return(TyFS) iv_clTemporaryHeap.getHeapValue(tyFs + tyOffset); |
| } |
| |
| inline void FSHeap::setFeatureWithOffset(TyFS tyFs, TyFeatureOffset tyOffset, TyFS tyValue) { |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs + tyOffset) ); |
| assert( tyOffset > 0 ); |
| assert( tyOffset <= iv_rclTypeSystem.getFeatureNumber( getType(tyFs) )); |
| iv_clTemporaryHeap.setHeapValue(tyFs + tyOffset, tyValue); |
| } |
| |
| inline void FSHeap::setStringRef(TyFS strHeapRef, TyFS strRef) { |
| // convert from logical string offset to absolute offset into refHeap |
| strHeapRef = 1 + 2*(strHeapRef-1); |
| |
| // set offset into StringHeap |
| iv_clTemporaryStringRefHeap.setHeapValue(strHeapRef, strRef); |
| |
| // set length |
| iv_clTemporaryStringRefHeap.setHeapValue(strHeapRef+1, |
| u_strlen(iv_clTemporaryStringHeap.getHeapStart()+strRef) ); |
| } |
| |
| inline UnicodeStringRef FSHeap::getFSAsString(TyFS tyFS) const { |
| if (tyFS == 0) { |
| return UnicodeStringRef(); |
| } |
| assert( iv_clTemporaryStringRefHeap.debugIsValidHeapCell(tyFS) ); |
| // convert from logical string offset to absolute offset into refHeap |
| tyFS = 1 + 2*(tyFS-1); |
| return UnicodeStringRef( iv_clTemporaryStringHeap.getHeapStart()+ |
| iv_clTemporaryStringRefHeap.getHeapValue(tyFS), |
| (size_t) iv_clTemporaryStringRefHeap.getHeapValue(tyFS+1)); |
| } |
| |
| inline TyFS FSHeap::getStringAsFS(int crStringRef) { |
| // increase string ref heap by 2 |
| TyFS stringRef = iv_clTemporaryStringRefHeap.increaseHeap(2); |
| // convert to local string offset |
| stringRef = 1 + ((stringRef-1)/2); |
| setStringRef(stringRef, crStringRef); |
| return stringRef; |
| } |
| |
| inline TyFS FSHeap::getLongAsFS(INT64 l) { |
| return addLong(l); |
| } |
| |
| inline TyFS FSHeap::getDoubleAsFS(double l) { |
| return addDouble(l); |
| } |
| |
| inline TyFS FSHeap::getFeatureInternal(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.isAppropriateFeature( getType(tyFs), tyFeature ) ); |
| TyFeatureOffset tyFeatureOffset = iv_rclTypeSystem.getFeatureOffset(tyFeature); |
| assert( debugIsValidHeapCell(tyFs + tyFeatureOffset) ); |
| TyFS tyFsCell = iv_clTemporaryHeap.getHeapValue(tyFs + tyFeatureOffset); |
| return tyFsCell; |
| } |
| |
| inline bool FSHeap::isUntouchedFSValue(TyFS tyFS, TyFSFeature tyFeature) const { |
| TyFS tyFsCell = getFeatureInternal(tyFS, tyFeature); |
| return tyFsCell == INVALID_FS; |
| } |
| |
| |
| inline int FSHeap::getIntValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_INTEGER) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsInt(tyResult); |
| } |
| |
| inline float FSHeap::getFloatValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_FLOAT) ); |
| assertWithMsg( sizeof(float) <= sizeof(TyHeapCell*), "Port required"); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsFloat(tyResult); |
| } |
| |
| inline UnicodeStringRef FSHeap::getStringValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyStringType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsString(tyResult); |
| } |
| |
| inline bool FSHeap::getBooleanValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyBooleanType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsBoolean(tyResult); |
| } |
| |
| |
| inline char FSHeap::getByteValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyByteType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsByte(tyResult); |
| } |
| |
| inline short FSHeap::getShortValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyShortType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsShort(tyResult); |
| } |
| |
| inline INT64 FSHeap::getLongValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyLongType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsLong(tyResult); |
| } |
| |
| inline double FSHeap::getDoubleValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyDoubleType, iv_rclTypeSystem.getRangeType(tyFeature) ) ); |
| TyFS tyResult = getFeatureInternal(tyFs, tyFeature); |
| return getFSAsDouble(tyResult); |
| } |
| |
| |
| inline TyHeapCell const * FSHeap::getCArrayFromFS(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( iv_rclTypeSystem.getFeatureNumber( getType(tyFs) ) == 0 ); |
| if ( 0 == iv_clTemporaryHeap.getHeapValue(tyFs + 1)) { |
| return NULL; |
| } |
| return(TyHeapCell const *) iv_clTemporaryHeap.getHeapStart() + tyFs + 2; |
| } |
| |
| inline TyHeapCell * FSHeap::getCArrayFromFS(TyFS tyFs) { |
| FSHeap const * cpConstThis = this; |
| return CONST_CAST(TyHeapCell *, cpConstThis->getCArrayFromFS(tyFs) ); |
| } |
| |
| inline char const * FSHeap::get8BitArray(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( iv_rclTypeSystem.getFeatureNumber( getType(tyFs) ) == 0 ); |
| if ( 0 == iv_clTemporaryHeap.getHeapValue(tyFs + 1)) { |
| return NULL; |
| } |
| return(char const *) this->iv_clTemporary8BitHeap.getHeapStart() + iv_clTemporaryHeap.getHeapValue(tyFs + 2); |
| } |
| |
| inline short const * FSHeap::get16BitArray(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( iv_rclTypeSystem.getFeatureNumber( getType(tyFs) ) == 0 ); |
| if ( 0 == iv_clTemporaryHeap.getHeapValue(tyFs + 1)) { |
| return NULL; |
| } |
| return(short const *) this->iv_clTemporary16BitHeap.getHeapStart() + iv_clTemporaryHeap.getHeapValue(tyFs + 2); |
| } |
| |
| inline INT64 const * FSHeap::get64BitArray(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( iv_rclTypeSystem.getFeatureNumber( getType(tyFs) ) == 0 ); |
| if ( 0 == iv_clTemporaryHeap.getHeapValue(tyFs + 1)) { |
| return NULL; |
| } |
| |
| return(INT64 const *) this->iv_clTemporary64BitHeap.getHeapStart() + iv_clTemporaryHeap.getHeapValue(tyFs + 2); |
| } |
| |
| inline size_t FSHeap::getArraySize(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( sizeof(WORD32) <= sizeof(uima::lowlevel::TyFS) ); |
| return(size_t) iv_clTemporaryHeap.getHeapValue(tyFs + 1); |
| } |
| |
| inline TyHeapCell FSHeap::getArrayOffset(TyFS tyFs) const { |
| assert( isValid(tyFs) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, getType(tyFs) ) ); |
| assert( sizeof(WORD32) <= sizeof(uima::lowlevel::TyFS) ); |
| TyFSType typecode = getType(tyFs); |
| if (typecode == uima::internal::gs_tyBooleanArrayType || |
| typecode == uima::internal::gs_tyByteArrayType || |
| typecode == uima::internal::gs_tyShortArrayType || |
| typecode == uima::internal::gs_tyLongArrayType || |
| typecode == uima::internal::gs_tyDoubleArrayType) { |
| return(size_t) iv_clTemporaryHeap.getHeapValue(tyFs + 2); |
| } else { |
| return tyFs+2; |
| } |
| } |
| |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| |
| inline void FSHeap::setFeatureInternal(TyFS tyFs, TyFSFeature tyFeature, TyFS tyValue) { |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.isAppropriateFeature( getType(tyFs), tyFeature ) ); |
| TyFeatureOffset tyFeatureOffset = iv_rclTypeSystem.getFeatureOffset(tyFeature); |
| TyHeapCell tyFsCell = tyFs + tyFeatureOffset; |
| assert( debugIsValidHeapCell(tyFsCell) ); |
| iv_clTemporaryHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| |
| inline void FSHeap::setFSValue(TyFS tyFs, TyFSFeature tyFeature, TyFS tyValue) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( debugIsValidHeapCell(tyFs) ); |
| assert( resides(tyFs) ); |
| assert( iv_rclTypeSystem.isAppropriateFeature( getType(tyFs), tyFeature ) ); |
| #ifndef NDEBUG |
| if (tyValue != INVALID_FS) { |
| assert( debugIsValidHeapCell(tyValue) ); |
| if (iv_rclTypeSystem.subsumes( uima::internal::gs_tyFSArrayType, iv_rclTypeSystem.getRangeType( tyFeature ) )) { |
| assert(resides(tyValue)); |
| } else if ( !iv_rclTypeSystem.subsumes( uima::internal::gs_tyStringType, iv_rclTypeSystem.getRangeType( tyFeature ) ) ) { |
| assert( resides(tyValue) ); |
| assert( iv_rclTypeSystem.subsumes( iv_rclTypeSystem.getRangeType( tyFeature ), getType(tyValue) ) ); |
| } else { |
| assert( iv_clTemporaryStringRefHeap.resides(tyValue) ); |
| } |
| } |
| #endif |
| setFeatureInternal(tyFs, tyFeature, tyValue); |
| } |
| |
| inline TyFS FSHeap::getFSValue(TyFS tyFs, TyFSFeature tyFeature) const { |
| TyFS tyFsCell = getFeatureInternal(tyFs, tyFeature); |
| #ifndef NDEBUG |
| if (tyFsCell != INVALID_FS) { |
| if ( ! iv_rclTypeSystem.subsumes( uima::internal::gs_tyStringType, iv_rclTypeSystem.getRangeType( tyFeature ) ) ) { |
| assert( iv_rclTypeSystem.subsumes( iv_rclTypeSystem.getRangeType(tyFeature), getType(tyFsCell) ) ); |
| } |
| } |
| #endif |
| return tyFsCell; |
| } |
| |
| inline void FSHeap::setIntValue(TyFS tyFs, TyFSFeature tyFeature, int iValue) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_INTEGER) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, (TyFS)iValue ); |
| } |
| |
| inline void FSHeap::setFloatValue(TyFS tyFs, TyFSFeature tyFeature, float fValue) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_FLOAT) ); |
| assertWithMsg( sizeof(float) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, getAsFS(fValue) ); |
| } |
| |
| |
| inline void FSHeap::setBooleanValue(TyFS tyFs, TyFSFeature tyFeature, bool ref) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_BOOLEAN) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, getAsFS(ref) ); |
| } |
| |
| |
| inline void FSHeap::setByteValue(TyFS tyFs, TyFSFeature tyFeature, char ref) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_BYTE) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, getAsFS(ref) ); |
| } |
| |
| inline void FSHeap::setShortValue(TyFS tyFs, TyFSFeature tyFeature, short ref) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_SHORT) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, getAsFS(ref) ); |
| } |
| |
| inline void FSHeap::setLongValue(TyFS tyFs, TyFSFeature tyFeature, INT64 ref) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_LONG) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, addLong(ref) ); |
| } |
| |
| inline void FSHeap::setDoubleValue(TyFS tyFs, TyFSFeature tyFeature, double ref) { |
| assert( iv_rclTypeSystem.isValidFeature(tyFeature) ); |
| assert( iv_rclTypeSystem.getTypeName( iv_rclTypeSystem.getRangeType(tyFeature) ) == icu::UnicodeString(CAS::TYPE_NAME_DOUBLE) ); |
| assertWithMsg( sizeof(int) <= sizeof(TyHeapCell*), "Port required"); |
| setFeatureInternal(tyFs, tyFeature, addDouble(ref) ); |
| } |
| |
| |
| inline void FSHeap::setArrayElement(int tyValue, TyHeapCell tyFsCell) { |
| this->iv_clTemporaryHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| inline void FSHeap::setArrayElement(float tyValue, TyHeapCell tyFsCell) { |
| this->iv_clTemporaryHeap.setHeapValue(tyFsCell, getAsFS(tyValue)); |
| } |
| |
| inline void FSHeap::setArrayElement(bool tyValue, TyHeapCell tyFsCell) { |
| iv_clTemporary8BitHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| inline void FSHeap::setArrayElement(char tyValue, TyHeapCell tyFsCell) { |
| iv_clTemporary8BitHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| inline void FSHeap::setArrayElement(short tyValue, TyHeapCell tyFsCell) { |
| iv_clTemporary16BitHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| inline void FSHeap::setArrayElement(INT64 tyValue, TyHeapCell tyFsCell) { |
| iv_clTemporary64BitHeap.setHeapValue(tyFsCell, tyValue); |
| } |
| inline void FSHeap::setArrayElement(double tyValue, TyHeapCell tyFsCell) { |
| INT64 int64Val; |
| memcpy(&int64Val, &tyValue, sizeof(INT64)); |
| iv_clTemporary64BitHeap.setHeapValue(tyFsCell, int64Val); |
| } |
| |
| inline bool FSHeap::getBoolean(TyHeapCell tyFsCell) { |
| char val = iv_clTemporary8BitHeap.getHeapValue(tyFsCell); |
| if |
| (val==1) return true; |
| else |
| return false; |
| } |
| inline char FSHeap::getByte(TyHeapCell tyFsCell) { |
| return iv_clTemporary8BitHeap.getHeapValue(tyFsCell); |
| } |
| inline short FSHeap::getShort(TyHeapCell tyFsCell) { |
| return iv_clTemporary16BitHeap.getHeapValue(tyFsCell); |
| } |
| inline INT64 FSHeap::getLong(TyHeapCell tyFsCell) { |
| return iv_clTemporary64BitHeap.getHeapValue(tyFsCell); |
| } |
| inline double FSHeap::getDouble(TyHeapCell tyFsCell) { |
| INT64 int64Val = iv_clTemporary64BitHeap.getHeapValue(tyFsCell); |
| double d; |
| memcpy(&d, &int64Val, sizeof(double)); |
| return d; |
| } |
| |
| } |
| } |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| |
| #if defined( _MSC_VER ) |
| #pragma warning( pop ) |
| #endif |
| |
| #endif |
| |
| |