BASIC

Author Topic: XML  (Read 6997 times)

MrTAToad

  • Guest
XML
« on: 2010-Jun-22 »
This is a XML system (originally written by "Lymington") from his routine here : http://www.codeproject.com/KB/XML/XMJFileStreaming.aspx

As per usual, some changes were needed - removal of #include files, and in this instance removal of the need to put things into a data segment (the original code could be used by Visual Basic).

It allows reading and writing of XML files.  At the moment, I've only setup interfaces for reading, but the rest is no problem.

This is the test code :

Code: GLBasic [Select]
LOCAL result$

DEBUG XMJ_GetVersion$()+"\n"
DEBUG XMJ_GetDate$()+"\n"
DEBUG XMJ_ReadFile("test.xml","Order")+"\n"
DEBUG XMJ_GetFirstGroup("ITEM2",1)+"\n"
DEBUG XMJ_GetLastError$()+"\n"
DEBUG XMJ_GetNextGroup("ITEM",1)+"\n"
DEBUG XMJ_GetFirstGroup("Description",2)+"\n"
DEBUG XMJ_GetAttribute$("Description",result$)+"\n"
DEBUG "Result : "+result$+"\n"
DEBUG XMJ_GetFirstGroup("ITEM",1)+"\n"
DEBUG XMJ_GetAttribute$("Quantity",result$)+"\n"
DEBUG "Result : "+result$+"\n"

Current interface system :

Code: GLBasic [Select]
// --------------------------------- //
// Project: TestXML
// Start: Friday, June 18, 2010
// IDE Version: 8.006

INLINE
}
typedef int size_t;

// C commands
// mem... commands
extern "C" void *memset(void *s, int c, size_t n);
extern "C" void *memcpy(void *dest, const void *src, size_t n);
extern "C" int memcmp(const void *s1, const void *s2, size_t n);
extern "C" void * memmove(void * destination, const void * source, size_t num );

// Memory allocation/freeing commands
extern "C" void *realloc( void * ptr, size_t size );
extern "C" void *malloc ( size_t size );
extern "C" void *calloc(size_t nmemb, size_t size);
extern "C" void free(void *ptr);

// String commands
extern "C" char * strcat ( char * destination, const char * source );
extern "C" int strncmp ( const char * str1, const char * str2, size_t num );
extern "C" size_t strlen(const char *s);
extern "C" char * strcpy ( char * destination, const char * source );
extern "C" char * strncpy ( char * destination, const char * source, size_t num );
extern "C" int strcmp ( const char * str1, const char * str2 );
extern "C" int sprintf ( char * str, const char * format, ... );

// Low level I/O
extern "C" int access(const char *pathname, int mode);
extern "C" int open(const char *pathname, int flags);
extern "C" size_t READ(int fd, void *buf, size_t count);
extern "C" int write(int fd, char *buf, size_t count);
extern "C" int close(int fd);
extern "C" int rename(const char *_old, const char *_new);

