ISIS Logo
UTILITIES
EPICS Utilities
compress.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <iostream>
5 #include <sstream>
6 #include <iomanip>
7 #include <vector>
8 #include <algorithm>
9 #include "zlib.h"
10 
11 #include <boost/scoped_array.hpp>
12 
13 #include <epicsExport.h>
14 
15 #include "utilities.h"
16 
19 epicsShareFunc int epicsShareAPI compressString(const std::string& str, std::string& comp_str)
20 {
21  uLong len = str.size(); // not including terminating NULL
22  uLong comprLen = compressBound(len); // we should not need more bytes than this
23  boost::scoped_array<Byte> compr(new Byte[comprLen]);
24  comp_str.resize(0);
25  int err = compress(compr.get(), &comprLen, (const Bytef*)str.c_str(), len);
26  if (err != Z_OK)
27  {
28  std::cerr << "compressString: compress failed with error " << err << std::endl;
29  return -1;
30  }
31  std::ostringstream oss;
32  for(int i=0; i<comprLen; ++i)
33  {
34  oss << std::hex << std::setfill ('0') << std::setw (2) << static_cast<unsigned>(compr[i]);
35  }
36  comp_str = oss.str();
37  return 0;
38 }
39 
41 epicsShareFunc int epicsShareAPI uncompressString(const std::string& comp_str, std::string& str)
42 {
43  int length = comp_str.length();
44  str.resize(0);
45  if (length == 0)
46  {
47  return 0;
48  }
49  if (length % 2 != 0) // strings created by compressString() are always an even number of bytes
50  {
51  std::cerr << "uncompressString: input length not an even number of characters" << std::endl;
52  return -1;
53  }
54  if (comp_str.find_first_of(" \t\r\n") != std::string::npos)
55  {
56  std::cerr << "uncompressString: whitespace characters found, did you forget the \"-t\" or \"-S\" options for caget?" << std::endl;
57  return -1;
58  }
59  std::vector<Byte> compr;
60  compr.reserve(length/2);
61  for(int i=0; i < length; i+=2)
62  {
63  compr.push_back(static_cast<Byte>(strtol(comp_str.substr(i,2).c_str(), NULL, 16)));
64  }
65  uLong uncomprLen = 0;
66  boost::scoped_array<Byte> uncompr;
67  int err = Z_BUF_ERROR;
68  for(int i=1; err == Z_BUF_ERROR && i<100; i *= 2)
69  {
70  uncomprLen = std::max(length * 20 * i, 65536); // we have to guess this
71  uncompr.reset(new Byte[uncomprLen]);
72  err = uncompress(uncompr.get(), &uncomprLen, &(compr[0]), compr.size());
73  }
74  if (err != Z_OK)
75  {
76  std::cerr << "uncompressString: uncompress failed with error " << err << " (length=" << length << ",uncomprLen=" << uncomprLen << ")" << std::endl;
77  return -1;
78  }
79  str.reserve(uncomprLen);
80  for(int i=0; (i < uncomprLen); ++i)
81  {
82  str.push_back(static_cast<char>(uncompr[i]));
83  }
84  return 0;
85 }
epicsShareFunc int epicsShareAPI compressString(const std::string &str, std::string &comp_str)
compress a string usinf zlib and then convert compressed bytes into an ascii hex sequence suitable fo...
Definition: compress.cpp:19
epicsShareFunc int epicsShareAPI uncompressString(const std::string &comp_str, std::string &str)
uncompress a string created using compressString()
Definition: compress.cpp:41
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5