vsl_block_binary_rle.h
Go to the documentation of this file.
1 // This is core/vsl/vsl_block_binary_rle.h
2 #ifndef vsl_block_binary_rle_h_
3 #define vsl_block_binary_rle_h_
4 //:
5 // \file
6 // \brief Efficiently Store/Load a block of values using Run length encoding.
7 // \author Ian Scott, Imorphics, Jun 2010
8 
9 #include <algorithm>
10 #include <iostream>
11 #ifdef _MSC_VER
12 # include <vcl_msvc_warnings.h>
13 #endif
14 #include <vsl/vsl_binary_io.h>
16 
17 //: Write a block of values to a vsl_b_ostream, as (value count) pairs.
18 template <class T>
19 inline void vsl_block_binary_rle_write(vsl_b_ostream &os, const T* begin, std::size_t nelems)
20 {
21  short version=1;
22  vsl_b_write(os, version);
23 
24  if (nelems==0) return;
25 
26  const T* last=begin;
27  const T* current=begin+1;
28  vsl_b_write(os, *last);
29  std::size_t block_count=1;
30  while (--nelems) // pre-decrement, since we have already written one element.
31  {
32  if (*last!=*current)
33  {
34  vsl_b_write(os, block_count);
35  last=current;
36  vsl_b_write(os, *last);
37  block_count=0;
38  }
39  ++current;
40  ++block_count;
41  }
42  vsl_b_write(os, block_count);
43 }
44 
45 //: Read a block of values from a vsl_b_ostream, potentially very efficiently for fundamental types.
46 template <class T>
47 inline void vsl_block_binary_rle_read(vsl_b_istream &is, T* begin, std::size_t nelems)
48 {
49  if (!is) return;
50 
51  short ver;
52  vsl_b_read(is, ver);
53  switch (ver)
54  {
55  case 1:
56  {
57  if (nelems==0) return;
58 
59  T* last=begin;
60  while (nelems)
61  {
62  vsl_b_read(is, *last);
63  std::size_t block_count;
64  vsl_b_read(is, block_count);
65  if (block_count > nelems)
66  {
67  std::cerr << "I/O ERROR: vsl_block_binary_rle_read(&is, T* begin, std::size_t nelems)\n"
68  << " Too many elements in stream.\n";
69  is.is().clear(std::ios::badbit); // Set an unrecoverable IO error on stream
70  return;
71  }
72  std::fill(last+1, last+block_count, *last);
73  last+=block_count;
74  nelems-=block_count;
75  }
76  break;
77  }
78  default:
79  std::cerr << "I/O ERROR: vsl_block_binary_rle_read(&is, T* begin, std::size_t nelems)\n"
80  << " Unknown version number "<< ver << '\n';
81  is.is().clear(std::ios::badbit); // Set an unrecoverable IO error on stream
82  return;
83  }
84 }
85 
86 #endif // vsl_block_binary_rle_h_
A binary output adaptor for any std::ostream.
Definition: vsl_binary_io.h:37
void vsl_b_write(vsl_b_ostream &os, char n)
Write char to vsl_b_ostream.
void vsl_block_binary_rle_write(vsl_b_ostream &os, const T *begin, std::size_t nelems)
Write a block of values to a vsl_b_ostream, as (value count) pairs.
Byte-swapping, arbitrary length integer conversion, and explicit I/O.
std::istream & is() const
A reference to the adaptor's stream.
void vsl_block_binary_rle_read(vsl_b_istream &is, T *begin, std::size_t nelems)
Read a block of values from a vsl_b_ostream, potentially very efficiently for fundamental types.
void vsl_b_read(vsl_b_istream &is, char &n)
Read char from vsl_b_istream.
An adaptor for any std::istream to make it suitable for binary input.
Set of functions, and objects to perform binary IO.