wasm: add native QByteArray conversion functions
Add functions which converts to and from JavaScript data arrays: static QByteArray::fromUint8Array(emscripten::val array) emscripten::val QByteArray::toUint8Array() const with corresponding internal qstdweb API: static Uint8Array Uint8Array::copyFrom(const QByteArray &buffer) QByteArray Uint8Array::copyToQByteArray() const Both functions will make a copy of the data, i.e. there is no shared reference counting. They take and return Uint8Array typed array views, via emscripten::val JavaScript object references. Unlike other native conversion functions, these have the special property that the data referenced by the native Uint8Array exists outside the heap memory area. This means we can’t e.g. memcpy the data. However, the heap is itself a JavaScript ArrayBuffer, and we can create a Uint8Array view to the buffer owned by the QByteArray, and then use JavaScript API to copy. See the qstdweb::Uint8Array::copy() implementation. That also means that a fromRawUint8Array() variant (which does not copy) is not possible to implement, since we can’t create a pointer to the source data. The inverse toRawUint8Array() is implementable - it would return a Uint8Array view which references the heap’s ArrayBuffer. However, this may turn out to be ill-advised, since Emscripten will create a new ArrayBuffer if/when it resizes the heap. In any case this left for a future expansion. Change-Id: Icaf48fd17ea8686bf04cb523cc1eb581ce63ed34 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Lorn Potter <lorn.potter@gmail.com>bb10
parent
3aaf5975e4
commit
01412ff16e
|
|
@ -461,4 +461,15 @@ QByteArray ba = QByteArrayLiteral("byte array contents");
|
|||
QByteArray encoded("Qt%20is%20great%33");
|
||||
QByteArray decoded = encoded.percentDecoded(); // Set to "Qt is great!"
|
||||
//! [54]
|
||||
|
||||
//! [55]
|
||||
emscripten::val uint8array = emscripten::val::global("g_uint8array");
|
||||
QByteArray byteArray = QByteArray::fromUint8Array(uint8array);
|
||||
//! [55]
|
||||
|
||||
//! [56]
|
||||
QByteArray byteArray = "test";
|
||||
emscripten::val uint8array = QByteArray::toUint8Array(byteArray);
|
||||
//! [56]
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -573,6 +573,18 @@ void Uint8Array::copyTo(char *destination) const
|
|||
Uint8Array(destination, length()).set(*this);
|
||||
}
|
||||
|
||||
// Copies the Uint8Array content to a destination QByteArray
|
||||
QByteArray Uint8Array::copyToQByteArray() const
|
||||
{
|
||||
if (length() > std::numeric_limits<qsizetype>::max())
|
||||
return QByteArray();
|
||||
|
||||
QByteArray destinationArray;
|
||||
destinationArray.resize(length());
|
||||
copyTo(destinationArray.data());
|
||||
return destinationArray;
|
||||
}
|
||||
|
||||
// Copies the Uint8Array content to a destination on the heap
|
||||
void Uint8Array::copy(char *destination, const Uint8Array &source)
|
||||
{
|
||||
|
|
@ -587,6 +599,12 @@ Uint8Array Uint8Array::copyFrom(const char *buffer, uint32_t size)
|
|||
return contentCopy;
|
||||
}
|
||||
|
||||
// Copies content from a QByteArray to a new Uint8Array object
|
||||
Uint8Array Uint8Array::copyFrom(const QByteArray &buffer)
|
||||
{
|
||||
return copyFrom(buffer.constData(), buffer.size());
|
||||
}
|
||||
|
||||
emscripten::val Uint8Array::val()
|
||||
{
|
||||
return m_uint8Array;
|
||||
|
|
|
|||
|
|
@ -128,8 +128,11 @@ namespace qstdweb {
|
|||
void set(const Uint8Array &source);
|
||||
|
||||
void copyTo(char *destination) const;
|
||||
QByteArray copyToQByteArray() const;
|
||||
|
||||
static void copy(char *destination, const Uint8Array &source);
|
||||
static Uint8Array copyFrom(const char *buffer, uint32_t size);
|
||||
static Uint8Array copyFrom(const QByteArray &buffer);
|
||||
emscripten::val val();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#include "qstringconverter_p.h"
|
||||
#include <qdatastream.h>
|
||||
#include <qmath.h>
|
||||
#if defined(Q_OS_WASM)
|
||||
#include "private/qstdweb_p.h"
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
#include <zconf.h>
|
||||
|
|
@ -4838,6 +4841,60 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WASM) || defined(Q_QDOC)
|
||||
|
||||
/*!
|
||||
\brief Constructs a new QByteArray containing a copy of the Uint8Array \a uint8array.
|
||||
|
||||
This function transfers data from a JavaScript data buffer - which
|
||||
is not addressable from C++ code - to heap memory owned by a QByteArray.
|
||||
The Uint8Array can be released once this function returns and a copy
|
||||
has been made.
|
||||
|
||||
The \a uint8array argument must an emscripten::val referencing an Uint8Array
|
||||
object, e.g. obtained from a global JavaScript variable:
|
||||
|
||||
\snippet code/src_corelib_text_qbytearray.cpp 55
|
||||
|
||||
This function returns a null QByteArray if the size of the Uint8Array
|
||||
exceeds the maximum capacity of QByteArray, or if the \a uint8array
|
||||
argument is not of the Uint8Array type.
|
||||
|
||||
\since 6.4
|
||||
\ingroup platform-type-conversions
|
||||
|
||||
\sa toUint8Array()
|
||||
*/
|
||||
|
||||
QByteArray QByteArray::fromUint8Array(emscripten::val uint8array)
|
||||
{
|
||||
return qstdweb::Uint8Array(uint8array).copyToQByteArray();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Creates a Uint8Array from a QByteArray
|
||||
|
||||
This function transfers data from heap memory owned by a QByteArray
|
||||
to a JavaScript data buffer. The function allocates and copies into an
|
||||
ArrayBuffer, and returns a Uint8Array view to that buffer.
|
||||
|
||||
The JavaScript objects own a copy of the data, and this
|
||||
QByteArray can be safely deleted after the copy has been made.
|
||||
|
||||
\snippet code/src_corelib_text_qbytearray.cpp 56
|
||||
|
||||
\since 6.4
|
||||
\ingroup platform-type-conversions
|
||||
|
||||
\sa toUint8Array()
|
||||
*/
|
||||
emscripten::val QByteArray::toUint8Array()
|
||||
{
|
||||
return qstdweb::Uint8Array::copyFrom(*this).val();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*! \typedef QByteArray::ConstIterator
|
||||
\internal
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ Q_FORWARD_DECLARE_CF_TYPE(CFData);
|
|||
Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WASM) || defined(Q_QDOC)
|
||||
namespace emscripten {
|
||||
class val;
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QString;
|
||||
|
|
@ -387,6 +393,11 @@ public:
|
|||
NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WASM) || defined(Q_QDOC)
|
||||
static QByteArray fromUint8Array(emscripten::val uint8array);
|
||||
emscripten::val toUint8Array();
|
||||
#endif
|
||||
|
||||
typedef char *iterator;
|
||||
typedef const char *const_iterator;
|
||||
typedef iterator Iterator;
|
||||
|
|
|
|||
Loading…
Reference in New Issue