summaryrefslogtreecommitdiff
path: root/lib/EventFlow/src/ore/ResMetaData.cpp
blob: 2587f3d61b4e1cdc408d8142e827a113b23b205b (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
#include <ore/ResDic.h>
#include <ore/ResEndian.h>
#include <ore/ResMetaData.h>

namespace ore {

static void SwapEndianImpl(ResEndian* endian, ResMetaData* res) {
    auto* dictionary = res->dictionary.ToPtr(endian->base);
    if (dictionary)
        SwapEndian(endian, dictionary);

    switch (res->type) {
    case ResMetaData::DataType::kArgument:
    case ResMetaData::DataType::kString:
    case ResMetaData::DataType::kStringArray:
    case ResMetaData::DataType::kActorIdentifier: {
        if (res->num_items == 0)
            break;
        BinString* str = res->value.str.ToPtr(endian->base);
        if (endian->is_serializing) {
            for (int i = 0, n = res->num_items; i < n; ++i) {
                auto* next = str->NextString();
                SwapEndian(&str->length);
                str = next;
            }
        } else {
            for (int i = 0, n = res->num_items; i < n; ++i) {
                SwapEndian(&str->length);
                str = str->NextString();
            }
        }
        break;
    }
    case ResMetaData::DataType::kContainer: {
        for (int i = 0, n = res->num_items; i < n; ++i) {
            ResMetaData* ptr = (&res->value.container + i)->ToPtr(endian->base);
            if (ptr)
                SwapEndian(endian, ptr);
        }
        break;
    }
    case ResMetaData::DataType::kInt:
    case ResMetaData::DataType::kBool:
    case ResMetaData::DataType::kFloat:
    case ResMetaData::DataType::kIntArray:
    case ResMetaData::DataType::kFloatArray:
        for (int i = 0, n = res->num_items; i < n; ++i) {
            SwapEndian(&res->value.i + i);
        }
        break;
    case ResMetaData::DataType::kWString:
    case ResMetaData::DataType::kWStringArray: {
        if (res->num_items == 0)
            break;
        BinWString* str = res->value.wstr.ToPtr(endian->base);
        if (endian->is_serializing) {
            for (int i = 0, n = res->num_items; i < n; ++i) {
                for (auto& c : *str)
                    c = static_cast<wchar_t>(SwapEndian(static_cast<u32>(c)));
                auto* next = str->NextString();
                SwapEndian(&str->length);
                str = next;
            }
        } else {
            for (int i = 0, n = res->num_items; i < n; ++i) {
                SwapEndian(&str->length);
                for (auto& c : *str)
                    c = static_cast<wchar_t>(SwapEndian(static_cast<u32>(c)));
                str = str->NextString();
            }
        }
        break;
    }
    case ResMetaData::DataType::kBoolArray:
        break;
    }
}

void SwapEndian(ResEndian* endian, ResMetaData* res) {
    if (endian->is_serializing) {
        SwapEndianImpl(endian, res);
        SwapEndian(&res->num_items);
    } else {
        SwapEndian(&res->num_items);
        SwapEndianImpl(endian, res);
    }
}

}  // namespace ore