-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFsdObject.cpp
More file actions
137 lines (114 loc) · 5.4 KB
/
Copy pathFsdObject.cpp
File metadata and controls
137 lines (114 loc) · 5.4 KB
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
// Copyright © 2016 CCP ehf.
#include "StdAfx.h"
#include "FsdObject.h"
#include "BinaryLoader.h"
#include <sstream>
#include <iostream>
FsdObject::FsdObject(IRoot* lockobj) :
m_data(nullptr),
m_offset(0),
m_path("")
{
}
FsdObject::~FsdObject()
{
m_objectSchemaAttributes.reset();
}
void FsdObject::SetObjectData(const char* data, uint32_t offset, const FsdSchemaAttributes& schemaAttributes, const char * path)
{
m_data = data;
m_offset = offset;
m_objectSchemaAttributes = schemaAttributes.objectAttributes;
m_path = path;
m_isFixedSize = schemaAttributes.hasSize;
// We don't have to do anything if this is a fixed sized object
if (m_isFixedSize){
return;
}
// Here we need to plot out which attributes are present on the instance and their offsets
// 1. Find the optional attributes that are present on the instance
std::vector<std::string> attributesWithVariableOffset = m_objectSchemaAttributes->attributesWithVariableOffset;
std::map<std::string, uint64_t> optionalValueLookup = m_objectSchemaAttributes->optionalValueLookups;
if (optionalValueLookup.size() != 0)
{
const char* optionalAttributesFieldData = &m_data[offset + m_objectSchemaAttributes->endOfFixedSizedData];
uint64_t optionalAttributesField = *reinterpret_cast<const uint64_t*>(optionalAttributesFieldData);
for (auto lookup = optionalValueLookup.begin(); lookup != optionalValueLookup.end(); ++lookup)
{
uint64_t attributeBit = (*lookup).second;
if (!(optionalAttributesField & attributeBit))
{
const char * attributeName = (*lookup).first.c_str();
attributesWithVariableOffset.erase(find(attributesWithVariableOffset.begin(), attributesWithVariableOffset.end(), std::string(attributeName)));
}
}
}
// 2. Store the offset to attributes in memory
uint32_t offsetAttributeArrayStart = m_offset + m_objectSchemaAttributes->endOfFixedSizedData + 8;
uint32_t sizeOfOffsetAttributeTable = uint32_t(4 * attributesWithVariableOffset.size());
m_offsetToVariableSizedData = offsetAttributeArrayStart + sizeOfOffsetAttributeTable;
uint32_t offsetTableSize = m_offsetToVariableSizedData - offsetAttributeArrayStart;
for (uint32_t offsetTableOffset = 0; offsetTableOffset < offsetTableSize; offsetTableOffset += 4)
{
int index = int(offsetTableOffset / 4);
std::string name(attributesWithVariableOffset[index]);
std::string offsetData(&m_data[offsetAttributeArrayStart + offsetTableOffset], 4);
m_offsetAttributeLookupTable[name] = *reinterpret_cast<const uint32_t*>(offsetData.c_str()) + m_offsetToVariableSizedData;
}
}
BlueStdResult FsdObject::GetAttr(const char* attributeName, PyObject*& result)
{
BlueStdResult success;
std::string attributeNameString(attributeName);
std::stringstream newPath;
newPath << std::string(m_path) << std::string(".") << attributeNameString;
if (m_objectSchemaAttributes->attributes.find(attributeNameString) == m_objectSchemaAttributes->attributes.end())
{
std::stringstream errorString;
errorString << "Object: " << std::string(m_path) << " - Attribute '" << attributeNameString << "' is not in the schema for this object. It may be removed by the 'usage' flag under the build configuration that produced this data.";
return BlueStdResult(BLUE_STD_RESULT_KEY_ERROR, errorString.str().c_str());
}
// The attribute should exist, first check the constant offset attributes, then the variable offset attributes
// If it is neither it is an optional attribute that is not set on this instance
if (m_objectSchemaAttributes->constantAttributeOffsets.find(attributeNameString) != m_objectSchemaAttributes->constantAttributeOffsets.end())
{
// found it in the constant attributes
uint32_t offset = m_objectSchemaAttributes->constantAttributeOffsets[attributeNameString];
result = BinaryLoader::LoadBinaryFromString(m_data, m_offset + offset, *m_objectSchemaAttributes->attributes[attributeNameString], newPath.str().c_str());
return BlueStdResult(BLUE_STD_RESULT_OK);
}
if (m_offsetAttributeLookupTable.find(attributeNameString) != m_offsetAttributeLookupTable.end())
{
// found it in the constant attributes
uint32_t offset = m_offsetAttributeLookupTable[attributeNameString];
result = BinaryLoader::LoadBinaryFromString(m_data, offset, *m_objectSchemaAttributes->attributes[attributeNameString], newPath.str().c_str());
return BlueStdResult(BLUE_STD_RESULT_OK);
}
// check for default values
BlueStdResult defaultAttributeLookupResult = GetDefaultValue(attributeNameString, result);
if (defaultAttributeLookupResult.GetType() == BLUE_STD_RESULT_OK)
{
return defaultAttributeLookupResult;
}
std::stringstream errorString;
errorString << "Object: " << std::string(m_path) << " - Attribute '" << attributeNameString << "' does not exist on this instance";
return BlueStdResult(BLUE_STD_RESULT_ATTRIBUTE_ERROR, errorString.str().c_str());
}
BlueStdResult FsdObject::GetDefaultValue(const std::string attributeName, PyObject*& result)
{
auto attributeSchema = m_objectSchemaAttributes->attributes.find(attributeName);
if (attributeSchema == m_objectSchemaAttributes->attributes.end())
{
// return something
return BlueStdResult(BLUE_STD_RESULT_ATTRIBUTE_ERROR);
}
std::shared_ptr<FsdSchemaAttributes> schema = attributeSchema->second;
if (!schema->hasDefault)
{
// we don't have a default value for this optional attribute
return BlueStdResult(BLUE_STD_RESULT_ATTRIBUTE_ERROR);
}
Py_INCREF(schema->defaultValue);
result = schema->defaultValue;
return BlueStdResult(BLUE_STD_RESULT_OK);
}