4242#include <Python.h>
4343
4444#include <libxml/tree.h>
45+ #include "libxml_wrap.h"
4546
4647#include "xmlpythonizer.h"
4748#include "dmidecodemodule.h"
@@ -245,18 +246,9 @@ xmlNode* load_mappingxml(options *opt) {
245246 return dmiMAP_GetRootElement (opt -> mappingxml );
246247}
247248
248- static PyObject * dmidecode_get_group (options * opt , const char * section )
249- {
250- PyObject * pydata = NULL ;
249+ xmlNode * __dmidecode_xml_getsection (options * opt , const char * section ) {
251250 xmlNode * dmixml_n = NULL ;
252251 xmlNode * group_n = NULL ;
253- ptzMAP * mapping = NULL ;
254-
255- /* Set default option values */
256- if ( opt -> devmem == NULL ) {
257- opt -> devmem = DEFAULT_MEM_DEV ;
258- }
259- opt -> flags = 0 ;
260252
261253 dmixml_n = xmlNewNode (NULL , (xmlChar * ) "dmidecode" );
262254 assert ( dmixml_n != NULL );
@@ -319,6 +311,27 @@ static PyObject *dmidecode_get_group(options *opt, const char *section)
319311 xmlSaveFormatFileEnc ("-" , doc , "UTF-8" , 1 );
320312 xmlFreeDoc (doc );
321313#endif
314+ return dmixml_n ;
315+ }
316+
317+ static PyObject * dmidecode_get_group (options * opt , const char * section )
318+ {
319+ PyObject * pydata = NULL ;
320+ xmlNode * dmixml_n = NULL ;
321+ ptzMAP * mapping = NULL ;
322+
323+ /* Set default option values */
324+ if ( opt -> devmem == NULL ) {
325+ opt -> devmem = DEFAULT_MEM_DEV ;
326+ }
327+ opt -> flags = 0 ;
328+
329+ // Decode the dmidata into an XML node
330+ dmixml_n = __dmidecode_xml_getsection (opt , section );
331+ if ( dmixml_n == NULL ) {
332+ // Exception already set
333+ return NULL ;
334+ }
322335
323336 // Convert the retrieved XML nodes to a Python dictionary
324337 mapping = dmiMAP_ParseMappingXML_GroupName (opt -> mappingxml , section );
@@ -339,11 +352,9 @@ static PyObject *dmidecode_get_group(options *opt, const char *section)
339352}
340353
341354
342- static PyObject * dmidecode_get_typeid (options * opt , int typeid )
355+ xmlNode * __dmidecode_xml_gettypeid (options * opt , int typeid )
343356{
344- PyObject * pydata = NULL ;
345357 xmlNode * dmixml_n = NULL ;
346- ptzMAP * mapping = NULL ;
347358
348359 /* Set default option values */
349360 if ( opt -> devmem == NULL ) {
@@ -369,6 +380,22 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid)
369380 PyReturnError (PyExc_RuntimeError , "Error decoding DMI data" );
370381 }
371382
383+ return dmixml_n ;
384+ }
385+
386+
387+ static PyObject * dmidecode_get_typeid (options * opt , int typeid )
388+ {
389+ PyObject * pydata = NULL ;
390+ xmlNode * dmixml_n = NULL ;
391+ ptzMAP * mapping = NULL ;
392+
393+ dmixml_n = __dmidecode_xml_gettypeid (opt , typeid );
394+ if ( dmixml_n == NULL ) {
395+ // Exception already set
396+ return NULL ;
397+ }
398+
372399 // Convert the retrieved XML nodes to a Python dictionary
373400 mapping = dmiMAP_ParseMappingXML_TypeID (opt -> mappingxml , opt -> type );
374401 if ( mapping == NULL ) {
@@ -448,6 +475,77 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args)
448475 return pydata ;
449476}
450477
478+ static PyObject * dmidecode_xmlapi (PyObject * self , PyObject * args , PyObject * keywds )
479+ {
480+ static char * keywordlist [] = {"query_type" , "result_type" , "section" , "typeid" };
481+ PyObject * pydata = NULL ;
482+ xmlDoc * dmixml_doc = NULL ;
483+ xmlNode * dmixml_n = NULL ;
484+ char * sect_query = NULL , * qtype = NULL , * rtype = NULL ;
485+ int type_query = -1 ;
486+
487+ // Parse the keywords - we only support keywords, as this is an internal API
488+ if ( !PyArg_ParseTupleAndKeywords (args , keywds , "ss|si" , keywordlist ,
489+ & qtype , & rtype , & sect_query , & type_query ) ) {
490+ return NULL ;
491+ }
492+
493+ // Check for sensible arguments and retrieve the xmlNode with DMI data
494+ switch ( * qtype ) {
495+ case 's' : // Section / GroupName
496+ if ( sect_query == NULL ) {
497+ PyReturnError (PyExc_TypeError , "section keyword cannot be NULL" )
498+ }
499+ dmixml_n = __dmidecode_xml_getsection (global_options , sect_query );
500+ break ;
501+
502+ case 't' : // TypeID / direct TypeMap
503+ if ( type_query < 0 ) {
504+ PyReturnError (PyExc_TypeError ,
505+ "typeid keyword must be set and must be a positive integer" );
506+ } else if ( type_query > 255 ) {
507+ PyReturnError (PyExc_ValueError ,
508+ "typeid keyword must be an integer between 0 and 255" );
509+ }
510+ dmixml_n = __dmidecode_xml_gettypeid (global_options , type_query );
511+ break ;
512+
513+ default :
514+ PyReturnError (PyExc_TypeError , "Internal error - invalid query type '%c'" , * qtype );
515+ }
516+
517+ // Check if we got any data
518+ if ( dmixml_n == NULL ) {
519+ // Exception already set
520+ return NULL ;
521+ }
522+
523+ // Check for sensible return type and wrap the correct type into a Python Object
524+ switch ( * rtype ) {
525+ case 'n' :
526+ pydata = libxml_xmlNodePtrWrap ((xmlNode * ) dmixml_n );
527+ break ;
528+
529+ case 'd' :
530+ dmixml_doc = xmlNewDoc ((xmlChar * ) "1.0" );
531+ if ( dmixml_doc == NULL ) {
532+ PyReturnError (PyExc_MemoryError , "Could not create new XML document" );
533+ }
534+ xmlDocSetRootElement (dmixml_doc , dmixml_n );
535+ pydata = libxml_xmlDocPtrWrap ((xmlDoc * ) dmixml_doc );
536+ break ;
537+
538+ default :
539+ PyReturnError (PyExc_TypeError , "Internal error - invalid result type '%c'" , * rtype );
540+ }
541+
542+ // Return XML data
543+ Py_INCREF (pydata );
544+ return pydata ;
545+ }
546+
547+
548+
451549static PyObject * dmidecode_dump (PyObject * self , PyObject * null )
452550{
453551 const char * f ;
@@ -544,10 +642,14 @@ static PyMethodDef DMIDataMethods[] = {
544642 {(char * )"pythonmap" , dmidecode_set_pythonxmlmap , METH_O ,
545643 (char * ) "Use another python dict map definition. The default file is " PYTHON_XML_MAP },
546644
645+ {(char * )"xmlapi" , dmidecode_xmlapi , METH_KEYWORDS ,
646+ (char * ) "Internal API for retrieving data as raw XML data" },
647+
547648 {NULL , NULL , 0 , NULL }
548649};
549650
550- void destruct_options (void * ptr ) {
651+ void destruct_options (void * ptr )
652+ {
551653 options * opt = (options * ) ptr ;
552654
553655 if ( opt -> mappingxml != NULL ) {
0 commit comments