summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/Qt3DSFoundation/Include/foundation/StringTable.h
blob: 7952946726d9584394b7ffc545a84bedfb4f4764 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/****************************************************************************
**
** Copyright (C) 2008-2012 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$
** 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 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** 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_RENDER_STRING_TABLE_H
#define QT3DS_RENDER_STRING_TABLE_H

#if defined(_WIN32) || defined(__QNXNTO__)
#include <wchar.h>
#ifndef WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T
#define WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T
#endif
#endif
#include "foundation/Qt3DSRefCounted.h"
#include "foundation/Qt3DSAllocator.h"
#include "EASTL/functional.h"
#include "EABase/eabase.h" //char16_t definition
#include "foundation/Qt3DSDataRef.h"
#include "foundation/Qt3DSOption.h"

namespace qt3ds {
namespace foundation {
    typedef char8_t Qt3DSBChar;
    typedef const char8_t *Qt3DSBCharPtr;
    class IStringTable;

    // Serialization types, NVRenderSerializationTypes.h
    struct SStrRemapMap;
    struct SWriteBuffer;

    class CRegisteredString;

    // Discriminated union of either data ref or str table
    // used so clients can test serialization without actually saving
    // the string table out and rebooting the entire system.
    class CStrTableOrDataRef
    {
        Option<NVDataRef<QT3DSU8>> m_DataRef;
        IStringTable *m_StrTable;

    public:
        CStrTableOrDataRef()
            : m_StrTable(NULL)
        {
        }
        CStrTableOrDataRef(NVDataRef<QT3DSU8> inData)
            : m_DataRef(inData)
        {
        }
        CStrTableOrDataRef(IStringTable &inStrTable)
            : m_StrTable(&inStrTable)
        {
        }
        CStrTableOrDataRef(const CStrTableOrDataRef &inOther)
            : m_DataRef(inOther.m_DataRef)
            , m_StrTable(inOther.m_StrTable)
        {
        }
        CStrTableOrDataRef &operator=(const CStrTableOrDataRef &inOther)
        {
            m_DataRef = inOther.m_DataRef;
            m_StrTable = inOther.m_StrTable;
            return *this;
        }
        bool HasStrTable() const { return m_StrTable != NULL; }
        bool HasDataRef() const { return m_DataRef.hasValue(); }
        NVDataRef<QT3DSU8> GetDataRef() const { return *m_DataRef; }
        IStringTable *GetStringTable() const
        {
            QT3DS_ASSERT(m_StrTable);
            return m_StrTable;
        }
    };

    // String that can only be constructed from strings in the string table.
    // These strings are valid utf-8 strings
    class CRegisteredString
    {
        Qt3DSBCharPtr m_String;

    public:
        CRegisteredString()
            : m_String("")
        {
        }
        CRegisteredString(const CRegisteredString &inOther)
            : m_String(inOther.m_String)
        {
        }
        CRegisteredString &operator=(const CRegisteredString &inOther)
        {
            m_String = inOther.m_String;
            return *this;
        }

        bool operator==(const CRegisteredString &inStr) const { return m_String == inStr.m_String; }
        // If you use this in a real map then you will get them sorted roughly by the correct
        // order.
        bool operator<(const char *inStr) const
        {
            // Ensure non-null strings to strcmp.
            const char *myStr = m_String ? m_String : "";
            inStr = inStr ? inStr : "";
            int answer;
            while (*myStr && *inStr) {
                answer = *inStr - *myStr;
                if (answer)
                    return answer < 0;
                ++myStr;
                ++inStr;
            }
            answer = *inStr - *myStr;
            return answer < 0;
        }
        size_t hash() const { return eastl::hash<size_t>()(reinterpret_cast<size_t>(m_String)); }
        operator Qt3DSBCharPtr() const { return c_str(); }
        Qt3DSBCharPtr c_str() const { return m_String ? m_String : ""; }
        bool IsValid() const { return m_String && *m_String; }

        // If this string is in the map, changes it to the map value.
        void Remap(const SStrRemapMap &inMap);

        void Remap(const IStringTable &inTable);

        // Using m_String as an offset, if possible remap into
        // inDataPtr's block of memory
        void Remap(NVDataRef<QT3DSU8> inDataPtr);

        void Remap(const CStrTableOrDataRef &inRef)
        {
            if (inRef.HasDataRef())
                Remap(inRef.GetDataRef());
            else if (inRef.HasStrTable())
                Remap(*inRef.GetStringTable());
            else {
                QT3DS_ASSERT(false);
            }
        }

        static CRegisteredString ISwearThisHasBeenRegistered(Qt3DSBCharPtr str)
        {
            CRegisteredString retval;
            retval.m_String = str;
            return retval;
        }
    };

    class IStringTable;

    class CStringHandle
    {
        QT3DSU32 m_Data;

        CStringHandle(QT3DSU32 hdl)
            : m_Data(hdl)
        {
        }

    public:
        CStringHandle()
            : m_Data(0)
        {
        }
        CStringHandle(const CStringHandle &other)
            : m_Data(other.m_Data)
        {
        }
        CStringHandle &operator=(const CStringHandle &other)
        {
            m_Data = other.m_Data;
            return *this;
        }
        bool IsValid() const { return m_Data != 0; }
        QT3DSU32 handle() const { return m_Data; }
        inline const char8_t *c_str(IStringTable &strTable) const;
        operator QT3DSU32() const { return m_Data; }
        static CStringHandle ISwearThisHasBeenRegistered(QT3DSU32 strHandle)
        {
            return CStringHandle(strHandle);
        }
    };

    // String table stores strings in utf-8 format and does valid utf-16,utf-32 -> utf-8
    // also converts utf8 -> either utf-32 or utf-16, depending on sizeof( wchar_t ) if
    // requested.
    // UICStrConvertUTF.h
    // Also generates offsets that are consistent so clients can convert their strings
    // to offsets during save and convert from offset to string during load regardless
    // of if they load before or after this table.
    class QT3DS_AUTOTEST_EXPORT IStringTable : public NVRefCounted
    {
    public:
        // default state is for multithreaded access to be disabled.
        // remember to implement in CNullStringManager in UICTestPresentation.hxx
        virtual void EnableMultithreadedAccess() = 0;
        virtual void DisableMultithreadedAccess() = 0;

        virtual CRegisteredString RegisterStr(Qt3DSBCharPtr str) = 0;
        // utf-16->utf-8
        virtual CRegisteredString RegisterStr(const char16_t *str) = 0;
        // utf-32->utf-8
        virtual CRegisteredString RegisterStr(const char32_t *str) = 0;

        virtual CStringHandle GetHandle(Qt3DSBCharPtr str) = 0;
        virtual CRegisteredString HandleToStr(QT3DSU32 strHandle) = 0;

        virtual CRegisteredString RegisterStr(const wchar_t *str) = 0;

        virtual const wchar_t *GetWideStr(Qt3DSBCharPtr src) = 0;
        virtual const wchar_t *GetWideStr(const wchar_t *str) = 0;

        Qt3DSBCharPtr GetNarrowStr(const wchar_t *src) { return RegisterStr(src); }
        Qt3DSBCharPtr GetNarrowStr(Qt3DSBCharPtr src) { return RegisterStr(src); }

        // The string table maintains a map that will tell clients where their strings will be
        // in terms of offsets into the data that the string table writes.
        // This map will change each time a new string is added to the string table.
        // Conversion from string -> data offset.
        virtual const SStrRemapMap &GetRemapMap() = 0;

        virtual NVAllocatorCallback &GetAllocator() = 0;

        // Save to a block of memory.  It is up the callers to deallocate using allocator
        // from GetAllocator().  Returns a remap map that takes existing strings and changes their
        // address such that they are offsets into the block of memory where this object
        // started saving.  Returns a map that converts registered strings into offsets of the
        // written buffer.
        virtual void Save(SWriteBuffer &ioBuffer) const = 0;

        // Load all the strings from inMemory.  inMemory is not freed by this object
        // Finally, you will need to take inMemory and call remap on all strings
        // from offsets back into their correct address into inMemory.
        virtual void Load(qt3ds::foundation::NVDataRef<QT3DSU8> inMemory) = 0;

        static IStringTable &CreateStringTable(NVAllocatorCallback &alloc);
    };

    inline const char8_t *CStringHandle::c_str(IStringTable &strTable) const
    {
        return strTable.HandleToStr(m_Data);
    }
}
}

// eastl extensions to allow easy hashtable creation using string table strings.
namespace eastl {

template <>
struct hash<qt3ds::foundation::CRegisteredString>
{
    size_t operator()(const qt3ds::foundation::CRegisteredString &str) const { return str.hash(); }
};

template <>
struct equal_to<qt3ds::foundation::CRegisteredString>
{
    bool operator()(const qt3ds::foundation::CRegisteredString &lhs,
                    const qt3ds::foundation::CRegisteredString &rhs) const
    {
        return lhs == rhs;
    }
};
}

#endif