Annotation of parser3/src/main/pa_xml_io.C, revision 1.2
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.2 ! paf 12: static const char * const IDENT="$Date: 2003/11/26 12:49:44 $";
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);
! 108: return to_read;
! 109: }
! 110:
! 111: };
! 112: #endif
! 113:
! 114: static int
! 115: xmlFileMatchMethod(const char* filename) {
! 116: if (!strncmp(filename, "parser://", 7 /*strlen("parser://"), and check xmlFileOpenMethod*/))
! 117: return(1);
! 118: return(0);
! 119: }
! 120:
! 121: /// parser://method/param/here -> ^/abc | ./abc
! 122: static void *
! 123: xmlFileOpenMethod (const char* afilename) {
! 124: //_asm int 3;
! 125: Request& r=pa_thread_request();
! 126:
! 127: char* s=pa_strdup(afilename+7 /*strlen("parser://")*/);
! 128: const char* method_cstr=lsplit(&s, '/');
! 129: const String* method=new String(method_cstr);
! 130: {
! 131: Temp_lang temp_lang(r, String::L_XML); // default language: XML
! 132: // @todo: s=params
! 133: if(const String* body_string=r.execute_virtual_method(r.main_class, *method)) {
! 134: MemoryStream *stream=new(UseGC) MemoryStream;
! 135: stream->m_buf=body_string->cstr(String::L_UNSPECIFIED);
! 136: stream->m_size=strlen(stream->m_buf);
! 137: return (void*)stream;
! 138: }
! 139: }
! 140:
! 141: throw Exception(0,
! 142: method,
! 143: "not found (referred from parser://name/)");
! 144: }
! 145:
! 146: static int
! 147: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
! 148: char * buffer, int len)
! 149: {
! 150: MemoryStream& stream=*static_cast<MemoryStream*>(context);
! 151:
! 152: return stream.read(buffer, len);
! 153: }
! 154:
! 155: /**
! 156: * xmlFileClose:
! 157: * @context: the I/O context
! 158: *
! 159: * Close an I/O channel
! 160: */
! 161: static int
! 162: pa_xmlFileCloseMethod (void * /*context*/) {
! 163: return 0;
! 164: }
! 165:
! 166:
1.1 paf 167:
168: void pa_xml_io_init() {
169: // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
170: xmlRegisterInputCallbacks(
171: xmlFileMatchLocalhost, xmlFileOpenLocalhost,
172: pa_xmlFileRead, pa_xmlFileClose);
1.2 ! paf 173:
! 174: // parser://method/param/here -> ^/abc | ./abc
! 175: xmlRegisterInputCallbacks(
! 176: xmlFileMatchMethod, xmlFileOpenMethod,
! 177: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1 paf 178: }
179:
180: #endif
E-mail: