1 /*
2  # This file is part of the Astrometry.net suite.
3  # Licensed under a 3-clause BSD style license - see LICENSE
4  */
5 
6 #ifndef IOUTILS_H
7 #define IOUTILS_H
8 
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <sys/types.h>
12 #include <time.h>
13 
14 #include "astrometry/an-bool.h"
15 #include "astrometry/bl.h"
16 #include "astrometry/keywords.h"
17 
18 extern uint32_t ENDIAN_DETECTOR;
19 
20 void QSORT_R(void* base, size_t nmembers, size_t member_size,
21              void* token, int (*compar)(void *, const void *, const void *));
22 
23 /**
24    You should define the "comparison" function like this:
25 
26    static int QSORT_COMPARISON_FUNCTION(my_comparison, void* token, const void* v1, const void* v2) {
27  */
28 #define QSORT_COMPARISON_FUNCTION(func, thunk, v1, v2) func(thunk, v1, v2)
29 
30 int copy_file(const char* infn, const char* outfn);
31 
32 int pad_fid(FILE* fid, size_t len, char pad);
33 int pad_file(char* filename, size_t len, char pad);
34 
35 /*
36  The "basename" function may overwrite its arg and may return a pointer
37  to static memory... both undesirable.  This replacement returns a newly-
38  allocated string containing the result.
39  */
40 Malloc
41 char* basename_safe(const char* path);
42 
43 Malloc
44 char* dirname_safe(const char* path);
45 
46 // Returns (system + user) CPU time, in seconds.
47 float get_cpu_usage(void);
48 
49 //int log_resource_usage(int loglevel);
50 
51 /*
52  Searches for the given "filename" in the given set of directories.
53  Returns a newly allocated string "dir/filename", or NULL if none of
54  the paths exists and is readable.
55  */
56 char* find_file_in_dirs(const char** dirs, int ndirs, const char* filename, anbool allow_absolute);
57 
58 // Are strings s1 and s2 equal?
59 anbool streq(const char* s1, const char* s2);
60 anbool strcaseeq(const char* s1, const char* s2);
61 
62 /*
63  Copy data from "fin" to "fout", starting at offset "offset"
64  (from the beginning of "fin"), and length "length".
65  Returns 0 on success.
66  */
67 int pipe_file_offset(FILE* fin, off_t offset, off_t length, FILE* fout);
68 
69 int write_file(const char* fn, const char* data, int len);
70 
71 /*
72  It's not really _safe_ as such, it just prints an error message if it fails...
73  */
74 void
75 ATTRIB_FORMAT(printf,2,3)
76     asprintf_safe(char** strp, const char* format, ...);
77 
78 int run_command_get_outputs(const char* cmd, sl** outlines, sl** errlines);
79 
80 void get_mmap_size(size_t start, size_t size, off_t* mapstart, size_t* mapsize, int* pgap);
81 
82 // If "dir" is NULL, create temp file in $TMP, or /tmp if not set.
83 char* create_temp_file(const char* fn, const char* dir);
84 
85 // If "dir" is NULL, create temp file in $TMP, or /tmp if not set.
86 char* create_temp_dir(const char* name, const char* dir);
87 
88 char* shell_escape(const char* str);
89 
90 int mkdir_p(const char* path);
91 
92 // Returns 0 on error.
93 time_t file_get_last_modified_time(const char* fn);
94 
95 anbool file_exists(const char* fn);
96 
97 anbool file_readable(const char* fn);
98 
99 anbool file_executable(const char* fn);
100 
101 anbool path_is_dir(const char* path);
102 
103 void* file_get_contents(const char* fn, size_t* len, anbool addzero);
104 
105 char* file_get_contents_offset(const char* fn, int offset, int length);
106 
107 sl* fid_add_lines(FILE* fid, anbool include_newlines, sl* list);
108 
109 sl* file_get_lines(const char* fn, anbool include_newlines);
110 
111 sl* fid_get_lines(FILE* fid, anbool include_newlines);
112 
113 sl* dir_get_contents(const char* path, sl* result, anbool filesonly, anbool recursive);
114 
115 int file_get_last_modified_string(const char* fn, const char* timeformat,
116                                   anbool utc, char* output, size_t outsize);
117 
118 /**
119  Splits the given "str" into words, so that the first line is at most
120  "firstlinew" long.  Subsequent lines have length <= "linew".  If
121  "lst" is non-NULL, the words are added into it.  Otherwise a new sl
122  is allocated.
123  */
124 sl* split_long_string(const char* str, int firstlinew, int linew, sl* lst);
125 
126 // Split a string on the first instance of "splitstr".
127 // Places the addresses of (newly-allocated) copies of the first and seconds parts of the string.
128 // Returns 1 if the string is found.
129 int split_string_once(const char* str, const char* splitstr, char** first, char** second);
130 
131 /**
132  If "cmdline" starts with "keyword", returns 1 and places the address of
133  the start of the next word in "p_next_word".
134  */
135 int is_word(const char* cmdline, const char* keyword, char** p_next_word);
136 
137 int starts_with(const char* str, const char* prefix);
138 
139 int ends_with(const char* str, const char* prefix);
140 
141 char* strdup_safe(const char* str);
142 
143 void add_sigbus_mmap_warning(void);
144 void reset_sigbus_mmap_warning(void);
145 
146 int write_u8(FILE* fout, unsigned char val);
147 int write_u16(FILE* fout, unsigned int val);
148 int write_u32(FILE* fout, unsigned int val);
149 int write_uints(FILE* fout, unsigned int* val, int n);
150 int write_double(FILE* fout, double val);
151 int write_float(FILE* fout, float val);
152 int write_fixed_length_string(FILE* fout, char* s, int length);
153 int write_string(FILE* fout, char* s);
154 
155 int write_u32_portable(FILE* fout, unsigned int val);
156 int write_u32s_portable(FILE* fout, unsigned int* val, int n);
157 
158 int read_u8(FILE* fin, unsigned char* val);
159 int read_u16(FILE* fout, unsigned int* val);
160 int read_u32(FILE* fin, unsigned int* val);
161 int read_double(FILE* fin, double* val);
162 int read_fixed_length_string(FILE* fin, char* s, int length);
163 char* read_string(FILE* fin);
164 char* read_string_terminated(FILE* fin, const char* terminators, int nterminators,
165                              anbool include_terminator);
166 
167 int read_u32_portable(FILE* fin, unsigned int* val);
168 int read_u32s_portable(FILE* fin, unsigned int* val, int n);
169 
170 struct buffered_read_data {
171     void* buffer;
172     int blocksize;
173     int elementsize;
174     int ntotal;
175     int nbuff;
176     int off;
177     int buffind;
178     int (*refill_buffer)(void* userdata, void* buffer, unsigned int offs, unsigned int nelems);
179     void* userdata;
180 };
181 typedef struct buffered_read_data bread_t;
182 
183 bread_t* buffered_read_new(int elementsize, int Nbuffer, int Ntotal,
184                            int (*refill_buffer)(void* userdata, void* buffer, unsigned int offs, unsigned int nelems),
185                            void* userdata);
186 
187 void* buffered_read(bread_t* buff);
188 
189 void buffered_read_pushback(bread_t* br);
190 
191 void buffered_read_reset(bread_t* br);
192 
193 void buffered_read_free(bread_t* br);
194 
195 void buffered_read_resize(bread_t* br, int newsize);
196 
197 #endif
198