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
|
// slang-fossil.cpp
#include "slang-fossil.h"
namespace Slang
{
namespace Fossil
{
const char Fossil::Header::kMagic[16] = {
'\xAB', // byte 0
'f', // byte 1
'o', // byte 2
's', // byte 3
's', // byte 4
'i', // byte 5
'l', // byte 6
' ', // byte 7
'1', // byte 8
'0', // byte 9
'0', // byte 10
'\xBB', // byte 11
'\r', // byte 12
'\n', // byte 13
'\x1A', // byte 14
'\n' // byte 15
};
Fossil::AnyValPtr getRootValue(ISlangBlob* blob)
{
return getRootValue(blob->getBufferPointer(), blob->getBufferSize());
}
Fossil::AnyValPtr getRootValue(void const* data, Size size)
{
if (!data)
{
SLANG_UNEXPECTED("bad format for fossil");
}
// There must be enough data to at least hold the header.
//
// (In practice there would need to be more data than
// just the header, but checking this invariant is a start).
//
if (size < sizeof(Fossil::Header))
{
SLANG_UNEXPECTED("bad format for fossil");
}
// Once we've checked that there's enough data, we can read
// the contents of the header.
//
auto header = reinterpret_cast<Fossil::Header const*>(data);
// The "magic" bytes at the start of the header must be
// what we expect (which is the contents of `Fossil::Header::kMagic`).
//
if (memcmp(header->magic, Fossil::Header::kMagic, sizeof(Fossil::Header::kMagic)) != 0)
{
SLANG_UNEXPECTED("bad format for fossil");
}
auto reportedSize = header->totalSizeIncludingHeader;
if (reportedSize > size)
{
SLANG_UNEXPECTED("bad format for fossil");
}
auto rootValueVariant = header->rootValue.get();
if (!rootValueVariant)
{
SLANG_UNEXPECTED("bad format for fossil");
}
return getVariantContentPtr(rootValueVariant);
}
} // namespace Fossil
Fossil::AnyValRef Fossil::ValRef<FossilizedContainerObjBase>::getElement(Index index) const
{
SLANG_ASSERT(index >= 0);
SLANG_ASSERT(index < getElementCount());
auto containerLayout = getLayout();
auto elementLayout = containerLayout->elementLayout.get();
auto elementStride = containerLayout->elementStride;
auto elementsPtr = (Byte*)getDataPtr();
auto elementPtr = (void*)(elementsPtr + elementStride * index);
return Fossil::AnyValRef(elementPtr, elementLayout);
}
FossilizedRecordElementLayout* FossilizedRecordLayout::getField(Index index) const
{
SLANG_ASSERT(index >= 0);
SLANG_ASSERT(index < fieldCount);
auto fieldsPtr = (FossilizedRecordElementLayout*)(this + 1);
return fieldsPtr + index;
}
Fossil::AnyValRef Fossil::ValRef<FossilizedRecordVal>::getField(Index index) const
{
SLANG_ASSERT(index >= 0);
SLANG_ASSERT(index < getFieldCount());
auto recordLayout = getLayout();
auto fieldInfo = recordLayout->getField(index);
auto fieldsPtr = (Byte*)getDataPtr();
auto fieldPtr = (void*)(fieldsPtr + fieldInfo->offset);
return Fossil::AnyValRef(fieldPtr, fieldInfo->layout);
}
} // namespace Slang
|