1 /* $Id: compress.cpp 538813 2017-06-14 12:15:14Z ivanov $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Vladimir Ivanov
27 *
28 * File Description: The Compression API
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbi_limits.h>
34 #include <util/compress/compress.hpp>
35
36
37 BEGIN_NCBI_SCOPE
38
39
40 //////////////////////////////////////////////////////////////////////////////
41 //
42 // CCompression
43 //
44
CCompression(ELevel level)45 CCompression::CCompression(ELevel level)
46 : m_DecompressMode(eMode_Unknown),
47 m_Level(level), m_ErrorCode(0), m_ErrorMsg(kEmptyStr), m_Flags(0)
48 {
49 return;
50 }
51
52
~CCompression(void)53 CCompression::~CCompression(void)
54 {
55 return;
56 }
57
58
GetLevel(void) const59 CCompression::ELevel CCompression::GetLevel(void) const
60 {
61 if ( m_Level == eLevel_Default) {
62 return GetDefaultLevel();
63 }
64 return m_Level;
65 }
66
67
SetLevel(ELevel level)68 void CCompression::SetLevel(ELevel level)
69 {
70 m_Level = level;
71 }
72
73
GetErrorCode(void) const74 int CCompression::GetErrorCode(void) const
75 {
76 return m_ErrorCode;
77 }
78
79
GetErrorDescription(void) const80 string CCompression::GetErrorDescription(void) const
81 {
82 return m_ErrorMsg;
83 }
84
85
SetError(int errcode,const char * description)86 void CCompression::SetError(int errcode, const char* description)
87 {
88 m_ErrorCode = errcode;
89 m_ErrorMsg = description ? description : kEmptyStr;
90 }
91
92
SetError(int errcode,const string & description)93 void CCompression::SetError(int errcode, const string& description)
94 {
95 m_ErrorCode = errcode;
96 m_ErrorMsg = description;
97 }
98
99
GetFlags(void) const100 CCompression::TFlags CCompression::GetFlags(void) const
101 {
102 return m_Flags;
103 }
104
105
SetFlags(TFlags flags)106 void CCompression::SetFlags(TFlags flags)
107 {
108 m_Flags = flags;
109 }
110
111
x_CompressFile(const string & src_file,CCompressionFile & dst_file,size_t buf_size)112 bool CCompression::x_CompressFile(const string& src_file,
113 CCompressionFile& dst_file,
114 size_t buf_size)
115 {
116 if ( !buf_size ) {
117 SetError(-1, "Buffer size cannot be zero");
118 return false;
119 }
120 _ASSERT(buf_size <= kMax_Int);
121
122 CNcbiIfstream is(src_file.c_str(), IOS_BASE::in | IOS_BASE::binary);
123 if ( !is.good() ) {
124 SetError(-1, "Cannot open source file");
125 return false;
126 }
127 AutoPtr<char, ArrayDeleter<char> > buf(new char[buf_size]);
128 while ( is ) {
129 is.read(buf.get(), buf_size);
130 size_t nread = (size_t)is.gcount();
131 size_t nwritten = dst_file.Write(buf.get(), nread);
132 if ( nwritten != nread ) {
133 return false;
134 }
135 }
136 return true;
137 }
138
139
x_DecompressFile(CCompressionFile & src_file,const string & dst_file,size_t buf_size)140 bool CCompression::x_DecompressFile(CCompressionFile& src_file,
141 const string& dst_file,
142 size_t buf_size)
143 {
144 if ( !buf_size ) {
145 SetError(-1, "Buffer size cannot be zero");
146 return false;
147 }
148 if ( buf_size > kMax_Int ) {
149 buf_size = kMax_Int;
150 }
151 _ASSERT(buf_size <= kMax_Int);
152
153 CNcbiOfstream os(dst_file.c_str(), IOS_BASE::out | IOS_BASE::binary);
154 if ( !os.good() ) {
155 SetError(-1, "Cannot open destination file");
156 return false;
157 }
158 AutoPtr<char, ArrayDeleter<char> > buf(new char[buf_size]);
159 long nread;
160 while ( (nread = src_file.Read(buf.get(), buf_size)) > 0 ) {
161 os.write(buf.get(), nread);
162 if ( !os.good() ) {
163 SetError(-1, "Error writing to ouput file");
164 return false;
165 }
166 }
167 if ( nread == -1 ) {
168 return false;
169 }
170 return true;
171 }
172
173
174
175 //////////////////////////////////////////////////////////////////////////////
176 //
177 // CCompressionProcessor
178 //
179
CCompressionProcessor(void)180 CCompressionProcessor::CCompressionProcessor(void)
181 {
182 Reset();
183 return;
184 }
185
186
~CCompressionProcessor(void)187 CCompressionProcessor::~CCompressionProcessor(void)
188 {
189 return;
190 }
191
192
193 //////////////////////////////////////////////////////////////////////////////
194 //
195 // CCompressionFile
196 //
197
CCompressionFile(void)198 CCompressionFile::CCompressionFile(void)
199 : m_File(0), m_Mode(eMode_Read)
200 {
201 return;
202 }
203
204
~CCompressionFile(void)205 CCompressionFile::~CCompressionFile(void)
206 {
207 return;
208 }
209
210
211
212 //////////////////////////////////////////////////////////////////////////////
213 //
214 // CCompressionUtil
215 //
216
StoreUI4(void * buffer,unsigned long value)217 void CCompressionUtil::StoreUI4(void* buffer, unsigned long value)
218 {
219 if ( !buffer ) {
220 NCBI_THROW(CCoreException, eInvalidArg, "Incorrect buffer pointer");
221 }
222 if ( value > kMax_UI4 ) {
223 NCBI_THROW(CCoreException, eInvalidArg,
224 "Stored value exceeded maximum size for Uint4 type");
225 }
226 unsigned char* buf = (unsigned char*)buffer;
227 for (int i = 0; i < 4; i++) {
228 buf[i] = (unsigned char)(value & 0xff);
229 value >>= 8;
230 }
231 }
232
GetUI4(const void * buffer)233 Uint4 CCompressionUtil::GetUI4(const void* buffer)
234 {
235 if ( !buffer ) {
236 NCBI_THROW(CCoreException, eInvalidArg, "Incorrect buffer pointer");
237 }
238 const unsigned char* buf = (const unsigned char*)buffer;
239 Uint4 value = 0;
240 for (int i = 3; i >= 0; i--) {
241 value <<= 8;
242 value += buf[i];
243 }
244 return value;
245 }
246
StoreUI2(void * buffer,unsigned long value)247 void CCompressionUtil::StoreUI2(void* buffer, unsigned long value)
248 {
249 if ( !buffer ) {
250 NCBI_THROW(CCoreException, eInvalidArg, "Incorrect buffer pointer");
251 }
252 if ( value > kMax_UI2 ) {
253 NCBI_THROW(CCoreException, eInvalidArg,
254 "Stored value exceeded maximum size for Uint2 type");
255 }
256 unsigned char* buf = (unsigned char*)buffer;
257 buf[0] = (unsigned char)(value & 0xff);
258 value >>= 8;
259 buf[1] = (unsigned char)(value & 0xff);
260 }
261
GetUI2(const void * buffer)262 Uint2 CCompressionUtil::GetUI2(const void* buffer)
263 {
264 if ( !buffer ) {
265 NCBI_THROW(CCoreException, eInvalidArg, "Incorrect buffer pointer");
266 }
267 const unsigned char* buf = (const unsigned char*)buffer;
268 return Uint2(((Uint2)(buf[1]) << 8) + buf[0]);
269 }
270
271
272 END_NCBI_SCOPE
273