summaryrefslogtreecommitdiff
path: root/ept/debtags/vocabulary.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ept/debtags/vocabulary.cc')
-rw-r--r--ept/debtags/vocabulary.cc170
1 files changed, 60 insertions, 110 deletions
diff --git a/ept/debtags/vocabulary.cc b/ept/debtags/vocabulary.cc
index f2575f9..78e2833 100644
--- a/ept/debtags/vocabulary.cc
+++ b/ept/debtags/vocabulary.cc
@@ -18,10 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <ept/debtags/vocabulary.h>
-#include <ept/debtags/maint/debdbparser.h>
-#include <wibble/exception.h>
-#include <wibble/sys/fs.h>
+#include "vocabulary.h"
+#include "maint/debdbparser.h"
+#include "ept/utils/sys.h"
#include <system_error>
#include <cassert>
#include <cstring>
@@ -32,7 +31,6 @@
#include <unistd.h>
using namespace std;
-using namespace wibble;
namespace ept {
namespace debtags {
@@ -113,7 +111,7 @@ string Vocabulary::pathname()
void Vocabulary::load(const std::string& pathname)
{
- if (!sys::fs::exists(pathname)) return;
+ if (!sys::exists(pathname)) return;
// Read uncompressed data
FILE* in = fopen(pathname.c_str(), "rt");
if (!in)
@@ -126,7 +124,7 @@ void Vocabulary::load(const std::string& pathname)
throw;
}
fclose(in);
- m_timestamp = sys::fs::timestamp(pathname, 0);
+ m_timestamp = sys::timestamp(pathname, 0);
}
voc::TagData& voc::FacetData::obtainTag(const std::string& name)
@@ -271,116 +269,68 @@ void Vocabulary::write()
void Vocabulary::write(const std::string& fname)
{
- // Build the temp file template
- char tmpfname[fname.size() + 7];
- strncpy(tmpfname, fname.c_str(), fname.size());
- strncpy(tmpfname + fname.size(), ".XXXXXX", 8);
-
- // Create and open the temporary file
- int fd = mkstemp(tmpfname);
- if (fd < 0)
- throw wibble::exception::File(tmpfname, "opening file");
-
- // Read the current umask
- mode_t cur_umask = umask(0);
- umask(cur_umask);
-
- // Give the file the right permissions
- if (fchmod(fd, 0666 & ~cur_umask) < 0)
- throw wibble::exception::File(tmpfname, "setting file permissions");
-
- // Pass the file descriptor to stdio
- FILE* out = fdopen(fd, "wt");
- if (!out)
- throw wibble::exception::File(tmpfname, "fdopening file");
-
- // Write out the merged vocabulary data
- write(out);
-
- // Flush stdio's buffers
- fflush(out);
-
- // Flush OS buffers
- fdatasync(fd);
-
- // Close the file
- fclose(out);
-
- // Rename the successfully written file to its final name
- if (rename(tmpfname, fname.c_str()) == -1)
- throw wibble::exception::System(string("renaming ") + tmpfname + " to " + fname);
+ // Serialize the merged vocabulary data
+ std::stringstream str;
+ write(str);
+ // Write it out atomically
+ sys::write_file_atomically(fname, str.str(), 0666);
}
-static void writeDebStyleField(FILE* out, const string& name, const string& val) throw ()
+static void writeDebStyleField(std::ostream& out, const string& name, const string& val) throw ()
{
- fprintf(out, "%s: ", name.c_str());
-
- // Properly escape newlines
- bool was_nl = false;
- for (string::const_iterator s = val.begin(); s != val.end(); s++)
- if (was_nl)
- // \n\n -> \n .\n
- if (*s == '\n')
- {
- fputc(' ', out);
- fputc('.', out);
- fputc(*s, out);
- }
- // \n([^ \t]) -> \n \1
- else if (*s != ' ' && *s != '\t')
- {
- fputc(' ', out);
- fputc(*s, out);
- was_nl = false;
- }
- // \n[ \t] goes unchanged
- else
- {
- fputc(*s, out);
- was_nl = false;
- }
- else
- if (*s == '\n')
- {
- fputc(*s, out);
- was_nl = true;
- }
- else
- fputc(*s, out);
-
- fputc('\n', out);
+ out << name << ": ";
+
+ // Properly escape newlines
+ bool was_nl = false;
+ for (string::const_iterator s = val.begin(); s != val.end(); s++)
+ if (was_nl)
+ // \n\n -> \n .\n
+ if (*s == '\n')
+ out << " ." << *s;
+ // \n([^ \t]) -> \n \1
+ else if (*s != ' ' && *s != '\t')
+ {
+ out << " " << *s;
+ was_nl = false;
+ }
+ // \n[ \t] goes unchanged
+ else
+ {
+ out << *s;
+ was_nl = false;
+ }
+ else
+ if (*s == '\n')
+ {
+ out << *s;
+ was_nl = true;
+ }
+ else
+ out << *s;
+
+ out << endl;
}
-void Vocabulary::write(FILE* out)
+void Vocabulary::write(std::ostream& out)
{
- long start_ofs = ftell(out);
- int facetid = 0;
- int tagid = 0;
-
- //fprintf(stderr, "Write\n");
- for (std::map<std::string, voc::FacetData>::iterator f = m_facets.begin(); f != m_facets.end(); ++f)
- {
- //fprintf(stderr, "Writing facet %.*s\n", PFSTR(f->first));
- writeDebStyleField(out, "Facet", f->first);
- for (std::map<std::string, std::string>::const_iterator j = f->second.begin();
- j != f->second.end(); j++)
- writeDebStyleField(out, j->first, j->second);
- fputc('\n', out);
-
- for (std::map<std::string, voc::TagData>::iterator t = f->second.m_tags.begin();
- t != f->second.m_tags.end(); t++)
- {
- //fprintf(stderr, "Writing tag %.*s\n", PFSTR(t->first));
- writeDebStyleField(out, "Tag", t->first);
- for (std::map<std::string, std::string>::const_iterator j = t->second.begin();
- j != t->second.end(); j++)
- writeDebStyleField(out, j->first, j->second);
- fputc('\n', out);
- }
- }
+ for (const auto& f: m_facets)
+ {
+ //fprintf(stderr, "Writing facet %.*s\n", PFSTR(f->first));
+ writeDebStyleField(out, "Facet", f.first);
+ for (const auto& j : f.second)
+ writeDebStyleField(out, j.first, j.second);
+ out << endl;
+
+ for (const auto& t : f.second.m_tags)
+ {
+ //fprintf(stderr, "Writing tag %.*s\n", PFSTR(t->first));
+ writeDebStyleField(out, "Tag", t.first);
+ for (const auto& j : t.second)
+ writeDebStyleField(out, j.first, j.second);
+ out << endl;
+ }
+ }
}
}
}
-
-// vim:set ts=4 sw=4: