Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CompressData.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: CompressData.h
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Routines for compressing and inflating data
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_COMPRESSDATA_H
37 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_COMPRESSDATA_H
38 
40 
41 #include <boost/archive/iterators/base64_from_binary.hpp>
42 #include <boost/archive/iterators/binary_from_base64.hpp>
43 #include <boost/archive/iterators/transform_width.hpp>
44 #include <boost/iostreams/copy.hpp>
45 #include <boost/iostreams/filter/zlib.hpp>
46 #include <boost/iostreams/filtering_stream.hpp>
47 #include <boost/assign/list_of.hpp>
48 
49 #include "zlib.h"
50 
51 
52 // Buffer size for zlib compression/decompression
53 #define CHUNK 16384
54 
55 namespace Nektar
56 {
57 namespace LibUtilities
58 {
59 
61  {
65  eEndianBigWord, /* Middle-endian, Honeywell 316 style */
66  eEndianLittleWord /* Middle-endian, PDP-11 style */
67  };
68 
69  const std::string EndianTypeMap[] =
70  {
71  "UnknownEndian",
72  "BigEndian",
73  "LittleEndian",
74  "BigWordEndian",
75  "LittleWordEndian"
76  };
77 
79 
80  namespace CompressData
81  {
82  LIB_UTILITIES_EXPORT std::string GetCompressString(void);
83 
84 
85  LIB_UTILITIES_EXPORT std::string GetBitSizeStr(void);
86 
87 
88  /**
89  * Compress a vector of NekDouble values into a string using zlib.
90  */
91  template<class T> int ZlibEncode(std::vector<T>& in, std::string& out)
92  {
93  int ret;
94  unsigned have;
95  std::string buffer;
96  buffer.resize(CHUNK);
97  z_stream strm;
98  unsigned char* input = (unsigned char*)(&in[0]);
99 
100  /* allocate deflate state */
101  strm.zalloc = Z_NULL;
102  strm.zfree = Z_NULL;
103  strm.opaque = Z_NULL;
104  ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
105 
106  ASSERTL0(ret == Z_OK, "Error initializing Zlib.");
107 
108  strm.avail_in = in.size() * sizeof(T) / sizeof(char);
109  strm.next_in = input;
110 
111  // Deflate input until output buffer is no longer full.
112  do {
113  strm.avail_out = CHUNK;
114  strm.next_out = (unsigned char*)(&buffer[0]);
115 
116  ret = deflate(&strm, Z_FINISH);
117 
118  // Deflate can return Z_OK, Z_STREAM_ERROR, Z_BUF_ERROR or
119  // Z_STREAM_END. All, except Z_STREAM_ERROR are ok.
120  ASSERTL0(ret != Z_STREAM_ERROR, "Zlib stream error");
121 
122  have = CHUNK - strm.avail_out;
123  out += buffer.substr(0, have);
124 
125  } while (strm.avail_out == 0);
126 
127  // Check all input was processed.
128  ASSERTL0(strm.avail_in == 0, "Not all input was used.");
129 
130  // Check stream is complete.
131  ASSERTL0(ret == Z_STREAM_END, "Stream not finished");
132 
133  // Clean-up and return
134  (void)deflateEnd(&strm);
135  return Z_OK;
136  }
137 
138 
139  /**
140  * Convert a string containing compressed binary (i.e. from
141  * deflate) into a base 64 string
142  */
144  std::string &compressedDataString,
145  std::string &base64string);
146 
147  /**
148  * Compress a vector of NekDouble values into a base64 string.
149  */
150  template<class T>
151  int ZlibEncodeToBase64Str(std::vector<T>& in, std::string& out64)
152  {
153  std::string out;
154 
155  int ok = ZlibEncode(in,out);
156 
157  BinaryStrToBase64Str(out,out64);
158 
159  return ok;
160  }
161 
162 
163  /**
164  * Decompress a zlib-compressed string into a vector of NekDouble
165  * values.
166  */
167  template<class T>
168  int ZlibDecode(std::string& in, std::vector<T>& out)
169  {
170  int ret;
171  unsigned have;
172  z_stream strm;
173  std::string buffer;
174  buffer.resize(CHUNK);
175  std::string output;
176 
177  strm.zalloc = Z_NULL;
178  strm.zfree = Z_NULL;
179  strm.opaque = Z_NULL;
180  strm.avail_in = 0;
181  strm.next_in = Z_NULL;
182  ret = inflateInit(&strm);
183  ASSERTL0(ret == Z_OK, "Error initializing zlib decompression.");
184 
185  strm.avail_in = in.size();
186  strm.next_in = (unsigned char*)(&in[0]);
187 
188  do {
189  strm.avail_out = CHUNK;
190  strm.next_out = (unsigned char*)(&buffer[0]);
191 
192  ret = inflate(&strm, Z_NO_FLUSH);
193 
194  ASSERTL0(ret != Z_STREAM_ERROR, "Stream error occured.");
195 
196  switch (ret) {
197  case Z_NEED_DICT:
198  ret = Z_DATA_ERROR; /* and fall through */
199  case Z_DATA_ERROR:
200  case Z_MEM_ERROR:
201  (void)inflateEnd(&strm);
202  return ret;
203  }
204 
205  have = CHUNK - strm.avail_out;
206  output += buffer.substr(0, have);
207 
208  } while (strm.avail_out == 0);
209 
210  (void)inflateEnd(&strm);
211 
212  if (ret == Z_STREAM_END)
213  {
214  T* readFieldData = (T*) output.c_str();
215  unsigned int len = output.size() * sizeof(*output.c_str())
216  / sizeof(T);
217  out.assign( readFieldData, readFieldData + len);
218  return Z_OK;
219  }
220  else
221  {
222  return Z_DATA_ERROR;
223  }
224  }
225 
226 
227 
228  /**
229  * Convert a string containing base 64 (i.e. from xml file)
230  * into a binary string
231  */
233  std::string &base64string,
234  std::string &compressedDataString);
235 
236 
237 
238  /**
239  * Decompress a base 64 compressed binary string into a vector
240  * of NekDouble values.
241  */
242  template<class T>
243  int ZlibDecodeFromBase64Str(std::string& in64, std::vector<T>& out)
244  {
245  std::string in;
246  Base64StrToBinaryStr(in64,in);
247 
248  return ZlibDecode(in,out);
249  }
250 
251  }
252 }
253 }
254 #endif
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
void BinaryStrToBase64Str(std::string &compressedDataString, std::string &base64string)
int ZlibDecode(std::string &in, std::vector< T > &out)
Definition: CompressData.h:168
array buffer
Definition: GsLib.hpp:60
#define CHUNK
Definition: CompressData.h:53
int ZlibEncode(std::vector< T > &in, std::string &out)
Definition: CompressData.h:91
#define LIB_UTILITIES_EXPORT
EndianType Endianness(void)
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:151
const std::string EndianTypeMap[]
Definition: CompressData.h:69
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243
void Base64StrToBinaryStr(std::string &base64string, std::string &compressedDataString)