KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
base_64_encoded_output.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Suneth Warnakulasuriya
11 //
12 
13 #pragma once
14 
15 // System includes
16 #include <algorithm>
17 #include <array>
18 #include <iterator>
19 #include <string>
20 #include <ostream>
21 
22 // External includes
23 
24 // Project includes
25 #include "includes/define.h"
26 
27 namespace Kratos
28 {
31 
41 class KRATOS_API(KRATOS_CORE) Base64EncodedOutput
42 {
43 public:
45 
46 
48  using IndexType = std::size_t;
49 
53 
61  template<class TIteratorType>
63  {
64  public:
67 
68  using value_type = char;
69  using pointer = char*;
70  using reference = char&;
71  using iterator_category = std::forward_iterator_tag;
72  using difference_type = std::ptrdiff_t;
73 
77 
85  ByteIterator(TIteratorType it)
86  : mIt(it),
87  mValue(*it),
88  mByteIndex(0u)
89  {}
90 
94 
103  {
104  return reinterpret_cast<const value_type*>(&mValue)[mByteIndex];
105  }
106 
115  {
116  using value_type = typename std::iterator_traits<TIteratorType>::value_type;
117  constexpr IndexType value_size = sizeof(value_type);
118  if ((++mByteIndex) == value_size) {
119  mValue = *++mIt;
120  mByteIndex = 0;
121  }
122  return *this;
123  }
124 
132  {
133  ByteIterator copy = *this;
134  ++(*this);
135  return copy;
136  }
137 
139 
140  private:
143 
144  TIteratorType mIt;
145  typename std::iterator_traits<TIteratorType>::value_type mValue;
146  IndexType mByteIndex = 0u;
147 
149  };
150 
154 
161  Base64EncodedOutput(std::ostream& rOStream)
162  : mrOStream(rOStream)
163  {
164  }
165 
172 
176 
187  template <typename TIteratorType,
188  std::enable_if_t<std::is_base_of_v<std::input_iterator_tag, typename std::iterator_traits<TIteratorType>::iterator_category>, bool> = true>
189  void WriteData(
190  TIteratorType Begin,
191  const IndexType N)
192  {
193  // skips writing if an empty container is passed.
194  if (N == 0) {
195  return;
196  }
197 
198  using value_type = typename std::iterator_traits<TIteratorType>::value_type;
199 
200  ByteIterator itr_byte_triplet(Begin);
201 
202  const IndexType raw_bytes = N * sizeof(value_type);
203 
204  // Following offset forces to write bytes to mByteTripliet array even
205  // if raw_bytes count is less than the mByteTripletIndex. This is important
206  // in the case if there are less number of raw_bytes (in case of UInt8 data type),
207  // then raw bytes may be less than mByteTripletIndex, hence avoiding
208  // reading data from the data stream.
209  const IndexType initial_byte_triplet_offset = raw_bytes + mByteTripletIndex;
210 
211  // first fill the existing mByteTriplet
212  IndexType number_of_written_bytes = 0;
213  for (; mByteTripletIndex < std::min(initial_byte_triplet_offset, IndexType{3}); ++mByteTripletIndex) {
214  mByteTriplet[mByteTripletIndex] = *itr_byte_triplet++;
215  ++number_of_written_bytes;
216  }
217 
218  // check if the triplets are filled otherwise don't write, wait for the
219  // closeOutputData call to write remaining bytes in mByteTriplet
220  if (mByteTripletIndex == 3) {
221  mByteTripletIndex = 0;
222  // write the last byte triplet
223  EncodeTriplet(mrOStream, mByteTriplet, 0);
224 
225  // in steps of 3
226  const IndexType number_of_triplets = (raw_bytes - number_of_written_bytes) / 3;
227 
228  for (IndexType i = 0; i < number_of_triplets; ++i) {
229  EncodeTriplet(mrOStream, {*itr_byte_triplet++, *itr_byte_triplet++, *itr_byte_triplet++}, 0);
230  }
231 
232  number_of_written_bytes += number_of_triplets * 3;
233 
234  // now fill the mByteTriplet with the remaining bytes of the data
235  const IndexType remaining_bytes = raw_bytes - number_of_written_bytes;
236  for (; mByteTripletIndex < remaining_bytes; ++mByteTripletIndex) {
237  mByteTriplet[mByteTripletIndex] = *itr_byte_triplet++;
238  }
239  }
240  }
241 
243 
244 private:
247 
253  std::ostream& mrOStream;
254 
260  IndexType mByteTripletIndex = 0;
261 
267  std::array<char, 3> mByteTriplet;
268 
275  constexpr static char base64Map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
276 
280 
291  static void EncodeTriplet(
292  std::ostream& rOutput,
293  const std::array<char, 3>& rBytes,
294  const IndexType Padding
295  )
296  {
297  char tmp[5] = {
298  base64Map[(rBytes[0] & 0xfc) >> 2],
299  base64Map[((rBytes[0] & 0x03) << 4) + ((rBytes[1] & 0xf0) >> 4)],
300  base64Map[((rBytes[1] & 0x0f) << 2) + ((rBytes[2] & 0xc0) >> 6)],
301  base64Map[rBytes[2] & 0x3f], '\0'};
302 
303  std::fill(tmp + 4 - Padding, tmp + 4, '=');
304 
305  rOutput << tmp;
306  }
307 
309 };
310 
312 
313 } // namespace Kratos
A forward iterator that iterates over bytes in a sequence.
Definition: base_64_encoded_output.h:63
value_type operator*() const
Dereference operator.
Definition: base_64_encoded_output.h:102
char & reference
Definition: base_64_encoded_output.h:70
ByteIterator operator++(int)
Post-increment operator.
Definition: base_64_encoded_output.h:131
char * pointer
Definition: base_64_encoded_output.h:69
ByteIterator(TIteratorType it)
Constructor.
Definition: base_64_encoded_output.h:85
std::forward_iterator_tag iterator_category
Definition: base_64_encoded_output.h:71
char value_type
Definition: base_64_encoded_output.h:68
ByteIterator & operator++()
Pre-increment operator.
Definition: base_64_encoded_output.h:114
std::ptrdiff_t difference_type
Definition: base_64_encoded_output.h:72
Encodes given iterator data to base 64 string representation.
Definition: base_64_encoded_output.h:42
std::size_t IndexType
The index type.
Definition: base_64_encoded_output.h:48
void WriteData(TIteratorType Begin, const IndexType N)
writes the iterator data to the given output stream
Definition: base_64_encoded_output.h:189
Base64EncodedOutput(std::ostream &rOStream)
Constructor.
Definition: base_64_encoded_output.h:161
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
static double min(double a, double b)
Definition: GeometryFunctions.h:71
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
u
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:30
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17