libutil++  1.9.3
 All Classes Functions Variables
Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
sella::file::GZCSVFileWriter Class Reference

A GZIP compressed CSV writer. More...

#include <GZCSVFileWriter.h>

Public Member Functions

 STANDARD_TYPEDEF (sella::file::GZCSVFileWriter)
 
 GZCSVFileWriter (const std::string &file, char delimiter=DefaultDelimiter, char seperator=DefaultSeperator) THROWS(IOException)
 
virtual ~GZCSVFileWriter () NO_EXCEPTIONS
 
void write (const std::vector< std::string > &data) THROWS(IOException)
 
void close (const std::string &rename=std::string()) THROWS(IOException)
 

Static Public Attributes

static const char DefaultDelimiter = 0x1e
 The default delimiter used between the fields of a record; the ASCII record seperator character.
 
static const char DefaultSeperator = 0x1d
 The default seperator used between the records of a file; the ASCII group seperator character.
 

Protected Member Functions

void write (uint8_t *input, ssize_t length, int flush) THROWS(IOException)
 

Detailed Description

A GZIP compressed CSV writer.

Definition at line 31 of file GZCSVFileWriter.h.

Constructor & Destructor Documentation

GZCSVFileWriter::GZCSVFileWriter ( const std::string &  file,
char  delimiter = DefaultDelimiter,
char  seperator = DefaultSeperator 
)

The base constructor for a file writer.

Parameters
[in]fileThe name of the file to write.
[in]delimiterThe field delimiter character for this file.
[in]seperatorThe record seperator character for this file.
Exceptions
IOExceptionif the file cannot be opened for writing.

Definition at line 26 of file GZCSVFileWriter.cpp.

26  :
27  filename(file),
28 
29  delimiter(delimiter),
30  seperator(seperator),
31 
32  descriptor(::open(file.c_str(), O_WRONLY | O_LARGEFILE | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH))
33 {
34  /* Ensure the file was opened for writing, and zero all buffers and state machines. */
35  if (this->descriptor <= 0) {
36  THROW(IOException, "failed to open file '%s' for writing", this->filename.c_str());
37  }
38  memset(&(this->stream), 0, sizeof(this->stream));
39  memset(&(this->buffer), 0, sizeof(this->buffer));
40 
41  /* Initialize for the writing of GZIP compressed files. */
42  if (::deflateInit2(&(this->stream), 9 /* Best Compression */, Z_DEFLATED, 16 + MAX_WBITS /* GZIP */, 9 /* Maximum Memory and Speed */, Z_DEFAULT_STRATEGY) != Z_OK) {
43  ::close(this->descriptor);
44 
45  THROW(IOException, "failed to initilize zlib instance for writing file '%s'", this->filename.c_str());
46  }
47 }
void close(const std::string &rename=std::string()) THROWS(IOException)
GZCSVFileWriter::~GZCSVFileWriter ( )
virtual

The class destructor; this destructor closes the file opened by this instance if it was not explicitly closed by the class user.

Definition at line 53 of file GZCSVFileWriter.cpp.

References close().

53  {
54  if (this->descriptor != 0) {
55  ::deflateEnd(&(this->stream));
56 
57  this->close();
58  }
59 }
void close(const std::string &rename=std::string()) THROWS(IOException)

Member Function Documentation

void GZCSVFileWriter::close ( const std::string &  rename = std::string())

Close the file opened by this instance. Failure to explicitly call this function will not cause a file descriptor leak if the class destructor is called: the destructor will call close() automatically if necessary.

Parameters
[in]renameWhen set to a non-zero length string, the file will be renamed to the value in rename after closing.

Definition at line 165 of file GZCSVFileWriter.cpp.

Referenced by ~GZCSVFileWriter().

165  {
166  uint8_t buffer[4];
167 
168  /* Close the compression stream out. */
169  this->write(buffer, 0, Z_FINISH);
170 
171  ::close(this->descriptor);
172 
173  if (rename.length() > 0) {
174  ::rename(this->filename.c_str(), rename.c_str());
175  }
176  this->filename.clear();
177  this->descriptor = 0;
178 }
void write(const std::vector< std::string > &data) THROWS(IOException)
void close(const std::string &rename=std::string()) THROWS(IOException)
void GZCSVFileWriter::write ( const std::vector< std::string > &  data)

