00001 /*************************************************************************** 00002 * Copyright (c) Riegel <juergen.riegel@web.de> * 00003 * * 00004 * This file is part of the FreeCAD CAx development system. * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Library General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU Library General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Library General Public * 00017 * License along with this library; see the file COPYING.LIB. If not, * 00018 * write to the Free Software Foundation, Inc., 59 Temple Place, * 00019 * Suite 330, Boston, MA 02111-1307, USA * 00020 * * 00021 ***************************************************************************/ 00022 00023 00024 #include "PreCompiled.h" 00025 00026 #ifndef _PreComp_ 00027 #endif 00028 00030 #include "Writer.h" 00031 #include "Persistence.h" 00032 #include "Exception.h" 00033 #include "Base64.h" 00034 #include "FileInfo.h" 00035 #include "Tools.h" 00036 00037 #include <algorithm> 00038 #include <locale> 00039 00040 using namespace Base; 00041 using namespace std; 00042 using namespace zipios; 00043 00044 00045 00046 // --------------------------------------------------------------------------- 00047 // Writer: Constructors and Destructor 00048 // --------------------------------------------------------------------------- 00049 00050 Writer::Writer(void) 00051 : indent(0),forceXML(false) 00052 { 00053 indBuf[0] = '\0'; 00054 } 00055 00056 Writer::~Writer() 00057 { 00058 } 00059 00060 void Writer::insertAsciiFile(const char* FileName) 00061 { 00062 std::ifstream from(FileName); 00063 if (!from) throw Base::Exception("Writer::insertAsciiFile() Could not open file!"); 00064 00065 Stream() << "<![CDATA[" << endl; 00066 char ch; 00067 while (from.get(ch)) Stream().put(ch); 00068 Stream() << endl << "]]>" << endl; 00069 } 00070 00071 void Writer::insertBinFile(const char* FileName) 00072 { 00073 std::ifstream from(FileName); 00074 if (!from) throw Base::Exception("Writer::insertAsciiFile() Could not open file!"); 00075 00076 Stream() << "<![CDATA[" << endl; 00077 00078 unsigned char buf[60]; 00079 std::string encoded; 00080 unsigned int i; 00081 00082 while (from){ 00083 for(i=0 ; i<60 && from;i++) 00084 buf[i] = from.get(); 00085 Stream() << Base::base64_encode(buf,i) << endl; 00086 } 00087 00088 Stream() << "]]>" << endl; 00089 } 00090 00091 void Writer::setForceXML(bool on) 00092 { 00093 forceXML = on; 00094 } 00095 00096 bool Writer::isForceXML(void) 00097 { 00098 return forceXML; 00099 } 00100 00101 std::string Writer::addFile(const char* Name,const Base::Persistence *Object) 00102 { 00103 // always check isForceXML() before requesting a file! 00104 assert(isForceXML()==false); 00105 00106 FileEntry temp; 00107 temp.FileName = getUniqueFileName(Name); 00108 temp.Object = Object; 00109 00110 FileList.push_back(temp); 00111 00112 FileNames.push_back( temp.FileName ); 00113 00114 // return the unique file name 00115 return temp.FileName; 00116 } 00117 00118 std::string Writer::getUniqueFileName(const char *Name) 00119 { 00120 // name in use? 00121 std::string CleanName = (Name ? Name : ""); 00122 std::vector<std::string>::const_iterator pos; 00123 pos = find(FileNames.begin(),FileNames.end(),CleanName); 00124 00125 if (pos == FileNames.end()) { 00126 // if not, name is OK 00127 return CleanName; 00128 } 00129 else { 00130 std::vector<std::string> names; 00131 names.reserve(FileNames.size()); 00132 FileInfo fi(CleanName); 00133 CleanName = fi.fileNamePure(); 00134 std::string ext = fi.extension(); 00135 for (pos = FileNames.begin();pos != FileNames.end();++pos) { 00136 fi.setFile(*pos); 00137 std::string FileName = fi.fileNamePure(); 00138 if (fi.extension() == ext) 00139 names.push_back(FileName); 00140 } 00141 std::stringstream str; 00142 str << Base::Tools::getUniqueName(CleanName, names); 00143 if (!ext.empty()) 00144 str << "." << ext; 00145 return str.str(); 00146 } 00147 } 00148 00149 const std::vector<std::string>& Writer::getFilenames() const 00150 { 00151 return FileNames; 00152 } 00153 00154 void Writer::incInd(void) 00155 { 00156 if (indent < 255) { 00157 indBuf[indent] = '\t'; 00158 indBuf[indent+1] = '\0'; 00159 indent++; 00160 } 00161 } 00162 00163 void Writer::decInd(void) 00164 { 00165 if (indent > 0) { 00166 indent--; 00167 indBuf[indent] = '\0'; 00168 } 00169 } 00170 00171 ZipWriter::ZipWriter(const char* FileName) 00172 : ZipStream(FileName) 00173 { 00174 #ifdef _MSC_VER 00175 ZipStream.imbue(std::locale::empty()); 00176 #else 00177 //FIXME: Check whether this is correct 00178 ZipStream.imbue(std::locale::classic()); 00179 #endif 00180 ZipStream.precision(12); 00181 ZipStream.setf(ios::fixed,ios::floatfield); 00182 } 00183 00184 ZipWriter::ZipWriter(std::ostream& os) 00185 : ZipStream(os) 00186 { 00187 #ifdef _MSC_VER 00188 ZipStream.imbue(std::locale::empty()); 00189 #else 00190 //FIXME: Check whether this is correct 00191 ZipStream.imbue(std::locale::classic()); 00192 #endif 00193 ZipStream.precision(12); 00194 ZipStream.setf(ios::fixed,ios::floatfield); 00195 } 00196 00197 void ZipWriter::writeFiles(void) 00198 { 00199 // use a while loop because it is possible that while 00200 // processing the files new ones can be added 00201 size_t index = 0; 00202 while (index < FileList.size()) { 00203 FileEntry entry = FileList.begin()[index]; 00204 ZipStream.putNextEntry(entry.FileName); 00205 entry.Object->SaveDocFile(*this); 00206 index++; 00207 } 00208 } 00209 00210 ZipWriter::~ZipWriter() 00211 { 00212 ZipStream.close(); 00213 }