#ifndef _CODE
#define _CODE

#include "Error.h"

#define MAXCODEDOMAINS 5

typedef struct _codeBlock
{
  int domain;			/* code domain */
  char *current;		/* next empty location */
  int initialSize;
  int dataSize;			/* size of malloced data */
  char *data;
  int malloced;
} CodeBlock;

typedef struct _codeDomain
{
  char *Domain;			/* name of this code domain */
  Method GetString;
  Method PutString;
  Method GetMemory;
  Method PutMemory;
  Method GetCard16;
  Method PutCard16;
  Method GetCard32;
  Method PutCard32;
} CodeDomain;

extern Trap Code_InitBlock(CodeBlock *block, char *domain,
			   char *data, int sizeHint);
extern Trap Code_CreateBlock(CodeBlock **block, char *domain,
			     char *data, int sizeHint);
extern Trap Code_FreeBlock(CodeBlock *block);
extern Trap Code_Expand(CodeBlock *block, int min);

/*
extern Trap Code_GetString(CodeBlock *block, char **string);
extern Trap Code_PutString(CodeBlock *block, char *string);
extern Trap Code_GetCard16(CodeBlock *block, Card16 *card);
extern Trap Code_PutCard16(CodeBlock *block, Card16 card);
extern Trap Code_GetCard32(CodeBlock *block, Card32 *card);
extern Trap Code_PutCard32(CodeBlock *block, Card32 card);
*/

/* Note there is no domain checking here... */

extern CodeDomain codeDomains[];

#define Code_GetString(block, string) \
  (codeDomains[(block)->domain].GetString(block, string))
#define Code_PutString(block, string) \
  (codeDomains[(block)->domain].PutString(block, string))
#define Code_GetMemory(block, memory, size) \
  (codeDomains[(block)->domain].GetMemory(block, memory, size))
#define Code_PutMemory(block, memory, size) \
  (codeDomains[(block)->domain].PutMemory(block, memory, size))
#define Code_GetCard16(block, card) \
  (codeDomains[(block)->domain].GetCard16(block, card))
#define Code_PutCard16(block, card) \
  (codeDomains[(block)->domain].PutCard16(block, card))
#define Code_GetCard32(block, card) \
  (codeDomains[(block)->domain].GetCard32(block, card))
#define Code_PutCard32(block, card) \
  (codeDomains[(block)->domain].PutCard32(block, card))
#define Code_BlockData(block) ((block)->data)
#define Code_BlockLength(block) ((block)->current - (block)->data)
#define Code_ResetBlock(block) (block)->current = (block)->data

#endif /* _CODE */
