Annotation of parser3/src/main/pa_xml_io.C, revision 1.7
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.7 ! paf 12: static const char * const IDENT="$Date: 2003/11/28 09:36:04 $";
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: FILE *fd;
49: const char* document_root=pa_thread_request().request_info.document_root;
50: if(!document_root)
51: document_root=".";
52:
53: char path[MAX_STRING];
54: path[0]=0;
55: strcat(path, document_root);
56: strcat(path, &filename[16]);
57:
58: #ifdef WIN32
59: fd = fopen(path, "rb");
60: #else
61: fd = fopen(path, "r");
62: #endif /* WIN32 */
63: return((void *) fd);
64: }
65:
66: /**
67: * xmlFileRead:
68: * @context: the I/O context
69: * @buffer: where to drop data
70: * @len: number of bytes to write
71: *
72: * Read @len bytes to @buffer from the I/O channel.
73: *
74: * Returns the number of bytes written
75: */
76: static int
77: pa_xmlFileRead (void * context, char * buffer, int len) {
78: return(fread(&buffer[0], 1, len, (FILE *) context));
79: }
80:
81: /**
82: * xmlFileClose:
83: * @context: the I/O context
84: *
85: * Close an I/O channel
86: */
87: static int
88: pa_xmlFileClose (void * context) {
89: return ( ( fclose((FILE *) context) == EOF ) ? -1 : 0 );
90: }
91:
1.2 paf 92: //////////////////////////
93:
94: #ifndef DOXYGEN
95: struct MemoryStream {
96: const char* m_buf;
97: size_t m_size;
98: size_t m_position;
99:
100: int read(char* a_buffer, size_t a_size) {
101: size_t left=m_size-m_position;
102: if(!left)
103: return 0;
104:
105: size_t to_read=min(a_size, left);
106: memcpy(a_buffer, m_buf, to_read);
1.3 paf 107: m_position+=to_read;
1.2 paf 108: return to_read;
109: }
110:
111: };
112: #endif
113:
114: static int
115: xmlFileMatchMethod(const char* filename) {
1.3 paf 116: if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2 paf 117: return(1);
118: return(0);
119: }
120:
1.5 paf 121: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 122: static void *
123: xmlFileOpenMethod (const char* afilename) {
124: Request& r=pa_thread_request();
125:
1.3 paf 126: char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
1.2 paf 127: const char* method_cstr=lsplit(&s, '/');
128: const String* method=new String(method_cstr);
1.4 paf 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));
1.2 paf 134: {
135: Temp_lang temp_lang(r, String::L_XML); // default language: XML
1.3 paf 136: Request::Execute_nonvirtual_method_result body=
1.4 paf 137: r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
1.3 paf 138: if(body.string) {
1.2 paf 139: MemoryStream *stream=new(UseGC) MemoryStream;
1.3 paf 140: stream->m_buf=body.string->cstr(String::L_UNSPECIFIED);
1.2 paf 141: stream->m_size=strlen(stream->m_buf);
142: return (void*)stream;
143: }
144: }
145:
146: throw Exception(0,
1.3 paf 147: new String(afilename),
148: "'%s' method not found in %s class",
149: method_cstr, MAIN_CLASS_NAME);
1.2 paf 150: }
151:
152: static int
153: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
154: char * buffer, int len)
155: {
156: MemoryStream& stream=*static_cast<MemoryStream*>(context);
157:
158: return stream.read(buffer, len);
159: }
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:
1.5 paf 174: // parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 175: xmlRegisterInputCallbacks(
176: xmlFileMatchMethod, xmlFileOpenMethod,
177: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1 paf 178: }
179:
180: #endif
E-mail: