• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*############################################################################
2   # Copyright 2016-2017 Intel Corporation
3   #
4   # Licensed under the Apache License, Version 2.0 (the "License");
5   # you may not use this file except in compliance with the License.
6   # You may obtain a copy of the License at
7   #
8   #     http://www.apache.org/licenses/LICENSE-2.0
9   #
10   # Unless required by applicable law or agreed to in writing, software
11   # distributed under the License is distributed on an "AS IS" BASIS,
12   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   # See the License for the specific language governing permissions and
14   # limitations under the License.
15   ############################################################################*/
16 
17 /*!
18  * \file
19  * \brief Buffer handling utilities implementation.
20  */
21 
22 #include <util/buffutil.h>
23 
24 #include <ctype.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "util/envutil.h"
28 
29 /// file static variable that indicates verbose logging
30 static bool g_bufutil_verbose = false;
31 
ToggleVerbosity()32 bool ToggleVerbosity() {
33   g_bufutil_verbose = (g_bufutil_verbose) ? false : true;
34   return g_bufutil_verbose;
35 }
36 
FileExists(char const * filename)37 bool FileExists(char const* filename) {
38   FILE* fp = NULL;
39   if (!filename || !filename[0]) {
40     return false;
41   }
42   fp = fopen(filename, "rb");
43   if (fp) {
44     fclose(fp);
45     return true;
46   }
47   return false;
48 }
49 
GetFileSize(char const * filename)50 size_t GetFileSize(char const* filename) {
51   size_t file_length = 0;
52   FILE* fp = fopen(filename, "rb");
53   if (fp) {
54     fseek(fp, 0, SEEK_END);
55     file_length = ftell(fp);
56     fclose(fp);
57   }
58   return file_length;
59 }
60 
GetFileSize_S(char const * filename,size_t max_size)61 size_t GetFileSize_S(char const* filename, size_t max_size) {
62   size_t size = GetFileSize(filename);
63   if (size > max_size) {
64     return 0;
65   } else {
66     return size;
67   }
68 }
69 
AllocBuffer(size_t size)70 void* AllocBuffer(size_t size) {
71   void* buffer = NULL;
72   if (size) {
73     buffer = malloc(size);
74   }
75   if (!buffer) {
76     log_error("failed to allocate memory");
77   }
78   return buffer;
79 }
80 
NewBufferFromFile(const char * filename,size_t * size)81 void* NewBufferFromFile(const char* filename, size_t* size) {
82   void* buffer = NULL;
83 
84   do {
85     size_t len = 0;
86 
87     if (!FileExists(filename)) {
88       log_error("cannot access '%s'", filename);
89       break;
90     }
91 
92     len = GetFileSize_S(filename, SIZE_MAX);
93     if (len == 0) {
94       log_error("cannot load empty file '%s'", filename);
95       break;
96     }
97 
98     buffer = AllocBuffer(len);
99 
100     if (buffer) {
101       if (0 != ReadLoud(filename, buffer, len)) {
102         free(buffer);
103         buffer = NULL;
104         break;
105       }
106     }
107 
108     if (size) {
109       *size = len;
110     }
111   } while (0);
112   return buffer;
113 }
114 
ReadBufferFromFile(const char * filename,void * buffer,size_t size)115 int ReadBufferFromFile(const char* filename, void* buffer, size_t size) {
116   int result = 0;
117   FILE* file = NULL;
118   do {
119     size_t bytes_read = 0;
120     size_t file_size = 0;
121     file = fopen(filename, "rb");
122     if (!file) {
123       result = -1;
124       break;
125     }
126     fseek(file, 0, SEEK_END);
127     file_size = ftell(file);
128     fseek(file, 0, SEEK_SET);
129     if ((size_t)file_size != size) {
130       result = -1;
131       break;
132     }
133 
134     if (buffer && (0 != size)) {
135       bytes_read = fread(buffer, 1, size, file);
136       if (bytes_read != size) {
137         result = -1;
138         break;
139       }
140     }
141   } while (0);
142 
143   if (file) {
144     fclose(file);
145   }
146 
147   return result;
148 }
149 
WriteBufferToFile(const void * buffer,size_t size,const char * filename)150 int WriteBufferToFile(const void* buffer, size_t size, const char* filename) {
151   int result = 0;
152   FILE* file = NULL;
153   do {
154     size_t bytes_written = 0;
155 
156     file = fopen(filename, "wb");
157     if (!file) {
158       result = -1;
159       break;
160     }
161     bytes_written = fwrite(buffer, 1, size, file);
162     if (bytes_written != size) {
163       result = -1;
164       break;
165     }
166   } while (0);
167 
168   if (file) {
169     fclose(file);
170   }
171 
172   return result;
173 }
174 
ReadLoud(char const * filename,void * buf,size_t size)175 int ReadLoud(char const* filename, void* buf, size_t size) {
176   int result;
177 
178   if (!buf || 0 == size) {
179     log_error("internal error: invalid buffer to ReadLoud");
180     return -1;
181   }
182 
183   if (g_bufutil_verbose) {
184     log_msg("reading %s", filename);
185   }
186 
187   if (!FileExists(filename)) {
188     log_error("cannot access '%s' for reading", filename);
189     return -1;
190   }
191 
192   if (size != GetFileSize(filename)) {
193     log_error("unexpected file size for '%s'. Expected: %d; got: %d", filename,
194               (int)size, (int)GetFileSize(filename));
195     return -1;
196   }
197 
198   result = ReadBufferFromFile(filename, buf, size);
199   if (0 != result) {
200     log_error("failed to read from `%s`", filename);
201     return result;
202   }
203 
204   if (g_bufutil_verbose) {
205     PrintBuffer(buf, size);
206   }
207 
208   return result;
209 }
210 
WriteLoud(void * buf,size_t size,char const * filename)211 int WriteLoud(void* buf, size_t size, char const* filename) {
212   int result = -1;
213 
214   if (!buf || 0 == size) {
215     log_error("internal error: invalid buffer to WriteLoud");
216     return -1;
217   }
218 
219   if (g_bufutil_verbose) {
220     log_msg("writing %s", filename);
221   }
222 
223   result = WriteBufferToFile(buf, size, filename);
224 
225   if (0 != result) {
226     log_error("failed to write to `%s`", filename);
227     return result;
228   }
229 
230   if (g_bufutil_verbose) {
231     PrintBuffer(buf, size);
232   }
233 
234   return result;
235 }
236 
PrintBuffer(const void * buffer,size_t size)237 void PrintBuffer(const void* buffer, size_t size) {
238   BufferPrintOptions opts;
239   opts.show_header = true;
240   opts.show_offset = true;
241   opts.show_hex = true;
242   opts.show_ascii = true;
243   opts.bytes_per_group = 2;
244   opts.groups_per_line = 8;
245   PrintBufferOpt(buffer, size, opts);
246 }
247 
PrintBufferOpt(const void * buffer,size_t size,BufferPrintOptions opts)248 void PrintBufferOpt(const void* buffer, size_t size, BufferPrintOptions opts) {
249   unsigned char* bytes = (unsigned char*)buffer;
250   size_t bytes_per_line = opts.bytes_per_group * opts.groups_per_line;
251   size_t line_offset = 0;
252   size_t byte_offset = 0;
253   size_t byte_col = 0;
254   if (opts.show_header) {
255     if (opts.show_offset) {
256       log_fmt("  offset");
257       log_fmt(": ");
258     }
259 
260     if (opts.show_hex) {
261       byte_col = 0;
262       while (byte_col < bytes_per_line) {
263         log_fmt("%x%x", (int)byte_col, (int)byte_col);
264         if (0 == (byte_col + 1) % opts.bytes_per_group) {
265           log_fmt(" ");
266         }
267         byte_col += 1;
268       }
269     }
270 
271     if (opts.show_hex && opts.show_ascii) {
272       log_fmt("| ");
273     }
274 
275     if (opts.show_ascii) {
276       byte_col = 0;
277       while (byte_col < bytes_per_line) {
278         log_fmt("%x", (int)byte_col);
279         byte_col += 1;
280       }
281     }
282 
283     log_fmt("\n");
284 
285     if (opts.show_offset) {
286       log_fmt("--------");
287       log_fmt(": ");
288     }
289 
290     if (opts.show_hex) {
291       byte_col = 0;
292       while (byte_col < bytes_per_line) {
293         log_fmt("--");
294         if (0 == (byte_col + 1) % opts.bytes_per_group) {
295           log_fmt("-");
296         }
297         byte_col += 1;
298       }
299     }
300 
301     if (opts.show_hex && opts.show_ascii) {
302       log_fmt("|-");
303     }
304 
305     if (opts.show_ascii) {
306       byte_col = 0;
307       while (byte_col < bytes_per_line) {
308         log_fmt("-");
309         byte_col += 1;
310       }
311     }
312     log_fmt("\n");
313   }
314 
315   line_offset = 0;
316 
317   while (line_offset < size) {
318     if (opts.show_offset) {
319       log_fmt("%08x", (int)line_offset);
320       log_fmt(": ");
321     }
322 
323     if (opts.show_hex) {
324       byte_col = 0;
325       while (byte_col < bytes_per_line) {
326         byte_offset = line_offset + byte_col;
327         if (byte_offset < size) {
328           log_fmt("%02x", (int)bytes[byte_offset]);
329         } else {
330           log_fmt("  ");
331         }
332         if (0 == (byte_col + 1) % opts.bytes_per_group) {
333           log_fmt(" ");
334         }
335         byte_col += 1;
336       }
337     }
338 
339     if (opts.show_hex && opts.show_ascii) {
340       log_fmt("| ");
341     }
342 
343     if (opts.show_ascii) {
344       byte_col = 0;
345       while (byte_col < bytes_per_line) {
346         byte_offset = line_offset + byte_col;
347         if (byte_offset < size) {
348           unsigned char ch = bytes[byte_offset];
349           if (isprint(ch)) {
350             log_fmt("%c", ch);
351           } else {
352             log_fmt(".");
353           }
354         } else {
355           log_fmt("  ");
356         }
357         byte_col += 1;
358       }
359     }
360 
361     log_fmt("\n");
362     line_offset += bytes_per_line;
363   }
364 }
365