PropertyFile.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 #endif
00029
00031
00032 #include <Base/Exception.h>
00033 #include <Base/Reader.h>
00034 #include <Base/Writer.h>
00035 #include <Base/Stream.h>
00036 #include <Base/Console.h>
00037 #include <Base/PyObjectBase.h>
00038
00039 #include "PropertyFile.h"
00040 #include "Document.h"
00041 #include "PropertyContainer.h"
00042 #include "DocumentObject.h"
00043 #define new DEBUG_CLIENTBLOCK
00044 using namespace App;
00045 using namespace Base;
00046 using namespace std;
00047
00048
00049
00050
00051
00052
00053
00054 TYPESYSTEM_SOURCE(App::PropertyFileIncluded , App::Property);
00055
00056 PropertyFileIncluded::PropertyFileIncluded()
00057 {
00058
00059 }
00060
00061 PropertyFileIncluded::~PropertyFileIncluded()
00062 {
00063
00064 if (!_cValue.empty()) {
00065 Base::FileInfo file(_cValue.c_str());
00066 file.deleteFile();
00067 }
00068 }
00069
00070 std::string PropertyFileIncluded::getDocTransientPath(void) const
00071 {
00072 PropertyContainer *co = getContainer();
00073 if (co->isDerivedFrom(DocumentObject::getClassTypeId()))
00074 return dynamic_cast<DocumentObject*>(co)->getDocument()->TransientDir.getValue();
00075
00076 return std::string();
00077 }
00078
00079 std::string PropertyFileIncluded::getExchangeTempFile(void) const
00080 {
00081 return Base::FileInfo::getTempFileName(Base::FileInfo
00082 (getValue()).fileName().c_str(), getDocTransientPath().c_str());
00083 }
00084
00085 void PropertyFileIncluded::setValue(const char* sFile, const char* sName)
00086 {
00087 if (sFile) {
00088 if (_cValue == sFile)
00089 throw Base::Exception("Not possible to set the same file!");
00090
00091 std::string pathTrans = getDocTransientPath();
00092 Base::FileInfo file(sFile);
00093 std::string path = file.dirPath();
00094 if (!file.exists()) {
00095 std::stringstream str;
00096 str << "File " << file.filePath() << " does not exist.";
00097 throw Base::Exception(str.str());
00098 }
00099
00100 aboutToSetValue();
00101
00102
00103 Base::FileInfo value(_cValue);
00104 std::string pathAct = value.dirPath();
00105 if (value.exists())
00106 value.deleteFile();
00107
00108
00109 if (sName) {
00110 Base::FileInfo ExtraName(path + "/" + sName);
00111 if (ExtraName.exists() ) {
00112
00113 int i=0;
00114
00115 do {
00116 i++;
00117 std::stringstream str;
00118 str << path << "/" << sName << i;
00119 ExtraName.setFile(str.str());
00120 }
00121 while (ExtraName.exists());
00122 _cValue = ExtraName.filePath();
00123 _BaseFileName = ExtraName.fileName();
00124
00125 }
00126 else {
00127 _cValue = path + "/" + sName;
00128 _BaseFileName = sName;
00129 }
00130 }
00131 else if (value.fileName().empty()) {
00132 _cValue = pathTrans + "/" + file.fileName();
00133 _BaseFileName = file.fileName();
00134 }
00135
00136
00137 if (path == pathTrans) {
00138 bool done = file.renameFile(_cValue.c_str());
00139
00140 if (!done) {
00141 std::stringstream str;
00142 str << "Cannot rename file " << file.filePath() << " to " << _cValue;
00143 throw Base::Exception(str.str());
00144 }
00145 }
00146
00147 else {
00148
00149 Base::FileInfo fi(_cValue);
00150 if (fi.exists()) {
00151 Base::FileInfo fi2(Base::FileInfo::getTempFileName());
00152 std::stringstream str;
00153 str << fi.dirPath() << "/" << fi2.fileNamePure();
00154 std::string ext = fi.extension(false);
00155 if (!ext.empty())
00156 str << "." << ext;
00157 Base::FileInfo fi3(str.str());
00158 _cValue = fi3.filePath();
00159 _BaseFileName = fi3.fileName();
00160 }
00161
00162 bool done = file.copyTo(_cValue.c_str());
00163
00164 if (!done) {
00165 std::stringstream str;
00166 str << "Cannot copy file from " << file.filePath() << " to " << _cValue;
00167 throw Base::Exception(str.str());
00168 }
00169 }
00170
00171 hasSetValue();
00172 }
00173 }
00174
00175 const char* PropertyFileIncluded::getValue(void) const
00176 {
00177 return _cValue.c_str();
00178 }
00179
00180 PyObject *PropertyFileIncluded::getPyObject(void)
00181 {
00182 PyObject *p = PyUnicode_DecodeUTF8(_cValue.c_str(),_cValue.size(),0);
00183 if (!p) throw Base::Exception("UTF8 conversion failure at PropertyString::getPyObject()");
00184 return p;
00185 }
00186
00187 void PropertyFileIncluded::setPyObject(PyObject *value)
00188 {
00189 std::string string;
00190 if (PyUnicode_Check(value)) {
00191 PyObject* unicode = PyUnicode_AsUTF8String(value);
00192 string = PyString_AsString(unicode);
00193 Py_DECREF(unicode);
00194 }
00195 else if (PyString_Check(value)) {
00196 string = PyString_AsString(value);
00197 }
00198 else if (PyFile_Check(value)) {
00199 PyObject* FileName = PyFile_Name(value);
00200 string = PyString_AsString(FileName);
00201 }
00202 else if (PyTuple_Check(value)) {
00203 if (PyTuple_Size(value) != 2)
00204 throw Py::TypeError("Tuple need size of (filePath,newFileName)");
00205 PyObject* file = PyTuple_GetItem(value,0);
00206 PyObject* name = PyTuple_GetItem(value,1);
00207
00208
00209 std::string fileStr;
00210 if (PyUnicode_Check(file)) {
00211 PyObject* unicode = PyUnicode_AsUTF8String(file);
00212 fileStr = PyString_AsString(unicode);
00213 Py_DECREF(unicode);
00214 }
00215 else if (PyString_Check(file)) {
00216 fileStr = PyString_AsString(file);
00217 }
00218 else if (PyFile_Check(file)) {
00219 PyObject* FileName = PyFile_Name(file);
00220 fileStr = PyString_AsString(FileName);
00221 }
00222 else {
00223 std::string error = std::string("first in tuple must be a file or string");
00224 error += value->ob_type->tp_name;
00225 throw Py::TypeError(error);
00226 }
00227
00228
00229 std::string nameStr;
00230 if (PyString_Check(name)) {
00231 nameStr = PyString_AsString(name);
00232 }
00233 else if (PyFile_Check(name)) {
00234 PyObject* FileName = PyFile_Name(name);
00235 nameStr = PyString_AsString(FileName);
00236 }
00237 else {
00238 std::string error = std::string("second in tuple must be a string");
00239 error += value->ob_type->tp_name;
00240 throw Py::TypeError(error);
00241 }
00242
00243 setValue(fileStr.c_str(),nameStr.c_str());
00244 return;
00245
00246 }
00247 else {
00248 std::string error = std::string("type must be str or file");
00249 error += value->ob_type->tp_name;
00250 throw Py::TypeError(error);
00251 }
00252
00253
00254 setValue(string.c_str());
00255 }
00256
00257 void PropertyFileIncluded::Save (Base::Writer &writer) const
00258 {
00259 if (writer.isForceXML()) {
00260 writer.Stream() << writer.ind() << "<FileIncluded file=\"\">" << endl;
00261
00262
00263 if (!_cValue.empty())
00264 writer.insertBinFile(_cValue.c_str());
00265
00266 writer.Stream() << writer.ind() <<"</FileIncluded>" << endl ;
00267 }
00268 else {
00269
00270 if (!_cValue.empty()) {
00271 Base::FileInfo file(_cValue.c_str());
00272 writer.Stream() << writer.ind() << "<FileIncluded file=\"" <<
00273 writer.addFile(file.fileName().c_str(), this) << "\"/>" << std::endl;
00274 }
00275 else
00276 writer.Stream() << writer.ind() << "<FileIncluded file=\"\"/>" << std::endl;
00277 }
00278 }
00279
00280 void PropertyFileIncluded::Restore(Base::XMLReader &reader)
00281 {
00282 reader.readElement("FileIncluded");
00283 string file (reader.getAttribute("file") );
00284
00285 if (!file.empty()) {
00286
00287 reader.addFile(file.c_str(),this);
00288
00289
00290 aboutToSetValue();
00291 _cValue = getDocTransientPath() + "/" + file;
00292 _BaseFileName = file;
00293 hasSetValue();
00294 }
00295 }
00296
00297 void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
00298 {
00299 std::ifstream from(_cValue.c_str());
00300 if (!from)
00301 throw Base::Exception("PropertyFileIncluded::SaveDocFile() "
00302 "File in document transient dir deleted");
00303
00304
00305 unsigned char c;
00306 std::ostream& to = writer.Stream();
00307 while (from.get((char&)c)) {
00308 to.put((const char)c);
00309 }
00310 }
00311
00312 void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
00313 {
00314 std::ofstream to(_cValue.c_str());
00315 if (!to)
00316 throw Base::Exception("PropertyFileIncluded::RestoreDocFile() "
00317 "File in document transient dir deleted");
00318
00319
00320 aboutToSetValue();
00321 unsigned char c;
00322 while (reader.get((char&)c)) {
00323 to.put((const char)c);
00324 }
00325 to.close();
00326 hasSetValue();
00327 }
00328
00329 Property *PropertyFileIncluded::Copy(void) const
00330 {
00331 PropertyFileIncluded *p= new PropertyFileIncluded();
00332
00333
00334 p->_BaseFileName = _BaseFileName;
00335
00336 if (!_cValue.empty()) {
00337 Base::FileInfo file(_cValue);
00338
00339
00340 Base::FileInfo NewName(Base::FileInfo::getTempFileName(file.fileName().c_str(),file.dirPath().c_str()));
00341 NewName.deleteFile();
00342
00343 bool done = file.renameFile(NewName.filePath().c_str());
00344 assert(done);
00345
00346 Base::Console().Log("Copy this=%p Befor=%s After=%s\n",p,p->_cValue.c_str(),NewName.filePath().c_str());
00347 p->_cValue = NewName.filePath().c_str();
00348 }
00349
00350 return p;
00351 }
00352
00353 void PropertyFileIncluded::Paste(const Property &from)
00354 {
00355 aboutToSetValue();
00356 Base::FileInfo file(_cValue);
00357
00358 file.deleteFile();
00359 const PropertyFileIncluded &fileInc = dynamic_cast<const PropertyFileIncluded&>(from);
00360
00361 if (!fileInc._cValue.empty()) {
00362
00363 Base::FileInfo NewFile(fileInc._cValue);
00364 _cValue = NewFile.dirPath() + "/" + fileInc._BaseFileName;
00365 bool done = NewFile.renameFile(_cValue.c_str());
00366 assert(done);
00367 }
00368 else
00369 _cValue.clear();
00370 hasSetValue();
00371 }
00372
00373
00374
00375
00376
00377
00378 TYPESYSTEM_SOURCE(App::PropertyFile , App::PropertyString);
00379
00380 PropertyFile::PropertyFile()
00381 {
00382
00383 }
00384
00385 PropertyFile::~PropertyFile()
00386 {
00387
00388 }
00389