/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these librararies and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: ExternalId.C /main/1 1996/07/29 16:51:51 cde-hp $ */ // Copyright (c) 1994 James Clark // See the file COPYING for copying permission. #ifdef __GNUG__ #pragma implementation #endif #include "splib.h" #include "ExternalId.h" #include "CharsetInfo.h" #include "macros.h" #include "ParserMessages.h" #ifdef SP_NAMESPACE namespace SP_NAMESPACE { #endif ExternalId::ExternalId() : haveSystem_(0), havePublic_(0) { } void ExternalId::setSystem(Text &text) { text.swap(system_); haveSystem_ = 1; } Boolean ExternalId::setPublic(Text &text, const CharsetInfo &charset, Char space, const MessageType1 *&error) { havePublic_ = 1; return public_.init(text, charset, space, error); } void ExternalId::setLocation(const Location &loc) { loc_ = loc; } PublicId::PublicId() : formal_(0) { } Boolean PublicId::init(Text &text, const CharsetInfo &charset, Char space, const MessageType1 *&error) { text.swap(text_); const StringC &str = text_.string(); formal_ = 0; const Char *next = str.data(); const Char *lim = str.data() + str.size(); Char solidus = charset.execToDesc('/'); Char minus = charset.execToDesc('-'); Char plus = charset.execToDesc('+'); const Char *fieldStart; size_t fieldLength; if (!nextField(solidus, next, lim, fieldStart, fieldLength)) { error = &ParserMessages::fpiMissingField; return 0; } if (fieldLength == 1 && (*fieldStart == minus || *fieldStart == plus)) { ownerType_ = (*fieldStart == plus ? registered : unregistered); if (!nextField(solidus, next, lim, fieldStart, fieldLength)) { error = &ParserMessages::fpiMissingField; return 0; } } else ownerType_ = ISO; owner_.assign(fieldStart, fieldLength); if (!nextField(solidus, next, lim, fieldStart, fieldLength)) { error = &ParserMessages::fpiMissingField; return 0; } size_t i; for (i = 0; i < fieldLength; i++) if (fieldStart[i] == space) break; if (i >= fieldLength) { error = &ParserMessages::fpiMissingTextClassSpace; return 0; } StringC textClassString(fieldStart, i); if (!lookupTextClass(textClassString, charset, textClass_)) { error = &ParserMessages::fpiInvalidTextClass; return 0; } i++; // skip the space fieldStart += i; fieldLength -= i; if (fieldLength == 1 && *fieldStart == minus) { unavailable_ = 1; if (!nextField(solidus, next, lim, fieldStart, fieldLength)) { error = &ParserMessages::fpiMissingField; return 0; } } else unavailable_ = 0; description_.assign(fieldStart, fieldLength); if (!nextField(solidus, next, lim, fieldStart, fieldLength)) { error = &ParserMessages::fpiMissingField; return 0; } if (textClass_ != CHARSET) { for (i = 0; i < fieldLength; i++) { UnivChar c; if (!charset.descToUniv(fieldStart[i], c) || c < UnivCharsetDesc::A || c >= UnivCharsetDesc::A + 26) { error = &ParserMessages::fpiInvalidLanguage; return 0; } } // The public text language must be a name. // Names cannot be empty. if (fieldLength == 0) { error = &ParserMessages::fpiInvalidLanguage; return 0; } } languageOrDesignatingSequence_.assign(fieldStart, fieldLength); if (nextField(solidus, next, lim, fieldStart, fieldLength)) { switch (textClass_) { case CAPACITY: case CHARSET: case NOTATION: case SYNTAX: error = &ParserMessages::fpiIllegalDisplayVersion; return 0; default: break; } haveDisplayVersion_ = 1; displayVersion_.assign(fieldStart, fieldLength); } else haveDisplayVersion_ = 0; if (next != 0) { error = &ParserMessages::fpiExtraField; return 0; } formal_ = 1; return 1; } Boolean PublicId::nextField(Char solidus, const Char *&next, const Char *lim, const Char *&fieldStart, size_t &fieldLength) { if (next == 0) return 0; fieldStart = next; for (; next < lim; next++) { if (next[0] == solidus && next + 1 < lim && next[1] == solidus) { fieldLength = next - fieldStart; next += 2; return 1; } } fieldLength = lim - fieldStart; next = 0; return 1; } const char *const PublicId::textClasses[] = { "CAPACITY", "CHARSET", "DOCUMENT", "DTD", "ELEMENTS", "ENTITIES", "LPD", "NONSGML", "NOTATION", "SHORTREF", "SUBDOC", "SYNTAX", "TEXT", }; Boolean PublicId::lookupTextClass(const StringC &str, const CharsetInfo &charset, TextClass &textClass) { for (size_t i = 0; i < SIZEOF(textClasses); i++) if (str == charset.execToDesc(textClasses[i])) { textClass = TextClass(i); return 1; } return 0; } Boolean PublicId::getOwnerType(OwnerType &result) const { if (!formal_) return 0; result = ownerType_; return 1; } Boolean PublicId::getOwner(StringC &result) const { if (!formal_) return 0; result = owner_; return 1; } Boolean PublicId::getTextClass(TextClass &result) const { if (!formal_) return 0; result = textClass_; return 1; } Boolean PublicId::getUnavailable(Boolean &result) const { if (!formal_) return 0; result = unavailable_; return 1; } Boolean PublicId::getDescription(StringC &result) const { if (!formal_) return 0; result = description_; return 1; } Boolean PublicId::getLanguage(StringC &result) const { if (!formal_ || textClass_ == CHARSET) return 0; result = languageOrDesignatingSequence_; return 1; } Boolean PublicId::getDesignatingSequence(StringC &result) const { if (!formal_ || textClass_ != CHARSET) return 0; result = languageOrDesignatingSequence_; return 1; } Boolean PublicId::getDisplayVersion(StringC &result) const { if (!formal_) return 0; if (haveDisplayVersion_) result = displayVersion_; return 1; } #ifdef SP_NAMESPACE } #endif