1 /*
2  * Copyright (C) 2016 The Android Open Source Project
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 #include <stdio.h>
18 #include <inttypes.h>
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 
25 #include <nanohub/nanoapp.h>
26 
reallocOrDie(void * buf,size_t bufSz)27 void *reallocOrDie(void *buf, size_t bufSz)
28 {
29     void *newBuf = realloc(buf, bufSz);
30     if (!newBuf) {
31         fprintf(stderr, "Failed to allocate %zu bytes\n", bufSz);
32         exit(2);
33     }
34     return newBuf;
35 }
36 
assertMem(size_t used,size_t total)37 void assertMem(size_t used, size_t total)
38 {
39     if (used <= total)
40         return;
41     fprintf(stderr, "Buffer size %zu is not big enough to complete operation; we need %zu bytes\n", total, used);
42     exit(2);
43 }
44 
45 // read file of known size, make sure the size is correct
readFile(void * dst,uint32_t len,const char * fileName)46 bool readFile(void *dst, uint32_t len, const char *fileName)
47 {
48     FILE *f = fopen(fileName, "rb");
49     bool ret = false;
50 
51     if (!f)
52         return false;
53 
54     if (len != fread(dst, 1, len, f))
55         goto out;
56 
57     if (fread(&len, 1, 1, f)) //make sure file is actually over
58         goto out;
59 
60     ret = true;
61 
62 out:
63     fclose(f);
64     return ret;
65 }
66 
67 // read complete file of unknown size, return malloced buffer and size
loadFile(const char * fileName,uint32_t * size)68 void *loadFile(const char *fileName, uint32_t *size)
69 {
70     FILE *f = fopen(fileName, "rb");
71     uint8_t *dst = NULL;
72     uint32_t len = 0, grow = 16384, total = 0;
73     uint32_t block;
74 
75     if (!f) {
76         fprintf(stderr, "couldn't open %s: %s\n", fileName, strerror(errno));
77         exit(2);
78     }
79 
80     do {
81         len += grow; dst = reallocOrDie(dst, len);
82 
83         block = fread(dst + total, 1, grow, f);
84         total += block;
85     } while (block == grow);
86 
87     *size = total;
88     if (!feof(f)) {
89         fprintf(stderr, "Failed to read entire file %s: %s\n",
90                 fileName, strerror(errno));
91         free(dst);
92         fclose(f);
93         dst = NULL;
94         exit(2);
95     }
96 
97     return dst;
98 }
99 
doPrintHash(FILE * out,const char * pfx,const uint32_t * hash,size_t size,int increment)100 static void doPrintHash(FILE *out, const char *pfx, const uint32_t *hash, size_t size, int increment)
101 {
102     size_t i;
103     int pos;
104     fprintf(out, "%s: ", pfx);
105     for (i = 0, pos = 0; i < size; ++i, pos += increment)
106         fprintf(out, "%08" PRIx32, hash[pos]);
107     fprintf(out, "\n");
108 }
109 
printHash(FILE * out,const char * pfx,const uint32_t * hash,size_t size)110 void printHash(FILE *out, const char *pfx, const uint32_t *hash, size_t size)
111 {
112     doPrintHash(out, pfx, hash, size, 1);
113 }
114 
printHashRev(FILE * out,const char * pfx,const uint32_t * hash,size_t size)115 void printHashRev(FILE *out, const char *pfx, const uint32_t *hash, size_t size)
116 {
117     doPrintHash(out, pfx, hash + size - 1, size, -1);
118 }
119