//This support library has been made by Salvatore Russo and is released under GNU public license.
//It uses standard template libraries to create String class and StringList class used in DeleD
//plugins made by me.
//It also includes some facilities to add or retrieve header, or convert a long, integer or unsigned to a string,
//and get materials as a stringlist or handle callback errors.
#ifndef _SUPPORT_H_
#define _SUPPORT_H_
//standard classes to use
#include <cstdio>
#include <string>
#include <deque>
//so you know error types
#include "dll.h"
typedef std::string stdstring;
//Define a class String based on STL string
class String : public stdstring {
public:
//constructors
String() : stdstring() {};
String(const char* str) : stdstring(str) {};
String(const stdstring& str) : stdstring(str) {};
//trim function in my implementation removes spaces but also \t and \n chars
//from end and beginning of string only
void Trim(){
int k = (this->length())-1;
while(k>=0){
if((*this)[k]==' ' || (*this)[k]=='\t' || (*this)[k]=='\n'){
this->erase(k,1);//trim
k=k-1;
}
else k=-1;
}
k=0;
while(k < this->length()){
if((*this)[k]==' ' || (*this)[k]=='\t' || (*this)[k]=='\n'){
this->erase(k,1);//trim
}
else k=this->length();
}
}
//replace all instaces of "from" char with "to" char
void Replace(char from,char to){
int k = (this->length())-1;
while(k>=0){
if((*this)[k]==from) (*this)[k]=to;//replace
k=k-1;
}
}
};
using std::deque;
//Define a class StringList based on STL deque and the defined class String
class StringList : public deque <String> {
public:
//Adds a String to StringList
void Add(String str){push_back(str);}
//Loads a stringlist from a file
//note that each String added to StringList
//is separed by a \n character and it's present
//at the end of line.
void LoadFromFile(const char* filename){
FILE *nuovofile;
nuovofile=fopen(filename,"r");//opens new file
int c;
String str;
c = fgetc(nuovofile);
while(c!=EOF){
if(c!='\n'){
str.append((char*)&c);
}
else {
str.append((char*)&c);
str.Trim();
Add(str);
str.clear();
};
c = fgetc (nuovofile);
}
}
//GetText returns a String containing all the text included in
//the StringList
String GetText(){
String str;
for(int i=0;i<this->size();i++){
str=str+(*this)[i];
}
return str;
}
};
//convert long integer to a string
String toString(long x) {
char buffer[256];
sprintf(buffer,"%ld",x);
return String(buffer);
}
String toString(int x) {
char buffer[256];
sprintf(buffer,"%d",x);
return String(buffer);
}
String toString(unsigned x) {
char buffer[256];
sprintf(buffer,"%u",x);
return String(buffer);
}
//This function subdivides a string in a list of strings
StringList SubdivideString(String str,String divider){
StringList strings;//returned StringList
strings.clear();//clear returned stringlist
int c=0;
int l=str.length();
//process entire string
while(c<l){
String resultstr;
resultstr.clear();
//read characters until divider is encountered
while((str[c]!=divider[0]) && c<l){
resultstr=resultstr + str[c];
c++;
}
//Remove spaces \t and \n from string in my implementation...
//pay attention or change it in dll.h if you don't want to remove
//a particular char.
resultstr.Trim();//trims string resultstr
strings.Add(resultstr);//add trimmed string
c++;
}
return strings;
}
// adds the length of a string in bytes to that string,
// including the length of the 'length' string itself!
String AddLengthToHeader(String header){
long len=header.length()+(toString(header.length())).length()+1;
String tempStr = toString(len)+String(";")+header;
if (tempStr.length() > len) len++;
return (toString(len)+String(";")+header);
}
// this function reads the header length and then extract
// the whole header from data...
StringList GetHeader(String data,String delimeter){
int position = 0;
String myStr;
myStr.clear();
while (data[position] != delimeter[0]){ // headerlength is the first value of data
myStr = myStr + data[position];
position++;
}
int headerlength = atoi(myStr.c_str());
myStr.clear();
myStr = data.substr(0,headerlength); // retrieve complete header from data
return SubdivideString(myStr,delimeter); // return as stringlist
}
//this function show an error message when giving callback error code
void ErrorMessage(unsigned error){
String errore;
errore.clear();
errore.append("Error Code ");
errore=errore+toString(error)+String(": ");
switch(error){
case PE_NODATA :
errore.append("No Data present.");
break;
case PE_INVALIDVERSION :
errore.append("Invalid Version.");
break;
case PE_INVALIDMEM :
errore.append("Invalid GetMem Command.");
break;
case PE_INVALIDGET :
errore.append("Invalid GetData Command.");
break;
case PE_INVALIDSET:
errore.append("Invalid SetData Command.");
break;
case PE_INVALIDHEADER:
errore.append("Invalid Header.");
break;
case PE_INVALIDDATASTRING:
errore.append("Invalid Data String.");
break;
case PE_INVALIDDATAPROPERTY:
errore.append("Invalid Data Property.");
break;
case PE_OBJECTDATA:
errore.append("Error in Object Data.");
break;
case PE_LIGHTDATA:
errore.append("Error in Light Data.");
break;
case PE_MATERIALDATA:
errore.append("Error in Material Data.");
break;
case PE_UNKNOWNREASON:
errore.append("Unknown Callback Reason.");
break;
case PE_UNKNOWNERROR:
errore.append("Unknown Error.");
break;
default:
errore.append("Unknown Error Code.");
break;
}
MessageBox(NULL,errore.c_str(),"Error in Callback",MB_ICONERROR);
}
//This function returns a string made of all data
//to write materials on a DMF file.
//it includes ";" and as first element the number of materials
String GetMaterials( String materials_data, int num_materials ){
StringList materiali;//A stringlist with all materials data
StringList temp_list=SubdivideString(materials_data,String(";"));//data from DeleD
String temp=toString(num_materials)+String(";");
materiali.Add(temp);//Add number of materials
temp.clear();
int offs=0;
//Add materials
for( int i=0;i<num_materials;i++){
int n_layers=atoi(temp_list[offs+4].c_str());
String curr_mat;
for(int k=offs;k<=offs+4+n_layers;k++) curr_mat=curr_mat+temp_list[k]+String(";");
materiali.Add(curr_mat);
offs+=4+n_layers+1;
}
String ret;//return string
for(int i=0;i<materiali.size();i++) ret+=materiali[i]+String("\n");
return ret;//return materials
}
//This function returns a string made of all data
//to write objects on a DMF file.
//it includes ";" and as first element the number of objects
String GetObjects( String objects_data, int num_objects){
//we'll extract only data from DeleD string and copy them into a StringList
StringList Objects=SubdivideString(objects_data,String(";"));
StringList temp_objs;
temp_objs.Add(toString(num_objects)+String(";"));
int index=0;
for(int obj=0;obj<num_objects;obj++){
//(Object information: name,ID,type,visible,snapmethod,groupid,autoUV,tag)
temp_objs.Add( Objects[index]+String(";")+
Objects[index+1]+String(";")+
Objects[index+2]+String(";")+
Objects[index+3]+String(";")+
Objects[index+4]+String(";")+
Objects[index+5]+String(";")+
Objects[index+6]+String(";")+
Objects[index+7]+String(";"));
index=index+8;
int num_vertices=atoi(Objects[index].c_str());//(Number of vertices in this object)
temp_objs.Add( Objects[index]+String(";") );
index++;
for(int vert=0;vert<num_vertices;vert++){
//(Vertice information: X,Y,Z values)
temp_objs.Add( Objects[index]+String(";")+
Objects[index+1]+String(";")+
Objects[index+2]+String(";"));
index=index+3;
}
int num_polygons=atoi(Objects[index].c_str());
//(Number of polygons in this object)
temp_objs.Add( Objects[index]+String(";") );
index++;
for(int poly=0;poly<num_polygons;poly++){
int num_items = (atoi(Objects[index].c_str())*3)+2;//(Number of data to write for each poly)
String temp_str;
for(int item=0;item<num_items;item++){
if(item<num_items-1) temp_str+=Objects[index+item]+String(";");
else temp_objs.Add( temp_str+Objects[index+item]+String(";") );
}
temp_str.clear();
index=index+num_items;
}
}
String ret;//return string
for(int i=0;i<temp_objs.size();i++) ret+=temp_objs[i]+String("\n");
return ret;
}
//This function returns a string made of all data
//needed to import a basic cube in DeleD.
String CreateDeleDCube(){
String MyChars;
//create a cube object to pass to DeleD
MyChars.append("Cube0;0;1;-1;1;-1;-1;User info;");//Object information: name,ID,type,visible,snapmethod,groupid,autoUV,tag
MyChars.append("8;");//Number of vertices in this object
MyChars.append("128;0;128;");//Vertice information: X,Y,Z values
MyChars.append("-128;0;128;");
MyChars.append("-128;0;-128;");
MyChars.append("128;0;-128;");
MyChars.append("128;128;128;");
MyChars.append("-128;128;128;");
MyChars.append("-128;128;-128;");
MyChars.append("128;128;-128;");
MyChars.append("6;");//Number of polygons in this object
MyChars.append("4;0;0;1;5;4;1.0000;0.0000;-1.0000;0.0000;-1.0000;1.0000;1.0000;1.0000;");//Polygon information: # of vertices,textureID,vertice index values,uv values (2 per vertice)
MyChars.append("4;0;1;2;6;5;1.0000;0.0000;-1.0000;0.0000;-1.0000;1.0000;1.0000;1.0000;");
MyChars.append("4;0;2;3;7;6;-1.0000;0.0000;1.0000;0.0000;1.0000;1.0000;-1.0000;1.0000;");
MyChars.append("4;0;3;0;4;7;-1.0000;0.0000;1.0000;0.0000;1.0000;1.0000;-1.0000;1.0000;");
MyChars.append("4;0;3;2;1;0;1.0000;-1.0000;-1.0000;-1.0000;-1.0000;1.0000;1.0000;1.0000;");
MyChars.append("4;0;4;5;6;7;1.0000;1.0000;-1.0000;1.0000;-1.0000;-1.0000;1.0000;-1.0000;");
return MyChars;
}
#endif /* _SUPPORT_H_ */