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