slightly simplified temp file handling

This commit is contained in:
"Jean-Francois Dockes ext:(%22) 2012-08-21 08:35:39 +02:00
parent 6eada80b08
commit 2870274f80
2 changed files with 36 additions and 46 deletions

View File

@ -201,9 +201,9 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf,
{ {
m_fn = f; m_fn = f;
// This is used by filters which manage some kind of cache. // Compute udi for the input file. This is used by filters which
// Indexing by udi makes things easier (because they sometimes get a temp // manage some kind of cache. Indexing by udi makes things easier
// as input // because they sometimes get a temp as actual input.
string udi; string udi;
make_udi(f, cstr_null, udi); make_udi(f, cstr_null, udi);
@ -216,7 +216,9 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf,
// In general, even when the input mime type is set (when // In general, even when the input mime type is set (when
// previewing), we can't use it: it's the type for the actual // previewing), we can't use it: it's the type for the actual
// document, but this can be part of a compound document, and // document, but this can be part of a compound document, and
// we're dealing with the top level file here. // we're dealing with the top level file here, or this could be a
// compressed file. The flag tells us we really can use it
// (e.g. the beagle indexer sets it).
if (flags & FIF_doUseInputMimetype) { if (flags & FIF_doUseInputMimetype) {
if (!imime) { if (!imime) {
LOGERR(("FileInterner:: told to use null imime\n")); LOGERR(("FileInterner:: told to use null imime\n"));
@ -227,8 +229,7 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf,
LOGDEB(("FileInterner:: [%s] mime [%s] preview %d\n", LOGDEB(("FileInterner:: [%s] mime [%s] preview %d\n",
f.c_str(), imime?imime->c_str() : "(null)", m_forPreview)); f.c_str(), imime?imime->c_str() : "(null)", m_forPreview));
// We need to run mime type identification in any case to check // Run mime type identification in any case (see comment above).
// for a compressed file.
l_mime = mimetype(m_fn, stp, m_cfg, usfci); l_mime = mimetype(m_fn, stp, m_cfg, usfci);
// If identification fails, try to use the input parameter. This // If identification fails, try to use the input parameter. This
@ -344,22 +345,21 @@ void FileInterner::init(const string &data, RclConfig *cnf,
df->set_property(Dijon::Filter::OPERATING_MODE, df->set_property(Dijon::Filter::OPERATING_MODE,
m_forPreview ? "view" : "index"); m_forPreview ? "view" : "index");
bool setres = false; bool result = false;
df->set_docsize(data.length()); df->set_docsize(data.length());
if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_STRING)) { if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_STRING)) {
setres = df->set_document_string(data); result = df->set_document_string(data);
} else if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_DATA)) { } else if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_DATA)) {
setres = df->set_document_data(data.c_str(), data.length()); result = df->set_document_data(data.c_str(), data.length());
} else if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_FILE_NAME)) { } else if (df->is_data_input_ok(Dijon::Filter::DOCUMENT_FILE_NAME)) {
string filename; TempFile temp = dataToTempFile(data, m_mimetype);
if (dataToTempFile(data, m_mimetype, filename)) { if (temp.isNotNull() &&
if (!(setres=df->set_document_file(filename))) { (result = df->set_document_file(temp->filename()))) {
m_tmpflgs[0] = false; m_tmpflgs[m_handlers.size()] = true;
m_tempfiles.pop_back(); m_tempfiles.push_back(temp);
}
} }
} }
if (!setres) { if (!result) {
LOGINFO(("FileInterner:: set_doc failed inside for mtype %s\n", LOGINFO(("FileInterner:: set_doc failed inside for mtype %s\n",
m_mimetype.c_str())); m_mimetype.c_str()));
delete df; delete df;
@ -436,38 +436,30 @@ FileInterner::~FileInterner()
// Create a temporary file for a block of data (ie: attachment) found // Create a temporary file for a block of data (ie: attachment) found
// while walking the internal document tree, with a type for which the // while walking the internal document tree, with a type for which the
// handler needs an actual file (ie : external script). // handler needs an actual file (ie : external script).
bool FileInterner::dataToTempFile(const string& dt, const string& mt, TempFile FileInterner::dataToTempFile(const string& dt, const string& mt)
string& fn)
{ {
// Find appropriate suffix for mime type // Create temp file with appropriate suffix for mime type
TempFile temp(new TempFileInternal(m_cfg->getSuffixFromMimeType(mt))); TempFile temp(new TempFileInternal(m_cfg->getSuffixFromMimeType(mt)));
if (temp->ok()) { if (!temp->ok()) {
// We are called before the handler is actually on the stack, so the
// index is m_handlers.size(). m_tmpflgs is a static array, so this is
// no problem
m_tmpflgs[m_handlers.size()] = true;
m_tempfiles.push_back(temp);
} else {
LOGERR(("FileInterner::dataToTempFile: cant create tempfile: %s\n", LOGERR(("FileInterner::dataToTempFile: cant create tempfile: %s\n",
temp->getreason().c_str())); temp->getreason().c_str()));
return false; return TempFile();
} }
int fd = open(temp->filename(), O_WRONLY); int fd = open(temp->filename(), O_WRONLY);
if (fd < 0) { if (fd < 0) {
LOGERR(("FileInterner::dataToTempFile: open(%s) failed errno %d\n", LOGERR(("FileInterner::dataToTempFile: open(%s) failed errno %d\n",
temp->filename(), errno)); temp->filename(), errno));
return false; return TempFile();
} }
if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) { if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) {
close(fd); close(fd);
LOGERR(("FileInterner::dataToTempFile: write to %s failed errno %d\n", LOGERR(("FileInterner::dataToTempFile: write to %s failed errno %d\n",
temp->filename(), errno)); temp->filename(), errno));
return false; return TempFile();
} }
close(fd); close(fd);
fn = temp->filename(); return temp;
return true;
} }
// See if the error string is formatted as a missing helper message, // See if the error string is formatted as a missing helper message,
@ -707,7 +699,7 @@ void FileInterner::popHandler()
{ {
if (m_handlers.empty()) if (m_handlers.empty())
return; return;
int i = m_handlers.size()-1; int i = m_handlers.size() - 1;
if (m_tmpflgs[i]) { if (m_tmpflgs[i]) {
m_tempfiles.pop_back(); m_tempfiles.pop_back();
m_tmpflgs[i] = false; m_tmpflgs[i] = false;
@ -777,18 +769,16 @@ int FileInterner::addHandler()
} else if (newflt->is_data_input_ok(Dijon::Filter::DOCUMENT_DATA)) { } else if (newflt->is_data_input_ok(Dijon::Filter::DOCUMENT_DATA)) {
setres = newflt->set_document_data(txt->c_str(), txt->length()); setres = newflt->set_document_data(txt->c_str(), txt->length());
} else if (newflt->is_data_input_ok(Dijon::Filter::DOCUMENT_FILE_NAME)) { } else if (newflt->is_data_input_ok(Dijon::Filter::DOCUMENT_FILE_NAME)) {
string filename; TempFile temp = dataToTempFile(*txt, mimetype);
if (dataToTempFile(*txt, mimetype, filename)) { if (temp.isNotNull() &&
if (!(setres = newflt->set_document_file(filename))) { (setres = newflt->set_document_file(temp->filename()))) {
m_tmpflgs[m_handlers.size()] = false; m_tmpflgs[m_handlers.size()] = true;
m_tempfiles.pop_back(); m_tempfiles.push_back(temp);
} else { // Hack here, but really helps perfs: if we happen to
// Hack here, but really helps perfs: if we happen to // create a temp file for, ie, an image attachment, keep
// create a temp file for, ie, an image attachment, // it around for preview to use it through get_imgtmp()
// keep it around for preview reuse if (!mimetype.compare(0, 6, "image/")) {
if (!mimetype.compare(0, 6, "image/")) { m_imgtmp = m_tempfiles.back();
m_imgtmp = m_tempfiles.back();
}
} }
} }
} }

View File

@ -149,7 +149,7 @@ class FileInterner {
Status internfile(Rcl::Doc& doc, const string &ipath = ""); Status internfile(Rcl::Doc& doc, const string &ipath = "");
/** Return the file's (top level object) mimetype (useful for /** Return the file's (top level object) mimetype (useful for
* container files) * creating the pseudo-doc for container files)
*/ */
const string& getMimetype() {return m_mimetype;} const string& getMimetype() {return m_mimetype;}
@ -244,7 +244,7 @@ class FileInterner {
void tmpcleanup(); void tmpcleanup();
bool dijontorcl(Rcl::Doc&); bool dijontorcl(Rcl::Doc&);
void collectIpathAndMT(Rcl::Doc&) const; void collectIpathAndMT(Rcl::Doc&) const;
bool dataToTempFile(const string& data, const string& mt, string& fn); TempFile dataToTempFile(const string& data, const string& mt);
void popHandler(); void popHandler();
int addHandler(); int addHandler();
void checkExternalMissing(const string& msg, const string& mt); void checkExternalMissing(const string& msg, const string& mt);