sella::file::GZCSVFileWriter Class Reference

#include <GZCSVFileWriter.h>

List of all members.

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] file The name of the file to write.
[in] delimiter The field delimiter character for this file.
[in] seperator The record seperator character for this file.
Exceptions:
IOException if the file cannot be opened for writing.

Definition at line 24 of file GZCSVFileWriter.cpp.

00024                                                                                                            :
00025         filename(file),
00026 
00027         delimiter(delimiter),
00028         seperator(seperator),
00029 
00030         descriptor(::open(file.c_str(), O_WRONLY | O_LARGEFILE | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH))
00031 {
00032         /* Ensure the file was opened for writing, and zero all buffers and state machines. */
00033         if (this->descriptor <= 0) {
00034                 THROW(IOException, "failed to open file '%s' for writing", this->filename.c_str());
00035         }
00036         memset(&(this->stream), 0, sizeof(this->stream));
00037         memset(&(this->buffer), 0, sizeof(this->buffer));
00038 
00039         /* Initialize for the writing of GZIP compressed files. */
00040         if (::deflateInit2(&(this->stream), 9 /* Best Compression */, Z_DEFLATED, 16 + MAX_WBITS /* GZIP */, 9 /* Maximum Memory and Speed */, Z_DEFAULT_STRATEGY) != Z_OK) {
00041 		::close(this->descriptor);
00042 
00043                 THROW(IOException, "failed to initilize zlib instance for writing file '%s'", this->filename.c_str());
00044         }
00045 }

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 51 of file GZCSVFileWriter.cpp.

References close().

00051                                                 {
00052         if (this->descriptor != 0) {
00053                 ::deflateEnd(&(this->stream));
00054 
00055                 this->close();
00056         }
00057 }


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] rename When set to a non-zero length string, the file will be renamed to the value in rename after closing.

Definition at line 163 of file GZCSVFileWriter.cpp.

Referenced by ~GZCSVFileWriter().

00163                                                                         {
00164         uint8_t buffer[4];
00165 
00166         /* Close the compression stream out. */
00167         this->write(buffer, 0, Z_FINISH);
00168 	
00169 	::close(this->descriptor);
00170 
00171         if (rename.length() > 0) {
00172                 ::rename(this->filename.c_str(), rename.c_str());
00173         }
00174         this->filename.clear();
00175         this->descriptor = 0;
00176 }

void GZCSVFileWriter::write ( uint8_t *  input,
ssize_t  length,
int  flush 
) [protected]

Append a character sequence to the file after compressing it.

Parameters:
[in] data The bytes to compress before writing.
[in] size The number of bytes to compress.
[in] flush The zlib flush flag to utilize for the compression.
Exceptions:
IOException if unabled to write the supplied bytes for any reason.

Definition at line 122 of file GZCSVFileWriter.cpp.

00122                                                                                           {
00123         ssize_t expect;
00124 
00125         this->stream.next_in = input;
00126         this->stream.avail_in = length;
00127 
00128         do {
00129                 this->stream.next_out = this->buffer[0];
00130                 this->stream.avail_out = sizeof(this->buffer[0]);
00131 
00132                 /* Compress the supplied data into the buffer. */
00133                 switch (::deflate(&(this->stream), flush)) {
00134                         case Z_STREAM_ERROR:
00135                                 THROW(IOException, "zlib compression failure when writing buffer to compressed file '%s'", this->filename.c_str());
00136                 }
00137 
00138                 /* Write the compressed data to the file. */
00139                 if ((expect = (sizeof(this->buffer[0]) - this->stream.avail_out)) > 0) {
00140                         while ((length = ::write(this->descriptor, this->buffer[0], sizeof(this->buffer[0]) - this->stream.avail_out)) != expect) {
00141                                 if (length == -1) {
00142                                         THROW(IOException, "failure writing buffer to compressed file '%s'", this->filename.c_str());
00143                                 }
00144                                 expect -= length;
00145                         }
00146                 }
00147         } while (this->stream.avail_out == 0);
00148 
00149         /* Ensure all data was compressed and written to the file. */
00150         if (this->stream.avail_in != 0) {
00151                 THROW(IOException, "failed to write full buffer to compressed file '%s'", this->filename.c_str());
00152         }
00153 }

void GZCSVFileWriter::write ( const std::vector< std::string > &  data  ) 

Append the next record to the file.

Parameters:
[in] data The vector which contains all fields of the record.
Exceptions:
IOException if unabled to write the next record for any reason.

Definition at line 66 of file GZCSVFileWriter.cpp.

00066                                                                                  {
00067         size_t length = 0;
00068 
00069         /* Write all fields, one at a time, to the compression stream. */
00070         for (auto iter = data.begin(); iter != data.end(); ++iter) {
00071                 ssize_t offset = 0;
00072 
00073                 /* Append the field delimiter if this is not the first field of the record. */
00074                 if (iter != data.begin()) {
00075                         /* Purge the buffer if required to make room for the field delimiter. */
00076                         if (sizeof(this->delimiter) > (sizeof(this->buffer[1]) - length)) {
00077                                 this->write(this->buffer[1], length, Z_NO_FLUSH);
00078 
00079                                 length = 0;
00080                         }
00081                         this->buffer[1][length++] = this->delimiter;
00082                 }
00083 
00084                 do { /* Append the field value to the buffer. */
00085                         /* Copy as much of the field value as possible to the buffer. */
00086                         if ((iter->length() - offset) > (sizeof(this->buffer[1]) - length)) {
00087                                 ::memcpy(&(this->buffer[1][length]), &(iter->c_str()[offset]), sizeof(this->buffer[1]) - length);
00088 
00089                                 this->write(this->buffer[1], sizeof(this->buffer[1]), Z_NO_FLUSH);
00090 
00091                                 offset += (sizeof(this->buffer[1]) - length);
00092                                 length = 0;
00093                         } else {
00094                                 ::memcpy(&(this->buffer[1][length]), &(iter->c_str()[offset]), iter->length() - offset);
00095 
00096                                 length += (iter->length() - offset);
00097                                 offset += (iter->length() - offset);
00098                         }
00099                 } while (offset != static_cast<ssize_t>(iter->length()));
00100         }
00101 
00102         /* Purge the buffer if required to make room for the record seperator. */
00103         if (sizeof(this->seperator) > (sizeof(this->buffer[1]) - length)) {
00104                 this->write(this->buffer[1], length, Z_NO_FLUSH);
00105 
00106                 length = 0;
00107         }
00108         this->buffer[1][length++] = this->seperator;
00109 
00110         this->write(this->buffer[1], length, Z_NO_FLUSH);
00111 }


The documentation for this class was generated from the following files:
 All Classes Functions Variables

Generated on 20 Nov 2014 for libutil++ by  doxygen 1.6.1