
#include"NARReader.h"

NARReader::NARReader(char* archiveName)
{
	pMapping=0;
	hMapping=0;
	fileList=new PointerList();

	narHandle=CreateFileA(archiveName,GENERIC_READ,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if(narHandle!=NULL){

		hMapping=CreateFileMapping(narHandle, NULL, PAGE_READONLY,0,0,0);

		if(hMapping==0){
			CloseHandle(narHandle);
			narHandle=0;
			return;
		}

		pMapping=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);

		if(pMapping==0){
			CloseHandle(hMapping);
			CloseHandle(narHandle);
			narHandle=0;
			return;
		}

		unsigned int addr=(unsigned int)pMapping;

		char header[4]={'N','A','R',0}; // four byte header!
		if(strcmp(header,(char*)addr)!=0) // check for header!
			return;

		addr+=4; // pass header!


		while( (!IsBadReadPtr((void*)addr,4)) && (strlen((char*)addr)!=0) )
		{
			fileList->AddPointer((void*)addr); 
			addr=addr+strlen((char*)addr)+1;
			unsigned int size=*(unsigned int*)addr;
			addr=addr+4+size;
		}
	}
}


int NARReader::GetFileCount()
{
	return fileList->GetSize();
}

void* NARReader::ReadFile(int index)
{
	if(fileList->GetSize())
	{
		void* addr=fileList->GetPointer(index);
		if(addr)
			return (void*)((unsigned int)addr+strlen((char*)addr)+5);
		return 0;
	}else
		return 0;
}

char* NARReader::ReadFileName(int index)
{
	if(fileList->GetSize())
	{
		void* addr=fileList->GetPointer(index);
		if(addr)
			return (char*)(addr);
		return 0;
	}else
		return 0;
}

void* NARReader::ReadFile(char* fileName)
{
	if(fileList->GetSize())
	{
		for(int i=0;i<fileList->GetSize();i++)
		{
			void* addr=fileList->GetPointer(i);
			if(strcmp((char*)addr,fileName)==0)
				return (void*)((unsigned int)addr+strlen((char*)addr)+5);
		}
		return 0;
	}else
		return 0;
}

DWORD NARReader::ReadFileSize(char* fileName)
{
	if(fileList->GetSize())
	{
		for(int i=0;i<fileList->GetSize();i++)
		{
			void* addr=fileList->GetPointer(i);
			if(strcmp((char*)addr,fileName)==0)
				return *(DWORD*)((unsigned int)addr+strlen((char*)addr)+1);
		}
		return 0;
	}else
		return 0;
}

DWORD NARReader::ReadFileSize(int index)
{
	if(fileList->GetSize())
	{
		void* addr=fileList->GetPointer(index);
		return *(DWORD*)((unsigned int)addr+strlen((char*)addr)+1);
	}else
		return 0;
}

NARReader::~NARReader()
{
	if(pMapping)
	{
		UnmapViewOfFile((const void*)pMapping);
		CloseHandle(hMapping);
		CloseHandle(narHandle);
	}

	delete fileList;
}