mirror of
https://github.com/depp/syncfiles.git
synced 2025-01-10 04:29:21 +00:00
Refactor allocation API
This way we don't need to expose MemError() to platform-independent code.
This commit is contained in:
parent
617bf831d8
commit
8e2efa707e
@ -9,16 +9,17 @@ const struct ConvertEngine kEngines[][2] = {
|
||||
{{Convert1fBuild, Convert1fRun}, {Convert1rBuild, Convert1rRun}}};
|
||||
|
||||
int ConverterBuild(struct Converter *c, Handle data, Size datasz,
|
||||
ConvertDirection direction, OSErr *errp)
|
||||
ConvertDirection direction)
|
||||
{
|
||||
int engine, r;
|
||||
int engine;
|
||||
const struct ConvertEngine *funcs;
|
||||
Handle out;
|
||||
ErrorCode err;
|
||||
|
||||
if (datasz == 0) {
|
||||
return kErrorBadData;
|
||||
}
|
||||
engine = (UInt8) * *data - 1;
|
||||
engine = (UInt8)(**data) - 1;
|
||||
if (engine < 0 || (int)(sizeof(kEngines) / sizeof(*kEngines)) <= engine) {
|
||||
/* Invalid engine. */
|
||||
return kErrorBadData;
|
||||
@ -28,9 +29,9 @@ int ConverterBuild(struct Converter *c, Handle data, Size datasz,
|
||||
/* Invalid engine. */
|
||||
return kErrorBadData;
|
||||
}
|
||||
r = funcs->build(&out, data, datasz, errp);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
err = funcs->build(&out, data, datasz);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
c->data = out;
|
||||
c->run = funcs->run;
|
||||
|
@ -4,19 +4,6 @@
|
||||
|
||||
#include "lib/defs.h"
|
||||
|
||||
/* Error codes. */
|
||||
enum
|
||||
{
|
||||
/* No error. */
|
||||
kErrorOK,
|
||||
|
||||
/* Memory allocation failed. */
|
||||
kErrorNoMemory,
|
||||
|
||||
/* Invaild table data. */
|
||||
kErrorBadData
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* Constants for CR and LF. Note that we should not use '\n' or '\r'
|
||||
@ -62,8 +49,7 @@ struct ConverterState {
|
||||
};
|
||||
|
||||
/* Implementation function for building a converter. */
|
||||
typedef int (*ConvertBuildf)(Handle *out, Handle data, Size datasz,
|
||||
OSErr *errp);
|
||||
typedef ErrorCode (*ConvertBuildf)(Handle *out, Handle data, Size datasz);
|
||||
|
||||
/* Implementation function for running a converter. */
|
||||
typedef void (*ConvertRunf)(const void *cvtptr, LineBreakConversion lc,
|
||||
@ -78,16 +64,16 @@ struct Converter {
|
||||
|
||||
/* Build a converter from the given conversion table data. */
|
||||
int ConverterBuild(struct Converter *c, Handle data, Size datasz,
|
||||
ConvertDirection direction, OSErr *errp);
|
||||
ConvertDirection direction);
|
||||
|
||||
/* Engine 1: extended ASCII */
|
||||
|
||||
int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp);
|
||||
ErrorCode Convert1fBuild(Handle *out, Handle data, Size datasz);
|
||||
void Convert1fRun(const void *cvtptr, LineBreakConversion lc,
|
||||
struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend,
|
||||
const UInt8 **iptr, const UInt8 *iend);
|
||||
|
||||
int Convert1rBuild(Handle *out, Handle data, Size datasz, OSErr *errp);
|
||||
ErrorCode Convert1rBuild(Handle *out, Handle data, Size datasz);
|
||||
void Convert1rRun(const void *cvtptr, LineBreakConversion lc,
|
||||
struct ConverterState *stateptr, UInt8 **optr, UInt8 *oend,
|
||||
const UInt8 **iptr, const UInt8 *iend);
|
||||
|
@ -12,7 +12,7 @@ struct Convert1fState {
|
||||
UInt8 lastch;
|
||||
};
|
||||
|
||||
int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp)
|
||||
ErrorCode Convert1fBuild(Handle *out, Handle data, Size datasz)
|
||||
{
|
||||
Handle h;
|
||||
struct Convert1fData *cvt;
|
||||
@ -22,7 +22,6 @@ int Convert1fBuild(Handle *out, Handle data, Size datasz, OSErr *errp)
|
||||
|
||||
h = NewHandle(sizeof(struct Convert1fData));
|
||||
if (h == NULL) {
|
||||
*errp = MemError();
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
cvt = (void *)*h;
|
||||
|
@ -28,12 +28,11 @@ struct TTree {
|
||||
int count;
|
||||
};
|
||||
|
||||
static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
|
||||
static ErrorCode CreateTree(struct TTree *tree, Handle data, Size datasz)
|
||||
{
|
||||
struct TNode **nodes, *node;
|
||||
int i, j, dpos, enclen, encend, state, cur, nodecount, nodealloc;
|
||||
unsigned ch;
|
||||
OSErr err;
|
||||
|
||||
/* Create a tree with a root node mapping all the ASCII characters except
|
||||
NUL, CR, and LF. NUL won't map because an output of 0 is interpreted as
|
||||
@ -42,8 +41,7 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
|
||||
nodes =
|
||||
(struct TNode **)NewHandle(kInitialTableAlloc * sizeof(struct TNode));
|
||||
if (nodes == NULL) {
|
||||
err = MemError();
|
||||
goto have_error;
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
nodecount = 1;
|
||||
nodealloc = kInitialTableAlloc;
|
||||
@ -81,11 +79,11 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
|
||||
if (state == 0) {
|
||||
if (nodecount >= nodealloc) {
|
||||
nodealloc *= 2;
|
||||
SetHandleSize((Handle)nodes,
|
||||
nodealloc * sizeof(struct TNode));
|
||||
err = MemError();
|
||||
if (err != 0) {
|
||||
goto have_error;
|
||||
if (!ResizeHandle(
|
||||
(Handle)nodes,
|
||||
nodealloc * sizeof(struct TNode))) {
|
||||
DisposeHandle((Handle)nodes);
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
node = *nodes + cur;
|
||||
}
|
||||
@ -105,7 +103,10 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetHandleSize((Handle)nodes, nodecount * sizeof(struct TNode));
|
||||
if (!ResizeHandle((Handle)nodes, nodecount * sizeof(struct TNode))) {
|
||||
DisposeHandle((Handle)nodes);
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
tree->nodes = nodes;
|
||||
tree->count = nodecount;
|
||||
return 0;
|
||||
@ -113,11 +114,6 @@ static int CreateTree(struct TTree *tree, Handle data, Size datasz, OSErr *errp)
|
||||
bad_table:
|
||||
DisposeHandle((Handle)nodes);
|
||||
return kErrorBadData;
|
||||
|
||||
have_error:
|
||||
DisposeHandle((Handle)nodes);
|
||||
*errp = err;
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
|
||||
struct NodeInfo {
|
||||
@ -139,8 +135,7 @@ struct CNode {
|
||||
UInt8 span;
|
||||
};
|
||||
|
||||
static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
|
||||
OSErr *errp)
|
||||
static ErrorCode CompactTree(Handle *out, struct TNode **nodes, int nodecount)
|
||||
{
|
||||
Handle ctree;
|
||||
struct TNode *node;
|
||||
@ -153,7 +148,6 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
|
||||
/* Figure out where each compacted node will go. */
|
||||
infos = (struct NodeInfo **)NewHandle(sizeof(struct NodeInfo) * nodecount);
|
||||
if (infos == NULL) {
|
||||
*errp = MemError();
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
offset = 0;
|
||||
@ -178,7 +172,6 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
|
||||
/* Create the compacted tree. */
|
||||
ctree = NewHandle(offset);
|
||||
if (ctree == NULL) {
|
||||
*errp = MemError();
|
||||
DisposeHandle((Handle)infos);
|
||||
return kErrorNoMemory;
|
||||
}
|
||||
@ -208,18 +201,18 @@ static int CompactTree(Handle *out, struct TNode **nodes, int nodecount,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Convert1rBuild(Handle *out, Handle data, Size datasz, OSErr *errp)
|
||||
ErrorCode Convert1rBuild(Handle *out, Handle data, Size datasz)
|
||||
{
|
||||
struct TTree table;
|
||||
int r;
|
||||
ErrorCode err;
|
||||
|
||||
r = CreateTree(&table, data, datasz, errp);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
err = CreateTree(&table, data, datasz);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
r = CompactTree(out, table.nodes, table.count, errp);
|
||||
err = CompactTree(out, table.nodes, table.count);
|
||||
DisposeHandle((Handle)table.nodes);
|
||||
return r;
|
||||
return err;
|
||||
}
|
||||
|
||||
struct Convert1rState {
|
||||
|
@ -41,7 +41,7 @@ static void Failf(const char *msg, ...)
|
||||
|
||||
static const char *const kErrorNames[] = {"ok", "no memory", "bad data"};
|
||||
|
||||
static const char *ErrorName(int err)
|
||||
static const char *ErrorName(ErrorCode err)
|
||||
{
|
||||
if (err < 0 || (int)(sizeof(kErrorNames) / sizeof(*kErrorNames)) <= err) {
|
||||
Dief("bad error code: %d", err);
|
||||
@ -151,12 +151,12 @@ static void TestConverter(const char *name, struct CharmapData data)
|
||||
Handle datah;
|
||||
struct Converter cf, cr, cc;
|
||||
struct ConverterState st;
|
||||
int r, i, j, k, jmax, len0, len1, len2;
|
||||
OSErr err;
|
||||
int i, j, k, jmax, len0, len1, len2;
|
||||
UInt8 *ptr;
|
||||
const UInt8 *iptr, *iend, *istart;
|
||||
UInt8 *optr, *oend;
|
||||
int lblen[4];
|
||||
ErrorCode err;
|
||||
|
||||
cf.data = NULL;
|
||||
cr.data = NULL;
|
||||
@ -166,14 +166,14 @@ static void TestConverter(const char *name, struct CharmapData data)
|
||||
/* Load the converter into memory and build the conversion table. */
|
||||
datap = (void *)data.ptr;
|
||||
datah = &datap;
|
||||
r = ConverterBuild(&cf, datah, data.size, kToUTF8, &err);
|
||||
if (r != 0) {
|
||||
Failf("ConverterBuild: to UTF-8: %s", ErrorName(r));
|
||||
err = ConverterBuild(&cf, datah, data.size, kToUTF8);
|
||||
if (err != 0) {
|
||||
Failf("ConverterBuild: to UTF-8: %s", ErrorName(err));
|
||||
goto done;
|
||||
}
|
||||
r = ConverterBuild(&cr, datah, data.size, kFromUTF8, &err);
|
||||
if (r != 0) {
|
||||
Failf("ConverterBuild: from UTF-8: %s", ErrorName(r));
|
||||
err = ConverterBuild(&cr, datah, data.size, kFromUTF8);
|
||||
if (err != 0) {
|
||||
Failf("ConverterBuild: from UTF-8: %s", ErrorName(err));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ int main(int argc, char **argv)
|
||||
for (i = 0; i < 3; i++) {
|
||||
buf = malloc(kConvertBufferSize);
|
||||
if (buf == NULL) {
|
||||
DieErrorf(errno, "malloc");
|
||||
Dief("malloc failed");
|
||||
}
|
||||
gBuffer[i] = buf;
|
||||
}
|
||||
|
63
lib/defs.h
63
lib/defs.h
@ -2,18 +2,35 @@
|
||||
#define defs_h
|
||||
/* defs.h - common definitions. */
|
||||
|
||||
/*==============================================================================
|
||||
Basic definitions
|
||||
==============================================================================*/
|
||||
|
||||
#if macintosh
|
||||
|
||||
#include <MacTypes.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Definitions in <MacTypes.h> */
|
||||
|
||||
/* Include <stddef.h> for NULL */
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if __STDC_VERSION__ >= 199901l
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#if __bool_true_false_are_defined
|
||||
typedef bool Boolean;
|
||||
#else
|
||||
enum
|
||||
{
|
||||
false,
|
||||
true
|
||||
};
|
||||
typedef unsigned char Boolean;
|
||||
#endif
|
||||
|
||||
typedef uint8_t UInt8;
|
||||
typedef int8_t SInt8;
|
||||
typedef uint16_t UInt16;
|
||||
@ -25,19 +42,47 @@ typedef char *Ptr;
|
||||
typedef Ptr *Handle;
|
||||
typedef long Size;
|
||||
|
||||
typedef SInt16 OSErr;
|
||||
#endif
|
||||
|
||||
/* Definitions in <MacMemory.h> */
|
||||
/*==============================================================================
|
||||
Error codes and error reporting
|
||||
==============================================================================*/
|
||||
|
||||
Handle NewHandle(Size byteCount);
|
||||
void HLock(Handle h);
|
||||
void HUnlock(Handle h);
|
||||
/* Error codes. */
|
||||
typedef enum
|
||||
{
|
||||
/* No error. */
|
||||
kErrorOK,
|
||||
|
||||
/* Memory allocation failed. */
|
||||
kErrorNoMemory,
|
||||
|
||||
/* Invaild table data. */
|
||||
kErrorBadData
|
||||
} ErrorCode;
|
||||
|
||||
/*==============================================================================
|
||||
Memory allocation
|
||||
==============================================================================*/
|
||||
|
||||
#if macintosh
|
||||
|
||||
#include <MacMemory.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Allocate a relocatable block of memory. */
|
||||
Handle NewHandle(Size byteSize);
|
||||
|
||||
/* Free a relocatable block of memory. */
|
||||
void DisposeHandle(Handle h);
|
||||
void SetHandleSize(Handle h, Size newSize);
|
||||
OSErr MemError(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* Resize a relocatable block of memory. Return true on success. */
|
||||
Boolean ResizeHandle(Handle h, Size newSize);
|
||||
|
||||
/* Fill memory with zeroes. */
|
||||
void MemClear(void *ptr, Size size);
|
||||
|
||||
#endif
|
||||
|
@ -22,19 +22,6 @@ void Dief(const char *msg, ...)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void DieErrorf(int errcode, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
fputs("Error: ", stderr);
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
fputs(": ", stderr);
|
||||
fputs(strerror(errcode), stderr);
|
||||
fputc('\n', stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Handle NewHandle(Size byteCount)
|
||||
{
|
||||
Ptr p;
|
||||
@ -45,26 +32,17 @@ Handle NewHandle(Size byteCount)
|
||||
}
|
||||
p = malloc(byteCount);
|
||||
if (byteCount > 0 && p == NULL) {
|
||||
Dief("NewHandle: malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
h = malloc(sizeof(Ptr));
|
||||
if (h == NULL) {
|
||||
Dief("NewHandle: malloc failed");
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
*h = p;
|
||||
return h;
|
||||
}
|
||||
|
||||
void HLock(Handle h)
|
||||
{
|
||||
(void)h;
|
||||
}
|
||||
|
||||
void HUnlock(Handle h)
|
||||
{
|
||||
(void)h;
|
||||
}
|
||||
|
||||
void DisposeHandle(Handle h)
|
||||
{
|
||||
if (h != NULL) {
|
||||
@ -73,23 +51,21 @@ void DisposeHandle(Handle h)
|
||||
}
|
||||
}
|
||||
|
||||
void SetHandleSize(Handle h, Size newSize)
|
||||
Boolean ResizeHandle(Handle h, Size newSize)
|
||||
{
|
||||
Ptr p;
|
||||
if (h == NULL) {
|
||||
Dief("SetHandleSize: h = NULL");
|
||||
Dief("ResizeHandle: h = NULL");
|
||||
}
|
||||
if (newSize < 0) {
|
||||
Dief("ResizeHandle: newSize = %ld", newSize);
|
||||
}
|
||||
p = realloc(*h, newSize);
|
||||
if (newSize > 0 && p == NULL) {
|
||||
Dief("SetHandleSize: realloc failed");
|
||||
return false;
|
||||
}
|
||||
*h = p;
|
||||
}
|
||||
|
||||
OSErr MemError(void)
|
||||
{
|
||||
/* Memory allocation failures abort the program. */
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemClear(void *ptr, Size size)
|
||||
|
Loading…
x
Reference in New Issue
Block a user