Beispiel #1
0
void FileEntry(u_int16 *entry) {
//    PrintEntry(entry);
//    puts(" FILE");
#if 1
    register int i;
    putch('F');
    for (i=0;i<32/2;i++) {
	putch(*entry >> 8);
	putch(*entry++);
    }
    putch('\n');
    entry -= 32/2;
#endif

#ifdef MAXFILES
    if (files < MAXFILES) {
	/* Must save file size and file start cluster to be able to
	   open the file at a later time. The files can not
	   be opened by a number because the numbering is different,
	   and they can't be opened by name because there can be
	   several files with the same name in different directories.
	*/
	memcpy(fileNames[files], entry, 12/2);
	fileSize[files] =
	    ((u_int32)SwapWord(entry[30/2]) << 16) | SwapWord(entry[28/2]);
	fileCluster[files] =
	    ((u_int32)SwapWord(entry[20/2]) << 16) | SwapWord(entry[26/2]);
	files++;
    }
#endif
}
Beispiel #2
0
treeNodeObj *readTreeNode( SHPTreeHandle disktree )
{
  int i,res;
  ms_int32 offset;
  treeNodeObj *node;

  node = (treeNodeObj *) msSmallMalloc(sizeof(treeNodeObj));
  node->ids = NULL;

  res = fread( &offset, 4, 1, disktree->fp );
  if ( !res )
    return NULL;

  if ( disktree->needswap ) SwapWord ( 4, &offset );

  fread( &node->rect, sizeof(rectObj), 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 8, &node->rect.minx );
  if ( disktree->needswap ) SwapWord ( 8, &node->rect.miny );
  if ( disktree->needswap ) SwapWord ( 8, &node->rect.maxx );
  if ( disktree->needswap ) SwapWord ( 8, &node->rect.maxy );

  fread( &node->numshapes, 4, 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 4, &node->numshapes );
  if( node->numshapes > 0 )
    node->ids = (ms_int32 *)msSmallMalloc(sizeof(ms_int32)*node->numshapes);
  fread( node->ids, node->numshapes*4, 1, disktree->fp );
  for( i=0; i < node->numshapes; i++ ) {
    if ( disktree->needswap ) SwapWord ( 4, &node->ids[i] );
  }

  fread( &node->numsubnodes, 4, 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 4, &node->numsubnodes );

  return node;
}
void XGToolbarView::ChangeToolMenu(short resID)
{
	unsigned short i,len;
	HRSRC hsrc;
	HGLOBAL h;
	void *data;
	unsigned long offset;
	
	if (fResID == resID) return;
	if (fOverTool != 0xFFFF) XGToolTip::CloseTip();
	fResID = resID;
	
	hsrc = ::FindResource(_GInstance,MAKEINTRESOURCE(resID),"TMenu");
	Assert(hsrc != NULL);
	h = LoadResource(_GInstance,hsrc);
	Assert(h != NULL);
	data = LockResource(h);
	
	/*
	 *	Now create the object
	 */
	
	fToolbar.SetSize(::SizeofResource(_GInstance,hsrc));
	memcpy(*fToolbar,data,fToolbar.GetSize());
	
	/*
	 *	Release the resource
	 */
	
	UnlockResource(h);
	FreeResource(h);

	fToolbar.SetShort(0,SwapWord(fToolbar.GetShort(0)));
	len = GetToolLength();
	for (i = 0; i < len; i++) {
		offset = GetItemOffset(i);
		
		fToolbar.SetShort(offset,SwapWord(fToolbar.GetShort(offset)));
		fToolbar.SetShort(offset+2,SwapWord(fToolbar.GetShort(offset+2)));
	}
	fStatus.SetSize(len);
	for (i = 0; i < len; i++) fStatus.SetChar(i,0);
	fOverTool = -1;
	
	/*
	 *	Redraw me
	 */
	
	InvalView();
}
Beispiel #4
0
static void searchDiskTreeNode(SHPTreeHandle disktree, rectObj aoi, ms_bitarray status) 
{
  int i;
  ms_int32 offset;
  ms_int32 numshapes, numsubnodes;
  rectObj rect;

  int *ids=NULL;

  fread( &offset, 4, 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 4, &offset );

  fread( &rect, sizeof(rectObj), 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 8, &rect.minx );
  if ( disktree->needswap ) SwapWord ( 8, &rect.miny );
  if ( disktree->needswap ) SwapWord ( 8, &rect.maxx );
  if ( disktree->needswap ) SwapWord ( 8, &rect.maxy );
      
  fread( &numshapes, 4, 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 4, &numshapes );

  if(!msRectOverlap(&rect, &aoi)) { /* skip rest of this node and sub-nodes */
    offset += numshapes*sizeof(ms_int32) + sizeof(ms_int32);
    fseek(disktree->fp, offset, SEEK_CUR);
    return;
  }
  if(numshapes > 0) {
    ids = (int *)msSmallMalloc(numshapes*sizeof(ms_int32));

    fread( ids, numshapes*sizeof(ms_int32), 1, disktree->fp );
    if (disktree->needswap )
    {
      for( i=0; i<numshapes; i++ )
      {
        SwapWord( 4, &ids[i] );    
        msSetBit(status, ids[i], 1);
      }
    }
    else
    {
      for(i=0; i<numshapes; i++)
        msSetBit(status, ids[i], 1);
    }
    free(ids);
  }

  fread( &numsubnodes, 4, 1, disktree->fp );
  if ( disktree->needswap ) SwapWord ( 4, &numsubnodes );

  for(i=0; i<numsubnodes; i++)
    searchDiskTreeNode(disktree, aoi, status);

  return;
}
Beispiel #5
0
static void writeTreeNode(SHPTreeHandle disktree, treeNodeObj *node)
{
  int i,j;
  ms_int32 offset;
  char *pabyRec = NULL;

  offset = getSubNodeOffset(node);

  pabyRec = msSmallMalloc(sizeof(rectObj) + (3 * sizeof(ms_int32)) + (node->numshapes * sizeof(ms_int32)) );

  memcpy( pabyRec, &offset, 4);
  if( disktree->needswap ) SwapWord( 4, pabyRec );

  memcpy( pabyRec+4, &node->rect, sizeof(rectObj));
  for (i=0; i < 4; i++)
    if( disktree->needswap ) SwapWord( 8, pabyRec+4+(8*i) );

  memcpy( pabyRec+36, &node->numshapes, 4);
  if( disktree->needswap ) SwapWord( 4, pabyRec+36 );

  j = node->numshapes*sizeof(ms_int32);
  memcpy( pabyRec+40, node->ids, j);
  for (i=0; i<node->numshapes; i++)
    if( disktree->needswap ) SwapWord( 4, pabyRec+40+(4*i));

  memcpy( pabyRec+j+40, &node->numsubnodes, 4);
  if( disktree->needswap ) SwapWord( 4, pabyRec+40+j );

  fwrite( pabyRec, 44+j, 1, disktree->fp);
  free (pabyRec);

  for(i=0; i<node->numsubnodes; i++ ) {
    if(node->subnode[i])
      writeTreeNode(disktree, node->subnode[i]);
  }


  return;

}
Beispiel #6
0
void DirEntry(u_int16 *entry) {
//    PrintEntry(entry);
//    puts(" DIR");
#if 1
    register int i;
    putch('D');
    for (i=0;i<32/2;i++) {
	putch(*entry >> 8);
	putch(*entry++);
    }
    putch('\n');
    entry -= 32/2;
#endif

    if (dirs < MAXDIRS) {
	/* Must save start cluster to be able to enter the directory. */
	memcpy(dirNames[dirs], entry, 12/2);
	dirCluster[dirs] =
	    ((u_int32)SwapWord(entry[20/2]) << 16) | SwapWord(entry[26/2]);
	dirs++;
    }
}
word Compile8(byte *pbCompileBuffer, ScanData *psd, bool fOdd)
{
	// Make space for header

	byte *pb = pbCompileBuffer;
	pb += sizeof(word); // ibasc;
	pb += sizeof(word); // ibaiclr;

	// Copy over ops. Translate even / odd to asked alignment
	// Filter out sc's (will go to another stream).

	byte *pop = (byte *)(psd + 1);
	byte *pbT = pb;
	if (fOdd)
		*pbT++ = kopAlign;
	while (true) {
		int op = (int)(word)*pop++;
		if (op >= kopEvenData1 && op <= kopEvenData48) {
			if (fOdd)
				op = op - kopEvenData1 + kopOddData1;
			*pbT++ = op;
			continue;
		}
		if (op >= kopOddData1 && op <= kopOddData48) {
			if (fOdd)
				op = op - kopOddData1 + kopEvenData1;
			*pbT++ = op;
			continue;
		}
		if (op >= kopEvenSide1 && op <= kopEvenSide16) {
			int cb = op - kopEvenSide1 + 1;
			pop += (cb + 1) / 2;
			if (fOdd)
				op = op - kopEvenSide1 + kopOddSide1;
			*pbT++ = op;
			continue;
		}
		if (op >= kopOddSide1 && op <= kopOddSide16) {
			int cb = op - kopOddSide1 + 1;
			pop += (cb + 1) / 2;
			if (fOdd)
				op = op - kopOddSide1 + kopEvenSide1;
			*pbT++ = op;
			continue;
		}
		*pbT++ = op;
		if (op == kopEnd)
			break;
	}
	if (((byte)(pword)pbT) & 1)
		pbT++;
	int cbOps = pbT - pb;

	// Transcode side codes into alignment sensitive mapping table offsets

	word *pwT = (word *)pbT;
	pop = (byte *)(psd + 1);
	while (true) {
		int op = (int)(word)*pop++;
		int cb;
		bool fOddOp;
		if (op >= kopEvenSide1 && op <= kopEvenSide16) {
			cb = op - kopEvenSide1 + 1;
			fOddOp = fOdd;
		} else if (op >= kopOddSide1 && op <= kopOddSide16) {
			cb = op - kopOddSide1 + 1;
			fOddOp = !fOdd;
		} else if (op == kopEnd) {
			break;
		} else {
			continue;
		}

		int cbT = cb;
		byte abSideIndex[512];
		byte *pbSideIndex = abSideIndex;
		while (true) {
			byte sc = *pop++;
			*pbSideIndex++ = ((sc >> 5) & 0x7);
			cbT--;
			if (cbT == 0)
				break;
			*pbSideIndex++ = ((sc >> 1) & 0x7);
			cbT--;
			if (cbT == 0)
				break;
		}
		
		pbSideIndex = abSideIndex;
		cbT = cb;
		if (fOddOp) {
			byte b1 = *pbSideIndex++;
			*pwT++ = GetSideColorOffset(b1, 0, 0, 0);
			cbT--;
		}
		while (cbT != 0) {
			byte b1, b2, b3, b4;
			switch (cbT) {
			case 1:
				b1 = *pbSideIndex++;
				*pwT++ = GetSideColorOffset(b1, 0, 0, 0);
				cbT--;
				break;

			case 2:
			case 3:
				b1 = *pbSideIndex++;
				b2 = *pbSideIndex++;
				*pwT++ = GetSideColorOffset(b1, b2, 0, 0);
				cbT -= 2;
				break;

			case 4:
			default:
				b1 = *pbSideIndex++;
				b2 = *pbSideIndex++;
				b3 = *pbSideIndex++;
				b4 = *pbSideIndex++;
				*pwT++ = GetSideColorOffset(b1, b2, b3, b4);
				cbT -= 4;
				break;
			}
		}
	}
	pbT = (byte *)pwT;
	int cbScs = pbT - (pb + cbOps);

	// Now copy data and align as we go

	pop = pbCompileBuffer + 4;
	byte *pbSrc = ((byte *)psd) + SwapWord(psd->ibaiclr);
	while (true) {
		int op = (int)(word)*pop++;
		if (op == kopEnd)
			break;
		if (op == kopAlign) {
			pbT++;
			continue;
		}
		if (op >= kopEvenData1 && op <= kopEvenData48) {
			int cb = op - kopEvenData1 + 1;
			byte *pbDstT = pbT;
			byte *pbSrcT = pbSrc;
			while (pbDstT < &pbT[cb])
				*pbDstT++ = *pbSrcT++;
			pbT += cb;
			pbSrc += cb;
		}
		if (op >= kopOddData1 && op <= kopOddData48) {
			int cb = op - kopOddData1 + 1;
			byte *pbDstT = pbT;
			byte *pbSrcT = pbSrc;
			while (pbDstT < &pbT[cb])
				*pbDstT++ = *pbSrcT++;
			pbT += cb;
			pbSrc += cb;
		}
	}

	// Stuff in correct byte offsets

	pwT = (word *)pbCompileBuffer;

	// ibasc
	*pwT++ = 4 + cbOps;

	// ibaiclr
	*pwT = 4 + cbOps + cbScs;

	return pbT - pbCompileBuffer;
}
Beispiel #8
0
static int
SHPSearchDiskTreeNode( FILE *fp, double *padfBoundsMin, double *padfBoundsMax,
                       int **ppanResultBuffer, int *pnBufferMax, 
                       int *pnResultCount, int bNeedSwap )

