Annotation of parser3/src/main/pa_xml_io.C, revision 1.15
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.15 ! paf 12: static const char * const IDENT="$Date: 2003/12/01 14:20:50 $";
1.1 paf 13:
14: #include "libxslt/extensions.h"
15:
16: #include "pa_globals.h"
17: #include "pa_request.h"
18:
1.8 paf 19: #ifndef DOXYGEN
20: struct MemoryStream {
21: const char* m_buf;
22: size_t m_size;
23: size_t m_position;
24:
25: int read(char* a_buffer, size_t a_size) {
26: size_t left=m_size-m_position;
27: if(!left)
28: return 0;
29:
30: size_t to_read=min(a_size, left);
1.14 paf 31: memcpy(a_buffer, m_buf+m_position, to_read);
1.8 paf 32: m_position+=to_read;
33: return to_read;
34: }
35:
36: };
37: #endif
38:
1.15 ! paf 39: static void *
! 40: xmlFileOpen_ReadIntoStream (const char* filename, bool adjust_path_to_root_from_document_root=false) {
! 41: Request& r=pa_thread_request();
! 42: char adjust_buf[MAX_STRING];
! 43: if(adjust_path_to_root_from_document_root) {
! 44: const char* document_root=r.request_info.document_root;
! 45: if(!document_root)
! 46: document_root=".";
! 47:
! 48: adjust_buf[0]=0;
! 49: strcat(adjust_buf, document_root);
! 50: strcat(adjust_buf, &filename[16]);
! 51: filename=adjust_buf;
! 52: } else
! 53: if(strstr(filename, "file://"))
! 54: filename+=7/*strlen("file://")*/;
! 55: else if(strstr(filename, "://"))
! 56: return 0; // plug out [do not handle other prefixes]
! 57:
! 58: const char *buf;
! 59: try {
! 60: buf=file_read_text(r.charsets, *new String(filename));
! 61: } catch(const Exception& e) {
! 62: buf=e.comment();
! 63: } catch(...) {
! 64: buf="xmlFileOpenLocalhost: unknown error";
! 65: }
! 66: MemoryStream* stream=new(UseGC) MemoryStream;
! 67: stream->m_buf=buf;
! 68: stream->m_size=strlen(buf);
! 69: return (void *)stream;
! 70: }
1.9 paf 71:
72: #ifdef PA_SAFE_MODE
73: static int
74: xmlFileMatchSafeMode(const char* file_spec_cstr) {
1.15 ! paf 75: return 1; // always intercept, causing xmlFileOpenSafeMode to be called
! 76: }
! 77: static void *
! 78: xmlFileOpenSafeMode(const char* filename) {
! 79: return xmlFileOpen_ReadIntoStream(filename); // handles localfile case, else returns 0
1.9 paf 80: }
81: #endif
82:
83:
1.1 paf 84: /**
85: * xmlFileMatchWithLocalhostEqDocumentRoot:
86: * filename: the URI for matching
87: *
88: * check if the URI matches an HTTP one
89: *
90: * Returns 1 if matches, 0 otherwise
91: */
92: static int
93: xmlFileMatchLocalhost(const char* filename) {
94: if (!strncmp(filename, "http://localhost", 16))
95: return(1);
96: return(0);
97: }
98:
99: /**
1.15 ! paf 100: * xmlFileOpenLocalhost:
1.1 paf 101: * filename: the URI for matching
102: *
103: * http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
104: *
105: * Returns an I/O context or NULL in case of error
106: */
107: static void *
108: xmlFileOpenLocalhost (const char* filename) {
1.15 ! paf 109: return xmlFileOpen_ReadIntoStream(filename, true/*adjust path to root from document_root*/);
1.1 paf 110: }
111:
1.2 paf 112: static int
113: xmlFileMatchMethod(const char* filename) {
1.3 paf 114: if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2 paf 115: return(1);
116: return(0);
117: }
118:
1.5 paf 119: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 120: static void *
121: xmlFileOpenMethod (const char* afilename) {
1.15 ! paf 122: const char* buf;
! 123: try {
! 124: Request& r=pa_thread_request();
! 125:
! 126: char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
! 127: const char* method_cstr=lsplit(&s, '/');
! 128: const String* method=new String(method_cstr);
! 129: String::Body param_body("/");
! 130: if(s)
! 131: param_body.append_know_length(s, strlen(s));
! 132:
! 133: VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
! 134: {
! 135: Temp_lang temp_lang(r, String::L_XML); // default language: XML
! 136: Request::Execute_nonvirtual_method_result body=
! 137: r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
! 138: if(body.string) {
! 139: buf=body.string->cstr(String::L_UNSPECIFIED);
! 140: } else
! 141: throw Exception(0,
! 142: new String(afilename),
! 143: "'%s' method not found in %s class",
! 144: method_cstr, MAIN_CLASS_NAME);
1.2 paf 145: }
1.15 ! paf 146: } catch(const Exception& e) {
! 147: buf=e.comment();
! 148: } catch(...) {
! 149: buf="xmlFileOpenLocalhost: unknown error";
1.2 paf 150: }
1.15 ! paf 151: MemoryStream* stream=new(UseGC) MemoryStream;
! 152: stream->m_buf=buf;
! 153: stream->m_size=strlen(buf);
! 154: return (void *)stream;
1.2 paf 155: }
156:
1.15 ! paf 157: /**
! 158: * pa_xmlFileReadMethod:
! 159: * @context: the I/O context
! 160: * @buffer: where to drop data
! 161: * @len: number of bytes to write
! 162: *
! 163: * Read @len bytes to @buffer from the I/O channel.
! 164: *
! 165: * Returns the number of bytes written
! 166: */
1.2 paf 167: static int
168: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
169: char * buffer, int len)
170: {
171: MemoryStream& stream=*static_cast<MemoryStream*>(context);
172:
173: return stream.read(buffer, len);
174: }
175:
176: static int
177: pa_xmlFileCloseMethod (void * /*context*/) {
178: return 0;
179: }
180:
181:
1.1 paf 182:
183: void pa_xml_io_init() {
1.9 paf 184: #ifdef PA_SAFE_MODE
185: // safe mode checker, always fail match, but checks non-"://" there
186: xmlRegisterInputCallbacks(
1.15 ! paf 187: xmlFileMatchSafeMode, xmlFileOpenSafeMode,
! 188: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.9 paf 189: #endif
1.1 paf 190: // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
191: xmlRegisterInputCallbacks(
192: xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.8 paf 193: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.2 paf 194:
1.5 paf 195: // parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 196: xmlRegisterInputCallbacks(
197: xmlFileMatchMethod, xmlFileOpenMethod,
198: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1 paf 199: }
200:
201: #endif
E-mail: