|
rpm-build |
9243a4 |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
rpm-build |
9243a4 |
/*
|
|
rpm-build |
9243a4 |
* This file is part of the libmspub project.
|
|
rpm-build |
9243a4 |
*
|
|
rpm-build |
9243a4 |
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
rpm-build |
9243a4 |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
rpm-build |
9243a4 |
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
rpm-build |
9243a4 |
*/
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#include "libmspub_utils.h"
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#include <cstdarg>
|
|
rpm-build |
9243a4 |
#include <cstring>
|
|
rpm-build |
9243a4 |
#include <string.h> // for memcpy
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#include <unicode/ucnv.h>
|
|
rpm-build |
9243a4 |
#include <unicode/utypes.h>
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#include <zlib.h>
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#define ZLIB_CHUNK 16384
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
namespace libmspub
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#ifdef DEBUG
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
void debugPrint(const char *const format, ...)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
va_list args;
|
|
rpm-build |
9243a4 |
va_start(args, format);
|
|
rpm-build |
9243a4 |
std::vfprintf(stderr, format, args);
|
|
rpm-build |
9243a4 |
va_end(args);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#endif
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
using std::strcmp;
|
|
rpm-build |
9243a4 |
const char *windowsCharsetNameByOriginalCharset(const char *name)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (strcmp(name, "Shift_JIS") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-932";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "GB18030") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-936";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "Big5") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-950";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "ISO-8859-1") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-1252";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "ISO-8859-2") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-1250";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "windows-1251") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-1251";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (strcmp(name, "windows-1256") == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return "windows-1256";
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
return nullptr;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
const char *mimeByImgType(ImgType type)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
switch (type)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
case PNG:
|
|
rpm-build |
9243a4 |
return "image/png";
|
|
rpm-build |
9243a4 |
case JPEG:
|
|
rpm-build |
9243a4 |
return "image/jpeg";
|
|
rpm-build |
9243a4 |
case DIB:
|
|
rpm-build |
9243a4 |
return "image/bmp";
|
|
rpm-build |
9243a4 |
case PICT:
|
|
rpm-build |
9243a4 |
return "image/pict";
|
|
rpm-build |
9243a4 |
case WMF:
|
|
rpm-build |
9243a4 |
return "image/wmf";
|
|
rpm-build |
9243a4 |
case EMF:
|
|
rpm-build |
9243a4 |
return "image/emf";
|
|
rpm-build |
9243a4 |
case TIFF:
|
|
rpm-build |
9243a4 |
return "image/tiff";
|
|
rpm-build |
9243a4 |
default:
|
|
rpm-build |
9243a4 |
MSPUB_DEBUG_MSG(("Unknown image type %d passed to mimeByImgType!\n", type));
|
|
rpm-build |
9243a4 |
return nullptr;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
void rotateCounter(double &x, double &y, double centerX, double centerY, short rotation)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
double vecX = x - centerX;
|
|
rpm-build |
9243a4 |
double vecY = centerY - y;
|
|
rpm-build |
9243a4 |
double sinTheta = sin(rotation * M_PI / 180.);
|
|
rpm-build |
9243a4 |
double cosTheta = cos(rotation * M_PI / 180.);
|
|
rpm-build |
9243a4 |
double newVecX = cosTheta * vecX - sinTheta * vecY;
|
|
rpm-build |
9243a4 |
double newVecY = sinTheta * vecX + cosTheta * vecY;
|
|
rpm-build |
9243a4 |
x = centerX + newVecX;
|
|
rpm-build |
9243a4 |
y = centerY - newVecY;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
double doubleModulo(double x, double y)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (y <= 0) // y <= 0 doesn't make sense
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return x;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
while (x < 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
x += y;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
while (x >= y)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
x -= y;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
return x;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
double toFixedPoint(int fp)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
unsigned short fractionalPart = ((unsigned short) fp) & 0xFFFF;
|
|
rpm-build |
9243a4 |
short integralPart = fp >> 16;
|
|
rpm-build |
9243a4 |
return integralPart + fractionalPart / 65536.;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
double readFixedPoint(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return toFixedPoint(readS32(input));
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
void flipIfNecessary(double &x, double &y, double centerX, double centerY, bool flipVertical, bool flipHorizontal)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
double vecX = x - centerX;
|
|
rpm-build |
9243a4 |
double vecY = centerY - y;
|
|
rpm-build |
9243a4 |
if (flipVertical)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
y = centerY + vecY;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (flipHorizontal)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
x = centerX - vecX;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
unsigned correctModulo(int x, unsigned n) // returns the canonical representation of x in Z/nZ
|
|
rpm-build |
9243a4 |
//difference with C++ % operator is that this never returns negative values.
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (x < 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
int result = x % (int)n;
|
|
rpm-build |
9243a4 |
//sign of result is implementation defined
|
|
rpm-build |
9243a4 |
if (result < 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return n + result;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
return result;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
return x % n;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
librevenge::RVNGBinaryData inflateData(librevenge::RVNGBinaryData deflated)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
librevenge::RVNGBinaryData inflated;
|
|
rpm-build |
9243a4 |
unsigned char out[ZLIB_CHUNK];
|
|
rpm-build |
9243a4 |
const unsigned char *data = deflated.getDataBuffer();
|
|
rpm-build |
9243a4 |
z_stream strm;
|
|
rpm-build |
9243a4 |
int ret;
|
|
rpm-build |
9243a4 |
strm.zalloc = Z_NULL;
|
|
rpm-build |
9243a4 |
strm.zfree = Z_NULL;
|
|
rpm-build |
9243a4 |
strm.opaque = Z_NULL;
|
|
rpm-build |
9243a4 |
strm.avail_in = 0;
|
|
rpm-build |
9243a4 |
strm.next_in = Z_NULL;
|
|
rpm-build |
9243a4 |
if (inflateInit2(&strm,-MAX_WBITS) != Z_OK)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return librevenge::RVNGBinaryData();
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
int have;
|
|
rpm-build |
9243a4 |
unsigned left = deflated.size();
|
|
rpm-build |
9243a4 |
do
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
strm.avail_in = ZLIB_CHUNK > left ? left : ZLIB_CHUNK;
|
|
rpm-build |
9243a4 |
strm.next_in = (unsigned char *)data;
|
|
rpm-build |
9243a4 |
do
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
strm.avail_out = ZLIB_CHUNK;
|
|
rpm-build |
9243a4 |
strm.next_out = out;
|
|
rpm-build |
9243a4 |
ret = inflate(&strm, Z_NO_FLUSH);
|
|
rpm-build |
9243a4 |
if (ret < 0 || ret == Z_NEED_DICT)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
inflateEnd(&strm;;
|
|
rpm-build |
9243a4 |
return librevenge::RVNGBinaryData();
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
have = ZLIB_CHUNK - strm.avail_out;
|
|
rpm-build |
9243a4 |
inflated.append(out, have);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
while (strm.avail_out == 0);
|
|
rpm-build |
9243a4 |
data += ZLIB_CHUNK > left ? left : ZLIB_CHUNK;
|
|
rpm-build |
9243a4 |
left -= ZLIB_CHUNK > left ? left : ZLIB_CHUNK;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
while (ret != Z_STREAM_END);
|
|
rpm-build |
9243a4 |
inflateEnd(&strm;;
|
|
rpm-build |
9243a4 |
return inflated;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
namespace
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
static void _appendUCS4(librevenge::RVNGString &text, unsigned ucs4Character)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
unsigned char first;
|
|
rpm-build |
9243a4 |
int len;
|
|
rpm-build |
9243a4 |
if (ucs4Character < 0x80)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0;
|
|
rpm-build |
9243a4 |
len = 1;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else if (ucs4Character < 0x800)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0xc0;
|
|
rpm-build |
9243a4 |
len = 2;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else if (ucs4Character < 0x10000)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0xe0;
|
|
rpm-build |
9243a4 |
len = 3;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else if (ucs4Character < 0x200000)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0xf0;
|
|
rpm-build |
9243a4 |
len = 4;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else if (ucs4Character < 0x4000000)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0xf8;
|
|
rpm-build |
9243a4 |
len = 5;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
first = 0xfc;
|
|
rpm-build |
9243a4 |
len = 6;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
char outbuf[7] = { 0 };
|
|
rpm-build |
9243a4 |
int i;
|
|
rpm-build |
9243a4 |
for (i = len - 1; i > 0; --i)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
outbuf[i] = char((ucs4Character & 0x3f) | 0x80);
|
|
rpm-build |
9243a4 |
ucs4Character >>= 6;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
outbuf[0] = char((ucs4Character & 0xff) | first);
|
|
rpm-build |
9243a4 |
outbuf[len] = '\0';
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
text.append(outbuf);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
} // anonymous namespace
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#define MSPUB_NUM_ELEMENTS(array) sizeof(array)/sizeof(array[0])
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
uint8_t readU8(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (!input || input->isEnd())
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
MSPUB_DEBUG_MSG(("Something bad happened here!"));
|
|
rpm-build |
9243a4 |
if (input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
MSPUB_DEBUG_MSG((" Tell: %ld\n", input->tell()));
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
throw EndOfStreamException();
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
unsigned long numBytesRead;
|
|
rpm-build |
9243a4 |
uint8_t const *p = input->read(sizeof(uint8_t), numBytesRead);
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
if (p && numBytesRead == sizeof(uint8_t))
|
|
rpm-build |
9243a4 |
return *(uint8_t const *)(p);
|
|
rpm-build |
9243a4 |
throw EndOfStreamException();
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
uint16_t readU16(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
auto p0 = (uint16_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p1 = (uint16_t)readU8(input);
|
|
rpm-build |
9243a4 |
return (uint16_t)(p0|(p1<<8));
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
uint32_t readU32(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
auto p0 = (uint32_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p1 = (uint32_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p2 = (uint32_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p3 = (uint32_t)readU8(input);
|
|
rpm-build |
9243a4 |
return (uint32_t)(p0|(p1<<8)|(p2<<16)|(p3<<24));
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
int8_t readS8(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return (int8_t)readU8(input);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
int16_t readS16(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return (int16_t)readU16(input);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
int32_t readS32(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
return (int32_t)readU32(input);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
uint64_t readU64(librevenge::RVNGInputStream *input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
auto p0 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p1 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p2 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p3 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p4 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p5 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p6 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
auto p7 = (uint64_t)readU8(input);
|
|
rpm-build |
9243a4 |
return (uint64_t)(p0|(p1<<8)|(p2<<16)|(p3<<24)|(p4<<32)|(p5<<40)|(p6<<48)|(p7<<56));
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
void readNBytes(librevenge::RVNGInputStream *input, unsigned long length, std::vector<unsigned char> &out)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (length == 0)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
MSPUB_DEBUG_MSG(("Attempt to read 0 bytes!"));
|
|
rpm-build |
9243a4 |
return;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
unsigned long numBytesRead = 0;
|
|
rpm-build |
9243a4 |
const unsigned char *tmpBuffer = input->read(length, numBytesRead);
|
|
rpm-build |
9243a4 |
if (numBytesRead != length)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
out.clear();
|
|
rpm-build |
9243a4 |
return;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
out = std::vector<unsigned char>(numBytesRead);
|
|
rpm-build |
9243a4 |
memcpy(out.data(), tmpBuffer, numBytesRead);
|
|
rpm-build |
9243a4 |
return;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
unsigned long getLength(librevenge::RVNGInputStream *const input)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (!input)
|
|
rpm-build |
9243a4 |
throw EndOfStreamException();
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
const long orig = input->tell();
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
unsigned long end = 0;
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
if (0 == input->seek(0, librevenge::RVNG_SEEK_END))
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
end = static_cast<unsigned long>(input->tell());
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
else
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
// RVNG_SEEK_END does not work. Use the harder way.
|
|
rpm-build |
9243a4 |
if (0 != input->seek(0, librevenge::RVNG_SEEK_SET))
|
|
rpm-build |
9243a4 |
throw EndOfStreamException();
|
|
rpm-build |
9243a4 |
while (!input->isEnd())
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
readU8(input);
|
|
rpm-build |
9243a4 |
++end;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
if (0 != input->seek(orig, librevenge::RVNG_SEEK_SET))
|
|
rpm-build |
9243a4 |
throw EndOfStreamException();
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
return end;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
#define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000)
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
void appendCharacters(librevenge::RVNGString &text, const std::vector<unsigned char> &characters,
|
|
rpm-build |
9243a4 |
const char *encoding)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (characters.empty())
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
MSPUB_DEBUG_MSG(("Attempt to append 0 characters!"));
|
|
rpm-build |
9243a4 |
return;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
UErrorCode status = U_ZERO_ERROR;
|
|
rpm-build |
9243a4 |
UConverter *conv = nullptr;
|
|
rpm-build |
9243a4 |
conv = ucnv_open(encoding, &status);
|
|
rpm-build |
9243a4 |
if (U_SUCCESS(status))
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
// ICU documentation claims that character-by-character processing is faster "for small amounts of data" and "'normal' charsets"
|
|
rpm-build |
9243a4 |
// (in any case, it is more convenient :) )
|
|
rpm-build |
9243a4 |
const auto *src = (const char *)characters.data();
|
|
rpm-build |
9243a4 |
const char *srcLimit = (const char *)src + characters.size();
|
|
rpm-build |
9243a4 |
while (src < srcLimit)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
auto ucs4Character = (uint32_t)ucnv_getNextUChar(conv, &src, srcLimit, &status);
|
|
rpm-build |
9243a4 |
if (U_SUCCESS(status))
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
_appendUCS4(text, ucs4Character);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
if (conv)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
ucnv_close(conv);
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
bool stillReading(librevenge::RVNGInputStream *input, unsigned long until)
|
|
rpm-build |
9243a4 |
{
|
|
rpm-build |
9243a4 |
if (input->isEnd())
|
|
rpm-build |
9243a4 |
return false;
|
|
rpm-build |
9243a4 |
if (input->tell() < 0)
|
|
rpm-build |
9243a4 |
return false;
|
|
rpm-build |
9243a4 |
if ((unsigned long)input->tell() >= until)
|
|
rpm-build |
9243a4 |
return false;
|
|
rpm-build |
9243a4 |
return true;
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
}
|
|
rpm-build |
9243a4 |
|
|
rpm-build |
9243a4 |
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
|