MADARA  3.4.1
FileFragmenter.h
Go to the documentation of this file.
1 #ifndef _MADARA_KNOWLEDGE_FILEFRAGMENTER_H_
2 #define _MADARA_KNOWLEDGE_FILEFRAGMENTER_H_
3 
4 #include <string>
5 #include <vector>
12 
13 namespace madara
14 {
15 namespace knowledge
16 {
23 {
24 public:
29 
36  FileFragmenter(char* buffer, size_t size, size_t frag_size = 60000)
37  : file_size(0), file_contents(0)
38  {
39  fragment_buffer(buffer, size, frag_size);
40  }
41 
47  FileFragmenter(const std::string& filename, size_t frag_size = 60000)
48  : file_size(0), file_contents(0)
49  {
50  fragment_file(filename, frag_size);
51  }
52 
60  inline size_t fragment_file(
61  const std::string& filename, size_t frag_size = 60000)
62  {
63  void* buffer;
64 
65  if (utility::read_file(filename, buffer, file_size) == 0)
66  {
68  "FileFragmenter::fragment_file: "
69  "read file %s, contents of size %d is at %p.\n",
70  filename.c_str(), (int)file_size, buffer);
71 
72  file_contents = (char*)buffer;
73  return fragment_buffer(file_contents.get(), file_size, frag_size);
74  }
75  else
76  {
78  "FileFragmenter::fragment_file: "
79  "ERROR: Could not read file %s.\n",
80  filename.c_str());
81  }
82 
83  return 0;
84  }
85 
93  inline size_t fragment_buffer(
94  char* buffer, size_t size, size_t frag_size = 60000)
95  {
96  size_t num_frags = size / frag_size;
97  size_t extra = size % frag_size;
98  utility::ScopedArray<unsigned char> segment = new unsigned char[frag_size];
99 
100  if (extra > 0)
101  {
102  records.resize(num_frags + 1);
103 
104  // copy over the extra chars to the last record
105  memcpy(segment.get(), &(buffer[num_frags * frag_size]), extra);
106  records[num_frags].set_file(segment.get(), extra);
107  }
108  else
109  {
110  records.resize(num_frags);
111  }
112 
113  // need to then emplace each buffer into the records
114  for (size_t i = 0; i < num_frags; ++i)
115  {
116  // copy over each segment of frag_size and emplace in record
117  memcpy(segment.get(), &(buffer[i * frag_size]), frag_size);
118  records[i].set_file(segment.get(), frag_size);
119  }
120 
121  return records.size();
122  }
123 
132  const KnowledgeUpdateSettings& settings =
134  {
135  containers::Vector result(key, kb, 0, true, settings);
136 
137  for (size_t i = 0; i < records.size(); ++i)
138  result.push_back(records[i]);
139 
140  return result;
141  }
142 
151  size_t from_kb(const std::string& key, KnowledgeBase& kb,
152  const KnowledgeUpdateSettings& settings =
154  {
155  file_size = 0;
156  file_contents = 0;
157  bool has_missing = false;
158  containers::Vector fragments(key, kb, -1, true, settings);
159 
160  fragments.copy_to(records);
161 
163  "FileFragmenter::from_kb:"
164  " iterating through each record in %d records at %s\n",
165  (int)records.size(), key.c_str());
166 
167  // go through the records and check for valid records
168  for (auto record : records)
169  {
170  // if it's valid, add the size
171  if (record.is_file_type())
172  {
173  file_size += record.size();
174  }
175  else
176  {
178  "FileFragmenter::from_kb:"
179  " missing fragment\n");
180 
181  has_missing = true;
182  }
183  }
184 
186  "FileFragmenter::from_kb:"
187  " after iterations, file_size=%d\n",
188  (int)file_size);
189 
190  // if there are no missing fragments, copy everything to file_contents
191  if (!has_missing)
192  {
193  file_contents = new char[file_size];
194  char* current = file_contents.get();
195 
196  // go through the records and check for valid records
197  for (auto record : records)
198  {
199  // need to check on whether or not we need to try/catch here
200  std::shared_ptr<const std::vector<unsigned char>> binary =
201  record.share_binary();
202 
204  "FileFragmenter::from_kb:"
205  " copying %d bytes to file_contents\n",
206  (int)binary->size());
207 
208  memcpy(current, binary->data(), record.size());
209 
210  current += record.size();
211 
213  "FileFragmenter::from_kb:"
214  " proceeding to next record copy\n");
215 
216  } // end for all records
217  } // end not missing any file fragments
218  else
219  {
221  "FileFragmenter::from_kb:"
222  " missing fragments. Not rebuilding file_contents\n");
223  }
224 
225  return file_size;
226  }
227 
232  inline const char* get_file_contents(void)
233  {
234  return file_contents.get();
235  }
236 
239 
241  size_t file_size;
242 
245 };
246 }
247 }
248 
249 #endif // _MADARA_KNOWLEDGE_FILEFRAGMENTER_H_
#define madara_logger_ptr_log(loggering, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:41
Splits files into fragments that can be saved to and loaded from a knowledge base.
FileFragmenter(char *buffer, size_t size, size_t frag_size=60000)
Constructor.
size_t fragment_file(const std::string &filename, size_t frag_size=60000)
Fragments a file into smaller buffers up to a specified size.
containers::Vector create_vector(const std::string &key, KnowledgeBase &kb, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings::GLOBAL_AS_LOCAL_NO_EXPAND)
Creates a vector in a knowledge base with the current file fragments.
size_t fragment_buffer(char *buffer, size_t size, size_t frag_size=60000)
Fragments a file into smaller buffers up to a specified size.
utility::ScopedArray< char > file_contents
the buffer that holds the file contents
size_t from_kb(const std::string &key, KnowledgeBase &kb, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings::GLOBAL_AS_LOCAL_NO_EXPAND)
Creates a vector in a knowledge base with the current file fragments.
const char * get_file_contents(void)
Returns the file contents as a character buffer.
KnowledgeVector records
records that contain the file fragments
size_t file_size
the size of the file contents
FileFragmenter(const std::string &filename, size_t frag_size=60000)
Constructor.
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
Settings for applying knowledge updates.
static const KnowledgeUpdateSettings GLOBAL_AS_LOCAL_NO_EXPAND
This class stores a vector of KaRL variables.
Definition: Vector.h:36
void copy_to(KnowledgeVector &target) const
Copies the vector elements to an STL vector of Knowledge Records.
Definition: Vector.cpp:402
void push_back(KnowledgeRecord value)
Pushes the value to the end of the array after incrementing the array size.
Definition: Vector.cpp:153
T * get(void)
get the underlying pointer
Definition: ScopedArray.inl:78
constexpr string_t string
constexpr binary_t binary
Provides functions and classes for the distributed knowledge base.
::std::vector< KnowledgeRecord > KnowledgeVector
T get(const KnowledgeRecord &kr)
Get the value of a KnowlegeRecord.
Definition: GetRecord.h:121
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
int read_file(const std::string &filename, void *&buffer, size_t &size, bool add_zero_char)
Reads a file into a provided void pointer.
Definition: Utility.cpp:418
Copyright(c) 2020 Galois.