1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/misc/types_nl.h"
21 #include "nel/misc/debug.h"
22 #include "nel/misc/file.h"
24 #include "game_share/huffman.h"
31 using namespace NLMISC
;
36 * \author Stephane Coutelas
37 * \author Nevrax France
48 /// occurence of the string
54 CStringInfos() : Occurence(1) { }
60 //-----------------------------------------------
63 //-----------------------------------------------
64 sint
main( sint argc
, char ** argv
)
66 uint currentVersion
= 1;
68 map
<string
,CStringInfos
> base
;
72 printf("Create a file associating a string id with a string and its Huffman code\n\n");
73 printf("OCC2HUFF <string file> [<string file> ...] <occ file>\n");
77 // open the id string association file(s)
79 for( i
= 1; i
< argc
- 1; i
++ )
81 printf("Reading string association file '%s'...\n",argv
[i
]);
83 ifstream
input1(argv
[i
], ios::in
);
84 if( !input1
.is_open() )
86 nlwarning("can't open the file %s",argv
[i
]);
90 // read the tokens and create the string infos
91 while( !input1
.eof() )
95 getline(input1
,line
,'\n');
97 // test the line ( there must be at least 2 '"',remove comments if exist )
98 sint32 idx
= line
.find_first_of("#");
99 bool hasComments
= false;
102 line
= line
.substr(0,idx
);
105 if( line
.size() == 0 )
109 if( line
.find_first_of("\"") == -1 )
113 nlwarning("Missing string value in the string '%s'",line
.c_str());
117 if( line
.find_first_of("\"") == line
.find_last_of("\"") )
121 nlwarning("Missing a delimiter \" in the string '%s'",line
.c_str());
126 // extract string id and string
127 idx
= line
.find_first_of(" \t");
131 si
.Id
= line
.substr(0,idx
);
133 sint32 startIdx
= line
.find_first_of("\"");
134 sint32 endIdx
= line
.find_last_of("\"");
135 si
.Str
= line
.substr(startIdx
+1,endIdx
-startIdx
-1);
138 map
<string
,CStringInfos
>::iterator itStr
= base
.find( si
.Id
);
139 if( itStr
== base
.end() )
141 base
.insert( make_pair(si
.Id
,si
) );
145 nlwarning("The string %s already exists !",si
.Id
.c_str());
152 // open the id occurence association file
153 string occfilename
= argv
[argc
-1];
154 printf("Reading occurence file '%s'...\n",occfilename
.c_str());
155 ifstream
input2(occfilename
.c_str(), ios::in
);
156 if( !input2
.is_open() )
158 nlwarning("Can't open the file %s, set all occurences to 1",argv
[argc
-1]);
162 // read the tokens and update the string infos with occurences
163 while( !input2
.eof() )
167 getline(input2
,line
,'\n');
170 sint32 idx
= line
.find_first_of("#");
171 if( idx
!= string::npos
)
173 line
= line
.substr(0,idx
);
175 if( line
.size() == 0 )
179 char * buffer
= new char[line
.size()+1];
180 strcpy(buffer
,line
.c_str());
182 // extract string id and occurence
185 token
= strtok(buffer
," \t");
188 stoken
= string( token
);
189 map
<string
,CStringInfos
>::iterator itStr
= base
.find( stoken
);
190 if( itStr
!= base
.end() )
192 token
= strtok(NULL
," \t");
193 (*itStr
).second
.Occurence
= atoi( token
);
194 if( (*itStr
).second
.Occurence
== 0 )
196 nlwarning("The occurence of string '%s' is 0 (problem with occurence ?: '%s'), set it to 1",(*itStr
).second
.Str
.c_str(),token
);
197 (*itStr
).second
.Occurence
= 1;
202 nlwarning("The string '%s' is in the .occ but in the txt files!",token
);
209 ofstream
output2(occfilename
.c_str(), ios::app
);
210 if (output2
.is_open())
212 map
<string
,CStringInfos
>::iterator itBase
;
213 for( itBase
= base
.begin(); itBase
!= base
.end(); ++itBase
)
215 if((*itBase
).second
.Occurence
== 0)
217 output2
<< (*itBase
).first
<< " 1" <<endl
;
218 (*itBase
).second
.Occurence
= 1;
225 // build the Huffman tree
226 printf("Building Huffman tree...\n");
228 map
<string
,CStringInfos
>::iterator itBase
;
229 for( itBase
= base
.begin(); itBase
!= base
.end(); ++itBase
)
231 huff
.add( (*itBase
).first
,(*itBase
).second
.Occurence
);
236 // open the output file
237 string outputFileName
= "chat_static.cdb";
238 COFile
output( outputFileName
);
240 // save id|string|occurence
241 printf("Writing binary file '%s'...\n",outputFileName
.c_str());
242 output
.serialVersion(currentVersion
);
243 uint32 count
= base
.size();
244 output
.serial( count
);
246 for( itBase
= base
.begin(); itBase
!= base
.end(); ++itBase
)
248 if( (*itBase
).second
.Occurence
> 0 )
250 huff
.getCode( (*itBase
).first
, code
);
251 output
.serial( (*itBase
).second
.Id
);
252 output
.serial( (*itBase
).second
.Str
);
253 output
.serial( (*itBase
).second
.Occurence
);
254 output
.serialCont( code
);
259 /*printf("Writing debug text file...\n");
260 FILE * outputTest = nlfopen("chat_static_base_test.log","wt");
261 for( itBase = base.begin(); itBase != base.end(); ++itBase )
263 fprintf(outputTest,"id: %s str: %s occ: %d\n",(*itBase).second.Id.c_str(),(*itBase).second.Str.c_str(), (*itBase).second.Occurence );
265 fclose(outputTest);*/
267 printf("Process complete.\n");