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(),
68 objectFiles.insert(make_pair(filePath, block));
71 void Loader::LoadExports(char *src, Export *begin, Export *end) {
72 for (Export *i = begin; i < end; ++i) {
73 string identifier(src + i->nameOffset);
74 LoadedExport &exp(exports[identifier]);
75 exp.typeId = i->typeId;
76 exp.location = src + i->dataOffset;
77 exports.insert(make_pair(identifier, exp));
81 void Loader::LoadExternals(char *src, External *begin, External *end) {
82 for (External *i = begin; i < end; ++i) {
83 string identifier(src + i->nameOffset);
84 map<string, LoadedExport>::const_iterator
85 exp(exports.find(identifier));
86 if (exp == exports.end()) {
87 throw std::runtime_error("undefined reference to "
90 const TypeDescription &td(TypeDescription::Get(exp->second.typeId));
91 char *dest = src + i->referenceOffset;
93 std::memcpy(dest, exp->second.location, td.Size());
95 std::memcpy(dest, &exp->second.location, sizeof(char *));
100 void Loader::LoadImages(char *src, Image *begin, Image *end) {
101 for (Image *i = begin; i != end; ++i) {
102 const string path(src + i->pathOffset);
103 SDL_Surface **dest = reinterpret_cast<SDL_Surface **>(src + i->destOffset);
104 std::map<string, SDL_Surface *>::const_iterator
105 found(images.find(path));
106 if (found != images.end()) {
107 *dest = found->second;
109 SDL_Surface *loaded = IMG_Load(path.c_str());
110 images.insert(make_pair(path, loaded));
116 void Loader::LoadObjects(char *src, Object *begin, Object *end) {
117 for (Object *i = begin; i < end; i = i->Next()) {
118 const TypeDescription &td =
119 TypeDescription::Get(i->typeId);
120 LoadObject(src, i->RawObject(), td);
124 void Loader::LoadObject(char *src, char *object, const TypeDescription &td) {
125 for (TypeDescription::FieldIterator
126 i(td.FieldsBegin()), end(td.FieldsEnd());
128 const FieldDescription &field = i->second;
129 if (field.IsReferenced() || field.IsAggregate()) {
130 char **dest(reinterpret_cast<char **>(object + field.Offset()));
132 *dest = src + *reinterpret_cast<unsigned int *>(dest);
135 const TypeDescription &nestedType
136 = TypeDescription::Get(field.TypeId());
137 LoadObject(src, object + field.Offset(), nestedType);
142 void Loader::LoadArrays(char *src, Array *begin, Array *end) {
143 for (Array *i = begin; i < end; i = i->Next()) {
145 for (char *j = i->Data(), *end = i->Data() + i->size;
146 j < end; j += sizeof(void *)) {
147 unsigned int offset = *reinterpret_cast<unsigned int *>(j);
149 *reinterpret_cast<char **>(j) = src + offset;
153 const TypeDescription &td = TypeDescription::Get(i->typeId);
154 for (char *j = i->Data(), *end = i->Data() + i->size;
155 j < end; j += td.Size()) {
156 LoadObject(src, j, td);