• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

okteta

  • sources
  • kde-4.12
  • kdesdk
  • okteta
  • kasten
  • controllers
  • view
  • structures
  • datatypes
  • strings
utf16stringdata.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Okteta Kasten Framework, made within the KDE community.
3  *
4  * Copyright 2011 Alex Richardson <alex.richardson@gmx.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) version 3, or any
10  * later version accepted by the membership of KDE e.V. (or its
11  * successor approved by the membership of KDE e.V.), which shall
12  * act as a proxy defined in Section 6 of version 3 of the license.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 
24 
25 #include "utf16stringdata.h"
26 
27 #include <QVarLengthArray>
28 
29 #include <KLocale>
30 #include <KDebug> //TODO remove
31 
32 #include <abstractbytearraymodel.h>
33 
34 #include "../topleveldatainformation.h"
35 #include "../dummydatainformation.h"
36 #include "stringdatainformation.h"
37 
38 Utf16StringData::Utf16StringData(StringDataInformation* parent)
39  : StringData(parent), mNonBMPCount(0)
40 {
41 }
42 
43 Utf16StringData::~Utf16StringData()
44 {
45 }
46 
47 QString Utf16StringData::charType() const
48 {
49  return mLittleEndian ? i18n("UTF16-LE char") : i18n("UTF16-BE char");
50 }
51 
52 QString Utf16StringData::typeName() const
53 {
54  return mLittleEndian ? i18n("UTF16-LE string") : i18n("UTF16-BE string");
55 }
56 
57 uint Utf16StringData::count() const
58 {
59  return mCodePoints.size();
60 }
61 
62 QString Utf16StringData::stringValue(int row) const
63 {
64  //TODO details
65  Q_ASSERT((uint)row < count());
66  //TODO show invalid values
67  uint val = mCodePoints.at(row);
68  QString number = QString::number(val, 16).toUpper();
69  if (number.length() == 1)
70  number = QLatin1String("0") + number;
71  if (val > UNICODE_MAX)
72  return i18n("Value too big: 0x%1", number);
73  else if (val > BMP_MAX) {
74  QString ret(2, Qt::Uninitialized);
75  ret[0] = QChar::highSurrogate(val);
76  ret[1] = QChar::lowSurrogate(val);
77  return i18n("%1 (U+%2)", ret, number);
78  }
79  else
80  return i18n("%1 (U+%2)", QString(QChar(mCodePoints.at(row))), number);
81 }
82 
83 QString Utf16StringData::completeString(bool skipInvalid) const
84 {
85  QVarLengthArray<QChar> data(mCodePoints.size() + mNonBMPCount);
86  int codePointCount = mCodePoints.size();
87  int i = 0;
88  for (int idx = 0; idx < codePointCount; ++idx) {
89  uint val = mCodePoints.at(idx);
90  if (val > UNICODE_MAX)
91  {
92  if (skipInvalid)
93  continue;
94  else
95  data[i] = QChar::ReplacementCharacter;
96  }
97  else if (val > BMP_MAX) {
98  data[i] = QChar::highSurrogate(val);
99  i++;
100  data[i] = QChar::lowSurrogate(val);
101  }
102  else
103  {
104  data[i] = QChar((ushort)val);
105  }
106  i++;
107  }
108  return QString(data.constData(), i);
109 }
110 
111 qint64 Utf16StringData::read(Okteta::AbstractByteArrayModel* input, Okteta::Address address,
112  BitCount64 bitsRemaining)
113 {
114  const int oldSize = count();
115  mNonBMPCount = 0;
116  if (mMode == CharCount)
117  {
118  mCodePoints.reserve(mLength.maxChars);
119  }
120  else if (mMode == ByteCount)
121  {
122  mCodePoints.reserve(mLength.maxBytes / 2);
123  }
124 
125  mParent->topLevelDataInformation()->_childCountAboutToChange(mParent, oldSize, 0);
126  mParent->topLevelDataInformation()->_childCountChanged(mParent, oldSize, 0);
127 
128  const uint oldMax = mCodePoints.size();
129  quint64 remaining = bitsRemaining;
130  Okteta::Address addr = address;
131  uint count = 0;
132  mEofReached = false;
133  if (((mMode & CharCount) && mLength.maxChars == 0)
134  || ((mMode & ByteCount) && mLength.maxBytes < 2))
135  return 0;
136 
137  bool eofAtStart = false;
138  if (bitsRemaining < 16)
139  eofAtStart = true;
140 
141  while (true)
142  {
143  if (remaining < 16)
144  {
145  mEofReached = true;
146  break;
147  }
148  uint codePoint;
149  ushort val;
150  bool terminate = false;
151 
152  if (mLittleEndian)
153  val = input->byte(addr) | (input->byte(addr + 1) << 8);
154  else
155  val = (input->byte(addr) << 8) | input->byte(addr + 1);
156  //high surrogate -> if is followed by low surrogate we have a 4 bit char
157  if (QChar::isHighSurrogate(val))
158  {
159  if (remaining < 32 || ((mMode & ByteCount) && (addr + 2 - address) / 2 >= Okteta::Address(mLength.maxBytes / 2)))
160  {
161  codePoint = val;
162  mEofReached = true;
163  terminate = true;
164  }
165  else
166  {
167  ushort val2;
168  if (mLittleEndian)
169  val2 = input->byte(addr + 2) | (input->byte(addr + 3) << 8);
170  else
171  val2 = (input->byte(addr + 2) << 8) | input->byte(addr + 3);
172 
173  if (QChar::isLowSurrogate(val2))
174  {
175  codePoint = QChar::surrogateToUcs4(val, val2);
176  remaining -= 16;
177  addr += 2;
178  mNonBMPCount++; // codepoint > 0xffff -> non BMP
179  }
180  else
181  codePoint = val;
182  }
183  }
184  else
185  {
186  codePoint = val;
187  }
188 
189  if (count < oldMax)
190  mCodePoints[count] = codePoint;
191  else
192  mCodePoints.append(codePoint);
193 
194  remaining -= 16;
195  addr += 2;
196  count++;
197 
198  //now check if we have to terminate
199  if (mMode & Sequence)
200  {
201  if (codePoint == mTerminationCodePoint)
202  terminate = true;
203  }
204  if (mMode & ByteCount)
205  {
206  // divide by two in case someone set length to an odd number of bytes
207  if ((addr - address) / 2 >= Okteta::Address(mLength.maxBytes / 2))
208  terminate = true;
209  }
210  if (mMode & CharCount)
211  {
212  if (count >= mLength.maxChars)
213  terminate = true;
214  }
215  if (mMode == None) {
216  kDebug() << "no termination mode set!!";
217  Q_ASSERT(false);
218  }
219  if (terminate)
220  break;
221  }
222  mCodePoints.resize(count);
223  mParent->topLevelDataInformation()->_childCountAboutToChange(mParent, 0, count);
224  mParent->topLevelDataInformation()->_childCountChanged(mParent, 0, count);
225 
226  if (eofAtStart)
227  return -1;
228  return (addr - address) * 8;
229 }
230 
231 BitCount32 Utf16StringData::size() const
232 {
233  //add 16 for every non BMP char, since they use 32 bits
234  return (mCodePoints.size() + mNonBMPCount) * 16;
235 }
236 
237 BitCount32 Utf16StringData::sizeAt(uint i) const
238 {
239  Q_ASSERT(i <= count());
240  uint val = mCodePoints.at(i);
241  return val > 0xffff ? 32 : 16;
242 }
Okteta::Address
qint32 Address
Definition: address.h:34
Okteta::AbstractByteArrayModel
could it be useful to hide the data access behind an iterator? * class KDataBufferIterator { public: ...
Definition: abstractbytearraymodel.h:79
abstractbytearraymodel.h
StringData
Definition: stringdata.h:36
DataInformation::topLevelDataInformation
TopLevelDataInformation * topLevelDataInformation() const
Definition: datainformation.cpp:240
Utf16StringData::charType
virtual QString charType() const
Definition: utf16stringdata.cpp:47
StringData::mLittleEndian
bool mLittleEndian
Definition: stringdata.h:89
Utf16StringData::~Utf16StringData
virtual ~Utf16StringData()
Definition: utf16stringdata.cpp:43
TopLevelDataInformation::_childCountAboutToChange
void _childCountAboutToChange(DataInformation *sender, uint oldCount, uint newCount)
Definition: topleveldatainformation.h:184
BitCount64
quint64 BitCount64
Definition: datainformationbase.h:42
TopLevelDataInformation::_childCountChanged
void _childCountChanged(DataInformation *sender, uint oldCount, uint newCount)
Definition: topleveldatainformation.h:192
StringData::ByteCount
Definition: stringdata.h:45
StringData::BMP_MAX
static const uint BMP_MAX
Definition: stringdata.h:79
stringdatainformation.h
Utf16StringData::stringValue
virtual QString stringValue(int row) const
Definition: utf16stringdata.cpp:62
BitCount32
quint32 BitCount32
Definition: datainformationbase.h:37
Utf16StringData::read
virtual qint64 read(Okteta::AbstractByteArrayModel *input, Okteta::Address address, BitCount64 bitsRemaining)
Definition: utf16stringdata.cpp:111
Utf16StringData::sizeAt
virtual BitCount32 sizeAt(uint i) const
Definition: utf16stringdata.cpp:237
Utf16StringData::Utf16StringData
Utf16StringData(StringDataInformation *parent)
Definition: utf16stringdata.cpp:38
StringData::mTerminationCodePoint
quint32 mTerminationCodePoint
Definition: stringdata.h:87
Utf16StringData::completeString
virtual QString completeString(bool skipInvalid=false) const
Definition: utf16stringdata.cpp:83
StringData::Sequence
Definition: stringdata.h:43
Utf16StringData::count
virtual uint count() const
Definition: utf16stringdata.cpp:57
Okteta::AbstractByteArrayModel::byte
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...
StringData::mLength
union StringData::@5 mLength
StringData::mMode
uint mMode
Definition: stringdata.h:88
Utf16StringData::size
virtual BitCount32 size() const
Definition: utf16stringdata.cpp:231
StringData::mParent
StringDataInformation * mParent
Definition: stringdata.h:82
StringData::None
Definition: stringdata.h:42
utf16stringdata.h
Utf16StringData::typeName
virtual QString typeName() const
Definition: utf16stringdata.cpp:52
StringData::mEofReached
bool mEofReached
Definition: stringdata.h:90
StringData::CharCount
Definition: stringdata.h:44
StringDataInformation
Definition: stringdatainformation.h:39
StringData::UNICODE_MAX
static const uint UNICODE_MAX
Definition: stringdata.h:78
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:04:09 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

okteta

Skip menu "okteta"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • okteta
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal