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
46{
47
49{
53 eEndianBigWord, /* Middle-endian, Honeywell 316 style */
54 eEndianLittleWord /* Middle-endian, PDP-11 style */
55};
56
57const std::string EndianTypeMap[] = {"UnknownEndian", "BigEndian",
58 "LittleEndian", "BigWordEndian",
59 "LittleWordEndian"};
60
62
63namespace CompressData
64{
66LIB_UTILITIES_EXPORT std::string GetBitSizeStr(void);
67
68/**
69 * Compress a vector of NekDouble values into a string using zlib.
70 */
71template <class T> int ZlibEncode(std::vector<T> &in, std::string &out)
72{
73 int ret;
74 unsigned have;
75 std::string buffer;
76 buffer.resize(CHUNK);
77 z_stream strm;
78 unsigned char *input = (unsigned char *)(&in[0]);
79
80 /* allocate deflate state */
81 strm.zalloc = Z_NULL;
82 strm.zfree = Z_NULL;
83 strm.opaque = Z_NULL;
84 ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
85
86 ASSERTL0(ret == Z_OK, "Error initializing Zlib.");
87
88 strm.avail_in = (unsigned int)in.size() * sizeof(T) / sizeof(char);
89 strm.next_in = input;
90
91 // Deflate input until output buffer is no longer full.
92 do
93 {
94 strm.avail_out = CHUNK;
95 strm.next_out = (unsigned char *)(&buffer[0]);
96
97 ret = deflate(&strm, Z_FINISH);
98
99 // Deflate can return Z_OK, Z_STREAM_ERROR, Z_BUF_ERROR or
100 // Z_STREAM_END. All, except Z_STREAM_ERROR are ok.
101 ASSERTL0(ret != Z_STREAM_ERROR, "Zlib stream error");
102
103 have = CHUNK - strm.avail_out;
104 out += buffer.substr(0, have);
105
106 } while (strm.avail_out == 0);
107
108 // Check all input was processed.
109 ASSERTL0(strm.avail_in == 0, "Not all input was used.");
110
111 // Check stream is complete.
112 ASSERTL0(ret == Z_STREAM_END, "Stream not finished");
113
114 // Clean-up and return
115 (void)deflateEnd(&strm);
116 return Z_OK;
117}
118
119/**
120 * Convert a string containing compressed binary (i.e. from
121 * deflate) into a base 64 string
122 */
124 std::string &compressedDataString, std::string &base64string);
125
126/**
127 * Compress a vector of NekDouble values into a base64 string.
128 */
129template <class T>
130int ZlibEncodeToBase64Str(std::vector<T> &in, std::string &out64)
131{
132 std::string out;
133
134 int ok = ZlibEncode(in, out);
135
136 BinaryStrToBase64Str(out, out64);
137
138 return ok;
139}
140
141/**
142 * Decompress a zlib-compressed string into a vector of NekDouble
143 * values.
144 */
145template <class T> int ZlibDecode(std::string &in, std::vector<T> &out)
146{
147 int ret;
148 unsigned have;
149 z_stream strm;
150 std::string buffer;
151 buffer.resize(CHUNK);
152 std::string output;
153
154 strm.zalloc = Z_NULL;
155 strm.zfree = Z_NULL;
156 strm.opaque = Z_NULL;
157 strm.avail_in = 0;
158 strm.next_in = Z_NULL;
159 ret = inflateInit(&strm);
160 ASSERTL0(ret == Z_OK, "Error initializing zlib decompression.");
161
162 strm.avail_in = (unsigned int)in.size();
163 strm.next_in = (unsigned char *)(&in[0]);
164
165 do
166 {
167 strm.avail_out = CHUNK;
168 strm.next_out = (unsigned char *)(&buffer[0]);
169
170 ret = inflate(&strm, Z_NO_FLUSH);
171
172 ASSERTL0(ret != Z_STREAM_ERROR, "Stream error occured.");
173
174 switch (ret)
175 {
176 case Z_NEED_DICT:
177 ret = Z_DATA_ERROR;
178 /* Falls through. */
179 case Z_DATA_ERROR:
180 case Z_MEM_ERROR:
181 (void)inflateEnd(&strm);
182 return ret;
183 }
184
185 have = CHUNK - strm.avail_out;
186 output += buffer.substr(0, have);
187
188 } while (strm.avail_out == 0);
189
190 (void)inflateEnd(&strm);
191
192 if (ret == Z_STREAM_END)
193 {
194 T *readFieldData = (T *)output.c_str();
195 unsigned int len =
196 (unsigned int)output.size() * sizeof(*output.c_str()) / sizeof(T);
197 out.assign(readFieldData, readFieldData + len);
198 return Z_OK;
199 }
200 else
201 {
202 return Z_DATA_ERROR;
203 }
204}
205
206/**
207 * Convert a string containing base 64 (i.e. from xml file)
208 * into a binary string
209 */
211 std::string &base64string, std::string &compressedDataString);
212
213/**
214 * Decompress a base 64 compressed binary string into a vector
215 * of NekDouble values.
216 */
217template <class T>
218int ZlibDecodeFromBase64Str(std::string &in64, std::vector<T> &out)
219{
220 std::string in;
221 Base64StrToBinaryStr(in64, in);
222
223 return ZlibDecode(in, out);
224}
225
226} // namespace CompressData
227} // namespace Nektar::LibUtilities
228#endif
#define CHUNK
Definition: CompressData.h:43
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define LIB_UTILITIES_EXPORT
array buffer
Definition: GsLib.hpp:81
void Base64StrToBinaryStr(std::string &base64string, std::string &compressedDataString)
int ZlibDecode(std::string &in, std::vector< T > &out)
Definition: CompressData.h:145
int ZlibEncode(std::vector< T > &in, std::string &out)
Definition: CompressData.h:71
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:218
void BinaryStrToBase64Str(std::string &compressedDataString, std::string &base64string)
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:130
const std::string EndianTypeMap[]
Definition: CompressData.h:57
EndianType Endianness(void)