summaryrefslogtreecommitdiffstats
path: root/src/dm/systems/Qt3DSDMWStrOpsImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dm/systems/Qt3DSDMWStrOpsImpl.h')
-rw-r--r--src/dm/systems/Qt3DSDMWStrOpsImpl.h761
1 files changed, 761 insertions, 0 deletions
diff --git a/src/dm/systems/Qt3DSDMWStrOpsImpl.h b/src/dm/systems/Qt3DSDMWStrOpsImpl.h
new file mode 100644
index 0000000..d65ac13
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMWStrOpsImpl.h
@@ -0,0 +1,761 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_IMPORT_WSTR_OPS_IMPL_H
+#define QT3DS_IMPORT_WSTR_OPS_IMPL_H
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMWStrOps.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMMetaDataTypes.h"
+#include "Qt3DSDMXML.h"
+#include "EABase/eabase.h"
+#include "Qt3DSDMStringTable.h"
+
+namespace qt3dsdm {
+using qt3ds::QT3DSI8;
+using qt3ds::QT3DSU8;
+using qt3ds::QT3DSI16;
+using qt3ds::QT3DSU16;
+using qt3ds::QT3DSU32;
+using qt3ds::QT3DSI32;
+using qt3ds::QT3DSU64;
+using qt3ds::QT3DSI64;
+using qt3ds::QT3DSF32;
+using qt3ds::QT3DSF64;
+template <>
+struct WStrOps<bool>
+{
+ QT3DSU32 ToStr(bool item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%s", item ? L"True" : L"False"));
+ }
+ bool StrTo(const wchar_t *buffer, bool &item)
+ {
+ if (AreEqual(buffer, L"True"))
+ item = true;
+ else
+ item = false;
+ return true;
+ }
+ QT3DSU32 ToStr(bool item, NVDataRef<char8_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ _snprintf(buffer.begin(), buffer.size(), "%s", item ? "True" : "False"));
+ }
+ bool StrTo(const char8_t *buffer, bool &item)
+ {
+ if (AreEqualCaseless(buffer, "True"))
+ item = true;
+ else
+ item = false;
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSU8>
+{
+ QT3DSU32 ToStr(QT3DSU8 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%hu", static_cast<QT3DSU16>(item)));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU8 &item)
+ {
+ item = static_cast<QT3DSU8>(strtoul(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSI8>
+{
+ QT3DSU32 ToStr(QT3DSI8 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%hd", static_cast<QT3DSI16>(item)));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI8 &item)
+ {
+ item = static_cast<QT3DSI8>(strtol(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSU16>
+{
+ QT3DSU32 ToStr(QT3DSU16 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%hu", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU16 &item)
+ {
+ item = static_cast<QT3DSU16>(strtoul(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSI16>
+{
+ QT3DSU32 ToStr(QT3DSI16 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%hd", item));
+ }
+ QT3DSU32 ToStr(QT3DSI16 item, NVDataRef<char8_t> buffer)
+ {
+ return static_cast<QT3DSU32>(sprintf(buffer.begin(), "%hd", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI16 &item)
+ {
+ item = static_cast<QT3DSI16>(strtol(buffer, NULL, 10));
+ return true;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSU32>
+{
+ QT3DSU32 ToStr(QT3DSU32 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%lu", item));
+ }
+ QT3DSU32 ToStr(QT3DSU32 item, NVDataRef<char8_t> buffer)
+ {
+ // hope the buffer is big enough...
+ return static_cast<QT3DSU32>(sprintf(buffer.begin(), "%u", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU32 &item)
+ {
+ item = strtoul(buffer, NULL, 10);
+ return true;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSI32>
+{
+ QT3DSU32 ToStr(QT3DSI32 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%ld", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI32 &item)
+ {
+ item = strtol(buffer, NULL, 10);
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSF32>
+{
+ QT3DSU32 ToStr(QT3DSF32 item, NVDataRef<wchar_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ wcsncpy(buffer.begin(), s.toStdWString().c_str(), buffer.size());
+ return s.length();
+ }
+ QT3DSU32 ToStr(QT3DSF32 item, NVDataRef<char8_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ strncpy(buffer.begin(), s.toStdString().c_str(), buffer.size());
+ return s.length();
+ }
+ bool StrTo(const char8_t *buffer, QT3DSF32 &item)
+ {
+ bool ok;
+ item = QLocale::c().toFloat(buffer, &ok);
+ return ok;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSF64>
+{
+ QT3DSU32 ToStr(QT3DSF64 item, NVDataRef<wchar_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ wcsncpy(buffer.begin(), s.toStdWString().c_str(), buffer.size());
+ return s.length();
+ }
+ bool StrTo(const char8_t *buffer, QT3DSF64 &item)
+ {
+ bool ok;
+ item = QLocale::c().toDouble(buffer, &ok);
+ return ok;
+ }
+};
+#define QT3DS_WCHAR_T_None L"None"
+#define QT3DS_WCHAR_T_Float L"Float"
+#define QT3DS_WCHAR_T_Float2 L"Float2"
+#define QT3DS_WCHAR_T_Float3 L"Float3"
+#define QT3DS_WCHAR_T_Float4 L"Float4"
+#define QT3DS_WCHAR_T_Long L"Long"
+#define QT3DS_WCHAR_T_String L"String"
+#define QT3DS_WCHAR_T_Bool L"Bool"
+#define QT3DS_WCHAR_T_Long4 L"Long4"
+#define QT3DS_WCHAR_T_StringRef L"StringRef"
+#define QT3DS_WCHAR_T_ObjectRef L"ObjectRef"
+#define QT3DS_WCHAR_T_StringOrInt L"StringOrInt"
+#define QT3DS_WCHAR_T_FloatList L"FloatList"
+
+#define QT3DS_IMPORT_ITERATE_DMTYPE \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::None, None, QT3DSF32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float, Float, QT3DSF32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float2, Float2, SFloat2) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float3, Float3, SFloat3) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float4, Float4, SFloat4) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Long, Long, QT3DSI32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::String, String, TDataStrPtr) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Bool, Bool, bool) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Long4, Long4, SLong4) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::StringRef, StringRef, SStringRef) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::ObjectRef, ObjectRef, SObjectRefType) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::StringOrInt, StringOrInt, SStringOrInt) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::FloatList, FloatList, TFloatList)
+
+template <>
+struct WStrOps<DataModelDataType::Value>
+{
+ QT3DSU32 ToStr(DataModelDataType::Value item, NVDataRef<wchar_t> buffer)
+ {
+ const wchar_t *data = NULL;
+ switch (item) {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ case x: \
+ data = QT3DS_WCHAR_T_##y; \
+ break;
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ default:
+ break;
+ }
+ if (data == NULL) {
+ QT3DS_ASSERT(false);
+ data = L"Unknown";
+ }
+ return (QT3DSU32)swprintf(buffer.begin(), buffer.size(), L"%ls", data);
+ }
+ bool StrTo(const wchar_t *buffer, DataModelDataType::Value &item)
+ {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ if (AreEqual(buffer, QT3DS_WCHAR_T_##y)) { \
+ item = x; \
+ return true; \
+ }
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ item = DataModelDataType::None;
+ return false;
+ }
+};
+template <typename TBufferType>
+struct WStrOpsDMWriter
+{
+ TBufferType &buf;
+ WStrOpsDMWriter(TBufferType &_buf)
+ : buf(_buf)
+ {
+ }
+
+ void operator()(float val) { buf.Write(val); }
+ void operator()(const SFloat2 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 2)); }
+ void operator()(const SFloat3 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 3)); }
+ void operator()(const SFloat4 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 4)); }
+ void operator()(QT3DSI32 val) { buf.Write(val); }
+ void operator()(bool val) { buf.Write(val); }
+ void operator()(const TDataStrPtr &val)
+ {
+ if (val != NULL)
+ buf.Write(NVConstDataRef<wchar_t>(val->GetData(), (QT3DSU32)val->GetLength()));
+ }
+ void operator()(const SLong4 &val)
+ {
+ buf.Write(NVConstDataRef<QT3DSU32>(&val.m_Longs[0], 4), 4);
+ }
+ void operator()(const SStringRef &val) { buf.Write(val.m_Id, (QT3DSU32)wcslen(val.m_Id) + 1); }
+ void operator()(const SObjectRefType &val) { val.m_Value.visit<void>(*this); }
+ void operator()(const SStringOrInt &val) { val.m_Value.visit<void>(*this); }
+ void operator()(const TFloatList &val)
+ {
+ buf.Write(NVConstDataRef<float>(val.data(), (QT3DSU32)val.size()));
+ }
+ void operator()() { QT3DS_ASSERT(false); }
+};
+
+template <>
+struct WStrOps<SValue>
+{
+ template <typename TBufferType>
+ void ToBuf(const SValue &item, TBufferType &outBuffer)
+ {
+ WStrOpsDMWriter<TBufferType> writer(outBuffer);
+ item.visit<void>(writer);
+ }
+ template <typename TBufferType>
+ SValue BufTo(DataModelDataType::Value type, TBufferType &inReader)
+ {
+ switch (type) {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ case x: { \
+ z retval; \
+ Read(inReader, retval); \
+ return retval; \
+ }
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return SValue();
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, float &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat2 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 2));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat3 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 3));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat4 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 4));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, QT3DSI32 &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, bool &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, TDataStrPtr &val)
+ {
+ NVConstDataRef<wchar_t> buffer;
+ reader.ReadBuffer(buffer);
+ val = std::make_shared<CDataStr>(buffer.begin(), buffer.size());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SLong4 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSU32>(&val.m_Longs[0], 4));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SStringRef &val)
+ {
+ NVConstDataRef<wchar_t> buffer;
+ reader.ReadBuffer(buffer);
+ val = SStringRef(buffer.begin());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, TFloatList &val)
+ {
+ NVConstDataRef<QT3DSF32> buffer;
+ reader.ReadBuffer(buffer);
+ val.assign(buffer.begin(), buffer.end());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SObjectRefType &val)
+ {
+ // Force the read to be as string; callers can always convert to a different
+ // format later if required.
+ TDataStrPtr theValue;
+ Read(reader, theValue);
+ val.m_Value = theValue;
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SStringOrInt &val)
+ {
+ NVConstDataRef<char8_t> buffer;
+ reader.ReadBuffer(buffer);
+ if (buffer.size() == 0)
+ return;
+
+ if ((buffer[0] >= '0' && buffer[0] <= '9') || buffer[0] == '-') {
+ QT3DSI32 theVal;
+ WStrOps<QT3DSI32>().StrTo(buffer.begin(), theVal);
+ val = SStringOrInt(theVal);
+ } else {
+ NVConstDataRef<wchar_t> wideBuffer;
+ reader.ReadBuffer(wideBuffer);
+ val = SStringOrInt(std::make_shared<CDataStr>(wideBuffer.begin()));
+ }
+ }
+};
+
+// Write the wchar_t but exlude the null terminator
+// Meant to write data model values.
+// Memory buffer contains a non-null-terminated
+// wchar_t string
+struct WCharTWriter
+{
+ MemoryBuffer<RawAllocator> &m_Buffer;
+ WCharTWriter(MemoryBuffer<RawAllocator> &buf)
+ : m_Buffer(buf)
+ {
+ }
+ void Write(const wchar_t *value, QT3DSU32 len = 0)
+ {
+ if (IsTrivial(value))
+ return;
+ if (len == 0)
+ len = (QT3DSU32)wcslen(value);
+ m_Buffer.write(value, len);
+ }
+ void Write(wchar_t value) { m_Buffer.write(value); }
+ void Write(bool value) { Write(value ? L"True" : L"False"); }
+
+ // Takes care of long and float
+ template <typename TDataType>
+ void Write(TDataType value)
+ {
+ wchar_t buf[256];
+ QT3DSU32 numWritten = WStrOps<TDataType>().ToStr(value, NVDataRef<wchar_t>(buf, 256));
+ if (numWritten)
+ Write((const wchar_t *)buf);
+ else {
+ QT3DS_ASSERT(false);
+ }
+ }
+ template <typename TDataType>
+ void Write(NVConstDataRef<TDataType> values, QT3DSU32 grouping = 6, QT3DSU32 tabCount = 0)
+ {
+ for (QT3DSU32 idx = 0; idx < values.size(); ++idx) {
+ if (idx) {
+ if ((idx % grouping) == 0) {
+ Write((wchar_t)'\n');
+ for (QT3DSU32 tabIdx = 0; tabIdx < tabCount; ++tabIdx)
+ Write((wchar_t)'\t');
+ } else
+ Write((wchar_t)' ');
+ }
+ Write(values[idx]);
+ }
+ }
+
+ void Write(NVConstDataRef<wchar_t> values, QT3DSU32 ignored = 6)
+ {
+ (void)ignored;
+ if (values.size() && values[0] != 0) {
+ QT3DSU32 lastItem = values.size() - 1;
+ if (values[lastItem] == 0)
+ --lastItem;
+ Write(values.begin(), lastItem + 1);
+ }
+ }
+};
+
+inline bool IsWhite(wchar_t value)
+{
+ return value == '\n' || value == '\r' || value == ' ' || value == '\t';
+}
+
+// skip until we find whitespace.
+inline wchar_t *FindNextWhitespace(wchar_t *input)
+{
+ if (input == NULL)
+ return input;
+ wchar_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && !IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// skip until we find whitespace.
+inline char8_t *FindNextWhitespace(char8_t *input)
+{
+ if (input == NULL)
+ return input;
+ char8_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && !IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// skip until we find something that isn't whitespace.
+inline wchar_t *FindNextNonWhitespace(wchar_t *input)
+{
+ if (input == NULL)
+ return input;
+ wchar_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+inline char8_t *FindNextNonWhitespace(char8_t *input)
+{
+ if (input == NULL)
+ return input;
+ char8_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// Reading is destructive in the case of floating point lists, so we may
+// destroy the incoming string.
+// We are assuming the string is null-terminated at end ptr.
+struct WCharTReader
+{
+ char8_t *m_StartPtr;
+ // Buffer used for temp storage
+ MemoryBuffer<RawAllocator> &m_Buffer;
+ IStringTable &m_StringTable;
+ WCharTReader(char8_t *sp, MemoryBuffer<RawAllocator> &buf, IStringTable &inStringTable)
+ : m_StartPtr(sp)
+ , m_Buffer(buf)
+ , m_StringTable(inStringTable)
+ {
+ }
+ void Read(const char8_t *&outPtr) { outPtr = m_StartPtr; }
+ void Read(const wchar_t *&outPtr) { outPtr = m_StringTable.GetWideStr(m_StartPtr); }
+ template <typename TDataType>
+ void Read(TDataType &data)
+ {
+ bool success = WStrOps<TDataType>().StrTo(m_StartPtr, data);
+ QT3DS_ASSERT(success);
+ (void)success;
+ }
+ // Destructive operation because we can't trust
+ // strtod to do the right thing. On windows, for long strings,
+ // it calls strlen every operation thus leading to basically N^2
+ // behavior
+ template <typename TDataType>
+ void ReadRef(NVDataRef<TDataType> data)
+ {
+ QT3DSU32 idx = 0;
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr);
+ for (; idx < data.size() && m_StartPtr && *m_StartPtr; ++idx) {
+ char8_t *nextPtr = FindNextWhitespace(m_StartPtr);
+ if (nextPtr && *nextPtr)
+ *nextPtr = 0;
+ else
+ nextPtr = NULL;
+ WStrOps<TDataType>().StrTo(m_StartPtr, data[idx]);
+ m_StartPtr = nextPtr;
+ if (m_StartPtr)
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1);
+ }
+ }
+
+ void ReadBuffer(NVConstDataRef<char8_t> &outBuffer)
+ {
+ if (m_StartPtr && *m_StartPtr) {
+ QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr);
+ outBuffer = NVConstDataRef<char8_t>(m_StartPtr, len + 1);
+ }
+ }
+ void ReadBuffer(NVConstDataRef<wchar_t> &outBuffer)
+ {
+ if (m_StartPtr && *m_StartPtr) {
+ QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr);
+ outBuffer = NVConstDataRef<wchar_t>(m_StringTable.GetWideStr(m_StartPtr), len + 1);
+ }
+ }
+
+ // Destructive operation because we can't trust
+ // strtod to do the right thing. On windows, for long strings,
+ // it calls strlen every operation thus leading to basically N^2
+ // behavior
+ template <typename TDataType>
+ void ReadBuffer(NVConstDataRef<TDataType> &outBuffer)
+ {
+ m_Buffer.clear();
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr);
+ while (m_StartPtr && *m_StartPtr) {
+ char8_t *nextPtr = FindNextWhitespace(m_StartPtr);
+ if (nextPtr && *nextPtr)
+ *nextPtr = 0;
+ else
+ nextPtr = NULL;
+ TDataType temp;
+ WStrOps<TDataType>().StrTo(m_StartPtr, temp);
+ m_Buffer.write(temp);
+ m_StartPtr = nextPtr;
+ if (m_StartPtr)
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1);
+ }
+ QT3DSU32 numItems = m_Buffer.size() / sizeof(TDataType);
+ if (numItems)
+ outBuffer = NVConstDataRef<TDataType>((TDataType *)m_Buffer.begin(), numItems);
+ else
+ outBuffer = NVConstDataRef<TDataType>();
+ }
+};
+
+template <>
+struct WStrOps<CDataModelHandle>
+{
+ template <typename THandleType>
+ QT3DSU32 ToStr(THandleType item, NVDataRef<wchar_t> buffer)
+ {
+ int theValue(item);
+ return WStrOps<int>().ToStr(theValue, buffer);
+ }
+ template <typename THandleType>
+ bool StrTo(const char8_t *buffer, THandleType &item)
+ {
+ int theValue;
+ bool retval = WStrOps<int>().StrTo(buffer, theValue);
+ item = theValue;
+ return retval;
+ }
+};
+
+#define IMPLEMENT_HANDLE_WSTROPS(HandleType) \
+ template <> \
+ struct WStrOps<HandleType> : public WStrOps<CDataModelHandle> \
+ { \
+ };
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMInstanceHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMPropertyHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMSlideHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMSlideGraphHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMAnimationHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMKeyframeHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMActionHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerArgHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMEventHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerParamHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMMetaDataPropertyHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMCategoryHandle);
+#undef IMPLEMENT_HANDLE_WSTROPS
+
+template <>
+struct WStrOps<EAnimationType>
+{
+ QT3DSU32 ToStr(EAnimationType value, NVDataRef<wchar_t> buffer)
+ {
+ const wchar_t *animType = NULL;
+ switch (value) {
+ case EAnimationTypeLinear:
+ animType = L"Linear";
+ break;
+ case EAnimationTypeBezier:
+ animType = L"Bezier";
+ break;
+ case EAnimationTypeEaseInOut:
+ animType = L"EaseInOut";
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+ if (animType != NULL)
+ return swprintf(buffer.begin(), buffer.size(), L"%ls", animType);
+ else {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ }
+ bool StrTo(const wchar_t *buffer, EAnimationType &item)
+ {
+ if (AreEqual(L"Linear", buffer)) {
+ item = EAnimationTypeLinear;
+ return true;
+ }
+ if (AreEqual(L"Bezier", buffer)) {
+ item = EAnimationTypeBezier;
+ return true;
+ }
+ if (AreEqual(L"EaseInOut", buffer)) {
+ item = EAnimationTypeEaseInOut;
+ return true;
+ }
+ return false;
+ }
+};
+
+// Implemented in UICDMMetaData.h
+template <>
+struct WStrOps<CompleteMetaDataType::Enum>
+{
+ QT3DSU32 ToStr(CompleteMetaDataType::Enum item, NVDataRef<wchar_t> buffer);
+ bool StrTo(const wchar_t *buffer, CompleteMetaDataType::Enum &item);
+};
+
+template <>
+struct WStrOps<HandlerArgumentType::Value>
+{
+ QT3DSU32 ToStr(HandlerArgumentType::Value item, NVDataRef<wchar_t> buffer);
+ bool StrTo(const wchar_t *buffer, HandlerArgumentType::Value &item);
+};
+
+#ifndef __clang__
+#ifndef __INTEGRITY
+// IDOMReader implementations
+template <typename TDataType>
+bool IDOMReader::ValueList(NVDataRef<TDataType> data)
+{
+ const wchar_t *value;
+ if (Value(value)) {
+ WCharTReader reader(const_cast<wchar_t *>(value), m_TempBuf);
+ reader.ReadRef(data);
+ }
+ return true;
+}
+
+// Destructive operation because we can't trust
+// strtod to do the right thing. On windows, for long strings,
+// it calls strlen every operation thus leading to basically N^2
+// behavior
+template <typename TDataType>
+NVConstDataRef<TDataType> IDOMReader::ChildValueList(TWideXMLCharPtr listName)
+{
+ NVConstDataRef<TDataType> retval;
+ TWideXMLCharPtr childValue = NULL;
+ if (ChildValue(listName, childValue)) {
+ WCharTReader reader(const_cast<wchar_t *>(childValue), m_TempBuf);
+ reader.ReadBuffer(retval);
+ }
+ return retval;
+}
+#endif
+#endif
+}
+
+#endif