• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 Esmertec AG.
3  * Copyright (C) 2007 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "xml2wbxml.h"
19 #include "wbxml_stl.h"
20 #include "imps_encoder.h"
21 
22 struct PublicIdData {
23     const char * pubid;
24     const char * xmlns;
25     PublicId idVal;
26 };
27 
28 // http://www.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.htm
29 static const PublicIdData knownPublicId[] = {
30     { "-//OMA//DTD IMPS-CSP 1.3//EN",
31         "http://www.openmobilealliance.org/DTD/IMPS-CSP1.3",
32         PUBLICID_IMPS_1_3 },
33     { "-//OMA//DTD WV-CSP 1.2//EN",
34         "http://www.openmobilealliance.org/DTD/WV-CSP1.2",
35         PUBLICID_IMPS_1_2 },
36     { "-//WIRELESSVILLAGE//DTD CSP 1.1//EN",
37         "http://www.wireless-village.org/CSP1.1",
38         PUBLICID_IMPS_1_1 },
39     /*
40     { "-//OMA//DRM 2.1//EN", XXX,           0x13 },
41     { "-//OMA//DTD DRMREL 1.0//EN", XXX,    0x0e },
42     { "-//SYNCML//DTD DevInf 1.2//EN", XXX, 0x1203 },
43     { "-//SYNCML//DTD MetaInf 1.2//EN", XXX,0x1202 },
44     { "-//SYNCML//DTD SyncML 1.2//EN", XXX, 0x1201 }
45     */
46 };
47 
makeEncoder(int publicid)48 static WbxmlEncoder * makeEncoder(int publicid)
49 {
50     switch (publicid) {
51         case PUBLICID_IMPS_1_3:
52         case PUBLICID_IMPS_1_2:
53         case PUBLICID_IMPS_1_1:
54             return new ImpsWbxmlEncoder(publicid);
55 
56         default:
57             return NULL;
58     }
59 }
60 
Xml2WbxmlEncoder()61 Xml2WbxmlEncoder::Xml2WbxmlEncoder() :
62     mWbxmlHandler(NULL),
63     mEncoder(NULL),
64     mPublicId(-1),
65     mDepth(0),
66     mErrorCode(NO_ERROR)
67 {
68     mExpatParser = new ExpatParser();
69     mExpatParser->setContentHandler(this);
70 }
71 
~Xml2WbxmlEncoder()72 Xml2WbxmlEncoder::~Xml2WbxmlEncoder()
73 {
74     delete(mExpatParser);
75     delete(mEncoder);
76 }
77 
setWbxmlHandler(WbxmlHandler * handler)78 void Xml2WbxmlEncoder::setWbxmlHandler(WbxmlHandler * handler)
79 {
80     mWbxmlHandler = handler;
81 }
82 
startElement(const char * name,const char ** atts)83 void Xml2WbxmlEncoder::startElement(const char *name, const char **atts)
84 {
85     if (getErrorCode() != NO_ERROR)
86         return;
87 
88     if (!mDepth) {
89         if (!isPublicIdSet()) {
90             for (int i = 0; atts[i]; i += 2) {
91                 // TODO: for now we don't handle xmlns:<prefix> yet
92                 if (strcmp(atts[i], "xmlns") == 0) {
93                     if (detectPublicIdByXmlns(atts[i + 1]))
94                         break;
95                 }
96             }
97         }
98         if (isPublicIdSet()) {
99             // TODO: at present fixed to WBXML 1.3, UTF-8, no string table
100             mEncoder = makeEncoder(mPublicId);
101             if (mEncoder == NULL) {
102                 setError(ERROR_UNSUPPORTED_DOCTYPE);
103                 return;
104             }
105             mEncoder->setWbxmlHandler(mWbxmlHandler);
106         } else {
107             setError(ERROR_NO_PUBLIC_ID);
108             return;
109         }
110     }
111     setError(mEncoder->startElement(name, atts));
112     mDepth++;
113 }
114 
endElement(const char * name)115 void Xml2WbxmlEncoder::endElement(const char *name)
116 {
117     if (getErrorCode() != NO_ERROR)
118         return;
119 
120     setError(mEncoder->endElement());
121     mDepth--;
122 }
123 
characters(const char * data,int len)124 void Xml2WbxmlEncoder::characters(const char *data, int len)
125 {
126     if (getErrorCode() != NO_ERROR)
127         return;
128 
129     setError(mEncoder->characters(data, len));
130 }
131 
startDoctype(const char * doctypeName,const char * sysid,const char * pubid,int has_internal_subset)132 void Xml2WbxmlEncoder::startDoctype(const char *doctypeName,
133         const char *sysid,
134         const char *pubid,
135         int has_internal_subset)
136 {
137     if (!isPublicIdSet()) {
138         detectPublicId(pubid);
139     }
140 }
141 
detectPublicId(const char * pubid)142 bool Xml2WbxmlEncoder::detectPublicId(const char * pubid)
143 {
144     for (size_t i = 0; i < sizeof(knownPublicId) / sizeof(knownPublicId[0]); i++) {
145         if (strcmp(pubid, knownPublicId[i].pubid) == 0) {
146             //printf ("pubid %s => 0x%x\n", pubid, knownPublicId[i].idVal);
147             setPublicId(knownPublicId[i].idVal);
148             return true;
149         }
150     }
151     return false;
152 }
153 
detectPublicIdByXmlns(const char * xmlnsUri)154 bool Xml2WbxmlEncoder::detectPublicIdByXmlns(const char * xmlnsUri)
155 {
156     for (size_t i = 0; i < sizeof(knownPublicId) / sizeof(knownPublicId[0]); i++) {
157         if (strcmp(xmlnsUri, knownPublicId[i].xmlns) == 0) {
158             //printf ("xmlns %s => 0x%x\n", xmlnsUri, knownPublicId[i].idVal);
159             setPublicId(knownPublicId[i].idVal);
160             return true;
161         }
162     }
163     return false;
164 }
165 
encode(const char * data,uint32_t dataLen,bool end)166 int Xml2WbxmlEncoder::encode(const char * data, uint32_t dataLen, bool end)
167 {
168     if (data == NULL) {
169         return WBXML_STATUS_ERROR;
170     }
171     if (mExpatParser->parse(data, (int)dataLen, end) != XML_STATUS_OK) {
172         //printf ("Expat error: %s\n", XML_ErrorString(XML_GetErrorCode(mExpat)));
173         return WBXML_STATUS_ERROR;
174     }
175     return getErrorCode() == NO_ERROR ? WBXML_STATUS_OK : WBXML_STATUS_ERROR;
176 }
177 
178