]> git.localhorst.tv Git - l2e.git/blob - src/loader/TypeDescription.cpp
8fd95d7437ef90f3744eea17d0135f4980d1aa64
[l2e.git] / src / loader / TypeDescription.cpp
1 /*
2  * TypeDescription.cpp
3  *
4  *  Created on: Sep 4, 2012
5  *      Author: holy
6  */
7
8 #include "TypeDescription.h"
9
10 #include <cassert>
11 #include <cstring>
12 #include <stdexcept>
13
14 using std::map;
15 using std::string;
16 using std::vector;
17
18 namespace loader {
19
20 void TypeDescription::AddField(const std::string &n, const FieldDescription &f) {
21         if (HasField(n)) {
22                 throw std::invalid_argument("duplicate definition of field " + n + " of type " + name);
23         } else {
24                 fields.insert(std::make_pair(n, f));
25         }
26 }
27
28 bool TypeDescription::HasField(const std::string &name) const {
29         return fields.count(name);
30 }
31
32 const FieldDescription &TypeDescription::GetField(const std::string &n) const {
33         map<string, FieldDescription>::const_iterator result(fields.find(n));
34         if (result != fields.end()) {
35                 return result->second;
36         } else {
37                 throw std::invalid_argument("undefined field " + n + " of type " + name);
38         }
39 }
40
41 void TypeDescription::Construct(void *data) const {
42         if (constructor) {
43                 (*constructor)(data);
44         } else {
45                 std::memset(data, 0, Size());
46         }
47 }
48
49 void TypeDescription::Load(void *data) const {
50         if (loader) {
51                 (*loader)(data);
52         }
53 }
54
55
56 void TypeDescription::AddSupertype(int id, std::ptrdiff_t offset) {
57         supertypes[id] = offset;
58 }
59
60 bool TypeDescription::IsSubtypeOf(int id) const {
61         return supertypes.count(id);
62 }
63
64 std::ptrdiff_t TypeDescription::SupertypeOffset(int id) const {
65         return supertypes.at(id);
66 }
67
68
69 vector<TypeDescription> TypeDescription::typeDescriptions;
70
71 TypeDescription &TypeDescription::CreateOrGet(const std::string &name) {
72         for (vector<TypeDescription>::iterator i(typeDescriptions.begin()), end(typeDescriptions.end()); i != end; ++i) {
73                 if (i->name == name) {
74                         return *i;
75                 }
76         }
77         typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
78         return typeDescriptions.back();
79 }
80
81 int TypeDescription::GetTypeId(const std::string &name) {
82         for (vector<TypeDescription>::size_type i(0), end(typeDescriptions.size()); i < end; ++i) {
83                 if (typeDescriptions[i].name == name) {
84                         return i;
85                 }
86         }
87         typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
88         return typeDescriptions.size() - 1;
89 }
90
91 const TypeDescription &TypeDescription::Get(int id) {
92         assert(id >= 0 && id < int(typeDescriptions.size()));
93         return typeDescriptions[id];
94 }
95
96 }