{
    int i;
    int offset;
    int numshapes, numsubnodes;
    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];

/* -------------------------------------------------------------------- */
/*      Read and unswap first part of node info.                        */
/* -------------------------------------------------------------------- */
    fread( &offset, 4, 1, fp );
    if ( bNeedSwap ) SwapWord ( 4, &offset );

    fread( adfNodeBoundsMin, sizeof(double), 2, fp );
    fread( adfNodeBoundsMax, sizeof(double), 2, fp );
    if ( bNeedSwap )
    {
        SwapWord( 8, adfNodeBoundsMin + 0 );
        SwapWord( 8, adfNodeBoundsMin + 1 );
        SwapWord( 8, adfNodeBoundsMax + 0 );
        SwapWord( 8, adfNodeBoundsMax + 1 );
    }
      
    fread( &numshapes, 4, 1, fp );
    if ( bNeedSwap ) SwapWord ( 4, &numshapes );

/* -------------------------------------------------------------------- */
/*      If we don't overlap this node at all, we can just fseek()       */
/*      pass this node info and all subnodes.                           */
/* -------------------------------------------------------------------- */
    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
                                padfBoundsMin, padfBoundsMax, 2 ) )
    {
        offset += numshapes*sizeof(int) + sizeof(int);
        fseek(fp, offset, SEEK_CUR);
        return TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add all the shapeids at this node to our list.                  */
/* -------------------------------------------------------------------- */
    if(numshapes > 0) 
    {
        if( *pnResultCount + numshapes > *pnBufferMax )
        {
            *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25);
            *ppanResultBuffer = (int *) 
                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );
        }

        fread( *ppanResultBuffer + *pnResultCount, 
               sizeof(int), numshapes, fp );

        if (bNeedSwap )
        {
            for( i=0; i<numshapes; i++ )
                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
        }

        *pnResultCount += numshapes; 
    } 

