27 #include <QVarLengthArray>
34 #include "../topleveldatainformation.h"
35 #include "../dummydatainformation.h"
39 :
StringData(parent), mOneByteCount(0), mTwoByteCount(0), mThreeByteCount(0), mFourByteCount(0), mNonBMPCount(0)
49 return i18n(
"UTF8 char");
54 return i18n(
"UTF8 string");
59 return mCodePoints.size();
64 Q_ASSERT((uint)row <
count());
66 uint val = mCodePoints.at(row);
67 QString number = QString::number(val, 16).toUpper();
68 if (number.length() == 1)
69 number = QLatin1String(
"0") + number;
71 return i18n(
"Value too big: 0x%1", number);
73 QString ret(2, Qt::Uninitialized);
74 ret[0] = QChar::highSurrogate(val);
75 ret[1] = QChar::lowSurrogate(val);
76 return i18n(
"%1 (U+%2)", ret, number);
79 return i18n(
"%1 (U+%2)", QString(QChar(mCodePoints.at(row))), number);
84 QVarLengthArray<QChar> data(mCodePoints.size() + mNonBMPCount);
85 int codePointCount = mCodePoints.size();
87 for (
int idx = 0; idx < codePointCount; ++idx) {
88 uint val = mCodePoints.at(idx);
95 data[i] = QChar::ReplacementCharacter;
98 data[i] = QChar::highSurrogate(val);
100 data[i] = QChar::lowSurrogate(val);
104 data[i] = QChar((ushort)val);
108 return QString(data.constData(), i);
114 const int oldSize =
count();
122 mCodePoints.reserve(
mLength.maxChars);
126 mCodePoints.reserve(
mLength.maxBytes / 1.5);
132 const uint oldMax = mCodePoints.size();
133 quint64 remaining = bitsRemaining;
141 bool eofAtStart =
false;
142 if (bitsRemaining < 8)
153 quint8 byte = input->
byte(addr);
154 bool terminate =
false;
161 else if ((byte & 0xe0) == 0xc0)
164 if (byte == 0xc0 || byte == 0xc1)
167 mErrorIndices[
count] = 1;
170 else if (remaining < 16)
174 mErrorIndices[
count] = 1;
182 quint8 byte2 = input->
byte(addr);
183 if ((byte2 & 0xc0) != 0x80)
185 mErrorIndices[
count] = 2;
186 codePoint = (byte << 8) | byte2;
190 codePoint = (byte2 & 0x3f) | ((byte & 0x1f) << 6);
194 else if ((byte & 0xf0) == 0xe0)
199 mErrorIndices[
count] = 1;
203 else if (remaining < 24)
206 mErrorIndices[
count] = 2;
209 codePoint = (byte << 8) | input->
byte(addr);
216 quint8 byte2 = input->
byte(addr);
218 quint8 byte3 = input->
byte(addr);
219 if ((byte2 & 0xc0) != 0x80 || (byte3 & 0xc0) != 0x80)
221 mErrorIndices[
count] = 3;
222 codePoint = (byte << 16) | (byte2 << 8) | byte3;
226 codePoint = (byte3 & 0x3f) | ((byte2 & 0x3f) << 6) | ((byte & 0x1f) << 12);
230 else if ((byte & 0xf8) == 0xf0)
235 mErrorIndices[
count] = 1;
239 else if (remaining < 24)
242 mErrorIndices[
count] = 2;
245 codePoint = (byte << 8) | input->
byte(addr);
248 else if (remaining < 32)
251 mErrorIndices[
count] = 3;
252 codePoint = (byte << 16) | (input->
byte(addr + 1) << 8) | input->
byte(addr + 2);
262 quint8 byte2 = input->
byte(addr);
264 quint8 byte3 = input->
byte(addr);
266 quint8 byte4 = input->
byte(addr);
267 if ((byte2 & 0xc0) != 0x80 || (byte3 & 0xc0) != 0x80 || (byte4 & 0xc0) != 0x80)
269 mErrorIndices[
count] = 3;
270 codePoint = (byte << 16) | (byte2 << 8) | byte3;
274 codePoint = (byte4 & 0x3f) | ((byte3 & 0x3f) << 6)
275 | ((byte2 & 0x3f) << 12) | ((byte & 0x1f) << 18);
278 mErrorIndices[
count] = 4;
280 codePoint = (byte << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
286 mErrorIndices[
count] = 1;
294 mCodePoints[
count] = codePoint;
296 mCodePoints.append(codePoint);
308 if (
mMode & ByteCount)
311 if (uint(addr - address) >=
mLength.maxBytes)
314 if (
mMode & CharCount)
320 kDebug() <<
"no termination mode set!!";
326 mCodePoints.resize(count);
332 return (addr - address) * 8;
338 return (mOneByteCount + mTwoByteCount * 2 + mThreeByteCount * 3 + mFourByteCount * 4) * 8;
343 Q_ASSERT(i <=
count());
344 quint8 isError = mErrorIndices[i];
347 uint val = mCodePoints.at(i);
350 else if (val < 0x7ff)
352 else if (val < 0xffff)
could it be useful to hide the data access behind an iterator? * class KDataBufferIterator { public: ...
virtual uint count() const
virtual BitCount32 size() const
virtual BitCount32 sizeAt(uint i) const
static const uint BMP_MAX
virtual QString stringValue(int row) const
static const char ASCII_MAX
virtual QString typeName() const
quint32 mTerminationCodePoint
virtual Byte byte(Address offset) const =0
locates working range The idea behind is to tell buffer which range will be requested in the followin...
union StringData::@5 mLength
StringDataInformation * mParent
virtual QString completeString(bool skipInvalid=false) const
virtual QString charType() const
virtual qint64 read(Okteta::AbstractByteArrayModel *input, Okteta::Address address, BitCount64 bitsRemaining)
Utf8StringData(StringDataInformation *parent)
virtual ~Utf8StringData()
static const uint UNICODE_MAX