// These are used with the open function
#ifdef WIN32
        typedef struct __RECT {
                long left;
                long top;
                long right;
                long bottom;
                } __RECT;

        typedef int HDC;

        /* Specifiy one of these flags TO define the access mode. */
        #define _O_RDONLY       0
        #define _O_WRONLY       1
        #define _O_RDWR         2

        /* Mask FOR access mode bits IN the _open flags. */
        #define _O_ACCMODE      (_O_RDONLY|_O_WRONLY|_O_RDWR)

        #define _O_APPEND       0x0008  /* Writes will add TO the END of the file. */

        #define _O_RANDOM       0x0010
        #define _O_SEQUENTIAL   0x0020
        #define _O_TEMPORARY    0x0040  /* Make the file dissappear after closing.
                                         * WARNING: Even IF NOT created by _open! */

        #define _O_NOINHERIT    0x0080

        #define _O_CREAT        0x0100  /* Create the file IF it does NOT exist. */
        #define _O_TRUNC        0x0200  /* Truncate the file IF it does exist. */
        #define _O_EXCL         0x0400  /* Open only IF the file does NOT exist. */

        #define _O_SHORT_LIVED  0x1000

        /* NOTE: Text is the DEFAULT even IF the given _O_TEXT bit is NOT on. */
        #define _O_TEXT         0x4000  /* CR-LF IN file becomes LF IN memory. */
        #define _O_BINARY       0x8000  /* INPUT AND output is NOT translated. */
        #define _O_RAW          _O_BINARY

        #ifndef _NO_OLDNAMES

        /* POSIX/Non-ANSI names FOR increased portability */
        #define O_RDONLY        _O_RDONLY
        #define O_WRONLY        _O_WRONLY
        #define O_RDWR          _O_RDWR
        #define O_ACCMODE       _O_ACCMODE
        #define O_APPEND        _O_APPEND
        #define O_CREAT         _O_CREAT
        #define O_TRUNC         _O_TRUNC
        #define O_EXCL          _O_EXCL
        #define O_TEXT          _O_TEXT
        #define O_BINARY        _O_BINARY
        #define O_TEMPORARY     _O_TEMPORARY
        #define O_NOINHERIT     _O_NOINHERIT
        #define O_SEQUENTIAL    _O_SEQUENTIAL
        #define O_RANDOM        _O_RANDOM

        #define SM_CXSCREEN 0
        #define SM_CYSCREEN 1
        #define HWND_BOTTOM     ((HWND)1)
        #define HWND_NOTOPMOST  ((HWND)(-2))
        #define HWND_TOP                ((HWND)0)
        #define HWND_TOPMOST    ((HWND)(-1))
        #define HWND_DESKTOP    (HWND)0
        #define HWND_MESSAGE    ((HWND)(-3))

        #define SWP_DRAWFRAME           0x0020
        #define SWP_FRAMECHANGED        0x0020
        #define SWP_HIDEWINDOW          0x0080
        #define SWP_NOACTIVATE          0x0010
        #define SWP_NOCOPYBITS          0x0100
        #define SWP_NOMOVE                      0x0002
        #define SWP_NOSIZE                      0x0001
        #define SWP_NOREDRAW            0x0008
        #define SWP_NOZORDER            0x0004
        #define SWP_SHOWWINDOW          0x0040
        #define SWP_NOOWNERZORDER       0x0200
        #define SWP_NOREPOSITION        SWP_NOOWNERZORDER
        #define SWP_NOSENDCHANGING      0x0400
        #define SWP_DEFERERASE          0x2000
        #define SWP_ASYNCWINDOWPOS      0x4000

        #define SW_HIDE             0
        #define SW_SHOWNORMAL       1
        #define SW_SHOWNOACTIVATE   4
        #define SW_SHOW             5
        #define SW_MINIMIZE         6
        #define SW_SHOWNA           8
        #define SW_SHOWMAXIMIZED        11
        #define SW_MAXIMIZE                     12
        #define SW_RESTORE                      13
        #define HORZRES 8
        #define VERTRES 10

        extern "C" __stdcall int GetSystemMetrics(int);
        extern "C" __stdcall int GetWindowRect(HWND hWnd,struct __RECT *lpRect);
        extern "C" __stdcall int GetClientRect(HWND hWnd,struct __RECT *lpRect);
        extern "C" __stdcall int SetWindowTextA(HWND hWnd,const char *lpString);
        extern "C" __stdcall HWND GetDesktopWindow(void);
        extern "C" __stdcall int SetWindowPos(HWND hWnd,HWND hWndInsertAfter,int X,int Y,int cx,int cy,int uFlags);
        extern "C" __stdcall int EnumDisplaySettingsA(const char*, unsigned int, void*);
        extern "C" __stdcall HWND GetForegroundWindow(void);
        extern "C" __stdcall int GetLastError(void);
        extern "C" __stdcall int GetSystemMetrics(int nIndex);
        extern "C" __stdcall HDC GetDC(HWND);
        extern "C" __stdcall int GetDeviceCaps(HDC,int);

        #endif
