textpack.cc

Go to the documentation of this file.
00001 
00007 /*
00008  *  Copyright (C) 2002  The Exult Team
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #  include <config.h>
00027 #endif
00028 
00029 #ifndef ALPHA_LINUX_CXX
00030 #  include <unistd.h>
00031 #  include <fstream>
00032 #  include <cstdio>
00033 #  include <cstdlib>
00034 #endif
00035 #include <iostream>
00036 #include <vector>
00037 #include "Flex.h"
00038 #include "utils.h"
00039 #include "exceptions.h"
00040 #include "msgfile.h"
00041 
00042 using std::atoi;
00043 using std::cerr;
00044 using std::cin;
00045 using std::cout;
00046 using std::endl;
00047 using std::exit;
00048 using std::ifstream;
00049 using std::ofstream;
00050 using std::istream;
00051 using std::ostream;
00052 using std::size_t;
00053 using std::strlen;
00054 using std::vector;
00055 
00056 /*
00057  *  Read in a Flex file where each entry is a 0-delimited text string.
00058  */
00059 
00060 static void Read_flex
00061   (
00062   const char *filename,   // File to read.
00063   vector<char *>& strings   // Strings are stored here.
00064   )
00065   {
00066   Flex in(filename);    // May throw exception.
00067   int cnt = in.number_of_objects();
00068   strings.resize(cnt);
00069   for (int i = 0; i < cnt; i++)
00070     {
00071     size_t len;
00072     strings[i] = in.retrieve(i, len);
00073     if (!len)   // Empty?
00074       {
00075       delete strings[i];
00076       strings[i] = 0;
00077       }
00078     }
00079   } 
00080 
00081 /*
00082  *  Write out a Flex file where each entry is a 0-delimited text string.
00083  */
00084 
00085 static void Write_flex
00086   (
00087   const char *filename,   // File to write.
00088   char *title,      // For the header.
00089   vector<char *>& strings   // Okay if some are null.
00090   )
00091   {
00092   ofstream out;
00093   U7open(out, filename);    // May throw exception.
00094   Flex_writer writer(out, title, strings.size());
00095   for (vector<char *>::const_iterator it = strings.begin();
00096           it != strings.end(); ++it)
00097     {
00098     const char *str = *it;
00099     if (str)
00100       out << str;
00101     out.put((char) 0);  // 0-delimit.
00102     writer.mark_section_done();
00103     }
00104   if (!writer.close())
00105     throw file_write_exception(filename);
00106   }
00107 
00108 /*
00109  *  Write out text, with each line in the form "nnn:sssss", where nnn is
00110  *  the Flex entry #, and anything after the ':' is the string.
00111  *  NOTES:  Null entry #'s will be skipped in the output.
00112  *    Max. text length is 1024.
00113  */
00114 
00115 static void Write_text
00116   (
00117   ostream& out,
00118   vector<char *>& strings   // Strings to write.
00119   )
00120   {
00121   out << "# Written by Exult Textpack tool" << endl;
00122   int cnt = strings.size();
00123   for (int i = 0; i < cnt; i++)
00124     {
00125     char *text = strings[i];
00126     if (!text)
00127       continue;
00128     if (strlen(text) + 1 > 1024)
00129       {
00130       cerr << "Text in entry " << i << " is too long"
00131               << endl;
00132       exit(1);
00133       }
00134     out << i << ':' << text << endl;
00135     }
00136   out.flush();
00137   }
00138 
00139 /*
00140  *  Print usage and exit.
00141  */
00142 
00143 static void Usage()
00144   {
00145   cerr << "Usage: textpack -[x|c] flexfile [textfile]" << endl <<
00146     "    Missing [textfile] => stdin/stdout" << endl;
00147   exit(1);
00148   }
00149 
00150 /*
00151  *  Create or extract from Flex files consisting of text entries.
00152  */
00153 
00154 int main
00155   (
00156   int argc,
00157   char **argv
00158   )
00159   {
00160   if (argc < 3 || argv[1][0] != '-')
00161     Usage();    // (Exits.)
00162   char *flexname = argv[2];
00163   vector<char *> strings;   // Text stored here.
00164   switch (argv[1][1])   // Which function?
00165     {
00166   case 'c':     // Create Flex.
00167     if (argc >= 4)    // Text filename given?
00168       {
00169       ifstream in;  // Open as text.
00170       try {
00171         U7open(in, argv[3], true);
00172       } catch (exult_exception& e) {
00173         cerr << e.what() << endl;
00174         exit(1);
00175       }
00176       if (Read_text_msg_file(in, strings) == -1)
00177         exit(1);
00178       }
00179     else      // Default to stdin.
00180       if (Read_text_msg_file(cin, strings) == -1)
00181         exit(1);
00182     try {
00183       Write_flex(flexname, "Flex created by Exult", strings);
00184     } catch (exult_exception& e){
00185       cerr << e.what() << endl;
00186       exit(1);
00187     }
00188     break;
00189   case 'x':     // Extract to text.
00190     try {
00191       Read_flex(flexname, strings);
00192     } catch (exult_exception& e){
00193       cerr << e.what() << endl;
00194       exit(1);
00195     }
00196     if (argc >= 4)    // Text file given?
00197       {
00198       ofstream out;
00199       try {
00200         U7open(out, argv[3],  true);
00201       } catch(exult_exception& e) {
00202         cerr << e.what() << endl;
00203         exit(1);
00204       }
00205       Write_text(out, strings);
00206       }
00207     else
00208       Write_text(cout, strings);
00209     break;
00210   default:
00211     Usage();
00212     }
00213           // Clean up allocated strings.
00214   for (vector<char *>::iterator it = strings.begin(); 
00215             it != strings.end(); ++it)
00216     delete *it;
00217   return 0;
00218   }

Generated on Mon Jul 9 14:42:50 2007 for ExultEngine by  doxygen 1.5.1