1 /* Copyright 2015 the unarr project authors (see AUTHORS file).
2 License: LGPLv3 */
3
4 #include "unarr-imp.h"
5
ar_open_archive(ar_stream * stream,size_t struct_size,ar_archive_close_fn close,ar_parse_entry_fn parse_entry,ar_entry_get_name_fn get_name,ar_entry_uncompress_fn uncompress,ar_get_global_comment_fn get_comment,off64_t first_entry_offset)6 ar_archive *ar_open_archive(ar_stream *stream, size_t struct_size, ar_archive_close_fn close, ar_parse_entry_fn parse_entry,
7 ar_entry_get_name_fn get_name, ar_entry_uncompress_fn uncompress, ar_get_global_comment_fn get_comment,
8 off64_t first_entry_offset)
9 {
10 ar_archive *ar = malloc(struct_size);
11 if (!ar)
12 return NULL;
13 memset(ar, 0, struct_size);
14 ar->close = close;
15 ar->parse_entry = parse_entry;
16 ar->get_name = get_name;
17 ar->uncompress = uncompress;
18 ar->get_comment = get_comment;
19 ar->stream = stream;
20 ar->entry_offset_first = first_entry_offset;
21 ar->entry_offset_next = first_entry_offset;
22 return ar;
23 }
24
ar_close_archive(ar_archive * ar)25 void ar_close_archive(ar_archive *ar)
26 {
27 if (ar)
28 ar->close(ar);
29 free(ar);
30 }
31
ar_at_eof(ar_archive * ar)32 bool ar_at_eof(ar_archive *ar)
33 {
34 return ar->at_eof;
35 }
36
ar_parse_entry(ar_archive * ar)37 bool ar_parse_entry(ar_archive *ar)
38 {
39 return ar->parse_entry(ar, ar->entry_offset_next);
40 }
41
ar_parse_entry_at(ar_archive * ar,off64_t offset)42 bool ar_parse_entry_at(ar_archive *ar, off64_t offset)
43 {
44 ar->at_eof = false;
45 return ar->parse_entry(ar, offset ? offset : ar->entry_offset_first);
46 }
47
ar_parse_entry_for(ar_archive * ar,const char * entry_name)48 bool ar_parse_entry_for(ar_archive *ar, const char *entry_name)
49 {
50 ar->at_eof = false;
51 if (!entry_name)
52 return false;
53 if (!ar_parse_entry_at(ar, ar->entry_offset_first))
54 return false;
55 do {
56 const char *name = ar_entry_get_name(ar);
57 if (name && strcmp(name, entry_name) == 0)
58 return true;
59 } while (ar_parse_entry(ar));
60 return false;
61 }
62
ar_entry_get_name(ar_archive * ar)63 const char *ar_entry_get_name(ar_archive *ar)
64 {
65 return ar->get_name(ar);
66 }
67
ar_entry_get_offset(ar_archive * ar)68 off64_t ar_entry_get_offset(ar_archive *ar)
69 {
70 return ar->entry_offset;
71 }
72
ar_entry_get_size(ar_archive * ar)73 size_t ar_entry_get_size(ar_archive *ar)
74 {
75 return ar->entry_size_uncompressed;
76 }
77
ar_entry_get_filetime(ar_archive * ar)78 time64_t ar_entry_get_filetime(ar_archive *ar)
79 {
80 return ar->entry_filetime;
81 }
82
ar_entry_uncompress(ar_archive * ar,void * buffer,size_t count)83 bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count)
84 {
85 return ar->uncompress(ar, buffer, count);
86 }
87
ar_get_global_comment(ar_archive * ar,void * buffer,size_t count)88 size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count)
89 {
90 if (!ar->get_comment)
91 return 0;
92 return ar->get_comment(ar, buffer, count);
93 }
94
ar_log(const char * prefix,const char * file,int line,const char * msg,...)95 void ar_log(const char *prefix, const char *file, int line, const char *msg, ...)
96 {
97 va_list args;
98 va_start(args, msg);
99 if (prefix)
100 fprintf(stderr, "%s ", prefix);
101 if (strrchr(file, '/'))
102 file = strrchr(file, '/') + 1;
103 if (strrchr(file, '\\'))
104 file = strrchr(file, '\\') + 1;
105 fprintf(stderr, "%s:%d: ", file, line);
106 vfprintf(stderr, msg, args);
107 fprintf(stderr, "\n");
108 va_end(args);
109 }
110