Annotation of parser3/src/main/pa_xml_io.C, revision 1.5

1.1       paf         1: /** @file
                      2:        Parser: plugins to xml library, controlling i/o; implementation
                      3: 
                      4:        Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
                      5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      6: */
                      7: 
                      8: #include "pa_xml_io.h"
                      9: 
                     10: #ifdef XML
                     11: 
1.5     ! paf        12: static const char * const IDENT="$Date: 2003/11/28 09:33:20 $";
1.1       paf        13: 
                     14: #include "libxslt/extensions.h"
                     15: 
                     16: #include "pa_globals.h"
                     17: #include "pa_request.h"
                     18: 
                     19: /**
                     20:  * xmlFileMatchWithLocalhostEqDocumentRoot:
                     21:  * filename:  the URI for matching
                     22:  *
                     23:  * check if the URI matches an HTTP one
                     24:  *
                     25:  * Returns 1 if matches, 0 otherwise
                     26:  */
                     27: static int
                     28: xmlFileMatchLocalhost(const char* filename) {
                     29:        if (!strncmp(filename, "http://localhost", 16))
                     30:                return(1);
                     31:        return(0);
                     32: }
                     33: 
                     34: 
                     35: /**
                     36:  * xmlFileOpenHttpLocalhost :
                     37:  * filename:  the URI for matching
                     38:  *
                     39:  * http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                     40:  *
                     41:  * input from FILE *, supports compressed input
                     42:  * if filename is " " then the standard input is used
                     43:  *
                     44:  * Returns an I/O context or NULL in case of error
                     45:  */
                     46: static void *
                     47: xmlFileOpenLocalhost (const char* filename) {
                     48:        //_asm int 3;
                     49:        FILE *fd;
                     50:        const char* document_root=pa_thread_request().request_info.document_root;
                     51:        if(!document_root)
                     52:                document_root=".";
                     53: 
                     54:        char path[MAX_STRING];  
                     55:        path[0]=0;
                     56:        strcat(path, document_root);
                     57:        strcat(path, &filename[16]);
                     58:        
                     59: #ifdef WIN32
                     60:        fd = fopen(path, "rb");
                     61: #else
                     62:        fd = fopen(path, "r");
                     63: #endif /* WIN32 */
                     64:        return((void *) fd);
                     65: }
                     66: 
                     67: /**
                     68:  * xmlFileRead:
                     69:  * @context:  the I/O context
                     70:  * @buffer:  where to drop data
                     71:  * @len:  number of bytes to write
                     72:  *
                     73:  * Read @len bytes to @buffer from the I/O channel.
                     74:  *
                     75:  * Returns the number of bytes written
                     76:  */
                     77: static int
                     78: pa_xmlFileRead (void * context, char * buffer, int len) {
                     79:        return(fread(&buffer[0], 1,  len, (FILE *) context));
                     80: }
                     81: 
                     82: /**
                     83:  * xmlFileClose:
                     84:  * @context:  the I/O context
                     85:  *
                     86:  * Close an I/O channel
                     87:  */
                     88: static int
                     89: pa_xmlFileClose (void * context) {
                     90:        return ( ( fclose((FILE *) context) == EOF ) ? -1 : 0 );
                     91: }
                     92: 
1.2       paf        93: //////////////////////////
                     94: 
                     95: #ifndef DOXYGEN
                     96: struct MemoryStream {
                     97:        const char* m_buf;
                     98:        size_t m_size;
                     99:        size_t m_position;
                    100: 
                    101:        int read(char* a_buffer, size_t a_size) {
                    102:                size_t left=m_size-m_position;
                    103:                if(!left)
                    104:                        return 0;
                    105: 
                    106:                size_t to_read=min(a_size, left);
                    107:                memcpy(a_buffer, m_buf, to_read);
1.3       paf       108:                m_position+=to_read;
1.2       paf       109:                return to_read;
                    110:        }
                    111: 
                    112: };
                    113: #endif
                    114: 
                    115: static int
                    116: xmlFileMatchMethod(const char* filename) {
1.3       paf       117:        if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2       paf       118:                return(1);
                    119:        return(0);
                    120: }
                    121: 
1.5     ! paf       122: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       123: static void *
                    124: xmlFileOpenMethod (const char* afilename) {
                    125:        //_asm int 3;
                    126:        Request& r=pa_thread_request();
                    127: 
1.3       paf       128:        char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
1.2       paf       129:        const char* method_cstr=lsplit(&s, '/');
                    130:        const String* method=new String(method_cstr);
1.4       paf       131:        String::Body param_body("/");  
                    132:        if(s)
                    133:                param_body.append_know_length(s, strlen(s));
                    134: 
                    135:        VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
1.2       paf       136:        {
                    137:                Temp_lang temp_lang(r, String::L_XML); // default language: XML
1.3       paf       138:                Request::Execute_nonvirtual_method_result body=
1.4       paf       139:                        r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
1.3       paf       140:                if(body.string) {
1.2       paf       141:                        MemoryStream *stream=new(UseGC) MemoryStream;
1.3       paf       142:                        stream->m_buf=body.string->cstr(String::L_UNSPECIFIED);
1.2       paf       143:                        stream->m_size=strlen(stream->m_buf);
                    144:                        return (void*)stream;
                    145:                }
                    146:        }
                    147: 
                    148:        throw Exception(0,
1.3       paf       149:                new String(afilename),
                    150:                "'%s' method not found in %s class", 
                    151:                        method_cstr, MAIN_CLASS_NAME);
1.2       paf       152: }
                    153: 
                    154: static int
                    155: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
                    156:                                          char * buffer, int len) 
                    157: {
                    158:        MemoryStream& stream=*static_cast<MemoryStream*>(context);
                    159: 
                    160:        return stream.read(buffer, len);
                    161: }
                    162: 
                    163: /**
                    164:  * xmlFileClose:
                    165:  * @context:  the I/O context
                    166:  *
                    167:  * Close an I/O channel
                    168:  */
                    169: static int
                    170: pa_xmlFileCloseMethod (void * /*context*/) {
                    171:        return 0;
                    172: }
                    173: 
                    174: 
1.1       paf       175: 
                    176: void pa_xml_io_init() {
                    177:        // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                    178:        xmlRegisterInputCallbacks(
                    179:                xmlFileMatchLocalhost, xmlFileOpenLocalhost,
                    180:                pa_xmlFileRead, pa_xmlFileClose);
1.2       paf       181: 
1.5     ! paf       182:        // parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       183:        xmlRegisterInputCallbacks(
                    184:                xmlFileMatchMethod, xmlFileOpenMethod,
                    185:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1       paf       186: }
                    187: 
                    188: #endif

E-mail: