• 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
topleveldatainformation.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 2010, 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 #include "topleveldatainformation.h"
24 #include "datainformation.h"
25 #include "primitive/pointerdatainformation.h"
26 #include "datainformationwithchildren.h"
27 
28 #include "../script/scripthandler.h"
29 #include "../script/scriptlogger.h"
30 #include "../script/scriptengineinitializer.h"
31 #include "primitivefactory.h"
32 
33 #include <abstractbytearraymodel.h>
34 
35 #include <QScriptEngine>
36 
37 #include <KDebug>
38 
39 #include <limits>
40 
41 const quint64 TopLevelDataInformation::INVALID_OFFSET = std::numeric_limits<quint64>::max();
42 
43 TopLevelDataInformation::TopLevelDataInformation(DataInformation* data, ScriptLogger* logger,
44  QScriptEngine* engine, const QFileInfo& structureFile)
45  : QObject(0), mData(data), mLogger(logger), mStructureFile(structureFile),
46  mIndex(-1), mValid(!data->isDummy()), mChildDataChanged(false),
47  mDefaultLockOffset(INVALID_OFFSET), mLastReadOffset(INVALID_OFFSET), mLastModel(0)
48 {
49  Q_CHECK_PTR(mData);
50  mData->setParent(this);
51  setObjectName(mData->name());
52 
53  if (!mLogger)
54  mLogger.reset(new ScriptLogger());
55 
56  if (!engine)
57  engine = ScriptEngineInitializer::newEngine();
58  mScriptHandler.reset(new ScriptHandler(engine, this));
59 }
60 
61 TopLevelDataInformation::~TopLevelDataInformation()
62 {
63 }
64 
65 void TopLevelDataInformation::validate()
66 {
67  logger()->info(mData.data()) << "Validation requested.";
68  mScriptHandler->validateData(mData.data());
69 }
70 
71 QScriptEngine* TopLevelDataInformation::scriptEngine() const
72 {
73  return mScriptHandler->engine();
74 }
75 
76 void TopLevelDataInformation::resetValidationState()
77 {
78  mData->resetValidationState();
79 }
80 
81 void TopLevelDataInformation::read(Okteta::AbstractByteArrayModel* input, Okteta::Address address,
82  const Okteta::ArrayChangeMetricsList& changesList, bool forceRead)
83 {
84  mChildDataChanged = false;
85  const bool updateNeccessary = forceRead || isReadingNecessary(input, address, changesList);
86  if (!updateNeccessary)
87  return;
88 
89  quint64 remainingBits = (input->size() - address) * 8;
90  quint8 bitOffset = 0;
91  mData->beginRead(); //before reading set wasAbleToRead to false
92  mData->resetValidationState(); //reading new data -> validation state is old
93  const DataInformation* oldData = mData.data();
94  mScriptHandler->updateDataInformation(mData.data()); //unlikely that this is useful, but maybe someone needs it
95  if (mData.data() != oldData)
96  mLogger->info() << "Main element was replaced!";
97  mData->readData(input, address, remainingBits, &bitOffset);
98 
99  // Read all the delayed PointerDataInformation
100  // We do this because the pointed data is independent from the
101  // structure containing the pointer and so we can use fields
102  // which come after the pointer itself in the structure
103  while (!mDelayedRead.isEmpty())
104  mDelayedRead.dequeue()->delayedReadData(input, address);
105 
106  if (mChildDataChanged)
107  {
108  emit dataChanged();
109  mChildDataChanged = false;
110  }
111  mLastModel = input;
112  mLastReadOffset = address;
113 }
114 
115 void TopLevelDataInformation::enqueueReadData(PointerDataInformation* toRead)
116 {
117  mDelayedRead.append(toRead);
118 }
119 
120 bool TopLevelDataInformation::isReadingNecessary(Okteta::AbstractByteArrayModel* model,
121  Okteta::Address address, const Okteta::ArrayChangeMetricsList& changesList)
122 {
123  if (model != mLastModel)
124  return true; //whenever we have a new model we have to read
125 
126  if (isLockedFor(model))
127  address = lockPositionFor(model);
128 
129  if (quint64(address) != mLastReadOffset)
130  return true; //address as changed, we have to read again
131 
132  //address has not changed, check whether the changes affect us
133 
134  //TODO always return true if structure contains pointers
135  if (changesList.isEmpty())
136  return false; //no changes
137  const Okteta::Address structureSizeInBytes = (mData->size() / 8) + (mData->size() % 8 == 0 ? 0 : 1);
138  const Okteta::Address end = address + structureSizeInBytes;
139  for (int i = 0; i < changesList.length(); ++i)
140  {
141  const Okteta::ArrayChangeMetrics& change = changesList.at(i);
142  //this is valid for all types
143  if (change.offset() >= end)
144  {
145  //insertion/deletion/swapping is after end of structure, it doesn't interest us
146  continue;
147  }
148  //now handle special cases
149  else if (change.type() == Okteta::ArrayChangeMetrics::Replacement)
150  {
151  //handle it for replacements
152  if (change.lengthChange() == 0 && change.offset() + change.removeLength() <= address) {
153  //no length change and it doesn't affect structure since it is before
154  //could use insertLength() instead of removeLength() since they are the same
155  continue;
156  }
157  else {
158  //something was removed/inserted before start of structure
159  //which means all bytes have moved forwards/backwards: reread all
160  return true;
161  }
162  }
163  else if (change.type() == Okteta::ArrayChangeMetrics::Swapping)
164  {
165  if (change.secondEnd() < address) {
166  //swapped ranges end before start, i.e. the range of interest does not change
167  continue;
168  }
169  else {
170  //Not sure what other possibilities there are, but rather waste CPU or I/O rereading
171  //than showing outdated values
172  return true;
173  }
174  }
175  else
176  {
177  kDebug() << "Invalid change";
178  continue;
179  }
180  }
181  return false; //nothing affected us
182 }
183 
184 void TopLevelDataInformation::lockPositionToOffset(Okteta::Address offset, const Okteta::AbstractByteArrayModel* model)
185 {
186  if (quint64(offset) == INVALID_OFFSET)
187  {
188  //we use quint64 max to indicate not locked -> error out
189  mLogger->error() << "Attempting to lock at uint64_max, this is forbidden.";
190  return;
191  }
192  mLockedPositions.insert(model, quint64(offset));
193  kDebug() << mData->name() << ": Locking start offset in model" << model << "to position" << hex << offset;
194  //remove when deleted
195  connect(model, SIGNAL(destroyed(QObject*)), this, SLOT(removeByteArrayModelFromList(QObject*)));
196 }
197 
198 void TopLevelDataInformation::unlockPosition(const Okteta::AbstractByteArrayModel* model)
199 {
200  Q_ASSERT(mLockedPositions.contains(model) && mLockedPositions.value(model) != INVALID_OFFSET);
201  kDebug() << "removing lock at position" << mLockedPositions.value(model) << ", model=" << model;
202  mLockedPositions.insert(model, INVALID_OFFSET);
203 }
204 
205 void TopLevelDataInformation::removeByteArrayModelFromList(QObject* obj)
206 {
207  Q_ASSERT(qobject_cast<Okteta::AbstractByteArrayModel*>(obj));
208  const Okteta::AbstractByteArrayModel* model = static_cast<Okteta::AbstractByteArrayModel*>(obj);
209  mLockedPositions.remove(model);
210 }
211 
212 bool TopLevelDataInformation::isLockedByDefault() const
213 {
214  return mDefaultLockOffset != INVALID_OFFSET;
215 }
216 
217 void TopLevelDataInformation::setDefaultLockOffset(Okteta::Address offset)
218 {
219  if (quint64(offset) == INVALID_OFFSET)
220  {
221  //we use quint64 max to indicate not locked -> error out
222  mLogger->error() << "Attempting to lock by default at uint64_max, this is forbidden.";
223  return;
224  }
225  mDefaultLockOffset = offset;
226 }
227 
228 void TopLevelDataInformation::newModelActivated(Okteta::AbstractByteArrayModel* model)
229 {
230  //don't add null pointers to map
231  if (model && !mLockedPositions.contains(model))
232  {
233  //if this structure has no default lock offset, mDefaultLockOfsset will contain NOT_LOCKED
234  mLockedPositions.insert(model, mDefaultLockOffset);
235  if (mDefaultLockOffset == INVALID_OFFSET)
236  kDebug() << "new model activated:" << model << ", not locked.";
237  else
238  kDebug() << "new model activated:" << model << ", locked at 0x" << QString::number(mDefaultLockOffset, 16);
239  }
240 }
241 
242 bool TopLevelDataInformation::isLockedFor(const Okteta::AbstractByteArrayModel* model) const
243 {
244  Q_ASSERT(mLockedPositions.contains(model));
245  return mLockedPositions.value(model, 0) != INVALID_OFFSET;
246 }
247 
248 quint64 TopLevelDataInformation::lockPositionFor(const Okteta::AbstractByteArrayModel* model) const
249 {
250  Q_ASSERT(mLockedPositions.contains(model) && mLockedPositions.value(model) != INVALID_OFFSET);
251  return mLockedPositions.value(model);
252 }
253 
254 int TopLevelDataInformation::indexOf(const DataInformation* const data) const
255 {
256  Q_ASSERT(data == mData.data());
257  Q_UNUSED(data)
258  return mIndex;
259 }
260 
261 void TopLevelDataInformation::setActualDataInformation(DataInformation* newData)
262 {
263  Q_ASSERT(newData);
264  mData.reset(newData);
265 }
DataInformation
Interface that must be implemented by all datatypes.
Definition: datainformation.h:67
TopLevelDataInformation::read
void read(Okteta::AbstractByteArrayModel *input, Okteta::Address address, const Okteta::ArrayChangeMetricsList &changesList, bool forceRead)
Reads the necessary data from input.
Definition: topleveldatainformation.cpp:81
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
Okteta::ArrayChangeMetrics::type
int type() const
Definition: arraychangemetrics.h:140
Okteta::ArrayChangeMetrics::Replacement
Definition: arraychangemetrics.h:47
datainformation.h
PointerDataInformation
Definition: pointerdatainformation.h:30
Okteta::ArrayChangeMetrics::offset
Address offset() const
Definition: arraychangemetrics.h:141
Okteta::ArrayChangeMetrics::Swapping
Definition: arraychangemetrics.h:47
TopLevelDataInformation::unlockPosition
void unlockPosition(const Okteta::AbstractByteArrayModel *model)
Definition: topleveldatainformation.cpp:198
TopLevelDataInformation::dataChanged
void dataChanged()
QObject
TopLevelDataInformation::logger
ScriptLogger * logger() const
Definition: topleveldatainformation.h:174
TopLevelDataInformation::newModelActivated
void newModelActivated(Okteta::AbstractByteArrayModel *model)
Definition: topleveldatainformation.cpp:228
TopLevelDataInformation::setActualDataInformation
void setActualDataInformation(DataInformation *newData)
Definition: topleveldatainformation.cpp:261
Okteta::AbstractByteArrayModel::size
virtual Size size() const =0
TopLevelDataInformation::~TopLevelDataInformation
virtual ~TopLevelDataInformation()
Definition: topleveldatainformation.cpp:61
TopLevelDataInformation::isLockedByDefault
bool isLockedByDefault() const
Definition: topleveldatainformation.cpp:212
TopLevelDataInformation::resetValidationState
void resetValidationState()
Definition: topleveldatainformation.cpp:76
TopLevelDataInformation::enqueueReadData
void enqueueReadData(PointerDataInformation *toRead)
Definition: topleveldatainformation.cpp:115
ScriptEngineInitializer::newEngine
QScriptEngine * newEngine()
Definition: scriptengineinitializer.cpp:106
Okteta::ArrayChangeMetrics::secondEnd
Address secondEnd() const
Definition: arraychangemetrics.h:146
ScriptHandler
Definition: scripthandler.h:39
TopLevelDataInformation::scriptEngine
QScriptEngine * scriptEngine() const
Definition: topleveldatainformation.cpp:71
ScriptLogger
NOT THREAD SAFE!
Definition: scriptlogger.h:35
Okteta::ArrayChangeMetricsList
Definition: arraychangemetricslist.h:36
topleveldatainformation.h
TopLevelDataInformation::isLockedFor
bool isLockedFor(const Okteta::AbstractByteArrayModel *model) const
Definition: topleveldatainformation.cpp:242
TopLevelDataInformation::indexOf
int indexOf(const DataInformation *const data) const
Definition: topleveldatainformation.cpp:254
primitivefactory.h
TopLevelDataInformation::setDefaultLockOffset
void setDefaultLockOffset(Okteta::Address offset)
Definition: topleveldatainformation.cpp:217
ScriptLogger::info
QDebug info(const DataInformation *origin)
Definition: scriptlogger.h:66
Okteta::ArrayChangeMetrics::removeLength
Size removeLength() const
Definition: arraychangemetrics.h:142
pointerdatainformation.h
datainformationwithchildren.h
Okteta::ArrayChangeMetrics
Definition: arraychangemetrics.h:38
TopLevelDataInformation::lockPositionFor
quint64 lockPositionFor(const Okteta::AbstractByteArrayModel *model) const
Definition: topleveldatainformation.cpp:248
TopLevelDataInformation::lockPositionToOffset
void lockPositionToOffset(Okteta::Address offset, const Okteta::AbstractByteArrayModel *model)
Definition: topleveldatainformation.cpp:184
Okteta::ArrayChangeMetrics::lengthChange
Size lengthChange() const
Definition: arraychangemetrics.h:144
TopLevelDataInformation::validate
void validate()
Definition: topleveldatainformation.cpp:65
TopLevelDataInformation::INVALID_OFFSET
static const quint64 INVALID_OFFSET
Definition: topleveldatainformation.h:63
TopLevelDataInformation::TopLevelDataInformation
TopLevelDataInformation(DataInformation *data, ScriptLogger *logger=0, QScriptEngine *engine=0, const QFileInfo &structureFile=QFileInfo())
create a new TopLevelDataInformation wrapping data
Definition: topleveldatainformation.cpp:43
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