mirror of
https://github.com/AltraMayor/f3.git
synced 2025-08-04 02:55:57 -04:00

If an F3 file (i.e. *.fff) but the last one is missing, f3read will report the missing file with a warning similar to this one: Missing file 0001.fff AND the following warning will be presented at the end of the report: WARNING: Not all F3 files are available Kenneth Arnold suggested this feature in an e-mail: "I also noticed that if one of the files is completely missing, f3read will still report no errors. The chance that this will happen on its own without messing something else up is too small to worry about, except possibly in the case that the device was actually read-only and no files actually got created. In that case, f3read succeeds with 0 sectors OK and 0 sectors lost." The last F3 file, if missing, is not reported because it can be confusing. The following example gives an idea of the problem: a memory card wasn't empty when f3write was called and the last F3 file created was 0010.fff with exactly 1GB; here none F3 file is missing. Then, some non-F3 files were removed, and f3read is called. f3read would report a missing file even when non-F3 files were removed! The problem gets a little bit uglier if 0010.fff in the example is less that 1GB, or the file system doesn't let f3write to fill it up for a few bytes (this should be very rare, but there's no guarantee that it cannot happen). Finally, the implementation of this feature has a positive side effect: f3read processes F3 files in ascending order, that is, 0001.fff, 0002.fff, ..., NNNN.fff. Before the order was file system dependent. Magic numbers related to the number of digits in the F3 files' names were eliminated.
106 lines
2.3 KiB
C
106 lines
2.3 KiB
C
#include "utils.h"
|
|
|
|
const char *adjust_unit(double *ptr_bytes)
|
|
{
|
|
const char *units[] = { "Byte", "KB", "MB", "GB", "TB", "PB", "EB" };
|
|
int i = 0;
|
|
double final = *ptr_bytes;
|
|
|
|
while (i < 7 && final >= 1024) {
|
|
final /= 1024;
|
|
i++;
|
|
}
|
|
*ptr_bytes = final;
|
|
return units[i];
|
|
}
|
|
|
|
void full_fn_from_number(char *full_fn, const char **filename,
|
|
const char *path, int num)
|
|
{
|
|
static char format[32] = "";
|
|
if (!format[0]) {
|
|
assert(FILENAME_NUM_DIGITS > 0);
|
|
assert(FILENAME_NUM_DIGITS < 10);
|
|
sprintf(format, "%%s/%%%02ii.fff", FILENAME_NUM_DIGITS);
|
|
}
|
|
assert(snprintf(full_fn, PATH_MAX, format, path, num + 1) < PATH_MAX);
|
|
*filename = full_fn + strlen(path) + 1;
|
|
}
|
|
|
|
#ifdef APPLE_MAC
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
|
|
int srand48_r(long int seedval, struct drand48_data *buffer)
|
|
{
|
|
/* The standards say we only have 32 bits. */
|
|
if (sizeof(long int) > 4)
|
|
seedval &= 0xffffffffl;
|
|
|
|
buffer->__x[2] = seedval >> 16;
|
|
buffer->__x[1] = seedval & 0xffffl;
|
|
buffer->__x[0] = 0x330e;
|
|
|
|
buffer->__a = 0x5deece66dull;
|
|
buffer->__c = 0xb;
|
|
buffer->__init = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __drand48_iterate(unsigned short int xsubi[3],
|
|
struct drand48_data *buffer)
|
|
{
|
|
uint64_t X;
|
|
uint64_t result;
|
|
|
|
/* Initialize buffer, if not yet done. */
|
|
if (__builtin_expect(!buffer->__init, 0)) {
|
|
buffer->__a = 0x5deece66dull;
|
|
buffer->__c = 0xb;
|
|
buffer->__init = 1;
|
|
}
|
|
|
|
/* Do the real work. We choose a data type which contains at least
|
|
48 bits. Because we compute the modulus it does not care how
|
|
many bits really are computed. */
|
|
|
|
X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0];
|
|
|
|
result = X * buffer->__a + buffer->__c;
|
|
|
|
xsubi[0] = result & 0xffff;
|
|
xsubi[1] = (result >> 16) & 0xffff;
|
|
xsubi[2] = (result >> 32) & 0xffff;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __nrand48_r(unsigned short int xsubi[3],
|
|
struct drand48_data *buffer, long int *result)
|
|
{
|
|
/* Compute next state. */
|
|
if (__drand48_iterate(xsubi, buffer) < 0)
|
|
return -1;
|
|
|
|
/* Store the result. */
|
|
if (sizeof(unsigned short int) == 2)
|
|
*result = xsubi[2] << 15 | xsubi[1] >> 1;
|
|
else
|
|
*result = xsubi[2] >> 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int lrand48_r(struct drand48_data *buffer, long int *result)
|
|
{
|
|
/* Be generous for the arguments, detect some errors. */
|
|
if (buffer == NULL)
|
|
return -1;
|
|
|
|
return __nrand48_r(buffer->__x, buffer, result);
|
|
}
|
|
|
|
#endif /* APPLE_MAC */
|