/* -------------------------------------------------------------------- */
/*      Process the subnodes.                                           */
/* -------------------------------------------------------------------- */
    fread( &numsubnodes, 4, 1, fp );
    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );

    for(i=0; i<numsubnodes; i++)
    {
        if( !SHPSearchDiskTreeNode( fp, padfBoundsMin, padfBoundsMax, 
                                    ppanResultBuffer, pnBufferMax, 
                                    pnResultCount, bNeedSwap ) )
            return FALSE;
    }

    return TRUE;
}
Beispiel #9
0
////////////////////////////////////////////////////////////////////////////
//
// LoadLIBShape()
//
int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP)
{
	#define CHUNK(Name)	(*ptr == *Name) &&			\
								(*(ptr+1) == *(Name+1)) &&	\
								(*(ptr+2) == *(Name+2)) &&	\
								(*(ptr+3) == *(Name+3))


	int RT_CODE;
	FILE *fp;
	char CHUNK[5];
	char far *ptr;
	memptr IFFfile = NULL;
	unsigned long FileLen, size, ChunkLen;
	int loop;


	RT_CODE = 1;

	// Decompress to ram and return ptr to data and return len of data in
	//	passed variable...

	if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))
		Quit("Error Loading Compressed lib shape!");

	// Evaluate the file
	//
	ptr = MK_FP(IFFfile,0);
	if (!CHUNK("FORM"))
		goto EXIT_FUNC;
	ptr += 4;

	FileLen = *(long far *)ptr;
	SwapLong((long far *)&FileLen);
	ptr += 4;

	if (!CHUNK("ILBM"))
		goto EXIT_FUNC;
	ptr += 4;

	FileLen += 4;
	while (FileLen)
	{
		ChunkLen = *(long far *)(ptr+4);
		SwapLong((long far *)&ChunkLen);
		ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;

		if (CHUNK("BMHD"))
		{
			ptr += 8;
			SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;
			SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;
			SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;
			SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;
			SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;
			SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;
			SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;
			SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;
			SwapWord(&SHP->bmHdr.w);
			SwapWord(&SHP->bmHdr.h);
			SwapWord(&SHP->bmHdr.x);
			SwapWord(&SHP->bmHdr.y);
			ptr += ChunkLen;
		}
		else
		if (CHUNK("BODY"))
		{
			ptr += 4;
			size = *((long far *)ptr);
			ptr += 4;
			SwapLong((long far *)&size);
			SHP->BPR = (SHP->bmHdr.w+7) >> 3;
			MM_GetPtr(&SHP->Data,size);
			if (!SHP->Data)
				goto EXIT_FUNC;
			movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
			ptr += ChunkLen;

			break;
		}
		else
Beispiel #10
0
OGRErr OGRPGeoLayer::createFromShapeBin( GByte *pabyShape, 
                                         OGRGeometry **ppoGeom,
                                         int nBytes )

{
    *ppoGeom = NULL;

    if( nBytes < 1 )
        return OGRERR_FAILURE;

    int nSHPType = pabyShape[0];


//    CPLDebug( "PGeo", 
//              "Shape type read from PGeo data is nSHPType = %d", 
//              nSHPType );

/* -------------------------------------------------------------------- */
/*      type 50 appears to just be an alias for normal line             */
/*      strings. (#1484)                                                */
/*      Type 51 appears to just be an alias for normal polygon. (#3100) */
/*      TODO: These types include additional attributes including       */
/*      non-linear segments and such. They should be handled.           */
/* -------------------------------------------------------------------- */
    switch( nSHPType )
    {
      case 50:
        nSHPType = SHPT_ARC;
        break;
      case 51:
        nSHPType = SHPT_POLYGON;
        break;
      case 52:
        nSHPType = SHPT_POINT;
        break;
      case 53:
        nSHPType = SHPT_MULTIPOINT;
        break;
      case 54:
        nSHPType = SHPT_MULTIPATCH;
    }

/* ==================================================================== */
/*  Extract vertices for a Polygon or Arc.				*/
/* ==================================================================== */
    if(    nSHPType == SHPT_ARC
        || nSHPType == SHPT_ARCZ
        || nSHPType == SHPT_ARCM
        || nSHPType == SHPT_ARCZM
        || nSHPType == SHPT_POLYGON 
        || nSHPType == SHPT_POLYGONZ
        || nSHPType == SHPT_POLYGONM
        || nSHPType == SHPT_POLYGONZM
        || nSHPType == SHPT_MULTIPATCH 
        || nSHPType == SHPT_MULTIPATCHM)
    {
        GInt32         nPoints, nParts;
        int            i, nOffset;
        GInt32         *panPartStart;

        if (nBytes < 44)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Extract part/point count, and build vertex and part arrays      */
/*      to proper size.                                                 */
/* -------------------------------------------------------------------- */
	memcpy( &nPoints, pabyShape + 40, 4 );
	memcpy( &nParts, pabyShape + 36, 4 );

	CPL_LSBPTR32( &nPoints );
	CPL_LSBPTR32( &nParts );

        if (nPoints < 0 || nParts < 0 ||
            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d.",
                     nPoints, nParts);
            return OGRERR_FAILURE;
        }

        int bHasZ = (  nSHPType == SHPT_POLYGONZ
                    || nSHPType == SHPT_POLYGONZM
                    || nSHPType == SHPT_ARCZ
                    || nSHPType == SHPT_ARCZM
                    || nSHPType == SHPT_MULTIPATCH 
                    || nSHPType == SHPT_MULTIPATCHM );

        int bIsMultiPatch = ( nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM );

        /* With the previous checks on nPoints and nParts, */
        /* we should not overflow here and after */
        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
        int nRequiredSize = 44 + 4 * nParts + 16 * nPoints;
        if ( bHasZ )
        {
            nRequiredSize += 16 + 8 * nPoints;
        }
        if( bIsMultiPatch )
        {
            nRequiredSize += 4 * nParts;
        }
        if (nRequiredSize > nBytes)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nPoints=%d, nParts=%d, nBytes=%d, nSHPType=%d",
                     nPoints, nParts, nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

        panPartStart = (GInt32 *) VSICalloc(nParts,sizeof(GInt32));
        if (panPartStart == NULL)
        {
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Copy out the part array from the record.                        */
/* -------------------------------------------------------------------- */
	memcpy( panPartStart, pabyShape + 44, 4 * nParts );
	for( i = 0; i < nParts; i++ )
	{
            CPL_LSBPTR32( panPartStart + i );

            /* We check that the offset is inside the vertex array */
            if (panPartStart[i] < 0 ||
                panPartStart[i] >= nPoints)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, nPoints = %d",
                         i, panPartStart[i], nPoints); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
            if (i > 0 && panPartStart[i] <= panPartStart[i-1])
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, panPartStart[%d] = %d",
                         i, panPartStart[i], i - 1, panPartStart[i - 1]); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
	}

	nOffset = 44 + 4*nParts;

/* -------------------------------------------------------------------- */
/*      If this is a multipatch, we will also have parts types.  For    */
/*      now we ignore and skip past them.                               */
/* -------------------------------------------------------------------- */
        if( bIsMultiPatch )
            nOffset += 4*nParts;
        
/* -------------------------------------------------------------------- */
/*      Copy out the vertices from the record.                          */
/* -------------------------------------------------------------------- */
        double *padfX = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfY = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfZ = (double *) VSICalloc(sizeof(double),nPoints);
        if (padfX == NULL || padfY == NULL || padfZ == NULL)
        {
            CPLFree( panPartStart );
            CPLFree( padfX );
            CPLFree( padfY );
            CPLFree( padfZ );
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(padfX + i, pabyShape + nOffset + i * 16, 8 );
	    memcpy(padfY + i, pabyShape + nOffset + i * 16 + 8, 8 );
            CPL_LSBPTR64( padfX + i );
            CPL_LSBPTR64( padfY + i );
	}

        nOffset += 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( bHasZ )
        {
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( padfZ + i, pabyShape + nOffset + 16 + i*8, 8 );
                CPL_LSBPTR64( padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      Build corresponding OGR objects.                                */
/* -------------------------------------------------------------------- */
        if(    nSHPType == SHPT_ARC 
            || nSHPType == SHPT_ARCZ
            || nSHPType == SHPT_ARCM
            || nSHPType == SHPT_ARCZM )
        {
/* -------------------------------------------------------------------- */
/*      Arc - As LineString                                             */
/* -------------------------------------------------------------------- */
            if( nParts == 1 )
            {
                OGRLineString *poLine = new OGRLineString();
                *ppoGeom = poLine;

                poLine->setPoints( nPoints, padfX, padfY, padfZ );
            }

/* -------------------------------------------------------------------- */
/*      Arc - As MultiLineString                                        */
/* -------------------------------------------------------------------- */
            else
            {
                OGRMultiLineString *poMulti = new OGRMultiLineString;
                *ppoGeom = poMulti;

                for( i = 0; i < nParts; i++ )
                {
                    OGRLineString *poLine = new OGRLineString;
                    int nVerticesInThisPart;

                    if( i == nParts-1 )
                        nVerticesInThisPart = nPoints - panPartStart[i];
                    else
                        nVerticesInThisPart = 
                            panPartStart[i+1] - panPartStart[i];

                    poLine->setPoints( nVerticesInThisPart, 
                                       padfX + panPartStart[i], 
                                       padfY + panPartStart[i], 
                                       padfZ + panPartStart[i] );

                    poMulti->addGeometryDirectly( poLine );
                }
            }
        } /* ARC */

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
        else if(    nSHPType == SHPT_POLYGON
                 || nSHPType == SHPT_POLYGONZ
                 || nSHPType == SHPT_POLYGONM
                 || nSHPType == SHPT_POLYGONZM )
        {
            OGRPolygon *poMulti = new OGRPolygon;
            *ppoGeom = poMulti;

            for( i = 0; i < nParts; i++ )
            {
                OGRLinearRing *poRing = new OGRLinearRing;
                int nVerticesInThisPart;

                if( i == nParts-1 )
                    nVerticesInThisPart = nPoints - panPartStart[i];
                else
                    nVerticesInThisPart = 
                        panPartStart[i+1] - panPartStart[i];

                poRing->setPoints( nVerticesInThisPart, 
                                   padfX + panPartStart[i], 
                                   padfY + panPartStart[i], 
                                   padfZ + panPartStart[i] );

                poMulti->addRingDirectly( poRing );
            }
        } /* polygon */

/* -------------------------------------------------------------------- */
/*      Multipatch                                                      */
/* -------------------------------------------------------------------- */
        else if( bIsMultiPatch )
        {
            /* return to this later */
        } 

        CPLFree( panPartStart );
        CPLFree( padfX );
        CPLFree( padfY );
        CPLFree( padfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

/* ==================================================================== */
/*  Extract vertices for a MultiPoint.					*/
/* ==================================================================== */
    else if(    nSHPType == SHPT_MULTIPOINT
             || nSHPType == SHPT_MULTIPOINTM
             || nSHPType == SHPT_MULTIPOINTZ
             || nSHPType == SHPT_MULTIPOINTZM )
    {
#ifdef notdef
	int32		nPoints;
	int    		i, nOffset;

	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
	if( bBigEndian ) SwapWord( 4, &nPoints );

	psShape->nVertices = nPoints;
        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
        psShape->padfM = (double *) calloc(nPoints,sizeof(double));

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );

	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
	}

        nOffset = 48 + 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*	Get the X/Y bounds.						*/
/* -------------------------------------------------------------------- */
        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );

	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );

/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( psShape->nSHPType == SHPT_MULTIPOINTZ || psShape->nSHPType == SHPT_MULTIPOINTZM )
        {
            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfZ + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      If we have a M measure value, then read it now.  We assume      */
/*      that the measure can be present for any shape if the size is    */
/*      big enough, but really it will only occur for the Z shapes      */
/*      (options), and the M shapes.                                    */
/* -------------------------------------------------------------------- */
        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
        {
            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfM + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
            }
        }
#endif
    }

/* ==================================================================== */
/*      Extract vertices for a point.                                   */
/* ==================================================================== */
    else if(    nSHPType == SHPT_POINT
             || nSHPType == SHPT_POINTM
             || nSHPType == SHPT_POINTZ
             || nSHPType == SHPT_POINTZM )
    {
        int	nOffset;
        double  dfX, dfY, dfZ = 0;

        int bHasZ = (nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM);

        if (nBytes < 4 + 8 + 8 + ((nSHPType == SHPT_POINTZ) ? 8 : 0))
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }
        
	memcpy( &dfX, pabyShape + 4, 8 );
	memcpy( &dfY, pabyShape + 4 + 8, 8 );

        CPL_LSBPTR64( &dfX );
        CPL_LSBPTR64( &dfY );
        nOffset = 20 + 8;
        
        if( bHasZ )
        {
            memcpy( &dfZ, pabyShape + 4 + 16, 8 );
            CPL_LSBPTR64( &dfZ );
        }

        *ppoGeom = new OGRPoint( dfX, dfY, dfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

    char* pszHex = CPLBinaryToHex( nBytes, pabyShape );
    CPLDebug( "PGEO", "Unsupported geometry type:%d\nnBytes=%d, hex=%s",
              nSHPType, nBytes, pszHex );
    CPLFree(pszHex);

    return OGRERR_FAILURE;
}
Beispiel #11
0
static int
SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, double *padfBoundsMax,
                       int **ppanResultBuffer, int *pnBufferMax, 
                       int *pnResultCount, int bNeedSwap, int nRecLevel )

{
    unsigned int i;
    unsigned int offset;
    unsigned int numshapes, numsubnodes;
    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];
    int nFReadAcc;

/* -------------------------------------------------------------------- */
/*      Read and unswap first part of node info.                        */
/* -------------------------------------------------------------------- */
    nFReadAcc = (int)hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX );
    if ( bNeedSwap ) SwapWord ( 4, &offset );

    nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX );
    nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX );
    if ( bNeedSwap )
    {
        SwapWord( 8, adfNodeBoundsMin + 0 );
        SwapWord( 8, adfNodeBoundsMin + 1 );
        SwapWord( 8, adfNodeBoundsMax + 0 );
        SwapWord( 8, adfNodeBoundsMax + 1 );
    }
      
    nFReadAcc += (int)hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX );
    if ( bNeedSwap ) SwapWord ( 4, &numshapes );

    /* Check that we could read all previous values */
    if( nFReadAcc != 1 + 2 + 2 + 1 )
    {
        hDiskTree->sHooks.Error("I/O error");
        return FALSE;
    }

    /* Sanity checks to avoid int overflows in later computation */
    if( offset > INT_MAX - sizeof(int) )
    {
        hDiskTree->sHooks.Error("Invalid value for offset");
        return FALSE;
    }

    if( numshapes > (INT_MAX - offset - sizeof(int)) / sizeof(int) ||
        numshapes > INT_MAX / sizeof(int) - *pnResultCount )
    {
        hDiskTree->sHooks.Error("Invalid value for numshapes");
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      If we don't overlap this node at all, we can just fseek()       */
/*      pass this node info and all subnodes.                           */
/* -------------------------------------------------------------------- */
    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
                                padfBoundsMin, padfBoundsMax, 2 ) )
    {
        offset += numshapes*sizeof(int) + sizeof(int);
        hDiskTree->sHooks.FSeek(hDiskTree->fpQIX, offset, SEEK_CUR);
        return TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add all the shapeids at this node to our list.                  */
/* -------------------------------------------------------------------- */
    if(numshapes > 0) 
    {
        if( *pnResultCount + numshapes > *pnBufferMax )
        {
            int* pNewBuffer;

            *pnBufferMax = (*pnResultCount + numshapes + 100) * 5 / 4;

            if( *pnBufferMax > INT_MAX / sizeof(int) )
                *pnBufferMax = *pnResultCount + numshapes;

            pNewBuffer = (int *)
                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );

            if( pNewBuffer == NULL )
            {
                hDiskTree->sHooks.Error("Out of memory error");
                return FALSE;
            }

            *ppanResultBuffer = pNewBuffer;
        }

        if( hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount,
                    sizeof(int), numshapes, hDiskTree->fpQIX ) != numshapes )
        {
            hDiskTree->sHooks.Error("I/O error");
            return FALSE;
        }

        if (bNeedSwap )
        {
            for( i=0; i<numshapes; i++ )
                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
        }

        *pnResultCount += numshapes; 
    } 

/* -------------------------------------------------------------------- */
/*      Process the subnodes.                                           */
/* -------------------------------------------------------------------- */
    if( hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX ) != 1 )
    {
        hDiskTree->sHooks.Error("I/O error");
        return FALSE;
    }
    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );
    if( numsubnodes > 0 && nRecLevel == 32 )
    {
        hDiskTree->sHooks.Error("Shape tree is too deep");
        return FALSE;
    }

    for(i=0; i<numsubnodes; i++)
    {
        if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
                                    ppanResultBuffer, pnBufferMax, 
                                    pnResultCount, bNeedSwap, nRecLevel + 1 ) )
            return FALSE;
    }

    return TRUE;
}
Beispiel #12
0
void MessageByteOrderSwap(word cmsgs, Message *pmsg, bool fNative)
{
	for (; cmsgs != 0; cmsgs--, pmsg++) {
		word mid = pmsg->mid;
        if (!fNative) {
            mid = base::ByteBuffer::HostToNetWord(pmsg->mid);
        }

		pmsg->mid = SwapWord(pmsg->mid);
		pmsg->smidSender = SwapWord(pmsg->smidSender);
		pmsg->smidReceiver = SwapWord(pmsg->smidReceiver);
		pmsg->tDelivery = SwapDword(pmsg->tDelivery);

		switch (mid) {
		case kmidHit:
		case kmidNearbyAllyHit:
		case kmidDelete:
		case kmidEnemyNearby:
		case kmidPowerLowHigh:
		case kmidMoveWaitingNearby:
		case kmidBeingUpgraded:
		case kmidUpgradeComplete:
		case kmidAnimationComplete:
		case kmidBuildComplete:
		case kmidFireComplete:
		case kmidSpawnSmoke:
		case kmidGalaxiteDelivery:
		case kmidMoveAction:
		case kmidAttackAction:
		case kmidGuardAction:
		case kmidGuardVicinityAction:
		case kmidGuardAreaAction:
		case kmidHuntEnemiesAction:
		case kmidFire:
		case kmidHeal:
		case kmidPlaySfx:
			// These are only sent. If they arrive here, it's a mistake

			Assert(false, "Message %d is classified as sent only", pmsg->mid);
			break;

		default:
			// Message unknown, not classified yet

			Assert(false, "Message %d unknown, not classified yet", pmsg->mid);
			break;

		// Posted

		case kmidMineCommand:
			pmsg->MineCommand.gidTarget = SwapWord(pmsg->MineCommand.gidTarget);
			pmsg->MineCommand.wptTarget.wx = SwapWord(pmsg->MineCommand.wptTarget.wx);
			pmsg->MineCommand.wptTarget.wy = SwapWord(pmsg->MineCommand.wptTarget.wy);
			break;

		case kmidAttackCommand:
			pmsg->AttackCommand.gidTarget = SwapWord(pmsg->AttackCommand.gidTarget);
			pmsg->AttackCommand.wptTarget.wx = SwapWord(pmsg->AttackCommand.wptTarget.wx);
			pmsg->AttackCommand.wptTarget.wy = SwapWord(pmsg->AttackCommand.wptTarget.wy);
			pmsg->AttackCommand.wptTargetCenter.wx = SwapWord(pmsg->AttackCommand.wptTargetCenter.wx);
			pmsg->AttackCommand.wptTargetCenter.wy = SwapWord(pmsg->AttackCommand.wptTargetCenter.wy);
			pmsg->AttackCommand.tcTargetRadius = SwapWord(pmsg->AttackCommand.tcTargetRadius);
			pmsg->AttackCommand.wcMoveDistPerUpdate = SwapWord(pmsg->AttackCommand.wcMoveDistPerUpdate);
			break;

		case kmidMoveCommand:
			pmsg->MoveCommand.gidTarget = SwapWord(pmsg->MoveCommand.gidTarget);
			pmsg->MoveCommand.wptTarget.wx = SwapWord(pmsg->MoveCommand.wptTarget.wx);
			pmsg->MoveCommand.wptTarget.wy = SwapWord(pmsg->MoveCommand.wptTarget.wy);
			pmsg->MoveCommand.wptTargetCenter.wx = SwapWord(pmsg->MoveCommand.wptTargetCenter.wx);
			pmsg->MoveCommand.wptTargetCenter.wy = SwapWord(pmsg->MoveCommand.wptTargetCenter.wy);
			pmsg->MoveCommand.tcTargetRadius = SwapWord(pmsg->MoveCommand.tcTargetRadius);
			pmsg->MoveCommand.wcMoveDistPerUpdate = SwapWord(pmsg->MoveCommand.wcMoveDistPerUpdate);
			break;

		case kmidBuildOtherCommand:
			pmsg->BuildOtherCommand.ut = SwapWord(pmsg->BuildOtherCommand.ut);
			pmsg->BuildOtherCommand.wpt.wx = SwapWord(pmsg->BuildOtherCommand.wpt.wx);
			pmsg->BuildOtherCommand.wpt.wy = SwapWord(pmsg->BuildOtherCommand.wpt.wy);
			break;

		case kmidAbortBuildOtherCommand:
			pmsg->AbortBuildOtherCommand.ut = SwapWord(pmsg->AbortBuildOtherCommand.ut);
			break;

		case kmidUpgradeCommand:
			pmsg->UpgradeCommand.wfUpgrade = SwapWord(pmsg->UpgradeCommand.wfUpgrade);
			break;

		case kmidDeliverCommand:
			pmsg->DeliverCommand.gidTarget = SwapWord(pmsg->DeliverCommand.gidTarget);
			break;

		case kmidTransformCommand:
		case kmidSelfDestructCommand:
		case kmidRepairCommand:
		case kmidAbortUpgradeCommand:
			// No parameters
			break;

        case kmidPlayerDisconnect:
            pmsg->PlayerDisconnect.pid = SwapWord(pmsg->PlayerDisconnect.pid);
            pmsg->PlayerDisconnect.nReason =
                    SwapWord(pmsg->PlayerDisconnect.nReason);
            break;
		}
	}
}
Beispiel #13
0
void NetMessageByteOrderSwap(NetMessage *pnm, bool fNative)
{
	// Swap endian order

    word nmid;
    if (fNative) {
        nmid = pnm->nmid;
    } else {
        nmid = SwapWord(pnm->nmid);
    }

	pnm->nmid = SwapWord(pnm->nmid);
	pnm->cb = SwapWord(pnm->cb);

	switch (nmid) {
	case knmidCsPlayerJoin:
	case knmidCsClientReady:
	case knmidScCantAcceptMoreConnections:
	case knmidScServerInfo:
	case knmidCsConnect:
    case knmidCsRequestBeginGame:
    case knmidScBeginGameFail:
    case knmidCsLagAcknowledge:
    case knmidCsChallengeWin:
		// Nothing to do for these

		break;

    case knmidCsWinStats:
        {
            WinStatsNetMessage *pwsnm = (WinStatsNetMessage *)pnm;
            pwsnm->ws.cCreditsAcquired = SwapDword(pwsnm->ws.cCreditsAcquired);
            pwsnm->ws.cCreditsConsumed = SwapDword(pwsnm->ws.cCreditsConsumed);
            pwsnm->ws.sidm = SwapWord(pwsnm->ws.sidm);
            pwsnm->ws.sidmAllies = SwapWord(pwsnm->ws.sidmAllies);
            pwsnm->ws.cEnemyMobileUnitsKilled =
                    SwapWord(pwsnm->ws.cEnemyMobileUnitsKilled);
            pwsnm->ws.cEnemyStructuresKilled =
                    SwapWord(pwsnm->ws.cEnemyStructuresKilled);
            pwsnm->ws.cMobileUnitsLost = SwapWord(pwsnm->ws.cMobileUnitsLost);
            pwsnm->ws.cStructuresLost = SwapWord(pwsnm->ws.cStructuresLost);
            pwsnm->ws.ff = SwapWord(pwsnm->ws.ff);
            for (int i = 0; i < ARRAYSIZE(pwsnm->ws.acut); i++) {
                pwsnm->ws.acut[i] = SwapWord(pwsnm->ws.acut[i]);
            }
            for (int i = 0; i < ARRAYSIZE(pwsnm->ws.acutBuilt); i++) {
                pwsnm->ws.acutBuilt[i] = SwapWord(pwsnm->ws.acutBuilt[i]);
            }
        }
        break;

    case knmidScCheckWin:
        {
            CheckWinNetMessage *pcwnm = (CheckWinNetMessage *)pnm;
            pcwnm->pid = SwapWord(pcwnm->pid);
        }
        break;

	case knmidScGameParams:
		{
			GameParamsNetMessage *pgpnm = (GameParamsNetMessage *)pnm;
            SwapGameParams(&pgpnm->rams);
		}
		break;

	case knmidScBeginGame:
		{
			BeginGameNetMessage *pbgnm = (BeginGameNetMessage *)pnm;
			pbgnm->ulRandomSeed = SwapDword(pbgnm->ulRandomSeed);
		}
		break;

	case knmidScPlayersUpdate:
		{
			PlayersUpdateNetMessage *punm = (PlayersUpdateNetMessage *)pnm;
			int cplrr = fNative ? punm->cplrr : SwapWord(punm->cplrr);
			punm->cplrr = SwapWord(punm->cplrr);
			for (int iplrr = 0; iplrr < cplrr; iplrr++) {
				PlayerRecord *pplrr = &punm->aplrr[iplrr];
				pplrr->pid = SwapWord(pplrr->pid);
				pplrr->side = SwapWord(pplrr->side);
                pplrr->wf = SwapWord(pplrr->wf);
			}
		}
		break;

	case knmidCsClientCommands:
		{
			ClientCommandsNetMessage *pccnm = (ClientCommandsNetMessage *)pnm;
			MessageByteOrderSwap(fNative ? pccnm->cmsgCommands : SwapWord(pccnm->cmsgCommands), pccnm->amsgCommands, fNative);
			pccnm->cmsgCommands = SwapWord(pccnm->cmsgCommands);
		}
		break;

	case knmidScUpdate:
		{
			UpdateNetMessage *punm = (UpdateNetMessage *)pnm;
			MessageByteOrderSwap(fNative ? punm->cmsgCommands : SwapWord(punm->cmsgCommands), punm->amsgCommands, fNative);
			punm->cmsgCommands = SwapWord(punm->cmsgCommands);
			punm->cUpdatesBlock = SwapDword(punm->cUpdatesBlock);
			punm->cUpdatesSync = SwapDword(punm->cUpdatesSync);
		}
		break;

	case knmidCsUpdateResult:
		{
			UpdateResultNetMessage *purnm = (UpdateResultNetMessage *)pnm;
			purnm->ur.cUpdatesBlock = SwapDword(purnm->ur.cUpdatesBlock);
			purnm->ur.hash = SwapDword(purnm->ur.hash);
			purnm->ur.cmsLatency = SwapDword(purnm->ur.cmsLatency);
		}
		break;

	case knmidScLagNotify:
		{
			LagNotifyNetMessage *plnnm = (LagNotifyNetMessage *)pnm;
			plnnm->pidLagging = SwapWord(plnnm->pidLagging);
			plnnm->cSeconds = SwapWord(plnnm->cSeconds);
		}
		break;

	case knmidScPlayerDisconnect:
		{
			PlayerDisconnectNetMessage *ppdnm = (PlayerDisconnectNetMessage *)pnm;
			ppdnm->pid = SwapWord(ppdnm->pid);
			ppdnm->nReason = SwapWord(ppdnm->nReason);
		}
		break;

    case knmidCsKillLaggingPlayer:
        {
            KillLaggingPlayerNetMessage *pklpnm =
                    (KillLaggingPlayerNetMessage *)pnm;
            pklpnm->pid = SwapWord(pklpnm->pid);
            pklpnm->fYes = SwapWord(pklpnm->fYes);
        }
        break;

	case knmidCsPlayerResign:
		{
			PlayerResignNetMessage *pprnm = (PlayerResignNetMessage *)pnm;
			pprnm->pid = SwapWord(pprnm->pid);
		}
		break;

    case knmidScSyncError:
        {
            SyncErrorNetMessage *psenm = (SyncErrorNetMessage *)pnm;
            for (int i = 0; i < kcPlayersMax; i++) {
                psenm->aur[i].cUpdatesBlock =
                        SwapDword(psenm->aur[i].cUpdatesBlock);
                psenm->aur[i].hash = SwapDword(psenm->aur[i].hash);
                psenm->aur[i].cmsLatency =
                        SwapDword(psenm->aur[i].cmsLatency);
            }
            psenm->urLastStraw.cUpdatesBlock =
                    SwapDword(psenm->urLastStraw.cUpdatesBlock);
            psenm->urLastStraw.hash = SwapDword(psenm->urLastStraw.hash);
            psenm->urLastStraw.cmsLatency =
                    SwapDword(psenm->urLastStraw.cmsLatency);
        }
        break;

	default:
		Assert("Unhandled knmid! (%d)", nmid);
		break;
	}
}
Beispiel #14
0
////////////////////////////////////////////////////////////////////////////
//
// LoadLIBShape()
//
id0_int_t LoadLIBShape(const id0_char_t *SLIB_Filename, const id0_char_t *Filename,struct Shape *SHP)
{
	#define CHUNK(Name)	(*ptr == *Name) &&			\
								(*(ptr+1) == *(Name+1)) &&	\
								(*(ptr+2) == *(Name+2)) &&	\
								(*(ptr+3) == *(Name+3))


	id0_int_t RT_CODE;
	//FILE *fp;
	//id0_char_t CHUNK[5];
	id0_char_t id0_far *ptr;
	memptr IFFfile = NULL;
	id0_unsigned_long_t FileLen, size, ChunkLen;
	//id0_int_t loop;


	RT_CODE = 1;

	// Decompress to ram and return ptr to data and return len of data in
	//	passed variable...

	if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))
		Quit("Error Loading Compressed lib shape!");

	// Evaluate the file
	//
	ptr = (id0_char_t *)IFFfile;
	//ptr = MK_FP(IFFfile,0);
	if (!CHUNK("FORM"))
		goto EXIT_FUNC;
	ptr += 4;

    memcpy(&FileLen, ptr, sizeof(id0_unsigned_long_t));
    FileLen = BE_Cross_Swap32BE(FileLen);
	//FileLen = *(id0_long_t id0_far *)ptr;
	//SwapLong((id0_long_t id0_far *)&FileLen);
	ptr += 4;

	if (!CHUNK("ILBM"))
		goto EXIT_FUNC;
	ptr += 4;

	FileLen += 4;
	while (FileLen)
	{
        memcpy(&ChunkLen, (ptr+4), sizeof(id0_long_t));
        ChunkLen = BE_Cross_Swap32BE(ChunkLen);
		//ChunkLen = *(id0_long_t id0_far *)(ptr+4);
		//SwapLong((id0_long_t id0_far *)&ChunkLen);
		ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;

		if (CHUNK("BMHD"))
		{
			ptr += 8;
			SHP->bmHdr.w = BE_Cross_Swap16BE(((struct BitMapHeader id0_far *)ptr)->w);
			SHP->bmHdr.h = BE_Cross_Swap16BE(((struct BitMapHeader id0_far *)ptr)->h);
			SHP->bmHdr.x = BE_Cross_Swap16BE(((struct BitMapHeader id0_far *)ptr)->x);
			SHP->bmHdr.y = BE_Cross_Swap16BE(((struct BitMapHeader id0_far *)ptr)->y);
#if 0
			SHP->bmHdr.w = ((struct BitMapHeader id0_far *)ptr)->w;
			SHP->bmHdr.h = ((struct BitMapHeader id0_far *)ptr)->h;
			SHP->bmHdr.x = ((struct BitMapHeader id0_far *)ptr)->x;
			SHP->bmHdr.y = ((struct BitMapHeader id0_far *)ptr)->y;
#endif
			SHP->bmHdr.d = ((struct BitMapHeader id0_far *)ptr)->d;
			SHP->bmHdr.trans = ((struct BitMapHeader id0_far *)ptr)->trans;
			SHP->bmHdr.comp = ((struct BitMapHeader id0_far *)ptr)->comp;
			SHP->bmHdr.pad = ((struct BitMapHeader id0_far *)ptr)->pad;
#if 0
			SwapWord(&SHP->bmHdr.w);
			SwapWord(&SHP->bmHdr.h);
			SwapWord(&SHP->bmHdr.x);
			SwapWord(&SHP->bmHdr.y);
#endif
			ptr += ChunkLen;
		}
		else
		if (CHUNK("BODY"))
		{
			ptr += 4;
            memcpy(&size, ptr, sizeof(id0_long_t));
            size = BE_Cross_Swap32BE(size);
			//size = *((id0_long_t id0_far *)ptr);
			ptr += 4;
			//SwapLong((id0_long_t id0_far *)&size);
			SHP->BPR = (SHP->bmHdr.w+7) >> 3;
			MM_GetPtr(&SHP->Data,size);
			if (!SHP->Data)
				goto EXIT_FUNC;
			//movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
			memcpy(SHP->Data,ptr,size);
			ptr += ChunkLen;

			break;
		}
		else
Beispiel #15
0
int msWriteTree(treeObj *tree, char *filename, int B_order)
{
  char    signature[3] = "SQT";
  char    version = 1;
  char    reserved[3] = {0,0,0};
  SHPTreeHandle disktree;
  int   i;
  char    mtBigEndian;
  char    pabyBuf[32];
  char    *pszBasename, *pszFullname;


  disktree = (SHPTreeHandle) malloc(sizeof(SHPTreeInfo));
  MS_CHECK_ALLOC(disktree, sizeof(SHPTreeInfo), MS_FALSE);

  /* -------------------------------------------------------------------- */
  /*  Compute the base (layer) name.  If there is any extension     */
  /*  on the passed in filename we will strip it off.         */
  /* -------------------------------------------------------------------- */
  pszBasename = (char *) msSmallMalloc(strlen(filename)+5);
  strcpy( pszBasename, filename );
  for( i = strlen(pszBasename)-1;
       i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
       && pszBasename[i] != '\\';
       i-- ) {}

  if( pszBasename[i] == '.' )
    pszBasename[i] = '\0';

  /* -------------------------------------------------------------------- */
  /*  Open the .shp and .shx files.  Note that files pulled from      */
  /*  a PC to Unix with upper case filenames won't work!        */
  /* -------------------------------------------------------------------- */
  pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5);
  sprintf( pszFullname, "%s%s", pszBasename, MS_INDEX_EXTENSION);
  disktree->fp = fopen(pszFullname, "wb");

  msFree(pszBasename); /* not needed */
  msFree(pszFullname);

  if(!disktree->fp) {
    msFree(disktree);
    msSetError(MS_IOERR, NULL, "msWriteTree()");
    return(MS_FALSE);
  }


  /* for efficiency, trim the tree */
  msTreeTrim(tree);

  /* -------------------------------------------------------------------- */
  /*  Establish the byte order on this machine.         */
  /* -------------------------------------------------------------------- */
  i = 1;
  if( *((uchar *) &i) == 1 )
    mtBigEndian = MS_FALSE;
  else
    mtBigEndian = MS_TRUE;

  if( !(mtBigEndian ^ ( B_order == MS_LSB_ORDER || B_order == MS_NEW_LSB_ORDER )) )
    disktree->needswap = 1;
  else
    disktree->needswap = 0;

  if( B_order == MS_NATIVE_ORDER )
    disktree->needswap = 0;

  /* write the header */
  if ( B_order > 0 ) {
    memcpy( pabyBuf, &signature, 3 );
    memcpy (&disktree->signature, &signature, 3);
    pabyBuf[3] = B_order;

    memcpy( pabyBuf+4, &version, 1);
    memcpy( pabyBuf+5, &reserved, 3);

    memcpy( &disktree->version, &version, 1);
    memcpy( &disktree->flags, &reserved, 3);

    fwrite( pabyBuf, 8, 1, disktree->fp );
  }

  memcpy( pabyBuf, &tree->numshapes, 4 );
  if( disktree->needswap ) SwapWord( 4, pabyBuf );

  memcpy( pabyBuf+4, &tree->maxdepth, 4 );
  if( disktree->needswap ) SwapWord( 4, pabyBuf+4 );

  i = fwrite( pabyBuf, 8, 1, disktree->fp );
  if( !i ) {
    fprintf (stderr, "unable to write to index file ... exiting \n");
    msSHPDiskTreeClose( disktree );
    return (MS_FALSE);
  }

  writeTreeNode(disktree, tree->root);

  msSHPDiskTreeClose( disktree );

  return(MS_TRUE);
}
Beispiel #16
0
SBNSearchHandle SBNOpenDiskTree( const char* pszSBNFilename,
                                 SAHooks *psHooks )
{
    int i;
    SBNSearchHandle hSBN;
    uchar abyHeader[108];
    int nShapeCount;
    int nMaxDepth;
    int nMaxNodes;
    int nNodeDescSize;
    int nNodeDescCount;
    uchar* pabyData = NULL;
    SBNNodeDescriptor* pasNodeDescriptor = NULL;
    uchar abyBinHeader[8];
    int nCurNode;
    int nNextNonEmptyNode;
    int nExpectedBinId;
    int bBigEndian;

    /* -------------------------------------------------------------------- */
    /*  Establish the byte order on this machine.                           */
    /* -------------------------------------------------------------------- */
    i = 1;
    if( *((unsigned char *) &i) == 1 )
        bBigEndian = FALSE;
    else
        bBigEndian = TRUE;

    /* -------------------------------------------------------------------- */
    /*      Initialize the handle structure.                                */
    /* -------------------------------------------------------------------- */
    hSBN = (SBNSearchHandle)
           calloc(sizeof(struct SBNSearchInfo),1);

    if (psHooks == NULL)
        SASetupDefaultHooks( &(hSBN->sHooks) );
    else
        memcpy( &(hSBN->sHooks), psHooks, sizeof(SAHooks) );

    hSBN->fpSBN = hSBN->sHooks.FOpen(pszSBNFilename, "rb");
    if (hSBN->fpSBN == NULL)
    {
        free(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Check file header signature.                                    */
    /* -------------------------------------------------------------------- */
    if (hSBN->sHooks.FRead(abyHeader, 108, 1, hSBN->fpSBN) != 1 ||
            abyHeader[0] != 0 ||
            abyHeader[1] != 0 ||
            abyHeader[2] != 0x27 ||
            (abyHeader[3] != 0x0A && abyHeader[3] != 0x0D) ||
            abyHeader[4] != 0xFF ||
            abyHeader[5] != 0xFF ||
            abyHeader[6] != 0xFE ||
            abyHeader[7] != 0x70)
    {
        hSBN->sHooks.Error( ".sbn file is unreadable, or corrupt." );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Read shapes bounding box.                                       */
    /* -------------------------------------------------------------------- */

    memcpy(&hSBN->dfMinX, abyHeader + 32, 8);
    memcpy(&hSBN->dfMinY, abyHeader + 40, 8);
    memcpy(&hSBN->dfMaxX, abyHeader + 48, 8);
    memcpy(&hSBN->dfMaxY, abyHeader + 56, 8);

    if( !bBigEndian )
    {
        SwapWord(8, &hSBN->dfMinX);
        SwapWord(8, &hSBN->dfMinY);
        SwapWord(8, &hSBN->dfMaxX);
        SwapWord(8, &hSBN->dfMaxY);
    }

    if( hSBN->dfMinX > hSBN->dfMaxX ||
            hSBN->dfMinY > hSBN->dfMaxY )
    {
        hSBN->sHooks.Error( "Invalid extent in .sbn file." );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Read and check number of shapes.                                */
    /* -------------------------------------------------------------------- */
    nShapeCount = READ_MSB_INT(abyHeader + 28);
    hSBN->nShapeCount = nShapeCount;
    if (nShapeCount < 0 || nShapeCount > 256000000 )
    {
        char szErrorMsg[64];
        sprintf(szErrorMsg, "Invalid shape count in .sbn : %d", nShapeCount );
        hSBN->sHooks.Error( szErrorMsg );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Compute tree depth.                                             */
    /*      It is computed such as in average there are not more than 8     */
    /*      shapes per node. With a minimum depth of 2, and a maximum of 15 */
    /* -------------------------------------------------------------------- */
    nMaxDepth = 2;
    while( nMaxDepth < 15 && nShapeCount > ((1 << nMaxDepth) - 1) * 8 )
        nMaxDepth ++;
    hSBN->nMaxDepth = nMaxDepth;
    nMaxNodes = (1 << nMaxDepth) - 1;

    /* -------------------------------------------------------------------- */
    /*      Check that the first bin id is 1.                               */
    /* -------------------------------------------------------------------- */

    if( READ_MSB_INT(abyHeader + 100) != 1 )
    {
        hSBN->sHooks.Error( "Unexpected bin id" );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Read and check number of node descriptors to be read.           */
    /*      There are at most (2^nMaxDepth) - 1, but all are not necessary  */
    /*      described. Non described nodes are empty.                       */
    /* -------------------------------------------------------------------- */
    nNodeDescSize = READ_MSB_INT(abyHeader + 104);
    nNodeDescSize *= 2; /* 16-bit words */

    /* each bin descriptor is made of 2 ints */
    nNodeDescCount = nNodeDescSize / 8;

    if ((nNodeDescSize % 8) != 0 ||
            nNodeDescCount < 0 || nNodeDescCount > nMaxNodes )
    {
        char szErrorMsg[64];
        sprintf(szErrorMsg,
                "Invalid node descriptor size in .sbn : %d", nNodeDescSize );
        hSBN->sHooks.Error( szErrorMsg );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    pabyData = (uchar*) malloc( nNodeDescSize );
    pasNodeDescriptor = (SBNNodeDescriptor*)
                        calloc ( nMaxNodes, sizeof(SBNNodeDescriptor) );
    if (pabyData == NULL || pasNodeDescriptor == NULL)
    {
        free(pabyData);
        free(pasNodeDescriptor);
        hSBN->sHooks.Error( "Out of memory error" );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Read node descriptors.                                          */
    /* -------------------------------------------------------------------- */
    if (hSBN->sHooks.FRead(pabyData, nNodeDescSize, 1,
                           hSBN->fpSBN) != 1)
    {
        free(pabyData);
        free(pasNodeDescriptor);
        hSBN->sHooks.Error( "Cannot read node descriptors" );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    hSBN->pasNodeDescriptor = pasNodeDescriptor;

    for(i = 0; i < nNodeDescCount; i++)
    {
        /* -------------------------------------------------------------------- */
        /*      Each node descriptor contains the index of the first bin that   */
        /*      described it, and the number of shapes in this first bin and    */
        /*      the following bins (in the relevant case).                      */
        /* -------------------------------------------------------------------- */
        int nBinStart = READ_MSB_INT(pabyData + 8 * i);
        int nNodeShapeCount = READ_MSB_INT(pabyData + 8 * i + 4);
        pasNodeDescriptor[i].nBinStart = nBinStart > 0 ? nBinStart : 0;
        pasNodeDescriptor[i].nShapeCount = nNodeShapeCount;

        if ((nBinStart > 0 && nNodeShapeCount == 0) ||
                nNodeShapeCount < 0 || nNodeShapeCount > nShapeCount)
        {
            hSBN->sHooks.Error( "Inconsistant shape count in bin" );
            SBNCloseDiskTree(hSBN);
            return NULL;
        }
    }

    free(pabyData);
    pabyData = NULL;

    /* Locate first non-empty node */
    nCurNode = 0;
    while(nCurNode < nMaxNodes && pasNodeDescriptor[nCurNode].nBinStart <= 0)
        nCurNode ++;

    if( nCurNode >= nMaxNodes)
    {
        hSBN->sHooks.Error( "All nodes are empty" );
        SBNCloseDiskTree(hSBN);
        return NULL;
    }

    pasNodeDescriptor[nCurNode].nBinOffset =
        hSBN->sHooks.FTell(hSBN->fpSBN);

    /* Compute the index of the next non empty node. */
    nNextNonEmptyNode = nCurNode + 1;
    while(nNextNonEmptyNode < nMaxNodes &&
            pasNodeDescriptor[nNextNonEmptyNode].nBinStart <= 0)
        nNextNonEmptyNode ++;

    nExpectedBinId = 1;

    /* -------------------------------------------------------------------- */
    /*      Traverse bins to compute the offset of the first bin of each    */
    /*      node.                                                           */
    /*      Note: we could use the .sbx file to compute the offsets instead.*/
    /* -------------------------------------------------------------------- */
    while( hSBN->sHooks.FRead(abyBinHeader, 8, 1,
                              hSBN->fpSBN) == 1 )
    {
        int nBinId;
        int nBinSize;

        nExpectedBinId ++;

        nBinId = READ_MSB_INT(abyBinHeader);
        nBinSize = READ_MSB_INT(abyBinHeader + 4);
        nBinSize *= 2; /* 16-bit words */

        if( nBinId != nExpectedBinId )
        {
            hSBN->sHooks.Error( "Unexpected bin id" );
            SBNCloseDiskTree(hSBN);
            return NULL;
        }

        /* Bins are always limited to 100 features */
        /* If there are more, then they are located in continuous bins */
        if( (nBinSize % 8) != 0 || nBinSize <= 0 || nBinSize > 100 * 8)
        {
            hSBN->sHooks.Error( "Unexpected bin size" );
            SBNCloseDiskTree(hSBN);
            return NULL;
        }

        if( nNextNonEmptyNode < nMaxNodes &&
                nBinId == pasNodeDescriptor[nNextNonEmptyNode].nBinStart )
        {
            nCurNode = nNextNonEmptyNode;
            pasNodeDescriptor[nCurNode].nBinOffset =
                hSBN->sHooks.FTell(hSBN->fpSBN) - 8;

            /* Compute the index of the next non empty node. */
            nNextNonEmptyNode = nCurNode + 1;
            while(nNextNonEmptyNode < nMaxNodes &&
                    pasNodeDescriptor[nNextNonEmptyNode].nBinStart <= 0)
                nNextNonEmptyNode ++;
        }

        pasNodeDescriptor[nCurNode].nBinCount ++;

        /* Skip shape description */
        hSBN->sHooks.FSeek(hSBN->fpSBN, nBinSize, SEEK_CUR);
    }

    return hSBN;
}
Beispiel #17
0
SHPTreeHandle msSHPDiskTreeOpen(const char * pszTree, int debug)
{
  char    *pszFullname, *pszBasename;
  SHPTreeHandle psTree;

  char    pabyBuf[16];
  int     i;
  char    bBigEndian;

  /* -------------------------------------------------------------------- */
  /*  Establish the byte order on this machine.         */
  /* -------------------------------------------------------------------- */
  i = 1;
  if( *((uchar *) &i) == 1 )
    bBigEndian = MS_FALSE;
  else
    bBigEndian = MS_TRUE;

  /* -------------------------------------------------------------------- */
  /*  Initialize the info structure.              */
  /* -------------------------------------------------------------------- */
  psTree = (SHPTreeHandle) msSmallMalloc(sizeof(SHPTreeInfo));

  /* -------------------------------------------------------------------- */
  /*  Compute the base (layer) name.  If there is any extension     */
  /*  on the passed in filename we will strip it off.         */
  /* -------------------------------------------------------------------- */
  pszBasename = (char *) msSmallMalloc(strlen(pszTree)+5);
  strcpy( pszBasename, pszTree );
  for( i = strlen(pszBasename)-1;
       i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
       && pszBasename[i] != '\\';
       i-- ) {}

  if( pszBasename[i] == '.' )
    pszBasename[i] = '\0';

  /* -------------------------------------------------------------------- */
  /*  Open the .shp and .shx files.  Note that files pulled from      */
  /*  a PC to Unix with upper case filenames won't work!        */
  /* -------------------------------------------------------------------- */
  pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5);
  sprintf( pszFullname, "%s%s", pszBasename, MS_INDEX_EXTENSION);
  psTree->fp = fopen(pszFullname, "rb" );
  if( psTree->fp == NULL ) {
      sprintf( pszFullname, "%s.QIX", pszBasename);
      psTree->fp = fopen(pszFullname, "rb" );
  }

  msFree(pszBasename); /* don't need these any more */
  msFree(pszFullname);

  if( psTree->fp == NULL ) {
    msFree(psTree);
    return( NULL );
  }

  fread( pabyBuf, 8, 1, psTree->fp );

  memcpy( &psTree->signature, pabyBuf, 3 );
  if( strncmp(psTree->signature,"SQT",3) ) {
    /* ---------------------------------------------------------------------- */
    /*     must check if the 2 first bytes equal 0 of max depth that cannot   */
    /*     be more than 65535. If yes, we must swap all value. The problem    */
    /*     here is if there's no Depth (bytea 5,6,7,8 in the file) all bytes  */
    /*     will be set to 0. So,we will test with the number of shapes (bytes */
    /*     1,2,3,4) that cannot be more than 65535 too.                       */
    /* ---------------------------------------------------------------------- */
    if (debug) {
      msDebug("WARNING in msSHPDiskTreeOpen(): %s is in old index format "
              "which has been deprecated.  It is strongly recommended to "
              "regenerate it in new format.\n", pszTree);
    }
    if((pabyBuf[4] == 0 && pabyBuf[5] == 0 &&
        pabyBuf[6] == 0 && pabyBuf[7] == 0)) {
      psTree->LSB_order = !(pabyBuf[0] == 0 && pabyBuf[1] == 0);
    } else {
      psTree->LSB_order = !(pabyBuf[4] == 0 && pabyBuf[5] == 0);
    }
    psTree->needswap = ((psTree->LSB_order) != (!bBigEndian));

    /* ---------------------------------------------------------------------- */
    /*     poor hack to see if this quadtree was created by a computer with a */
    /*     different Endian                                                   */
    /* ---------------------------------------------------------------------- */
    psTree->version = 0;
  } else {
    psTree->needswap = (( pabyBuf[3] == MS_NEW_MSB_ORDER ) ^ ( bBigEndian ));

    psTree->LSB_order = ( pabyBuf[3] == MS_NEW_LSB_ORDER );
    memcpy( &psTree->version, pabyBuf+4, 1 );
    memcpy( &psTree->flags, pabyBuf+5, 3 );

    fread( pabyBuf, 8, 1, psTree->fp );
  }

  if( psTree->needswap ) SwapWord( 4, pabyBuf );
  memcpy( &psTree->nShapes, pabyBuf, 4 );

  if( psTree->needswap ) SwapWord( 4, pabyBuf+4 );
  memcpy( &psTree->nDepth, pabyBuf+4, 4 );

  return( psTree );
}
bool eZ80AccessorSZX::SetState(xIo::eStreamMemory& is)
{
	ZXSTHEADER header;
	if(is.Read(&header, sizeof(header)) != sizeof(header))
		return false;
	if(header.dwMagic != FOURCC('Z', 'X', 'S', 'T'))
		return false;
	bool model48k = false;
	switch(header.chMachineId)
	{
	case ZXSTMID_16K:
	case ZXSTMID_48K:
	case ZXSTMID_NTSC48K:
		model48k = true;
		break;
	case ZXSTMID_128K:
	case ZXSTMID_PENTAGON128:
		break;
	default:
		return false;
	}
	SetupDevices(model48k);
	ZXSTBLOCK block;
	while(is.Read(&block, sizeof(block)) == sizeof(block))
	{
		switch(block.dwId)
		{
		case FOURCC('Z', '8', '0', 'R'):
			{
				ZXSTZ80REGS regs;
				if(!ReadBlock(is, &regs, block))
					return false;
				af = SwapWord(regs.AF);
				bc = SwapWord(regs.BC);
				de = SwapWord(regs.DE);
				hl = SwapWord(regs.HL);
				alt.af = SwapWord(regs.AF1);
				alt.bc = SwapWord(regs.BC1);
				alt.de = SwapWord(regs.DE1);
				alt.hl = SwapWord(regs.HL1);

				ix = SwapWord(regs.IX);
				iy = SwapWord(regs.IY);
				sp = SwapWord(regs.SP);
				pc = SwapWord(regs.PC);
				i = regs.I;
				r_low = regs.R;
				r_hi = regs.R & 0x80;
				im = regs.IM;
				iff1 = regs.IFF1;
				iff2 = regs.IFF2;
				t = Dword((const byte*)&regs.dwCyclesStart) % frame_tacts;
				if(regs.wMemPtr)
					memptr = SwapWord(regs.wMemPtr);
			}
			break;
		case FOURCC('S', 'P', 'C', 'R'):
			{
				ZXSTSPECREGS regs;
				if(!ReadBlock(is, &regs, block))
					return false;
				devices->IoWrite(0xfe, (regs.chFe&0x18) | regs.chBorder, t);
				devices->IoWrite(0x7ffd, model48k ? 0x30 : regs.ch7ffd, t);
				if(model48k)
					devices->Get<eMemory>()->SetRomPage(eMemory::P_ROM_48);
				else
					devices->Get<eMemory>()->SetRomPage((regs.ch7ffd & 0x10) ? eMemory::P_ROM_128_0 : eMemory::P_ROM_128_1);
			}
			break;
		case FOURCC('R', 'A', 'M', 'P'):
			{
				ZXSTRAMPAGE ram_page;
				if(!ReadBlock(is, &ram_page, block, sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1))
					return false;
				byte* buf = new byte[eMemory::PAGE_SIZE];
				bool ok = false;
				if(SwapWord(ram_page.wFlags)&ZXSTRF_COMPRESSED)
				{
#ifdef USE_ZIP
					size_t size = ram_page.blk.dwSize - (sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1);
					byte* buf_compr = new byte[size];
					ok = is.Read(buf_compr, size) == size;
					if(ok)
					{
						z_stream zs;
						memset(&zs, 0, sizeof(zs));
						zs.next_in = buf_compr;
						zs.avail_in = size;
						zs.next_out = buf;
						zs.avail_out = eMemory::PAGE_SIZE;
						ok = inflateInit2(&zs, 15) == Z_OK;
						if(ok)
							ok = inflate(&zs, Z_NO_FLUSH) == Z_STREAM_END;
						inflateEnd(&zs);
					}
					SAFE_DELETE_ARRAY(buf_compr);
#endif//USE_ZIP
				}
				else
				{
					size_t size = ram_page.blk.dwSize - (sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1);
					ok = size == eMemory::PAGE_SIZE;
					if(ok)
					{
						ok = is.Read(buf, size) == size;
					}
				}
				if(ok && ram_page.chPageNo <= 7)
				{
					memcpy(memory->Get(eMemory::P_RAM0 + ram_page.chPageNo), buf, eMemory::PAGE_SIZE);
				}
				SAFE_DELETE(buf);
				if(!ok)
					return false;
			}
			break;
		case FOURCC('A', 'Y', '\0', '\0'):
			{
				ZXSTAYBLOCK ay_state;
				if(!ReadBlock(is, &ay_state, block))
					return false;
				devices->Get<eAY>()->SetRegs(ay_state.chAyRegs);
				devices->Get<eAY>()->Select(ay_state.chCurrentRegister);
			}
			break;
		default:
			if(is.Seek(block.dwSize, xIo::eStreamMemory::S_CUR) != 0)
				return false;
		}
		if(is.Pos() == is.Size())
			return true;
	}
	return false;
}