Example #1
0
/* ---------- OpenWGroup -----------------------------------------------*/
IFFP OpenWGroup(GroupContext *parent0,GroupContext* new0)
{
	register GroupContext *parent = parent0;
	register GroupContext *newtmp    = new0;
	register int ckEnd;
	register IFFP iffp = IFF_OKAY;

	newtmp->parent       = parent;
	newtmp->clientFrame  = parent->clientFrame;
	newtmp->file         = parent->file;
	newtmp->position     = parent->position;
	newtmp->bound        = parent->bound;
	newtmp->ckHdr.ckID   = NULL_CHUNK;
	newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;

	if ( Known(parent->ckHdr.ckSize) ) {
		ckEnd = newtmp->position + ChunkMoreBytes(parent);
		if ( newtmp->bound == szNotYetKnown || newtmp->bound > ckEnd )
			newtmp->bound = ckEnd;
	};

	if ( parent->ckHdr.ckID == NULL_CHUNK || /* not currently writing a chunk*/
		IS_ODD(newtmp->position) ||
		(Known(newtmp->bound) && IS_ODD(newtmp->bound)) )
		iffp = CLIENT_ERROR;
	return(iffp);
}
Example #2
0
/* ---------- PutCkHdr -------------------------------------------------*/
IFFP PutCkHdr(GroupContext *context0, int ckID, int ckSize)
{
	register GroupContext *context = context0;
	int minPSize = sizeof(ChunkHeader); /* physical chunk >= minPSize bytes*/

	/* CLIENT_ERROR if we're already inside a chunk or asked to write
	* other than one FORM, LIST, or CAT at the top level of a file */
	/* Also, non-positive int values are illegal and used for error codes.*/
	/* (We could check for other illegal IDs...)*/
	if ( context->ckHdr.ckID != NULL_CHUNK  ||  ckID <= 0 )
		return(CLIENT_ERROR);
	else if (context->parent == NULL)  {
		switch (ckID)  {
	   case FORM:  case LIST:  case CAT:  break;
	   default: return(CLIENT_ERROR);
		}
		if (context->position != 0)
			return(CLIENT_ERROR);
	}

	if ( Known(ckSize) ) {
		if ( ckSize < 0 )
			return(CLIENT_ERROR);
		minPSize += ckSize;
	};
	if ( Known(context->bound)  &&
		context->position + minPSize > context->bound )
		return(CLIENT_ERROR);

	context->ckHdr.ckID   = ckID;
	context->ckHdr.ckSize = ckSize;
	context->bytesSoFar   = 0;
	{
		context->ckHdr.ckSize = endianSwap32(context->ckHdr.ckSize);
		if (0 > fwrite(&context->ckHdr, 1,sizeof(ChunkHeader),context->file))
			return(DOS_ERROR);
		context->ckHdr.ckSize = endianSwap32(context->ckHdr.ckSize);
	}
	context->position += sizeof(ChunkHeader);
	return(IFF_OKAY);
}
Example #3
0
/* ---------- IFFWriteBytes ---------------------------------------------*/
IFFP IFFWriteBytes(GroupContext *context0, char *data, int nBytes)
{
	register GroupContext *context = context0;

	if ( context->ckHdr.ckID == NULL_CHUNK  ||   /* not in a chunk */
		nBytes < 0  ||            /* negative nBytes */
		(Known(context->bound)  &&      /* overflow context */
		context->position + nBytes > context->bound)  ||
		(Known(context->ckHdr.ckSize)  &&      /* overflow chunk */
		context->bytesSoFar + nBytes > context->ckHdr.ckSize) )
	{
		return(CLIENT_ERROR);
	}

	if (0 > fwrite(data, 1,nBytes,context->file))
		return(DOS_ERROR);

	context->bytesSoFar += nBytes;
	context->position   += nBytes;
	return(IFF_OKAY);
}
Example #4
0
IFFP OpenWIFF(BPTR file, GroupContext *new0, int limit)
{
	register GroupContext *newtmp = new0;
	register IFFP iffp = IFF_OKAY;

	newtmp->parent       = NULL;
	newtmp->clientFrame  = NULL;
	newtmp->file         = file;
	newtmp->position     = 0;
	newtmp->bound        = limit;
	newtmp->ckHdr.ckID   = NULL_CHUNK;  /* indicates no current chunk */
	newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;

	if (0 > Seek(file, 0, OFFSET_BEGINNING))   /* Go to start of the file.*/
		iffp = DOS_ERROR;
	else if ( Known(limit) && IS_ODD(limit) )
		iffp = CLIENT_ERROR;
	return(iffp);
}
Example #5
0
void FindRoot(const Tree &tree, unsigned *ptruNode1, unsigned *ptruNode2,
  double *ptrdLength1, double *ptrdLength2,
  ROOT RootMethod)
	{
#if	TRACE
	tree.LogMe();
#endif
	if (tree.IsRooted())
		Quit("FindRoot: tree already rooted");

	const unsigned uNodeCount = tree.GetNodeCount();
	const unsigned uLeafCount = tree.GetLeafCount();

	if (uNodeCount < 2)
		Quit("Root: don't support trees with < 2 edges");

	EdgeInfo **EIs = new EdgeInfo *[uNodeCount];
	for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
		EIs[uNodeIndex] = new EdgeInfo[3];

	EdgeList Edges;
	for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
		if (tree.IsLeaf(uNodeIndex))
			{
			unsigned uParent = tree.GetNeighbor1(uNodeIndex);
			Edges.Add(uParent, uNodeIndex);
			}

#if	TRACE
	Log("Edges: ");
	Edges.LogMe();
#endif

// Main loop: iterate until all distances known
	double dAllMaxDist = -1e20;
	unsigned uMaxFrom = NULL_NEIGHBOR;
	unsigned uMaxTo = NULL_NEIGHBOR;
	for (;;)
		{
		EdgeList NextEdges;

#if	TRACE
		Log("\nTop of main loop\n");
		Log("Edges: ");
		Edges.LogMe();
		Log("MDs:\n");
		ListEIs(EIs, uNodeCount);
#endif

	// For all edges
		const unsigned uEdgeCount = Edges.GetCount();
		if (0 == uEdgeCount)
			break;
		for (unsigned n = 0; n < uEdgeCount; ++n)
			{
			unsigned uNodeFrom;
			unsigned uNodeTo;
			Edges.GetEdge(n, &uNodeFrom, &uNodeTo);

			CalcInfo(tree, uNodeFrom, uNodeTo, EIs);
#if	TRACE
			Log("Edge %u -> %u\n", uNodeFrom, uNodeTo);
#endif
			const unsigned uNeighborCount = tree.GetNeighborCount(uNodeFrom);
			for (unsigned i = 0; i < uNeighborCount; ++i)
				{
				const unsigned uNeighborIndex = tree.GetNeighbor(uNodeFrom, i);
				if (!Known(tree, EIs, uNeighborIndex, uNodeFrom) &&
				  AllKnownOut(tree, EIs, uNeighborIndex, uNodeFrom))
					NextEdges.Add(uNeighborIndex, uNodeFrom);
				}
			}
		Edges.Copy(NextEdges);
		}

#if	TRACE
	ListEIs(EIs, uNodeCount);
#endif

	switch (RootMethod)
		{
	case ROOT_MidLongestSpan:
		RootByMidLongestSpan(tree, EIs, ptruNode1, ptruNode2,
		  ptrdLength1, ptrdLength2);
		break;

	case ROOT_MinAvgLeafDist:
		RootByMinAvgLeafDist(tree, EIs, ptruNode1, ptruNode2,
		  ptrdLength1, ptrdLength2);
		break;

	default:
		Quit("Invalid RootMethod=%d", RootMethod);
		}

	for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex)
		delete[] EIs[uNodeIndex];
	delete[] EIs;
	}