123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
#include "uop.h" #include <SDL/SDL_endian.h> #include <fstream> #include <iostream> #include "uopconfig.h" #include "cliloc.h" extern UOPConfig *config; void latin2unicode(string from, string &to) { string::iterator si; to = ""; for(si=from.begin();si!=from.end();si++) { to += '\x00'; to += *si; } } /** * @todo Add better error handling/reporting * when a file can't be opened (intloc*,cliloc*). */ Cliloc::Cliloc(string formClass) { ifstream file; Uint32 len; string filename=config->encapDatLoc(formClass+"."+config->getString("Language")); file.open(filename.c_str()); if (!file.is_open()) return; char buffer[4]; while (!file.eof()) { file.read(buffer,4); Uint32 classID=SDL_SwapBE32(*(Uint32*)buffer); switch (classID) { case locForm: case locInfo: case locText: case locTime: case locName: break; default: file.read(buffer,4); classID=SDL_SwapBE32(*(Uint32*)buffer); break; } if (classID==locForm) { file.read(buffer,4); len=SDL_SwapBE32(*(Uint32*)buffer); Uint8 *dynbuf = new Uint8[len+4]; *(Uint32*)dynbuf=*(Uint32*)buffer; file.read((char *)dynbuf+4,len); ClForm *form=new ClForm(); form->load(dynbuf); forms.push_back(form); delete [] dynbuf; } else break; // if it's not a form here.. this file is corrupt } file.close(); } Cliloc::~Cliloc() { } string &Cliloc::getString(Uint16 index) { list<ClForm *>::iterator i; string *str=NULL; for (i=forms.begin();i!=forms.end() && !str;i++) str=(*i)->getString(index); if (!str) str=&this->str; return *str; } ClForm::ClForm() { } Uint32 ClForm::load(Uint8 *data) { Uint32 len=SDL_SwapBE32(*(Uint32*)data); Uint32 offset=4; while (offset<len) { Uint32 subClassID=0; Uint32 classID=SDL_SwapBE32(*(Uint32*)(data+offset)); offset+=4; switch (classID) { case locForm: case locInfo: case locText: case locTime: case locName: break; default: subClassID=classID; classID=SDL_SwapBE32(*(Uint32*)(data+offset)); offset+=4; break; } switch (classID) { case locForm: ClForm *form; switch (subClassID) { case locData: form=new ClDataForm(); break; default: form=new ClForm(); break; } offset+=form->load(data+offset); forms.push_back(form); break; default: return len; } } len+=4; if (len&1) len++; return len; } ClForm::~ClForm() { } string *ClForm::getString(Uint16 index) { list<ClForm *>::iterator i; string *str=NULL; for (i=forms.begin();i!=forms.end() && !str;i++) str=(*i)->getString(index); return str; } ClDataForm::ClDataForm() { text=NULL; } Uint32 ClDataForm::load(Uint8 *data) { Uint32 len=SDL_SwapBE32(*(Uint32*)data); Uint32 offset=4; while (offset<len) { Uint32 subClassID=0; Uint32 classID=SDL_SwapBE32(*(Uint32*)(data+offset)); offset+=4; switch (classID) { case locForm: case locInfo: case locText: case locTime: case locName: break; default: subClassID=classID; classID=SDL_SwapBE32(*(Uint32*)(data+offset)); offset+=4; break; } switch (classID) { case locInfo: ClInfo *info; switch (subClassID) { case locLang: info=new ClLangInfo(); break; default: info=new ClInfo(); break; } offset+=info->load(data+offset); infos.push_back(info); break; case locText: text=new ClText(); offset+=text->load(data+offset); break; default: return len; } } len+=4; if (len&1) len++; return len; } ClDataForm::~ClDataForm() { } string *ClDataForm::getString(Uint16 index) { string *str=NULL; Uint16 max=0; list<ClInfo *>::iterator i; for (i=infos.begin();i!=infos.end() && !max;i++) max=(*i)->getLangNumItems(); if (index<max && text) str=text->getString(index); return str; } ClInfo::ClInfo() { data=NULL; } Uint32 ClInfo::load(Uint8 *dat) { Uint32 len=SDL_SwapBE32(*(Uint32*)dat); size=len; data=new Uint8[size]; memcpy(data,dat+4,size); len+=4; if (len&1) len++; return len; } Uint16 ClInfo::getLangNumItems() { return 0; } ClInfo::~ClInfo() { if (data) delete [] data; } ClLangInfo::ClLangInfo() { numberItems=0; } Uint32 ClLangInfo::load(Uint8 *dat) { Uint32 len=ClInfo::load(dat); language=(char *)data; Uint16 offset=strlen((char *)data)+1; bytesPerChar=SDL_SwapLE32(*(Uint32*)(data+offset)); offset+=4; offset+=4; formClass=(char *)(data+offset); offset+=strlen((char *)(data+offset))+1; offset+=4; numberItems=SDL_SwapLE16(*(Uint16*)(data+offset)); return len; } Uint16 ClLangInfo::getLangNumItems() { return numberItems; } ClLangInfo::~ClLangInfo() { } ClText::ClText() { } Uint32 ClText::load(Uint8 *data) { Uint32 len=SDL_SwapBE32(*(Uint32*)data); for (Uint32 offset=4;offset<len;) { text.push_back((char *)(data+offset)); offset+=strlen((char *)(data+offset))+1; } len+=4; if (len&1) len++; return len; } ClText::~ClText() { } string *ClText::getString(Uint16 index) { return &text[index]; }