~ubuntu-branches/ubuntu/hoary/gnucash/hoary

« back to all changes in this revision

Viewing changes to src/experimental/ofx/parser/DtdParser.C

  • Committer: Bazaar Package Importer
  • Author(s): James A. Treacy
  • Date: 2002-03-16 14:14:59 UTC
  • Revision ID: james.westby@ubuntu.com-20020316141459-wtkyyrpfovryhl1s
Tags: upstream-1.6.6
ImportĀ upstreamĀ versionĀ 1.6.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id: DtdParser.C,v 1.1 2000/06/08 06:08:58 peticolas Exp $
 
2
// Copyright (C) 1997 ISOGEN International Corp. and TechnoTeacher, Inc.
 
3
// All Rights Reserved.
 
4
//
 
5
// <Restrictions>
 
6
// This file and its associated materials are copyrighted material of
 
7
// ISOGEN International Corp. (ISOGEN) and TechnoTeacher,
 
8
// Inc. (TechnoTeacher).  License to copy and use this file and its
 
9
// associated materials is granted to everyone, free of charge, with
 
10
// the following restrictions: (1) The ISOGEN and TechnoTeacher
 
11
// copyright statement must be maintained in any copies. (2) New
 
12
// materials derived from these materials must indicate their source,
 
13
// including references to the ISOGEN and TechnoTeacher web sites
 
14
// (www.isogen.com and www.techno.com). (3) These materials may not be
 
15
// sold in any form without the express written permission of ISOGEN
 
16
// and TechnoTeacher.  [However, feel free to sell things you create
 
17
// from these materials as long as the things you create are truly
 
18
// different in function--we want to encourage people to learn from
 
19
// these materials and benefit from having learned--we just don't want
 
20
// others to sell what we're giving away.]
 
21
// </Restrictions>
 
22
 
 
23
#include "config.h"
 
24
#include "DtdParser.h"
 
25
 
 
26
#include "macros.h"
 
27
#include "sptchar.h"
 
28
#include "CodingSystemKit.h"
 
29
 
 
30
#include "PosixStorage.h"
 
31
#ifdef SP_WININET
 
32
#include "WinInetStorage.h"
 
33
#else
 
34
#include "URLStorage.h"
 
35
#endif
 
36
#include "LiteralStorage.h"
 
37
#include "NotationStorage.h"
 
38
#include "ExtendEntityManager.h"
 
39
#include "SOEntityCatalog.h"
 
40
 
 
41
#include "ErrorCountEventHandler.h"
 
42
 
 
43
#ifndef SP_DEFAULT_ENCODING
 
44
#ifdef WIN32
 
45
#define SP_DEFAULT_ENCODING SP_T("WINDOWS")
 
46
#else
 
47
#define SP_DEFAULT_ENCODING  SP_T("IS8859-1")
 
48
#endif
 
49
#endif /* not SP_DEFAULT_ENCODING */
 
50
 
 
51
#ifndef SGML_SEARCH_PATH_DEFAULT
 
52
#define SGML_SEARCH_PATH_DEFAULT SP_T("")
 
53
#endif
 
54
 
 
55
#ifndef SGML_CATALOG_FILES_DEFAULT
 
56
#define SGML_CATALOG_FILES_DEFAULT SP_T("")
 
57
#endif /* not SGML_CATALOG_FILES_DEFAULT */
 
58
 
 
59
#ifdef SP_NAMESPACE
 
