/* LIBDGL -- a Directed Graph Library implementation * Copyright (C) 2002 Roberto Micarelli * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * best view with tabstop=4 */ #include #include #include #include #include #include #include #define DGL_V2 1 #include "type.h" #include "tree.h" #include "graph.h" #include "graph_v1.h" #if defined(DGL_V2) #include "graph_v2.h" #endif #include "helpers.h" void dglResetStats( dglGraph_s * pgraph ) { #ifdef DGL_STATS pgraph->clkAddEdge = 0; pgraph->cAddEdge = 0; pgraph->clkNodeTree = 0; pgraph->cNodeTree = 0; #endif } int dglInitialize(dglGraph_s * pGraph, dglByte_t Version, dglInt32_t NodeAttrSize, dglInt32_t EdgeAttrSize, dglInt32_t * pOpaqueSet) { if ( pGraph == NULL ) { return -DGL_ERR_BadArgument; } switch( Version ) { case 1: #ifdef DGL_V2 case 2: case 3: #endif memset( pGraph , 0 , sizeof( dglGraph_s ) ); /* * round attr size to the upper multiple of dglInt32_t size */ if ( NodeAttrSize % sizeof(dglInt32_t) ) NodeAttrSize += ( sizeof(dglInt32_t) - (NodeAttrSize % sizeof(dglInt32_t)) ); if ( EdgeAttrSize % sizeof(dglInt32_t) ) EdgeAttrSize += ( sizeof(dglInt32_t) - (EdgeAttrSize % sizeof(dglInt32_t)) ); pGraph->Version = Version; pGraph->NodeAttrSize = NodeAttrSize; pGraph->EdgeAttrSize = EdgeAttrSize; if ( pOpaqueSet ) memcpy( & pGraph->aOpaqueSet , pOpaqueSet , sizeof( dglInt32_t ) * 16 ); #ifdef DGL_ENDIAN_BIG pGraph->Endian = DGL_ENDIAN_BIG; #else pGraph->Endian = DGL_ENDIAN_LITTLE; #endif } switch( Version ) { case 1: if ( dgl_initialize_V1(pGraph) < 0 ) { return -pGraph->iErrno; } else return 0; #ifdef DGL_V2 case 2: case 3: if ( dgl_initialize_V2(pGraph) < 0 ) { return -pGraph->iErrno; } else return 0; #endif } pGraph->iErrno = DGL_ERR_VersionNotSupported; return -pGraph->iErrno; } int dglRelease( dglGraph_s * pGraph ) { switch( pGraph->Version ) { case 1: return dgl_release_V1(pGraph); #ifdef DGL_V2 case 2: case 3: return dgl_release_V2(pGraph); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } int dglUnflatten( dglGraph_s * pGraph ) { switch( pGraph->Version ) { case 1: return dgl_unflatten_V1(pGraph); #ifdef DGL_V2 case 2: case 3: return dgl_unflatten_V2(pGraph); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } int dglFlatten( dglGraph_s * pGraph ) { switch( pGraph->Version ) { case 1: return dgl_flatten_V1(pGraph); #ifdef DGL_V2 case 2: case 3: return dgl_flatten_V2(pGraph); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } dglInt32_t * dglGetNode(dglGraph_s * pGraph , dglInt32_t nNodeId) { switch( pGraph->Version ) { case 1: return dgl_get_node_V1(pGraph, nNodeId); #ifdef DGL_V2 case 2: case 3: return dgl_get_node_V2(pGraph, nNodeId); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } dglInt32_t * dglNodeGet_OutEdgeset(dglGraph_s * pGraph, dglInt32_t * pnNode) { if ( pnNode) { switch( pGraph->Version ) { case 1: return dgl_getnode_outedgeset_V1(pGraph, pnNode); #ifdef DGL_V2 case 2: case 3: return dgl_getnode_outedgeset_V2(pGraph, pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } return NULL; } dglInt32_t * dglNodeGet_InEdgeset(dglGraph_s * pGraph, dglInt32_t * pnNode) { if ( pnNode) { switch( pGraph->Version ) { case 1: pGraph->iErrno = DGL_ERR_NotSupported; return NULL; #ifdef DGL_V2 case 2: case 3: return dgl_getnode_inedgeset_V2(pGraph, pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } return NULL; } /* * Given that node id can be negative, only iErrno can report a error, * thus it is initialized to zero */ dglInt32_t dglNodeGet_Id(dglGraph_s * pGraph, dglInt32_t * pnNode) { pGraph->iErrno = 0; if (pnNode) { switch( pGraph->Version ) { case 1: return DGL_NODE_ID_v1(pnNode); #ifdef DGL_V2 case 2: case 3: return DGL_NODE_ID_v2(pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t dglNodeGet_Status(dglGraph_s * pGraph, dglInt32_t * pnNode) { pGraph->iErrno = 0; if (pnNode) { switch( pGraph->Version ) { case 1: return DGL_NODE_STATUS_v1(pnNode); #ifdef DGL_V2 case 2: case 3: return DGL_NODE_STATUS_v2(pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t * dglNodeGet_Attr(dglGraph_s * pGraph, dglInt32_t * pnNode) { if ( pnNode) { switch( pGraph->Version ) { case 1: return DGL_NODE_ATTR_PTR_v1(pnNode); #ifdef DGL_V2 case 2: case 3: return DGL_NODE_ATTR_PTR_v2(pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return NULL; } void dglNodeSet_Attr(dglGraph_s * pGraph, dglInt32_t * pnNode, dglInt32_t * pnAttr) { if ( pnNode) { switch( pGraph->Version ) { case 1: memcpy(DGL_NODE_ATTR_PTR_v1(pnNode), pnAttr, pGraph->NodeAttrSize); return; #ifdef DGL_V2 case 2: case 3: memcpy(DGL_NODE_ATTR_PTR_v2(pnNode), pnAttr, pGraph->NodeAttrSize); return; #endif } return; } return; } int dglNodeGet_InDegree( dglGraph_s * pGraph, dglInt32_t * pnNode ) { #ifdef DGL_V2 dglInt32_t * pinedgeset; #endif pGraph->iErrno = 0; if ( pnNode) { switch( pGraph->Version ) { case 1: pGraph->iErrno = DGL_ERR_NotSupported; return 0; #ifdef DGL_V2 case 2: if ( DGL_NODE_STATUS_v2(pnNode) & DGL_NS_ALONE ) return 0; pinedgeset = dglNodeGet_InEdgeset(pGraph, pnNode); if ( pinedgeset ) return DGL_EDGESET_EDGECOUNT_v2(pinedgeset); return 0; case 3: return dglNodeGet_Valence(pGraph, pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } int dglNodeGet_OutDegree( dglGraph_s * pGraph, dglInt32_t * pnNode ) { dglInt32_t * poutedgeset; pGraph->iErrno = 0; if ( pnNode) { switch( pGraph->Version ) { case 1: if ( DGL_NODE_STATUS_v1(pnNode) & DGL_NS_ALONE ) return 0; poutedgeset = dglNodeGet_OutEdgeset(pGraph, pnNode); if ( poutedgeset ) return DGL_EDGESET_EDGECOUNT_v1(poutedgeset); return 0; #ifdef DGL_V2 case 2: if ( DGL_NODE_STATUS_v2(pnNode) & DGL_NS_ALONE ) return 0; poutedgeset = dglNodeGet_OutEdgeset(pGraph, pnNode); if ( poutedgeset ) return DGL_EDGESET_EDGECOUNT_v2(poutedgeset); return 0; case 3: return dglNodeGet_Valence(pGraph, pnNode); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } int dglNodeGet_Valence( dglGraph_s * pGraph, dglInt32_t * pnNode ) { #ifdef DGL_V2 dglInt32_t * poutedgeset; dglInt32_t * pinedgeset; int c; #endif pGraph->iErrno = 0; if ( pnNode) { switch( pGraph->Version ) { #ifdef DGL_V2 case 3: if ( DGL_NODE_STATUS_v2(pnNode) & DGL_NS_ALONE ) return 0; poutedgeset = dglNodeGet_OutEdgeset(pGraph, pnNode); pinedgeset = dglNodeGet_InEdgeset(pGraph, pnNode); c = 0; if ( poutedgeset ) c += DGL_EDGESET_EDGECOUNT_v2(poutedgeset); if ( pinedgeset ) c += DGL_EDGESET_EDGECOUNT_v2(pinedgeset); return c; #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t dglEdgesetGet_EdgeCount(dglGraph_s * pGraph, dglInt32_t * pnEdgeset) { pGraph->iErrno = 0; if ( pnEdgeset ) { switch( pGraph->Version ) { case 1: return DGL_EDGESET_EDGECOUNT_v1(pnEdgeset); #ifdef DGL_V2 case 2: case 3: return DGL_EDGESET_EDGECOUNT_v2(pnEdgeset); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t dglEdgeGet_Cost( dglGraph_s * pGraph , dglInt32_t * pnEdge ) { pGraph->iErrno = 0; if (pnEdge) { switch(pGraph->Version) { case 1: return DGL_EDGE_COST_v1(pnEdge); #ifdef DGL_V2 case 2: case 3: return DGL_EDGE_COST_v2(pnEdge); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t dglEdgeGet_Id( dglGraph_s * pGraph , dglInt32_t * pnEdge ) { pGraph->iErrno = 0; if (pnEdge) { switch(pGraph->Version) { case 1: return DGL_EDGE_ID_v1(pnEdge); #ifdef DGL_V2 case 2: case 3: return DGL_EDGE_ID_v2(pnEdge); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return 0; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return 0; } dglInt32_t * dglEdgeGet_Head( dglGraph_s * pGraph , dglInt32_t * pnEdge ) { pGraph->iErrno = 0; if (pnEdge) { switch(pGraph->Version) { case 1: if ( pGraph->Flags & DGL_GS_FLAT ) { return DGL_NODEBUFFER_SHIFT_v1(pGraph,DGL_EDGE_HEADNODE_OFFSET_v1(pnEdge)); } else { return dgl_get_node_V1(pGraph, DGL_EDGE_HEADNODE_OFFSET_v1(pnEdge)); } #ifdef DGL_V2 case 2: case 3: if ( pGraph->Flags & DGL_GS_FLAT ) { return DGL_NODEBUFFER_SHIFT_v2(pGraph,DGL_EDGE_HEADNODE_OFFSET_v2(pnEdge)); } else { return dgl_get_node_V2(pGraph, DGL_EDGE_HEADNODE_OFFSET_v2(pnEdge)); } #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return NULL; } dglInt32_t * dglEdgeGet_Tail( dglGraph_s * pGraph , dglInt32_t * pnEdge ) { pGraph->iErrno = 0; if (pnEdge) { switch(pGraph->Version) { case 1: if ( pGraph->Flags & DGL_GS_FLAT ) { return DGL_NODEBUFFER_SHIFT_v1(pGraph,DGL_EDGE_TAILNODE_OFFSET_v1(pnEdge)); } else { return dgl_get_node_V1(pGraph, DGL_EDGE_TAILNODE_OFFSET_v1(pnEdge)); } #ifdef DGL_V2 case 2: case 3: if ( pGraph->Flags & DGL_GS_FLAT ) { return DGL_NODEBUFFER_SHIFT_v2(pGraph,DGL_EDGE_TAILNODE_OFFSET_v2(pnEdge)); } else { return dgl_get_node_V2(pGraph, DGL_EDGE_TAILNODE_OFFSET_v2(pnEdge)); } #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return NULL; } dglInt32_t * dglEdgeGet_Attr( dglGraph_s * pGraph , dglInt32_t * pnEdge ) { pGraph->iErrno = 0; if (pnEdge) { switch(pGraph->Version) { case 1: return DGL_EDGE_ATTR_PTR_v1(pnEdge); #ifdef DGL_V2 case 2: case 3: return DGL_EDGE_ATTR_PTR_v2(pnEdge); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return NULL; } int dglEdgeSet_Attr( dglGraph_s * pGraph , dglInt32_t * pnAttr , dglInt32_t * pnEdge ) { if (pnEdge) { switch( pGraph->Version ) { case 1: memcpy(DGL_EDGE_ATTR_PTR_v1(pnEdge), pnAttr, pGraph->EdgeAttrSize); return 0; #ifdef DGL_V2 case 2: case 3: memcpy(DGL_EDGE_ATTR_PTR_v2(pnEdge), pnAttr, pGraph->EdgeAttrSize); return 0; #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } pGraph->iErrno = DGL_ERR_UnexpectedNullPointer; return -pGraph->iErrno; } dglInt32_t * dglGetEdge( dglGraph_s * pGraph , dglInt32_t nEdgeId ) { switch( pGraph->Version ) { case 1: return dgl_get_edge_V1(pGraph, nEdgeId ); break; #ifdef DGL_V2 case 2: case 3: return dgl_get_edge_V2(pGraph, nEdgeId ); break; #endif } pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } int dglDelEdge( dglGraph_s * pGraph , dglInt32_t nEdgeId ) { switch( pGraph->Version ) { case 1: return dgl_del_edge_V1(pGraph, nEdgeId ); break; #ifdef DGL_V2 case 2: case 3: return dgl_del_edge_V2(pGraph, nEdgeId ); break; #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } int dglAddEdge( dglGraph_s * pGraph , dglInt32_t nHead , dglInt32_t nTail , dglInt32_t nCost , dglInt32_t nEdge ) { int nRet; #ifdef DGL_STATS clock_t clk; clk = clock(); pGraph->cAddEdge ++; #endif switch( pGraph->Version ) { case 1: nRet = dgl_add_edge_V1(pGraph, nHead, nTail, nCost, nEdge, NULL, NULL, NULL, 0); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_add_edge_V2(pGraph, nHead, nTail, nCost, nEdge, NULL, NULL, NULL, 0); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } #ifdef DGL_STATS pGraph->clkAddEdge += clock() - clk; #endif return nRet; } int dglAddEdgeX ( dglGraph_s * pGraph , dglInt32_t nHead , dglInt32_t nTail , dglInt32_t nCost , dglInt32_t nEdge , void * pvHeadAttr , void * pvTailAttr , void * pvEdgeAttr , dglInt32_t nFlags ) { int nRet; #ifdef DGL_STATS clock_t clk; clk = clock(); pGraph->cAddEdge ++; #endif switch( pGraph->Version ) { case 1: nRet = dgl_add_edge_V1(pGraph, nHead, nTail, nCost, nEdge, pvHeadAttr, pvTailAttr, pvEdgeAttr, nFlags); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_add_edge_V2(pGraph, nHead, nTail, nCost, nEdge, pvHeadAttr, pvTailAttr, pvEdgeAttr, nFlags); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } #ifdef DGL_STATS pGraph->clkAddEdge += clock() - clk; #endif return nRet; } int dglAddNode( dglGraph_s * pGraph , dglInt32_t nNodeId , void * pvNodeAttr , dglInt32_t nFlags ) { int nRet; switch( pGraph->Version ) { case 1: nRet = dgl_add_node_V1(pGraph, nNodeId, pvNodeAttr, nFlags); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_add_node_V2(pGraph, nNodeId, pvNodeAttr, nFlags); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } return nRet; } int dglDelNode( dglGraph_s * pGraph , dglInt32_t nNodeId ) { int nRet; switch( pGraph->Version ) { case 1: nRet = dgl_del_node_V1(pGraph, nNodeId); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_del_node_V2(pGraph, nNodeId); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } return nRet; } int dglWrite( dglGraph_s * pGraph, int fd ) { int nRet; switch( pGraph->Version ) { case 1: nRet = dgl_write_V1(pGraph, fd); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_write_V2(pGraph, fd); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } return nRet; } int dglRead( dglGraph_s * pGraph, int fd ) { dglByte_t bVersion; int nRet; if ( read( fd , & bVersion , 1 ) != 1 ) { pGraph->iErrno = DGL_ERR_Read; nRet = -pGraph->iErrno; } else { switch( bVersion ) { case 1: nRet = dgl_read_V1( pGraph, fd ); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_read_V2( pGraph, fd, bVersion ); break; #endif default: pGraph->iErrno = DGL_ERR_VersionNotSupported; nRet = -pGraph->iErrno; break; } } return nRet; } int dglShortestPath ( dglGraph_s * pGraph, dglSPReport_s **ppReport, dglInt32_t nStart, dglInt32_t nDestination, dglSPClip_fn fnClip, void * pvClipArg, dglSPCache_s * pCache ) { int nRet; switch( pGraph->Version ) { case 1: nRet = dgl_dijkstra_V1( pGraph, ppReport, NULL, nStart, nDestination, fnClip, pvClipArg, pCache ); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_dijkstra_V2( pGraph, ppReport, NULL, nStart, nDestination, fnClip, pvClipArg, pCache ); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } return nRet; } int dglShortestDistance ( dglGraph_s * pGraph, dglInt32_t * pnDistance , dglInt32_t nStart, dglInt32_t nDestination, dglSPClip_fn fnClip, void * pvClipArg, dglSPCache_s * pCache ) { int nRet; switch( pGraph->Version ) { case 1: nRet = dgl_dijkstra_V1( pGraph, NULL, pnDistance, nStart, nDestination, fnClip, pvClipArg, pCache ); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_dijkstra_V2( pGraph, NULL, pnDistance, nStart, nDestination, fnClip, pvClipArg, pCache ); break; #endif default: pGraph->iErrno = DGL_ERR_BadVersion; nRet = -pGraph->iErrno; break; } return nRet; } int dglDepthSpanning ( dglGraph_s * pgraphInput, dglGraph_s * pgraphOutput, dglInt32_t nVertexNode, dglSpanClip_fn fnClip, void * pvClipArg ) { int nRet; void * pvVisited; if ( dglGet_EdgeCount(pgraphInput) == 0 ) { /* no span */ pgraphInput->iErrno = 0; return 0; } #ifndef DGL_V2 if ( pgraphInput->Version == 2 ) { pgraphInput->iErrno = DGL_ERR_BadVersion; return -pgraphInput->iErrno; } #endif nRet = dglInitialize( pgraphOutput, dglGet_Version(pgraphInput), dglGet_NodeAttrSize(pgraphInput), dglGet_EdgeAttrSize(pgraphInput), dglGet_Opaque(pgraphInput) ); if ( nRet < 0 ) return nRet; if ( (pvVisited = avl_create( dglTreeNodeCompare, NULL, dglTreeGetAllocator() )) == NULL ) { pgraphInput->iErrno = DGL_ERR_MemoryExhausted; return -pgraphInput->iErrno; } switch( pgraphInput->Version ) { case 1: nRet = dgl_depthfirst_spanning_V1( pgraphInput, pgraphOutput, nVertexNode , pvVisited , fnClip , pvClipArg ); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_depthfirst_spanning_V2( pgraphInput, pgraphOutput, nVertexNode , pvVisited , fnClip , pvClipArg ); break; #endif default: pgraphInput->iErrno = DGL_ERR_BadVersion; nRet = -pgraphInput->iErrno; break; } avl_destroy( pvVisited, dglTreeNodeCancel ); if ( nRet < 0 ) { dglRelease( pgraphOutput ); } return nRet; } int dglDepthComponents( dglGraph_s * pgraphInput, dglGraph_s * pgraphComponents, int cgraphComponents, dglSpanClip_fn fnClip, void * pvClipArg ) { int i, nret = 0; dglTreeNode_s findVisited; void * pvVisited; dglInt32_t * pvertex , * pnode; if ( dglGet_EdgeCount(pgraphInput) == 0 ) { /* no span */ pgraphInput->iErrno = 0; return 0; } #ifndef DGL_V2 if ( pgraphInput->Version == 2 || pgraphInput->Version == 3 ) { pgraphInput->iErrno = DGL_ERR_BadVersion; return -pgraphInput->iErrno; } #endif if ( (pvVisited = avl_create( dglTreeNodeCompare, NULL, dglTreeGetAllocator() )) == NULL ) { pgraphInput->iErrno = DGL_ERR_MemoryExhausted; goto error; } /* * choose a vertex to start from */ pvertex = NULL; { dglNodeTraverser_s pT; dglNode_T_Initialize( &pT, pgraphInput ); for( pnode = dglNode_T_First( &pT ); pnode; pnode = dglNode_T_Next( &pT ) ) { switch(pgraphInput->Version) { case 1: if ( DGL_NODE_STATUS_v1(pnode) & DGL_NS_HEAD ) pvertex = pnode; break; #ifdef DGL_V2 case 2: case 3: if ( DGL_NODE_STATUS_v2(pnode) & DGL_NS_HEAD ) pvertex = pnode; break; #endif } if ( pvertex ) break; } dglNode_T_Release( &pT ); } if ( pvertex == NULL ) { pgraphInput->iErrno = DGL_ERR_UnexpectedNullPointer; goto error; } for ( i = 0; i < cgraphComponents && pvertex; i++ ) { nret = dglInitialize( & pgraphComponents[i], dglGet_Version(pgraphInput), dglGet_NodeAttrSize(pgraphInput), dglGet_EdgeAttrSize(pgraphInput), dglGet_Opaque(pgraphInput) ); if ( nret < 0 ) goto error; switch( pgraphInput->Version ) { case 1: nret = dgl_depthfirst_spanning_V1(pgraphInput, & pgraphComponents[i], DGL_NODE_ID_v1(pvertex), pvVisited, fnClip, pvClipArg); if ( nret < 0 ) goto error; break; #ifdef DGL_V2 case 2: case 3: nret = dgl_depthfirst_spanning_V2(pgraphInput, & pgraphComponents[i], DGL_NODE_ID_v1(pvertex), pvVisited, fnClip, pvClipArg); if ( nret < 0 ) goto error; break; #endif default: pgraphInput->iErrno = DGL_ERR_BadVersion; nret = -pgraphInput->iErrno; goto error; } /* * select next unvisited vertex */ pvertex = NULL; { dglNodeTraverser_s pT; dglNode_T_Initialize( &pT, pgraphInput ); for( pnode = dglNode_T_First( &pT ); pnode; pnode = dglNode_T_Next( &pT ) ) { switch(pgraphInput->Version) { case 1: if ( DGL_NODE_STATUS_v1(pnode) & DGL_NS_HEAD ) { findVisited.nKey = DGL_NODE_ID_v1(pnode); if ( avl_find( pvVisited, &findVisited ) == NULL ) { pvertex = pnode; break; } } break; #ifdef DGL_V2 case 2: case 3: if ( DGL_NODE_STATUS_v2(pnode) & DGL_NS_HEAD ) { findVisited.nKey = DGL_NODE_ID_v2(pnode); if ( avl_find( pvVisited, &findVisited ) == NULL ) { pvertex = pnode; break; } } break; #endif } if ( pvertex ) break; } dglNode_T_Release( &pT ); } } avl_destroy( pvVisited, dglTreeNodeCancel ); return i; error: avl_destroy( pvVisited, dglTreeNodeCancel ); return nret; } int dglMinimumSpanning( dglGraph_s * pgraphInput, dglGraph_s * pgraphOutput, dglInt32_t nVertexNode, dglSpanClip_fn fnClip, void * pvClipArg ) { int nRet; if ( dglGet_EdgeCount(pgraphInput) == 0 ) { /* no span */ pgraphInput->iErrno = 0; return 0; } nRet = dglInitialize( pgraphOutput, dglGet_Version(pgraphInput), dglGet_NodeAttrSize(pgraphInput), dglGet_EdgeAttrSize(pgraphInput), dglGet_Opaque(pgraphInput) ); if ( nRet < 0 ) return nRet; switch( pgraphInput->Version ) { case 1: nRet = dgl_minimum_spanning_V1( pgraphInput, pgraphOutput, nVertexNode , fnClip , pvClipArg ); break; #ifdef DGL_V2 case 2: case 3: nRet = dgl_minimum_spanning_V2( pgraphInput, pgraphOutput, nVertexNode , fnClip , pvClipArg ); break; #endif default: pgraphInput->iErrno = DGL_ERR_BadVersion; nRet = -pgraphInput->iErrno; break; } if ( nRet < 0 ) { dglRelease( pgraphOutput ); } return nRet; } void dglFreeSPReport( dglGraph_s * pgraph , dglSPReport_s * pSPReport ) { int iArc; if ( pSPReport ) { if ( pSPReport->pArc ) { for ( iArc = 0 ; iArc < pSPReport->cArc ; iArc ++ ) { if ( pSPReport->pArc[iArc].pnEdge ) free( pSPReport->pArc[iArc].pnEdge ); } free( pSPReport->pArc ); } free( pSPReport ); } } int dglInitializeSPCache( dglGraph_s * pGraph, dglSPCache_s * pCache ) { switch( pGraph->Version ) { case 1: return dgl_sp_cache_initialize_V1( pGraph, pCache, 0 ); #ifdef DGL_V2 case 2: case 3: return dgl_sp_cache_initialize_V2( pGraph, pCache, 0 ); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } void dglReleaseSPCache( dglGraph_s * pGraph, dglSPCache_s * pCache ) { pGraph->iErrno = 0; switch( pGraph->Version ) { case 1: dgl_sp_cache_release_V1( pGraph, pCache ); break; #ifdef DGL_V2 case 2: case 3: dgl_sp_cache_release_V2( pGraph, pCache ); break; #endif } pGraph->iErrno = DGL_ERR_BadVersion; } int dglErrno( dglGraph_s * pgraph ) { return pgraph->iErrno; } char * dglStrerror( dglGraph_s * pgraph ) { switch( pgraph->iErrno ) { case DGL_ERR_BadVersion: return "Bad Version"; case DGL_ERR_BadNodeType: return "Bad Node Type"; case DGL_ERR_MemoryExhausted: return "Memory Exhausted"; case DGL_ERR_HeapError: return "Heap Error"; case DGL_ERR_UndefinedMethod: return "Undefined Method"; case DGL_ERR_Write: return "Write"; case DGL_ERR_Read: return "Read"; case DGL_ERR_NotSupported: return "Not Supported"; case DGL_ERR_UnknownByteOrder: return "Unknown Byte Order"; case DGL_ERR_NodeNotFound: return "Node Not Found"; case DGL_ERR_HeadNodeNotFound: return "Head Node Not Found"; case DGL_ERR_TailNodeNotFound: return "Tail Node Not Found"; case DGL_ERR_BadEdge: return "Bad Edge"; case DGL_ERR_BadOnFlatGraph: return "Operation Not Supported On Flat-State Graph"; case DGL_ERR_BadOnTreeGraph: return "Operation Not Supported On Tree-State Graph"; case DGL_ERR_TreeSearchError: return "Tree Search Error"; case DGL_ERR_UnexpectedNullPointer: return "Unexpected Null Pointer"; case DGL_ERR_VersionNotSupported: return "Version Not Supported"; case DGL_ERR_EdgeNotFound: return "Edge Not Found"; case DGL_ERR_NodeAlreadyExist: return "Node Already Exist"; case DGL_ERR_NodeIsAComponent: return "Node Is A Component"; case DGL_ERR_EdgeAlreadyExist: return "Edge Already Exist"; case DGL_ERR_BadArgument: return "Bad Argument"; } return "unknown graph error code"; } /* * dglGraph_s hiders */ int dglGet_Version (dglGraph_s * pgraph) { return pgraph->Version; } void dglSet_Version (dglGraph_s * pgraph, int nVersion) { pgraph->Version = nVersion; } int dglGet_Endianess (dglGraph_s * pgraph) { return pgraph->Endian; } int dglGet_NodeAttrSize (dglGraph_s * pgraph) { return pgraph->NodeAttrSize; } int dglGet_EdgeAttrSize (dglGraph_s * pgraph) { return pgraph->EdgeAttrSize; } int dglGet_NodeCount (dglGraph_s * pgraph) { return pgraph->cNode; } int dglGet_HeadNodeCount (dglGraph_s * pgraph) { return pgraph->cHead; } int dglGet_TailNodeCount (dglGraph_s * pgraph) { return pgraph->cTail; } int dglGet_AloneNodeCount (dglGraph_s * pgraph) { return pgraph->cAlone; } int dglGet_EdgeCount (dglGraph_s * pgraph) { return pgraph->cEdge; } int dglGet_State (dglGraph_s * pgraph) { return pgraph->Flags; } dglInt32_t * dglGet_Opaque (dglGraph_s * pgraph) { return pgraph->aOpaqueSet; } void dglSet_Opaque( dglGraph_s * pgraph, dglInt32_t * pOpaque ) { memcpy( pgraph->aOpaqueSet , pOpaque , sizeof( dglInt32_t ) * 16 ); } int dglGet_NodeSize (dglGraph_s * pgraph) { switch(pgraph->Version) { case 1: return DGL_NODE_SIZEOF_v1( pgraph->NodeAttrSize ); #ifdef DGL_V2 case 2: case 3: return DGL_NODE_SIZEOF_v2( pgraph->NodeAttrSize ); #endif } pgraph->iErrno = DGL_ERR_BadVersion; return -pgraph->iErrno; } int dglGet_EdgeSize (dglGraph_s * pgraph) { switch(pgraph->Version) { case 1: return DGL_EDGE_SIZEOF_v1( pgraph->NodeAttrSize ); #ifdef DGL_V2 case 2: case 3: return DGL_EDGE_SIZEOF_v2( pgraph->NodeAttrSize ); #endif } pgraph->iErrno = DGL_ERR_BadVersion; return -pgraph->iErrno; } dglInt64_t dglGet_Cost(dglGraph_s * pgraph) { return pgraph->nnCost; } void dglSet_Cost(dglGraph_s * pgraph, dglInt64_t nnCost) { pgraph->nnCost = nnCost; } dglInt32_t dglGet_Family(dglGraph_s * pgraph) { return pgraph->nFamily; } void dglSet_Family(dglGraph_s * pgraph, dglInt32_t nFamily) { pgraph->nFamily = nFamily; } dglInt32_t dglGet_Options(dglGraph_s * pgraph) { return pgraph->nOptions; } void dglSet_Options(dglGraph_s * pgraph, dglInt32_t nOptions) { pgraph->nOptions = nOptions; } dglEdgePrioritizer_s * dglGet_EdgePrioritizer(dglGraph_s * pGraph) { return & pGraph->edgePrioritizer; } dglNodePrioritizer_s * dglGet_NodePrioritizer(dglGraph_s * pGraph) { return & pGraph->nodePrioritizer; } /* * Node Traverse */ int dglNode_T_Initialize( dglNodeTraverser_s * pT , dglGraph_s * pGraph ) { switch( pGraph->Version ) { case 1: return dgl_node_t_initialize_V1( pGraph, pT ); #ifdef DGL_V2 case 2: case 3: return dgl_node_t_initialize_V2( pGraph, pT ); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } void dglNode_T_Release( dglNodeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: dgl_node_t_release_V1( pT ); return; #ifdef DGL_V2 case 2: case 3: dgl_node_t_release_V2( pT ); return; #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; } dglInt32_t * dglNode_T_First( dglNodeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: return dgl_node_t_first_V1( pT ); #ifdef DGL_V2 case 2: case 3: return dgl_node_t_first_V2( pT ); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } dglInt32_t * dglNode_T_Next( dglNodeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: return dgl_node_t_next_V1( pT ); #ifdef DGL_V2 case 2: case 3: return dgl_node_t_next_V2( pT ); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } dglInt32_t * dglNode_T_Find( dglNodeTraverser_s * pT , dglInt32_t nNodeId ) { switch( pT->pGraph->Version ) { case 1: return dgl_node_t_find_V1( pT , nNodeId ); #ifdef DGL_V2 case 2: case 3: return dgl_node_t_find_V2( pT , nNodeId ); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } /* * Edge Traverser */ int dglEdge_T_Initialize( dglEdgeTraverser_s * pT , dglGraph_s * pGraph , dglEdgePrioritizer_s * pEdgePrioritizer ) { switch( pGraph->Version ) { case 1: return dgl_edge_t_initialize_V1( pGraph, pT , pEdgePrioritizer ); #ifdef DGL_V2 case 2: case 3: return dgl_edge_t_initialize_V2( pGraph, pT , pEdgePrioritizer ); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } void dglEdge_T_Release( dglEdgeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: dgl_edge_t_release_V1( pT ); return; #ifdef DGL_V2 case 2: case 3: dgl_edge_t_release_V2( pT ); return; #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; } dglInt32_t * dglEdge_T_First( dglEdgeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: return dgl_edge_t_first_V1( pT ); #ifdef DGL_V2 case 2: case 3: return dgl_edge_t_first_V2( pT ); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } dglInt32_t * dglEdge_T_Next( dglEdgeTraverser_s * pT ) { switch( pT->pGraph->Version ) { case 1: return dgl_edge_t_next_V1( pT ); #ifdef DGL_V2 case 2: case 3: return dgl_edge_t_next_V2( pT ); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } int dglEdgeset_T_Initialize ( dglEdgesetTraverser_s * pT , dglGraph_s * pGraph , dglInt32_t * pnEdgeset ) { switch(pGraph->Version) { case 1: return dgl_edgeset_t_initialize_V1(pGraph,pT,pnEdgeset); #ifdef DGL_V2 case 2: case 3: return dgl_edgeset_t_initialize_V2(pGraph,pT,pnEdgeset); #endif } pGraph->iErrno = DGL_ERR_BadVersion; return -pGraph->iErrno; } void dglEdgeset_T_Release( dglEdgesetTraverser_s * pT ) { } dglInt32_t * dglEdgeset_T_First( dglEdgesetTraverser_s * pT ) { switch(pT->pGraph->Version) { case 1: return dgl_edgeset_t_first_V1(pT); #ifdef DGL_V2 case 2: case 3: return dgl_edgeset_t_first_V2(pT); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } dglInt32_t * dglEdgeset_T_Next( dglEdgesetTraverser_s * pT ) { switch(pT->pGraph->Version) { case 1: return dgl_edgeset_t_next_V1(pT); #ifdef DGL_V2 case 2: case 3: return dgl_edgeset_t_next_V2(pT); #endif } pT->pGraph->iErrno = DGL_ERR_BadVersion; return NULL; } /* * chunked I/O */ #define __CIO_BEGIN 0 #define __CIO_W_HEADER 1 #define __CIO_W_NODEBUFFER 2 #define __CIO_W_EDGEBUFFER 3 #define __CIO_R_HEADER 4 #define __CIO_R_NODEBUFFER 5 #define __CIO_R_EDGEBUFFER 6 #define __CIO_END 7 int dglIOContextInitialize(dglGraph_s * pG, dglIOContext_s * pIO) { pIO->pG = pG; pIO->nState = __CIO_BEGIN; pIO->cb = 0; pIO->ib = 0; pIO->pb = NULL; return 0; } void dglIOContextRelease( dglIOContext_s * pIO ) { } int dglWriteChunk(dglIOContext_s * pIO, dglWriteChunk_fn pfn, void * pv) { unsigned char * pb; int cb; switch( pIO->nState ) { case __CIO_BEGIN: pIO->pb = pIO->ab; pb = pIO->pb; memcpy( pb, & pIO->pG->Version , 1 ); pb += 1; /* 1 */ memcpy( pb, & pIO->pG->Endian , 1 ); pb += 1; /* 2 */ memcpy( pb, & pIO->pG->NodeAttrSize , 4 ); pb += 4; /* 6 */ memcpy( pb, & pIO->pG->EdgeAttrSize , 4 ); pb += 4; /* 10 */ memcpy( pb, & pIO->pG->aOpaqueSet , 64 ); pb += 64; /* 74 */ memcpy( pb, & pIO->pG->nOptions , 4 ); pb += 4; /* 78 */ memcpy( pb, & pIO->pG->nFamily , 4 ); pb += 4; /* 82 */ memcpy( pb, & pIO->pG->nnCost , 8 ); pb += 8; /* 90 */ memcpy( pb, & pIO->pG->cNode , 4 ); pb += 4; /* 94 */ memcpy( pb, & pIO->pG->cHead , 4 ); pb += 4; /* 98 */ memcpy( pb, & pIO->pG->cTail , 4 ); pb += 4; /* 102 */ memcpy( pb, & pIO->pG->cAlone , 4 ); pb += 4; /* 106 */ memcpy( pb, & pIO->pG->cEdge , 4 ); pb += 4; /* 110 */ memcpy( pb, & pIO->pG->iNodeBuffer , 4 ); pb += 4; /* 114 */ memcpy( pb, & pIO->pG->iEdgeBuffer , 4 ); pb += 4; /* 118 */ pIO->cb = 118; cb = pfn(pIO->pG, pIO->pb, pIO->cb, pv); if (cb >= 0) { pIO->ib += cb; if ((pIO->cb - pIO->ib) == 0) { pIO->ib = 0; pIO->cb = pIO->pG->iNodeBuffer; pIO->pb = pIO->pG->pNodeBuffer; pIO->nState = __CIO_W_NODEBUFFER; } else { pIO->nState = __CIO_W_HEADER; } } return cb; case __CIO_W_HEADER: cb = pfn(pIO->pG, pIO->pb + pIO->ib, pIO->cb - pIO->ib, pv); if (cb > 0) { pIO->ib += cb; if ((pIO->cb - pIO->ib) == 0) { if ( pIO->pG->iNodeBuffer > 0 ) { pIO->ib = 0; pIO->cb = pIO->pG->iNodeBuffer; pIO->pb = pIO->pG->pNodeBuffer; pIO->nState = __CIO_W_NODEBUFFER; } else if ( pIO->pG->iEdgeBuffer > 0 ) { pIO->ib = 0; pIO->cb = pIO->pG->iEdgeBuffer; pIO->pb = pIO->pG->pEdgeBuffer; pIO->nState = __CIO_W_EDGEBUFFER; } else { pIO->nState = __CIO_END; } } else { pIO->nState = __CIO_W_HEADER; } } return cb; case __CIO_W_NODEBUFFER: cb = pfn(pIO->pG, pIO->pb + pIO->ib, pIO->cb - pIO->ib, pv); if (cb > 0) { pIO->ib += cb; if ((pIO->cb - pIO->ib) == 0) { if ( pIO->pG->iEdgeBuffer > 0 ) { pIO->ib = 0; pIO->cb = pIO->pG->iEdgeBuffer; pIO->pb = pIO->pG->pEdgeBuffer; pIO->nState = __CIO_W_EDGEBUFFER; } else { pIO->nState = __CIO_END; } } } return cb; case __CIO_W_EDGEBUFFER: cb = pfn(pIO->pG, pIO->pb + pIO->ib, pIO->cb - pIO->ib, pv); if (cb > 0) { pIO->ib += cb; if ((pIO->cb - pIO->ib) == 0) { pIO->nState = __CIO_END; } } return cb; case __CIO_END: pfn(pIO->pG, NULL, 0, pv); /* notify end of graph */ return 0; } return 0; } #ifndef MIN #define MIN(x,y) (((x)<(y))?x:y) #endif int dglReadChunk(dglIOContext_s * pIO, dglByte_t * pbChunk, int cbChunk) { int i, c; unsigned char * pb; switch( pIO->nState ) { case __CIO_BEGIN: pIO->cb = 118; pIO->ib = 0; pIO->pb = pIO->ab; c = MIN(cbChunk, 118); memcpy( pIO->pb, pbChunk, c ); pIO->ib += c; if ((pIO->cb - pIO->ib) == 0) goto init_nodebuffer; pIO->nState = __CIO_R_HEADER; return c; case __CIO_R_HEADER: c = MIN(cbChunk , pIO->cb - pIO->ib); memcpy( pIO->pb + pIO->ib, pbChunk, c ); pIO->ib += c; init_nodebuffer: if ((pIO->cb - pIO->ib) == 0) { pb = pIO->pb; memcpy( & pIO->pG->Version , pb , 1 ); pb += 1; /* 1 */ memcpy( & pIO->pG->Endian , pb , 1 ); pb += 1; /* 2 */ memcpy( & pIO->pG->NodeAttrSize , pb , 4 ); pb += 4; /* 6 */ memcpy( & pIO->pG->EdgeAttrSize , pb , 4 ); pb += 4; /* 10 */ memcpy( & pIO->pG->aOpaqueSet , pb , 64 ); pb += 64; /* 74 */ memcpy( & pIO->pG->nOptions , pb , 4 ); pb += 4; /* 78 */ memcpy( & pIO->pG->nFamily , pb , 4 ); pb += 4; /* 82 */ memcpy( & pIO->pG->nnCost , pb , 8 ); pb += 8; /* 90 */ memcpy( & pIO->pG->cNode , pb , 4 ); pb += 4; /* 94 */ memcpy( & pIO->pG->cHead , pb , 4 ); pb += 4; /* 98 */ memcpy( & pIO->pG->cTail , pb , 4 ); pb += 4; /* 102 */ memcpy( & pIO->pG->cAlone , pb , 4 ); pb += 4; /* 106 */ memcpy( & pIO->pG->cEdge , pb , 4 ); pb += 4; /* 110 */ memcpy( & pIO->pG->iNodeBuffer , pb , 4 ); pb += 4; /* 114 */ memcpy( & pIO->pG->iEdgeBuffer , pb , 4 ); pb += 4; /* 118 */ pIO->fSwap = 0; #ifdef DGL_ENDIAN_BIG if ( pIO->pG->Endian == DGL_ENDIAN_LITTLE ) pIO->fSwap = 1; #else if ( pIO->pG->Endian == DGL_ENDIAN_BIG ) pIO->fSwap = 1; #endif if ( pIO->fSwap ) { dgl_swapInt32Bytes( & pIO->pG->NodeAttrSize ); dgl_swapInt32Bytes( & pIO->pG->EdgeAttrSize ); dgl_swapInt32Bytes( & pIO->pG->nOptions ); dgl_swapInt32Bytes( & pIO->pG->nFamily ); dgl_swapInt64Bytes( & pIO->pG->nnCost ); dgl_swapInt32Bytes( & pIO->pG->cNode ); dgl_swapInt32Bytes( & pIO->pG->cHead ); dgl_swapInt32Bytes( & pIO->pG->cTail ); dgl_swapInt32Bytes( & pIO->pG->cAlone ); dgl_swapInt32Bytes( & pIO->pG->cEdge ); dgl_swapInt32Bytes( & pIO->pG->iNodeBuffer ); dgl_swapInt32Bytes( & pIO->pG->iEdgeBuffer ); for ( i = 0 ; i < 16 ; i ++ ) { dgl_swapInt32Bytes( & pIO->pG->aOpaqueSet[i] ); } #ifdef DGL_ENDIAN_BIG pIO->pG->Endian = DGL_ENDIAN_BIG; #else pIO->pG->Endian = DGL_ENDIAN_LITTLE; #endif } if ( pIO->pG->iNodeBuffer > 0 ) { pIO->pG->pNodeBuffer = malloc( pIO->pG->iNodeBuffer ); if ( pIO->pG->pNodeBuffer == NULL ) { return -1; } pIO->cb = pIO->pG->iNodeBuffer; pIO->pb = pIO->pG->pNodeBuffer; pIO->ib = 0; pIO->nState = __CIO_R_NODEBUFFER; } else { goto init_edgebuffer; } } return c; case __CIO_R_NODEBUFFER: c = MIN(cbChunk , pIO->cb - pIO->ib); memcpy( pIO->pb + pIO->ib, pbChunk, c ); pIO->ib += c; init_edgebuffer: if ((pIO->cb - pIO->ib) == 0) { if ( pIO->pG->iEdgeBuffer > 0 ) { pIO->pG->pEdgeBuffer = malloc( pIO->pG->iEdgeBuffer ); if ( pIO->pG->pEdgeBuffer == NULL ) { return -1; } pIO->cb = pIO->pG->iEdgeBuffer; pIO->pb = pIO->pG->pEdgeBuffer; pIO->ib = 0; pIO->nState = __CIO_R_EDGEBUFFER; } else { pIO->nState = __CIO_END; } } return c; case __CIO_R_EDGEBUFFER: c = MIN(cbChunk , pIO->cb - pIO->ib); memcpy( pIO->pb + pIO->ib, pbChunk, c ); pIO->ib += c; if ((pIO->cb - pIO->ib) == 0) { pIO->nState = __CIO_END; } return c; case __CIO_END: { /* switch on FLAT bit */ pIO->pG->Flags |= DGL_GS_FLAT; /* nodebuffer and edgebuffer are both arrays on 32 bit integer * byte order swapping is straightforward */ if (pIO->fSwap && pIO->pG->iNodeBuffer > 0) { int in, cn; dglInt32_t * pn; for ( cn = pIO->pG->iNodeBuffer / sizeof(dglInt32_t), pn = (dglInt32_t*)pIO->pG->pNodeBuffer, in = 0 ; in < cn ; in ++ ) { dgl_swapInt32Bytes( & pn[in] ); } } if (pIO->fSwap && pIO->pG->iEdgeBuffer > 0) { int in, cn; dglInt32_t * pn; for ( cn = pIO->pG->iEdgeBuffer / sizeof(dglInt32_t), pn = (dglInt32_t*)pIO->pG->pEdgeBuffer, in = 0 ; in < cn ; in ++ ) { dgl_swapInt32Bytes( & pn[in] ); } } } return 0; default: return 0; } }