#elif _WIN32_CE
        /*
         * Flag values FOR open(2) AND fcntl(2)
         * The kernel adds 1 TO the open modes TO turn it into some
         * combination of FREAD AND FWRITE.
         */

        #define _FOPEN          (-1)    /* from sys/file.h, kernel use only */
        #define _FREAD          0x0001  /* READ enabled */
        #define _FWRITE         0x0002  /* write enabled */
        #define _FAPPEND        0x0008  /* append (writes guaranteed at the END) */
        #define _FMARK          0x0010  /* internal; mark during gc() */
        #define _FDEFER         0x0020  /* internal; defer FOR NEXT gc pass */
        #define _FASYNC         0x0040  /* signal pgrp when DATA ready */
        #define _FSHLOCK        0x0080  /* BSD flock() shared lock present */
        #define _FEXLOCK        0x0100  /* BSD flock() exclusive lock present */
        #define _FCREAT         0x0200  /* open with file create */
        #define _FTRUNC         0x0400  /* open with truncation */
        #define _FEXCL          0x0800  /* error on open IF file exists */
        #define _FNBIO          0x1000  /* non blocking I/O (sys5 style) */
        #define _FSYNC          0x2000  /* do all writes synchronously */
        #define _FNONBLOCK      0x4000  /* non blocking I/O (POSIX style) */
        #define _FNDELAY        _FNONBLOCK      /* non blocking I/O (4.2 style) */
        #define _FNOCTTY        0x8000  /* don't assign a ctty on this open */

        #define O_ACCMODE       (O_RDONLY|O_WRONLY|O_RDWR)

        #define O_RDONLY        0               /* +1 == FREAD */
        #define O_WRONLY        1               /* +1 == FWRITE */
        #define O_RDWR          2               /* +1 == FREAD|FWRITE */
        #define O_APPEND        _FAPPEND
        #define O_CREAT         _FCREAT
        #define O_TRUNC         _FTRUNC
        #define O_EXCL          _FEXCL
        /*      O_SYNC          _FSYNC          NOT posix, defined below */
        /*      O_NDELAY        _FNDELAY        set IN include/fcntl.h */
        /*      O_NDELAY        _FNBIO          set IN 5include/fcntl.h */
        #define O_NONBLOCK      _FNONBLOCK
        #define O_NOCTTY        _FNOCTTY
        /* FOR machines which care - */
        #if defined (_WIN32) || defined (__CYGWIN__)
        #define _FBINARY        0x10000
        #define _FTEXT          0x20000
        #define _FNOINHERIT     0x40000

        #define O_BINARY        _FBINARY
        #define O_TEXT          _FTEXT
        #define O_NOINHERIT     _FNOINHERIT

        /* The windows header files define versions with a leading underscore.  */
        #define _O_RDONLY       O_RDONLY
        #define _O_WRONLY       O_WRONLY
        #define _O_RDWR         O_RDWR
        #define _O_APPEND       O_APPEND
        #define _O_CREAT        O_CREAT
        #define _O_TRUNC        O_TRUNC
        #define _O_EXCL         O_EXCL
        #define _O_TEXT         O_TEXT
        #define _O_BINARY       O_BINARY
        #define _O_RAW          O_BINARY
        #define _O_NOINHERIT    O_NOINHERIT
        #endif

        #ifndef _POSIX_SOURCE

        #define O_SYNC          _FSYNC

        #endif
#else
        // For all other platforms
        #define _O_ACCMODE       00003
        #define _O_RDONLY           00
        #define _O_WRONLY           01
        #define _O_RDWR             02
        #define _O_CREAT         00100   /* NOT fcntl */
        #define _O_EXCL          00200   /* NOT fcntl */
        #define _O_NOCTTY        00400   /* NOT fcntl */
        #define _O_TRUNC         01000   /* NOT fcntl */
        #define _O_APPEND        02000
        #define _O_NONBLOCK      04000   /* NOT fcntl */
        #define _O_NDELAY        O_NONBLOCK
#endif

#ifndef IPHONE
        // This is for non-windows platforms
        extern "C" __stdcall void SDL_WM_SetCaption(const char *,const char *);