60
namespace SP_NAMESPACE {
 
61
#endif
 
62
 
 
63
#ifdef SP_MSDOS_FILENAMES
 
64
const Char FILE_SEP = ';';
 
65
#else
 
66
const Char FILE_SEP = ':';
 
67
#endif
 
68
 
 
69
DtdParser::
 
70
DtdParser( const char * requiredInternalCode)
 
71
: internalCharsetIsDocCharset_( 1),
 
72
  codingSystem_( 0),
 
73
  mapCatalogDocument_(0),
 
74
  mgr_( &nullMgr_)
 
75
{
 
76
    initCodingSystem( requiredInternalCode);
 
77
}
 
78
 
 
79
void
 
80
DtdParser::
 
81
setMessenger( Messenger * mgr)
 
82
{
 
83
    mgr_ = mgr ? mgr : &nullMgr_;
 
84
}
 
85
 
 
86
class DtdParserEventHandler
 
87
: public ErrorCountEventHandler
 
88
{
 
89
  public:
 
90
    DtdParserEventHandler( Messenger *);
 
91
    void message( MessageEvent *);
 
92
  private:
 
93
    Messenger * mgr_;
 
94
};
 
95
 
 
96
DtdParserEventHandler::
 
97
DtdParserEventHandler( Messenger * mgr)
 
98
: mgr_( mgr)
 
99
{
 
100
}
 
101
 
 
102
void
 
103
DtdParserEventHandler::
 
104
message( MessageEvent * event)
 
105
{
 
106
    // ignore ParserMessages::documentEndProlog and ParserMessages::documentElementUndefined
 
107
    if ( event->message().type->number() != 45 && event->message().type->number() != 319) {
 
108
        mgr_->dispatchMessage( event->message());
 
109
    }
 
110
    ErrorCountEventHandler::message( event);
 
111
}
 
112
 
 
113
ConstPtr< Dtd>
 
114
DtdParser::
 
115
parseDtd( const StringC & sysid)
 
116
{
 
117
    DtdParserEventHandler handler( mgr_);
 
118
 
 
119
    SgmlParser::Params sdParams;
 
120
    sdParams.sysid = convertInput( SP_T( "<LITERAL> "));
 
121
    sdParams.entityManager = entityManager().pointer();
 
122
    sdParams.options = &options_;
 
123
    sdParser_.init( sdParams);
 
124
    sdParser_.parseAll( handler, handler.cancelPtr());
 
125
 
 
126
    SgmlParser::Params params;
 
127
    params.sysid = sysid;
 
128
    params.entityType = SgmlParser::Params::dtd;
 
129
// unnecessary, since params.doctypeName starts out empty anyway.
 
130
//    params.doctypeName = convertInput( SP_T( ""));
 
131
    params.entityManager = entityManager().pointer();
 
132
    params.options = &options_;
 
133
    params.parent = &sdParser_;
 
134
    parser_.init( params);
 
135
    parser_.parseAll( handler, handler.cancelPtr());
 
136
 
 
137
    Ptr< Dtd> dtd( parser_.baseDtd());
 
138
    delete dtd->removeElementType( params.doctypeName);
 
139
 
 
140
    return dtd;
 
141
}
 
142
 
 
143
Boolean
 
144
stringMatches( const SP_TCHAR * s, const char * key)
 
145
{
 
146
  for (; *key != '\0'; s++, key++) {
 
147
    if (*s != tolower(*key) && *s != toupper(*key))
 
148
      return 0;
 
149
  }
 
150
  return *s == '\0';
 
151
}
 
152
 
 
153
void
 
154
DtdParser::
 
155
initCodingSystem( const char * requiredInternalCode)
 
156
{
 
157
  const char *name = requiredInternalCode;
 
158
#ifdef SP_MULTI_BYTE
 
159
  char buf[256];
 
160
  if (!name) {
 
161
    const SP_TCHAR *internalCode = tgetenv(SP_T("SP_SYSTEM_CHARSET"));
 
162
    if (internalCode) {
 
163
      buf[255] = '\0';
 
164
      for (size_t i = 0; i < 255; i++) {
 
165
        buf[i] = internalCode[i];
 
166
        if (buf[i] == '\0')
 
167
          break;
 
168
      }
 
169
      name = buf;
 
170
    }
 
171
  }
 
172
  if (requiredInternalCode)
 
173
    internalCharsetIsDocCharset_ = 0;
 
174
  else {
 
175
    const SP_TCHAR *useInternal = tgetenv(SP_T("SP_CHARSET_FIXED"));
 
176
    if (useInternal
 
177
        && (stringMatches(useInternal, "YES")
 
178
            || stringMatches(useInternal, "1")))
 
179
      internalCharsetIsDocCharset_ = 0;
 
180
  }
 
181
#endif /* SP_MULTI_BYTE */
 
182
  codingSystemKit_ = CodingSystemKit::make(name);
 
183
  const SP_TCHAR *codingName = tgetenv(internalCharsetIsDocCharset_
 
184
                                       ? SP_T("SP_BCTF")
 
185
                                       : SP_T("SP_ENCODING"));
 
186
  if (codingName)
 
187
    codingSystem_ = lookupCodingSystem(codingName);
 
188
#ifdef SP_MULTI_BYTE
 
189
  if (!codingSystem_ && !internalCharsetIsDocCharset_)
 
190
    codingSystem_ = lookupCodingSystem(SP_DEFAULT_ENCODING);
 
191
#endif
 
192
  if (!codingSystem_
 
193
#ifndef SP_WIDE_SYSTEM
 
194
      || codingSystem_->fixedBytesPerChar() > 1
 
195
#endif
 
196
    )
 
197
    codingSystem_ = codingSystemKit_->identityCodingSystem();
 
198
}
 
199
 
 
200
const CodingSystem *
 
201
DtdParser::
 
202
lookupCodingSystem( const AppChar * codingName)
 
203
{
 
204
#define MAX_CS_NAME 50
 
205
  if (tcslen(codingName) < MAX_CS_NAME) {
 
206
    char buf[MAX_CS_NAME];
 
207
    int i;
 
208
    for (i = 0; codingName[i] != SP_T('\0'); i++) {
 
209
      SP_TUCHAR c = codingName[i];
 
210
#ifdef SP_WIDE_SYSTEM
 
211
      if (c > (unsigned char)-1)
 
212
        return 0;
 
213
#endif
 
214
      buf[i] = char(c);
 
215
    }
 
216
    buf[i] = '\0';
 
217
    return codingSystemKit_->makeCodingSystem(buf, internalCharsetIsDocCharset_);
 
218
  }
 
219
  return 0;
 
220
}
 
221
 
 
222
StringC
 
223
DtdParser::
 
224
convertInput( const SP_TCHAR * s)
 
225
{
 
226
#ifdef SP_WIDE_SYSTEM
 
227
  StringC str(s, wcslen(s));
 
228
#else
 
229
  StringC str(codingSystem()->convertIn(s));
 
230
#endif
 
231
  for (size_t i = 0; i < str.size(); i++)
 
232
    if (str[i] == '\n')
 
233
      str[i] = '\r';
 
234
  return str;
 
235
}
 
236
 
 
237
Boolean
 
238
DtdParser::
 
239
makeSystemId( int nFiles, AppChar * const * files, StringC & result)
 
240
{
 
241
  Vector<StringC> filenames(nFiles == 0 ? 1 : nFiles);
 
242
  int i;
 
243
  for (i = 0; i < nFiles; i++)
 
244
    filenames[i] = convertInput(tcscmp(files[i], SP_T("-")) == 0
 
245
                                ? SP_T("<OSFD>0")
 
246
                                : files[i]);
 
247
  if (nFiles == 0)
 
248
    filenames[0] = convertInput(SP_T("<OSFD>0"));
 
249
  return entityManager()->mergeSystemIds(filenames,
 
250
                                         mapCatalogDocument_,
 
251
                                         systemCharset(),
 
252
                                         *mgr_,
 
253
                                         result);
 
254
}
 
255
 
 
256
Ptr< ExtendEntityManager> &
 
257
DtdParser::
 
258
entityManager()
 
259
{
 
260
  if (!entityManager_.isNull())
 
261
    return entityManager_;
 
262
  PosixStorageManager *sm
 
263
    = new PosixStorageManager("OSFILE",
 
264
                              &systemCharset(),
 
265
#ifndef SP_WIDE_SYSTEM
 
266
                              codingSystem(),
 
267
#endif
 
268
                              5);
 
269
  size_t i;
 
270
  for (i = 0; i < searchDirs_.size(); i++)
 
271
    sm->addSearchDir(convertInput(searchDirs_[i]));
 
272
  {
 
273
    const AppChar *e = tgetenv(SP_T("SGML_SEARCH_PATH"));
 
274
    if (!e)
 
275
      e = SGML_SEARCH_PATH_DEFAULT;
 
276
    if (*e) {
 
277
      StringC str(convertInput(e));
 
278
      size_t i = 0;
 
279
      size_t start = 0;
 
280
      for (;;) {
 
281
        if (i == str.size() || str[i] == FILE_SEP) {
 
282
          sm->addSearchDir(StringC(str.data() + start,
 
283
                                   i - start));
 
284
          if (i == str.size())
 
285
            break;
 
286
          start = ++i;
 
287
        }
 
288
        else
 
289
          i++;
 
290
      }
 
291
    }
 
292
  }
 
293
 
 
294
  entityManager_ = ExtendEntityManager::make(sm,
 
295
                                             codingSystem(),
 
296
                                             inputCodingSystemKit(),
 
297
                                             internalCharsetIsDocCharset_);
 
298
#ifdef SP_WININET
 
299
  entityManager_->registerStorageManager(new WinInetStorageManager("URL"));
 
300
#else
 
301
  entityManager_->registerStorageManager(new URLStorageManager("URL"));
 
302
#endif
 
303
  entityManager_->registerStorageManager(new LiteralStorageManager("LITERAL"));
 
304
  entityManager_->registerStorageManager(new NotationStorageManager("CLSID"));
 
305
  entityManager_->registerStorageManager(new NotationStorageManager("MIMETYPE"));
 
306
  Vector<StringC> v;
 
307
  for (i = 0; i < catalogSysids_.size(); i++)
 
308
    // filenames specified on command-line must exist
 
309
    v.push_back(convertInput(catalogSysids_[i]));
 
310
  {
 
311
    const AppChar *e = tgetenv(SP_T("SGML_CATALOG_FILES"));
 
312
    if (!e)
 
313
      e = SGML_CATALOG_FILES_DEFAULT;
 
314
    if (*e) {
 
315
      StringC str(convertInput(e));
 
316
      size_t i = 0;
 
317
      size_t start = 0;
 
318
      for (;;) {
 
319
        if (i == str.size() || str[i] == FILE_SEP) {
 
320
          v.push_back(StringC(str.data() + start,
 
321
                              i - start));
 
322
          if (i == str.size())
 
323
            break;
 
324
          start = ++i;
 
325
        }
 
326
        else
 
327
          i++;
 
328
      }
 
329
    }
 
330
  }
 
331
  entityManager_->setCatalogManager(SOCatalogManager::make(v,
 
332
                                                           catalogSysids_.size(),
 
333
                                                           &systemCharset(),
 
334
                                                           &systemCharset(),
 
335
                                                           0));
 
336
  return entityManager_;
 
337
}
 
338
 
 
339
#ifdef SP_NAMESPACE
 
340
}
 
341
#endif