/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
*pInfo = 0;
pEndDestBuf = pDestBuf+nDestChars;
pEndSrcBuf = pSrcBuf+nSrcBytes; do
{ if ( pSrcBuf < pEndSrcBuf )
{
c = static_cast<unsignedchar>(*pSrcBuf);
/* End, when not a base64 character */
bBase64End = false; if ( c <= 0x7F )
{
nBase64Value = aImplBase64IndexTab[c]; if ( nBase64Value == 0xFF )
bBase64End = true;
}
} else
{
bEnd = true;
bBase64End = true;
}
if ( bShifted )
{ if ( bBase64End )
{
bShifted = false;
/* If the character causing us to drop out was SHIFT_IN */ /* or SHIFT_OUT, it may be a special escape for SHIFT_IN. */ /* The test for SHIFT_IN is not necessary, but allows */ /* an alternate form of UTF-7 where SHIFT_IN is escaped */ /* by SHIFT_IN. This only works for some values of */ /* SHIFT_IN. It is so implemented, because this comes */ /* from the official unicode book (The Unicode Standard, */ /* Version 2.0) and so I think, that someone of the */ /* world has used this feature. */ if ( !bEnd )
{ if ( (c == IMPL_SHIFT_IN_CHAR) || (c == IMPL_SHIFT_OUT_CHAR) )
{ /* If no base64 character, and the terminating */ /* character of the shift sequence was the */ /* SHIFT_OUT_CHAR, then it't a special escape */ /* for SHIFT_IN_CHAR. */ if ( bFirst && (c == IMPL_SHIFT_OUT_CHAR) )
{ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL; break;
}
*pDestBuf = IMPL_SHIFT_IN_CHAR;
pDestBuf++;
bWroteOne = true;
}
/* Skip character */
pSrcBuf++; if ( pSrcBuf < pEndSrcBuf )
c = static_cast<unsignedchar>(*pSrcBuf); else
bEnd = true;
}
}
/* Empty sequence not allowed, so when we don't write one */ /* valid char, then the sequence is corrupt */ if ( !bWroteOne )
{ /* When no more bytes in the source buffer, then */ /* this buffer may be too small */ if ( bEnd )
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL; else
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR )
{ if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) { if (!bEnd) {
++pSrcBuf;
}
} else { //TODO: move pSrcBuf back to a reasonable starting place
}
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; break;
} /* We insert here no default char, because I think */ /* this is better to ignore this */
}
}
} else
{ /* Add 6 Bits from character to the bit buffer */
nBufferBits += 6;
nBitBuffer |= static_cast<sal_uInt32>(nBase64Value & 0x3F) << (32-nBufferBits);
bFirst = false;
}
/* Extract as many full 16 bit characters as possible from the */ /* bit buffer. */ while ( (pDestBuf < pEndDestBuf) && (nBufferBits >= 16) )
{
nBitBufferTemp = nBitBuffer >> (32-16);
*pDestBuf = static_cast<sal_Unicode>(nBitBufferTemp & 0xFFFF);
pDestBuf++;
nBitBuffer <<= 16;
nBufferBits -= 16;
bWroteOne = true;
}
if ( bBase64End )
{ /* Sequence ended and we have some bits, then the */ /* sequence is corrupted */ if ( nBufferBits && nBitBuffer )
{ /* When no more bytes in the source buffer, then */ /* this buffer may be too small */ if ( bEnd )
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL; else
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR )
{ if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) { if (!bEnd) {
++pSrcBuf;
}
} else { //TODO: move pSrcBuf back to a reasonable starting place
}
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; break;
} if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) != RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE )
{ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL; break;
}
*pDestBuf++
= RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
}
}
}
nBitBuffer = 0;
nBufferBits = 0;
}
}
if ( !bEnd )
{ if ( !bShifted )
{ if ( c == IMPL_SHIFT_IN_CHAR )
{
bShifted = true;
bFirst = true;
bWroteOne = false;
} else
{ /* No direct encoded character, then the buffer is */ /* corrupt */ if ( c > 0x7F )
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR )
{ if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) {
++pSrcBuf;
}
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; break;
} if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) != RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE )
{ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL; break;
}
*pDestBuf++
= RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
}
} else
{ /* Write char to unicode buffer */ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL; break;
}
*pDestBuf = c;
pDestBuf++;
*pInfo = 0;
pEndDestBuf = pDestBuf+nDestBytes;
pEndSrcBuf = pSrcBuf+nSrcChars; do
{ if ( pSrcBuf < pEndSrcBuf )
{
c = *pSrcBuf;
bNeedShift = (c > 0x7F) || aImplMustShiftTab[c]; if ( bNeedShift && !bShifted )
{ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; break;
}
*pDestBuf = IMPL_SHIFT_IN_CHAR;
pDestBuf++; /* Special case handling for SHIFT_IN_CHAR */ if ( c == IMPL_SHIFT_IN_CHAR )
{ if ( pDestBuf >= pEndDestBuf )
{
*pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; break;
}
*pDestBuf = IMPL_SHIFT_OUT_CHAR;
pDestBuf++;
} else
bShifted = true;
}
} else
{
bEnd = true;
bNeedShift = false;
}
if ( bShifted )
{ /* Write the character to the bit buffer, or pad the bit */ /* buffer out to a full base64 character */ if ( bNeedShift )
{
nBufferBits += 16;
nBitBuffer |= static_cast<sal_uInt32>(c) << (32-nBufferBits);
} else
nBufferBits += (6-(nBufferBits%6))%6;
/* Flush out as many full base64 characters as possible */ while ( (pDestBuf < pEndDestBuf) && (nBufferBits >= 6) )
{
nBitBufferTemp = nBitBuffer >> (32-6);
*pDestBuf = aImplBase64Tab[nBitBufferTemp];
pDestBuf++;
nBitBuffer <<= 6;
nBufferBits -= 6;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.