From 74dae54b1b092aca744b4df6668569d6fc1153b5 Mon Sep 17 00:00:00 2001 From: Jonathan Beck Date: Sun, 11 Jan 2009 20:44:33 +0100 Subject: Add a pythyon binding to the library (using SWIG). --- Makefile.am | 2 +- configure.ac | 7 +- include/plist/plist.h | 3 + m4/ac_pkg_swig.m4 | 122 +++++++++++++++++++++++ m4/ac_python_devel.m4 | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++ m4/swig_python.m4 | 65 +++++++++++++ src/plist.c | 5 + swig/Makefile.am | 15 +++ swig/__init__.py | 1 + swig/plist.i | 171 ++++++++++++++++++++++++++++++++ 10 files changed, 654 insertions(+), 2 deletions(-) create mode 100644 m4/ac_pkg_swig.m4 create mode 100644 m4/ac_python_devel.m4 create mode 100644 m4/swig_python.m4 create mode 100644 swig/Makefile.am create mode 100644 swig/__init__.py create mode 100644 swig/plist.i diff --git a/Makefile.am b/Makefile.am index 264b0a3..fdb496d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src include plutil +SUBDIRS = src include plutil swig pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libplist-1.0.pc diff --git a/configure.ac b/configure.ac index 2f171e1..fb8a484 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,11 @@ AC_CONFIG_MACRO_DIR([m4]) AC_PROG_LIBTOOL +AM_PATH_PYTHON(2.3) +AC_PROG_SWIG(1.3.21) +SWIG_PYTHON + + # Checks for programs. AC_PROG_CC AM_PROG_CC_C_O @@ -48,4 +53,4 @@ fi AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter") AC_SUBST(GLOBAL_CFLAGS) -AC_OUTPUT(Makefile src/Makefile include/Makefile plutil/Makefile libplist-1.0.pc) +AC_OUTPUT(Makefile src/Makefile include/Makefile plutil/Makefile swig/Makefile libplist-1.0.pc) diff --git a/include/plist/plist.h b/include/plist/plist.h index b496d6f..976408d 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -71,7 +71,10 @@ plist_t plist_get_first_child(plist_t node); plist_t plist_get_next_sibling(plist_t node); plist_t plist_get_prev_sibling(plist_t node); +//utili function to find first (and only the first encountred) corresponding node plist_t plist_find_node(plist_t plist, plist_type type, void *value, uint64_t length); +plist_t plist_find_node_by_string(plist_t plist, char *value); + void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length); //Plist reading diff --git a/m4/ac_pkg_swig.m4 b/m4/ac_pkg_swig.m4 new file mode 100644 index 0000000..738f69d --- /dev/null +++ b/m4/ac_pkg_swig.m4 @@ -0,0 +1,122 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ac_pkg_swig.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_PROG_SWIG([major.minor.micro]) +# +# DESCRIPTION +# +# This macro searches for a SWIG installation on your system. If found you +# should call SWIG via $(SWIG). You can use the optional first argument to +# check if the version of the available SWIG is greater than or equal to +# the value of the argument. It should have the format: N[.N[.N]] (N is a +# number between 0 and 999. Only the first N is mandatory.) +# +# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that +# the swig package is this version number or higher. +# +# In configure.in, use as: +# +# AC_PROG_SWIG(1.3.17) +# SWIG_ENABLE_CXX +# SWIG_MULTI_MODULE_SUPPORT +# SWIG_PYTHON +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Sebastian Huber +# Copyright (c) 2008 Alan W. Irwin +# Copyright (c) 2008 Rafael Laboissiere +# Copyright (c) 2008 Andrew Collier +# +# 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AC_PROG_SWIG],[ + AC_PATH_PROG([SWIG],[swig]) + if test -z "$SWIG" ; then + AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org]) + SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' + elif test -n "$1" ; then + AC_MSG_CHECKING([for SWIG version]) + [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] + AC_MSG_RESULT([$swig_version]) + if test -n "$swig_version" ; then + # Calculate the required version number components + [required=$1] + [required_major=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_major" ; then + [required_major=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_minor=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_minor" ; then + [required_minor=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_patch=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_patch" ; then + [required_patch=0] + fi + # Calculate the available version number components + [available=$swig_version] + [available_major=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_major" ; then + [available_major=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_minor=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_minor" ; then + [available_minor=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_patch=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_patch" ; then + [available_patch=0] + fi + if test $available_major -ne $required_major \ + -o $available_minor -ne $required_minor \ + -o $available_patch -lt $required_patch ; then + AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) + SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' + else + AC_MSG_NOTICE([SWIG executable is '$SWIG']) + SWIG_LIB=`$SWIG -swiglib` + AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB']) + fi + else + AC_MSG_WARN([cannot determine SWIG version]) + SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false' + fi + fi + AC_SUBST([SWIG_LIB]) +]) diff --git a/m4/ac_python_devel.m4 b/m4/ac_python_devel.m4 new file mode 100644 index 0000000..7cec10f --- /dev/null +++ b/m4/ac_python_devel.m4 @@ -0,0 +1,265 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ac_python_devel.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_PYTHON_DEVEL([version]) +# +# DESCRIPTION +# +# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it +# in your configure.ac. +# +# This macro checks for Python and tries to get the include path to +# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) +# output variables. It also exports $(PYTHON_EXTRA_LIBS) and +# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code. +# +# You can search for some particular version of Python by passing a +# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please +# note that you *have* to pass also an operator along with the version to +# match, and pay special attention to the single quotes surrounding the +# version number. Don't use "PYTHON_VERSION" for this: that environment +# variable is declared as precious and thus reserved for the end-user. +# +# This macro should work for all versions of Python >= 2.1.0. As an end +# user, you can disable the check for the python version by setting the +# PYTHON_NOVERSIONCHECK environment variable to something else than the +# empty string. +# +# If you need to use this macro for an older Python version, please +# contact the authors. We're always open for feedback. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Sebastian Huber +# Copyright (c) 2008 Alan W. Irwin +# Copyright (c) 2008 Rafael Laboissiere +# Copyright (c) 2008 Andrew Collier +# Copyright (c) 2008 Matteo Settenvini +# Copyright (c) 2008 Horst Knorr +# +# 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 3 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AC_PYTHON_DEVEL],[ + # + # Allow the use of a (user set) custom python version + # + AC_ARG_VAR([PYTHON_VERSION],[The installed Python + version to use, for example '2.3'. This string + will be appended to the Python interpreter + canonical name.]) + + AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) + if test -z "$PYTHON"; then + AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path]) + PYTHON_VERSION="" + fi + + # + # Check for a version of Python >= 2.1.0 + # + AC_MSG_CHECKING([for a version of Python >= '2.1.0']) + ac_supports_python_ver=`$PYTHON -c "import sys, string; \ + ver = string.split(sys.version)[[0]]; \ + print ver >= '2.1.0'"` + if test "$ac_supports_python_ver" != "True"; then + if test -z "$PYTHON_NOVERSIONCHECK"; then + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([ +This version of the AC@&t@_PYTHON_DEVEL macro +doesn't work properly with versions of Python before +2.1.0. You may need to re-run configure, setting the +variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG, +PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. +Moreover, to disable this check, set PYTHON_NOVERSIONCHECK +to something else than an empty string. +]) + else + AC_MSG_RESULT([skip at user request]) + fi + else + AC_MSG_RESULT([yes]) + fi + + # + # if the macro parameter ``version'' is set, honour it + # + if test -n "$1"; then + AC_MSG_CHECKING([for a version of Python $1]) + ac_supports_python_ver=`$PYTHON -c "import sys, string; \ + ver = string.split(sys.version)[[0]]; \ + print ver $1"` + if test "$ac_supports_python_ver" = "True"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([this package requires Python $1. +If you have it installed, but it isn't the default Python +interpreter in your system path, please pass the PYTHON_VERSION +variable to configure. See ``configure --help'' for reference. +]) + PYTHON_VERSION="" + fi + fi + + # + # Check if you have distutils, else fail + # + AC_MSG_CHECKING([for the distutils Python package]) + ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` + if test -z "$ac_distutils_result"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([cannot import Python module "distutils". +Please check your Python installation. The error was: +$ac_distutils_result]) + PYTHON_VERSION="" + fi + + # + # Check for Python include path + # + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON_CPPFLAGS"; then + python_path=`$PYTHON -c "import distutils.sysconfig; \ + print distutils.sysconfig.get_python_inc();"` + if test -n "${python_path}"; then + python_path="-I$python_path" + fi + PYTHON_CPPFLAGS=$python_path + fi + AC_MSG_RESULT([$PYTHON_CPPFLAGS]) + AC_SUBST([PYTHON_CPPFLAGS]) + + # + # Check for Python library path + # + AC_MSG_CHECKING([for Python library path]) + if test -z "$PYTHON_LDFLAGS"; then + # (makes two attempts to ensure we've got a version number + # from the interpreter) + py_version=`$PYTHON -c "from distutils.sysconfig import *; \ + from string import join; \ + print join(get_config_vars('VERSION'))"` + if test "$py_version" == "[None]"; then + if test -n "$PYTHON_VERSION"; then + py_version=$PYTHON_VERSION + else + py_version=`$PYTHON -c "import sys; \ + print sys.version[[:3]]"` + fi + fi + + PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \ + from string import join; \ + print '-L' + get_python_lib(0,1), \ + '-lpython';"`$py_version + fi + AC_MSG_RESULT([$PYTHON_LDFLAGS]) + AC_SUBST([PYTHON_LDFLAGS]) + + # + # Check for site packages + # + AC_MSG_CHECKING([for Python site-packages path]) + if test -z "$PYTHON_SITE_PKG"; then + PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \ + print distutils.sysconfig.get_python_lib(0,0);"` + fi + AC_MSG_RESULT([$PYTHON_SITE_PKG]) + AC_SUBST([PYTHON_SITE_PKG]) + + # + # libraries which must be linked in when embedding + # + AC_MSG_CHECKING(python extra libraries) + if test -z "$PYTHON_EXTRA_LIBS"; then + PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LOCALMODLIBS'), conf('LIBS')"` + fi + AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) + AC_SUBST(PYTHON_EXTRA_LIBS) + + # + # linking flags needed when embedding + # + AC_MSG_CHECKING(python extra linking flags) + if test -z "$PYTHON_EXTRA_LDFLAGS"; then + PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LINKFORSHARED')"` + fi + AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) + AC_SUBST(PYTHON_EXTRA_LDFLAGS) + + # + # final check to see if everything compiles alright + # + AC_MSG_CHECKING([consistency of all components of python development environment]) + AC_LANG_PUSH([C]) + # save current global flags + LIBS="$ac_save_LIBS $PYTHON_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" + AC_TRY_LINK([ + #include + ],[ + Py_Initialize(); + ],[pythonexists=yes],[pythonexists=no]) + + AC_MSG_RESULT([$pythonexists]) + + if test ! "$pythonexists" = "yes"; then + AC_MSG_ERROR([ + Could not link test program to Python. Maybe the main Python library has been + installed in some non-standard library path. If so, pass it to configure, + via the LDFLAGS environment variable. + Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib" + ============================================================================ + ERROR! + You probably have to install the development version of the Python package + for your distribution. The exact name of this package varies among them. + ============================================================================ + ]) + PYTHON_VERSION="" + fi + AC_LANG_POP + # turn back to default flags + CPPFLAGS="$ac_save_CPPFLAGS" + LIBS="$ac_save_LIBS" + + # + # all done! + # +]) diff --git a/m4/swig_python.m4 b/m4/swig_python.m4 new file mode 100644 index 0000000..2496976 --- /dev/null +++ b/m4/swig_python.m4 @@ -0,0 +1,65 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/swig_python.html +# =========================================================================== +# +# SYNOPSIS +# +# SWIG_PYTHON([use-shadow-classes = {no, yes}]) +# +# DESCRIPTION +# +# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), and +# $(SWIG_PYTHON_OPT) output variables. +# +# $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate code +# for Python. Shadow classes are enabled unless the value of the optional +# first argument is exactly 'no'. If you need multi module support +# (provided by the SWIG_MULTI_MODULE_SUPPORT macro) use +# $(SWIG_PYTHON_LIBS) to link against the appropriate library. It contains +# the SWIG Python runtime library that is needed by the type check system +# for example. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Sebastian Huber +# Copyright (c) 2008 Alan W. Irwin +# Copyright (c) 2008 Rafael Laboissiere +# Copyright (c) 2008 Andrew Collier +# +# 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([SWIG_PYTHON],[ + AC_REQUIRE([AC_PROG_SWIG]) + AC_REQUIRE([AC_PYTHON_DEVEL]) + test "x$1" != "xno" || swig_shadow=" -noproxy" + AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow]) + AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS]) +]) diff --git a/src/plist.c b/src/plist.c index 640bbe5..adee262 100644 --- a/src/plist.c +++ b/src/plist.c @@ -194,6 +194,11 @@ plist_t plist_find_node(plist_t plist, plist_type type, void *value, uint64_t le return NULL; } +plist_t plist_find_node_by_string(plist_t plist, char *value) +{ + return plist_find_node(plist, PLIST_STRING, value, strlen(value)); +} + void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) { if (!node) diff --git a/swig/Makefile.am b/swig/Makefile.am new file mode 100644 index 0000000..2e5b280 --- /dev/null +++ b/swig/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/include + +BUILT_SOURCES = $(srcdir)/plist_wrap.c +SWIG_SOURCES = plist.i + +pkgpython_PYTHON = PList.py __init__.py +pkgpyexec_LTLIBRARIES = _PList.la +_PList_la_SOURCES = $(srcdir)/plist_wrap.c $(SWIG_SOURCES) +_PList_la_CFLAGS = $(PYTHON_CPPFLAGS) -I$(top_srcdir)/src +_PList_la_LDFLAGS = -module $(PYTHON_LDFLAGS) +_PList_la_LIBADD = ../src/libplist.la + +$(srcdir)/plist_wrap.c : $(SWIG_SOURCES) + $(SWIG) $(SWIG_PYTHON_OPT) $(INCLUDES) -I$(top_srcdir)/src -o $@ $< + diff --git a/swig/__init__.py b/swig/__init__.py new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/swig/__init__.py @@ -0,0 +1 @@ + diff --git a/swig/plist.i b/swig/plist.i new file mode 100644 index 0000000..78f102f --- /dev/null +++ b/swig/plist.i @@ -0,0 +1,171 @@ + /* swig.i */ + %module PList + %{ + /* Includes the header in the wrapper code */ + #include +typedef struct { + plist_t node; +} PListNode; + %} +/* Parse the header file to generate wrappers */ +typedef enum { + PLIST_BOOLEAN, + PLIST_UINT, + PLIST_REAL, + PLIST_STRING, + PLIST_UNICODE, + PLIST_ARRAY, + PLIST_DICT, + PLIST_DATE, + PLIST_DATA, + PLIST_KEY, + PLIST_NONE +} plist_type; + +typedef struct { + plist_t node; +} PListNode; + +%extend PListNode { // Attach these functions to struct Vector + PListNode(plist_type t) { + PListNode* node = NULL; + switch (t) { + case PLIST_ARRAY : + node = (PListNode*) malloc(sizeof(PListNode)); + node->node = plist_new_array(); + break; + case PLIST_DICT : + node = (PListNode*) malloc(sizeof(PListNode)); + node->node = plist_new_dict(); + break; + default : + node = NULL; + break; + } + return node; + } + + PListNode(char* xml) { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist_from_xml(xml, strlen(xml), &plist->node); + return plist; + } + + PListNode(char* bin, uint64_t len) { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist_from_bin(bin, len, &plist->node); + return plist; + } + + ~PListNode() { + plist_free($self->node); + free($self); + } + + void AddSubNode(PListNode* subnode) { + plist_add_sub_node($self->node, subnode); + } + + void AddSubKey(char* k) { + plist_add_sub_key_el($self->node, k); + } + + void AddSubString(char* s) { + plist_add_sub_string_el($self->node, s); + } + + void AddSubBool(char b) { + plist_add_sub_bool_el($self->node, b); + } + + void AddSubUInt(uint64_t i) { + plist_add_sub_uint_el($self->node, i); + } + + void AddSubReal(double d) { + plist_add_sub_real_el($self->node, d); + } + + void AddSubData(char* v, uint64_t l) { + plist_add_sub_data_el($self->node, v, l); + } + + PListNode* GetFirstChild() { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist_get_first_child(&$self->node); + return plist; + } + + PListNode* GetNextSibling() { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist_get_next_sibling(&$self->node); + return plist; + } + + PListNode* GetPrevSibling() { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist_get_prev_sibling(&$self->node); + return plist; + } + + char* AsKey() { + char* k = NULL; + plist_get_key_val($self->node, &k); + return k; + } + + char* AsString() { + char* s = NULL; + plist_get_string_val($self->node, &s); + return s; + } + + char AsBool() { + char b; + plist_get_bool_val($self->node, &b); + return b; + } + + uint64_t AsUInt() { + uint64_t i = 0; + plist_get_uint_val($self->node, &i); + return i; + } + + double AsReal() { + double d = 0; + plist_get_real_val($self->node, &d); + return d; + } + + char* AsData() { + char* v; + uint64_t l; + plist_get_data_val($self->node, &v, &l); + return v; + } + + plist_type GetType() { + return plist_get_node_type($self->node); + } + + PListNode* FindSubNodeByString(char* s) { + PListNode* plist = (PListNode*) malloc(sizeof(PListNode)); + plist = plist_find_node_by_string($self->node, s); + return plist; + } + + char* ToXml () { + char* s = NULL; + uint32_t l; + plist_to_xml($self->node, &s, &l); + return s; + } + + char* ToBin () { + char* s = NULL; + uint32_t l; + plist_to_bin($self->node, &s, &l); + return s; + } +}; \ No newline at end of file -- cgit v1.1-32-gdbae