Logo Search packages:      
Sourcecode: inkscape version File versions

streams-gzip.cpp

/*
 * IO layer : gzip streambuf and streams
 *
 * Authors:
 *   Johan Ceuppens <jceuppen at easynet dot be>
 *
 * Copyright (C) 2004 Johan Ceuppens
 *
 * Released under GNU LGPL, read the file 'COPYING.LIB' for more information
 */

#include "streams-gzip.h"

namespace Inkscape {

//With some inpsiration and code from libgsf, fastjar, libpng and RFC 1952

static int const GZIP_IS_ASCII           = 0x01; //file contains text
static int const GZIP_HEADER_CRC     = 0x02; //there is a CRC in the header
static int const GZIP_EXTRA_FIELD    = 0x04; //there is an 'extra' field
static int const GZIP_ORIGINAL_NAME  = 0x08; //the original is stored
static int const GZIP_HAS_COMMENT    = 0x10; //There is a comment in the header
static unsigned int const GZIP_HEADER_FLAGS = (GZIP_IS_ASCII
                                     |GZIP_HEADER_CRC
                                     |GZIP_EXTRA_FIELD
                                     |GZIP_ORIGINAL_NAME
                                     |GZIP_HAS_COMMENT);

/**
 * GZipBuffer
 */

00033 void GZipBuffer::consume_header() throw(GZipHeaderException)
{
    unsigned int flags;
    guint8 data[4];

    try {
      _urihandle->read(data, 4);
      check_signature(data);
      check_flags(data);
      flags = data[3];
      _urihandle->read(data, 4);
      //get_modification_time()
      _urihandle->read(data, 1);
      //check_extra_flags();
      _urihandle->read(data, 1);
      //check_OS();
      
      if (flags & GZIP_EXTRA_FIELD) {
          get_extrafield();
      }
      if (flags & GZIP_ORIGINAL_NAME) {
          get_filename();
      }
      if (flags & GZIP_HAS_COMMENT) {
          get_comment();
      }
      if (flags & GZIP_HEADER_CRC) {
          get_crc();
      }
    }
    catch(std::exception& e) {
      throw GZipHeaderException();
    }
}

void GZipBuffer::check_signature(guint8 *data) throw(GZipHeaderException)
{
    guint8 const signature[2] = {0x1f, 0x8b};
    if (memcmp(data, signature, sizeof(signature)) != 0)
      throw GZipHeaderException();
}

void GZipBuffer::check_flags(guint8 *data) throw(GZipHeaderException)
{
    unsigned int flags = data[3];
    if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0)
      throw GZipHeaderException();
}

gchar *GZipBuffer::get_filename()
{
#ifdef DEBUG_STREAMS
    std::cout<<"Filename is ";
#endif
    return read_string();
}

gchar *GZipBuffer::get_comment()
{
#ifdef DEBUG_STREAMS
    std::cout<<"Comment is "<<std::endl;
#endif
    return read_string();
}

guint16 GZipBuffer::get_crc()
{
    guint16 buf;
    _urihandle->read(&buf, 2);
    return buf;
}

void GZipBuffer::get_extrafield()
{
    guint8 length_data[2];
    _urihandle->read(length_data, 2);
    unsigned int const length = length_data[0] | (length_data[1] << 8);
    guint8 *data = new guint8[length];
    _urihandle->read(data, length);
}

gchar *GZipBuffer::read_string() throw(GZipHeaderException)
{
    GByteArray *gba = g_byte_array_new();
    try {
      guint8 byte[1];
      do {
          _urihandle->read(byte, 1);
          g_byte_array_append(gba, byte, sizeof(byte));
#ifdef DEBUG_STREAMS
          std::cout <<(char)*byte;
#endif
      } while (*byte != 0);
    } catch (std::exception& e) {
      g_byte_array_free(gba, TRUE);
      throw GZipHeaderException();
    }
#ifdef DEBUG_STREAMS
    std::cout<<std::endl;
#endif
    gchar *ret = (gchar *)gba->data;
    g_byte_array_free(gba, FALSE);
    return ret;
}

} // namespace Inkscape

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :

Generated by  Doxygen 1.6.0   Back to index