~ubuntu-branches/ubuntu/quantal/libarchive/quantal

« back to all changes in this revision

Viewing changes to libarchive/test/read_open_memory.c

  • Committer: Package Import Robot
  • Author(s): Andres Mejia
  • Date: 2012-02-23 19:29:24 UTC
  • mfrom: (8.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120223192924-73n4iedok5fwgsyr
Tags: 3.0.3-5
* Detect if locales or locales-all is installed for use with test suite.
* Bump Standards-Version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
 */
40
40
 
41
41
struct read_memory_data {
42
 
        unsigned char   *buffer;
 
42
        unsigned char   *start;
 
43
        unsigned char   *p;
43
44
        unsigned char   *end;
44
45
        size_t   read_size;
45
46
        size_t copy_buff_size;
49
50
 
50
51
static int      memory_read_close(struct archive *, void *);
51
52
static int      memory_read_open(struct archive *, void *);
52
 
static off_t    memory_read_skip(struct archive *, void *, off_t request);
 
53
static int64_t  memory_read_seek(struct archive *, void *, int64_t request, int whence);
 
54
static int64_t  memory_read_skip(struct archive *, void *, int64_t request);
53
55
static ssize_t  memory_read(struct archive *, void *, const void **buff);
54
56
static int      read_open_memory_internal(struct archive *a, void *buff,
55
57
    size_t size, size_t read_size, int fullapi);
58
60
int
59
61
read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size)
60
62
{
61
 
        return read_open_memory_internal(a, buff, size, read_size, 1);
 
63
        return read_open_memory_internal(a, buff, size, read_size, 2);
62
64
}
63
65
 
64
66
/*
68
70
int
69
71
read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_size)
70
72
{
71
 
        return read_open_memory_internal(a, buff, size, read_size, 0);
 
73
        return read_open_memory_internal(a, buff, size, read_size, 1);
 
74
}
 
75
 
 
76
/*
 
77
 * Include a seek callback as well.
 
78
 */
 
79
int
 
80
read_open_memory_seek(struct archive *a, void *buff, size_t size, size_t read_size)
 
81
{
 
82
        return read_open_memory_internal(a, buff, size, read_size, 3);
72
83
}
73
84
 
74
85
static int
75
86
read_open_memory_internal(struct archive *a, void *buff,
76
 
    size_t size, size_t read_size, int fullapi)
 
87
    size_t size, size_t read_size, int level)
77
88
{
78
89
        struct read_memory_data *mine;
79
90
 
83
94
                return (ARCHIVE_FATAL);
84
95
        }
85
96
        memset(mine, 0, sizeof(*mine));
86
 
        mine->buffer = (unsigned char *)buff;
87
 
        mine->end = mine->buffer + size;
 
97
        mine->start = mine->p = (unsigned char *)buff;
 
98
        mine->end = mine->start + size;
88
99
        mine->read_size = read_size;
89
100
        mine->copy_buff_offset = 32;
90
101
        mine->copy_buff_size = read_size + mine->copy_buff_offset * 2;
91
102
        mine->copy_buff = malloc(mine->copy_buff_size);
92
103
        memset(mine->copy_buff, 0xA5, mine->copy_buff_size);
93
 
        if (fullapi)
94
 
                return (archive_read_open2(a, mine, memory_read_open,
95
 
                            memory_read, memory_read_skip, memory_read_close));
96
 
        else
97
 
                return (archive_read_open2(a, mine, NULL,
98
 
                            memory_read, NULL, memory_read_close));
 
104
 
 
105
        switch (level) {
 
106
        case 3:
 
107
                archive_read_set_seek_callback(a, memory_read_seek);
 
108
        case 2:
 
109
                archive_read_set_open_callback(a, memory_read_open);
 
110
                archive_read_set_skip_callback(a, memory_read_skip);
 
111
        case 1:
 
112
                archive_read_set_read_callback(a, memory_read);
 
113
                archive_read_set_close_callback(a, memory_read_close);
 
114
                archive_read_set_callback_data(a, mine);
 
115
        }
 
116
        return archive_read_open1(a);
99
117
}
100
118
 
101
119
/*
119
137
memory_read(struct archive *a, void *client_data, const void **buff)
120
138
{
121
139
        struct read_memory_data *mine = (struct read_memory_data *)client_data;
122
 
        size_t size;
 
140
        ssize_t size;
123
141
 
124
142
        (void)a; /* UNUSED */
125
 
        size = mine->end - mine->buffer;
126
 
        if (size > mine->read_size)
 
143
        size = mine->end - mine->p;
 
144
        if (size < 0) {
 
145
                buff = NULL;
 
146
                return 0;
 
147
        }
 
148
        if ((size_t)size > mine->read_size)
127
149
                size = mine->read_size;
128
150
        else
129
151
                memset(mine->copy_buff, 0xA5, mine->copy_buff_size);
130
 
        memcpy(mine->copy_buff + mine->copy_buff_offset, mine->buffer, size);
 
152
        memcpy(mine->copy_buff + mine->copy_buff_offset, mine->p, size);
131
153
        *buff = mine->copy_buff + mine->copy_buff_offset;
132
154
 
133
 
        mine->buffer += size;
 
155
        mine->p += size;
134
156
        return ((ssize_t)size);
135
157
}
136
158
 
137
159
/*
138
160
 * How mean can a skip() routine be?  Let's try to find out.
139
161
 */
140
 
static off_t
141
 
memory_read_skip(struct archive *a, void *client_data, off_t skip)
 
162
static int64_t
 
163
memory_read_skip(struct archive *a, void *client_data, int64_t skip)
142
164
{
143
165
        struct read_memory_data *mine = (struct read_memory_data *)client_data;
144
166
 
145
167
        (void)a; /* UNUSED */
146
168
        /* We can't skip by more than is available. */
147
 
        if ((off_t)skip > (off_t)(mine->end - mine->buffer))
148
 
                skip = mine->end - mine->buffer;
 
169
        if ((off_t)skip > (off_t)(mine->end - mine->p))
 
170
                skip = mine->end - mine->p;
149
171
        /* Always do small skips by prime amounts. */
150
172
        if (skip > 71)
151
173
                skip = 71;
152
 
        mine->buffer += skip;
 
174
        mine->p += skip;
153
175
        return (skip);
154
176
}
155
177
 
156
178
/*
 
179
 */
 
180
static int64_t
 
181
memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
 
182
{
 
183
        struct read_memory_data *mine = (struct read_memory_data *)client_data;
 
184
 
 
185
        (void)a; /* UNUSED */
 
186
        switch (whence) {
 
187
        case SEEK_SET:
 
188
                mine->p = mine->start + offset;
 
189
                break;
 
190
        case SEEK_END:
 
191
                mine->p = mine->end + offset;
 
192
                break;
 
193
        case SEEK_CUR:
 
194
                mine->p += offset;
 
195
                break;
 
196
        }
 
197
        if (mine->p < mine->start) {
 
198
                mine->p = mine->start;
 
199
                return ARCHIVE_FAILED;
 
200
        }
 
201
        if (mine->p > mine->end) {
 
202
                mine->p = mine->end;
 
203
                return ARCHIVE_FAILED;
 
204
        }
 
205
        return (mine->p - mine->start);
 
206
}
 
207
 
 
208
/*
157
209
 * Close is just cleaning up our one small bit of data.
158
210
 */
159
211
static int