Filter:   InfoImg
download cliloc.cc
Language: C++
LOC: 258
Project Info
Ultima Online Project(uop)
Server: SourceForge
Type: cvs
SourceForge\u\uop\uop\uop\
   acinclude.m4
   aclocal.m4
   action.cc
   action.h
   animation.cc
   animation.h
   artexport.cc
   artfactory.cc
   artfactory.h
   audio.cc
   audio.h
   btree.cc
   btree.h
   cache.h
   cliloc.cc
   cliloc.h
   config.h.in
   configure.in
   cvs2cl.pl
   entity.cc
   entity.h
   gumps.cc
   gumps.h
   interface.cc
   interface.h
   interfacegumps.cc
   interfacegumps.h
   interfacehandler.cc
   interfacehandler.h
   intrface.def
   Makefile.am
   Makefile.in
   message.cc
   message.h
   musicmap.def
   network.cc
   network.h
   patchhandler.cc
   patchhandler.h
   readable.pl
   serverhandler.cc
   serverhandler.h
   sprite.cc
   sprite.h
   stamp-h.in
   texthandler.cc
   texthandler.h
   tiledata.cc
   tiledata.h
   unreadable.pl
   uop.cc
   uop.cfg
   uop.dox
   uop.h
   uopconfig.cc
   uopconfig.h
   uosprite.h
   uostub.pl
   world.cc
   world.h

#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];
}