/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <nanohub/nanoapp.h>
void *reallocOrDie(void *buf, size_t bufSz)
{
void *newBuf = realloc(buf, bufSz);
if (!newBuf) {
fprintf(stderr, "Failed to allocate %zu bytes\n", bufSz);
exit(2);
}
return newBuf;
}
void assertMem(size_t used, size_t total)
{
if (used <= total)
return;
fprintf(stderr, "Buffer size %zu is not big enough to complete operation; we need %zu bytes\n", total, used);
exit(2);
}
// read file of known size, make sure the size is correct
bool readFile(void *dst, uint32_t len, const char *fileName)
{
FILE *f = fopen(fileName, "rb");
bool ret = false;
if (!f)
return false;
if (len != fread(dst, 1, len, f))
goto out;
if (fread(&len, 1, 1, f)) //make sure file is actually over
goto out;
ret = true;
out:
fclose(f);
return ret;
}
// read complete file of unknown size, return malloced buffer and size
void *loadFile(const char *fileName, uint32_t *size)
{
FILE *f = fopen(fileName, "rb");
uint8_t *dst = NULL;
uint32_t len = 0, grow = 16384, total = 0;
uint32_t block;
if (!f) {
fprintf(stderr, "couldn't open %s: %s\n", fileName, strerror(errno));
exit(2);
}
do {
len += grow; dst = reallocOrDie(dst, len);
block = fread(dst + total, 1, grow, f);
total += block;
} while (block == grow);
*size = total;
if (!feof(f)) {
fprintf(stderr, "Failed to read entire file %s: %s\n",
fileName, strerror(errno));
free(dst);
fclose(f);
dst = NULL;
exit(2);
}
fclose(f);
return dst;
}
static void doPrintHash(FILE *out, const char *pfx, const uint32_t *hash, size_t size, int increment)
{
size_t i;
int pos;
fprintf(out, "%s: ", pfx);
for (i = 0, pos = 0; i < size; ++i, pos += increment)
fprintf(out, "%08" PRIx32, hash[pos]);
fprintf(out, "\n");
}
void printHash(FILE *out, const char *pfx, const uint32_t *hash, size_t size)
{
doPrintHash(out, pfx, hash, size, 1);
}
void printHashRev(FILE *out, const char *pfx, const uint32_t *hash, size_t size)
{
doPrintHash(out, pfx, hash + size - 1, size, -1);
}