#endif

        #include "XMJcalls.h"
        #include "JPR_GetNxtLne.h"
        #include "JPR_GetNxtLne.cpp"
        #include "XMJ_rSrc.cpp"

        namespace __GLBASIC__ {
ENDINLINE


//! Get the version of XMJ
//\param None
//\\return Version of XMJ being used
FUNCTION XMJ_GetVersion$:
LOCAL temp$

        temp$=""

INLINE
        char *ptr;

        ptr=XMJ_getVersion();
        if (ptr)
        {
                temp_Str.assign(ptr);
        }
ENDINLINE

        RETURN temp$
ENDFUNCTION

//! Get the date XMJ was written
//\param None
//\\return Date that XMJ was written
FUNCTION XMJ_GetDate$:
LOCAL temp$

        temp$=""

INLINE
        char *ptr;

        ptr=XMJ_getDate();
        if (ptr)
        {
                temp_Str.assign(ptr);
        }
ENDINLINE

        RETURN temp$
ENDFUNCTION

//! Get last error message
//\param None
//\\return The last error message
FUNCTION XMJ_GetLastError$:
LOCAL temp$

        temp$=""

INLINE
        char *ptr;

        ptr=XMJ_getLastError();
        if (ptr)
        {
                temp_Str.assign(ptr);
        }
ENDINLINE

        RETURN temp$
ENDFUNCTION

//! Open and read a XML file
//\param fileName$ - Filename to be read
//\param rootName$ - Root name in the file
//\\return > 0 if the file was loaded and the root name was found.  Any other value denotes an error
FUNCTION XMJ_ReadFile%:fileName$,rootName$
INLINE
        return XMJ_readFile((char *) fileName_Str.c_str(),(char *) rootName_Str.c_str());
ENDINLINE
ENDFUNCTION

//! Finds the first named group within the higher numbered group & establishes its bounds within that higher group
//\param name$ - Name of group
//\param depth% - Defines depth of search
//\return > 0 if the group name was found.  Any other value denotes an error
FUNCTION XMJ_GetFirstGroup%:name$,depth%
INLINE
        return XMJ_getFrstGroup((char *) name_Str.c_str(),(long) depth);
ENDINLINE
ENDFUNCTION

//! Finds the last named group within the higher numbered group & establishes its bounds within that higher group
//\param name$ - Name of group
//\param depth% - Defines depth of search
//\return > 0 if the group name was found.  Any other value denotes an error
FUNCTION XMJ_GetLastGroup%:name$,depth%
INLINE
        return XMJ_getLastGroup((char *) name_Str.c_str(),(long) depth);
ENDINLINE
ENDFUNCTION

//! Finds the next named group within the higher numbered group & establishes its bounds within that higher group.
//\param name$ - Name of group
//\param depth% - Defines depth of search
//\return > 0 if the group name was found.  Any other value of denotes an error
FUNCTION XMJ_GetNextGroup%:name$,depth%
INLINE
        return XMJ_getNextGroup((char *) name_Str.c_str(),(long) depth);
ENDINLINE
ENDFUNCTION


//! Get the attribute for the current group
//\param attribute$ - Name of attribute
//\param BYREF result$ - Stores the attribute.  Up to 1024 characters will be returned
//\return > 0 if the attribute was found.  Any other value denotes an error
FUNCTION XMJ_GetAttribute$:attribute$,BYREF result$
LOCAL r;

        result$=""
INLINE
        char buffer[1024]={0};

        r=DGNat(XMJ_getAttribute((char *) attribute_Str.c_str(),(char *) &buffer));
        if (r==true)
        {
                result_Str.assign((char *) &buffer);
        }
ENDINLINE

       
        RETURN r
ENDFUNCTION

//! Frees the dynamic array & zeroises the ‘depth’ array & counters.
//\param None
//\return > 0 if the command completed successfully.  Any other value denotes an error
FUNCTION XMJ_Reset%:
INLINE
        return XMJ_reset();
ENDINLINE
ENDFUNCTION
 

And the current project is included.  The good thing about this one is that its multi-platform.  The I/O will need a very slight modification for Linux, and a few other platforms as there is no _O_TEXT value setup for them

[attachment deleted by admin]

MrTAToad

  • Guest
Re: XML
« Reply #1 on: 2010-Jun-22 »
No problem!  It seems to work fine too...

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10667
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: XML
« Reply #2 on: 2010-Jun-22 »
for char* (write) you could do:

char* pBuffer = mystring_Str.getbuffer( max_required_length_excluding_null_character );
xml_getwhatever( pBuffer );
mystring_Str.releasebuffer(); // find '\0' character and set the .len member for correct + and LEN operations.

MrTAToad

  • Guest
Re: XML
« Reply #3 on: 2010-Jun-22 »
Ah - that could be better!

MrTAToad

  • Guest
Re: XML
« Reply #4 on: 2010-Jun-22 »
I've now included an interface to all relevant routines - I haven't tried them all though.

The original link does point to a simplistic help document

[attachment deleted by admin]

Offline Hatonastick

  • Dr. Type
  • ****
  • Posts: 474
  • Amstrad CPC 6128
    • View Profile
Re: XML
« Reply #5 on: 2010-Jul-06 »
This looks just the ticket mate.  Does it also now write XML?  I'm guessing that's a yes.

Anyway attached is a slightly tidied-up version (actually I probably made it worse :P) of the original document which doesn't require registration with CodeProject to download and doesn't contain macros, all converted to PDF form.  I love Open Office. :)

Edit: Not sure why I altered and uploaded the original document as it appears you've already written one.  Sorry. :)

[attachment deleted by admin]
« Last Edit: 2010-Jul-06 by Hatonastick »
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

MrTAToad

  • Guest
Re: XML
« Reply #6 on: 2010-Jul-06 »
The only downside is that the length of text returned is limited to 256 or so characters - if you increase it, it gets the text from the next attribute  :S


Offline Hatonastick

  • Dr. Type
  • ****
  • Posts: 474
  • Amstrad CPC 6128
    • View Profile