Append the next record to the file.

Parameters
[in]dataThe vector which contains all fields of the record.
Exceptions
IOExceptionif unabled to write the next record for any reason.

Definition at line 68 of file GZCSVFileWriter.cpp.

68  {
69  size_t length = 0;
70 
71  /* Write all fields, one at a time, to the compression stream. */
72  for (auto iter = data.begin(); iter != data.end(); ++iter) {
73  ssize_t offset = 0;
74 
75  /* Append the field delimiter if this is not the first field of the record. */
76  if (iter != data.begin()) {
77  /* Purge the buffer if required to make room for the field delimiter. */
78  if (sizeof(this->delimiter) > (sizeof(this->buffer[1]) - length)) {
79  this->write(this->buffer[1], length, Z_NO_FLUSH);
80 
81  length = 0;
82  }
83  this->buffer[1][length++] = this->delimiter;
84  }
85 
86  do { /* Append the field value to the buffer. */
87  /* Copy as much of the field value as possible to the buffer. */
88  if ((iter->length() - offset) > (sizeof(this->buffer[1]) - length)) {
89  ::memcpy(&(this->buffer[1][length]), &(iter->c_str()[offset]), sizeof(this->buffer[1]) - length);
90 
91  this->write(this->buffer[1], sizeof(this->buffer[1]), Z_NO_FLUSH);
92 
93  offset += (sizeof(this->buffer[1]) - length);
94  length = 0;
95  } else {
96  ::memcpy(&(this->buffer[1][length]), &(iter->c_str()[offset]), iter->length() - offset);
97 
98  length += (iter->length() - offset);
99  offset += (iter->length() - offset);
100  }
101  } while (offset != static_cast<ssize_t>(iter->length()));
102  }
103 
104  /* Purge the buffer if required to make room for the record seperator. */
105  if (sizeof(this->seperator) > (sizeof(this->buffer[1]) - length)) {
106  this->write(this->buffer[1], length, Z_NO_FLUSH);
107 
108  length = 0;
109  }
110  this->buffer[1][length++] = this->seperator;
111 
112  this->write(this->buffer[1], length, Z_NO_FLUSH);
113 }
void write(const std::vector< std::string > &data) THROWS(IOException)
void GZCSVFileWriter::write ( uint8_t *  input,
ssize_t  length,
int  flush 
)
protected

Append a character sequence to the file after compressing it.

Parameters
[in]dataThe bytes to compress before writing.
[in]sizeThe number of bytes to compress.
[in]flushThe zlib flush flag to utilize for the compression.
Exceptions
IOExceptionif unabled to write the supplied bytes for any reason.

Definition at line 124 of file GZCSVFileWriter.cpp.

124  {
125  ssize_t expect;
126 
127  this->stream.next_in = input;
128  this->stream.avail_in = length;
129 
130  do {
131  this->stream.next_out = this->buffer[0];
132  this->stream.avail_out = sizeof(this->buffer[0]);
133 
134  /* Compress the supplied data into the buffer. */
135  switch (::deflate(&(this->stream), flush)) {
136  case Z_STREAM_ERROR:
137  THROW(IOException, "zlib compression failure when writing buffer to compressed file '%s'", this->filename.c_str());
138  }
139 
140  /* Write the compressed data to the file. */
141  if ((expect = (sizeof(this->buffer[0]) - this->stream.avail_out)) > 0) {
142  while ((length = ::write(this->descriptor, this->buffer[0], sizeof(this->buffer[0]) - this->stream.avail_out)) != expect) {
143  if (length == -1) {
144  THROW(IOException, "failure writing buffer to compressed file '%s'", this->filename.c_str());
145  }
146  expect -= length;
147  }
148  }
149  } while (this->stream.avail_out == 0);
150 
151  /* Ensure all data was compressed and written to the file. */
152  if (this->stream.avail_in != 0) {
153  THROW(IOException, "failed to write full buffer to compressed file '%s'", this->filename.c_str());
154  }
155 }
void write(const std::vector< std::string > &data) THROWS(IOException)

The documentation for this class was generated from the following files: