JavaScript.Projects/source/apps/WebAssembly_Ports/Current.Port/wasm_port/mx/mxclamp.cpp
Source: JavaScript.Projects/source/apps/WebAssembly_Ports/Current.Port/wasm_port/mx/mxclamp.cpp
/*
MX library.
http://lostsidedead.com/svn
libmx written by jared bruni, it is wrappers around SDL
and other api's to provide a set of classes and functions
to produce multi media applications, using object oriented
techniques.
(C) 2008 LostSideDead
*/
#include "mxclamp.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
namespace mx
{
mxClampOutFile::mxClampOutFile(string filename)
{
fname = filename;
}
mxClampOutFile::~mxClampOutFile()
{
if(file.is_open())
file.close();
}
bool mxClampOutFile::openFile()
{
file.open(fname.c_str(), std::ios::out | std::ios::binary);
if(!file.is_open())
return false;
return true;
}
bool mxClampOutFile::openFile(string fname)
{
this->fname = fname;
return openFile();
}
/* writes files to be compressed to disk
provides the basic guarantee ( i think )
*/
bool mxClampOutFile::writeToFile()
{
vector<mxClamp_info>::iterator vi;
vector<string>::iterator si;
for(vi = files.begin(), si = file_names.begin(); vi != files.end(); vi++, si++)
{
void *temp = 0, *tempc = 0;
try
{
uLongf size_compressed = vi->size_bytes;
fstream ifile;
temp = (void*) malloc ( sizeof(char) * vi->size_bytes+1 );
tempc = (void*) malloc ( sizeof(char) * vi->size_bytes+1 );
ifile.open(si->c_str(), std::ios::in | std::ios::binary);
ifile.read((char*)temp, vi->size_bytes);
ifile.close();
if(compress((Bytef*)tempc, (uLongf*)&size_compressed, (const Bytef*) temp, (uLong) vi->size_bytes) != Z_OK)
{
throw mx::mxException<string>(" compression error ");
}
cout << *si << " " << vi->size_bytes << "/" << size_compressed << "\n";
vi->size_compressed = size_compressed;
file.write((char*)&*vi, sizeof(mxClamp_info));
file.write((char*)tempc, vi->size_compressed);
free(temp);
free(tempc);
temp = 0;
tempc = 0;
}
catch (...)
{
if(temp != 0)
free(temp);
if(tempc != 0)
free(tempc);
file.close();
throw; // propagate exception, must reopen the file before you can rewrite
}
}
file.close();
return true;
}
/* adds a file to the list of files to be written
if file is not found throws mxException */
bool mxClampOutFile::addFile(string name)
{
if(name.length()==0) return false;
fstream testfile;
testfile.open(name.c_str(), std::ios::in);
if(!testfile.is_open())
throw mx::mxException<std::string>(" Error file " + name + " not found cannot add to file list ");
testfile.seekg(0, std::ios::end);
mxClamp_info info;
info.size_bytes = testfile.tellg();
testfile.close();
string pless;
int pos = 0;
pos = name.rfind("/");
if(pos != -1)
{
pless = name.substr(pos+1, name.length()-pos);
} else pless = name;
snprintf(info.filename, 255, "%s", pless.c_str());
files.push_back(info);
file_names.push_back(name);
return true;
}
/* attempts to open the file if fails throws mxException */
mxClampResourceFile::mxClampResourceFile(string filename)
{
fname = filename;
the_file.open(filename.c_str(), std::ios::in | std::ios::binary);
if(!the_file.is_open())
throw mx::mxException<string>(" error could not open .mxd resource file ");
buildInfo();
}
mxClampResourceFile::~mxClampResourceFile()
{
if(the_file.is_open())
the_file.close();
}
void mxClampResourceFile::reopen()
{
return ; // blah
the_file.close();
the_file.open(fname.c_str(), std::ios::in | std::ios::binary );
if(!the_file.is_open())
throw mx::mxException<string> (" Could not reopen .mxd archive \n");
the_file.seekg(0, std::ios::beg);
}
void mxClampResourceFile::buildInfo()
{
mxClamp_info i;
std::cout << "building information about compressed .mxd archive ...\n";
while(!the_file.eof())
{
int position;
memset(&i, 0, sizeof(i));
the_file.read((char*)&i, sizeof(i));
position = the_file.tellg();
if(position == -1) break;
std::cout << "file in archive: " << i.filename << " " << i.size_compressed << " / " << i.size_bytes << " \n";
;
file_names.push_back(i);
clamp_off.push_back(position);
the_file.seekg(i.size_compressed, std::ios::cur);
}
the_file.close();
}
/* operator [] throws a exception when a filename that is not within the archive is quiered
access raw bytes returns zero instead */
void *mxClampResourceFile::operator[](string filename)
{
unsigned int s;
void *bytes = accessRawBytes(filename, s);
if(bytes == 0)
throw mxException<string>(" Invalid file name, does not exisit within archive ");
return bytes;
}
void *mxClampResourceFile::accessRawBytes(string filename, unsigned int &size)
{
vector<mxClamp_info>::iterator i;
vector<unsigned int>::iterator ui;
std::fstream the_file;
the_file.open(fname.c_str(), std::ios::in | std::ios::binary);
if(!the_file.is_open()) { return 0; }
the_file.seekg(0, std::ios::beg);
for(i=file_names.begin(),ui=clamp_off.begin(); i!=file_names.end(); i++, ui++)
{
if(i->filename == filename)
{
uLongf ulen = i->size_bytes;
the_file.seekg(*ui, std::ios::beg);
void *ctemp, *temp;
ctemp = (void*) malloc ( i->size_compressed + 1 );
temp = (void *) malloc ( i->size_bytes + 1 );
the_file.read((char*)ctemp, i->size_compressed );
if(uncompress((Bytef*)temp, &ulen,(const Bytef*)ctemp, (uLongf)i->size_compressed) == Z_DATA_ERROR)
{
the_file.close();
free(ctemp);
free(temp);
the_file.close();
throw mx::mxException<string>(" error on decompression of file " + string(filename));
}
free(ctemp);
std::cout << "Read: " << filename << " [OK]\n";
size = i->size_bytes;
the_file.close();
return temp;
}
}
the_file.close();
return 0;
}
}