PlatformUtils.hpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:21k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: PlatformUtils.hpp,v 1.12 2001/10/25 21:52:28 peiyongz Exp $
  58.  */
  59. #if !defined(PLATFORMUTILS_HPP)
  60. #define PLATFORMUTILS_HPP
  61. #include <util/XercesDefs.hpp>
  62. #include <util/XMLException.hpp>
  63. class XMLMsgLoader;
  64. class XMLNetAccessor;
  65. class XMLTransService;
  66. //
  67. //  For internal use only
  68. //
  69. //  This class provides a simple abstract API via which lazily evaluated
  70. //  data can be cleaned up.
  71. //
  72. class XMLUTIL_EXPORT XMLDeleter
  73. {
  74. public :
  75.     virtual ~XMLDeleter();
  76. protected :
  77.     XMLDeleter();
  78. private :
  79.     XMLDeleter(const XMLDeleter&);
  80.     void operator=(const XMLDeleter&);
  81. };
  82. /**
  83.   * Utilities that must be implemented in a platform-specific way.
  84.   *
  85.   * This class contains methods that must be implemented in a platform
  86.   * specific manner. The actual implementations of these methods are
  87.   * available in the per-platform files indide <code>src/util/Platforms
  88.   * </code>.
  89.   */
  90. class XMLUTIL_EXPORT XMLPlatformUtils
  91. {
  92. public :
  93.     /** @name Public Types */
  94.     //@{
  95.     enum PanicReasons
  96.     {
  97.         Panic_NoTransService
  98.         , Panic_NoDefTranscoder
  99.         , Panic_CantFindLib
  100.         , Panic_UnknownMsgDomain
  101.         , Panic_CantLoadMsgDomain
  102.         , Panic_SynchronizationErr
  103.         , Panic_SystemInit
  104.         , PanicReasons_Count
  105.     };
  106.     //@}
  107.     /** @name Public Static Data */
  108.     //@{
  109.     /** The network accessor
  110.       *
  111.       * This is provided by the per-platform driver, so each platform can
  112.       * choose what actual implementation it wants to use. The object must
  113.       * be dynamically allocated.
  114.       *
  115.       * <i>Note that you may optionally, if your platform driver does not
  116.       * install a network accessor, set it manually from your client code
  117.       * after calling Initialize(). This works because this object is
  118.       * not required during initialization, and only comes into play during
  119.       * actual XML parsing.</i>
  120.       */
  121.     static XMLNetAccessor*      fgNetAccessor;
  122.     /** The transcoding service.
  123.       *
  124.       * This is provided by the per platform driver, so each platform can
  125.       * choose what implemenation it wants to use. When the platform
  126.       * independent initialization code needs to get a transcoding service
  127.       * object, it will call <code>makeTransService()</code> to ask the
  128.       * per-platform code to create one. Only one transcoding service
  129.       * object is reqeusted per-process, so it is shared and synchronized
  130.       * among parser instances within that process.
  131.       */
  132.     static XMLTransService*     fgTransService;
  133.     //@}
  134.     /** @name Initialization amd Panic methods */
  135.     //@{
  136.     /** Perform per-process parser initialization
  137.       *
  138.       * Initialization <b>must</b> be called first in any client code.
  139.       */
  140.     static void Initialize();
  141.     /** Perform per-process parser termination
  142.       *
  143.       * The termination call is currently optional, to aid those dynamically
  144.       * loading the parser to clean up before exit, or to avoid spurious
  145.       * reports from leak detectors.
  146.       */
  147.     static void Terminate();
  148.     /** The panic mechanism.
  149.       *
  150.       * If, during initialization, we cannot even get far enough along
  151.       * to get transcoding up or get message loading working, we call
  152.       * this method.</p>
  153.       *
  154.       * Each platform can implement it however they want. This method is
  155.       * expected to display something meaningful and end the process. The
  156.       * enum indicates why its being called, to allow the per-platform code
  157.       * to display or log something more specific if desired.</p>
  158.       *
  159.       * @param reason The enumeration that defines the cause of the failure
  160.       */
  161.     static void panic
  162.     (
  163.         const   PanicReasons    reason
  164.     );
  165.     //@}
  166.     /** @name File Methods */
  167.     //@{
  168.     /** Get the current file position
  169.       *
  170.       * This must be implemented by the per-platform driver, which should
  171.       * use local file services to deterine the current position within
  172.       * the passed file.
  173.       *
  174.       * Since the file API provided here only reads, if the host platform
  175.       * supports separate read/write positions, only the read position is
  176.       * of any interest, and hence should be the one returned.
  177.       *
  178.       * @param theFile The file handle
  179.       */
  180.     static unsigned int curFilePos(FileHandle theFile);
  181.     /** Closes the file handle
  182.       *
  183.       * This must be implemented by the per-platform driver, which should
  184.       * use local file services to close the passed file handle, and to
  185.       * destroy the passed file handle and any allocated data or system
  186.       * resources it contains.
  187.       *
  188.       * @param theFile The file handle to close
  189.       */
  190.     static void closeFile(FileHandle theFile);
  191.     /** Returns the file size
  192.       *
  193.       * This must be implemented by the per-platform driver, which should
  194.       * use local file services to determine the current size of the file
  195.       * represented by the passed handle.
  196.       *
  197.       * @param theFile The file handle whose size you want
  198.       *
  199.       * @return Returns the size of the file in bytes
  200.       */
  201.     static unsigned int fileSize(FileHandle theFile);
  202.     /** Opens the file
  203.       *
  204.       * This must be implemented by the per-platform driver, which should
  205.       * use local file services to open passed file. If it fails, a
  206.       * null handle pointer should be returned.
  207.       *
  208.       * @param fileName The string containing the name of the file
  209.       *
  210.       * @return The file handle of the opened file
  211.       */
  212.     static FileHandle openFile(const char* const fileName);
  213.     /** Opens a named file
  214.       *
  215.       * This must be implemented by the per-platform driver, which should
  216.       * use local file services to open the passed file. If it fails, a
  217.       * null handle pointer should be returned.
  218.       *
  219.       * @param fileName The string containing the name of the file
  220.       *
  221.       * @return The file handle of the opened file
  222.       */
  223.     static FileHandle openFile(const XMLCh* const fileName);
  224.     /** Opens the standard input as a file
  225.       *
  226.       * This must be implemented by the per-platform driver, which should
  227.       * use local file services to open a handle to the standard input.
  228.       * It should be a copy of the standard input handle, since it will
  229.       * be closed later!
  230.       *
  231.       * @return The file handle of the standard input stream
  232.       */
  233.     static FileHandle openStdInHandle();
  234.     /** Reads the file buffer
  235.       *
  236.       * This must be implemented by the per-platform driver, which should
  237.       * use local file services to read up to 'toRead' bytes of data from
  238.       * the passed file, and return those bytes in the 'toFill' buffer. It
  239.       * is not an error not to read the requested number of bytes. When the
  240.       * end of file is reached, zero should be returned.
  241.       *
  242.       * @param theFile The file handle to be read from.
  243.       * @param toRead The maximum number of byte to read from the current
  244.       * position
  245.       * @param toFill The byte buffer to fill
  246.       *
  247.       * @return Returns the number of bytes read from the stream or file
  248.       */
  249.     static unsigned int readFileBuffer
  250.     (
  251.                 FileHandle      theFile
  252.         , const unsigned int    toRead
  253.         ,       XMLByte* const  toFill
  254.     );
  255.     /** Resets the file handle
  256.       *
  257.       * This must be implemented by the per-platform driver which will use
  258.       * local file services to reset the file position to the start of the
  259.       * the file.
  260.       *
  261.       * @param theFile The file handle that you want to reset
  262.       */
  263.     static void resetFile(FileHandle theFile);
  264.     //@}
  265.     /** @name File System Methods */
  266.     //@{
  267.     /** Gets the full path from a relative path
  268.       *
  269.       * This must be implemented by the per-platform driver. It should
  270.       * complete a relative path using the 'current directory', or whatever
  271.       * the local equivalent of a current directory is. If the passed
  272.       * source path is actually fully qualified, then a straight copy of it
  273.       * will be returned.
  274.       *
  275.       * @param srcPath The path of the file for which you want the full path
  276.       *
  277.       * @return Returns the fully qualified path of the file name including
  278.       * the file name. This is dyanmically allocated and must be deleted
  279.       * by the caller when its no longer needed!
  280.       */
  281.     static XMLCh* getFullPath(const XMLCh* const srcPath);
  282.     /** Determines if a path is relative or absolute
  283.       *
  284.       * This must be implemented by the per-platform driver, which should
  285.       * determine whether the passed path is relative or not. The concept
  286.       * of relative and absolute might be... well relative on different
  287.       * platforms. But, as long as the determination is made consistently
  288.       * and in coordination with the weavePaths() method, it should work
  289.       * for any platform.
  290.       *
  291.       * @param toCheck The file name which you want to check
  292.       *
  293.       * @return Returns true if the filename appears to be relative
  294.       */
  295.     static bool isRelative(const XMLCh* const toCheck);
  296.     /** Utility to join two paths
  297.       *
  298.       * This must be implemented by the per-platform driver, and should
  299.       * weave the relative path part together with the base part and return
  300.       * a new path that represents this combination.
  301.       *
  302.       * If the relative part turns out to be fully qualified, it will be
  303.       * returned as is. If it is not, then it will be woven onto the
  304.       * passed base path, by removing one path component for each leading
  305.       * "../" (or whatever is the equivalent in the local system) in the
  306.       * relative path.
  307.       *
  308.       * @param basePath The string containing the base path
  309.       * @param relativePath The string containing the relative path
  310.       *
  311.       * @return Returns a string containing the 'woven' path. It should
  312.       * be dynamically allocated and becomes the responsibility of the
  313.       * caller to delete.
  314.       */
  315.     static XMLCh* weavePaths
  316.     (
  317.         const   XMLCh* const    basePath
  318.         , const XMLCh* const    relativePath
  319.     );
  320.     //@}
  321.     /** @name Timing Methods */
  322.     //@{
  323.     /** Gets the system time in milliseconds
  324.       *
  325.       * This must be implemented by the per-platform driver, which should
  326.       * use local services to return the current value of a running
  327.       * millisecond timer. Note that the value returned is only as accurate
  328.       * as the millisecond time of the underyling host system.
  329.       *
  330.       * @return Returns the system time as an unsigned long
  331.       */
  332.     static unsigned long getCurrentMillis();
  333.     //@}
  334.     /** @name Mutex Methods */
  335.     //@{
  336.     /** Closes a mutex handle
  337.       *
  338.       * Each per-platform driver must implement this. Only it knows what
  339.       * the actual content of the passed mutex handle is.
  340.       *
  341.       * @param mtxHandle The mutex handle that you want to close
  342.       */
  343.     static void closeMutex(void* const mtxHandle);
  344.     /** Locks a mutex handle
  345.       *
  346.       * Each per-platform driver must implement this. Only it knows what
  347.       * the actual content of the passed mutex handle is.
  348.       *
  349.       * @param mtxHandle The mutex handle that you want to lock
  350.       */
  351.     static void lockMutex(void* const mtxHandle);
  352.     /** Make a new mutex
  353.       *
  354.       * Each per-platform driver must implement this. Only it knows what
  355.       * the actual content of the passed mutex handle is. The returned
  356.       * handle pointer will be eventually passed to closeMutex() which is
  357.       * also implemented by the platform driver.
  358.       */
  359.     static void* makeMutex();
  360.     /** Unlocks a mutex
  361.       *
  362.       * Each per-platform driver must implement this. Only it knows what
  363.       * the actual content of the passed mutex handle is.
  364.       *
  365.       * Note that, since the underlying system synchronization services
  366.       * are used, Xerces cannot guarantee that lock/unlock operaitons are
  367.       * correctly enforced on a per-thread basis or that incorrect nesting
  368.       * of lock/unlock operations will be caught.
  369.       *
  370.       * @param mtxGandle The mutex handle that you want to unlock
  371.       */
  372.     static void unlockMutex(void* const mtxHandle);
  373.     //@}
  374.     /** @name External Message Support */
  375.     //@{
  376.     /** Loads the message set from among the available domains
  377.       *
  378.       * The returned object must be dynamically allocated and the caller
  379.       * becomes responsible for cleaning it up.
  380.       *
  381.       * @param msgDomain The message domain which you want to load
  382.       */
  383.     static XMLMsgLoader* loadMsgSet(const XMLCh* const msgDomain);
  384.     //@}
  385.     /** @name Miscellaneous synchronization methods */
  386.     //@{
  387.     /** Conditionally updates or returns a single word variable atomically
  388.       *
  389.       * This must be implemented by the per-platform driver. The
  390.       * compareAndSwap subroutine performs an atomic operation which
  391.       * compares the contents of a single word variable with a stored old
  392.       * value. If the values are equal, a new value is stored in the single
  393.       * word variable and TRUE is returned; otherwise, the old value is set
  394.       * to the current value of the single word variable and FALSE is
  395.       * returned.
  396.       *
  397.       * The compareAndSwap subroutine is useful when a word value must be
  398.       * updated only if it has not been changed since it was last read.
  399.       *
  400.       * Note: The word containing the single word variable must be aligned
  401.       * on a full word boundary.
  402.       *
  403.       * @param toFill Specifies the address of the single word variable
  404.       * @param newValue Specifies the new value to be conditionally assigned
  405.       * to the single word variable.
  406.       * @param toCompare Specifies the address of the old value to be checked
  407.       * against (and conditionally updated with) the value of the single word
  408.       * variable.
  409.       *
  410.       * @return Returns the new value assigned to the single word variable
  411.       */
  412.     static void* compareAndSwap
  413.     (
  414.                 void**      toFill
  415.         , const void* const newValue
  416.         , const void* const toCompare
  417.     );
  418.     //@}
  419.     /** @name Atomic Increment and Decrement */
  420.     //@{
  421.     /** Increments a single word variable atomically.
  422.       *
  423.       * This must be implemented by the per-platform driver. The
  424.       * atomicIncrement subroutine increments one word in a single atomic
  425.       * operation. This operation is useful when a counter variable is shared
  426.       * between several threads or processes. When updating such a counter
  427.       * variable, it is important to make sure that the fetch, update, and
  428.       * store operations occur atomically (are not interruptible).
  429.       *
  430.       * @param location Specifies the address of the word variable to be
  431.       * incremented.
  432.       *
  433.       * @return The function return value is positive if the result of the
  434.       * operation was positive. Zero if the result of the operation was zero.
  435.       * Negative if the result of the operation was negative. Except for the
  436.       * zero case, the value returned may differ from the actual result of
  437.       * the operation - only the sign and zero/nonzero state is guaranteed
  438.       * to be correct.
  439.       */
  440.     static int atomicIncrement(int& location);
  441.     /** Decrements a single word variable atomically.
  442.       *
  443.       * This must be implemented by the per-platform driver. The
  444.       * atomicDecrement subroutine increments one word in a single atomic
  445.       * operation. This operation is useful when a counter variable is shared
  446.       * between several threads or processes. When updating such a counter
  447.       * variable, it is important to make sure that the fetch, update, and
  448.       * store operations occur atomically (are not interruptible).
  449.       *
  450.       * @param location Specifies the address of the word variable to be
  451.       * decremented.
  452.       *
  453.       * @return The function return value is positive if the result of the
  454.       * operation was positive. Zero if the result of the operation was zero.
  455.       * Negative if the result of the operation was negative. Except for the
  456.       * zero case, the value returned may differ from the actual result of the
  457.       * operation - only the sign and zero/nonzero state is guaranteed to be
  458.       * correct.
  459.       */
  460.     static int atomicDecrement(int& location);
  461.     //@}
  462.     /** @name NEL Character Handling  */
  463.     //@{
  464. /**
  465.       * This function enables the recognition of NEL char as whitespace chars
  466.       * which is disabled by default.
  467.       * It is only called once per process. Once it is set, any subsequent calls
  468.       * will result in exception being thrown.
  469.       *
  470.       * Note: Turning this option on will make the parser non complicant.
  471.       */
  472.     static void recognizeNEL(bool state);
  473.     /**
  474.       * Return the value of fgNEL flag.
  475.       */
  476.     static bool isNELRecognized();
  477.     //@}
  478. private :
  479.     /** @name Private static methods */
  480.     //@{
  481.     /** Loads a message set from the available domains
  482.       *
  483.       * @param msgDomain The message domain containing the message to be
  484.       * loaded
  485.       */
  486.     static XMLMsgLoader* loadAMsgSet(const XMLCh* const msgDomain);
  487.     /** Creates a net accessor object.
  488.       *
  489.       * Each per-platform driver must implement this method. However,
  490.       * having a Net Accessor is optional and this method can return a
  491.       * null pointer if remote access via HTTP and FTP URLs is not required.
  492.       *
  493.       * @return An object derived from XMLNetAccessor. It must be dynamically
  494.       *         allocated, since it will be deleted later.
  495.       */
  496.     static XMLNetAccessor* makeNetAccessor();
  497.     /** Creates a Transoding service
  498.       *
  499.       * Each per-platform driver must implement this method and return some
  500.       * derivative of the XMLTransService class. This object serves as the
  501.       * transcoder factory for this process. The object must be dynamically
  502.       * allocated and the caller is responsible for cleaning it up.
  503.       *
  504.       * @return A dynamically allocated object of some class derived from
  505.       *         the XMLTransService class.
  506.       */
  507.     static XMLTransService* makeTransService();
  508.     /** Does initialization for a particular platform
  509.       *
  510.       * Each per-platform driver must implement this to do any low level
  511.       * system initialization required. It <b>cannot</b> use any XML
  512.       * parser or utilities services!
  513.       */
  514.     static void platformInit();
  515.     /** Does termination for a particular platform
  516.       *
  517.       * Each per-platform driver must implement this to do any low level
  518.       * system resource cleanup required. It <b>cannot</b> use any XML
  519.       * parser or utilities services!
  520.       */
  521.     static void platformTerm();
  522.     //@}
  523. };
  524. MakeXMLException(XMLPlatformUtilsException, XMLUTIL_EXPORT)
  525. // ---------------------------------------------------------------------------
  526. //  XMLDeleter: Public Destructor
  527. // ---------------------------------------------------------------------------
  528. inline XMLDeleter::~XMLDeleter()
  529. {
  530. }
  531. // ---------------------------------------------------------------------------
  532. //  XMLDeleter: Hidden constructors and operators
  533. // ---------------------------------------------------------------------------
  534. inline XMLDeleter::XMLDeleter()
  535. {
  536. }
  537. #endif