1 /*
2 * Copyright 2014 Zane U. Ji.
3 *
4 * This file is part of Xml Copy Editor.
5 *
6 * Xml Copy Editor is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * Xml Copy Editor is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Xml Copy Editor; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "xmltextinfo.h"
22
XmlTextInfo(const wxString & path,const char * encoding)23 XmlTextInfo::XmlTextInfo
24 ( const wxString &path
25 , const char *encoding /*= NULL*/
26 )
27 : WrapExpat ( encoding )
28 {
29 XML_SetUserData ( p, this );
30 XML_SetBase ( p, path.utf8_str() );
31 XML_SetDoctypeDeclHandler ( p, startdoctypehandler, NULL );
32 XML_SetProcessingInstructionHandler ( p, processinghandler );
33 XML_SetElementHandler ( p, start, NULL );
34 XML_SetDefaultHandlerExpand ( p, defaulthandler );
35 }
36
~XmlTextInfo()37 XmlTextInfo::~XmlTextInfo()
38 {
39 }
40
startdoctypehandler(void * data,const XML_Char * doctypeName,const XML_Char * sysid,const XML_Char * pubid,int has_internal_subset)41 void XMLCALL XmlTextInfo::startdoctypehandler
42 ( void *data
43 , const XML_Char *doctypeName
44 , const XML_Char *sysid
45 , const XML_Char *pubid
46 , int has_internal_subset
47 )
48 {
49 XmlTextInfo *pThis = (XmlTextInfo *)data;
50
51 pThis->mDocTypeName = wxString::FromUTF8 ( doctypeName );
52 }
53
processinghandler(void * data,const XML_Char * target,const XML_Char * datastring)54 void XMLCALL XmlTextInfo::processinghandler
55 ( void *data
56 , const XML_Char *target
57 , const XML_Char *datastring
58 )
59 {
60 XmlTextInfo *pThis = (XmlTextInfo *)data;
61
62 if ( strcmp ( target, "xml-stylesheet" ) )
63 return;
64
65 char *href = strstr ( ( char * ) datastring, "href" );
66 if ( !href )
67 return;
68 href += strlen ( "href" );
69
70 char ch = '"'; // Is '' or "" used?
71 char *start = strchr ( href, ch);
72 char *p = strchr ( href, '\'');
73 if ( start == NULL
74 || ( p != NULL && start > p ) )
75 {
76 start = p;
77 ch = '\'';
78 }
79 if ( !start++ )
80 return;
81 while ( isspace ( *start ) )
82 start++;
83
84 char *end = strchr ( start, ch);
85 if ( !end )
86 return;
87 while ( isspace ( end[-1] ) )
88 end--;
89
90 pThis->mXslFile = wxString::FromUTF8 ( start, end - start );
91 }
92
start(void * data,const XML_Char * el,const XML_Char ** attr)93 void XMLCALL XmlTextInfo::start
94 ( void *data
95 , const XML_Char *el
96 , const XML_Char **attr
97 )
98 {
99 XmlTextInfo *pThis = (XmlTextInfo *)data;
100
101 for ( ; *attr; attr += 2 )
102 {
103 if ( strstr ( *attr, ":noNamespaceSchemaLocation" ) )
104 {
105 pThis->mXsdFile = wxString::FromUTF8 ( attr[1] );
106 break;
107 }
108 if ( strstr ( *attr, ":schemaLocation" ) )
109 { // TODO: Support multiple schemas
110 std::string str ( attr[1] );
111 char *p = strtok ( ( char * ) str.c_str(), " \t\r\n" );
112 if ( !p )
113 continue;
114 p = strtok ( NULL, " \t\r\n" );
115 if ( !p )
116 continue;
117 pThis->mXsdFile = wxString::FromUTF8 ( p );
118 break;
119 }
120 }
121
122 pThis->mDocTypeName = wxString::FromUTF8 ( el );
123
124 XML_SetElementHandler ( pThis->p, NULL, NULL );
125 }
126
defaulthandler(void * data,const XML_Char * s,int len)127 void XMLCALL XmlTextInfo::defaulthandler
128 ( void *data
129 , const XML_Char *s
130 , int len
131 )
132 {
133 XmlTextInfo *pThis = (XmlTextInfo *)data;
134 const char *p = s;
135 const char *end = s + len;
136 while ( p < end && *p != '\r' )
137 p++;
138 if ( p < end )
139 {
140 if ( p + 1 < end && p[1] == '\n' )
141 pThis->mEOL = _T ( "\r\n" );
142 else
143 pThis->mEOL = _T ( "\n" );
144 XML_SetDefaultHandlerExpand ( pThis->p, NULL );
145 return;
146 }
147
148 p = s;
149 while ( p < end && *p != '\r')
150 p++;
151 if ( p < end )
152 {
153 pThis->mEOL = _T ( "\n" );
154 XML_SetDefaultHandlerExpand ( pThis->p, NULL );
155 }
156 }
157