Code

* src/path-prefix.h: Add missing CREATE_* directory locations
[inkscape.git] / src / streams-gzip.cpp
1 /*
2  * IO layer : gzip streambuf and streams
3  *
4  * Authors:
5  *   Johan Ceuppens <jceuppen at easynet dot be>
6  *
7  * Copyright (C) 2004 Johan Ceuppens
8  *
9  * Released under GNU LGPL, read the file 'COPYING.LIB' for more information
10  */
12 #include "streams-gzip.h"
14 namespace Inkscape {
16 //With some inpsiration and code from libgsf, fastjar, libpng and RFC 1952
18 static int const GZIP_IS_ASCII       = 0x01; //file contains text
19 static int const GZIP_HEADER_CRC     = 0x02; //there is a CRC in the header
20 static int const GZIP_EXTRA_FIELD    = 0x04; //there is an 'extra' field
21 static int const GZIP_ORIGINAL_NAME  = 0x08; //the original is stored
22 static int const GZIP_HAS_COMMENT    = 0x10; //There is a comment in the header
23 static unsigned int const GZIP_HEADER_FLAGS = (GZIP_IS_ASCII
24                                                |GZIP_HEADER_CRC
25                                                |GZIP_EXTRA_FIELD
26                                                |GZIP_ORIGINAL_NAME
27                                                |GZIP_HAS_COMMENT);
29 /**
30  * GZipBuffer
31  */
33 void GZipBuffer::consume_header() throw(GZipHeaderException)
34 {
35     unsigned int flags;
36     guint8 data[4];
38     try {
39         _urihandle->read(data, 4);
40         check_signature(data);
41         check_flags(data);
42         flags = data[3];
43         _urihandle->read(data, 4);
44         //get_modification_time()
45         _urihandle->read(data, 1);
46         //check_extra_flags();
47         _urihandle->read(data, 1);
48         //check_OS();
49         
50         if (flags & GZIP_EXTRA_FIELD) {
51             get_extrafield();
52         }
53         if (flags & GZIP_ORIGINAL_NAME) {
54             get_filename();
55         }
56         if (flags & GZIP_HAS_COMMENT) {
57             get_comment();
58         }
59         if (flags & GZIP_HEADER_CRC) {
60             get_crc();
61         }
62     }
63     catch(std::exception& e) {
64         throw GZipHeaderException();
65     }
66 }
68 void GZipBuffer::check_signature(guint8 *data) throw(GZipHeaderException)
69 {
70     guint8 const signature[2] = {0x1f, 0x8b};
71     if (memcmp(data, signature, sizeof(signature)) != 0)
72         throw GZipHeaderException();
73 }
75 void GZipBuffer::check_flags(guint8 *data) throw(GZipHeaderException)
76 {
77     unsigned int flags = data[3];
78     if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0)
79         throw GZipHeaderException();
80 }
82 gchar *GZipBuffer::get_filename()
83 {
84 #ifdef DEBUG_STREAMS
85     std::cout<<"Filename is ";
86 #endif
87     return read_string();
88 }
90 gchar *GZipBuffer::get_comment()
91 {
92 #ifdef DEBUG_STREAMS
93     std::cout<<"Comment is "<<std::endl;
94 #endif
95     return read_string();
96 }
98 guint16 GZipBuffer::get_crc()
99 {
100     guint16 buf;
101     _urihandle->read(&buf, 2);
102     return buf;
105 void GZipBuffer::get_extrafield()
107     guint8 length_data[2];
108     _urihandle->read(length_data, 2);
109     unsigned int const length = length_data[0] | (length_data[1] << 8);
110     guint8 *data = new guint8[length];
111     _urihandle->read(data, length);
114 gchar *GZipBuffer::read_string() throw(GZipHeaderException)
116     GByteArray *gba = g_byte_array_new();
117     try {
118         guint8 byte[1];
119         do {
120             _urihandle->read(byte, 1);
121             g_byte_array_append(gba, byte, sizeof(byte));
122 #ifdef DEBUG_STREAMS
123             std::cout <<(char)*byte;
124 #endif
125         } while (*byte != 0);
126     } catch (std::exception& e) {
127         g_byte_array_free(gba, TRUE);
128         throw GZipHeaderException();
129     }
130 #ifdef DEBUG_STREAMS
131     std::cout<<std::endl;
132 #endif
133     gchar *ret = (gchar *)gba->data;
134     g_byte_array_free(gba, FALSE);
135     return ret;
138 } // namespace Inkscape
140 /*
141   Local Variables:
142   mode:c++
143   c-file-style:"stroustrup"
144   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
145   indent-tabs-mode:nil
146   fill-column:99
147   End:
148 */
149 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :