void writeTree(FILE *file, Tree *t) { if(t == NULL) return; writeLong(file, (long)t); // first write the id of this node writeTreeNode(file, t); // write the node writeTree(file, t->left); // recursively write the left subtree writeTree(file, t->right); // recursively write the right subtree }
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; }
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); }