18 for(map<string, char *>::const_iterator
19 i(objectFiles.begin()), end(objectFiles.end());
26 void Loader::Load(const std::string &filePath) {
27 std::ifstream file(filePath.c_str());
28 file.seekg(0, std::ios::end);
29 int fileLength(file.tellg());
30 int length(fileLength + 15);
32 char *block = new char[length];
33 ObjectFileHeader *header =
34 reinterpret_cast<ObjectFileHeader *>(block);
36 unsigned long padding =
37 reinterpret_cast<unsigned long>(block) % 16;
39 header = reinterpret_cast<ObjectFileHeader *>(
40 block + (16 - padding));
43 file.seekg(0, std::ios::beg);
44 file.read(reinterpret_cast<char *>(header), fileLength);
47 header->IntegrityCheck(fileLength);
49 LoadExports(header->ident,
50 header->ExportsBegin(),
51 header->ExportsEnd());
52 LoadExternals(header->ident,
53 header->ExternalsBegin(),
54 header->ExternalsEnd());
55 LoadObjects(header->ident,
56 header->ObjectsBegin(),
57 header->ObjectsEnd());
58 LoadArrays(header->ident,
59 header->ArraysBegin(),
61 LoadImages(header->ident,
62 header->ImagesBegin(),
66 header->ObjectsBegin(),
67 header->ObjectsEnd());
69 header->ArraysBegin(),
75 objectFiles.insert(make_pair(filePath, block));
78 void Loader::LoadExports(char *src, Export *begin, Export *end) {
79 for (Export *i = begin; i < end; ++i) {
80 string identifier(src + i->nameOffset);
81 LoadedExport &exp(exports[identifier]);
82 exp.typeId = i->typeId;
83 exp.location = src + i->dataOffset;
84 exports.insert(make_pair(identifier, exp));
88 void Loader::LoadExternals(char *src, External *begin, External *end) {
89 for (External *i = begin; i < end; ++i) {
90 string identifier(src + i->nameOffset);
91 map<string, LoadedExport>::const_iterator
92 exp(exports.find(identifier));
93 if (exp == exports.end()) {
94 throw std::runtime_error("undefined reference to "
97 const TypeDescription &td(TypeDescription::Get(exp->second.typeId));
98 char *dest = src + i->referenceOffset;
100 std::memcpy(dest, exp->second.location, td.Size());
102 std::memcpy(dest, &exp->second.location, sizeof(char *));
107 void Loader::LoadImages(char *src, Image *begin, Image *end) {
108 for (Image *i = begin; i != end; ++i) {
109 const string path(src + i->pathOffset);
110 SDL_Surface **dest = reinterpret_cast<SDL_Surface **>(src + i->destOffset);
111 std::map<string, SDL_Surface *>::const_iterator
112 found(images.find(path));
113 if (found != images.end()) {
114 *dest = found->second;
116 SDL_Surface *loaded = IMG_Load(path.c_str());
117 images.insert(make_pair(path, loaded));
123 void Loader::LoadObjects(char *src, Object *begin, Object *end) {
124 for (Object *i = begin; i < end; i = i->Next()) {
125 const TypeDescription &td =
126 TypeDescription::Get(i->typeId);
127 LoadObject(src, i->RawObject(), td);
131 void Loader::LoadObject(char *src, char *object, const TypeDescription &td) {
132 for (TypeDescription::FieldIterator
133 i(td.FieldsBegin()), end(td.FieldsEnd());
135 const FieldDescription &field = i->second;
136 if (field.IsReferenced() || field.IsAggregate()) {
137 char **dest(reinterpret_cast<char **>(object + field.Offset()));
139 *dest = src + *reinterpret_cast<unsigned int *>(dest);
142 const TypeDescription &nestedType
143 = TypeDescription::Get(field.TypeId());
144 LoadObject(src, object + field.Offset(), nestedType);
149 void Loader::LoadArrays(char *src, Array *begin, Array *end) {
150 for (Array *i = begin; i < end; i = i->Next()) {
152 for (char *j = i->Data(), *end = i->Data() + i->size;
153 j < end; j += sizeof(void *)) {
154 unsigned int offset = *reinterpret_cast<unsigned int *>(j);
156 *reinterpret_cast<char **>(j) = src + offset;
160 const TypeDescription &td = TypeDescription::Get(i->typeId);
161 for (char *j = i->Data(), *end = i->Data() + i->size;
162 j < end; j += td.Size()) {
163 LoadObject(src, j, td);
170 void Loader::InitObjects(Object *begin, Object *end) {
171 for (Object *i = begin; i < end; i = i->Next()) {
172 const TypeDescription &td =
173 TypeDescription::Get(i->typeId);
174 InitObject(i->RawObject(), td);
178 void Loader::InitObject(char *object, const TypeDescription &td) {
181 for (TypeDescription::FieldIterator
182 i(td.FieldsBegin()), end(td.FieldsEnd());
184 const FieldDescription &field = i->second;
185 if (field.IsReferenced() || field.IsAggregate()) {
188 const TypeDescription &nestedType
189 = TypeDescription::Get(field.TypeId());
190 InitObject(object + field.Offset(), nestedType);
194 void Loader::InitArrays(Array *begin, Array *end) {
195 for (Array *i = begin; i < end; i = i->Next()) {
199 const TypeDescription &td = TypeDescription::Get(i->typeId);
200 for (char *j = i->Data(), *end = i->Data() + i->size;
201 j < end; j += td.Size()) {