You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by pe...@apache.org on 2004/08/11 18:05:55 UTC

cvs commit: xml-xerces/c/src/xercesc/framework/psvi XSValue.hpp XSValue.cpp

peiyongz    2004/08/11 09:05:54

  Added:       c/src/xercesc/framework/psvi XSValue.hpp XSValue.cpp
  Log:
  Externalised validation, actual/canonical value production for Schema built-in data types
  
  Revision  Changes    Path
  1.1                  xml-xerces/c/src/xercesc/framework/psvi/XSValue.hpp
  
  Index: XSValue.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2004 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 "Xerces" 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 apache\@apache.org.
   *
   * 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/>.
   */
  
  /*
   * $Log $
   * $Id $
   */
  
  #if !defined(XSVALUE_HPP)
  #define XSVALUE_HPP
  
  #include <xercesc/util/PlatformUtils.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  class XMLPARSER_EXPORT XSValueContext : public XMemory
  {
  public:
  
      enum XMLVersion {
              ver_10,
              ver_11
      };
  
      enum Status {
              st_Init,
              st_Invalid,
              st_InvalidChar,     //for numeric
              st_InvalidRange,    //for numeric
              st_UnRepresentable, //for numeric
              st_NoCanRep,
              st_NoActVal,
              st_NotSupported,
              st_UnknownType
      };
  
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
      /** @name Constructors */
      //@{
  
      /**
        * The default constructor 
        */
      XSValueContext
                    (
                      XMLVersion   version    = ver_10
                   ,  bool         toValidate = true 
                    );
  
      //@};
  
      /** @name Destructor */
      //@{
      ~XSValueContext();
      //@}
  
      /** @name Getters */
      //@{
  
      inline
      XMLVersion  getVersion()       const;
      
      inline
      bool        getValidation()    const;
  
      inline
      Status      getStatus()        const;
  
      //@}
  
      /** @name Setters */
      //@{
      inline
      void        setVersion(XMLVersion newVersion);
  
      inline
      void        setValidation(bool    toValidate);
      //@}
  
  private:
      // -----------------------------------------------------------------------
      //  Unimplemented constructors and operators
      // -----------------------------------------------------------------------
      XSValueContext(const XSValueContext&);
      XSValueContext & operator=(const XSValueContext &);
  
      // -----------------------------------------------------------------------
      //  data members
      // -----------------------------------------------------------------------
      XMLVersion    fVersion;
      bool          fToValidate;
      Status        fStatus;
  
      friend class XSValue;
  };
  
  inline
  XSValueContext::XMLVersion  
  XSValueContext::getVersion() const
  {
      return fVersion;
  }
      
  inline
  bool
  XSValueContext::getValidation() const
  {
      return fToValidate;
  }
  
  inline
  XSValueContext::Status
  XSValueContext::getStatus() const
  {
      return fStatus;
  }
  
  inline
  void 
  XSValueContext::setVersion(XSValueContext::XMLVersion newVersion)
  {
      fVersion = newVersion;
  }
  
  inline
  void
  XSValueContext::setValidation(bool toValidate)
  {
      fToValidate = toValidate;
  }
  
  
  class RegularExpression;
  
  class XMLPARSER_EXPORT XSValue : public XMemory
  {
  public:
  
      enum DataType {
                dt_string               = 0,
                dt_boolean              = 1,
                dt_decimal              = 2,
                dt_float                = 3,
                dt_double               = 4,
                dt_duration             = 5,
                dt_dateTime             = 6,
                dt_time                 = 7,
                dt_date                 = 8,
                dt_gYearMonth           = 9,
                dt_gYear                = 10,
                dt_gMonthDay            = 11,
                dt_gDay                 = 12,
                dt_gMonth               = 13,
                dt_hexBinary            = 14,
                dt_base64Binary         = 15,
                dt_anyURI               = 16,
                dt_QName                = 17,
                dt_NOTATION             = 18,
                dt_normalizedString     = 19,
                dt_token                = 20,
                dt_language             = 21,
                dt_NMTOKEN              = 22,
                dt_NMTOKENS             = 23,
                dt_Name                 = 24,
                dt_NCName               = 25,
                dt_ID                   = 26,
                dt_IDREF                = 27,
                dt_IDREFS               = 28,
                dt_ENTITY               = 29,
                dt_ENTITIES             = 30,
                dt_integer              = 31,
                dt_nonPositiveInteger   = 32,
                dt_negativeInteger      = 33,
                dt_long                 = 34,
                dt_int                  = 35,
                dt_short                = 36,
                dt_byte                 = 37,
                dt_nonNegativeInteger   = 38,
                dt_unsignedLong         = 39,
                dt_unsignedInt          = 40,
                dt_unsignedShort        = 41,
                dt_unsignedByte         = 42,
                dt_positiveInteger      = 43,
                dt_MAXCOUNT             = 44
      };
  
      enum DataGroup {
              dg_numerics,
              dg_datetimes,
              dg_strings
      };
  
      //  Constructors and Destructor
      // -----------------------------------------------------------------------
      /** @name Destructor */
      //@{
      ~XSValue();
      //@}
  
      //---------------------------------
      /** @name Externalization methods */
      //@{
  
      static
      bool     validate
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager = XMLPlatformUtils::fgMemoryManager
               );
  
      static
      XMLCh*   getCanonicalRepresentation
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager    = XMLPlatformUtils::fgMemoryManager
               );
  
      static
      XSValue* getActualValue
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager = XMLPlatformUtils::fgMemoryManager
               );
  
      //@}
  
      //----------------------------------
      /** public data */
  
      union {
                       bool      f_bool;
                       char      f_char;                    
              unsigned char      f_uchar;
                       short     f_short;
              unsigned short     f_ushort;
                       int       f_int;
              unsigned int       f_uint;
                       long      f_long;
              unsigned long      f_ulong;
                       float     f_float;
                       double    f_double;
                       XMLCh*    f_strVal;
  
              struct decimal {
                              int              f_sign;
                              unsigned int     f_scale;  
                              unsigned long    f_integral;
                              unsigned long    f_fraction;
              } f_decimal;
  
              struct datetime {
                              int       f_year;
                              int       f_month;
                              int       f_day;
                              int       f_hour;
                              int       f_min;
                              int       f_second;
                              int       f_milisec;
                              int       f_utc;
                              int       f_tz_hh;
                              int       f_tz_mm;
              } f_datetime;
  
      } fData;
  
      static
      void XSValue::reinitMutex();
  
      static
      void XSValue::reinitRegEx();
  
  private:
  
      typedef union
      {
                  long  f_long;
         unsigned long  f_ulong;
      } t_value;
  
      /** @name Constructors */
      //@{
      /**
        * The default constructor 
        *
        */
      XSValue(MemoryManager*  const manager);
  
      //@};
  
      // -----------------------------------------------------------------------
      //  Unimplemented constructors and operators
      // -----------------------------------------------------------------------
      XSValue(const XSValue&);
      XSValue & operator=(const XSValue &);
  
      //---------------------------------
      /** @name Helpers */
  
      //@{
  
      static const XSValue::DataGroup inGroup[];
  
      //@}
  
      static
      bool     validateNumerics
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      bool     validateDateTimes
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      bool     validateStrings
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XMLCh*   getCanRepNumerics
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XMLCh*   getCanRepDateTimes
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XMLCh*   getCanRepStrings
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XSValue*  getActValNumerics
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XSValue*  getActValDateTimes
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      XSValue*  getActValStrings
               (
                  const XMLCh*          const content    
                ,       DataType              datatype
                ,       XSValueContext&       context
                ,       MemoryManager*  const manager
               );
  
      static
      bool      getActualValue
                (
                   const XMLCh*         const content
                 ,       XSValueContext&      context
                 ,       int                  ct
                 ,       t_value&             retVal               
                 ,       int                  base
                 ,       MemoryManager* const manager
                 );
  
  
      static
      RegularExpression*     getRegex();
  
      // -----------------------------------------------------------------------
      //  data members
      // -----------------------------------------------------------------------
      MemoryManager*      fMemoryManager;    
  };
  
  
  XERCES_CPP_NAMESPACE_END
  
  #endif
  
  
  
  1.1                  xml-xerces/c/src/xercesc/framework/psvi/XSValue.cpp
  
  Index: XSValue.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2004 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 "Xerces" 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 apache\@apache.org.
   *
   * 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/>.
   */
  
  /*
   * $Log $
   * $Id $
   */
  
  #include <limits.h>
  #include <errno.h>
  
  #include <xercesc/framework/psvi/XSValue.hpp>
  
  #include <xercesc/util/XMLString.hpp>
  #include <xercesc/util/XMLStringTokenizer.hpp>
  
  #include <xercesc/util/XMLBigDecimal.hpp>
  #include <xercesc/util/XMLBigInteger.hpp>
  #include <xercesc/util/XMLFloat.hpp>
  #include <xercesc/util/XMLDouble.hpp>
  #include <xercesc/util/XMLDateTime.hpp>
  #include <xercesc/util/HexBin.hpp>
  #include <xercesc/util/Base64.hpp>
  #include <xercesc/util/XMLUri.hpp>
  #include <xercesc/util/XMLChar.hpp>
  #include <xercesc/util/Janitor.hpp>
  #include <xercesc/util/XMLRegisterCleanup.hpp>
  #include <xercesc/util/regx/RegularExpression.hpp>
  #include <xercesc/validators/schema/SchemaSymbols.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  /*** issues
   *
   *   1. For float, double, datetime family, the validation is almost similar to getActualValue
   *  
   *
   *   DataType                   DataGroup
   *                             num  dtm  str             validation           canonical      actual-value
   *   ======================================================================================================
   *    dt_string                          str              [2] Char              NA             content
   *    dt_boolean                         str           {true, false, 1, 0}   {true, false}    bool
   *    dt_decimal               num                         lexical only         yes            double
   *    dt_float                 num                         lexical/value        yes            double
   *    dt_double                num                         lexical/value        yes            double
   *    ---------------------------------------------------------------------------------------------------------
   * 5  dt_duration                   dtm                    yes                  NA             struct datetime
   *    dt_dateTime                   dtm                    yes                  yes            struct datetime
   *    dt_time                       dtm                    yes                  yes            struct datetime
   *    dt_date                       dtm                    yes                  NA             struct datetime
   *    dt_gYearMonth                 dtm                    yes                  NA             struct datetime
   *    ---------------------------------------------------------------------------------------------------------
   * 10 dt_gYear                      dtm                    yes                  NA             struct datetime
   *    dt_gMonthDay                  dtm                    yes                  NA             struct datetime
   *    dt_gDay                       dtm                    yes                  NA             struct datetime
   *    dt_gMonth                     dtm                    yes                  NA             struct datetime         
   *    dt_hexBinary                        str              decoding            ([a-f])         unsigned long ?
   *    ---------------------------------------------------------------------------------------------------------
   * 15 dt_base64Binary                     str              decoding             NA (errata?)   unsigned long ?
   *    dt_anyURI                           str              yes                  NA             content
   *    dt_QName                            str              a:b , [6]QName       NA             content
   *    dt_NOTATION                         str              [6]QName             NA             content
   *    dt_normalizedString                 str              no #xD #xA #x9       NA             content
   *    ---------------------------------------------------------------------------------------------------------
   * 20 dt_token                            str              no #xD #xA #x9 traling   NA         content
   *    dt_language                         str              language id          NA             content
   *    dt_NMTOKEN                          str              [7] Nmtoken          NA             content
   *    dt_NMTOKENS                         str              [8] Nmtokens         NA             content
   *    dt_Name                             str              [5] Name             NA             content
   *    ---------------------------------------------------------------------------------------------------------
   * 25 dt_NCName                           str              [4] NCName           NA             content
   *    dt_ID                               str              [4] NCName           NA             content
   *    dt_IDREF                            str              [4] NCName           NA             content
   *    dt_IDREFS                           str              ws seped IDREF       NA             content
   *    dt_ENTITY                           str              [4] NCName           NA             content
   *    ---------------------------------------------------------------------------------------------------------
   * 30 dt_ENTITIES                         str              ws seped ENTITY      NA             content
   *    dt_integer               num                         lexical              yes            long
   *    dt_nonPositiveInteger    num                         lexical              yes            long
   *    dt_negativeInteger       num                         lexical              yes            long
   *    dt_long                  num                         lexical              yes            long
   *    ---------------------------------------------------------------------------------------------------------
   * 35 dt_int                   num                         lexical              yes            int
   *    dt_short                 num                         lexical              yes            short
   *    dt_byte                  num                         lexical              yes            char
   *    dt_nonNegativeInteger    num                         lexical              yes            unsigned long
   *    dt_unsignedLong          num                         lexical              yes            unsigned long
   *    ---------------------------------------------------------------------------------------------------------
   * 40 dt_unsignedInt           num                         lexical              yes            unsigned int
   *    dt_unsignedShort         num                         lexical              yes            unsigned short
   *    dt_unsignedByte          num                         lexical              yes            unsigned char
   *    dt_positiveInteger       num                         lexical              yes            unsigned long
   *
   ***/
  
  const XSValue::DataGroup XSValue::inGroup[XSValue::dt_MAXCOUNT] = 
  {
      dg_strings,   dg_strings,   dg_numerics,  dg_numerics,  dg_numerics, 
      dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes,
      dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_strings, 
      dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,        
      dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings, 
      dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,        
      dg_strings,   dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics, 
      dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,         
      dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics
  };
  
  // ---------------------------------------------------------------------------
  //  Local static functions
  // ---------------------------------------------------------------------------
  static XMLMutex* sXSValueMutext = 0;
  static XMLRegisterCleanup XSValueMutexCleanup;
  
  static RegularExpression* sXSValueRegEx = 0;
  static XMLRegisterCleanup XSValueRegExCleanup;
  
  static XMLMutex& gXSValueMutex()
  {
      if (!sXSValueMutext)
      {
          XMLMutexLock lockInit(XMLPlatformUtils::fgAtomicMutex);
  
          if (!sXSValueMutext)
          {
              sXSValueMutext = new XMLMutex;
              XSValueRegExCleanup.registerCleanup(XSValue::reinitMutex);
          }
      }
  
      return *sXSValueMutext;
  }
  
  static RegularExpression& getRegEx()
  {
      if (!sXSValueRegEx)
      {
  	    // Lock the mutex
  	    XMLMutexLock lockInit(&gXSValueMutex());
  
          if (!sXSValueRegEx)
  		{
              try {
                  sXSValueRegEx = new (XMLPlatformUtils::fgMemoryManager) 
                           RegularExpression(
                                              XMLUni::fgLangPattern
                                            , SchemaSymbols::fgRegEx_XOption
                                            , XMLPlatformUtils::fgMemoryManager
                                            );
              }
              catch (...)
              {
  			    XMLPlatformUtils::panic(PanicHandler::Panic_CanCreateRegEx);
              }
  
              XSValueRegExCleanup.registerCleanup(XSValue::reinitRegEx);
          }
      }
  
      return *sXSValueRegEx;
  }
  
  // ---------------------------------------------------------------------------
  //  Local Data
  // ---------------------------------------------------------------------------
            
  static const XMLCh Separator_20[] = {chSpace, chNull};
  static const XMLCh Separator_ws[] = {chSpace, chLF, chCR, chHTab, chNull};
  
  static const int convert_2_long  = 1;
  static const int convert_2_ulong = 2;
  static const int base_decimal    = 10;
  
  // ---------------------------------------------------------------------------
  //  XSValue: Constructors and Destructor
  // ---------------------------------------------------------------------------
  XSValue::XSValue(MemoryManager*  const manager)
  :fMemoryManager(manager)
  {
      fData.f_strVal = 0;
  }
  
  XSValue::~XSValue()
  {
      if (fData.f_strVal)
          fMemoryManager->deallocate(fData.f_strVal);
  }
    
  // ---------------------------------------------------------------------------
  //  XSValue: Public Interface
  //
  //    No exception is thrown from these methods
  //
  // ---------------------------------------------------------------------------
  bool XSValue::validate(const XMLCh*         const content    
                       ,       DataType             datatype
                       ,       XSValueContext&      context
                       ,       MemoryManager* const manager)
  {
  
      if (!content || !*content)
          return false;
  
      switch (inGroup[datatype])
      {
      case XSValue::dg_numerics :
          return validateNumerics(content, datatype, context, manager);
          break;
      case XSValue::dg_datetimes:
          return validateDateTimes(content, datatype, context, manager);
          break;
      case XSValue::dg_strings:
          return validateStrings(content, datatype, context, manager);
          break;
      default:
          context.fStatus = XSValueContext::st_UnknownType;
          return false;
          break;
      }
   
  }
  
  XMLCh* 
  XSValue::getCanonicalRepresentation(const XMLCh*         const content    
                                    ,       DataType             datatype
                                    ,       XSValueContext&      context
                                    ,       MemoryManager* const manager)
  {
   
      if (!content || !*content)
          return 0;
      
      switch (inGroup[datatype])
      {
      case XSValue::dg_numerics :
          return getCanRepNumerics(content, datatype, context, manager);
          break;
      case XSValue::dg_datetimes:
          return getCanRepDateTimes(content, datatype, context, manager);
          break;
      case XSValue::dg_strings:
          return getCanRepStrings(content, datatype, context, manager);
          break;
      default:
          context.fStatus = XSValueContext::st_UnknownType;
          return 0;
          break;
      }
  
  }
  
  XSValue* XSValue::getActualValue(const XMLCh*         const content    
                                 ,       DataType             datatype
                                 ,       XSValueContext&      context
                                 ,       MemoryManager* const manager)
  {
  
      if (!content || !*content)
          return 0;
  
      switch (inGroup[datatype])
      {
      case XSValue::dg_numerics :
          return getActValNumerics(content, datatype, context, manager);
          break;
      case XSValue::dg_datetimes:
          return getActValDateTimes(content, datatype, context, manager);
          break;
      case XSValue::dg_strings:
          return getActValStrings(content, datatype, context, manager);
          break;
      default:
          context.fStatus = XSValueContext::st_UnknownType;
          return 0;
          break;
      }
      
  }
  
  // ---------------------------------------------------------------------------
  //  XSValue: Helpers
  // --------------------------------------------------------------------------- 
  
  /***
   *
   *  Boundary checking is done against Schema Type's lexcial space
   ***/
  bool 
  XSValue::validateNumerics(const XMLCh*         const content    
                          ,       DataType             datatype
                          ,       XSValueContext&      context
                          ,       MemoryManager* const manager)
  {
  
      try {
  
          if (datatype == XSValue::dt_decimal)
          {
              XMLBigDecimal::parseDecimal(content, manager); 
              //error: no
          }
          else if (datatype == XSValue::dt_float)
          {
              //XMLFloat takes care of 0, -0, -INF, INF and NaN
              //XMLFloat::checkBoundary() handles error and outofbound issues
              XMLFloat data(content, manager);
              if (data.isDataConverted())
              {
                  context.fStatus = XSValueContext::st_UnRepresentable;
                  return false;
              }
          }
          else if (datatype == XSValue::dt_double)
          {
              //XMLDouble takes care of 0, -0, -INF, INF and NaN
              //XMLDouble::checkBoundary() handles error and outofbound issues
              XMLDouble  data(content, manager);
              if (data.isDataConverted())
              {
                  context.fStatus = XSValueContext::st_UnRepresentable;
                  return false;
              }
          }
          /***
           *   For all potentially unrepresentable types
           *   
           *   For dt_long, dt_unsignedLong, doing lexical space
           *   checking ensures consistent behaviour on 32/64 boxes
           *
           ***/
          else if (datatype == XSValue::dt_integer            ||
                   datatype == XSValue::dt_negativeInteger    ||
                   datatype == XSValue::dt_nonPositiveInteger ||
                   datatype == XSValue::dt_nonNegativeInteger ||
                   datatype == XSValue::dt_positiveInteger    ||
                   datatype == XSValue::dt_long               ||
                   datatype == XSValue::dt_unsignedLong        )
          {
              XMLCh* compareData = (XMLCh*) manager->allocate(XMLString::stringLen(content) * sizeof(XMLCh));
              ArrayJanitor<XMLCh> janName(compareData);
              int    signValue = 0;
              XMLBigInteger::parseBigInteger(content, compareData, signValue,  manager);
  
              switch (datatype)
              { 
              case XSValue::dt_integer:
                  //error: no
                  break;
              case XSValue::dt_negativeInteger:
                  // error: > -1
                  {
                      if  (XMLBigInteger::compareValues(compareData
                                                      , signValue
                                                      , &(XMLUni::fgNegOne[1])
                                                      , -1
                                                      , manager) 
                                                      == XMLNumber::GREATER_THAN)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_nonPositiveInteger:
                  // error: > 0
                  {
                      if (XMLBigInteger::compareValues(compareData
                                                     , signValue
                                                     , XMLUni::fgValueZero
                                                     , 0
                                                     , manager) 
                                                     == XMLNumber::GREATER_THAN)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_nonNegativeInteger:
                  // error: < 0
                  {
                      if (XMLBigInteger::compareValues(compareData
                                                     , signValue
                                                     , XMLUni::fgValueZero
                                                     , 0
                                                     , manager) 
                                                     == XMLNumber::LESS_THAN)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_positiveInteger:
                  // error: < 1
                  {
                      if (XMLBigInteger::compareValues(compareData
                                                     , signValue
                                                     , XMLUni::fgValueOne
                                                     , 1
                                                     , manager) 
                                                     == XMLNumber::LESS_THAN)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_long:
                  // error: < -9223372036854775808 || > 9223372036854775807
                  {
                      if ((XMLBigInteger::compareValues(compareData
                                                      , signValue
                                                      , &(XMLUni::fgLongMinInc[1])
                                                      , -1
                                                      , manager) 
                                                      == XMLNumber::LESS_THAN) ||
                          (XMLBigInteger::compareValues(compareData
                                                      , signValue
                                                      , XMLUni::fgLongMaxInc
                                                      , 1
                                                      , manager) 
                                                      == XMLNumber::GREATER_THAN))
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_unsignedLong:
                  // error: > 18446744073709551615
                  {
                      if (XMLBigInteger::compareValues(compareData
                                                     , signValue
                                                     , XMLUni::fgULongMaxInc
                                                     , 1
                                                     , manager) 
                                                     == XMLNumber::GREATER_THAN)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              default:
                  return false;
                  break;
              }
          }
          /***
           *   For all singed integer types
           ***/
          else if (datatype == XSValue::dt_int   ||
                   datatype == XSValue::dt_short ||
                   datatype == XSValue::dt_byte   )
          {
              t_value   actVal;
  
              if ( !getActualValue( 
                                    content
                                  , context
                                  , convert_2_long
                                  , actVal
                                  , base_decimal
                                  , manager
                                   )
                  )
                  return false;
  
              switch (datatype)
              { 
              case XSValue::dt_int:
                  // error: < INT_MIN || > INT_MAX
                  // strtol() won't overflow for INT_MIN-1 or INT_MAX+1 on 64 box
                  {
                      if ((actVal.f_long < INT_MIN) || 
                          (actVal.f_long > INT_MAX)  )
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_short:
                  // error: < SHRT_MIN || > SHRT_MAX
                  {
                      if ((actVal.f_long < SHRT_MIN) || 
                          (actVal.f_long > SHRT_MAX)  )
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              case XSValue::dt_byte:
                  // error: < CHAR_MIN || > CHAR_MAX
                  {
                      if ((actVal.f_long < CHAR_MIN) || 
                          (actVal.f_long > CHAR_MAX)  )
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return false;
                      }
                  }
                  break;
              default:
                  return false;
                  break;
              } 
          }
          /***
           *   For all unsinged integer types
           ***/
          else
          {
              t_value   actVal;
  
              if ( !getActualValue( 
                                    content
                                  , context
                                  , convert_2_ulong
                                  , actVal
                                  , base_decimal
                                  , manager
                                   )
                  )
                  return false;
  
              switch (datatype)
              { 
              case XSValue::dt_unsignedInt:     
                  // error: > UINT_MAX
                  // strtol() won't overflow for UINT_MAX+1 on 64 box
                  if (actVal.f_long > UINT_MAX) 
                  {
                      context.fStatus = XSValueContext::st_InvalidRange;
                      return false;
                  }
                  break;
              case XSValue::dt_unsignedShort:
                  // error: > USHRT_MAX
                  if (actVal.f_ulong > USHRT_MAX) 
                  {
                      context.fStatus = XSValueContext::st_InvalidRange;
                      return false;
                  }
                  break;
              case XSValue::dt_unsignedByte:   
                  // error: > UCHAR_MAX
                  if (actVal.f_ulong > UCHAR_MAX) 
                  {
                      context.fStatus = XSValueContext::st_InvalidRange;
                      return false;
                  }
                  break;
              default:
                  return false;
                  break;
              } 
          }
  
          return true;  //both valid chars and within boundary
      }
  
      catch (...)
      {
          //getActValue()/getCanonical() need to know the failure details
          //if validation is required
          context.fStatus = XSValueContext::st_InvalidChar; 
          return false; 
      }
  
  }
  
  bool XSValue::validateDateTimes(const XMLCh*         const content    
                                ,       DataType             datatype
                                ,       XSValueContext&      context
                                ,       MemoryManager* const manager)
  {
  
      try
      {
          XMLDateTime coreDate = XMLDateTime(content, manager);
  
          switch (datatype)
          { 
          case XSValue::dt_duration:
              coreDate.parseDuration();
              break;
          case XSValue::dt_dateTime:
              coreDate.parseDateTime();
              break;
          case XSValue::dt_time:
              coreDate.parseTime();
              break;
          case XSValue::dt_date:
              coreDate.parseDate();
              break;
          case XSValue::dt_gYearMonth:
              coreDate.parseYearMonth();
              break;
          case XSValue::dt_gYear:
              coreDate.parseYear();
              break;
          case XSValue::dt_gMonthDay:
              coreDate.parseMonthDay();
              break;
          case XSValue::dt_gDay:
              coreDate.parseDay();
              break;
          case XSValue::dt_gMonth:
              coreDate.parseMonth();
              break;
          default:
              return false;
              break;
          }
  
          return true; //parsing succeed
      }
  
      catch (...)
      {
          //getActValue()/getCanonical() need to know the failure details
          //if validation is required
          context.fStatus = XSValueContext::st_Invalid;
          return false; 
      }      
  
  }
  
  bool XSValue::validateStrings(const XMLCh*         const content    
                              ,       DataType             datatype
                              ,       XSValueContext&      context
                              ,       MemoryManager* const manager)
  {
  
      try
      {
          switch (datatype)
          { 
          case XSValue::dt_boolean:
              {
                  unsigned int i = 0;
                  for ( ; i < XMLUni::fgBooleanValueSpaceArraySize; i++ )
                  {
                      if ( XMLString::equals(content, XMLUni::fgBooleanValueSpace[i]))
                          break;
                  }
  
                  return (i == XMLUni::fgBooleanValueSpaceArraySize)? false : true;
              }
              break;
          case XSValue::dt_hexBinary:
              {
                  if (HexBin::getDataLength(content) == -1) 
                  {
                      context.fStatus = XSValueContext::st_Invalid;
                      return false;
                  }
              }
              break;
          case XSValue::dt_base64Binary:
              {
                  if (Base64::getDataLength(content, manager) == -1) 
                  {
                      context.fStatus = XSValueContext::st_Invalid;
                      return false;
                  }
              }
              break;
          case XSValue::dt_anyURI:
              return XMLUri::isValidURI(true, content);
              break;
          case XSValue::dt_QName:
              return (context.getVersion() == XSValueContext::ver_10) ? 
                  XMLChar1_0::isValidQName(content, XMLString::stringLen(content)) :
                  XMLChar1_1::isValidQName(content, XMLString::stringLen(content));
              break;
          case XSValue::dt_NOTATION:
              return XMLString::isValidNOTATION(content, manager);
              break;
          case XSValue::dt_string:
              {
                  XMLCh*   rawPtr = (XMLCh*) content;
  
                  if (context.getVersion() == XSValueContext::ver_10)
                  {
                      while (*rawPtr) 
                          if (!XMLChar1_0::isXMLChar(*rawPtr++)) 
                              return false;
                  }
                  else
                  {
                      while (*rawPtr) 
                          if (!XMLChar1_1::isXMLChar(*rawPtr++)) 
                              return false;
                  }
  
              }
              break;
          case XSValue::dt_normalizedString:
              {
                  XMLCh*   rawPtr = (XMLCh*) content;
  
                  if (context.getVersion() == XSValueContext::ver_10)
                  {
                      while (*rawPtr) 
                      {
                          if (!XMLChar1_0::isXMLChar(*rawPtr)) 
                              return false;
  
                          if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab )
                              return false;
  
                          rawPtr++;
                      }
                  }
                  else
                  {
                      while (*rawPtr) 
                      {
                          if (!XMLChar1_1::isXMLChar(*rawPtr)) return false;
  
                          if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab )
                              return false;
  
                          rawPtr++;
                      }
                  }
  
              }
              break;
          case XSValue::dt_token:
          case XSValue::dt_language:
              {
                  unsigned int strLen = XMLString::stringLen(content);
                  XMLCh*   rawPtr = (XMLCh*) content;
                  bool     inWS = false;
  
                  if (context.getVersion() == XSValueContext::ver_10)
                  {
  
                      // Check leading/Trailing white space
                      if (XMLChar1_0::isWhitespace(content[0])      ||
                          XMLChar1_0::isWhitespace(content[strLen])  )
                          return false;
  
                      while (*rawPtr) 
                      {
                          if (!XMLChar1_0::isXMLChar(*rawPtr)) 
                              return false;
  
                          if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab )
                              return false;
  
                          if (XMLChar1_0::isWhitespace(*rawPtr))
                          {
                              if (inWS)
                                  return false;
                              else
                                  inWS = true;
                          }
                          else
                              inWS = false;
  
                          rawPtr++;
                      }
                  }
                  else
                  {
  
                      // Check leading/Trailing white space
                      if (XMLChar1_1::isWhitespace(content[0])      ||
                          XMLChar1_1::isWhitespace(content[strLen])  )
                          return false;
  
                      while (*rawPtr) 
                      {
                          if (!XMLChar1_1::isXMLChar(*rawPtr)) 
                              return false;
  
                          if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab )
                              return false;
  
                          if (XMLChar1_1::isWhitespace(*rawPtr))
                          {
                              if (inWS)
                                  return false;
                              else
                                  inWS = true;
                          }
                          else
                              inWS = false;
  
                          rawPtr++;
                      }
                  }
  
              }
  
              return (datatype == XSValue::dt_token) ?
                  true : getRegEx().matches(content, manager);
  
              break;
          case XSValue::dt_NMTOKEN:
              return (context.getVersion() == XSValueContext::ver_10) ? 
                  XMLChar1_0::isValidNmtoken(content, XMLString::stringLen(content)) :
                  XMLChar1_1::isValidNmtoken(content, XMLString::stringLen(content));
              break;
          case XSValue::dt_NMTOKENS:
              // [8]    Nmtokens   ::=    Nmtoken (#x20 Nmtoken)*
              {
                  XMLStringTokenizer tokenizer(content, Separator_20, manager);
  
                  if (context.getVersion() ==  XSValueContext::ver_10 )
                  {
                      while (tokenizer.hasMoreTokens()) 
                      {
                          const XMLCh* token = tokenizer.nextToken();
  
                          if (!XMLChar1_0::isValidNmtoken(token, XMLString::stringLen(token)))
                              return false;
                      }
                  }
                  else
                  {
                      while (tokenizer.hasMoreTokens()) 
                      {
                          const XMLCh* token = tokenizer.nextToken();
  
                          if (!XMLChar1_1::isValidNmtoken(token, XMLString::stringLen(token)))
                              return false;
                      }
                  }
              }
              break;
          case XSValue::dt_Name:
              return (context.getVersion() == XSValueContext::ver_10) ? 
                  XMLChar1_0::isValidName(content, XMLString::stringLen(content)) :
                  XMLChar1_1::isValidName(content, XMLString::stringLen(content));
              break;
          case XSValue::dt_NCName:
          case XSValue::dt_ID:
          case XSValue::dt_IDREF:
          case XSValue::dt_ENTITY:
              return (context.getVersion() == XSValueContext::ver_10) ? 
                  XMLChar1_0::isValidNCName(content, XMLString::stringLen(content)) :
                  XMLChar1_1::isValidNCName(content, XMLString::stringLen(content));
              break;
          case XSValue::dt_ENTITIES:
          case XSValue::dt_IDREFS:
              {
                  XMLStringTokenizer tokenizer(content, Separator_ws, manager);
  
                  if (context.getVersion() ==  XSValueContext::ver_10 )
                  {
                      while (tokenizer.hasMoreTokens()) 
                      {
                          const XMLCh* token = tokenizer.nextToken();
  
                          if (!XMLChar1_0::isValidNCName(token, XMLString::stringLen(token)))
                              return false;
                      }
                  }
                  else
                  {
                      while (tokenizer.hasMoreTokens()) 
                      {
                          const XMLCh* token = tokenizer.nextToken();
  
                          if (!XMLChar1_1::isValidNCName(token, XMLString::stringLen(token)))
                              return false;
                      }
                  }
              }
              break;
          default:
              return false;
              break;
          }
  
          return true; //parsing succeed
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_Invalid;
          return false; 
      }
  
  }
  
  
  XMLCh* XSValue::getCanRepNumerics(const XMLCh*         const content    
                                  ,       DataType             datatype
                                  ,       XSValueContext&      context
                                  ,       MemoryManager* const manager)
  {
      try 
      {
  
          // All getCanonicalRepresentation does lexcial space validation only
          // (no range checking), therefore if validation is requied,
          // we need to pass the content to the validate interface for complete checking
          if (context.getValidation() && !validateNumerics(content, datatype, context, manager))
              return 0;
  
          if (datatype == XSValue::dt_decimal)
          {
              return XMLBigDecimal::getCanonicalRepresentation(content, manager);
          }
          else if (datatype == XSValue::dt_float || datatype == XSValue::dt_double  )
          {
              return XMLAbstractDoubleFloat::getCanonicalRepresentation(content, manager);
          }  
          else 
          {
              return XMLBigInteger::getCanonicalRepresentation(content, manager);
          }
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_InvalidChar;
          return 0;
      }
  
  }
  
  XMLCh* XSValue::getCanRepDateTimes(const XMLCh*         const content    
                                   ,       DataType             datatype
                                   ,       XSValueContext&      context
                                   ,       MemoryManager* const manager)
  {
  
      try
      {
  
          XMLDateTime coreDate = XMLDateTime(content, manager);
  
          switch (datatype)
          { 
          case XSValue::dt_dateTime:
              //we need this parsing
              coreDate.parseDateTime();
              return coreDate.getDateTimeCanonicalRepresentation(manager);
              break;
          case XSValue::dt_time:
              // we need this parsing
              coreDate.parseTime(); 
              return coreDate.getTimeCanonicalRepresentation(manager);
              break;
          case XSValue::dt_duration:
          case XSValue::dt_date:
          case XSValue::dt_gYearMonth:
          case XSValue::dt_gYear:
          case XSValue::dt_gMonthDay:
          case XSValue::dt_gDay:
          case XSValue::dt_gMonth:
              {
                  if (context.getValidation() && !validateDateTimes(content, datatype, context, manager))
                      context.fStatus = XSValueContext::st_Invalid;
                  else
                      context.fStatus = XSValueContext::st_NoCanRep;
  
                  return 0;
              }
              break;
          default:
              return 0;
              break;
          }
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_Invalid;
          return 0;
      }
  
  }
  
  XMLCh* XSValue::getCanRepStrings(const XMLCh*         const content    
                                 ,       DataType             datatype
                                 ,       XSValueContext&      context
                                 ,       MemoryManager* const manager)
  {
      try
      {
          switch (datatype)
          { 
          case XSValue::dt_boolean:
              {
                  //always validate before getting canRep
                  if (XMLString::equals(content, XMLUni::fgBooleanValueSpace[0]) ||
                      XMLString::equals(content, XMLUni::fgBooleanValueSpace[2])  ) 
                  {
                      return XMLString::replicate(XMLUni::fgBooleanValueSpace[0], manager);
                  }
                  else if (XMLString::equals(content, XMLUni::fgBooleanValueSpace[1]) ||
                           XMLString::equals(content, XMLUni::fgBooleanValueSpace[3])  ) 
                  {
                      return XMLString::replicate(XMLUni::fgBooleanValueSpace[1], manager);
                  }
                  else
                  {
                      context.fStatus = XSValueContext::st_Invalid;
                      return 0;
                  }
              }
              break;
          case XSValue::dt_hexBinary: 
              //HexBin::getCanonicalRepresentation does validation automatically
              return HexBin::getCanonicalRepresentation(content, manager);
              break;
          case XSValue::dt_base64Binary:
              //Base64::getCanonicalRepresentation does validation automatically
              return Base64::getCanonicalRepresentation(content, manager);
              break;
          case XSValue::dt_anyURI:
          case XSValue::dt_QName:
          case XSValue::dt_NOTATION:
          case XSValue::dt_string:
          case XSValue::dt_normalizedString:
          case XSValue::dt_token:
          case XSValue::dt_language:
          case XSValue::dt_NMTOKEN:
          case XSValue::dt_NMTOKENS:
          case XSValue::dt_Name:
          case XSValue::dt_NCName:
          case XSValue::dt_ID:
          case XSValue::dt_IDREF:
          case XSValue::dt_ENTITY:
          case XSValue::dt_ENTITIES:
          case XSValue::dt_IDREFS:
              {
                  if (context.getValidation() && !validateStrings(content, datatype, context, manager))
                      context.fStatus = XSValueContext::st_Invalid;
                  else
                      context.fStatus = XSValueContext::st_NoCanRep;
  
                  return 0;
              }
              break;
          default:
              return 0;
              break;
          }
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_Invalid;
          return 0;
      }
  }
  
  XSValue*
  XSValue::getActValNumerics(const XMLCh*         const content    
                           ,       DataType             datatype
                           ,       XSValueContext&      context
                           ,       MemoryManager* const manager)
  {
  
      try {
  
          if (datatype == XSValue::dt_decimal)
          {
              XMLBigDecimal data(content, manager); 
  
              int      totalDigit = data.getTotalDigit();
              int      scale      = data.getScale();
              XMLCh*   intVal     = data.getIntVal();
  
              // get the fraction
              t_value  actValFract;
  
              if ( !getActualValue( 
                                    &(intVal[totalDigit - scale])
                                  , context
                                  , convert_2_ulong
                                  , actValFract
                                  , base_decimal
                                  , manager
                                  )
                  )
                  return 0;
  
              // get the integer
              t_value  actValInt;
              intVal[totalDigit - scale] = 0;
  
              if ( !getActualValue( 
                                    intVal
                                  , context
                                  , convert_2_ulong
                                  , actValInt
                                  , base_decimal
                                  , manager
                                  )
                  )
                  return 0;
  
              XSValue* retVal = new (manager) XSValue(manager);
  
              retVal->fData.f_decimal.f_sign     = data.getSign();
              retVal->fData.f_decimal.f_scale    = data.getScale();
              retVal->fData.f_decimal.f_fraction = actValFract.f_ulong;
              retVal->fData.f_decimal.f_integral = actValInt.f_ulong;
  
              return retVal;
          }
          else if (datatype == XSValue::dt_float)
          {
              //XMLFloat::checkBoundary() handles error and outofbound issues
              XMLFloat data(content, manager);
              XSValue* retVal = new (manager) XSValue(manager);
              retVal->fData.f_float = (float) data.getValue();
              return retVal;
          }
          else if (datatype == XSValue::dt_double)
          {
              //XMLDouble::checkBoundary() handles error and outofbound issues
              XMLDouble  data(content, manager);
              XSValue* retVal = new (manager) XSValue(manager);
              retVal->fData.f_double = data.getValue();
              return retVal;
          }
          else if (datatype == XSValue::dt_integer            ||
                   datatype == XSValue::dt_negativeInteger    ||
                   datatype == XSValue::dt_nonPositiveInteger ||
                   datatype == XSValue::dt_nonNegativeInteger ||
                   datatype == XSValue::dt_positiveInteger      )
          {
              t_value   actVal;                
  
              if ( !getActualValue( 
                                    content
                                  , context
                                  , convert_2_long
                                  , actVal
                                  , base_decimal
                                  , manager
                                  )
                  )
                  return 0;
  
              switch (datatype)
              { 
              case XSValue::dt_integer:
                  // error: no
                  {
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_negativeInteger:
                  // error: > -1
                  {
                      if (actVal.f_long > -1)
                          return 0;
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_nonPositiveInteger:
                  // error: > 0
                  {
                      if (actVal.f_long > 0)
                          return 0;
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_nonNegativeInteger:
                  // error: < 0
                  {
                      if (actVal.f_long < 0)
                          return 0;
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_positiveInteger:
                  // error: < 1
                  {
                      if (actVal.f_long < 1)
                          return 0;
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              default:
                  return 0;
                  break;
              }
          }
          else if (datatype == XSValue::dt_long  ||
                   datatype == XSValue::dt_int   ||
                   datatype == XSValue::dt_short ||
                   datatype == XSValue::dt_byte   )
          {
              t_value   actVal;                
  
              if ( !getActualValue( 
                                    content
                                  , context
                                  , convert_2_long
                                  , actVal
                                  , base_decimal
                                  , manager
                                   )
                 )
                 return 0;
  
              switch (datatype)
              { 
              case XSValue::dt_long:
                  // error : no
                  {
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_long = actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_int:
                  // error: < INT_MIN || > INT_MAX
                  // strtol() won't overflow for INT_MIN-1 or INT_MAX+1 on 64 box
                  {
                      if ((actVal.f_long < INT_MIN) || 
                          (actVal.f_long > INT_MAX)  )
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_int = (int) actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_short:
                  // error: < SHRT_MIN || > SHRT_MAX
                  {
                      if ((actVal.f_long < SHRT_MIN) || (actVal.f_long > SHRT_MAX))
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_short = (short) actVal.f_long;
                      return retVal;
                  }
                  break;
              case XSValue::dt_byte:
                  // error: < CHAR_MIN || > CHAR_MAX
                  {
                      if ((actVal.f_long < CHAR_MIN) || (actVal.f_long > CHAR_MAX))
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_char = (char) actVal.f_long;
                      return retVal;
                  }
                  break;
              default:
                  return 0;
                  break;
              } 
          }
          else
          {
  
              t_value   actVal;                
  
              if ( !getActualValue( 
                                    content
                                  , context
                                  , convert_2_ulong
                                  , actVal
                                  , base_decimal
                                  , manager
                                   )
                 )
                 return 0;
  
              switch (datatype)
              { 
              case XSValue::dt_unsignedLong:
                  // error: no
                  {
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_ulong = actVal.f_ulong;
                      return retVal;
                  }
                  break;
              case XSValue::dt_unsignedInt:     
                  // error: > UINT_MAX
                  // strtol() won't overflow for UINT_MAX+1 on 64 box
                  {
  
                      if (actVal.f_long > UINT_MAX) 
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_uint = (unsigned int) actVal.f_ulong;
                      return retVal;
                  }
                  break;
              case XSValue::dt_unsignedShort:
                  // error: > USHRT_MAX
                  {
                      if (actVal.f_ulong > USHRT_MAX)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_ushort = (unsigned short) actVal.f_ulong;
                      return retVal;
                  }
                  break;
              case XSValue::dt_unsignedByte:   
                  // error: > UCHAR_MAX
                  {
                      if (actVal.f_ulong > UCHAR_MAX)
                      {
                          context.fStatus = XSValueContext::st_InvalidRange;
                          return 0;
                      }
  
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_uchar = (unsigned char) actVal.f_ulong;
                      return retVal;
                  }
                  break;
              default:
                  return 0;
                  break;
              } 
          }
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_InvalidChar;
          return 0; 
      }
  }
  
  XSValue*  
  XSValue::getActValDateTimes(const XMLCh*         const content    
                            ,       DataType             datatype
                            ,       XSValueContext&      context
                            ,       MemoryManager* const manager)
  {
      try
      {
          //Need not check if validation is requested since
          //parsing functions below does the validation automatically
          XMLDateTime coreDate = XMLDateTime(content, manager);
  
          switch (datatype)
          { 
          case XSValue::dt_duration:
              coreDate.parseDuration();
              break;
          case XSValue::dt_dateTime:
              coreDate.parseDateTime();
              break;
          case XSValue::dt_time:
              coreDate.parseTime();
              break;
          case XSValue::dt_date:
              coreDate.parseDate();
              break;
          case XSValue::dt_gYearMonth:
              coreDate.parseYearMonth();
              break;
          case XSValue::dt_gYear:
              coreDate.parseYear();
              break;
          case XSValue::dt_gMonthDay:
              coreDate.parseMonthDay();
              break;
          case XSValue::dt_gDay:
              coreDate.parseDay();
              break;
          case XSValue::dt_gMonth:
              coreDate.parseMonth();
              break;
          default:
              return 0;
              break;
          }
  
          XSValue* retVal = new (manager) XSValue(manager);
  
          retVal->fData.f_datetime.f_year    = coreDate.fValue[XMLDateTime::CentYear];
          retVal->fData.f_datetime.f_month   = coreDate.fValue[XMLDateTime::Month];
          retVal->fData.f_datetime.f_day     = coreDate.fValue[XMLDateTime::Day];
          retVal->fData.f_datetime.f_hour    = coreDate.fValue[XMLDateTime::Hour];
          retVal->fData.f_datetime.f_min     = coreDate.fValue[XMLDateTime::Minute];
          retVal->fData.f_datetime.f_second  = coreDate.fValue[XMLDateTime::Second];
          retVal->fData.f_datetime.f_milisec = coreDate.fValue[XMLDateTime::MiliSecond];
          retVal->fData.f_datetime.f_utc     = coreDate.fValue[XMLDateTime::utc];
          retVal->fData.f_datetime.f_tz_hh   = coreDate.fTimeZone[XMLDateTime::hh];
          retVal->fData.f_datetime.f_tz_mm   = coreDate.fTimeZone[XMLDateTime::mm];
  
          return retVal;
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_Invalid;
          return 0; 
      }
  
  }
  
  XSValue*  
  XSValue::getActValStrings(const XMLCh*         const content    
                          ,       DataType             datatype
                          ,       XSValueContext&      context
                          ,       MemoryManager* const manager)
  {
      try
      {
          switch (datatype)
          { 
          case XSValue::dt_boolean:
              {
                  //do validation here more efficiently
                  if (XMLString::equals(content, XMLUni::fgBooleanValueSpace[0]) ||
                      XMLString::equals(content, XMLUni::fgBooleanValueSpace[2])  )
                  {
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_bool = true;
                      return retVal;
                  }
                  else if (XMLString::equals(content, XMLUni::fgBooleanValueSpace[1]) ||
                           XMLString::equals(content, XMLUni::fgBooleanValueSpace[3])  )
                  {
                      XSValue* retVal = new (manager) XSValue(manager);
                      retVal->fData.f_bool = false;
                      return retVal;
                  }
                  else
                  {
                      context.fStatus = XSValueContext::st_Invalid;
                      return 0;
                  }
              }
              break;
          case XSValue::dt_hexBinary:
              {
                  //todo: HexBinary::decode()
                  XSValue* retVal = new (manager) XSValue(manager);
                  return retVal;
              }       
              break;
          case XSValue::dt_base64Binary:
              {
                  unsigned int    len = 0;
                  XMLCh* decodedData = Base64::decode(content, &len, manager);
  
                  if (!decodedData)
                  {
                      context.fStatus = XSValueContext::st_Invalid;
                      return 0;
                  }
  
                  XSValue* retVal = new (manager) XSValue(manager);
                  retVal->fData.f_strVal = decodedData;
                  return retVal;
              }
              break;
          case XSValue::dt_anyURI:
          case XSValue::dt_QName:
          case XSValue::dt_NOTATION:
          case XSValue::dt_string:
          case XSValue::dt_normalizedString:
          case XSValue::dt_token:
          case XSValue::dt_language:
          case XSValue::dt_NMTOKEN:
          case XSValue::dt_NMTOKENS:
          case XSValue::dt_Name:
          case XSValue::dt_NCName:
          case XSValue::dt_ID:
          case XSValue::dt_IDREF:
          case XSValue::dt_ENTITY:
          case XSValue::dt_ENTITIES:
          case XSValue::dt_IDREFS:
              {
                  if (context.getValidation() && !validateStrings(content, datatype, context, manager))
                      context.fStatus = XSValueContext::st_Invalid;
                  else
                      context.fStatus = XSValueContext::st_NoActVal;
  
                  return 0;
              }
              break;
          default:
              return 0;
              break;
          }
      }
  
      catch (...)
      {
          context.fStatus = XSValueContext::st_Invalid;
          return 0; 
      }
  }
  
  // ---------------------------------------------------------------------------
  //  Utilities
  // ---------------------------------------------------------------------------
  bool XSValue::getActualValue(const XMLCh*         const content
                             ,       XSValueContext&      context
                             ,       int                  ct
                             ,       t_value&             retVal               
                             ,       int                  base
                             ,       MemoryManager* const manager)
  {
      char *nptr = XMLString::transcode(content, manager);
      ArrayJanitor<char> jan(nptr, manager);
      int   strLen = strlen(nptr);
      char *endptr = 0;
      errno = 0;
  
      if (ct == convert_2_long)
      {
          retVal.f_long = strtol(nptr, &endptr, base);
      }
      else if (ct == convert_2_ulong)
      {
          retVal.f_ulong = strtoul(nptr, &endptr, base);
      }
  
      // check if all chars are valid char
      if ( (endptr - nptr) != strLen)
      {
          context.fStatus = XSValueContext::st_InvalidChar;
          return false;
      }
  
      // check if overflow/underflow occurs
      if (errno == ERANGE)
      {
          context.fStatus = XSValueContext::st_UnRepresentable;
          return false;
      }
  
      return true;
  }
  
  // -----------------------------------------------------------------------
  //  Reinitialise the mutex and RegEx
  // -----------------------------------------------------------------------
  void XSValue::reinitMutex()
  {
      delete sXSValueMutext;
      sXSValueMutext = 0;
  }
  
  void XSValue::reinitRegEx()
  {
  	delete sXSValueRegEx;
  	sXSValueRegEx = 0;
  }
  
  // ---------------------------------------------------------------------------
  //  XSValueContext: Constructors and Destructor
  // ---------------------------------------------------------------------------
  XSValueContext::XSValueContext(XMLVersion   version
                              ,  bool         toValidate)
  :fVersion(version)
  ,fToValidate(toValidate)
  ,fStatus(st_Init)
  {
  }
  
  XSValueContext::~XSValueContext()
  {
  }
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org