• 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
  • core
fixedsizebytearraymodel.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the Okteta Core library, made within the KDE community.
3 
4  Copyright 2003,2008 Friedrich W. H. Kossebau <kossebau@kde.org>
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 "fixedsizebytearraymodel.h"
24 
25 // lib
26 #include <arraychangemetricslist.h>
27 // C
28 #include <string.h>
29 
30 
31 namespace Okteta
32 {
33 
34 FixedSizeByteArrayModel::FixedSizeByteArrayModel( Byte* data, int size, Byte fillUpByte, QObject* parent )
35  : AbstractByteArrayModel( parent ),
36  mData( data ),
37  mSize( size ),
38  mFillUpByte( fillUpByte ),
39  mReadOnly( true ),
40  mModified( false ),
41  mAutoDelete( false )
42 {
43 }
44 
45 FixedSizeByteArrayModel::FixedSizeByteArrayModel( int size, Byte fillUpByte, QObject* parent )
46  : AbstractByteArrayModel( parent ),
47  mData( new Byte[size] ),
48  mSize( size ),
49  mFillUpByte( fillUpByte ),
50  mReadOnly( false ),
51  mModified( false ),
52  mAutoDelete( true )
53 {
54  reset( 0, size );
55 }
56 
57 
58 void FixedSizeByteArrayModel::setByte( Address offset, Byte byte )
59 {
60  const bool wasModifiedBefore = mModified;
61 
62  mData[offset] = byte;
63  mModified = true;
64 
65  emit contentsChanged( ArrayChangeMetricsList::oneReplacement(offset, 1, 1) );
66  if( ! wasModifiedBefore )
67  emit modifiedChanged( true );
68 }
69 
70 
71 
72 Size FixedSizeByteArrayModel::insert( Address offset, const Byte* insertData, int insertLength )
73 {
74  // check all parameters
75  if( offset >= mSize || insertLength == 0 )
76  return 0;
77 
78  const bool wasModifiedBefore = mModified;
79 
80  if( offset + insertLength > mSize )
81  insertLength = mSize - offset;
82 
83  const Address behindInsertOffset = offset + insertLength;
84  // fmove right data behind the input range
85  memmove( &mData[behindInsertOffset], &mData[offset], mSize-behindInsertOffset );
86  // insert input
87  memcpy( &mData[offset], insertData, insertLength );
88 
89  mModified = true;
90 
91  emit contentsChanged( ArrayChangeMetricsList::oneReplacement(offset, 0, insertLength) );
92  //emit contentsReplaced( offset, , 0 ); TODO: how to signal the removed data?
93  if( ! wasModifiedBefore )
94  emit modifiedChanged( true );
95 
96  return insertLength;
97 }
98 
99 
100 Size FixedSizeByteArrayModel::remove( const AddressRange& _removeRange )
101 {
102  AddressRange removeRange( _removeRange );
103  if( removeRange.start() >= mSize || removeRange.width() == 0 )
104  return 0;
105 
106  const bool wasModifiedBefore = mModified;
107 
108  removeRange.restrictEndTo( mSize-1 );
109 
110  const Size removeLength = removeRange.width();
111  const Address behindRemoveOffset = removeRange.nextBehindEnd();
112  // fmove right data behind the input range
113  memmove( &mData[removeRange.start()], &mData[behindRemoveOffset], mSize-behindRemoveOffset );
114  // clear freed space
115  reset( mSize-removeLength, removeLength );
116 
117  mModified = true;
118 
119  emit contentsChanged( ArrayChangeMetricsList::oneReplacement(removeRange.start(), removeRange.width(), 0) );
120  //emit contentsReplaced( offset, 0, ); TODO: how to signal the inserted data?
121  if( ! wasModifiedBefore )
122  emit modifiedChanged( true );
123 
124  return removeLength;
125 }
126 
127 
128 Size FixedSizeByteArrayModel::replace( const AddressRange& _removeRange, const Byte* insertData, int insertLength )
129 {
130  AddressRange removeRange( _removeRange );
131  // check all parameters
132  if( removeRange.startsBehind( mSize-1 ) || (removeRange.width()==0 && insertLength==0) )
133  return 0;
134 
135  const bool wasModifiedBefore = mModified;
136 
137  removeRange.restrictEndTo( mSize-1 );
138  if( removeRange.start() + insertLength > mSize )
139  insertLength = mSize - removeRange.start();
140 
141  const Size sizeDiff = insertLength - removeRange.width();
142 
143  // is input longer than removed?
144  if( sizeDiff > 0 )
145  {
146  const Address behindInsertOffset = removeRange.start() + insertLength;
147  // fmove right data behind the input range
148  memmove( &mData[behindInsertOffset], &mData[removeRange.nextBehindEnd()], mSize-behindInsertOffset );
149  }
150  // is input smaller than removed?
151  else if( sizeDiff < 0 )
152  {
153  const Address behindRemoveOffset = removeRange.nextBehindEnd();
154  // fmove right data behind the input range
155  memmove( &mData[removeRange.start()+insertLength], &mData[behindRemoveOffset], mSize-behindRemoveOffset );
156  // clear freed space
157  reset( mSize+sizeDiff, -sizeDiff );
158  }
159  // insert input
160  memcpy( &mData[removeRange.start()], insertData, insertLength );
161 
162  mModified = true;
163 
164  emit contentsChanged( ArrayChangeMetricsList::oneReplacement(removeRange.start(), removeRange.width(), insertLength) );
165  //emit contentsReplaced( offset, 0, ); TODO: how to signal the changed data at the end?
166  if( ! wasModifiedBefore )
167  emit modifiedChanged( true );
168 
169  return insertLength;
170 }
171 
172 
173 bool FixedSizeByteArrayModel::swap( Address firstStart, const AddressRange& _secondRange )
174 {
175  AddressRange secondRange( _secondRange );
176  // check all parameters
177  if( secondRange.start() >= mSize || secondRange.width() == 0
178  || firstStart > mSize || secondRange.start() == firstStart )
179  return false;
180 
181  const bool wasModifiedBefore = mModified;
182 
183  secondRange.restrictEndTo( mSize-1 );
184  const bool toRight = firstStart > secondRange.start();
185  const Size movedLength = secondRange.width();
186  const Size displacedLength = toRight ? firstStart - secondRange.end()-1 : secondRange.start() - firstStart;
187 
188  // find out section that is smaller
189  Size smallPartLength, largePartLength, smallPartStart, largePartStart, smallPartDest, largePartDest;
190  // moving part is smaller?
191  if( movedLength < displacedLength )
192  {
193  smallPartStart = secondRange.start();
194  smallPartLength = movedLength;
195  largePartLength = displacedLength;
196  // moving part moves right?
197  if( toRight )
198  {
199  smallPartDest = firstStart - movedLength;
200  largePartStart = secondRange.nextBehindEnd();
201  largePartDest = secondRange.start();
202  }
203  else
204  {
205  smallPartDest = firstStart;
206  largePartStart = firstStart;
207  largePartDest = firstStart + movedLength;
208  }
209  }
210  else
211  {
212  largePartStart = secondRange.start();
213  largePartLength = movedLength;
214  smallPartLength = displacedLength;
215  // moving part moves right?
216  if( toRight )
217  {
218  largePartDest = firstStart - movedLength;
219  smallPartStart = secondRange.nextBehindEnd();
220  smallPartDest = secondRange.start();
221  }
222  else
223  {
224  largePartDest = firstStart;
225  smallPartStart = firstStart;
226  smallPartDest = firstStart + movedLength;
227  }
228  }
229 
230  // copy smaller part to tempbuffer
231  Byte* tempBuffer = new Byte[smallPartLength];
232  memcpy( tempBuffer, &mData[smallPartStart], smallPartLength );
233 
234  // move the larger part
235  memmove( &mData[largePartDest], &mData[largePartStart], largePartLength );
236 
237  // copy smaller part to its new dest
238  memcpy( &mData[smallPartDest], tempBuffer, smallPartLength );
239  delete [] tempBuffer;
240 
241  mModified = true;
242 
243  emit contentsChanged( ArrayChangeMetricsList::oneSwapping(firstStart, secondRange.start(),secondRange.width()) );
244  if( ! wasModifiedBefore )
245  emit modifiedChanged( true );
246 
247  return true;
248 }
249 
250 
251 Size FixedSizeByteArrayModel::fill( Byte fillByte, Address offset, Size fillLength )
252 {
253  // nothing to fill
254  if( offset >= mSize )
255  return 0;
256 
257  const bool wasModifiedBefore = mModified;
258 
259  const Size lengthToEnd = mSize - offset;
260 
261  if( fillLength < 0 || fillLength > lengthToEnd )
262  fillLength = lengthToEnd;
263 
264  memset( &mData[offset], fillByte, fillLength );
265  mModified = true;
266 
267  emit contentsChanged( ArrayChangeMetricsList::oneReplacement(offset, fillLength, fillLength) );
268  if( ! wasModifiedBefore )
269  emit modifiedChanged( true );
270 
271  return fillLength;
272 }
273 
274 
275 int FixedSizeByteArrayModel::compare( const AbstractByteArrayModel& other, const AddressRange& _otherRange, Address offset )
276 {
277  AddressRange otherRange( _otherRange );
278  //kDebug() << QString("offset: %1, otherRange: (%3/%4)" ).arg(offset).arg(otherRange.start()).arg(otherRange.end())
279  // << endl;
280  // test other values
281  if( otherRange.startsBehind(other.size()-1) )
282  return 1;
283 
284  // check own values
285  if( offset >= mSize )
286  return -1;
287 
288  int valueByLength = 0; // default: equal
289 
290  AddressRange range = AddressRange::fromWidth( offset, otherRange.width() );
291  Address lastOffset = other.size()-1;
292  //
293  if( otherRange.endsBehind(lastOffset) )
294  {
295  // make shorter
296  otherRange.setEnd( lastOffset );
297  if( otherRange.width() < range.width() )
298  valueByLength = 1;
299  }
300  lastOffset = mSize-1;
301  if( range.endsBehind(lastOffset) )
302  {
303  // make shorter
304  range.setEnd( lastOffset );
305  if( otherRange.width() > range.width() )
306  valueByLength = -1;
307  }
308  //kDebug()
309  // << QString( "range: (%1/%2), otherRange: (%3/%4)" ).arg(range.start()).arg(range.end()).arg(otherRange.start()).arg(otherRange.end())
310  // << endl;
311  const Address rangeEnd = range.end();
312  Address oi = otherRange.start();
313  for( Address i=range.start(); i<=rangeEnd; ++i,++oi )
314  {
315  Byte OD = other.byte(oi);
316  Byte data = mData[i];
317  //kDebug() << QString("%1==%2").arg((int)data).arg((int)OD) ;
318  if( OD == data )
319  continue;
320  return ( OD < data ) ? 1 : -1;
321  }
322 
323  return valueByLength;
324 }
325 
326 
327 void FixedSizeByteArrayModel::reset( unsigned int offset, unsigned int length )
328 {
329  memset( &mData[offset], mFillUpByte, length );
330 }
331 
332 
333 FixedSizeByteArrayModel::~FixedSizeByteArrayModel()
334 {
335  if( mAutoDelete )
336  delete [] mData;
337 }
338 
339 }
Okteta::FixedSizeByteArrayModel::compare
int compare(const AbstractByteArrayModel &other, const AddressRange &otherRange, Address offset=0)
Definition: fixedsizebytearraymodel.cpp:275
Okteta::FixedSizeByteArrayModel::reset
void reset(unsigned int pos, unsigned int length)
Definition: fixedsizebytearraymodel.cpp:327
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
Okteta::FixedSizeByteArrayModel::swap
virtual bool swap(Address firstStart, const AddressRange &secondRange)
moves the second section before the start of the first which is the same as moving the first behind t...
Definition: fixedsizebytearraymodel.cpp:173
Okteta::FixedSizeByteArrayModel::fill
virtual Size fill(Byte fillByte, Address offset=0, Size fillLength=-1)
fills the buffer with the FillChar.
Definition: fixedsizebytearraymodel.cpp:251
Okteta::FixedSizeByteArrayModel::insert
virtual Size insert(Address offset, const Byte *insertData, int insertLength)
inserts bytes copied from the given source at Position.
Definition: fixedsizebytearraymodel.cpp:72
Okteta::ArrayChangeMetricsList::oneSwapping
static ArrayChangeMetricsList oneSwapping(Address firstOffset, Size secondOffset, Size secondLength)
Definition: arraychangemetricslist.h:52
KDE::NumberRange::nextBehindEnd
N nextBehindEnd() const
Definition: numberrange.h:145
KDE::NumberRange< Address, Size >
KDE::Range::start
T start() const
Definition: range.h:86
KDE::Range::setEnd
void setEnd(T E)
sets the last index of the range
Definition: range.h:60
Okteta::Byte
unsigned char Byte
Definition: byte.h:29
Okteta::AbstractByteArrayModel::modifiedChanged
void modifiedChanged(bool isModified)
Okteta::FixedSizeByteArrayModel::remove
virtual Size remove(const AddressRange &removeRange)
removes beginning with position as much as possible
Definition: fixedsizebytearraymodel.cpp:100
Okteta::FixedSizeByteArrayModel::mModified
bool mModified
Definition: fixedsizebytearraymodel.h:86
QObject
Okteta::FixedSizeByteArrayModel::FixedSizeByteArrayModel
FixedSizeByteArrayModel(Byte *data, int size, Byte fillUpChar= '\0', QObject *parent=0)
creates a readonly buffer around the given data
Definition: fixedsizebytearraymodel.cpp:34
KDE::NumberRange::width
S width() const
Definition: numberrange.h:141
Okteta::AbstractByteArrayModel::size
virtual Size size() const =0
Okteta::FixedSizeByteArrayModel::mSize
int mSize
Definition: fixedsizebytearraymodel.h:80
KDE::Range::restrictEndTo
void restrictEndTo(T Limit)
restricts the end to Limit.
Definition: range.h:69
fixedsizebytearraymodel.h
Okteta::FixedSizeByteArrayModel::replace
virtual Size replace(const AddressRange &removeRange, const Byte *insertData, int insertLength)
replaces as much as possible
Definition: fixedsizebytearraymodel.cpp:128
Okteta::FixedSizeByteArrayModel::byte
virtual Byte byte(Address offset) const
locates working range The idea behind is to tell buffer which range will be requested in the followin...
Definition: fixedsizebytearraymodel.h:92
KDE::Range::end
T end() const
Definition: range.h:88
KDE::NumberRange< Address, Size >::fromWidth
static NumberRange fromWidth(AddressstartIndex, Sizewidth)
constructs a range by width
Okteta::AbstractByteArrayModel::contentsChanged
void contentsChanged(const Okteta::ArrayChangeMetricsList &changeList)
Okteta::ArrayChangeMetricsList::oneReplacement
static ArrayChangeMetricsList oneReplacement(Address offset, Size removeLength, Size insertLength)
Definition: arraychangemetricslist.h:47
KDE::Range::endsBehind
bool endsBehind(T Value) const
returns true if the range ends later than index.
Definition: range.h:101
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...
arraychangemetricslist.h
Okteta::FixedSizeByteArrayModel::mFillUpByte
Byte mFillUpByte
Definition: fixedsizebytearraymodel.h:82
Okteta::FixedSizeByteArrayModel::setByte
virtual void setByte(Address offset, Byte byte)
sets a single byte if the offset is not valid the behaviour is undefined
Definition: fixedsizebytearraymodel.cpp:58
Okteta::Size
qint32 Size
Definition: size.h:33
Okteta::FixedSizeByteArrayModel::~FixedSizeByteArrayModel
virtual ~FixedSizeByteArrayModel()
Definition: fixedsizebytearraymodel.cpp:333
Okteta::FixedSizeByteArrayModel::mAutoDelete
bool mAutoDelete
Definition: fixedsizebytearraymodel.h:88
KDE::Range::startsBehind
bool startsBehind(T Value) const
returns true if range is behind index.
Definition: range.h:97
Okteta::FixedSizeByteArrayModel::mData
Byte * mData
Definition: fixedsizebytearraymodel.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: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