Hi there. I'm relativly new to Xalan (and a complete novice with C++!!).
We have a UNIX based product which used a C API to interface to the outside world. While implementing an XML interface using Xalan/Xerces I wanted to avoid the use of files completely and so have exposed some more of the C++ interfaces to the XalanTransformer through the C API files. For my own convenience, I've added these to the XalanCAPI.cpp/XalanCAPI.h files (see attached - ref. "STAFFWARE ADDITIONS") as, when I tried to add a new .cpp file to my local project it didn't like the stream calls?? Anyway, I've got it working by using the modified C API files and am passing these back to you for comment/incorporation into the product (if appropriate). Regards Paul McMinn Staffware Professional Services Division _______________________________________________________________________ Never pay another Internet phone bill! Freeserve AnyTime, for all the Internet access you want, day and night, only �12.99 per month. Sign-up at http://www.freeserve.com/time/anytime
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, International * Business Machines, Inc., http://www.ibm.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #include "XalanTransformerDefinitions.hpp" #include <util/PlatformUtils.hpp> #include <cassert> #if defined(XALAN_OLD_STREAM_HEADERS) #include <strstream.h> #else #include <strstream> #endif #include "XalanCAPI.h" #include "XalanTransformer.hpp" XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanInitialize() { // Call the static initializer for Xerces. XMLPlatformUtils::Initialize(); // Initialize Xalan. XalanTransformer::initialize(); } XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanTerminate() { // Terminate Xalan. XalanTransformer::terminate(); // Call the static terminator for Xerces. XMLPlatformUtils::Terminate(); } XALAN_TRANSFORMER_EXPORT_FUNCTION(XalanHandle) CreateXalanTransformer() { // Create a XalanTransformer object. return new XalanTransformer(); } inline XalanTransformer* getTransformer(XalanHandle theHandle) { assert(theHandle != 0); #if defined(XALAN_OLD_STYLE_CASTS) return (XalanTransformer*)theHandle; #else return static_cast<XalanTransformer*>(theHandle); #endif } inline const XalanCompiledStylesheet* getStylesheet(XalanCSSHandle theHandle) { assert(theHandle != 0); #if defined(XALAN_OLD_STYLE_CASTS) return (const XalanCompiledStylesheet*)theHandle; #else return reinterpret_cast<const XalanCompiledStylesheet*>(theHandle); #endif } inline const XalanParsedSource* getParsedSource(XalanPSHandle theHandle) { assert(theHandle != 0); #if defined(XALAN_OLD_STYLE_CASTS) return (const XalanParsedSource*)theHandle; #else return reinterpret_cast<const XalanParsedSource*>(theHandle); #endif } XALAN_TRANSFORMER_EXPORT_FUNCTION(void) DeleteXalanTransformer(XalanHandle theXalanHandle) { // Delete a XalanTransformer object. delete getTransformer(theXalanHandle); } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToFile( const char* theXMLFileName, const char* theXSLFileName, const char* theOutFileName, XalanHandle theXalanHandle) { if(theXSLFileName == 0) { return getTransformer(theXalanHandle)->transform( theXMLFileName, theOutFileName); } else { return getTransformer(theXalanHandle)->transform( theXMLFileName, theXSLFileName, theOutFileName); } } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToFilePrebuilt( XalanPSHandle theParsedSource, XalanCSSHandle theCSSHandle, const char* theOutFileName, XalanHandle theXalanHandle) { // Do the transformation... return getTransformer(theXalanHandle)->transform( *getParsedSource(theParsedSource), getStylesheet(theCSSHandle), theOutFileName); } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToData( const char* theXMLFileName, const char* theXSLFileName, char** theOutput, XalanHandle theXalanHandle) { #if !defined(XALAN_NO_NAMESPACES) using std::ostrstream; #endif int status = 0; ostrstream theOutputStream; if(theXSLFileName == 0) { status = getTransformer(theXalanHandle)->transform( theXMLFileName, theOutputStream); } else { status = getTransformer(theXalanHandle)->transform( theXMLFileName, theXSLFileName, theOutputStream); } if (status == 0) { // Null-terminate the data. theOutputStream << '\0'; *theOutput = theOutputStream.str(); } return status; } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToDataPrebuilt( XalanPSHandle theParsedSource, XalanCSSHandle theCSSHandle, char** theOutput, XalanHandle theXalanHandle) { #if !defined(XALAN_NO_NAMESPACES) using std::ostrstream; #endif ostrstream theOutputStream; // Do the transformation... const int status = getTransformer(theXalanHandle)->transform( *getParsedSource(theParsedSource), getStylesheet(theCSSHandle), theOutputStream); if (status == 0) { // Null-terminate the data. theOutputStream << '\0'; *theOutput = theOutputStream.str(); } return status; } XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanFreeData(char* theStream) { // Delete the data. delete[] theStream; } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToHandler( const char* theXMLFileName, const char* theXSLFileName, XalanHandle theXalanHandle, void* theOutputHandle, XalanOutputHandlerType theOutputHandler, XalanFlushHandlerType theFlushHandler) { // Do the transformation... return getTransformer(theXalanHandle)->transform( theXMLFileName, theXSLFileName, theOutputHandle, theOutputHandler, theFlushHandler); } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToHandlerPrebuilt( XalanPSHandle theParsedSource, XalanCSSHandle theCSSHandle, XalanHandle theXalanHandle, void* theOutputHandle, XalanOutputHandlerType theOutputHandler, XalanFlushHandlerType theFlushHandler) { // Do the transformation... return getTransformer(theXalanHandle)->transform( *getParsedSource(theParsedSource), getStylesheet(theCSSHandle), theOutputHandle, theOutputHandler, theFlushHandler); } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanCompileStylesheet( const char* theXSLFileName, XalanHandle theXalanHandle, XalanCSSHandle* theCSSHandle) { const XalanCompiledStylesheet* theCompiledStylesheet = 0; const int theResult = getTransformer(theXalanHandle)->compileStylesheet( theXSLFileName, theCompiledStylesheet); if (theResult == 0) { *theCSSHandle = theCompiledStylesheet; } return theResult; } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanDestroyCompiledStylesheet( XalanCSSHandle theCSSHandle, XalanHandle theXalanHandle) { return getTransformer(theXalanHandle)->destroyStylesheet(getStylesheet(theCSSHandle)); } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanParseSource( const char* theXMLFileName, XalanHandle theXalanHandle, XalanPSHandle* thePSHandle) { const XalanParsedSource* theParsedSource = 0; const int theResult = getTransformer(theXalanHandle)->parseSource( theXMLFileName, theParsedSource); if (theResult == 0) { *thePSHandle = theParsedSource; } return theResult; } XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanSetStylesheetParam( const char* key, const char* expression, XalanHandle theXalanHandle) { getTransformer(theXalanHandle)->setStylesheetParam( XalanDOMString(key), XalanDOMString(expression)); } XALAN_TRANSFORMER_EXPORT_FUNCTION(XalanCCharPtr) XalanGetLastError(XalanHandle theXalanHandle) { // Get the last error. return getTransformer(theXalanHandle)->getLastError(); } /********************************************************************* * STAFFWARE ADDITIONS *********************************************************************/ /* XalanDestroyParsedSource() - Clean up routine for ParsedSource. * In standard CAPI header (XalanCAPI.h) but not in delivered CPP file??? */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanDestroyParsedSource( XalanPSHandle thePSHandle, XalanHandle theXalanHandle) { return getTransformer(theXalanHandle)->destroyParsedSource(getParsedSource(thePSHandle)); } /* XalanParseSourceData() - As per XalanParseSource() but using raw XML * data as its input. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanParseSourceData( const char* theInputDocument, XalanHandle theXalanHandle, XalanPSHandle* thePSHandle) { #if !defined(XALAN_NO_NAMESPACES) using std::istrstream; #endif // Our input streams... istrstream theXMLStream(theInputDocument, strlen(theInputDocument)); const XalanParsedSource* theParsedSource = 0; int theResult; theResult = getTransformer(theXalanHandle)->parseSource( &theXMLStream, theParsedSource); if (theResult == 0) { *thePSHandle = theParsedSource; } return theResult; } XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanCompileStylesheetData( const char* theXSLData, XalanHandle theXalanHandle, XalanCSSHandle* theCSSHandle) { #if !defined(XALAN_NO_NAMESPACES) using std::istrstream; #endif // Our input streams... istrstream theXSLStream(theXSLData, strlen(theXSLData)); const XalanCompiledStylesheet* theCompiledStylesheet = 0; const int theResult = getTransformer(theXalanHandle)->compileStylesheet( &theXSLStream, theCompiledStylesheet); if (theResult == 0) { *theCSSHandle = theCompiledStylesheet; } return theResult; }
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, International * Business Machines, Inc., http://www.ibm.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ #if !defined(XALAN_CAPI_HEADER_GUARD_1357924680) #define XALAN_CAPI_HEADER_GUARD_1357924680 #include <XalanTransformer/XalanTransformerDefinitions.hpp> /** * This is a simple C interface for the class XalanTransformer. It's * the user's responsibility to call XalanInitialize() before making * any other API calls, and to call XalanTerminate() when finished * with the API. * * After calling XalanTransformToData or XalanTransformToDataCSS, the user * should call XalanFreeData to release the memory allocated by that * operation. */ #if defined(__cplusplus) extern "C" { #endif /** * Handle used to store the address of XalanTransformer instance. */ typedef void* XalanHandle; /** * Handle used to store the address of Compiled Stylesheet instance. */ typedef const void* XalanCSSHandle; /** * Handle used to store the address of Parsed Source instance. */ typedef const void* XalanPSHandle; /** * This is a typedef to work around limitations with * the XALAN_TRANSFORMER_EXPORT_FUNCTION macro. */ typedef const char* XalanCCharPtr; /** * Initialize Xerces and Xalan. * * Should be called only once per process before making * any other API calls. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanInitialize(); /** * Terminate Xalan and Xerces. * * Should be called only once per process after deleting all * instances of XalanTransformer. Once a process has called * this function, it cannot use the API for the remaining * lifetime of the process. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanTerminate(); /** * Create a XalanTransformer instance. * * @return the XalanTransformer handle */ XALAN_TRANSFORMER_EXPORT_FUNCTION(XalanHandle) CreateXalanTransformer(); /** * Delete a XalanTransformer instance. * * @param theXalanHandle The XalanTransformer to destroy. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(void) DeleteXalanTransformer(XalanHandle theXalanHandle); /** * Transform the XML source tree to the given result file. * The processor will apply the stylesheet file to the input * file and write the transformation result to a new output file. * * @param theXMLFileName filename of XML input source * @param theXSLFileName filename of stylesheet source * @param theOutFileName filename of output source * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToFile( const char* theXMLFileName, const char* theXSLFileName, const char* theOutFileName, XalanHandle theXalanHandle); /** * Transform the XML source tree to the given result file. * The processor will apply the compiled stylesheet to the input * file and write the transformation result to a new output file. * * @param theParsedSource handle of parsed source * @param theCSSHandle handle of compiled stylesheet * @param theOutFileName filename of output source * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToFilePrebuilt( XalanPSHandle theParsedSource, XalanCSSHandle theCSSHandle, const char* theOutFileName, XalanHandle theXalanHandle); /** * Transform the XML source tree to a dynamically allocated buffer. * The processor will apply the stylesheet file to the input file * and assign the address of the dynamically allocated result to a * user supplied pointer. The user must call XalanFreeData with the * this pointer. * * @param theXMLFileName filename of XML input source * @param theXSLFileName filename of stylesheet source * @param theOutput a pointer to a char* * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToData( const char* theXMLFileName, const char* theXSLFileName, char** theOutput, XalanHandle theXalanHandle); /** * Transform the XML source tree to a dynamically allocated buffer. * The processor will apply the compiled stylesheet to the input file * and assign the address of the dynamically allocated result to a * user supplied pointer. The user must call XalanFreeData with the * this pointer. * * @param theXMLFileName filename of XML input source * @param theCSSHandle handle of compiled stylesheet * @param theOutput a pointer to a char* * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToDataPrebuilt( XalanPSHandle theParsedSource, XalanCSSHandle theCSSHandle, char** theOutput, XalanHandle theXalanHandle); /** * Free memory allocated as a result of calling * XalanTransformToData. * * @param theData The address of character data. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanFreeData(char* theData); /** * Transform the XML source tree to a callback function. * The processor will apply the stylesheet file to the input file * and allocate the transformation result to a callback function * in pre-allocated blocks. Once the transformation is complete, * a second callback, to flush the buffer, is called. You can pass * in NULL if you do not wish to implement a flush callback. Xalan * will release any memory allocated upon termination, and data passed * to the callback is not guaranteed to be null terminated. * * See XalanTransformerDefinitions.hpp for more details. * * @param theXMLFileName filename of XML input source * @param theXSLFileName filename of stylesheet source * @param theXalanHandle handle of XalanTransformer instance. * @param theOutputHandle void pointer passed through to callback. * @param theOutputHandler a user defined (callback) function. * @param theFlushHandler (can be NULL) a user defined (callback) function. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToHandler( const char* theXMLFileName, const char* theXSLFileName, XalanHandle theXalanHandle, void* theOutputHandle, XalanOutputHandlerType theOutputHandler, XalanFlushHandlerType theFlushHandler); /** * Transform the XML source tree to a callback function. * The processor will apply the compiled stylesheet to the input file * and allocate the transformation result to a callback function * in pre-allocated blocks. Once the transformation is complete, * a second callback, to flush the buffer, is called. You can pass * in NULL if you do not wish to implement a flush callback. Xalan * will release any memory allocated upon termination, and data passed * to the callback is not guaranteed to be null terminated. * * See XalanTransformerDefinitions.hpp for more details. * * @param thePSHandle handle of parsed source * @param theCSSHandle handle of compiled stylesheet * @param theXalanHandle handle of XalanTransformer instance. * @param theOutputHandle void pointer passed through to callback. * @param theOutputHandler a user defined (callback) function. * @param theFlushHandler (can be NULL) a user defined (callback) function. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanTransformToHandlerPrebuilt( XalanPSHandle thePSHandle, XalanCSSHandle theCSSHandle, XalanHandle theXalanHandle, void* theOutputHandle, XalanOutputHandlerType theOutputHandler, XalanFlushHandlerType theFlushHandler); /** * Creates a compiled stylesheet. * * @param theXSLFileName filename of stylesheet source * @param theXalanHandle handle of XalanTransformer instance. * @param theCSSHandle a pointer to a XalanCSSHandle * @return 0 for success. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanCompileStylesheet( const char* theXSLFileName, XalanHandle theXalanHandle, XalanCSSHandle* theCSSHandle); /** * Destroys a compiled stylesheet. * * @param theCSSHandle handle of the compiled stylesheet * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanDestroyCompiledStylesheet( XalanCSSHandle theCSSHandle, XalanHandle theXalanHandle); /** * Parse source document. The input source can be * a file name, a stream or a root node. * * @param theInputSource input source * @param theXalanHandle handle of XalanTransformer instance. * @param thePSHandle a pointer to a XalanPSHandle * @return 0 for success. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanParseSource( const char* theXMLFileName, XalanHandle theXalanHandle, XalanPSHandle* thePSHandle); /** * Destroys a parsed source. * a file name, a stream or a root node. * * @param thePSHandle handle of parsed source * @param theXalanHandle handle of XalanTransformer instance. * @return 0 for success */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanDestroyParsedSource( XalanPSHandle thePSHandle, XalanHandle theXalanHandle); /** * Set a top-level stylesheet parameter. This value can be evaluated via * xsl:param-variable. * * @param key name of the param * @param expression expression that will be evaluated * @param theXalanHandle handle of XalanTransformer instance. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(void) XalanSetStylesheetParam( const char* key, const char* expression, XalanHandle theXalanHandle); /** * Returns the last error that occurred as a * result of calling transform. * * The signiture for following function is really: * const char* * XalanGetLastError(XalanHandle theXalanHandle) const; * * @return error message const character pointer. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(XalanCCharPtr) XalanGetLastError(XalanHandle theXalanHandle); /*************************************************************** * STAFFWARE ADDITIONS ***************************************************************/ /** * Parse source document. The input source is a character * buffer. * * @param theInputSource input source * @param theXalanHandle handle of XalanTransformer instance. * @param thePSHandle a pointer to a XalanPSHandle * @return 0 for success. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanParseSourceData( const char* theInputSource, XalanHandle theXalanHandle, XalanPSHandle* thePSHandle); /** * Creates a compiled stylesheet from a char* buffer. * * @param theXSLData pointer to stylesheet source * @param theXalanHandle handle of XalanTransformer instance. * @param theCSSHandle a pointer to a XalanCSSHandle * @return 0 for success. */ XALAN_TRANSFORMER_EXPORT_FUNCTION(int) XalanCompileStylesheetData( const char* theXSLData, XalanHandle theXalanHandle, XalanCSSHandle* theCSSHandle); #if defined(__cplusplus) } #endif #endif // XALAN_CAPI_HEADER_GUARD_1357924680