Re: XML
« Reply #7 on: 2010-Jul-07 »
Oh.  That's not ideal.  Is it a bug or a feature? :)
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

MrTAToad

  • Guest
Re: XML
« Reply #8 on: 2010-Jul-07 »
I suspect it's a feature...

Offline Hatonastick

  • Dr. Type
  • ****
  • Posts: 474
  • Amstrad CPC 6128
    • View Profile
Re: XML
« Reply #9 on: 2010-Jul-07 »
Not my favourite sort of features those. :)  I was thinking of using this instead of a database system (this would have been a nice alternative because it would also be editable with a text editor in emergencies), but I think I'll probably look into SQLLite or something.  Not a huge deal though.  The project I was going to use it in probably wont ever get done anyway.  =D
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

MrTAToad

  • Guest
Re: XML
« Reply #10 on: 2010-Jul-07 »
The XML system is a trifle limited - but on the plus side it is cross-platform :)

Offline Hatonastick

  • Dr. Type
  • ****
  • Posts: 474
  • Amstrad CPC 6128
    • View Profile
Re: XML
« Reply #11 on: 2010-Jul-08 »
True, that is a very big plus side, and just because it wont do what I'm after doesn't mean anything.  It's still a very cool library.  :)
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

MrTAToad

  • Guest
Re: XML
« Reply #12 on: 2010-Jul-09 »
Yes, its not bad!

Offline siatek

  • Mr. Drawsprite
  • **
  • Posts: 58
    • View Profile
Re: XML
« Reply #13 on: 2012-Oct-31 »
Hi it's working great im just started on *.TMX (http://www.mapeditor.org/) loader and after few minutes i think that its look's promising ;)


Code: GLBasic [Select]

65 cowboy_animations 64 64
decorations 1024 128
fog FOG NO_GID 288 1888 160 64
water bubbles PARTICLEEMITTER NO_GID 928 1760 608 32
water bubbles PARTICLEEMITTER NO_GID 1088 1504 288 32
objects 1024 128
NO_NAME KASIA 65 32 1344  
rhino KASIA 65 384 1792  
NO_NAME NO_TYPE 41 352 1472  
NO_NAME NO_TYPE 41 448 1472  
NO_NAME NO_TYPE 41 544 1472  
NO_NAME NO_TYPE 41 768 1344  
NO_NAME NO_TYPE 41 832 1344  
NO_NAME NO_TYPE 56 1120 1632  
NO_NAME NO_TYPE 56 1184 1600  
NO_NAME NO_TYPE 56 1248 1568  
NO_NAME NO_TYPE 56 1312 1536  
NO_NAME NO_TYPE 58 1141 1843  
NO_NAME NO_TYPE 58 1280 1888  
NO_NAME NO_TYPE 58 1425 1840  
NO_NAME NO_TYPE 57 1045 1895  
NO_NAME PARTICLEEMITTER 60 1728 1792  
NO_NAME PARTICLEEMITTER 60 1952 1792  
zones 1024 128
death zone DEATHZONE NO_GID 0 2016 2016 160
NO_NAME WATER NO_GID 928 1792 608 128
NO_NAME WATER NO_GID 1088 1536 288 128
ice ICE NO_GID 288 1760 352 32
collision 1024 128
collision COLLISION NO_GID 0 1888 288 64
NO_NAME COLLISION NO_GID 1216 1728  
collision COLLISION NO_GID 160 1472 576 32
NO_NAME COLLISION NO_GID 1536 1600  
collision COLLISION NO_GID 1568 1792 448 64
NO_NAME COLLISION NO_GID 1216 1600  
collision COLLISION NO_GID 896 1792 32 128
collision COLLISION NO_GID 1536 1792 32 128
collision COLLISION NO_GID 896 1920 672 32
collision COLLISION NO_GID 448 1888 448 64
collision COLLISION NO_GID 736 1344 160 160
collision COLLISION NO_GID 0 1344 160 160
NO_NAME COLLISION NO_GID 160 1344  
NO_NAME COLLISION NO_GID 608 1344  
collision COLLISION NO_GID 320 1792 288 64

 
« Last Edit: 2012-Oct-31 by siatek »
glbasic roxx !!!

Offline r0ber7

  • Prof. Inline
  • *****
  • Posts: 517
    • View Profile
Re: XML
« Reply #14 on: 2012-Nov-01 »
Hey,

First of all, awesome. I haven't really looked at the code, so forgive me if these questions are irrelevant but it's late and I'm tired. Why the inline C? For parsing XML, all could be done in GLBasic, no? Just wondering, great to see this is on here, might use it in the future.  :good: