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 } while (strm.avail_out == 0);
106
107 // Check all input was processed.
108 ASSERTL0(strm.avail_in == 0, "Not all input was used.");
109
110 // Check stream is complete.
111 ASSERTL0(ret == Z_STREAM_END, "Stream not finished");
112
113 // Clean-up and return
114 (void)deflateEnd(&strm);
115 return Z_OK;
116}
117
118/**
119 * Convert a string containing compressed binary (i.e. from
120 * deflate) into a base 64 string
121 */
123 std::string &compressedDataString, std::string &base64string);
124
125/**
126 * Compress a vector of NekDouble values into a base64 string.
127 */
128template <class T>
129int ZlibEncodeToBase64Str(std::vector<T> &in, std::string &out64)
130{
131 std::string out;
132
133 int ok = ZlibEncode(in, out);
134
135 BinaryStrToBase64Str(out, out64);
136
137 return ok;
138}
139
140/**
141 * Decompress a zlib-compressed string into a vector of NekDouble
142 * values.
143 */
144template <class T> int ZlibDecode(std::string &in, std::vector<T> &out)
145{
146 int ret;
147 unsigned have;
148 z_stream strm;
149 std::string buffer;
150 buffer.resize(CHUNK);
151 std::string output;
152
153 strm.zalloc = Z_NULL;
154 strm.zfree = Z_NULL;
155 strm.opaque = Z_NULL;
156 strm.avail_in = 0;
157 strm.next_in = Z_NULL;
158 ret = inflateInit(&strm);
159 ASSERTL0(ret == Z_OK, "Error initializing zlib decompression.");
160
161 strm.avail_in = (unsigned int)in.size();
162 strm.next_in = (unsigned char *)(&in[0]);
163
164 do
165 {
166 strm.avail_out = CHUNK;
167 strm.next_out = (unsigned char *)(&buffer[0]);
168
169 ret = inflate(&strm, Z_NO_FLUSH);
170
171 ASSERTL0(ret != Z_STREAM_ERROR, "Stream error occured.");
172
173 switch (ret)
174 {
175 case Z_NEED_DICT:
176 ret = Z_DATA_ERROR;
177 /* Falls through. */
178 case Z_DATA_ERROR:
179 case Z_MEM_ERROR:
180 (void)inflateEnd(&strm);
181 return ret;
182 }
183
184 have = CHUNK - strm.avail_out;
185 output += buffer.substr(0, have);
186 } while (strm.avail_out == 0);
187
188 (void)inflateEnd(&strm);
189
190 if (ret == Z_STREAM_END)
191 {
192 T *readFieldData = (T *)output.c_str();
193 unsigned int len =
194 (unsigned int)output.size() * sizeof(*output.c_str()) / sizeof(T);
195 out.assign(readFieldData, readFieldData + len);
196 return Z_OK;
197 }
198 else
199 {
200 return Z_DATA_ERROR;
201 }
202}
203
204/**
205 * Convert a string containing base 64 (i.e. from xml file)
206 * into a binary string
207 */
209 std::string &base64string, std::string &compressedDataString);
210
211/**
212 * Decompress a base 64 compressed binary string into a vector
213 * of NekDouble values.
214 */
215template <class T>
216int ZlibDecodeFromBase64Str(std::string &in64, std::vector<T> &out)
217{
218 std::string in;
219 Base64StrToBinaryStr(in64, in);
220
221 return ZlibDecode(in, out);
222}
223
224} // namespace CompressData
225} // namespace Nektar::LibUtilities
226#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:144
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:216
void BinaryStrToBase64Str(std::string &compressedDataString, std::string &base64string)
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:129
const std::string EndianTypeMap[]
Definition: CompressData.h:57
EndianType Endianness(void)