Code

Merge from trunk
[inkscape.git] / src / streams-jar.cpp
1 #include <vector>
2 #include "streams-jar.h"
4 namespace Inkscape {
6 const int LOC_EXTRA = 6;  // extra bytes
7 const int LOC_COMP  = 8;  // compression method
8 const int LOC_CSIZE = 18; // compressed size
9 const int LOC_FNLEN = 26; // filename length
10 const int LOC_EFLEN = 28; // extra-field length
12 void JarBuffer::consume_header() throw(JarHeaderException)
13 {
14     try {
15         guint8 data[30];
16         _urihandle->read(data, 4);
17         check_signature(data);
18         _urihandle->read(data+4, 26);
19         compressed_size = compressed_left = unpack_4bytes(data, LOC_CSIZE);
20         eflen = unpack_2bytes(data, LOC_EFLEN);
21         flags = unpack_2bytes(data, LOC_EXTRA);
22         method = unpack_2bytes(data, LOC_COMP);
23         
24 #ifdef DEBUG_STREAMS
25         std::printf("Compressed size is %u\n", compressed_size);
26         std::printf("Extra field length is %hu\n", eflen);
27         std::printf("Flags are %#hx\n", flags);
28         std::printf("Compression method is %#hx\n", method);
29 #endif
30     }
31     catch (std::exception& e) {
32         throw JarHeaderException();
33     }
34 }
36 void JarBuffer::check_signature(guint8 *data) throw(JarHeaderException)
37 {
38     guint32 signature = unpack_4bytes(data, 0);
40 #ifdef DEBUG_STREAMS
41     std::printf("signature is %x\n", signature);
42 #endif
44     if (signature == 0x08074b50) {
45         _urihandle->read(data, 12);
46     } else if (signature != 0x02014b50 && signature != 0x04034b50) {
47         throw JarHeaderException();
48     }
49 }
51 void JarBuffer::reset()//resets zlib and buffer (also skips archived directories)
52 {
53     bool do_reset = false;
54     while (compressed_left == 0) {
55         consume_header();
56         do_reset = true;
57     }
59     if (do_reset) {
60         reset_inflation();
61         setg(eback(), eback(), eback());
62     }
63 }
65 int JarBuffer::consume_and_inflate()
66 {
67     int nbytes;
69     reset();
71     nbytes = compressed_left > BUFSIZE_STREAM ? BUFSIZE_STREAM
72             : compressed_left;
74     if (is_compressed())
75         return consume_compressed(nbytes);
76     else
77         return consume_uncompressed(nbytes);
78 }
80 int JarBuffer::consume_compressed(int nbytes)
81 {
82     int ret=do_consume_and_inflate(nbytes);
84     if ( ret == EOF && eflen > 0 ) {
85         std::vector<guint8> efbuf(eflen);
86         _urihandle->read(&efbuf[0], eflen);
87         return 1;
88     }
90     return ret;
91 }
93 int JarBuffer::consume_uncompressed(int nbytes)
94 {
95     std::vector<guint8> data(nbytes);
96     int consumed=consume(&data[0], nbytes);
97     if ( consumed != EOF ) {
98         copy_to_get(&data[0], consumed);
99         compressed_left -= consumed;
100     }
101     return consumed;
104 GByteArray *JarBuffer::inflate(guint8 *data, const int nbytes)
106     GByteArray *gba = do_inflate(data, nbytes);
107     compressed_left -= nbytes;
108     return gba;
111 guint32 JarBuffer::unpack_4bytes(guint8 *data, const int offset)
113     return ((guint32)data[offset]
114             + (((guint32)data[offset + 1]) << 8)
115             + (((guint32)data[offset + 2]) << 16)
116             + (((guint32)data[offset + 3]) << 24));
119 guint16 JarBuffer::unpack_2bytes(guint8 *data, int offset)
121     return ((guint16)data[offset] + (((guint16)data[offset + 1]) << 8));
124 } // namespace Inkscape
126 /*
127   Local Variables:
128   mode:c++
129   c-file-style:"stroustrup"
130   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
131   indent-tabs-mode:nil
132   fill-column:99
133   End:
134 */
135 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :