23#include <osl/thread.h>
24#include <osl/diagnose.h>
47 mnError( rSrc.mnError ),
69 return o_rEncryptionData.hasElements() ? ::comphelper::DocPasswordVerifierResult::OK : ::comphelper::DocPasswordVerifierResult::WrongPassword;
76 return bValid ? ::comphelper::DocPasswordVerifierResult::OK : ::comphelper::DocPasswordVerifierResult::WrongPassword;
118 maEncryptionData( rSrc.maEncryptionData ),
120 mnHash( rSrc.mnHash )
137 OString aBytePassword =
OUStringToOString( rPassword, osl_getThreadTextEncoding() );
138 sal_Int32 nLen = aBytePassword.getLength();
139 if( (0 < nLen) && (nLen < 16) )
149 ::std::vector< sal_uInt16 > aPassVect( 16 );
151 std::for_each(aPassVect.begin(), aPassVect.begin() + nLen,
152 [&rPassword, &nInd](sal_uInt16& rPass) {
153 rPass = static_cast< sal_uInt16 >( rPassword[nInd] );
158 OSL_ENSURE( aDocId.getLength() == 16,
"Unexpected length of the sequence!" );
161 aCodec97.
InitKey(aPassVect.data(),
reinterpret_cast<sal_uInt8 const *
>(aDocId.getConstArray()));
177 if( rEncryptionData.hasElements() )
197 sal_uInt16 nRet =
static_cast<sal_uInt16
>(
rStrm.
ReadBytes(pnData, nBytes));
203 std::vector<sal_uInt8>&& rVerifier,
204 std::vector<sal_uInt8>&& rVerifierHash)
205 : maSalt(
std::move(rSalt))
206 , maVerifier(
std::move(rVerifier))
207 , maVerifierHash(
std::move(rVerifierHash))
214 , maEncryptionData(rSrc.maEncryptionData)
215 , maSalt(rSrc.maSalt)
216 , maVerifier(rSrc.maVerifier)
217 , maVerifierHash(rSrc.maVerifierHash)
252 sal_Int32 nLen = rPassword.getLength();
253 if( (0 < nLen) && (nLen < 16) )
256 ::std::vector< sal_uInt16 > aPassVect( 16 );
258 std::for_each(aPassVect.begin(), aPassVect.begin() + nLen,
259 [&pcChar](sal_uInt16& rPass) {
260 rPass = static_cast< sal_uInt16 >( *pcChar );
277 if( rEncryptionData.hasElements() )
291 if( nNewStrmPos == nOldStrmPos )
294 sal_uInt32 nOldBlock =
GetBlock( nOldStrmPos );
295 sal_uInt16 nOldOffset =
GetOffset( nOldStrmPos );
297 sal_uInt32 nNewBlock =
GetBlock( nNewStrmPos );
298 sal_uInt16 nNewOffset =
GetOffset( nNewStrmPos );
301 if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
308 if( nNewOffset > nOldOffset )
317 sal_uInt16 nBytesLeft = nBytes;
321 sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
324 nRet = nRet +
static_cast<sal_uInt16
>(
rStrm.
ReadBytes(pnCurrData, nDecBytes));
326 mpCodec->
Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
330 pnCurrData += nDecBytes;
331 nBytesLeft = nBytesLeft - nDecBytes;
360 const SvStream& rStrm, std::size_t nNextPos, std::size_t nCurrSize,
361 sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
374 SvStream& rStrm, std::size_t& rnNextPos, std::size_t& rnCurrSize,
375 sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
376 bool& rbValid )
const
392 sal_uInt16 nBofId(0), nBofSize(0);
395 if (
rStrm.
good() && 4 <= nBofSize && nBofSize <= 16)
switch( nBofId )
419 default:
SAL_WARN(
"sc",
"XclImpStream::DetectBiffVersion - unknown BIFF version: 0x" << std::hex <<
nVersion );
431 mbGlobValidRec( false ),
432 mbHasGlobPos( false ),
436 mbHasComplRec( false ),
462 std::size_t nZeroRecCount = 5;
463 bool bIsZeroRec =
false;
469 if( bIsZeroRec ) --nZeroRecCount;
517 if(
rStrm.mxDecrypter )
518 xNewDecr =
rStrm.mxDecrypter->Clone();
535 OSL_ENSURE( !
maPosStack.empty(),
"XclImpStream::PopPosition - stack empty" );
553 OSL_ENSURE(
mbHasGlobPos,
"XclImpStream::SeekGlobalPosition - no position stored" );
640 nValue =
static_cast< sal_Int16
>( SVBT16ToUInt16( pnBuffer ) );
658 nValue = SVBT16ToUInt16( pnBuffer );
676 nValue =
static_cast< sal_Int32
>( SVBT32ToUInt32( pnBuffer ) );
694 nValue = SVBT32ToUInt32( pnBuffer );
712 nValue = SVBT64ToDouble( pnBuffer );
723 std::size_t nRet = 0;
727 std::size_t nBytesLeft = nBytes;
729 while(
mbValid && (nBytesLeft > 0) )
732 sal_uInt16 nReadRet =
ReadRawData( pnBuffer, nReadSize );
734 mbValid = (nReadSize == nReadRet);
735 OSL_ENSURE(
mbValid,
"XclImpStream::Read - stream read error" );
736 pnBuffer += nReadRet;
737 nBytesLeft -= nReadRet;
738 if(
mbValid && (nBytesLeft > 0) )
740 OSL_ENSURE(
mbValid,
"XclImpStream::Read - record overread" );
748 std::size_t nRet = 0;
751 const std::size_t nMaxBuffer = 4096;
753 std::size_t nBytesLeft = nBytes;
762 SAL_WARN_IF(nRet != nReadSize,
"sc",
"read less bytes than requested");
764 nBytesLeft -= nReadSize;
792 else if(
nPos > nCurrPos )
801 std::size_t nBytesLeft = nBytes;
809 nBytesLeft -= nReadSize;
812 OSL_ENSURE(
mbValid,
"XclImpStream::Ignore - record overread" );
817 bool& rb16Bit,
bool& rbRich,
bool& rbFareast,
818 sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf,
sal_uInt8 nFlags )
826 return rnExtInf + 4 * rnFormatRuns;
831 bool bRich, bFareast;
839 OUStringBuffer aRet(o3tl::sanitizing_min<sal_uInt16>(nChars,
mnRawRecLeft / (b16Bit ? 2 : 1)));
840 sal_uInt16 nCharsLeft = nChars;
841 sal_uInt16 nReadSize;
843 while (
IsValid() && nCharsLeft)
847 nReadSize = o3tl::sanitizing_min<sal_uInt16>(nCharsLeft,
mnRawRecLeft / 2);
848 OSL_ENSURE( (nReadSize <= nCharsLeft) || !(
mnRawRecLeft & 0x1),
849 "XclImpStream::ReadRawUniString - missing a byte" );
854 std::unique_ptr<sal_Unicode[]> pcBuffer(
new sal_Unicode[nReadSize + 1]);
857 sal_Unicode* pcEndChar = pcBuffer.get() + nReadSize;
861 sal_uInt16 nReadChar;
862 for( ;
IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
871 for( ;
IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
881 aRet.append( pcBuffer.get() );
883 nCharsLeft = nCharsLeft - nReadSize;
888 return aRet.makeStringAndClear();
912 sal_uInt16 nCharsLeft = nChars;
913 sal_uInt16 nReadSize;
915 while(
IsValid() && (nCharsLeft > 0) )
919 nReadSize = o3tl::sanitizing_min<sal_uInt16>(nCharsLeft,
mnRawRecLeft / 2);
920 OSL_ENSURE( (nReadSize <= nCharsLeft) || !(
mnRawRecLeft & 0x1),
921 "XclImpStream::IgnoreRawUniString - missing a byte" );
930 nCharsLeft = nCharsLeft - nReadSize;
952 std::unique_ptr<char[]> pcBuffer(
new char[ nChars + 1 ]);
953 sal_uInt16 nCharsRead =
ReadRawData( pcBuffer.get(), nChars );
954 pcBuffer[ nCharsRead ] =
'\0';
1032 OSL_ENSURE(
mnRawRecLeft == 0,
"XclImpStream::JumpToNextStringContinue - unexpected garbage" );
1062 OSL_ENSURE(
mbValid,
"XclImpStream::EnsureRawReadSize - record overread" );
1069 return static_cast<sal_uInt16
>(o3tl::sanitizing_min<std::size_t>(nBytes,
mnRawRecLeft));
1074 OSL_ENSURE( (nBytes <=
mnRawRecLeft),
"XclImpStream::ReadRawData - record overread" );
1075 sal_uInt16 nRet = 0;
virtual sal_uInt64 TellEnd()
SvStream & ReadDouble(double &rDouble)
SvStream & ReadInt16(sal_Int16 &rInt16)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
SvStream & ReadUChar(unsigned char &rChar)
Decrypts BIFF5 stream contents.
virtual XclImpBiff5Decrypter * OnClone() const override
Implementation of cloning this object.
XclImpBiff5Decrypter(sal_uInt16 nKey, sal_uInt16 nHash)
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize) override
Implementation of updating the decrypter.
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes) override
Implementation of the decryption.
::msfilter::MSCodec_XorXLS95 maCodec
css::uno::Sequence< css::beans::NamedValue > maEncryptionData
Crypto algorithm implementation.
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword) override
Implements password verification and initialization of the decoder.
virtual XclImpBiff8CryptoAPIDecrypter * OnClone() const override
Implementation of cloning this object.
::msfilter::MSCodec_CryptoAPI maCodec
XclImpBiff8CryptoAPIDecrypter(std::vector< sal_uInt8 > &&rSalt, std::vector< sal_uInt8 > &&rVerifier, std::vector< sal_uInt8 > &&rVerifierHash)
Decrypts BIFF8 stream contents using the given document identifier.
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize) override
Implementation of updating the decrypter.
std::vector< sal_uInt8 > maVerifier
std::vector< sal_uInt8 > maSalt
static sal_uInt32 GetBlock(std::size_t nStrmPos)
Returns the block number corresponding to the passed stream position.
static sal_uInt16 GetOffset(std::size_t nStrmPos)
Returns the block offset corresponding to the passed stream position.
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword) override
Implements password verification and initialization of the decoder.
msfilter::MSCodec97 * mpCodec
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes) override
Implementation of the decryption.
css::uno::Sequence< css::beans::NamedValue > maEncryptionData
XclImpBiff8Decrypter(std::vector< sal_uInt8 > &&rSalt, std::vector< sal_uInt8 > &&rVerifier, std::vector< sal_uInt8 > &&rVerifierHash)
std::vector< sal_uInt8 > maVerifierHash
::msfilter::MSCodec_Std97 maCodec
XclImpBiff8StdDecrypter(std::vector< sal_uInt8 > &&rSalt, std::vector< sal_uInt8 > &&rVerifier, std::vector< sal_uInt8 > &&rVerifierHash)
virtual XclImpBiff8StdDecrypter * OnClone() const override
Implementation of cloning this object.
Base class for BIFF stream decryption.
XclImpDecrypterRef Clone() const
Creates a (ref-counted) copy of this decrypter object.
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData)=0
virtual ~XclImpDecrypter() override
virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
sal_uInt16 Read(SvStream &rStrm, void *pData, sal_uInt16 nBytes)
Reads and decrypts nBytes bytes and stores data into the existing(!) buffer pData.
void Update(const SvStream &rStrm, sal_uInt16 nRecSize)
Updates the decrypter on start of a new record or after seeking stream.
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes)=0
Implementation of the decryption.
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize)=0
Implementation of updating the decrypter.
bool IsValid() const
Returns true, if the decoder has been initialized correctly.
sal_uInt64 mnOldPos
Decrypter error code.
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword)=0
Derived classes implement password verification and initialization of the decoder.
virtual ::comphelper::DocPasswordVerifierResult verifyPassword(const OUString &rPassword, css::uno::Sequence< css::beans::NamedValue > &o_rEncryptionData) override
Implementation of the comphelper::IDocPasswordVerifier interface.
virtual XclImpDecrypter * OnClone() const =0
Implementation of cloning this object.
sal_uInt16 mnRecSize
Last known stream position.
Access to global data from other classes.
This class represents an Excel stream position.
std::size_t GetPos() const
Returns the stored stream position.
XclImpStreamPos()
Constructs an invalid stream position data object.
void Get(SvStream &rStrm, std::size_t &rnNextPos, std::size_t &rnCurrSize, sal_uInt16 &rnRawRecId, sal_uInt16 &rnRawRecSize, sal_uInt16 &rnRawRecLeft, bool &rbValid) const
Writes the contained stream position data to the given variables.
sal_uInt16 mnRawRecSize
Current raw record ID (including CONTINUEs).
bool mbValid
Bytes left in current raw record (without following CONTINUEs).
void Set(const SvStream &rStrm, std::size_t nNextPos, std::size_t nCurrSize, sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft, bool bValid)
Sets the stream position data to the passed values.
sal_uInt16 mnRawRecLeft
Current raw record size (without following CONTINUEs).
sal_uInt16 mnRawRecId
Current calculated size of the record.
std::size_t mnCurrSize
Absolute position of next record.
std::size_t mnNextPos
Absolute position of the stream.
This class is used to import record oriented streams.
bool IsValid() const
Returns record reading state: false = record overread.
std::size_t mnNextRecPos
Size of system stream.
std::size_t ReadUniStringExtHeader(bool &rb16Bit, bool &rbRich, bool &rbFareast, sal_uInt16 &rnFormatRuns, sal_uInt32 &rnExtInf, sal_uInt8 nFlags)
Reads ext.
bool ReadNextRawRecHeader()
Seeks to next raw record header and reads record ID and size.
std::vector< XclImpStreamPos > maPosStack
Start position of current record.
sal_uInt16 GetNextRecId()
Returns the record ID of the following record.
std::size_t GetRecPos() const
Returns the position inside of the whole record content.
bool JumpToNextContinue()
Goes to start of the next CONTINUE record.
sal_uInt16 mnRecId
true = mnComplRecSize is valid.
static XclBiff DetectBiffVersion(SvStream &rStrm)
Detects the BIFF version of the passed workbook stream.
void ResetRecord(bool bContLookup, sal_uInt16 nAltContId=EXC_ID_UNKNOWN)
Sets stream pointer to begin of record content.
void EnableDecryption(bool bEnable=true)
Switches usage of current decryption algorithm on/off.
XclImpStreamPos maGlobPos
Stack for record positions.
bool mbCont
Replacement for NUL characters.
void SetupDecrypter()
Initializes the decrypter to read a new record.
void StoreGlobalPosition()
Stores current position.
std::size_t CopyToStream(SvStream &rOutStrm, std::size_t nBytes)
Copies nBytes bytes to rOutStrm.
void Seek(std::size_t nPos)
Seeks absolute in record content to the specified position.
void SeekGlobalPosition()
Seeks to the stored global user position.
void RestorePosition(const XclImpStreamPos &rPos)
Restores stream position contained in rPos.
bool mbValidRec
Usage of decryption.
sal_uInt16 mnRawRecId
Alternative record ID for content continuation.
std::size_t GetRecLeft()
Returns remaining data size of the whole record without record headers.
void StorePosition(XclImpStreamPos &rPos)
Stores current stream position into rPos.
XclImpStreamPos maFirstRec
Provides methods to decrypt data.
sal_uInt16 PeekRecId(std::size_t nPos)
const XclImpRoot & mrRoot
Reference to the system input stream.
bool mbHasGlobPos
Was user position a valid record?
bool mbGlobValidRec
Record ID for user defined position.
std::size_t Read(void *pData, std::size_t nBytes)
Reads nBytes bytes to the existing(!) buffer pData.
void SetNulSubstChar(sal_Unicode cNulSubst='?')
Sets a replacement character for NUL characters.
void SetupRecord()
Initializes all members after base stream has been sought to new record.
sal_uInt16 ReadRawData(void *pData, sal_uInt16 nBytes)
Reads and decrypts nBytes bytes to the existing(!) buffer pData.
bool JumpToNextStringContinue(bool &rb16Bit)
Goes to start of the next CONTINUE record while reading strings.
void Ignore(std::size_t nBytes)
Seeks forward inside the current record.
bool EnsureRawReadSize(sal_uInt16 nBytes)
Ensures that reading nBytes bytes is possible with next stream access.
std::size_t mnCurrRecSize
Start of next record header.
bool mbHasComplRec
Size of complete record data (with CONTINUEs).
sal_uInt16 mnAltContId
Current record ID (not the CONTINUE ID).
void PushPosition()
Pushes current position on user position stack.
sal_Unicode mcNulSubst
Bytes left in current raw record (without following CONTINUEs).
std::size_t mnComplRecSize
Helper for record position.
OUString ReadRawUniString(sal_uInt16 nChars, bool b16Bit)
Reads nChars characters and returns the string.
void IgnoreRawUniString(sal_uInt16 nChars, bool b16Bit)
Ignores nChars characters.
sal_uInt16 GetMaxRawReadSize(std::size_t nBytes) const
Returns the maximum size of raw data possible to read in one block.
sal_uInt16 mnGlobRecId
User defined position elsewhere in stream.
bool IsContinueId(sal_uInt16 nRecId) const
Returns true, if the passed ID is real or alternative continuation record ID.
sal_uInt16 mnRawRecSize
Current raw record ID (including CONTINUEs).
void SetupRawRecord()
Initializes all members after base stream has been sought to new raw record.
void CopyRecordToStream(SvStream &rOutStrm)
Copies the entire record to rOutStrm.
void IgnoreUniString(sal_uInt16 nChars, sal_uInt8 nFlags)
Ignores ext.
void PopPosition()
Seeks to last position from user position stack.
bool StartNextRecord()
Sets stream pointer to the start of the next record content.
bool mbValid
false = No more records to read.
std::size_t mnStreamSize
Is user position defined?
void SetDecrypter(XclImpDecrypterRef const &xDecrypter)
Enables decryption of record contents for the rest of the stream.
OUString ReadUniString()
Reads 16 bit character count, 8 bit flags, ext.
XclImpDecrypterRef mxDecrypter
Filter root data.
bool mbUseDecr
Automatic CONTINUE lookup on/off.
void CopyDecrypterFrom(const XclImpStream &rStrm)
Sets decrypter from another stream.
XclImpStream(SvStream &rInStrm, const XclImpRoot &rRoot)
Constructs the Excel record import stream using a TOOLS stream object.
OUString ReadRawByteString(sal_uInt16 nChars)
Reads nChar byte characters and returns the string.
OUString ReadByteString(bool b16BitLen)
Reads 8/16 bit string length, character array and returns the string.
void RewindRecord()
Sets stream pointer before current record and invalidates stream.
std::size_t GetRecSize()
Returns the data size of the whole record without record headers.
sal_uInt16 mnRawRecLeft
Current raw record size (without following CONTINUEs).
rtl_TextEncoding GetTextEncoding() const
Returns the text encoding to import/export byte strings.
static css::uno::Sequence< sal_Int8 > GenerateRandomByteSequence(sal_Int32 nLength)
void update(const SequenceAsHashMap &rSource)
bool Skip(std::size_t nDatLen)
bool VerifyKey(const sal_uInt8 *pSaltData, const sal_uInt8 *pSaltDigest)
virtual bool InitCipher(sal_uInt32 nCounter)=0
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16])=0
virtual css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
bool Decode(const void *pData, std::size_t nDatLen, sal_uInt8 *pBuffer, std::size_t nBufLen)
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16]) override
css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
void Skip(std::size_t nBytes)
bool VerifyKey(sal_uInt16 nKey, sal_uInt16 nHash) const
void InitKey(const sal_uInt8 pnPassData[16])
virtual void Decode(sal_uInt8 *pnData, std::size_t nBytes) override
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
DocPasswordVerifierResult
T sanitizing_min(T a, T b)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
#define STREAM_SEEK_TO_END
#define STREAM_SEEK_TO_BEGIN
TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
std::unique_ptr< char[]> aBuffer
std::shared_ptr< XclImpDecrypter > XclImpDecrypterRef
const sal_uInt16 EXC_BOF_BIFF4
const sal_uInt16 EXC_ID2_BOF
Text rotation: vertically stacked.
const sal_uInt16 EXC_BOF_BIFF8
const sal_uInt16 EXC_ID4_BOF
XclBiff
An enumeration for all Excel file format types (BIFF types).
@ EXC_BIFF_UNKNOWN
MS Excel 8.0 (97), 9.0 (2000), 10.0 (XP), 11.0 (2003)
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
const sal_uInt16 EXC_BOF_BIFF5
const sal_uInt16 EXC_ID5_BOF
const sal_uInt16 EXC_ID3_BOF
const sal_uInt16 EXC_BOF_BIFF2
const sal_uInt16 EXC_BOF_BIFF3
const ErrCode EXC_ENCR_ERROR_UNSUPP_CRYPT
const sal_uInt16 EXC_ENCR_BLOCKSIZE
const sal_uInt16 EXC_ID_UNKNOWN
const sal_uInt16 EXC_ID_CONT
const std::size_t EXC_REC_SEEK_TO_END
const sal_uInt8 EXC_STRF_RICH
const sal_uInt16 EXC_NUL
NUL character.
const sal_uInt8 EXC_NUL_C
LF character (unicode).
const sal_uInt8 EXC_STRF_UNKNOWN
const sal_uInt8 EXC_STRF_FAREAST
const sal_uInt8 EXC_STRF_16BIT