alaCarte Maps
Renderer for OpenStreetMap tiles
archive.cpp
Go to the documentation of this file.
1 
21 #include <fstream>
22 
23 #include "settings.hpp"
24 
25 #include "utils/archive.hpp"
26 
27 #define ROUND_PAGE(_X) (((_X) % PAGE_SIZE == 0) ? (_X) : (((_X) / PAGE_SIZE + 1) * PAGE_SIZE))
28 #define PAGE_SIZE (64 * 1024)
29 
30 Archive::Archive(const string& archPath)
31  : archPath(archPath)
32 {
33 }
34 
35 void Archive::addFile(const string& filePath)
36 {
37  paths.push_back(filePath);
38 }
39 
41 {
42  std::ofstream out(archPath, std::ofstream::binary);
43  if (!out.is_open())
44  BOOST_THROW_EXCEPTION(excp::FileNotWritable() << excp::InfoFileName(archPath));
45 
46  // magic number
47  out.write(MAGIC, sizeof(MAGIC));
48 
49  // number of files
50  uint32_t num = paths.size();
51  out.write((char*) &num, sizeof(num));
52 
53  uint64_t header_size = (uint64_t) out.tellp();
54  // length of offsets
55  header_size += paths.size() * sizeof(entry_t);
56 
57  // write file offsets
58  entry_t* entries = new entry_t[paths.size()];
59  entries[0].offset = ROUND_PAGE(header_size);
60  for (int i = 0; i < paths.size(); i++)
61  {
62  std::ifstream input(paths[i]);
63  if (!input.is_open())
64  BOOST_THROW_EXCEPTION(excp::FileNotFoundException() << excp::InfoFileName(paths[i]));
65  input.seekg(0, input.end);
66  uint64_t length = input.tellg();
67  entries[i].length = length;
68 
69  if (i < paths.size() - 1)
70  entries[i+1].offset = ROUND_PAGE(entries[i].offset + length);
71  }
72  out.write((char*) entries, paths.size() * sizeof(entry_t));
73  delete[] entries;
74 
75  // padding
76  while (out.tellp() % PAGE_SIZE != 0)
77  out.write("\0", 1);
78 
79  // write files
80  for (int i = 0; i < paths.size(); i++)
81  {
82  std::ifstream input(paths[i], std::ifstream::binary);
83  if (!input.is_open())
84  BOOST_THROW_EXCEPTION(excp::FileNotFoundException() << excp::InfoFileName(paths[i]));
85  out << input.rdbuf();
86 
87  // padding
88  while (out.tellp() % PAGE_SIZE != 0)
89  out.write("\0", 1);
90  }
91 }
92 
93 void Archive::getEntries(std::vector<Archive::entry_t>& entries)
94 {
95  std::ifstream in(archPath, std::ifstream::binary);
96  if (!in.is_open())
97  BOOST_THROW_EXCEPTION(excp::FileNotFoundException() << excp::InfoFileName(archPath));
98 
99  char buf[sizeof(MAGIC)];
100  in.read(buf, sizeof(MAGIC));
101  // check if CARTE file
102  if (strncmp(buf, MAGIC, sizeof(MAGIC)) != 0)
103  BOOST_THROW_EXCEPTION(excp::InputFormatException() << excp::InfoFileName(archPath));
104 
105  uint32_t num;
106  in.read((char*) &num, sizeof(num));
107 
108  for (int i = 0; i < num; i++)
109  {
110  entry_t e;
111  in.read((char*) &e, sizeof(e));
112  entries.push_back(e);
113  }
114 }
void getEntries(std::vector< entry_t > &entries)
Definition: archive.cpp:93
#define PAGE_SIZE
Definition: archive.cpp:28
uint64_t offset
Definition: archive.hpp:37
uint64_t length
Definition: archive.hpp:38
void write()
Definition: archive.cpp:40
Archive(const string &path)
Definition: archive.cpp:30
string archPath
Definition: archive.hpp:33
Thrown if input was not in the right format.
Definition: exceptions.hpp:77
std::vector< string > paths
Definition: archive.hpp:32
#define MAGIC
Definition: archive.hpp:27
void addFile(const string &filePath)
Definition: archive.cpp:35
Thrown if a file was not found.
Definition: exceptions.hpp:73
Thrown if a file was not writeable.
Definition: exceptions.hpp:75
#define ROUND_PAGE(_X)
This file is part of alaCarte.
Definition: archive.cpp:27
boost::error_info< struct TagFileName, string > InfoFileName
Use this to inform about a file name.
Definition: exceptions.hpp:43