void XalanDOMString::transcode(CharVectorType& theResult) const { invariants(); if (TranscodeToLocalCodePage(c_str(), length(), theResult, true) == false) { throw TranscodingError(); } }
int runTests( int argc, char* argv[]) { // Just hoist everything... XALAN_CPP_NAMESPACE_USE MemoryManagerType& theManager = XalanMemMgrs::getDefaultXercesMemMgr(); XalanFileUtility h(theManager); // Set the program help string, then get the command line parameters. // setHelp(h); bool setGold = false; const XalanDOMString processorType(XALAN_STATIC_UCODE_STRING("XalanC")); if (h.getParams(argc, argv, "PERFT-RESULTS", setGold) == true) { XalanTransformer xalan; // Generate Unique Run id and processor info XalanDOMString UniqRunid; h.generateUniqRunid(UniqRunid); // Defined basic constants for file manipulation and open results file const XalanDOMString resultFilePrefix("cpp"); XalanDOMString resultsFile= h.args.output; resultsFile += resultFilePrefix; resultsFile += UniqRunid; resultsFile += XalanFileUtility::s_xmlSuffix; XalanXMLFileReporter logFile(theManager, resultsFile); logFile.logTestFileInit("Performance Testing - Reports various performance metrics using the Transformer"); // Get the list of sub-directories below "base" and iterate through them bool foundDir = false; // Flag indicates directory found. Used in conjunction with -sub cmd-line arg. typedef XalanFileUtility::FileNameVectorType FileNameVectorType; FileNameVectorType dirs; h.getDirectoryNames(h.args.base, dirs); for(FileNameVectorType::size_type j = 0; j < dirs.size(); j++) { // Run specific category of files from given directory if (length(h.args.sub) > 0 && !equals(dirs[j], h.args.sub)) { continue; } cout << "Processing files in Directory: " << dirs[j] << endl; // Check that output directory is there. XalanDOMString theOutputDir = h.args.output; theOutputDir += dirs[j]; h.checkAndCreateDir(theOutputDir); // Indicate that directory was processed and get test files from the directory foundDir = true; FileNameVectorType files; h.getTestFileNames(h.args.base, dirs[j], false, files); XalanDOMString logEntry; logEntry = "Performance Directory: "; logEntry += dirs[j]; logFile.logTestCaseInit(logEntry); const long iterCount = h.args.iters; for(FileNameVectorType::size_type i = 0; i < files.size(); i++) { // Define variables used for timing and reporting ... clock_t startTime, endTime, accmTime, avgEtoe; double timeinMilliseconds = 0, theAverage =0; int transformResult = 0; typedef XalanXMLFileReporter::Hashtable Hashtable; Hashtable attrs(theManager); attrs.insert(Hashtable::value_type(XalanDOMString("idref"), files[i])); attrs.insert(Hashtable::value_type(XalanDOMString("UniqRunid"),UniqRunid)); attrs.insert(Hashtable::value_type(XalanDOMString("processor"),processorType)); logFile.addMetricToAttrs("Iterations",iterCount, attrs); if (h.args.skip) { if (checkForExclusion(files[i])) continue; } XalanDOMString theXSLFile = h.args.base; theXSLFile += dirs[j]; theXSLFile += XalanFileUtility::s_pathSep; theXSLFile += files[i]; XalanDOMString theXMLFile; h.generateFileName(theXSLFile,"xml", theXMLFile); XalanDOMString outbase = h.args.output; outbase += dirs[j]; outbase += XalanFileUtility::s_pathSep; outbase += files[i]; XalanDOMString theOutputFile; h.generateFileName(outbase, "out", theOutputFile); const XSLTInputSource xslInputSource(theXSLFile); const XSLTInputSource xmlInputSource(theXMLFile); const XSLTResultTarget theResultTarget(theOutputFile); attrs.insert(Hashtable::value_type(XalanDOMString("href"), theXSLFile)); cout << endl << files[i] << endl; // Time the parsing(compile) of the XSL stylesheet and report the results.. // startTime = clock(); const XalanCompiledStylesheet* compiledSS = 0; xalan.compileStylesheet(xslInputSource, compiledSS); endTime = clock(); if (compiledSS == 0) { continue; } timeinMilliseconds = calculateElapsedTime(startTime, endTime); cout << " XSL: " << timeinMilliseconds << " milliseconds, Parse" << endl; logFile.addMetricToAttrs("parsexsl",timeinMilliseconds, attrs); // Time the parsing of the input XML and report the results.. // startTime = clock(); const XalanParsedSource* parsedSource = 0; xalan.parseSource(xmlInputSource, parsedSource); endTime = clock(); if (parsedSource == 0) { continue; } timeinMilliseconds = calculateElapsedTime(startTime, endTime); cout << " XML: " << timeinMilliseconds << " milliseconds, Parse" <<endl; logFile.addMetricToAttrs("parsexml",timeinMilliseconds, attrs); // Perform One transform using parsed stylesheet and unparsed xml source, report results... // startTime = clock(); transformResult = xalan.transform(xmlInputSource, compiledSS, theResultTarget); endTime = clock(); if(!transformResult) { timeinMilliseconds = calculateElapsedTime(startTime, endTime); cout << endl << " One: " << timeinMilliseconds << " w/Parsed XSL." << endl; logFile.addMetricToAttrs("single", timeinMilliseconds, attrs); } else { cout << xalan.getLastError(); return -1; } // Do One eTOe transform with no pre parsing of either xsl or xml files. // And output metrics to console and result log startTime = clock(); transformResult = xalan.transform(xmlInputSource, xslInputSource, theResultTarget); endTime = clock(); if(!transformResult) { timeinMilliseconds = calculateElapsedTime(startTime, endTime); cout << " One: " << timeinMilliseconds << " eTOe." << endl; logFile.addMetricToAttrs("etoe", timeinMilliseconds, attrs); } else { cout << xalan.getLastError(); return -1; } // Perform multiple transforms and calculate the average time .. // These are done 3 different ways. // // FIRST: Parsed XSL Stylesheet and Parsed XML Source. // accmTime = 0; for(int j = 0; j < iterCount; ++j) { startTime = clock(); transformResult = xalan.transform(*parsedSource, compiledSS, theResultTarget); endTime = clock(); accmTime += endTime - startTime; } theAverage = calculateAvgTime(accmTime, iterCount); cout << endl << " Avg: " << theAverage << " for " << iterCount << " iter's w/Parsed files" << endl; logFile.addMetricToAttrs("avgparsedxml",theAverage, attrs); // SECOND: Parsed Stylesheet and UnParsed XML Source. // This is currently how the XalanJ 2.0 is performing transforms // accmTime = 0; for(int k = 0; k < iterCount; ++k) { startTime = clock(); transformResult = xalan.transform(xmlInputSource, compiledSS, theResultTarget); endTime = clock(); accmTime += endTime - startTime; } theAverage = calculateAvgTime(accmTime, iterCount); cout << " Avg: " << theAverage << " for " << iterCount << " iter's w/UnParsed XML" << endl; logFile.addMetricToAttrs("avgunparsedxml",theAverage, attrs); // THIRD: Neither Stylesheet nor XML Source are parsed. // Perform multiple etoe transforms and calculate the average ... // avgEtoe = 0; for(int jj = 0; jj < iterCount; ++jj) { startTime = clock(); transformResult = xalan.transform(xmlInputSource, xslInputSource, theResultTarget); endTime = clock(); avgEtoe += endTime - startTime; } theAverage = calculateAvgTime(avgEtoe,iterCount); // Output average transform time to console and result log cout << " Avg: " << theAverage << " for " << iterCount << " iter's of eToe" << endl; logFile.addMetricToAttrs("avgetoe",theAverage, attrs); logFile.logElementWAttrs(10, "perf", attrs, "xxx"); xalan.destroyParsedSource(parsedSource); xalan.destroyStylesheet(compiledSS); } logEntry = "Performance Directory: "; logEntry += dirs[j]; logFile.logTestCaseClose(logEntry, XalanDOMString("Done")); } // Check to see if -sub cmd-line directory was processed correctly. if (!foundDir) { cout << "Specified test directory: \"" << c_str(TranscodeToLocalCodePage(h.args.sub)) << "\" not found" << endl; } h.reportPassFail(logFile, UniqRunid); logFile.logTestFileClose("Performance", "Done"); logFile.close(); } return 0; }
void XalanOutputStream::transcode( const XalanDOMChar* theBuffer, size_type theBufferLength, TranscodeVectorType& theDestination) { if (m_transcoder == 0) { if (TranscodeToLocalCodePage( theBuffer, theBufferLength, theDestination) == false) { if (m_throwTranscodeException == true) { XalanDOMString theBuffer(theDestination.getMemoryManager()); throw TranscodingException(theBuffer); } else { } } } else { bool fDone = false; // Keep track of the total bytes we've added to the // destination vector, and the total bytes we've // eaten from theBuffer. size_type theTotalBytesFilled = 0; size_type theTotalBytesEaten = 0; // Keep track of the current position in the input buffer, // and amount remaining in the buffer, since we may not be // able to transcode it all at once. const XalanDOMChar* theBufferPosition = theBuffer; size_type theRemainingBufferLength = theBufferLength; // Keep track of the destination size, and the target size, which is // the size of the destination that has not yet been filled with // transcoded characters. Double the buffer size, in case we're // transcoding to a 16-bit encoding. // $$$ ToDo: We need to know the size of an encoding, so we can // do the right thing with the destination size. size_type theDestinationSize = theBufferLength * 2; size_type theTargetSize = theDestinationSize; do { // Resize the buffer... theDestination.resize(theDestinationSize + 1); size_type theSourceBytesEaten = 0; size_type theTargetBytesEaten = 0; XalanTranscodingServices::eCode theResult = m_transcoder->transcode( theBufferPosition, theRemainingBufferLength, #if defined(XALAN_OLD_STYLE_CASTS) (XMLByte*)&theDestination[0] + theTotalBytesFilled, #else reinterpret_cast<XMLByte*>(&theDestination[0]) + theTotalBytesFilled, #endif theTargetSize, theSourceBytesEaten, theTargetBytesEaten); if(theResult != XalanTranscodingServices::OK) { if (m_throwTranscodeException == true) { XalanDOMString theBuffer(theDestination.getMemoryManager()); throw TranscodingException(theBuffer); } } theTotalBytesFilled += theTargetBytesEaten; theTotalBytesEaten += theSourceBytesEaten; if (theTotalBytesEaten == theBufferLength) { fDone = true; } else { assert(theTotalBytesEaten < theBufferLength); // Update everything... theBufferPosition += theSourceBytesEaten; theRemainingBufferLength -= theSourceBytesEaten; // The new target size will always be the // current destination size, since we // grow by a factor of 2. This will // need to change if the factor is // every changed. theTargetSize = theDestinationSize; // Grow the destination by a factor of // two 2. See the previous comment if // you want to change this. theDestinationSize = theDestinationSize * 2; } } while(fDone == false); // Resize things, if there are any extra bytes... if (theDestination.size() != theTotalBytesFilled) { theDestination.resize(theTotalBytesFilled); } } }