QDaq  0.2.6
Qt-based Data Aqcuisition
 All Classes Functions Variables Typedefs Enumerations Enumerator Properties Groups Pages
bytearrayclass.cpp
1 #include <QtScript/QScriptClassPropertyIterator>
2 #include <QtScript/QScriptContext>
3 #include <QtScript/QScriptEngine>
4 #include "bytearrayclass.h"
5 #include "bytearrayprototype.h"
6 
7 #include <stdlib.h>
8 
9 Q_DECLARE_METATYPE(QByteArray*)
10 Q_DECLARE_METATYPE(ByteArrayClass*)
11 
12 class ByteArrayClassPropertyIterator : public QScriptClassPropertyIterator
13 {
14 public:
15  ByteArrayClassPropertyIterator(const QScriptValue &object);
16  ~ByteArrayClassPropertyIterator();
17 
18  bool hasNext() const;
19  void next();
20 
21  bool hasPrevious() const;
22  void previous();
23 
24  void toFront();
25  void toBack();
26 
27  QScriptString name() const;
28  uint id() const;
29 
30 private:
31  int m_index;
32  int m_last;
33 };
34 
36 ByteArrayClass::ByteArrayClass(QScriptEngine *engine)
37  : QObject(engine), QScriptClass(engine)
38 {
39  qScriptRegisterMetaType<QByteArray>(engine, toScriptValue, fromScriptValue);
40 
41  length = engine->toStringHandle(QLatin1String("length"));
42 
43  proto = engine->newQObject(new ByteArrayPrototype(this),
44  QScriptEngine::QtOwnership,
45  // QScriptEngine::SkipMethodsInEnumeration |
46  QScriptEngine::ExcludeSuperClassMethods |
47  QScriptEngine::ExcludeSuperClassProperties);
48  QScriptValue global = engine->globalObject();
49  proto.setPrototype(global.property("Object").property("prototype"));
50 
51  ctor = engine->newFunction(construct, proto);
52  ctor.setData(engine->toScriptValue(this));
53 }
55 
56 ByteArrayClass::~ByteArrayClass()
57 {
58 }
59 
61 QScriptClass::QueryFlags ByteArrayClass::queryProperty(const QScriptValue &object,
62  const QScriptString &name,
63  QueryFlags flags, uint *id)
64 {
65  QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
66  if (!ba)
67  return 0;
68  if (name == length) {
69  return flags;
70  } else {
71  bool isArrayIndex;
72  qint32 pos = name.toArrayIndex(&isArrayIndex);
73  if (!isArrayIndex)
74  return 0;
75  *id = pos;
76  if ((flags & HandlesReadAccess) && (pos >= ba->size()))
77  flags &= ~HandlesReadAccess;
78  return flags;
79  }
80 }
82 
84 QScriptValue ByteArrayClass::property(const QScriptValue &object,
85  const QScriptString &name, uint id)
86 {
87  QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
88  if (!ba)
89  return QScriptValue();
90  if (name == length) {
91  return ba->length();
92  } else {
93  qint32 pos = id;
94  if ((pos < 0) || (pos >= ba->size()))
95  return QScriptValue();
96  return uint(ba->at(pos)) & 255;
97  }
98  return QScriptValue();
99 }
101 
103 void ByteArrayClass::setProperty(QScriptValue &object,
104  const QScriptString &name,
105  uint id, const QScriptValue &value)
106 {
107  QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data());
108  if (!ba)
109  return;
110  if (name == length) {
111  resize(*ba, value.toInt32());
112  } else {
113  qint32 pos = id;
114  if (pos < 0)
115  return;
116  if (ba->size() <= pos)
117  resize(*ba, pos + 1);
118  (*ba)[pos] = char(value.toInt32());
119  }
120 }
122 
124 QScriptValue::PropertyFlags ByteArrayClass::propertyFlags(
125  const QScriptValue &/*object*/, const QScriptString &name, uint /*id*/)
126 {
127  if (name == length) {
128  return QScriptValue::Undeletable
129  | QScriptValue::SkipInEnumeration;
130  }
131  return QScriptValue::Undeletable;
132 }
134 
136 QScriptClassPropertyIterator *ByteArrayClass::newIterator(const QScriptValue &object)
137 {
138  return new ByteArrayClassPropertyIterator(object);
139 }
141 
142 QString ByteArrayClass::name() const
143 {
144  return QLatin1String("ByteArray");
145 }
146 
147 QScriptValue ByteArrayClass::prototype() const
148 {
149  return proto;
150 }
151 
152 QScriptValue ByteArrayClass::constructor()
153 {
154  return ctor;
155 }
156 
158 QScriptValue ByteArrayClass::newInstance(int size)
159 {
160  engine()->reportAdditionalMemoryCost(size);
161  return newInstance(QByteArray(size, /*ch=*/0));
162 }
164 
166 QScriptValue ByteArrayClass::newInstance(const QByteArray &ba)
167 {
168  QScriptValue data = engine()->newVariant(QVariant::fromValue(ba));
169  return engine()->newObject(this, data);
170 }
172 
174 QScriptValue ByteArrayClass::construct(QScriptContext *ctx, QScriptEngine *)
175 {
176  ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctx->callee().data());
177  if (!cls)
178  return QScriptValue();
179  QScriptValue arg = ctx->argument(0);
180  if (arg.instanceOf(ctx->callee()))
181  return cls->newInstance(qscriptvalue_cast<QByteArray>(arg));
182  else if (arg.isArray()) {
183  quint32 len = arg.property("length").toUInt32();
184  QByteArray ba((int)len,char(0));
185  for (quint32 i = 0; i < len; ++i) {
186  uint v = arg.property(i).toUInt32() & 255;
187  ba[i] = char(v);
188  }
189  return cls->newInstance(ba);
190  }
191  else if (arg.isString()) {
192  QString s = arg.toString();
193  QByteArray ba = s.toLatin1();
194  return cls->newInstance(ba);
195  }
196  else if (arg.isNumber()) {
197  int size = arg.toInt32();
198  return cls->newInstance(size);
199  }
200  return QScriptValue();
201 }
203 
204 QScriptValue ByteArrayClass::toScriptValue(QScriptEngine *eng, const QByteArray &ba)
205 {
206  QScriptValue ctor = eng->globalObject().property("ByteArray");
207  ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctor.data());
208  if (!cls)
209  return eng->newVariant(QVariant::fromValue(ba));
210  return cls->newInstance(ba);
211 }
212 
213 void ByteArrayClass::fromScriptValue(const QScriptValue &obj, QByteArray &ba)
214 {
215  ba = qvariant_cast<QByteArray>(obj.data().toVariant());
216 }
217 
219 void ByteArrayClass::resize(QByteArray &ba, int newSize)
220 {
221  int oldSize = ba.size();
222  ba.resize(newSize);
223  if (newSize > oldSize)
224  engine()->reportAdditionalMemoryCost(newSize - oldSize);
225 }
227 
228 
229 
230 ByteArrayClassPropertyIterator::ByteArrayClassPropertyIterator(const QScriptValue &object)
231  : QScriptClassPropertyIterator(object)
232 {
233  toFront();
234 }
235 
236 ByteArrayClassPropertyIterator::~ByteArrayClassPropertyIterator()
237 {
238 }
239 
241 bool ByteArrayClassPropertyIterator::hasNext() const
242 {
243  QByteArray *ba = qscriptvalue_cast<QByteArray*>(object().data());
244  return m_index < ba->size();
245 }
246 
247 void ByteArrayClassPropertyIterator::next()
248 {
249  m_last = m_index;
250  ++m_index;
251 }
252 
253 bool ByteArrayClassPropertyIterator::hasPrevious() const
254 {
255  return (m_index > 0);
256 }
257 
258 void ByteArrayClassPropertyIterator::previous()
259 {
260  --m_index;
261  m_last = m_index;
262 }
263 
264 void ByteArrayClassPropertyIterator::toFront()
265 {
266  m_index = 0;
267  m_last = -1;
268 }
269 
270 void ByteArrayClassPropertyIterator::toBack()
271 {
272  QByteArray *ba = qscriptvalue_cast<QByteArray*>(object().data());
273  m_index = ba->size();
274  m_last = -1;
275 }
276 
277 QScriptString ByteArrayClassPropertyIterator::name() const
278 {
279  return object().engine()->toStringHandle(QString::number(m_last));
280 }
281 
282 uint ByteArrayClassPropertyIterator::id() const
283 {
284  return m_last;
285 }
The prototype for the ByteArray class.