1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/*
* 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 <cstring>
#include <string>
#include <string.h>
#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
*/
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 :
|