/* format.c: OBJECT FORMATS
*
* $Id: //info.ravenbrook.com/project/mps/version/1.109/code/format.c#1 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
* DESIGN
*
* See protocol.mps.format.
*/
#include "mpm.h"
SRCID(format, "$Id: //info.ravenbrook.com/project/mps/version/1.109/code/format.c#1 $");
/* FormatCheck -- check a format */
Bool FormatCheck(Format format)
{
CHECKS(Format, format);
CHECKU(Arena, format->arena);
CHECKL(format->serial < format->arena->formatSerial);
CHECKL(format->variety == FormatVarietyA
|| format->variety == FormatVarietyB
|| format->variety == FormatVarietyAutoHeader);
CHECKL(RingCheck(&format->arenaRing));
CHECKL(AlignCheck(format->alignment));
/* @@@@ alignment should be less than maximum allowed */
CHECKL(FUNCHECK(format->scan));
CHECKL(format->variety == FormatVarietyFixed
? format->skip == NULL : FUNCHECK(format->skip));
CHECKL(FUNCHECK(format->move));
CHECKL(FUNCHECK(format->isMoved));
/* Ignore unused copy field. */
CHECKL(FUNCHECK(format->pad));
CHECKL(FUNCHECK(format->class));
return TRUE;
}
static Addr FormatDefaultClass(Addr object)
{
AVER(object != NULL);
return ((Addr *)object)[0];
}
/* FormatCreate -- create a format */
Res FormatCreate(Format *formatReturn, Arena arena,
Align alignment,
FormatVariety variety,
FormatScanMethod scan,
FormatSkipMethod skip,
FormatMoveMethod move,
FormatIsMovedMethod isMoved,
FormatCopyMethod copy,
FormatPadMethod pad,
FormatClassMethod class,
Size headerSize)
{
Format format;
Res res;
void *p;
AVER(formatReturn != NULL);
res = ControlAlloc(&p, arena, sizeof(FormatStruct),
/* withReservoirPermit */ FALSE);
if(res != ResOK)
return res;
format = (Format)p; /* avoid pun */
format->arena = arena;
RingInit(&format->arenaRing);
format->alignment = alignment;
format->variety = variety;
format->scan = scan;
format->skip = skip;
format->move = move;
format->isMoved = isMoved;
format->copy = copy;
format->pad = pad;
if (class == NULL) {
format->class = &FormatDefaultClass;
} else {
AVER(variety == FormatVarietyB);
format->class = class;
}
if (headerSize != 0) {
AVER(variety == FormatVarietyAutoHeader);
format->headerSize = headerSize;
} else {
format->headerSize = 0;
}
format->sig = FormatSig;
format->serial = arena->formatSerial;
++arena->formatSerial;
AVERT(Format, format);
RingAppend(&arena->formatRing, &format->arenaRing);
*formatReturn = format;
return ResOK;
}
/* FormatDestroy -- destroy a format */
void FormatDestroy(Format format)
{
AVERT(Format, format);
RingRemove(&format->arenaRing);
format->sig = SigInvalid;
RingFinish(&format->arenaRing);
ControlFree(format->arena, format, sizeof(FormatStruct));
}
/* FormatArena -- find the arena of a format
*
* Must be thread-safe. See <design/interface-c/#thread-safety>. */
Arena FormatArena(Format format)
{
/* Can't AVER format as that would not be thread-safe */
/* AVERT(Format, format); */
return format->arena;
}
/* FormatDescribe -- describe a format */
Res FormatDescribe(Format format, mps_lib_FILE *stream)
{
Res res;
res = WriteF(stream,
"Format $P ($U) {\n", (WriteFP)format, (WriteFU)format->serial,
" arena $P ($U)\n",
(WriteFP)format->arena, (WriteFU)format->arena->serial,
" alignment $W\n", (WriteFW)format->alignment,
" scan $F\n", (WriteFF)format->scan,
" skip $F\n", (WriteFF)format->skip,
" move $F\n", (WriteFF)format->move,
" isMoved $F\n", (WriteFF)format->isMoved,
" copy $F\n", (WriteFF)format->copy,
" pad $F\n", (WriteFF)format->pad,
"} Format $P ($U)\n", (WriteFP)format, (WriteFU)format->serial,
NULL);
if (res != ResOK) return res;
return ResOK;
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/