virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const { LocaleKey &lkey = (LocaleKey&)key; Locale loc; lkey.currentLocale(loc); #ifdef U_DEBUG_CALSVC fprintf(stderr, "DefaultCalendar factory %p: looking up %s\n", this, (const char*)loc.getName()); #endif UErrorCode resStatus = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, (const char*)loc.getName(), &resStatus); #ifdef U_DEBUG_CALSVC fprintf(stderr, "... ures_open -> %s\n", u_errorName(resStatus)); #endif if(U_FAILURE(resStatus) || (resStatus == U_USING_DEFAULT_WARNING) || (resStatus==U_USING_FALLBACK_WARNING)) { //Don't want to handle fallback data. ures_close(rb); status = resStatus; // propagate err back to caller #ifdef U_DEBUG_CALSVC fprintf(stderr, "... exitting (NULL)\n"); #endif return NULL; } int32_t len = 0; UnicodeString myString = ures_getUnicodeStringByKey(rb, Calendar::kDefaultCalendar, &status); #ifdef U_DEBUG_CALSVC UErrorCode debugStatus = U_ZERO_ERROR; const UChar *defCal = ures_getStringByKey(rb, Calendar::kDefaultCalendar, &len, &debugStatus); fprintf(stderr, "... get string(%d) -> %s\n", len, u_errorName(debugStatus)); #endif ures_close(rb); if(U_FAILURE(status)) { return NULL; } #ifdef U_DEBUG_CALSVC { char defCalStr[200]; if(len > 199) { len = 199; } u_UCharsToChars(defCal, defCalStr, len); defCalStr[len]=0; fprintf(stderr, "DefaultCalendarFactory: looked up %s, got DefaultCalendar= %s\n", (const char*)loc.getName(), defCalStr); } #endif return myString.clone(); }
// // createElement // We've just matched an element start tag. Create and fill in a UXMLElement object // for it. // UXMLElement * UXMLParser::createElement(RegexMatcher &mEl, UErrorCode &status) { // First capture group is the element's name. UXMLElement *el = new UXMLElement(this, intern(mEl.group(1, status), status), status); // Scan for attributes. int32_t pos = mEl.end(1, status); // The position after the end of the tag name while (mAttrValue.lookingAt(pos, status)) { // loop runs once per attribute on this element. UnicodeString attName = mAttrValue.group(1, status); UnicodeString attValue = mAttrValue.group(2, status); // Trim the quotes from the att value. These are left over from the original regex // that parsed the attribue, which couldn't conveniently strip them. attValue.remove(0,1); // one char from the beginning attValue.truncate(attValue.length()-1); // and one from the end. // XML Attribue value normalization. // This is one of the really screwy parts of the XML spec. // See http://www.w3.org/TR/2004/REC-xml11-20040204/#AVNormalize // Note that non-validating parsers must treat all entities as type CDATA // which simplifies things some. // Att normalization step 1: normalize any newlines in the attribute value mNewLineNormalizer.reset(attValue); attValue = mNewLineNormalizer.replaceAll(fOneLF, status); // Next change all xml white space chars to plain \u0020 spaces. mAttrNormalizer.reset(attValue); UnicodeString oneSpace((UChar)0x0020); attValue = mAttrNormalizer.replaceAll(oneSpace, status); // Replace character entities. replaceCharRefs(attValue, status); // Save the attribute name and value in our document structure. el->fAttNames.addElement((void *)intern(attName, status), status); el->fAttValues.addElement(attValue.clone(), status); pos = mAttrValue.end(2, status); } fPos = mEl.end(0, status); return el; }
/** * Register an entry object (adopted) with the given ID, source, * target, and variant strings. */ void TransliteratorRegistry::registerEntry(const UnicodeString& ID, const UnicodeString& source, const UnicodeString& target, const UnicodeString& variant, TransliteratorEntry* adopted, UBool visible) { UErrorCode status = U_ZERO_ERROR; registry.put(ID, adopted, status); if (visible) { registerSTV(source, target, variant); if (!availableIDs.contains((void*) &ID)) { UnicodeString *newID = (UnicodeString *)ID.clone(); // Check to make sure newID was created. if (newID != NULL) { // NUL-terminate the ID string newID->getTerminatedBuffer(); availableIDs.addElement(newID, status); } } } else { removeSTV(source, target, variant); availableIDs.removeElement((void*) &ID); } }
UXMLElement * UXMLParser::parse(const UnicodeString &src, UErrorCode &status) { if(U_FAILURE(status)) { return NULL; } UXMLElement *root = NULL; fPos = 0; // TODO use just a local pos variable and pass it into functions // where necessary? // set all matchers to work on the input string mXMLDecl.reset(src); mXMLComment.reset(src); mXMLSP.reset(src); mXMLDoctype.reset(src); mXMLPI.reset(src); mXMLElemStart.reset(src); mXMLElemEnd.reset(src); mXMLElemEmpty.reset(src); mXMLCharData.reset(src); mAttrValue.reset(src); mAttrNormalizer.reset(src); mNewLineNormalizer.reset(src); mAmps.reset(src); // Consume the XML Declaration, if present. if (mXMLDecl.lookingAt(fPos, status)) { fPos = mXMLDecl.end(status); } // Consume "misc" [XML production 27] appearing before DocType parseMisc(status); // Consume a DocType declaration, if present. if (mXMLDoctype.lookingAt(fPos, status)) { fPos = mXMLDoctype.end(status); } // Consume additional "misc" [XML production 27] appearing after the DocType parseMisc(status); // Get the root element if (mXMLElemEmpty.lookingAt(fPos, status)) { // Root is an empty element (no nested elements or content) root = createElement(mXMLElemEmpty, status); fPos = mXMLElemEmpty.end(status); } else { if (mXMLElemStart.lookingAt(fPos, status) == FALSE) { error("Root Element expected", status); goto errorExit; } root = createElement(mXMLElemStart, status); UXMLElement *el = root; // // This is the loop that consumes the root element of the document, // including all nested content. Nested elements are handled by // explicit pushes/pops of the element stack; there is no recursion // in the control flow of this code. // "el" always refers to the current element, the one to which content // is being added. It is above the top of the element stack. for (;;) { // Nested Element Start if (mXMLElemStart.lookingAt(fPos, status)) { UXMLElement *t = createElement(mXMLElemStart, status); el->fChildren.addElement(t, status); t->fParent = el; fElementStack.push(el, status); el = t; continue; } // Text Content. String is concatenated onto the current node's content, // but only if it contains something other than spaces. UnicodeString s = scanContent(status); if (s.length() > 0) { mXMLSP.reset(s); if (mXMLSP.matches(status) == FALSE) { // This chunk of text contains something other than just // white space. Make a child node for it. replaceCharRefs(s, status); el->fChildren.addElement(s.clone(), status); } mXMLSP.reset(src); // The matchers need to stay set to the main input string. continue; } // Comments. Discard. if (mXMLComment.lookingAt(fPos, status)) { fPos = mXMLComment.end(status); continue; } // PIs. Discard. if (mXMLPI.lookingAt(fPos, status)) { fPos = mXMLPI.end(status); continue; } // Element End if (mXMLElemEnd.lookingAt(fPos, status)) { fPos = mXMLElemEnd.end(0, status); const UnicodeString name = mXMLElemEnd.group(1, status); if (name != *el->fName) { error("Element start / end tag mismatch", status); goto errorExit; } if (fElementStack.empty()) { // Close of the root element. We're done with the doc. el = NULL; break; } el = (UXMLElement *)fElementStack.pop(); continue; } // Empty Element. Stored as a child of the current element, but not stacked. if (mXMLElemEmpty.lookingAt(fPos, status)) { UXMLElement *t = createElement(mXMLElemEmpty, status); el->fChildren.addElement(t, status); continue; } // Hit something within the document that doesn't match anything. // It's an error. error("Unrecognized markup", status); break; } if (el != NULL || !fElementStack.empty()) { // We bailed out early, for some reason. error("Root element not closed.", status); goto errorExit; } } // Root Element parse is complete. // Consume the annoying xml "Misc" that can appear at the end of the doc. parseMisc(status); // We should have reached the end of the input if (fPos != src.length()) { error("Extra content at the end of the document", status); goto errorExit; } // Success! return root; errorExit: delete root; return NULL; }