/* * MINIXML functions wrapper * * Copyright 2010-2011 Petr Chornyj * * 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, 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; see the file LICENSE.txt. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). * * As a special exception, the Harbour Project gives permission for * additional uses of the text contained in its release of Harbour. * * The exception is that, if you link the Harbour libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Harbour library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the Harbour * Project under the name Harbour. If you copy code from other * Harbour Project or Free Software Foundation releases into a copy of * Harbour, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for Harbour, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * */ #include "hbapi.h" #include "hbapiitm.h" #include "hbapierr.h" #include "hbapifs.h" #include "hbapistr.h" #include "hbstack.h" #include "hbvm.h" #include "mxml.h" #include "config.h" #define MXML_ERR_ARGS() ( hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, \ HB_ERR_ARGS_BASEPARAMS ) ) typedef struct /* placeholder for mxml_node_t */ { mxml_node_t * node; } HBMXML_NODE; /* callback function support */ typedef struct { PHB_ITEM type_cb; PHB_ITEM save_cb; PHB_ITEM sax_cb; void * hText; } HB_CBS_VAR; typedef struct { PHB_ITEM load_cb; PHB_ITEM save_cb; } HB_CUSTOM_CBS_VAR; typedef struct { PHB_ITEM error_cb; } HB_ERROR_CB_VAR; static void hb_cbs_var_init( void * cargo ) { HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) cargo; pCbs->type_cb = NULL; pCbs->save_cb = NULL; pCbs->sax_cb = NULL; } static void hb_custom_cbs_var_init( void * cargo ) { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) cargo; pCCbs->load_cb = NULL; pCCbs->save_cb = NULL; } static void hb_custom_cbs_var_release( void * cargo ) { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) cargo; if( pCCbs->load_cb ) hb_itemRelease( pCCbs->load_cb ); if( pCCbs->save_cb ) hb_itemRelease( pCCbs->save_cb ); } static void hb_error_cb_var_init( void * cargo ) { HB_ERROR_CB_VAR * pError_cb = ( HB_ERROR_CB_VAR * ) cargo; pError_cb->error_cb = NULL; } static void hb_error_cb_var_release( void * cargo ) { HB_ERROR_CB_VAR * pError_cb = ( HB_ERROR_CB_VAR * ) cargo; if( pError_cb->error_cb ) hb_itemRelease( pError_cb->error_cb ); } static HB_TSD_NEW( s_cbs_var, sizeof( HB_CBS_VAR ), hb_cbs_var_init, NULL ); static HB_TSD_NEW( s_custom_cbs_var, sizeof( HB_CUSTOM_CBS_VAR ), hb_custom_cbs_var_init, hb_custom_cbs_var_release ); static HB_TSD_NEW( s_error_cb_var, sizeof( HB_ERROR_CB_VAR ), hb_error_cb_var_init, hb_error_cb_var_release ); /* mxml_node_t * support */ static void hbmxml_release( mxml_node_t * node ) { if( mxmlGetRefCount( node ) <= ( node->parent ? 2 : 1 ) ) { void * user_data; /* remove userData when last HVM item with given node is cleared * It's not nice solution because node can still exists and can * be extracted yet but there is not destructor for userData * in MXML library so we have no choice :-( [druzus] */ if( ( user_data = mxmlGetUserData( node ) ) != NULL ) { mxmlSetUserData( node, NULL ); hb_itemRelease( ( PHB_ITEM ) user_data ); } } mxmlRelease( node ); } static HB_GARBAGE_FUNC( hbmxml_nodeDestructor ) { HBMXML_NODE * pHbnode = ( HBMXML_NODE * ) Cargo; if( pHbnode->node ) { hbmxml_release( pHbnode->node ); pHbnode->node = NULL; } } static const HB_GC_FUNCS s_gc_mxml_nodeFuncs = { hbmxml_nodeDestructor, hb_gcDummyMark }; static mxml_node_t * mxml_node_param( int iParam ) { HBMXML_NODE * pHbnode = ( HBMXML_NODE * ) hb_parptrGC( &s_gc_mxml_nodeFuncs, iParam ); return ( pHbnode && pHbnode->node ) ? pHbnode->node : NULL; } static HBMXML_NODE * mxml_node_new( mxml_node_t * node, int iNew ) { HBMXML_NODE * pHbnode = ( HBMXML_NODE * ) hb_gcAllocate( sizeof( HBMXML_NODE ), &s_gc_mxml_nodeFuncs ); pHbnode->node = node; if( iNew == 0 ) mxmlRetain( node ); return pHbnode; } static void mxml_node_push( mxml_node_t * node, int iNew ) { hb_itemPutPtrGC( hb_stackAllocItem(), mxml_node_new( node, iNew ) ); } static void mxml_node_ret( mxml_node_t * node, int iNew ) { if( node ) hb_itemPutPtrGC( hb_stackReturnItem(), mxml_node_new( node, iNew ) ); } /* mxml_index_t * support */ static HB_GARBAGE_FUNC( hbmxml_indexDestructor ) { mxml_index_t ** ppMxml_index = ( mxml_index_t ** ) Cargo; if( *ppMxml_index ) { mxmlIndexDelete( *ppMxml_index ); *ppMxml_index = NULL; } } static const HB_GC_FUNCS s_gc_mxml_indexFuncs = { hbmxml_indexDestructor, hb_gcDummyMark }; static mxml_index_t * mxml_index_param( int iParam ) { mxml_index_t ** ppMxml_index = ( mxml_index_t ** ) hb_parptrGC( &s_gc_mxml_indexFuncs, iParam ); return ( ppMxml_index && *ppMxml_index ) ? *ppMxml_index : NULL; } static mxml_index_t ** mxml_index_new( mxml_index_t * index ) { mxml_index_t ** ppMxml_index = ( mxml_index_t ** ) hb_gcAllocate( sizeof( mxml_index_t * ), &s_gc_mxml_indexFuncs ); *ppMxml_index = index; return ppMxml_index; } static void mxml_index_ret( mxml_index_t * index ) { hb_itemPutPtrGC( hb_stackReturnItem(), mxml_index_new( index ) ); } /* non-wrap hb_mxml*() functions */ HB_FUNC( HB_MXMLVERSION ) { hb_retc( MXML_VERSION ); } /* mxml_*() wrapper functions */ /* * - mxmlEntityAddCallback * - mxmlEntityRemoveCallback * - mxmlLoadFd * - mxmlSAXLoadFd * - mxmlSaveFd */ /* void mxmlAdd( mxml_node_t * parent, int where, mxml_node_t * child, mxml_node_t * node ) */ /* mxmlAdd() does not update reference counters, we use our own * wrapper which does it [druzus] */ static void mxmlAddRef( mxml_node_t * parent, int where, mxml_node_t * child, mxml_node_t * node ) { mxml_node_t * old_parent = node->parent; mxmlAdd( parent, where, ( child != NULL ) ? child : MXML_ADD_TO_PARENT, node ); if( ! old_parent ) mxmlRetain( node ); } HB_FUNC( MXMLADD ) { mxml_node_t * parent = mxml_node_param( 1 ); int where = hb_parnidef( 2, MXML_ADD_BEFORE ); mxml_node_t * child = mxml_node_param( 3 ); mxml_node_t * node = mxml_node_param( 4 ); if( parent && node ) { where = ( where == MXML_ADD_BEFORE ) ? MXML_ADD_BEFORE : MXML_ADD_AFTER; mxmlAddRef( parent, where, ( child != NULL ) ? child : MXML_ADD_TO_PARENT, node ); } else MXML_ERR_ARGS(); } /* void mxmlElementDeleteAttr( mxml_node_t * node, const char * name ) */ HB_FUNC( MXMLELEMENTDELETEATTR ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hName; mxmlElementDeleteAttr( node, hb_parstr_utf8( 2, &hName, NULL ) ); hb_strfree( hName ); } else MXML_ERR_ARGS(); } /* const char * mxmlElementGetAttr( mxml_node_t * node, const char * name ) */ HB_FUNC( MXMLELEMENTGETATTR ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hName; hb_retstr_utf8( mxmlElementGetAttr( node, hb_parstr_utf8( 2, &hName, NULL ) ) ); hb_strfree( hName ); } else MXML_ERR_ARGS(); } /* void mxmlElementSetAttr( mxml_node_t * node, const char * name, const char * value ) */ HB_FUNC( MXMLELEMENTSETATTR ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hName; void * hValue; mxmlElementSetAttr( node, hb_parstr_utf8( 2, &hName, NULL ), hb_parstr_utf8( 3, &hValue, NULL ) ); hb_strfree( hName ); hb_strfree( hValue ); } else MXML_ERR_ARGS(); } /* const char * mxmlEntityGetName( int val ) */ HB_FUNC( MXMLENTITYGETNAME ) { hb_retstr_utf8( mxmlEntityGetName( hb_parni( 1 ) ) ); } /* int mxmlEntityGetValue( const char * name ) */ HB_FUNC( MXMLENTITYGETVALUE ) { void * hName; hb_retni( mxmlEntityGetValue( hb_parstr_utf8( 1, &hName, NULL ) ) ); hb_strfree( hName ); } /* mxml_node_t * mxmlFindElement( mxml_node_t * node, mxml_node_t * top, const char * name, const char * attr, const char * value, int descend ); */ HB_FUNC( MXMLFINDELEMENT ) { void * hName; void * hAttr; void * hValue; mxml_node_t * node = mxml_node_param( 1 ); mxml_node_t * top = mxml_node_param( 2 ); if( node && top ) { mxml_node_t * nodef = mxmlFindElement( node, top, hb_parstr_utf8( 3, &hName, NULL ), hb_parstr_utf8( 4, &hAttr, NULL ), hb_parstr_utf8( 5, &hValue, NULL ), hb_parni( 6 ) ); hb_strfree( hName ); hb_strfree( hAttr ); hb_strfree( hValue ); mxml_node_ret( nodef, 0 ); } else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlFindPath( mxml_node_t * node, const char * path ) */ HB_FUNC( MXMLFINDPATH ) { void * hPath; mxml_node_t * node = mxml_node_param( 1 ); if( node ) { mxml_node_t * nodef = mxmlFindPath( node, hb_parstr_utf8( 2, &hPath, NULL ) ); mxml_node_ret( nodef, 0 ); hb_strfree( hPath ); } else MXML_ERR_ARGS(); } /* char * mxmlGetCDATA( mxml_node_t * node ) */ HB_FUNC( MXMLGETCDATA ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retstr_utf8( mxmlGetCDATA( node ) ); else MXML_ERR_ARGS(); } /* char * mxmlGetElement( mxml_node_t * node ) */ HB_FUNC( MXMLGETELEMENT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retstr_utf8( mxmlGetElement( node ) ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlGetFirstChild( mxml_node_t * node ) */ HB_FUNC( MXMLGETFIRSTCHILD ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxml_node_ret( mxmlGetFirstChild( node ), 0 ); else MXML_ERR_ARGS(); } /* int mxmlGetInteger( mxml_node_t * node ) */ HB_FUNC( MXMLGETINTEGER ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlGetInteger( node ) ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlGetLastChild( mxml_node_t * node ) */ HB_FUNC( MXMLGETLASTCHILD ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxml_node_ret( mxmlGetLastChild( node ), 0 ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlGetNextSibling( mxml_node_t * node ) */ HB_FUNC( MXMLGETNEXTSIBLING ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxml_node_ret( mxmlGetNextSibling( node ), 0 ); else MXML_ERR_ARGS(); } /* char * mxmlGetOpaque( mxml_node_t * node ) */ HB_FUNC( MXMLGETOPAQUE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retstr_utf8( mxmlGetOpaque( node ) ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlGetParent( mxml_node_t * node ) */ HB_FUNC( MXMLGETPARENT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxml_node_ret( mxmlGetParent( node ), 0 ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlGetPrevSibling( mxml_node_t *node ) */ HB_FUNC( MXMLGETPREVSIBLING ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxml_node_ret( mxmlGetPrevSibling( node ), 0 ); else MXML_ERR_ARGS(); } /* double mxmlGetReal( mxml_node_t * node ) */ HB_FUNC( MXMLGETREAL ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retnd( mxmlGetReal( node ) ); else MXML_ERR_ARGS(); } /* int mxmlGetRefCount( mxml_node_t * node ) */ HB_FUNC( MXMLGETREFCOUNT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlGetRefCount( node ) ); else MXML_ERR_ARGS(); } /* char * mxmlGetText( mxml_node_t * node, int * whitespace ) */ HB_FUNC( MXMLGETTEXT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { int whitespace = hb_parni( 2 ); hb_retstr_utf8( mxmlGetText( node, &whitespace ) ); hb_storni( whitespace, 2 ); } else MXML_ERR_ARGS(); } /* mxml_type_t mxmlGetType( mxml_node_t * node) */ HB_FUNC( MXMLGETTYPE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( ( int ) mxmlGetType( node ) ); else MXML_ERR_ARGS(); } /* void * mxmlGetUserData( mxml_node_t * node ) */ HB_FUNC( MXMLGETUSERDATA ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { PHB_ITEM pItem = ( PHB_ITEM ) mxmlGetUserData( node ); if( pItem ) hb_itemCopy( hb_stackReturnItem(), pItem ); } else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlIndexEnum( mxml_index_t * ind ) */ HB_FUNC( MXMLINDEXENUM ) { mxml_index_t * index = mxml_index_param( 1 ); if( index ) mxml_node_ret( mxmlIndexEnum( index ), 0 ); else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlIndexFind( mxml_index_t * ind, const char * element, const char * value ) */ HB_FUNC( MXMLINDEXFIND ) { mxml_index_t * index = mxml_index_param( 1 ); if( index ) { void * hElement; void * hValue; mxml_node_t * nodef = mxmlIndexFind( index, hb_parstr_utf8( 2, &hElement, NULL ), hb_parstr_utf8( 3, &hValue, NULL ) ); hb_strfree( hElement ); hb_strfree( hValue ); mxml_node_ret( nodef, 0 ); } else MXML_ERR_ARGS(); } /* void mxmlIndexDelete( mxml_index_t * ind ) */ HB_FUNC( MXMLINDEXDELETE ) { mxml_index_t ** ppIndex = ( mxml_index_t ** ) hb_parptrGC( &s_gc_mxml_indexFuncs, 1 ); if( ppIndex && *ppIndex ) { mxmlIndexDelete( *ppIndex ); *ppIndex = NULL; } else MXML_ERR_ARGS(); } /* int mxmlIndexGetCount( mxml_index_t * ind ) */ HB_FUNC( MXMLINDEXGETCOUNT ) { mxml_index_t * index = mxml_index_param( 1 ); if( index ) hb_retni( mxmlIndexGetCount( index ) ); else MXML_ERR_ARGS(); } /* mxml_index_t * mxmlIndexNew( mxml_node_t * node, const char * element, const char * attr ) */ HB_FUNC( MXMLINDEXNEW ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hElement; void * hAttribute; mxml_index_t * index = mxmlIndexNew( node, hb_parstr_utf8( 2, &hElement, NULL ), hb_parstr_utf8( 3, &hAttribute, NULL ) ); hb_strfree( hElement ); hb_strfree( hAttribute ); if( index ) mxml_index_ret( index ); } else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlIndexReset( mxml_index_t * ind ) */ HB_FUNC( MXMLINDEXRESET ) { mxml_index_t * index = mxml_index_param( 1 ); if( index ) mxml_node_ret( mxmlIndexReset( index ), 0 ); else MXML_ERR_ARGS(); } /* mxml_type_t type_cb( mxml_node_t * node ) */ static mxml_type_t type_cb( mxml_node_t * node ) { HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackTestTSD( &s_cbs_var ); if( pCbs != NULL ) { PHB_ITEM pCallback = pCbs->type_cb; if( pCallback && hb_vmRequestReenter() ) { int iResult; hb_vmPushEvalSym(); hb_vmPush( pCallback ); mxml_node_push( node, 0 ); hb_vmSend( 1 ); iResult = hb_parnidef( -1, MXML_TEXT ); hb_vmRequestRestore(); return ( mxml_type_t ) iResult; } } return MXML_TEXT; } HB_FUNC( MXMLLOADFILE ) { mxml_node_t * node_top; mxml_node_t * node; mxml_load_cb_t cb = MXML_NO_CALLBACK; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); FILE * file; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) node_top = MXML_NO_PARENT; else { node_top = mxml_node_param( 1 ); if( ! node_top ) { MXML_ERR_ARGS(); return; } } if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->type_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = type_cb; } else if( HB_ISNUM( 3 ) ) { switch( hb_parni( 3 ) ) { case 0: cb = MXML_NO_CALLBACK; break; case 1: cb = MXML_INTEGER_CALLBACK; break; case 2: cb = MXML_OPAQUE_CALLBACK; break; case 3: cb = MXML_REAL_CALLBACK; break; case 4: cb = MXML_TEXT_CALLBACK; break; case 5: cb = MXML_IGNORE_CALLBACK; break; default: cb = MXML_NO_CALLBACK; } } file = hb_fopen( hb_parc( 2 ), "rb" ); if( file ) { node = mxmlLoadFile( node_top, file, cb ); mxml_node_ret( node, ( node_top == MXML_NO_PARENT ) ? 1 : 0 ); fclose( file ); } pCbs->type_cb = NULL; } /* mxml_node_t * mxmlLoadString( mxml_node_t * top, const char * s, mxml_type_t (*cb)(mxml_node_t *) ) */ HB_FUNC( MXMLLOADSTRING ) { void * hFree; mxml_node_t * node_top; mxml_node_t * node; mxml_load_cb_t cb = MXML_NO_CALLBACK; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) node_top = MXML_NO_PARENT; else { node_top = mxml_node_param( 1 ); if( ! node_top ) { MXML_ERR_ARGS(); return; } } if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->type_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = type_cb; } else if( HB_ISNUM( 3 ) ) { switch( hb_parni( 3 ) ) { case 0: cb = MXML_NO_CALLBACK; break; case 1: cb = MXML_INTEGER_CALLBACK; break; case 2: cb = MXML_OPAQUE_CALLBACK; break; case 3: cb = MXML_REAL_CALLBACK; break; case 4: cb = MXML_TEXT_CALLBACK; break; case 5: cb = MXML_IGNORE_CALLBACK; break; default: cb = MXML_NO_CALLBACK; } } node = mxmlLoadString( node_top, hb_parstr_utf8( 2, &hFree, NULL ), cb ); pCbs->type_cb = NULL; mxml_node_ret( node, ( node_top == MXML_NO_PARENT ) ? 1 : 0 ); hb_strfree( hFree ); } /* mxml_node_t * mxmlNewCDATA( mxml_node_t * parent, const char * string ) */ HB_FUNC( MXMLNEWCDATA ) { void * hString; mxml_node_t * node; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) { node = mxmlNewCDATA( MXML_NO_PARENT, hb_parstr_utf8( 2, &hString, NULL ) ); mxml_node_ret( node, 1 ); hb_strfree( hString ); } else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) { node = mxmlNewCDATA( node_parent, hb_parstr_utf8( 2, &hString, NULL ) ); mxml_node_ret( node, 0 ); hb_strfree( hString ); } else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewElement( mxml_node_t * parent, const char * name ) */ HB_FUNC( MXMLNEWELEMENT ) { void * hName; mxml_node_t * node; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) { node = mxmlNewElement( MXML_NO_PARENT, hb_parstr_utf8( 2, &hName, NULL ) ); mxml_node_ret( node, 1 ); hb_strfree( hName ); } else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) { node = mxmlNewElement( node_parent, hb_parstr_utf8( 2, &hName, NULL ) ); mxml_node_ret( node, 0 ); hb_strfree( hName ); } else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewInteger( mxml_node_t * parent, int integer ) */ HB_FUNC( MXMLNEWINTEGER ) { if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) mxml_node_ret( mxmlNewInteger( MXML_NO_PARENT, hb_parni( 2 ) ), 1 ); else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) mxml_node_ret( mxmlNewInteger( node_parent, hb_parni( 2 ) ), 0 ); else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewOpaque( mxml_node_t *parent, const char * opaque ) */ HB_FUNC( MXMLNEWOPAQUE ) { void * hOpaque; mxml_node_t * node; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) { node = mxmlNewOpaque( MXML_NO_PARENT, hb_parstr_utf8( 2, &hOpaque, NULL ) ); mxml_node_ret( node, 1 ); hb_strfree( hOpaque ); } else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) { node = mxmlNewOpaque( node_parent, hb_parstr_utf8( 2, &hOpaque, NULL ) ); mxml_node_ret( node, 0 ); hb_strfree( hOpaque ); } else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewReal( mxml_node_t * parent, double real ) */ HB_FUNC( MXMLNEWREAL ) { if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) mxml_node_ret( mxmlNewReal( MXML_NO_PARENT, hb_parnd( 2 ) ), 1 ); else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) mxml_node_ret( mxmlNewReal( node_parent, hb_parnd( 2 ) ), 0 ); else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewText( mxml_node_t * parent, int whitespace, const char * string ) */ HB_FUNC( MXMLNEWTEXT ) { void * hString; mxml_node_t * node; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) { node = mxmlNewText( MXML_NO_PARENT, hb_parnidef( 2, 0 ), hb_parstr_utf8( 3, &hString, NULL ) ); mxml_node_ret( node, 1 ); hb_strfree( hString ); } else { mxml_node_t * node_parent = mxml_node_param( 1 ); if( node_parent ) { node = mxmlNewText( node_parent, hb_parnidef( 2, 0 ), hb_parstr_utf8( 3, &hString, NULL ) ); mxml_node_ret( node, 0 ); hb_strfree( hString ); } else MXML_ERR_ARGS(); } } /* mxml_node_t * mxmlNewXML( const char * version ) */ HB_FUNC( MXMLNEWXML ) { mxml_node_t * node; if( HB_ISCHAR( 1 ) ) { void * hVersion; node = mxmlNewXML( hb_parstr_utf8( 1, &hVersion, NULL ) ); hb_strfree( hVersion ); } else node = mxmlNewXML( NULL ); mxml_node_ret( node, 1 ); } /* void mxmlRemove( mxml_node_t * node ) */ /* mxmlRemove() does not update reference counters, we use our own * wrapper which does it [druzus] */ static void mxmlRemoveRef( mxml_node_t * node ) { if( node->parent ) { mxmlRemove( node ); mxmlRelease( node ); } } HB_FUNC( MXMLREMOVE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) mxmlRemoveRef( node ); else MXML_ERR_ARGS(); } /* void mxmlDelete( mxml_node_t * node ) */ HB_FUNC( MXMLDELETE ) { HBMXML_NODE * pHbnode = ( HBMXML_NODE * ) hb_parptrGC( &s_gc_mxml_nodeFuncs, 1 ); if( pHbnode && pHbnode->node ) { mxmlRemoveRef( pHbnode->node ); hbmxml_release( pHbnode->node ); pHbnode->node = NULL; } else MXML_ERR_ARGS(); } #if 0 /* int mxmlRelease( mxml_node_t * node ) */ HB_FUNC( MXMLRELEASE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlRelease( node ) ); else MXML_ERR_ARGS(); } /* int mxmlRetain( mxml_node_t * node ) */ HB_FUNC( MXMLRETAIN ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlRetain( node ) ); else MXML_ERR_ARGS(); } #endif /* void ( * mxml_sax_cb_t )( mxml_node_t *, mxml_sax_event_t, void * ) */ static void sax_cb( mxml_node_t * node, mxml_sax_event_t event, void * data ) { HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackTestTSD( &s_cbs_var ); if( node != NULL && pCbs != NULL ) { PHB_ITEM pCallback = pCbs->sax_cb; if( pCallback && hb_vmRequestReenter() ) { HB_USHORT uPCount = 2; hb_vmPushEvalSym(); hb_vmPush( pCallback ); mxml_node_push( node, 0 ); hb_vmPushInteger( ( int ) ( event + 1 ) ); if( data != NULL ) { hb_vmPush( ( PHB_ITEM ) data ); uPCount++; } hb_vmSend( uPCount ); hb_vmRequestRestore(); } } } /* mxml_node_t * mxmlSAXLoadFile( mxml_node_t * top, FILE * fp, mxml_load_cb_t cb, mxml_sax_cb_t sax_cb, void * sax_data ) */ HB_FUNC( MXMLSAXLOADFILE ) { mxml_node_t * node_top; mxml_node_t * node; mxml_load_cb_t cb = MXML_NO_CALLBACK; mxml_sax_cb_t cb_sax = MXML_NO_CALLBACK; PHB_ITEM pData = ( hb_pcount() > 4 ) ? hb_param( 5, HB_IT_ANY ) : NULL; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); FILE * file; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) node_top = MXML_NO_PARENT; else { node_top = mxml_node_param( 1 ); if( ! node_top ) { MXML_ERR_ARGS(); return; } } if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->type_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = type_cb; } else if( HB_ISNUM( 3 ) ) { switch( hb_parni( 3 ) ) { case 0: cb = MXML_NO_CALLBACK; break; case 1: cb = MXML_INTEGER_CALLBACK; break; case 2: cb = MXML_OPAQUE_CALLBACK; break; case 3: cb = MXML_REAL_CALLBACK; break; case 4: cb = MXML_TEXT_CALLBACK; break; case 5: cb = MXML_IGNORE_CALLBACK; break; default: cb = MXML_NO_CALLBACK; } } if( HB_ISBLOCK( 4 ) || HB_ISSYMBOL( 4 ) ) { pCbs->sax_cb = hb_param( 4, HB_IT_BLOCK | HB_IT_SYMBOL ); cb_sax = sax_cb; } file = hb_fopen( hb_parc( 2 ), "rb" ); if( file ) { node = mxmlSAXLoadFile( node_top, file, cb, cb_sax, pData ); mxml_node_ret( node, ( node_top == MXML_NO_PARENT ) ? 1 : 0 ); fclose( file ); } pCbs->type_cb = NULL; pCbs->sax_cb = NULL; } /* mxml_node_t * mxmlSAXLoadString( mxml_node_t * top, const char * s, mxml_load_cb_t cb, mxml_sax_cb_t sax_cb, void * sax_data ) */ HB_FUNC( MXMLSAXLOADSTRING ) { void * hFree; mxml_node_t * node_top; mxml_node_t * node; mxml_load_cb_t cb = MXML_NO_CALLBACK; mxml_sax_cb_t cb_sax = MXML_NO_CALLBACK; PHB_ITEM pData = ( hb_pcount() > 4 ) ? hb_param( 5, HB_IT_ANY ) : NULL; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); const char * s; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) node_top = MXML_NO_PARENT; else { node_top = mxml_node_param( 1 ); if( ! node_top ) { MXML_ERR_ARGS(); return; } } if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->type_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = type_cb; } else if( HB_ISNUM( 3 ) ) { switch( hb_parni( 3 ) ) { case 0: cb = MXML_NO_CALLBACK; break; case 1: cb = MXML_INTEGER_CALLBACK; break; case 2: cb = MXML_OPAQUE_CALLBACK; break; case 3: cb = MXML_REAL_CALLBACK; break; case 4: cb = MXML_TEXT_CALLBACK; break; case 5: cb = MXML_IGNORE_CALLBACK; break; default: cb = MXML_NO_CALLBACK; } } if( HB_ISBLOCK( 4 ) || HB_ISSYMBOL( 4 ) ) { pCbs->sax_cb = hb_param( 4, HB_IT_BLOCK | HB_IT_SYMBOL ); cb_sax = sax_cb; } s = hb_parstr_utf8( 2, &hFree, NULL ); if( s ) { node = mxmlSAXLoadString( node_top, s, cb, cb_sax, pData ); mxml_node_ret( node, ( node_top == MXML_NO_PARENT ) ? 1 : 0 ); } pCbs->type_cb = NULL; pCbs->sax_cb = NULL; hb_strfree( hFree ); } /* const char *( * mxml_save_cb_t )( mxml_node_t *, int ) */ static const char * save_cb( mxml_node_t * node, int where ) { HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackTestTSD( &s_cbs_var ); if( node != NULL && pCbs != NULL ) { PHB_ITEM pCallback = pCbs->save_cb; if( pCbs->hText ) { hb_strfree( pCbs->hText ); pCbs->hText = NULL; } if( pCallback && hb_vmRequestReenter() ) { const char * pszResult; hb_vmPushEvalSym(); hb_vmPush( pCallback ); mxml_node_push( node, 0 ); hb_vmPushInteger( where ); hb_vmSend( 2 ); pszResult = hb_itemGetStrUTF8( hb_param( -1, HB_IT_ANY ), &pCbs->hText, NULL ); hb_vmRequestRestore(); return pszResult; } } return NULL; } /* char * mxmlSaveAllocString( mxml_node_t *node, mxml_save_cb_t cb ) */ HB_FUNC( MXMLSAVEALLOCSTRING ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { mxml_save_cb_t cb = MXML_NO_CALLBACK; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); char buffer[ 8192 ]; int bytes; if( HB_ISBLOCK( 2 ) || HB_ISSYMBOL( 2 ) ) { pCbs->save_cb = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = save_cb; } bytes = mxmlSaveString( node, buffer, sizeof( buffer ), cb ); pCbs->save_cb = NULL; if( pCbs->hText ) { hb_strfree( pCbs->hText ); pCbs->hText = NULL; } if( bytes <= 0 ) hb_retc_null(); else if( bytes < ( int ) sizeof( buffer ) ) hb_retclen( buffer, bytes ); else { char * s = ( char * ) hb_xalloc( bytes + 1 ); if( s == NULL ) hb_retc_null(); else { mxmlSaveString( node, s, bytes + 1, cb ); hb_retclen_buffer( s, bytes ); } } } else MXML_ERR_ARGS(); } HB_FUNC( MXMLSAVEFILE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node && HB_ISCHAR( 2 ) ) { FILE * file; mxml_save_cb_t cb = MXML_NO_CALLBACK; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->save_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = save_cb; } file = hb_fopen( hb_parc( 2 ), "wb" ); if( file ) { hb_retni( mxmlSaveFile( node, file, cb ) ); fclose( file ); } pCbs->save_cb = NULL; if( pCbs->hText ) { hb_strfree( pCbs->hText ); pCbs->hText = NULL; } } else MXML_ERR_ARGS(); } /* int mxmlSaveString( mxml_node_t * node, char * buffer, int bufsize, mxml_save_cb_t cb ) */ HB_FUNC( MXMLSAVESTRING ) { mxml_node_t * node = mxml_node_param( 1 ); PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); if( node ) { mxml_save_cb_t cb = MXML_NO_CALLBACK; HB_CBS_VAR * pCbs = ( HB_CBS_VAR * ) hb_stackGetTSD( &s_cbs_var ); if( pBuffer && HB_ISBYREF( 2 ) && hb_parcsiz( 2 ) > 0 ) { char * buffer; HB_SIZE buffer_size; int bytes; if( hb_itemGetWriteCL( pBuffer, &buffer, &buffer_size ) ) { if( HB_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) ) { pCbs->save_cb = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ); cb = save_cb; } bytes = mxmlSaveString( node, buffer, ( int ) ( buffer_size + 1 ), cb ); if( bytes > 0 && ( HB_SIZE ) bytes <= buffer_size ) hb_storclen( buffer, bytes, 2 ); hb_retni( bytes ); pCbs->save_cb = NULL; if( pCbs->hText ) { hb_strfree( pCbs->hText ); pCbs->hText = NULL; } return; } } } MXML_ERR_ARGS(); } /* int mxmlSetCDATA( mxml_node_t * node, const char * data ) */ HB_FUNC( MXMLSETCDATA ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hData; hb_retni( mxmlSetCDATA( node, hb_parstr_utf8( 2, &hData, NULL ) ) ); hb_strfree( hData ); } else MXML_ERR_ARGS(); } /* int mxmlSetElement( mxml_node_t * node, const char * name ) */ HB_FUNC( MXMLSETELEMENT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hFree; hb_retni( mxmlSetElement( node, hb_parstr_utf8( 2, &hFree, NULL ) ) ); hb_strfree( hFree ); } else MXML_ERR_ARGS(); } /* void ( * mxml_error_cb_t )( const char * ) */ static void error_cb( const char * pszErrorMsg ) { HB_ERROR_CB_VAR * pError_cb = ( HB_ERROR_CB_VAR * ) hb_stackTestTSD( &s_error_cb_var ); if( pError_cb != NULL ) { PHB_ITEM pCallback = pError_cb->error_cb; if( pCallback && hb_vmRequestReenter() ) { hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_itemPutC( hb_stackAllocItem(), pszErrorMsg ); hb_vmSend( 1 ); hb_vmRequestRestore(); } } } HB_FUNC( MXMLSETERRORCALLBACK ) { PHB_ITEM pError = hb_param( 1, HB_IT_BLOCK | HB_IT_SYMBOL ); if( pError ) { HB_ERROR_CB_VAR * pError_cb = ( HB_ERROR_CB_VAR * ) hb_stackGetTSD( &s_error_cb_var ); if( pError_cb->error_cb ) hb_itemRelease( pError_cb->error_cb ); pError_cb->error_cb = hb_itemNew( pError ); mxmlSetErrorCallback( error_cb ); } else { HB_ERROR_CB_VAR * pError_cb = ( HB_ERROR_CB_VAR * ) hb_stackTestTSD( &s_error_cb_var ); if( pError_cb && pError_cb->error_cb ) { hb_itemRelease( pError_cb->error_cb ); pError_cb->error_cb = NULL; } mxmlSetErrorCallback( NULL ); } } /* int mxmlSetInteger( mxml_node_t * node, int integer ) */ HB_FUNC( MXMLSETINTEGER ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlSetInteger( node, hb_parnidef( 2, 0 ) ) ); else MXML_ERR_ARGS(); } /* int mxmlSetOpaque( mxml_node_t * node, const char * opaque ) */ HB_FUNC( MXMLSETOPAQUE ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hOpaque; hb_retni( mxmlSetOpaque( node, hb_parstr_utf8( 2, &hOpaque, NULL ) ) ); hb_strfree( hOpaque ); } else MXML_ERR_ARGS(); } /* int mxmlSetReal( mxml_node_t * node, double real ) */ HB_FUNC( MXMLSETREAL ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) hb_retni( mxmlSetReal( node, hb_parnd( 2 ) ) ); else MXML_ERR_ARGS(); } /* int mxmlSetText( mxml_node_t * node, int whitespace, const char * string ) */ HB_FUNC( MXMLSETTEXT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { void * hString; hb_retni( mxmlSetText( node, hb_parnidef( 2, 1 ), hb_parstr_utf8( 3, &hString, NULL ) ) ); hb_strfree( hString ); } else MXML_ERR_ARGS(); } /* int mxmlSetUserData(mxml_node_t * node, void * data ) */ HB_FUNC( MXMLSETUSERDATA ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { PHB_ITEM pItem = hb_itemClone( hb_param( 2, HB_IT_ANY ) ); if( pItem ) hb_retni( mxmlSetUserData( node, pItem ) ); } else MXML_ERR_ARGS(); } /* void mxmlSetWrapMargin( int column ) */ HB_FUNC( MXMLSETWRAPMARGIN ) { mxmlSetWrapMargin( hb_parni( 1 ) ); } /* mxml_node_t * mxmlWalkNext( mxml_node_t * node, mxml_node_t * top, int descend ) */ HB_FUNC( MXMLWALKNEXT ) { mxml_node_t * node = mxml_node_param( 1 ); mxml_node_t * top = mxml_node_param( 2 ); if( node && top ) { mxml_node_t * node_next = mxmlWalkNext( node, top, hb_parnidef( 3, MXML_NO_DESCEND ) ); mxml_node_ret( node_next, 0 ); } else MXML_ERR_ARGS(); } /* mxml_node_t * mxmlWalkPrev( mxml_node_t * node, mxml_node_t * top, int descend ) */ HB_FUNC( MXMLWALKPREV ) { mxml_node_t * node = mxml_node_param( 1 ); mxml_node_t * top = mxml_node_param( 2 ); if( node && top ) { mxml_node_t * node_prev = mxmlWalkPrev( node, top, hb_parnidef( 3, MXML_NO_DESCEND ) ); mxml_node_ret( node_prev, 0 ); } else MXML_ERR_ARGS(); } /* const void * mxmlGetCustom( mxml_node_t * node ) */ HB_FUNC( MXMLGETCUSTOM ) { mxml_node_t * node = mxml_node_param( 1 ); if( node ) { PHB_ITEM pItem = ( PHB_ITEM ) HB_UNCONST( mxmlGetCustom( node ) ); if( pItem ) hb_itemReturn( pItem ); } else MXML_ERR_ARGS(); } /* void ( * mxml_custom_destroy_cb_t )( void * ) */ static void custom_destroy_cb( void * Cargo ) { PHB_ITEM pItem = ( PHB_ITEM ) Cargo; if( pItem != NULL ) hb_itemRelease( pItem ); } /* mxml_node_t * mxmlNewCustom( mxml_node_t * parent, void * data, mxml_custom_destroy_cb_t destroy ) */ HB_FUNC( MXMLNEWCUSTOM ) { if( hb_pcount() > 1 ) { PHB_ITEM pItem = hb_itemClone( hb_param( 2, HB_IT_ANY ) ); mxml_node_t * parent = MXML_NO_PARENT; mxml_node_t * node = NULL; if( HB_ISNIL( 1 ) || ( HB_ISNUM( 1 ) && hb_parni( 1 ) == MXML_NO_PARENT ) ) node = mxmlNewCustom( MXML_NO_PARENT, pItem, custom_destroy_cb ); else { parent = mxml_node_param( 1 ); if( parent != NULL ) node = mxmlNewCustom( parent, pItem, custom_destroy_cb ); } if( node ) { mxml_node_ret( node, ( parent == MXML_NO_PARENT ) ? 1 : 0 ); return; } hb_itemRelease( pItem ); } MXML_ERR_ARGS(); } /* int mxmlSetCustom ( mxml_node_t * node, void * data, mxml_custom_destroy_cb_t destroy ) */ HB_FUNC( MXMLSETCUSTOM ) { mxml_node_t * node = mxml_node_param( 1 ); if( node && hb_pcount() > 1 ) { PHB_ITEM pItem = hb_itemClone( hb_param( 2, HB_IT_ANY ) ); if( pItem ) { int iResult = mxmlSetCustom( node, pItem, custom_destroy_cb ); if( iResult < 0 ) hb_itemRelease( pItem ); hb_retni( iResult ); } } else MXML_ERR_ARGS(); } /* int ( * mxml_custom_load_cb_t )( mxml_node_t *, const char * ) */ static int custom_load_cb( mxml_node_t * node, const char * data ) { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) hb_stackTestTSD( &s_custom_cbs_var ); if( node != NULL && pCCbs != NULL && data != NULL ) { PHB_ITEM pCallback = pCCbs->load_cb; if( pCallback && hb_vmRequestReenter() ) { int iResult; hb_vmPushEvalSym(); hb_vmPush( pCallback ); mxml_node_push( node, 0 ); hb_itemPutC( hb_stackAllocItem(), data ); hb_vmSend( 2 ); iResult = hb_parnidef( -1, 1 ); hb_vmRequestRestore(); return iResult; } } return 1; } /* char * ( * mxml_custom_save_cb_t )( mxml_node_t * ) */ static char * custom_save_cb( mxml_node_t * node ) { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) hb_stackTestTSD( &s_custom_cbs_var ); if( node != NULL && pCCbs != NULL ) { PHB_ITEM pCallback = pCCbs->save_cb; if( pCallback && hb_vmRequestReenter() ) { char * pszResult; const char * pszText; void * hText; hb_vmPushEvalSym(); hb_vmPush( pCallback ); mxml_node_push( node, 0 ); hb_vmSend( 1 ); pszText = hb_parstr_utf8( -1, &hText, NULL ); pszResult = pszText ? strdup( pszText ) : NULL; hb_strfree( hText ); hb_vmRequestRestore(); return pszResult; } } return NULL; } /* void mxmlSetCustomHandlers( mxml_custom_load_cb_t load, mxml_custom_save_cb_t save ) */ HB_FUNC( MXMLSETCUSTOMHANDLERS ) { PHB_ITEM pLoad = hb_param( 1, HB_IT_BLOCK | HB_IT_SYMBOL ), pSave = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ); if( pLoad && pSave ) { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) hb_stackGetTSD( &s_custom_cbs_var ); if( pCCbs->load_cb ) hb_itemRelease( pCCbs->load_cb ); pCCbs->load_cb = hb_itemNew( pLoad ); if( pCCbs->save_cb ) hb_itemRelease( pCCbs->save_cb ); pCCbs->save_cb = hb_itemNew( pSave ); mxmlSetCustomHandlers( custom_load_cb, custom_save_cb ); } else { HB_CUSTOM_CBS_VAR * pCCbs = ( HB_CUSTOM_CBS_VAR * ) hb_stackTestTSD( &s_custom_cbs_var ); if( pCCbs ) { if( pCCbs->load_cb ) { hb_itemRelease( pCCbs->load_cb ); pCCbs->load_cb = NULL; } if( pCCbs->save_cb ) { hb_itemRelease( pCCbs->save_cb ); pCCbs->save_cb = NULL; } } mxmlSetCustomHandlers( NULL, NULL ); } } /* temporary solution before final 2.7 release */ HB_FUNC( HB_MXMLGETATTRSCOUNT ) { mxml_node_t * node = mxml_node_param( 1 ); if( node && mxmlGetType( node ) == MXML_ELEMENT ) hb_retni( node->value.element.num_attrs ); else MXML_ERR_ARGS(); } HB_FUNC( HB_MXMLGETATTRSARRAY ) { mxml_node_t * node = mxml_node_param( 1 ); if( node && mxmlGetType( node ) == MXML_ELEMENT ) { PHB_ITEM pAttrs = hb_itemArrayNew( 0 ); PHB_ITEM pAttr = hb_itemNew( NULL ); int i; mxml_attr_t * attr; for( i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i--, attr++ ) { hb_arrayNew( pAttr, 2 ); hb_arraySetStrUTF8( pAttr, 1, attr->name ); hb_arraySetStrUTF8( pAttr, 2, attr->value ); hb_arrayAddForward( pAttrs, pAttr ); } hb_itemRelease( pAttr ); hb_itemReturnRelease( pAttrs ); } else MXML_ERR_ARGS(); } HB_FUNC( HB_MXMLGETATTRS ) { mxml_node_t * node = mxml_node_param( 1 ); if( node && mxmlGetType( node ) == MXML_ELEMENT ) { PHB_ITEM pAttrs = hb_hashNew( hb_itemNew( NULL ) ); PHB_ITEM pKey = NULL; PHB_ITEM pValue = NULL; int i; mxml_attr_t * attr; for( i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i--, attr++ ) { pKey = hb_itemPutStrUTF8( pKey, attr->name ); pValue = hb_itemPutStrUTF8( pValue, attr->value ); hb_hashAdd( pAttrs, pKey, pValue ); } hb_itemRelease( pKey ); hb_itemRelease( pValue ); hb_itemReturnRelease( pAttrs ); } else MXML_ERR_ARGS(); }