• 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
  • array
primitivearraydata.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, 2012 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 #include "primitivearraydata.h"
23 #include "arraydatainformation.h"
24 #include "../primitive/primitivedatainformation.h"
25 #include "../../script/scriptlogger.h"
26 #include "../../script/safereference.h"
27 
28 #include <abstractbytearraymodel.h>
29 
30 #include <limits>
31 #include <KLocalizedString>
32 #include <KDebug>
33 
34 
35 template<PrimitiveDataTypeEnum type>
36 inline PrimitiveArrayData<type>::PrimitiveArrayData(unsigned int initialLength, PrimitiveDataInformation* childType,
37  ArrayDataInformation* parent)
38  : AbstractArrayData(childType, parent), mNumReadValues(0), mDummy(parent)
39 {
40  Q_ASSERT(childType->type() == type);
41  mData.reserve(initialLength);
42  mData.resize(initialLength);
43 }
44 
45 template<PrimitiveDataTypeEnum type>
46 qint64 PrimitiveArrayData<type>::readData(Okteta::AbstractByteArrayModel* input, Okteta::Address address,
47  BitCount64 bitsRemaining)
48 {
49  Q_ASSERT(bitsRemaining % 8 == 0);
50  if (this->length() == 0)
51  return 0; //no need to read anything
52  //integer division -> gives us the desired result, limited by the number of items in this array
53  const quint64 maxRemaining = (bitsRemaining / 8) / sizeof(T);
54  //since its 64 bits may be larger than a 32 bit value and have all lower 32 bits as zero
55  //therefore we use std::numeric_limits::max()
56  quint32 maxRemaining32 = (maxRemaining > std::numeric_limits<quint32>::max()
57  ? std::numeric_limits<quint32>::max() : quint32(maxRemaining));
58  const quint32 maxNumItems = qMin(this->length(), maxRemaining32);
59  if (maxNumItems == 0)
60  return -1; //reached EOF
61  const QSysInfo::Endian byteOrder = AbstractArrayData::mParent->effectiveByteOrder();
62  if (byteOrder == QSysInfo::ByteOrder)
63  this->readDataNativeOrder(maxNumItems, input, address);
64  else
65  this->readDataNonNativeOrder(maxNumItems, input, address);
66  this->mNumReadValues = maxNumItems;
67  return maxNumItems * sizeof(T) * 8;
68 }
69 
70 template<PrimitiveDataTypeEnum type>
71 void PrimitiveArrayData<type>::readDataNativeOrder(uint numItems, Okteta::AbstractByteArrayModel* input,
72  Okteta::Address address)
73 {
74  Q_ASSERT(numItems <= length());
75  const Okteta::Size numBytes = numItems * sizeof(T);
76  Q_ASSERT(input->size() >= numBytes + address);
77  Q_UNUSED(numBytes);
78  Okteta::Byte* vectorBytes = reinterpret_cast<Okteta::Byte*>(this->mData.data());
79  const Okteta::Size numCopied = input->copyTo(vectorBytes, address, numItems * sizeof(T));
80  Q_ASSERT(numCopied == numBytes);
81  Q_UNUSED(numCopied);
82 }
83 
84 template<PrimitiveDataTypeEnum type>
85 void PrimitiveArrayData<type>::readDataNonNativeOrder(uint numItems, Okteta::AbstractByteArrayModel* input,
86  Okteta::Address address)
87 {
88  Q_ASSERT(numItems <= length());
89  const uint numBytes = numItems * sizeof(T);
90  Q_ASSERT(uint(input->size()) >= numBytes + address);
91  Okteta::Byte* vectorBytes = reinterpret_cast<Okteta::Byte*>(this->mData.data());
92  for (uint itemOffs = 0; itemOffs < numBytes; itemOffs += sizeof(T))
93  {
94  //the compiler should unroll this loop
95  for (uint byte = 0; byte < sizeof(T); byte++)
96  {
97  vectorBytes[itemOffs + byte] = input->byte(address + itemOffs + (sizeof(T) - byte - 1));
98  }
99  }
100 }
101 
102 template<PrimitiveDataTypeEnum type>
103 bool PrimitiveArrayData<type>::setChildData(uint row, QVariant value, Okteta::AbstractByteArrayModel* out,
104  Okteta::Address address, BitCount64 bitsRemaining)
105 {
106  Q_ASSERT(row < length());
107  Q_ASSERT(value.isValid());
108  Q_ASSERT(bitsRemaining % 8 == 0);
109  if ((row + 1) * sizeof(T) * 8 >= bitsRemaining)
110  {
111  this->mParent->logInfo() << " not enough bits remaining ("
112  << bitsRemaining << ") need " << ((row + 1) * sizeof(T) * 8);
113  return false;
114  }
115  QSysInfo::Endian byteOrder = AbstractArrayData::mParent->effectiveByteOrder();
116  bool littleEndian = byteOrder == QSysInfo::LittleEndian;
117  bool ok = false;
118  T convertedVal = DisplayClass::fromVariant(value, &ok);
119  if (!ok) {
120  this->mParent->logWarn() << "could not convert" << value << "to" << type;
121  return false;
122  }
123  kDebug() << AbstractArrayData::mParent->fullObjectPath() << "setting index" << row << "to"
124  << value << "(= " << convertedVal << ")";
125  this->mData[row] = convertedVal;
126  this->writeOneItem(convertedVal, address + (row * sizeof(T)), out, littleEndian);
127  return true;
128 }
129 
130 
131 
132 template<PrimitiveDataTypeEnum type>
133 void PrimitiveArrayData<type>::writeOneItem(T value, Okteta::Address addr,
134  Okteta::AbstractByteArrayModel* out, bool littleEndian)
135 {
136  if (littleEndian)
137  {
138  for (uint i = 0; i < sizeof(T); ++i)
139  {
140  //compiler should be smart enough not to create a loop
141  quint8 val = (quint64(value) & (quint64(0xff) << (8 * i))) >> (8 * i);
142  out->setByte(addr + i, val);
143  }
144  }
145  else
146  {
147  for (uint i = 0; i < sizeof(T); ++i)
148  {
149  //compiler should be smart enough not to create a loop
150  quint8 val = (quint64(value) & (quint64(0xff) << (8 * (sizeof(T) - i)))) >> (8 * (sizeof(T) - i));
151  out->setByte(addr + i, val);
152  }
153  }
154 }
155 
156 template<>
157 void PrimitiveArrayData<Type_Float>::writeOneItem(float value, Okteta::Address addr,
158  Okteta::AbstractByteArrayModel* out, bool littleEndian)
159 {
160  Q_ASSERT(sizeof(float) == sizeof(quint32));
161  union { quint32 intVal; float floatVal; } un;
162  un.floatVal = value;
163  PrimitiveArrayData<Type_UInt32>::writeOneItem(un.intVal, addr, out, littleEndian);
164 }
165 
166 template<>
167 void PrimitiveArrayData<Type_Double>::writeOneItem(double value, Okteta::Address addr,
168  Okteta::AbstractByteArrayModel* out, bool littleEndian)
169 {
170  Q_ASSERT(sizeof(double) == sizeof(quint64));
171  union { quint64 intVal; double doubleVal; } un;
172  un.doubleVal = value;
173  PrimitiveArrayData<Type_UInt64>::writeOneItem(un.intVal, addr, out, littleEndian);
174 }
175 
176 template<PrimitiveDataTypeEnum type>
177 QVariant PrimitiveArrayData<type>::dataAt(uint index, int column, int role)
178 {
179  Q_ASSERT(index < length());
180  if (role == Qt::DisplayRole)
181  {
182  if (column == DataInformation::ColumnName)
183  return QString(QLatin1Char('[') + QString::number(index) + QLatin1Char(']'));
184  if (column == DataInformation::ColumnType)
185  return PrimitiveType::typeName(type);
186  if (column == DataInformation::ColumnValue)
187  {
188  //if we are outside the valid range
189  if (uint(index) >= this->mNumReadValues)
190  return DataInformation::eofReachedData(Qt::DisplayRole);
191  else
192  return DisplayClass::staticValueString(mData.at(index));
193  }
194  }
195  if (column == DataInformation::ColumnValue && uint(index) >= this->mNumReadValues)
196  return DataInformation::eofReachedData(role);
197  return QVariant();
198 }
199 
200 template<PrimitiveDataTypeEnum type>
201 QString PrimitiveArrayData<type>::typeName() const
202 {
203  return QString(PrimitiveType::typeName(type) + QLatin1Char('[')
204  + QString::number(this->length()) + QLatin1Char(']'));
205 }
206 
207 template<PrimitiveDataTypeEnum type>
208 int PrimitiveArrayData<type>::indexOf(const DataInformation* data) const
209 {
210  if (data == &mDummy)
211  return this->mDummy.dummyIndex();
212  if (data == mChildType.data())
213  return this->mDummy.dummyIndex();
214  Q_ASSERT_X(false, "PrimitiveArrayData::indexOf", "Logic error, should never be reached");
215  return -1;
216 }
217 
218 template<PrimitiveDataTypeEnum type>
219 QScriptValue PrimitiveArrayData<type>::toScriptValue(uint index, QScriptEngine* engine, ScriptHandlerInfo* handlerInfo)
220 {
221  Q_ASSERT(index < length());
222  //invalidate all previous references
223  SafeReferenceHolder::instance.invalidateAll(mChildType.data());
224  mChildType->mWasAbleToRead = this->mNumReadValues > index;
225  mChildType->asPrimitive()->setValue(this->mData.at(index));
226  mChildType->setName(QString::number(index));
227  mDummy.setDummyIndex(index);
228  return mChildType->toScriptValue(engine, handlerInfo);
229 
230 }
231 
232 template<PrimitiveDataTypeEnum type>
233 QWidget* PrimitiveArrayData<type>::createChildEditWidget(uint index, QWidget* parent) const
234 {
235  Q_ASSERT(index < length());
236  Q_UNUSED(index)
237  return DisplayClass::staticCreateEditWidget(parent);
238 }
239 
240 template<PrimitiveDataTypeEnum type>
241 QVariant PrimitiveArrayData<type>::dataFromChildWidget(uint index, const QWidget* w) const
242 {
243  Q_ASSERT(index < length());
244  Q_UNUSED(index)
245  return DisplayClass::staticDataFromWidget(w);
246 }
247 
248 template<PrimitiveDataTypeEnum type>
249 void PrimitiveArrayData<type>::setChildWidgetData(uint index, QWidget* w) const
250 {
251  Q_ASSERT(index < length());
252  Q_UNUSED(index)
253  DisplayClass::staticSetWidgetData(mData.at(index), w);
254 }
255 
256 
257 //now instantiate all the template instances
258 template class PrimitiveArrayData<Type_Bool8>;
259 template class PrimitiveArrayData<Type_Bool16>;
260 template class PrimitiveArrayData<Type_Bool32>;
261 template class PrimitiveArrayData<Type_Bool64>;
262 template class PrimitiveArrayData<Type_Int8>;
263 template class PrimitiveArrayData<Type_Int16>;
264 template class PrimitiveArrayData<Type_Int32>;
265 template class PrimitiveArrayData<Type_Int64>;
266 template class PrimitiveArrayData<Type_UInt8>;
267 template class PrimitiveArrayData<Type_UInt16>;
268 template class PrimitiveArrayData<Type_UInt32>;
269 template class PrimitiveArrayData<Type_UInt64>;
270 template class PrimitiveArrayData<Type_Char>;
271 template class PrimitiveArrayData<Type_Float>;
272 template class PrimitiveArrayData<Type_Double>;
DataInformation
Interface that must be implemented by all datatypes.
Definition: datainformation.h:67
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
DataInformation::fullObjectPath
QString fullObjectPath() const
Definition: datainformation.cpp:258
DataInformation::effectiveByteOrder
QSysInfo::Endian effectiveByteOrder() const
Definition: datainformation.h:389
abstractbytearraymodel.h
PrimitiveArrayData::T
PrimitiveInfo< type >::valueType T
Definition: primitivearraydata.h:36
PrimitiveType::typeName
QString typeName(PrimitiveDataType type)
Definition: primitivedatatype.cpp:68
PrimitiveArrayData::setChildWidgetData
virtual void setChildWidgetData(uint index, QWidget *w) const
Definition: primitivearraydata.cpp:249
BitCount64
quint64 BitCount64
Definition: datainformationbase.h:42
primitivearraydata.h
QWidget
Okteta::Byte
unsigned char Byte
Definition: byte.h:29
DataInformation::ColumnType
Definition: datainformation.h:84
PrimitiveArrayData::dataFromChildWidget
virtual QVariant dataFromChildWidget(uint index, const QWidget *w) const
Definition: primitivearraydata.cpp:241
PrimitiveDataInformation::type
virtual PrimitiveDataType type() const =0
PrimitiveArrayData::mData
QVector< T > mData
Definition: primitivearraydata.h:78
DataInformation::ColumnValue
Definition: datainformation.h:84
AbstractArrayData
Definition: abstractarraydata.h:46
PrimitiveArrayData::PrimitiveArrayData
PrimitiveArrayData(unsigned int initialLength, PrimitiveDataInformation *childType, ArrayDataInformation *parent)
Definition: primitivearraydata.cpp:36
PrimitiveArrayData::dataAt
virtual QVariant dataAt(uint index, int column, int role)
Definition: primitivearraydata.cpp:177
ArrayDataInformation
Definition: arraydatainformation.h:36
Okteta::AbstractByteArrayModel::copyTo
virtual Size copyTo(Byte *dest, const AddressRange &copyRange) const
copies the data of the section into a given array Dest.
Definition: abstractbytearraymodel.cpp:60
PrimitiveArrayData::indexOf
virtual int indexOf(const DataInformation *data) const
Definition: primitivearraydata.cpp:208
Okteta::AbstractByteArrayModel::size
virtual Size size() const =0
Okteta::ByteOrder
ByteOrder
Definition: oktetacore.h:111
Okteta::AbstractByteArrayModel::setByte
virtual void setByte(Address offset, Byte byte)=0
sets a single byte if the offset is not valid the behaviour is undefined
PrimitiveArrayData::typeName
virtual QString typeName() const
Definition: primitivearraydata.cpp:201
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...
DataInformation::ColumnName
Definition: datainformation.h:84
PrimitiveArrayData
Definition: primitivearraydata.h:32
AbstractArrayData::mParent
ArrayDataInformation * mParent
Definition: abstractarraydata.h:90
PrimitiveArrayData::createChildEditWidget
virtual QWidget * createChildEditWidget(uint index, QWidget *parent) const
Definition: primitivearraydata.cpp:233
PrimitiveArrayData::readDataNonNativeOrder
void readDataNonNativeOrder(uint numItems, Okteta::AbstractByteArrayModel *input, Okteta::Address addr)
reads numItems items from the input, sizes must have been checked before calling this method!! ...
Definition: primitivearraydata.cpp:85
PrimitiveArrayData::setChildData
virtual bool setChildData(uint row, QVariant value, Okteta::AbstractByteArrayModel *out, Okteta::Address address, BitCount64 bitsRemaining)
Definition: primitivearraydata.cpp:103
DataInformation::data
virtual QVariant data(int column, int role) const
get the necessary data (for the model)
Definition: datainformation.cpp:156
ScriptHandlerInfo
Definition: scripthandlerinfo.h:39
PrimitiveArrayData::toScriptValue
virtual QScriptValue toScriptValue(uint index, QScriptEngine *engine, ScriptHandlerInfo *handlerInfo)
Definition: primitivearraydata.cpp:219
arraydatainformation.h
PrimitiveArrayData::writeOneItem
static void writeOneItem(T value, Okteta::Address addr, Okteta::AbstractByteArrayModel *out, bool littleEndian)
Definition: primitivearraydata.cpp:133
Okteta::Size
qint32 Size
Definition: size.h:33
PrimitiveArrayData::readData
virtual qint64 readData(Okteta::AbstractByteArrayModel *input, Okteta::Address address, BitCount64 bitsRemaining)
Definition: primitivearraydata.cpp:46
LittleEndian
Definition: endianness.h:32
SafeReferenceHolder::instance
static SafeReferenceHolder instance
Definition: safereference.h:41
PrimitiveArrayData::readDataNativeOrder
void readDataNativeOrder(uint numItems, Okteta::AbstractByteArrayModel *input, Okteta::Address addr)
reads numItems items from the input, sizes must have been checked before calling this method!! ...
Definition: primitivearraydata.cpp:71
PrimitiveDataInformation
A base class for all primitive data elements (e.g.
Definition: primitivedatainformation.h:34
DataInformation::eofReachedData
static QVariant eofReachedData(int role)
Definition: datainformation.cpp:189
SafeReferenceHolder::invalidateAll
void invalidateAll(DataInformation *data)
sets all refereces to this object to null
Definition: safereference.cpp:30
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:04:08 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