WARNING: USE THIS SOFTWARE AT YOUR OWN RISK! THIS IS EXPERIMENTAL SOFTWARE NOT INTENDED FOR PRODUCTION USE! Zuble is currently an early stage prototype. As such Zuble is minimally tested and inherently unstable. It is provided for experimental, development, and demonstration purposes only. Zuble QML Types   |  Zuble C++ Classes   |  Zuble Overview
Zuble  0.1
Zuble Framework C++/QML extension API
ZDataStream.cpp
Go to the documentation of this file.
1 /*
2  * Zuble - A run-time system for QML/Javascript applications
3  * Copyright (C) 2013, 2014 Bob Dinitto
4  *
5  * Filename: ZDataStream.cpp
6  * Created on: 11/9/2014
7  * Author: Bob Dinitto
8  *
9  * Zuble is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
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, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include "ZDataStream.h"
26 #include "ZByteArray.h"
27 #include <QtQml>
28 #include "zglobal.h"
29 
30 namespace Zbl
31 {
32 
33 QVariant ZDataStream::m_tags;
34 
35 
37 {
38  if(!m_tags.isNull())
39  return;
40 
41  QVariantMap map;
42 
43  map.insert("StatusOk", StatusOk);
44  map.insert("StatusReadPastEnd", StatusReadPastEnd);
45  map.insert("StatusReadCorruptData", StatusReadCorruptData);
46  map.insert("StatusWriteFailed", StatusWriteFailed);
47 
48  map.insert("ByteOrderBigEndian", ByteOrderBigEndian);
49  map.insert("ByteOrderLittleEndian", ByteOrderLittleEndian);
50 
51  map.insert("FpSinglePrecision", FpSinglePrecision);
52  map.insert("FpDoublePrecision", FpDoublePrecision);
53 
54  map.insert("Version_Qt_1_0", Version_Qt_1_0);
55  map.insert("Version_Qt_2_0", Version_Qt_2_0);
56  map.insert("Version_Qt_2_1", Version_Qt_2_1);
57  map.insert("Version_Qt_3_0", Version_Qt_3_0);
58  map.insert("Version_Qt_3_1", Version_Qt_3_1);
59  map.insert("Version_Qt_3_3", Version_Qt_3_3);
60  map.insert("Version_Qt_4_0", Version_Qt_4_0);
61  map.insert("Version_Qt_4_1", Version_Qt_4_1);
62  map.insert("Version_Qt_4_2", Version_Qt_4_2);
63  map.insert("Version_Qt_4_3", Version_Qt_4_3);
64  map.insert("Version_Qt_4_4", Version_Qt_4_4);
65  map.insert("Version_Qt_4_5", Version_Qt_4_5);
66  map.insert("Version_Qt_4_6", Version_Qt_4_6);
67  map.insert("Version_Qt_4_7", Version_Qt_4_7);
68  map.insert("Version_Qt_4_8", Version_Qt_4_8);
69  map.insert("Version_Qt_4_9", Version_Qt_4_9);
70  map.insert("Version_Qt_5_0", Version_Qt_5_0);
71  map.insert("Version_Qt_5_1", Version_Qt_5_1);
72  map.insert("Version_Qt_5_2", Version_Qt_5_2);
73  map.insert("Version_Qt_5_3", Version_Qt_5_3);
74  map.insert("Version_Qt_5_4", Version_Qt_5_4);
75  map.insert("Version_Qt_5_5", Version_Qt_5_5);
76  map.insert("Version_Qt_5_6", Version_Qt_5_6);
77  map.insert("Version_Qt_5_7", Version_Qt_5_7);
78  map.insert("Version_Qt_5_8", Version_Qt_5_8);
79  map.insert("Version_Qt_5_9", Version_Qt_5_9);
80  map.insert("Version_Qt_5_10", Version_Qt_5_10);
81  map.insert("Version_Qt_5_11", Version_Qt_5_11);
82  map.insert("Version_Qt_5_12", Version_Qt_5_12);
83  map.insert("Version_Qt_5_13", Version_Qt_5_13);
84 
85  m_tags = QVariant::fromValue(map);
86 }
87 
88 ZDataStream::ZDataStream(QObject *parent) :
89  QObject(parent)
90 {
91  qDebug("ZDataStream::ZDataStream");
92 
93  initZioDevice();
94 
95  createTags();
96 
97 }
98 
100  QObject(parent), m_dv(device)
101 {
102  qDebug("ZDataStream::ZDataStream - QIODevice");
103 
104  initZioDevice();
105 
106  createTags();
107 
108  m_ds = QDataStreamPtr::create();
109 
110  if(m_ds.isNull())
111  throw ZblException(
112  "ZDataStream::ZDataStream - error creating QDataStream object");
113 
114  m_ds->setDevice(m_dv.data());
115 }
116 
117 ZDataStream::ZDataStream(ZqByteArrayPtr byteArray, QObject *parent) :
118  QObject(parent), m_b(byteArray)
119 {
120  qDebug("ZDataStream::ZDataStream - QByteArray");
121 
122  initZioDevice();
123 
124  createTags();
125 
126  m_ds.reset(new QDataStream(byteArray.data(), QIODevice::ReadWrite));
127 
128  if(m_ds.isNull())
129  throw ZblException(
130  "ZDataStream::ZDataStream - error creating QDataStream object");
131 
132  qDebug() << "ZDataStream::ZDataStream - " << m_ds->device()->errorString();
133 }
134 
136 {
137  m_zd = new ZioDevice(this);
138 
139  connect(m_zd, SIGNAL(getCurrentDevice(QIODevice**)),
140  SLOT(getQDevice(QIODevice**)), Qt::DirectConnection);
141 }
142 
143 
145 {
146  qmlRegisterType<ZDataStream>("org.zuble.qml", 1, 0, "ZDataStream");
147 }
148 
150 {
151  if(!m_dv && !m_b)
152  throw ZblException("No device or byte array object available to stream.");
153 
154  if(!m_ds)
155  throw ZblException("Data stream object not initialized.");
156 }
157 
159 {
160  validateData();
161 
162  if(m_dv && !m_dv->isReadable())
163  throw ZblException(
164  "Error, device is not readable.");
165 }
166 
168 {
169  validateData();
170 
171  if(m_dv && !m_dv->isWritable())
172  throw ZblException(
173  "Error, device is not writable.");
174 }
175 
177 {
179  disconnect(m_zd, SIGNAL(getDevice(QIODevice**)), this,
180  SLOT(getQDevice(QIODevice**)));
181  m_ds.clear();
182  m_b.clear();
183  m_dv.clear();
185 }
186 
188 {
190  validateData();
191  m_ds->resetStatus();
193 }
194 
196 {
200 }
201 
203 {
204  *device = m_ds->device();
205 }
206 
208 {
210  validateData();
211  ZBL_SLOT_END_RETURN(static_cast<uint>(m_ds->status()), false,
213 }
214 
216 {
217  return m_tags;
218 }
219 
221 {
223  validateData();
224  m_ds->setByteOrder(QDataStream::ByteOrder(byteOrder));
226 }
227 
229 {
231  validateData();
232  ZBL_SLOT_END_RETURN(static_cast<uint>(m_ds->byteOrder()), false,
234 }
235 
237 {
239  validateData();
240  m_ds->setFloatingPointPrecision(
241  QDataStream::FloatingPointPrecision(floatingPointPrecision));
244 }
245 
247 {
249  validateData();
250  ZBL_SLOT_END_RETURN(static_cast<uint>(m_ds->floatingPointPrecision()), false,
253 }
254 
256 {
258  validateData();
259  m_ds->setVersion(QDataStream::Version(version));
261 }
262 
264 {
266  validateData();
267  ZBL_SLOT_END_RETURN(static_cast<uint>(m_ds->version()), false,
269 }
270 
271 bool ZDataStream::jWriteBytes(const QList<int> data)
272 {
273  qDebug("ZDataStream::jWriteBytes");
274  bool status = false;
275 
278  const int size = data.size();
279  char* bytes = new char[size];
280 
281  for(int i = 0; i < size; i++)
282  bytes[i] = static_cast<char>(data.at(i));
283 
284  qDebug("ZDataStream::jWriteBytes - writing %d bytes", size);
285 
286  m_ds->writeBytes(bytes, size);
287  status = m_ds->status() == QDataStream::Ok;
288  delete[] bytes;
289 
290  ZBL_SLOT_END_RETURN(status, false,
292 }
293 
295 {
296  qDebug("ZDataStream::jReadBytes");
297 
298  uint sizeReturned = 0;
299  QList<int> array;
300  char* data = NULL;
301 
304 
305  try
306  {
307  m_ds->readBytes(data, sizeReturned);
308 
309  qDebug("ZDataStream::jReadBytes - size returned = %u", sizeReturned);
310 
311  for(uint i = 0; i < sizeReturned; i++)
312  array.append(data[i]);
313 
314  if(data)
315  delete[] data;
316  }
317  catch(...)
318  {
319  if(data)
320  delete[] data;
321  throw;
322  }
323  ZBL_SLOT_END_RETURN(array, array,
325 
326 }
327 
329 {
330  qDebug("ZDataStream::zReadBytes");
331  QByteArray byteArray;
334  *m_ds.data() >> byteArray;
335  ZBL_SLOT_END_RETURN(new ZByteArray(byteArray), NULL,
337 }
338 
339 bool ZDataStream::zWriteBytes(QObject* zByteArray)
340 {
341  qDebug("ZDataStream::zWriteBytes");
344  ZByteArray* pByteArray = qobject_cast<ZByteArray*>(zByteArray);
345  if(!pByteArray)
346  throw ZblException("Object passed is not a ZByteArray.");
347  ZqByteArrayPtr byteArray(pByteArray->qByteArray());
348  *m_ds.data() << *byteArray.data();
349  ZBL_SLOT_END_RETURN(true, false,
351 }
352 
353 
354 bool ZDataStream::jWriteRawData(const QList<int> data)
355 {
356  qDebug("ZDataStream::jWriteBytes");
357  bool status = false;
358 
361 
362  const int size = data.size();
363  char* bytes = new char[size];
364 
365  try
366  {
367  for(int i = 0; i < size; i++)
368  bytes[i] = static_cast<qint8>(data.at(i));
369 
370  qDebug("ZDataStream::jWriteRawData - writing %d bytes", size);
371 
372  m_ds->writeRawData(static_cast<const char*>(bytes), size);
373  status = m_ds->status() == QDataStream::Ok;
374  delete[] bytes;
375 
376  }
377  catch(...)
378  {
379  delete[] bytes;
380  throw;
381  }
382 
383  ZBL_SLOT_END_RETURN(status, false,
385 }
386 
387 QList<int> ZDataStream::jReadRawData(uint len)
388 {
389  qDebug("ZDataStream::jReadRawData");
390 
391  int sizeReturned = 0;
392  QList<int> array;
393  char* data = new char[len];
394 
397 
398  try
399  {
400  sizeReturned = m_ds->readRawData(data, len);
401 
402  qDebug("ZDataStream::jReadRawData - size returned = %d", sizeReturned);
403 
404  if(sizeReturned == -1)
405  throw ZblException("QDataStream::readRawData encountered an error.");
406 
407  for(int i = 0; i < sizeReturned; i++)
408  array.append(data[i]);
409 
410  delete[] data;
411  }
412  catch(...)
413  {
414  if(data)
415  delete[] data;
416  throw;
417  }
418  ZBL_SLOT_END_RETURN(array, array,
420 
421 }
422 
423 QObject* ZDataStream::zReadRawData(uint len)
424 {
425  qDebug("ZDataStream::zReadRawData");
426  QByteArray byteArray;
427 
430  int sizeReturned = 0;
431  char* data = new char[len];
432 
433  try
434  {
435  sizeReturned = m_ds->readRawData(data, len);
436 
437  qDebug("ZDataStream::zReadRawData - size returned = %d", sizeReturned);
438 
439  if(sizeReturned == -1)
440  throw ZblException("QDataStream::readRawData encountered an error.");
441 
442  byteArray.append(data, sizeReturned);
443 
444  delete[] data;
445  }
446  catch(...)
447  {
448  delete[] data;
449  throw;
450  }
451 
452  ZBL_SLOT_END_RETURN(new ZByteArray(byteArray), NULL,
454 }
455 
456 bool ZDataStream::zWriteRawData(QObject* zByteArray)
457 {
458  qDebug("ZDataStream::zWriteRawData");
461  ZByteArray* pByteArray = qobject_cast<ZByteArray*>(zByteArray);
462  if(!pByteArray)
463  throw ZblException("Object passed is not a ZByteArray.");
464  ZqByteArrayPtr qByteArray(pByteArray->qByteArray());
465  const int size = qByteArray->size();
466  qDebug("ZDataStream::jWriteRawData - writing %d bytes", size);
467  m_ds->writeRawData(qByteArray->constData(), size);
468  ZBL_SLOT_END_RETURN(true, false,
470 }
471 
473 {
474  qDebug("ZDataStream::skipRawData");
475  int sizeReturned = -1;
477  sizeReturned = m_ds->skipRawData(len);
478  ZBL_SLOT_END_RETURN(sizeReturned, -1,
480 }
481 
482 
483 
484 #define readNumericDataType(dataType, className, methodName) \
485  dataType className::methodName() \
486  { \
487  qDebug("%s::%s", #className, #methodName); \
488  dataType data = 0; \
489  ZBL_SLOT_BEGIN_TRY \
490  validateReadable(); \
491  *m_ds >> data; \
492  ZBL_SLOT_END_RETURN(data, 0, \
493  Z_FAC_JS, className::methodName, methodName failed) \
494  }
495 
498 readNumericDataType(qint32, ZDataStream, readInt32)
499 readNumericDataType(quint32, ZDataStream, readUInt32)
500 readNumericDataType(qint64, ZDataStream, readInt64)
501 readNumericDataType(quint64, ZDataStream, readUInt64)
502 readNumericDataType(float, ZDataStream, readFloat)
503 readNumericDataType(double, ZDataStream, readDouble)
504 
505 quint8 ZDataStream::readByte()
506 {
507  qDebug("ZDataStream::readChar");
508  qint8 byte = 0;
511  *m_ds >> byte;
512  ZBL_SLOT_END_RETURN(byte, 0,
513  Z_FAC_JS, ZDataStream::readByte, readByte failed)
514 }
515 
516 #define writeNumericDataType(dataType, className, methodName) \
517  bool className::methodName(dataType data) \
518  { \
519  qDebug("%s::%s", #className, #methodName); \
520  ZBL_SLOT_BEGIN_TRY \
521  validateWritable(); \
522  *m_ds << data; \
523  ZBL_SLOT_END_RETURN(true, false, \
524  Z_FAC_JS, className::methodName, methodName failed) \
525  }
526 
527 
536 
537 bool ZDataStream::writeByte(quint8 data)
538 {
539  qDebug("ZDataStream::writeChar");
542  *m_ds << data; //static_cast<qint8>(data);
543  ZBL_SLOT_END_RETURN(true, false,
545 }
546 
547 #if 0
548 uint getStatus() const;
549 bool atEnd() const;
550 void setByteOrder(uint byteOrder);
551 uint getByteOrder() const;
552 
554 uint getFloatingPointPrecision() const;
555 
556 void setVersion(uint version);
557 uint getVersion() const;
558 #endif
559 
560 } // Zbl
This class supports streaming of text and binary data.
Definition: ZByteArray.h:41
Q_INVOKABLE bool jWriteBytes(const QList< int > data)
Q_INVOKABLE quint8 readByte()
Q_INVOKABLE uint skipRawData(uint len)
Q_INVOKABLE bool zWriteRawData(QObject *zByteArray)
void validateData() const
uint getVersion() const
ZioDevice * m_zd
Pointer to contained ZioDevice object.
Definition: ZDataStream.h:233
Q_INVOKABLE QObject * zReadBytes()
Q_INVOKABLE qint64 readInt64()
void setFloatingPointPrecision(uint floatingPointPrecision)
#define Z_FAC_JS
Definition: zglobal.h:123
Q_INVOKABLE bool writeUInt64(quint64 data)
Q_INVOKABLE quint32 readUInt32()
Q_INVOKABLE qint16 readInt16()
ZqByteArrayPtr m_b
Smartpointer to embedded QByteArray.
Definition: ZDataStream.h:223
void validateWritable() const
static QVariant m_tags
QVariantMap of QDataStream enumerations for use by Javascript programs.
Definition: ZDataStream.h:239
Q_INVOKABLE float readFloat()
Q_INVOKABLE bool writeFloat(float data)
void validateReadable() const
Reads and writes binary data to an i/o stream.
Definition: ZDataStream.h:53
uint floatingPointPrecision
Definition: ZDataStream.h:145
ZDataStream(QObject *parent=0)
Definition: ZDataStream.cpp:88
A javascript wrapper for QIODevice.
Definition: ZioDevice.h:40
Definition: ZAndGate.cpp:6
#define ZBL_SLOT_BEGIN_TRY
Definition: zglobal.h:128
Q_INVOKABLE bool writeByte(quint8 data)
Q_INVOKABLE qint32 readInt32()
Q_INVOKABLE void resetStatus()
Q_INVOKABLE bool writeInt32(qint32 data)
Q_INVOKABLE quint64 readUInt64()
Q_INVOKABLE QList< int > jReadBytes()
Q_INVOKABLE bool writeUInt16(quint16 data)
Q_INVOKABLE bool zWriteBytes(QObject *zByteArray)
Q_INVOKABLE QList< int > jReadRawData(uint len)
uint getStatus() const
#define ZBL_SLOT_END_VOID(facility, code, error_message)
Definition: zglobal.h:134
Q_INVOKABLE double readDouble()
uint getFloatingPointPrecision() const
static void registerType()
Registers ZDataStream as a QML type.
uint getByteOrder() const
QDataStreamPtr m_ds
Smartpointer to embedded QDataStream.
Definition: ZDataStream.h:228
Q_INVOKABLE bool writeInt64(qint64 data)
QVariant getTags()
QSharedPointer< QByteArray > ZqByteArrayPtr
Definition: zglobal.h:166
QObject * getJsDevice()
void getQDevice(QIODevice **device)
readNumericDataType(qint16, ZDataStream, readInt16) readNumericDataType(quint16
Q_INVOKABLE void release()
Zuble&#39;s Qt Exception Object.
Definition: ZblException.h:45
ZqIODevicePtr m_dv
Smartpointer to embedded QIODevice.
Definition: ZDataStream.h:218
Q_INVOKABLE bool writeUInt32(quint32 data)
ZqByteArrayPtr qByteArray()
Definition: ZByteArray.h:51
Q_INVOKABLE quint16 readUInt16()
Q_INVOKABLE bool writeDouble(double data)
QSharedPointer< QIODevice > ZqIODevicePtr
Definition: zglobal.h:164
Q_INVOKABLE QObject * zReadRawData(uint len)
writeNumericDataType(qint16, ZDataStream, writeInt16) writeNumericDataType(quint16
void setByteOrder(uint byteOrder)
Q_INVOKABLE bool writeInt16(qint16 data)
#define ZBL_SLOT_END_RETURN(return_success, return_failed, facility, code, error_message)
Definition: zglobal.h:141
void setVersion(uint version)
Q_INVOKABLE bool jWriteRawData(const QList< int > data)