xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/io.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2 
3 /*
4  * Copyright © 2014 Rob Clark <[email protected]>
5  * SPDX-License-Identifier: MIT
6  *
7  * Authors:
8  *    Rob Clark <[email protected]>
9  */
10 
11 #include <archive.h>
12 #include <fcntl.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <archive_entry.h>
18 
19 #include "io.h"
20 
21 struct io {
22    struct archive *a;
23    struct archive_entry *entry;
24    unsigned offset;
25 };
26 
27 static void
io_error(struct io * io)28 io_error(struct io *io)
29 {
30    fprintf(stderr, "%s\n", archive_error_string(io->a));
31    io_close(io);
32 }
33 
34 static struct io *
io_new(void)35 io_new(void)
36 {
37    struct io *io = calloc(1, sizeof(*io));
38    int ret;
39 
40    if (!io)
41       return NULL;
42 
43    io->a = archive_read_new();
44    ret = archive_read_support_filter_gzip(io->a);
45    if (ret != ARCHIVE_OK) {
46       io_error(io);
47       return NULL;
48    }
49 
50    ret = archive_read_support_filter_none(io->a);
51    if (ret != ARCHIVE_OK) {
52       io_error(io);
53       return NULL;
54    }
55 
56    ret = archive_read_support_format_all(io->a);
57    if (ret != ARCHIVE_OK) {
58       io_error(io);
59       return NULL;
60    }
61 
62    ret = archive_read_support_format_raw(io->a);
63    if (ret != ARCHIVE_OK) {
64       io_error(io);
65       return NULL;
66    }
67 
68    return io;
69 }
70 
71 struct io *
io_open(const char * filename)72 io_open(const char *filename)
73 {
74    struct io *io = io_new();
75    int ret;
76 
77    if (!io)
78       return NULL;
79 
80    ret = archive_read_open_filename(io->a, filename, 10240);
81    if (ret != ARCHIVE_OK) {
82       io_error(io);
83       return NULL;
84    }
85 
86    ret = archive_read_next_header(io->a, &io->entry);
87    if (ret != ARCHIVE_OK) {
88       io_error(io);
89       return NULL;
90    }
91 
92    return io;
93 }
94 
95 struct io *
io_openfd(int fd)96 io_openfd(int fd)
97 {
98    struct io *io = io_new();
99    int ret;
100 
101    if (!io)
102       return NULL;
103 
104    ret = archive_read_open_fd(io->a, fd, 10240);
105    if (ret != ARCHIVE_OK) {
106       io_error(io);
107       return NULL;
108    }
109 
110    ret = archive_read_next_header(io->a, &io->entry);
111    if (ret != ARCHIVE_OK) {
112       io_error(io);
113       return NULL;
114    }
115 
116    return io;
117 }
118 
119 void
io_close(struct io * io)120 io_close(struct io *io)
121 {
122    archive_read_free(io->a);
123    free(io);
124 }
125 
126 unsigned
io_offset(struct io * io)127 io_offset(struct io *io)
128 {
129    return io->offset;
130 }
131 
132 #include <assert.h>
133 int
io_readn(struct io * io,void * buf,int nbytes)134 io_readn(struct io *io, void *buf, int nbytes)
135 {
136    char *ptr = buf;
137    int ret = 0;
138    while (nbytes > 0) {
139       int n = archive_read_data(io->a, ptr, nbytes);
140       if (n < 0) {
141          fprintf(stderr, "%s\n", archive_error_string(io->a));
142          return n;
143       }
144       if (n == 0)
145          break;
146       ptr += n;
147       nbytes -= n;
148       ret += n;
149       io->offset += n;
150    }
151    return ret;
152 }
153