return oldValue;
}
+QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)
+{
+ if (!oldValue) {
+ if (newValue) {
+ releaseThisandParentDOM();
+ Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
+ addNamespace(newNamespace);\r
+ return new QName(*newValue);
+ }
+ return NULL;
+ }
+
+ delete oldValue;
+ releaseThisandParentDOM();
+ if (newValue) {
+ Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
+ addNamespace(newNamespace);\r
+ return new QName(*newValue);\r
+ }
+ return NULL;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)
+{
+ if (!oldValue) {
+ if (newValue) {
+ releaseThisandParentDOM();
+ return new DateTime(*newValue);
+ }
+ return NULL;
+ }
+
+ delete oldValue;
+ releaseThisandParentDOM();
+ return newValue ? new DateTime(*newValue) : NULL;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)
+{
+ delete oldValue;
+ releaseThisandParentDOM();
+ DateTime* ret = new DateTime(newValue);
+ ret->parseDateTime();
+ return ret;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)
+{
+ delete oldValue;
+ releaseThisandParentDOM();
+ DateTime* ret = new DateTime(newValue);
+ ret->parseDateTime();
+ return ret;
+}
+
XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)
{
if (newValue && newValue->hasParent())
#define __xmltooling_abstractxmlobj_h__\r
\r
#include <xmltooling/XMLObject.h>\r
+#include <xmltooling/util/DateTime.h>\r
\r
#if defined (_MSC_VER)\r
#pragma warning( push )\r
AbstractXMLObject(const AbstractXMLObject& src);\r
\r
/**\r
- * A helper function for derived classes.\r
+ * A helper function for derived classes, for assignment of strings.\r
+ *\r
* This 'normalizes' newString, and then if it is different from oldString,\r
- * it invalidates the DOM, frees the old string, and return the new.\r
+ * it invalidates the DOM, frees the old string, and returns the new.\r
* If not different, it frees the new string and just returns the old value.\r
* \r
* @param oldValue - the current value\r
XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue);\r
\r
/**\r
+ * A helper function for derived classes, for assignment of date/time data.\r
+ *\r
+ * It invalidates the DOM, frees the old object, and returns the new.\r
+ * \r
+ * @param oldValue - the current value\r
+ * @param newValue - the new value\r
+ * \r
+ * @return the value that should be assigned\r
+ */\r
+ DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);\r
+\r
+ /**\r
+ * A helper function for derived classes, for assignment of date/time data.\r
+ *\r
+ * It invalidates the DOM, frees the old object, and returns the new.\r
+ * \r
+ * @param oldValue - the current value\r
+ * @param newValue - the epoch to assign as the new value\r
+ * \r
+ * @return the value that should be assigned\r
+ */\r
+ DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue);\r
+\r
+ /**\r
+ * A helper function for derived classes, for assignment of date/time data.\r
+ *\r
+ * It invalidates the DOM, frees the old object, and returns the new.\r
+ * \r
+ * @param oldValue - the current value\r
+ * @param newValue - the new value in string form\r
+ * \r
+ * @return the value that should be assigned\r
+ */\r
+ DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue);\r
+\r
+ /**\r
+ * A helper function for derived classes, for assignment of QName data.\r
+ *\r
+ * It invalidates the DOM, frees the old object, and returns the new.\r
+ * \r
+ * @param oldValue - the current value\r
+ * @param newValue - the new value\r
+ * \r
+ * @return the value that should be assigned\r
+ */\r
+ QName* prepareForAssignment(QName* oldValue, const QName* newValue);\r
+\r
+ /**\r
* A helper function for derived classes, for assignment of (singleton) XML objects.\r
* \r
* It is indifferent to whether either the old or the new version of the value is null. \r
signature/VerifyingContext.h
utilinclude_HEADERS = \
+ util/DateTime.h \
util/NDC.h \
util/ParserPool.h \
util/XMLConstants.h \
io/AbstractXMLObjectUnmarshaller.cpp \
signature/impl/KeyInfoImpl.cpp \
signature/impl/KeyInfoSchemaValidators.cpp \
+ util/DateTime.cpp \
util/NDC.cpp \
util/ParserPool.cpp \
util/XMLConstants.cpp \
\r
#include <map>\r
#include <string>\r
-#include <xercesc/dom/DOM.hpp>\r
\r
-using namespace xercesc;\r
+#if defined (_MSC_VER)\r
+ #pragma warning( push )\r
+ #pragma warning( disable : 4250 4251 )\r
+#endif\r
\r
namespace xmltooling {\r
\r
\r
/**\r
* Builds a new instance of a plugin of a given type, configuring it\r
- * with the supplied element, if any.\r
+ * with the supplied parameters.\r
* \r
* @param type the name of the plugin type\r
* @param p parameters to configure plugin\r
\r
};\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
#endif /* __xmltooling_plugin_h__ */\r
#define END_XMLOBJECT }
/**
- * Declares abstract get/set methods for a named XML attribute.
+ * Declares abstract get/set methods for a typed XML attribute.
*
* @param proper the proper name of the attribute
* @param upcased the upcased name of the attribute
+ * @param type the attribute's data type
*/
-#define DECL_XMLOBJECT_ATTRIB(proper,upcased) \
+#define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
public: \
XMLTOOLING_DOXYGEN(proper attribute name) \
static const XMLCh upcased##_ATTRIB_NAME[]; \
XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
- virtual const XMLCh* get##proper() const=0; \
+ virtual const type* get##proper() const=0; \
XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
- virtual void set##proper(const XMLCh* proper)=0
+ virtual void set##proper(const type* proper)=0
/**
- * Implements get/set methods and a private member for a named XML attribute.
+ * Declares abstract get/set methods for a string XML attribute.
*
* @param proper the proper name of the attribute
+ * @param upcased the upcased name of the attribute
*/
-#define IMPL_XMLOBJECT_ATTRIB(proper) \
- private: \
- XMLCh* m_##proper; \
+#define DECL_STRING_ATTRIB(proper,upcased) \
+ DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
+
+/**
+ * Declares abstract get/set methods for a string XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ * @param upcased the upcased name of the attribute
+ */
+#define DECL_DATETIME_ATTRIB(proper,upcased) \
+ DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
+ XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
+ virtual void set##proper(time_t proper)=0; \
+ XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
+ virtual void set##proper(const XMLCh* proper)=0
+
+/**
+ * Declares abstract get/set methods for an integer XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ * @param upcased the upcased name of the attribute
+ */
+#define DECL_INTEGER_ATTRIB(proper,upcased) \
+ public: \
+ XMLTOOLING_DOXYGEN(proper attribute name) \
+ static const XMLCh upcased##_ATTRIB_NAME[]; \
+ XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
+ virtual int get##proper() const=0; \
+ XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
+ virtual void set##proper(int proper)=0
+
+/**
+ * Implements get/set methods and a private member for a typed XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ * @param type the attribute's data type
+ */
+#define IMPL_XMLOBJECT_ATTRIB(proper,type) \
+ protected: \
+ type* m_##proper; \
public: \
- const XMLCh* get##proper() const { \
+ const type* get##proper() const { \
return m_##proper; \
} \
- void set##proper(const XMLCh* proper) { \
+ void set##proper(const type* proper) { \
m_##proper = prepareForAssignment(m_##proper,proper); \
}
/**
+ * Implements get/set methods and a private member for a string XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ */
+#define IMPL_STRING_ATTRIB(proper) \
+ IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
+
+/**
+ * Implements get/set methods and a private member for a DateTime XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ */
+#define IMPL_DATETIME_ATTRIB(proper) \
+ IMPL_XMLOBJECT_ATTRIB(proper,xmltooling::DateTime); \
+ void set##proper(time_t proper) { \
+ m_##proper = prepareForAssignment(m_##proper,proper); \
+ } \
+ void set##proper(const XMLCh* proper) { \
+ m_##proper = prepareForAssignment(m_##proper,proper); \
+ }
+
+/**
+ * Implements get/set methods and a private member for an integer XML attribute.
+ *
+ * @param proper the proper name of the attribute
+ */
+#define IMPL_INTEGER_ATTRIB(proper) \
+ protected: \
+ int m_##proper; \
+ public: \
+ int get##proper() const { \
+ return m_##proper; \
+ } \
+ void set##proper(int proper) { \
+ if (m_##proper != proper) { \
+ releaseThisandParentDOM(); \
+ m_##proper = proper; \
+ } \
+ }
+
+/**
+ * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
+ *
+ * @param proper the proper name of the child type
+ * @param ns the C++ namespace for the type
+ */
+#define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
+ public: \
+ XMLTOOLING_DOXYGEN(Returns the proper child.) \
+ virtual ns::proper* get##proper() const=0; \
+ XMLTOOLING_DOXYGEN(Sets the proper child.) \
+ virtual void set##proper(ns::proper* child)=0
+
+/**
* Declares abstract get/set methods for a typed XML child object.
*
* @param proper the proper name of the child type
*/
-#define DECL_XMLOBJECT_CHILD(proper) \
+#define DECL_TYPED_CHILD(proper) \
public: \
XMLTOOLING_DOXYGEN(Returns the proper child.) \
virtual proper* get##proper() const=0; \
virtual void set##proper(proper* child)=0
/**
+ * Declares abstract get/set methods for a generic XML child object.
+ *
+ * @param proper the proper name of the child
+ */
+#define DECL_XMLOBJECT_CHILD(proper) \
+ public: \
+ XMLTOOLING_DOXYGEN(Returns the proper child.) \
+ virtual xmltooling::XMLObject* get##proper() const=0; \
+ XMLTOOLING_DOXYGEN(Sets the proper child.) \
+ virtual void set##proper(xmltooling::XMLObject* child)=0
+
+
+/**
* Implements get/set methods and a private list iterator member for a typed XML child object.
*
* @param proper the proper name of the child type
*/
-#define IMPL_XMLOBJECT_CHILD(proper) \
- private: \
+#define IMPL_TYPED_CHILD(proper) \
+ protected: \
proper* m_##proper; \
- std::list<XMLObject*>::iterator m_pos_##proper; \
+ std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
public: \
proper* get##proper() const { \
return m_##proper; \
}
/**
+ * Implements get/set methods and a private list iterator member for a generic XML child object.
+ *
+ * @param proper the proper name of the child
+ */
+#define IMPL_XMLOBJECT_CHILD(proper) \
+ protected: \
+ xmltooling::XMLObject* m_##proper; \
+ std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
+ public: \
+ xmltooling::XMLObject* get##proper() const { \
+ return m_##proper; \
+ } \
+ void set##proper(xmltooling::XMLObject* child) { \
+ prepareForAssignment(m_##proper,child); \
+ *m_pos_##proper = m_##proper = child; \
+ }
+
+/**
* Declares abstract get/set methods for a typed XML child collection.
*
* @param proper the proper name of the child type
*/
-#define DECL_XMLOBJECT_CHILDREN(proper) \
+#define DECL_TYPED_CHILDREN(proper) \
public: \
XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
virtual VectorOf(proper) get##proper##s()=0; \
virtual const std::vector<proper*>& get##proper##s() const=0
/**
+ * Declares abstract get/set methods for a generic XML child collection.
+ *
+ * @param proper the proper name of the child
+ */
+#define DECL_XMLOBJECT_CHILDREN(proper) \
+ public: \
+ XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
+ virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
+ XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
+ virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
+
+/**
* Implements get method and a private vector member for a typed XML child collection.
*
* @param proper the proper name of the child type
* @param fence insertion fence for new objects of the child collection in backing list
*/
-#define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
- private: \
+#define IMPL_TYPED_CHILDREN(proper,fence) \
+ protected: \
std::vector<proper*> m_##proper##s; \
public: \
VectorOf(proper) get##proper##s() { \
}
/**
- * Implements marshalling for an attribute
+ * Implements get method and a private vector member for a generic XML child collection.
+ *
+ * @param proper the proper name of the child
+ * @param fence insertion fence for new objects of the child collection in backing list
+ */
+#define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
+ protected: \
+ std::vector<xmltooling::XMLObject*> m_##proper##s; \
+ public: \
+ VectorOf(xmltooling::XMLObject) get##proper##s() { \
+ return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
+ } \
+ const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
+ return m_##proper##s; \
+ }
+
+/**
+ * Implements marshalling for a string attribute
*
* @param proper the proper name of the attribute
* @param ucase the upcased name of the attribute
* @param namespaceURI the XML namespace of the attribute
*/
-#define MARSHALL_XMLOBJECT_ATTRIB(proper,ucase,namespaceURI) \
+#define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
if(get##proper()) { \
domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
}
/**
+ * Implements marshalling for a DateTime attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
+ if(get##proper()) { \
+ domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()->getRawData()); \
+ }
+
+/**
+ * Implements marshalling for an integer attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
+ char buf##proper[64]; \
+ sprintf(buf##proper,"%d",get##proper()); \
+ auto_ptr_XMLCh wide##proper(buf##proper); \
+ domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, wide##proper.get())
+
+/**
+ * Implements marshalling for a QName attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
+ if(get##proper()) { \
+ auto_ptr_XMLCh qstr(get##proper()->toString().c_str()); \
+ domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
+ }
+
+/**
* Implements marshalling for an ID attribute
*
* @param proper the proper name of the attribute
* @param ucase the upcased name of the attribute
* @param namespaceURI the XML namespace of the attribute
*/
-#define MARSHALL_XMLOBJECT_ID_ATTRIB(proper,ucase,namespaceURI) \
+#define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
if(get##proper()) { \
domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
}
/**
- * Implements unmarshalling process branch for an attribute
+ * Implements unmarshalling process branch for a string attribute
*
* @param proper the proper name of the attribute
* @param ucase the upcased name of the attribute
* @param namespaceURI the XML namespace of the attribute
*/
-#define PROC_XMLOBJECT_ATTRIB(proper,ucase,namespaceURI) \
+#define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
set##proper(attribute->getValue()); \
return; \
* @param ucase the upcased name of the attribute
* @param namespaceURI the XML namespace of the attribute
*/
-#define PROC_XMLOBJECT_ID_ATTRIB(proper,ucase,namespaceURI) \
+#define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
set##proper(attribute->getValue()); \
static_cast<DOMElement*>(attribute->getParentNode())->setIdAttributeNode(attribute); \
}
/**
+ * Implements unmarshalling process branch for a DateTime attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
+ PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
+
+/**
+ * Implements unmarshalling process branch for a DateTime attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
+ if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
+ set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
+ return; \
+ }
+
+/**
+ * Implements unmarshalling process branch for an integer attribute
+ *
+ * @param proper the proper name of the attribute
+ * @param ucase the upcased name of the attribute
+ * @param namespaceURI the XML namespace of the attribute
+ */
+#define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
+ if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
+ set##proper(XMLString::parseInt(attribute->getValue())); \
+ return; \
+ }
+
+
+/**
* Implements unmarshalling process branch for typed child collection element
*
* @param proper the proper name of the child type
* @param namespaceURI the XML namespace of the child element
+ * @param force bypass use of hint and just cast down to check child
*/
-#define PROC_XMLOBJECT_CHILDREN(proper,namespaceURI) \
- if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
+#define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
+ if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
if (typesafe) { \
get##proper##s().push_back(typesafe); \
*
* @param proper the proper name of the child type
* @param namespaceURI the XML namespace of the child element
+ * @param force bypass use of hint and just cast down to check child
*/
-#define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
- if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
+#define PROC_TYPED_CHILD(proper,namespaceURI,force) \
+ if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
if (typesafe) { \
set##proper(typesafe); \
*/
#define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
class linkage cname##Impl \
- : public cname, \
+ : public virtual cname, \
public xmltooling::AbstractSimpleElement, \
public xmltooling::AbstractChildlessElement, \
public xmltooling::AbstractDOMCachingXMLObject, \
throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
/**
+ * Validator code that checks for one of a pair of
+ * required attributes, content, or singletons, but disallows both.
+ *
+ * @param cname the name of the XMLObject specialization
+ * @param proper1 the proper name of the first attribute, content, or singleton member
+ * @param proper2 the proper name of the second attribute, content, or singleton member
+ */
+#define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
+ if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
+ throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
+
+/**
* Validator code that checks for one of a set of three
* required attributes, content, or singletons.
*
throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
/**
+ * Validator code that checks for one of a set of three
+ * required attributes, content, or singletons but disallows more than one.
+ *
+ * @param cname the name of the XMLObject specialization
+ * @param proper1 the proper name of the first attribute, content, or singleton member
+ * @param proper2 the proper name of the second attribute, content, or singleton member
+ * @param proper3 the proper name of the third attribute, content, or singleton member
+ */
+#define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
+ int c##proper1##proper2##proper3=0; \
+ if (ptr->get##proper1()!=NULL) \
+ c##proper1##proper2##proper3++; \
+ if (ptr->get##proper2()!=NULL) \
+ c##proper1##proper2##proper3++; \
+ if (ptr->get##proper3()!=NULL) \
+ c##proper1##proper2##proper3++; \
+ if (c##proper1##proper2##proper3 != 1) \
+ throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
+
+/**
* Validator code that checks a co-constraint (if one present, the other must be)
* between a pair of attributes, content, or singletons.
*
void AbstractXMLObjectUnmarshaller::processChildElement(XMLObject* child, const DOMElement* childRoot)
{
- throw UnmarshallingException("Child elements are not permitted on this object.");
+ throw UnmarshallingException("Invalid child element: $1",params(1,child->getElementQName().toString().c_str()));
}
DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,PGPKeyPacket,Packet,XML Digital Signature version 20020212 PGPKeyPacket element);
BEGIN_XMLOBJECT(XMLTOOL_API,DSAKeyValue,xmltooling::XMLObject,XML Digital Signature version 20020212 DSAKeyValue element);
- DECL_XMLOBJECT_CHILD(P);
- DECL_XMLOBJECT_CHILD(Q);
- DECL_XMLOBJECT_CHILD(G);
- DECL_XMLOBJECT_CHILD(Y);
- DECL_XMLOBJECT_CHILD(J);
- DECL_XMLOBJECT_CHILD(Seed);
- DECL_XMLOBJECT_CHILD(PgenCounter);
+ DECL_TYPED_CHILD(P);
+ DECL_TYPED_CHILD(Q);
+ DECL_TYPED_CHILD(G);
+ DECL_TYPED_CHILD(Y);
+ DECL_TYPED_CHILD(J);
+ DECL_TYPED_CHILD(Seed);
+ DECL_TYPED_CHILD(PgenCounter);
/** DSAKeyValueType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,RSAKeyValue,xmltooling::XMLObject,XML Digital Signature version 20020212 RSAKeyValue element);
- DECL_XMLOBJECT_CHILD(Modulus);
- DECL_XMLOBJECT_CHILD(Exponent);
+ DECL_TYPED_CHILD(Modulus);
+ DECL_TYPED_CHILD(Exponent);
/** RSAKeyValueType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,KeyValue,xmltooling::SimpleElement,XML Digital Signature version 20020212 KeyValue element);
- DECL_XMLOBJECT_CHILD(DSAKeyValue);
- DECL_XMLOBJECT_CHILD(RSAKeyValue);
- DECL_XMLOBJECT_CHILD(XMLObject);
+ DECL_TYPED_CHILD(DSAKeyValue);
+ DECL_TYPED_CHILD(RSAKeyValue);
+ DECL_XMLOBJECT_CHILD(OtherKeyValue);
/** KeyValueType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,Transform,xmltooling::ElementProxy,XML Digital Signature version 20020212 Transform element);
- DECL_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM);
- DECL_XMLOBJECT_CHILDREN(XPath);
+ DECL_STRING_ATTRIB(Algorithm,ALGORITHM);
+ DECL_TYPED_CHILDREN(XPath);
/** TransformType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,Transforms,xmltooling::XMLObject,XML Digital Signature version 20020212 Transforms element);
- DECL_XMLOBJECT_CHILDREN(Transform);
+ DECL_TYPED_CHILDREN(Transform);
/** TransformsType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,RetrievalMethod,xmltooling::XMLObject,XML Digital Signature version 20020212 RetrievalMethod element);
- DECL_XMLOBJECT_ATTRIB(URI,URI);
- DECL_XMLOBJECT_ATTRIB(Type,TYPE);
- DECL_XMLOBJECT_CHILD(Transforms);
+ DECL_STRING_ATTRIB(URI,URI);
+ DECL_STRING_ATTRIB(Type,TYPE);
+ DECL_TYPED_CHILD(Transforms);
/** RetrievalMethodType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,X509IssuerSerial,xmltooling::XMLObject,XML Digital Signature version 20020212 X509IssuerSerial element);
- DECL_XMLOBJECT_CHILD(X509IssuerName);
- DECL_XMLOBJECT_CHILD(X509SerialNumber);
+ DECL_TYPED_CHILD(X509IssuerName);
+ DECL_TYPED_CHILD(X509SerialNumber);
/** X509IssuerSerialType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,X509Data,xmltooling::XMLObject,XML Digital Signature version 20020212 X509Data element);
- DECL_XMLOBJECT_CHILDREN(X509IssuerSerial);
- DECL_XMLOBJECT_CHILDREN(X509SKI);
- DECL_XMLOBJECT_CHILDREN(X509SubjectName);
- DECL_XMLOBJECT_CHILDREN(X509Certificate);
- DECL_XMLOBJECT_CHILDREN(X509CRL);
- DECL_XMLOBJECT_CHILDREN(XMLObject);
+ DECL_TYPED_CHILDREN(X509IssuerSerial);
+ DECL_TYPED_CHILDREN(X509SKI);
+ DECL_TYPED_CHILDREN(X509SubjectName);
+ DECL_TYPED_CHILDREN(X509Certificate);
+ DECL_TYPED_CHILDREN(X509CRL);
+ DECL_XMLOBJECT_CHILDREN(OtherX509Data);
/** X509DataType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,PGPData,xmltooling::XMLObject,XML Digital Signature version 20020212 PGPData element);
- DECL_XMLOBJECT_CHILD(PGPKeyID);
- DECL_XMLOBJECT_CHILD(PGPKeyPacket);
- DECL_XMLOBJECT_CHILDREN(XMLObject);
+ DECL_TYPED_CHILD(PGPKeyID);
+ DECL_TYPED_CHILD(PGPKeyPacket);
+ DECL_XMLOBJECT_CHILDREN(PGPDataExtension);
/** PGPDataType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
BEGIN_XMLOBJECT(XMLTOOL_API,KeyInfo,xmltooling::XMLObject,XML Digital Signature version 20020212 KeyInfo element);
- DECL_XMLOBJECT_ATTRIB(Id,ID);
- DECL_XMLOBJECT_CHILDREN(X509Data);
- DECL_XMLOBJECT_CHILDREN(KeyName);
- DECL_XMLOBJECT_CHILDREN(KeyValue);
- DECL_XMLOBJECT_CHILDREN(RetrievalMethod);
- DECL_XMLOBJECT_CHILDREN(MgmtData);
- DECL_XMLOBJECT_CHILDREN(PGPData);
- DECL_XMLOBJECT_CHILDREN(SPKIData);
- DECL_XMLOBJECT_CHILDREN(XMLObject);
+ DECL_STRING_ATTRIB(Id,ID);
+ DECL_TYPED_CHILDREN(X509Data);
+ DECL_TYPED_CHILDREN(KeyName);
+ DECL_TYPED_CHILDREN(KeyValue);
+ DECL_TYPED_CHILDREN(RetrievalMethod);
+ DECL_TYPED_CHILDREN(MgmtData);
+ DECL_TYPED_CHILDREN(PGPData);
+ DECL_TYPED_CHILDREN(SPKIData);
+ DECL_XMLOBJECT_CHILDREN(Other);
/** KeyInfoType local name */
static const XMLCh TYPE_NAME[];
END_XMLOBJECT;
* @throws SignatureException thrown if the verifying operation fails\r
*/\r
virtual void verify(const VerifyingContext& ctx) const=0;\r
+ \r
+ /**\r
+ * Type-safe clone operation.\r
+ * \r
+ * @return copy of object\r
+ */\r
+ virtual Signature* cloneSignature() const=0;\r
\r
protected:\r
Signature() {}\r
}\r
};\r
\r
- DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlsignature,xmltooling::XMLToolingException,Exceptions in signature processing);\r
+ DECL_XMLTOOLING_EXCEPTION(XMLSecurityException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlsignature,xmltooling::XMLToolingException,Exceptions in XML Security processing);\r
+ DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlsignature,xmlsignature::XMLSecurityException,Exceptions in signature processing);\r
\r
};\r
\r
/*
-* Copyright 2001-2006 Internet2
+ * Copyright 2001-2006 Internet2
*
-* Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
namespace xmlsignature {
- class XMLTOOL_DLLLOCAL DSAKeyValueImpl : public DSAKeyValue,
+ class XMLTOOL_DLLLOCAL DSAKeyValueImpl : public virtual DSAKeyValue,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(DSAKeyValue);
- IMPL_XMLOBJECT_CHILD(P);
- IMPL_XMLOBJECT_CHILD(Q);
- IMPL_XMLOBJECT_CHILD(G);
- IMPL_XMLOBJECT_CHILD(Y);
- IMPL_XMLOBJECT_CHILD(J);
- IMPL_XMLOBJECT_CHILD(Seed);
- IMPL_XMLOBJECT_CHILD(PgenCounter);
+ IMPL_TYPED_CHILD(P);
+ IMPL_TYPED_CHILD(Q);
+ IMPL_TYPED_CHILD(G);
+ IMPL_TYPED_CHILD(Y);
+ IMPL_TYPED_CHILD(J);
+ IMPL_TYPED_CHILD(Seed);
+ IMPL_TYPED_CHILD(PgenCounter);
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(P,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(Q,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(G,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(Y,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(J,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(Seed,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(PgenCounter,XMLConstants::XMLSIG_NS);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ PROC_TYPED_CHILD(P,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(Q,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(G,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(Y,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(J,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(Seed,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(PgenCounter,XMLConstants::XMLSIG_NS,false);
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL RSAKeyValueImpl : public RSAKeyValue,
+ class XMLTOOL_DLLLOCAL RSAKeyValueImpl : public virtual RSAKeyValue,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(RSAKeyValue);
- IMPL_XMLOBJECT_CHILD(Modulus);
- IMPL_XMLOBJECT_CHILD(Exponent);
+ IMPL_TYPED_CHILD(Modulus);
+ IMPL_TYPED_CHILD(Exponent);
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(Modulus,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(Exponent,XMLConstants::XMLSIG_NS);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ PROC_TYPED_CHILD(Modulus,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(Exponent,XMLConstants::XMLSIG_NS,false);
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL KeyValueImpl : public KeyValue,
+ class XMLTOOL_DLLLOCAL KeyValueImpl : public virtual KeyValue,
public AbstractSimpleElement,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
setDSAKeyValue(src.getDSAKeyValue()->cloneDSAKeyValue());
if (src.getRSAKeyValue())
setRSAKeyValue(src.getRSAKeyValue()->cloneRSAKeyValue());
- if (src.getXMLObject())
- setXMLObject(src.getXMLObject()->clone());
+ if (src.getOtherKeyValue())
+ setOtherKeyValue(src.getOtherKeyValue()->clone());
}
void init() {
m_DSAKeyValue=NULL;
m_RSAKeyValue=NULL;
- m_XMLObject=NULL;
+ m_OtherKeyValue=NULL;
m_children.push_back(NULL);
m_children.push_back(NULL);
m_children.push_back(NULL);
m_pos_DSAKeyValue=m_children.begin();
m_pos_RSAKeyValue=m_pos_DSAKeyValue;
++m_pos_RSAKeyValue;
- m_pos_XMLObject=m_pos_RSAKeyValue;
- ++m_pos_XMLObject;
+ m_pos_OtherKeyValue=m_pos_RSAKeyValue;
+ ++m_pos_OtherKeyValue;
}
IMPL_XMLOBJECT_CLONE(KeyValue);
- IMPL_XMLOBJECT_CHILD(DSAKeyValue);
- IMPL_XMLOBJECT_CHILD(RSAKeyValue);
- IMPL_XMLOBJECT_CHILD(XMLObject);
+ IMPL_TYPED_CHILD(DSAKeyValue);
+ IMPL_TYPED_CHILD(RSAKeyValue);
+ IMPL_XMLOBJECT_CHILD(OtherKeyValue);
IMPL_XMLOBJECT_CONTENT;
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(DSAKeyValue,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(RSAKeyValue,XMLConstants::XMLSIG_NS);
+ PROC_TYPED_CHILD(DSAKeyValue,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(RSAKeyValue,XMLConstants::XMLSIG_NS,false);
// Unknown child.
const XMLCh* nsURI=root->getNamespaceURI();
if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
- setXMLObject(childXMLObject);
+ setOtherKeyValue(childXMLObject);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL TransformImpl : public Transform,
+ class XMLTOOL_DLLLOCAL TransformImpl : public virtual Transform,
public AbstractDOMCachingXMLObject,
public AbstractElementProxy,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(Transform);
- IMPL_XMLOBJECT_ATTRIB(Algorithm);
- IMPL_XMLOBJECT_CHILDREN(XPath,m_children.end());
+ IMPL_STRING_ATTRIB(Algorithm);
+ IMPL_TYPED_CHILDREN(XPath,m_children.end());
IMPL_XMLOBJECT_CONTENT;
protected:
void marshallAttributes(DOMElement* domElement) const {
- MARSHALL_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
+ MARSHALL_STRING_ATTRIB(Algorithm,ALGORITHM,NULL);
}
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILDREN(XPath,XMLConstants::XMLSIG_NS);
+ PROC_TYPED_CHILDREN(XPath,XMLConstants::XMLSIG_NS,false);
// Unknown child.
const XMLCh* nsURI=root->getNamespaceURI();
if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
getXMLObjects().push_back(childXMLObject);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
void processAttribute(const DOMAttr* attribute) {
- PROC_XMLOBJECT_ATTRIB(Algorithm,ALGORITHM,NULL);
+ PROC_STRING_ATTRIB(Algorithm,ALGORITHM,NULL);
}
};
- class XMLTOOL_DLLLOCAL TransformsImpl : public Transforms,
+ class XMLTOOL_DLLLOCAL TransformsImpl : public virtual Transforms,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(Transforms);
- IMPL_XMLOBJECT_CHILDREN(Transform,m_children.end());
+ IMPL_TYPED_CHILDREN(Transform,m_children.end());
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILDREN(Transform,XMLConstants::XMLSIG_NS);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ PROC_TYPED_CHILDREN(Transform,XMLConstants::XMLSIG_NS,false);
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL RetrievalMethodImpl : public RetrievalMethod,
+ class XMLTOOL_DLLLOCAL RetrievalMethodImpl : public virtual RetrievalMethod,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(RetrievalMethod);
- IMPL_XMLOBJECT_ATTRIB(URI);
- IMPL_XMLOBJECT_ATTRIB(Type);
- IMPL_XMLOBJECT_CHILD(Transforms);
+ IMPL_STRING_ATTRIB(URI);
+ IMPL_STRING_ATTRIB(Type);
+ IMPL_TYPED_CHILD(Transforms);
protected:
void marshallAttributes(DOMElement* domElement) const {
- MARSHALL_XMLOBJECT_ATTRIB(URI,URI,NULL);
- MARSHALL_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
+ MARSHALL_STRING_ATTRIB(URI,URI,NULL);
+ MARSHALL_STRING_ATTRIB(Type,TYPE,NULL);
}
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(Transforms,XMLConstants::XMLSIG_NS);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ PROC_TYPED_CHILD(Transforms,XMLConstants::XMLSIG_NS,false);
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
void processAttribute(const DOMAttr* attribute) {
- PROC_XMLOBJECT_ATTRIB(URI,URI,NULL);
- PROC_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
+ PROC_STRING_ATTRIB(URI,URI,NULL);
+ PROC_STRING_ATTRIB(Type,TYPE,NULL);
}
};
- class XMLTOOL_DLLLOCAL X509IssuerSerialImpl : public X509IssuerSerial,
+ class XMLTOOL_DLLLOCAL X509IssuerSerialImpl : public virtual X509IssuerSerial,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
}
IMPL_XMLOBJECT_CLONE(X509IssuerSerial);
- IMPL_XMLOBJECT_CHILD(X509IssuerName);
- IMPL_XMLOBJECT_CHILD(X509SerialNumber);
+ IMPL_TYPED_CHILD(X509IssuerName);
+ IMPL_TYPED_CHILD(X509SerialNumber);
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(X509IssuerName,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(X509SerialNumber,XMLConstants::XMLSIG_NS);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ PROC_TYPED_CHILD(X509IssuerName,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(X509SerialNumber,XMLConstants::XMLSIG_NS,false);
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL X509DataImpl : public X509Data,
+ class XMLTOOL_DLLLOCAL X509DataImpl : public virtual X509Data,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
continue;
}
- getXMLObjects().push_back((*i)->clone());
+ getOtherX509Datas().push_back((*i)->clone());
}
}
}
IMPL_XMLOBJECT_CLONE(X509Data);
- IMPL_XMLOBJECT_CHILDREN(X509IssuerSerial,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(X509SKI,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(X509SubjectName,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(X509Certificate,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(X509CRL,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
+ IMPL_TYPED_CHILDREN(X509IssuerSerial,m_children.end());
+ IMPL_TYPED_CHILDREN(X509SKI,m_children.end());
+ IMPL_TYPED_CHILDREN(X509SubjectName,m_children.end());
+ IMPL_TYPED_CHILDREN(X509Certificate,m_children.end());
+ IMPL_TYPED_CHILDREN(X509CRL,m_children.end());
+ IMPL_XMLOBJECT_CHILDREN(OtherX509Data,m_children.end());
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILDREN(X509IssuerSerial,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(X509SKI,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(X509SubjectName,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(X509Certificate,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(X509CRL,XMLConstants::XMLSIG_NS);
+ PROC_TYPED_CHILDREN(X509IssuerSerial,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(X509SKI,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(X509SubjectName,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(X509Certificate,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(X509CRL,XMLConstants::XMLSIG_NS,false);
// Unknown child.
const XMLCh* nsURI=root->getNamespaceURI();
if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
- getXMLObjects().push_back(childXMLObject);
+ getOtherX509Datas().push_back(childXMLObject);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL SPKIDataImpl : public SPKIData,
+ class XMLTOOL_DLLLOCAL SPKIDataImpl : public virtual SPKIData,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
throw UnmarshallingException("Extension element must follow ds:SPKISexp element.");
}
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL PGPDataImpl : public PGPData,
+ class XMLTOOL_DLLLOCAL PGPDataImpl : public virtual PGPData,
public AbstractComplexElement,
public AbstractDOMCachingXMLObject,
public AbstractValidatingXMLObject,
setPGPKeyID(src.getPGPKeyID()->clonePGPKeyID());
if (src.getPGPKeyPacket())
setPGPKeyPacket(src.getPGPKeyPacket()->clonePGPKeyPacket());
- VectorOf(XMLObject) v=getXMLObjects();
- for (vector<XMLObject*>::const_iterator i=src.m_XMLObjects.begin(); i!=src.m_XMLObjects.end(); i++) {
+ VectorOf(XMLObject) v=getPGPDataExtensions();
+ for (vector<XMLObject*>::const_iterator i=src.m_PGPDataExtensions.begin(); i!=src.m_PGPDataExtensions.end(); i++) {
if (*i) {
v.push_back((*i)->clone());
}
}
IMPL_XMLOBJECT_CLONE(PGPData);
- IMPL_XMLOBJECT_CHILD(PGPKeyID);
- IMPL_XMLOBJECT_CHILD(PGPKeyPacket);
- IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
+ IMPL_TYPED_CHILD(PGPKeyID);
+ IMPL_TYPED_CHILD(PGPKeyPacket);
+ IMPL_XMLOBJECT_CHILDREN(PGPDataExtension,m_children.end());
protected:
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILD(PGPKeyID,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILD(PGPKeyPacket,XMLConstants::XMLSIG_NS);
+ PROC_TYPED_CHILD(PGPKeyID,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILD(PGPKeyPacket,XMLConstants::XMLSIG_NS,false);
// Unknown child.
const XMLCh* nsURI=root->getNamespaceURI();
if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
- getXMLObjects().push_back(childXMLObject);
+ getPGPDataExtensions().push_back(childXMLObject);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
};
- class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo,
+ class XMLTOOL_DLLLOCAL KeyInfoImpl : public virtual KeyInfo,
public AbstractComplexElement,
public AbstractSimpleElement,
public AbstractDOMCachingXMLObject,
continue;
}
- getXMLObjects().push_back((*i)->clone());
+ getOthers().push_back((*i)->clone());
}
}
}
IMPL_XMLOBJECT_CLONE(KeyInfo);
- IMPL_XMLOBJECT_ATTRIB(Id);
- IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(KeyValue,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(RetrievalMethod,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(X509Data,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(SPKIData,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(PGPData,m_children.end());
- IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
+ IMPL_STRING_ATTRIB(Id);
+ IMPL_TYPED_CHILDREN(KeyName,m_children.end());
+ IMPL_TYPED_CHILDREN(KeyValue,m_children.end());
+ IMPL_TYPED_CHILDREN(RetrievalMethod,m_children.end());
+ IMPL_TYPED_CHILDREN(X509Data,m_children.end());
+ IMPL_TYPED_CHILDREN(MgmtData,m_children.end());
+ IMPL_TYPED_CHILDREN(SPKIData,m_children.end());
+ IMPL_TYPED_CHILDREN(PGPData,m_children.end());
+ IMPL_XMLOBJECT_CHILDREN(Other,m_children.end());
IMPL_XMLOBJECT_CONTENT;
protected:
void marshallAttributes(DOMElement* domElement) const {
- MARSHALL_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
+ MARSHALL_ID_ATTRIB(Id,ID,NULL);
}
void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
- PROC_XMLOBJECT_CHILDREN(X509Data,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(RetrievalMethod,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(SPKIData,XMLConstants::XMLSIG_NS);
- PROC_XMLOBJECT_CHILDREN(PGPData,XMLConstants::XMLSIG_NS);
+ PROC_TYPED_CHILDREN(X509Data,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(KeyName,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(RetrievalMethod,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(SPKIData,XMLConstants::XMLSIG_NS,false);
+ PROC_TYPED_CHILDREN(PGPData,XMLConstants::XMLSIG_NS,false);
// Unknown child.
const XMLCh* nsURI=root->getNamespaceURI();
if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
- getXMLObjects().push_back(childXMLObject);
+ getOthers().push_back(childXMLObject);
- throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+ AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
}
void processAttribute(const DOMAttr* attribute) {
- PROC_XMLOBJECT_ID_ATTRIB(Id,ID,NULL);
+ PROC_ID_ATTRIB(Id,ID,NULL);
}
};
END_XMLOBJECTVALIDATOR;
BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,KeyValue);
- XMLOBJECTVALIDATOR_ONEOF3(KeyValue,DSAKeyValue,RSAKeyValue,XMLObject);
+ XMLOBJECTVALIDATOR_ONLYONEOF3(KeyValue,DSAKeyValue,RSAKeyValue,OtherKeyValue);
END_XMLOBJECTVALIDATOR;
BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,Transform);
const XMLCh* ns=xmlObject->getElementQName().getNamespaceURI();
if (XMLString::equals(ns,XMLConstants::XMLSIG_NS) || !ns || !*ns) {
throw ValidationException(
- "X509Data contains an illegal extension element ($1).",
+ "Object contains an illegal extension child element ($1).",
params(1,xmlObject->getElementQName().toString().c_str())
);
}
BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,X509Data);
if (!ptr->hasChildren())
throw ValidationException("X509Data must have at least one child element.");
- vector<XMLObject*> anys=ptr->getXMLObjects();
+ const vector<XMLObject*>& anys=ptr->getOtherX509Datas();
for_each(anys.begin(),anys.end(),checkWildcardNS());
END_XMLOBJECTVALIDATOR;
BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,KeyInfo);
if (!ptr->hasChildren())
throw ValidationException("KeyInfo must have at least one child element.");
- vector<XMLObject*> anys=ptr->getXMLObjects();
+ const vector<XMLObject*>& anys=ptr->getOthers();
for_each(anys.begin(),anys.end(),checkWildcardNS());
END_XMLOBJECTVALIDATOR;
\r
void releaseDOM();\r
XMLObject* clone() const;\r
+ Signature* cloneSignature() const;\r
\r
DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
\r
XMLObject* XMLSecSignatureImpl::clone() const\r
{\r
+ return cloneSignature();\r
+}\r
+\r
+Signature* XMLSecSignatureImpl::cloneSignature() const\r
+{\r
XMLSecSignatureImpl* ret=new XMLSecSignatureImpl();\r
\r
ret->m_c14n=XMLString::replicate(m_c14n);\r
--- /dev/null
+/*\r
+ * Copyright 2001-2006 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * DateTime.cpp\r
+ * \r
+ * Manipulation of XML date/time data. \r
+ */\r
+\r
+/*\r
+ * This is mostly copied from Xerces-C, but they don't seem inclined to produce a usable\r
+ * class, so I had to incorporate my own version of it for now. I can't inherit it\r
+ * since the fields I need are private.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "util/DateTime.h"\r
+\r
+#ifndef WIN32\r
+# include <errno.h>\r
+#endif\r
+\r
+#include <ctime>\r
+#include <xercesc/util/Janitor.hpp>\r
+#include <xercesc/util/NumberFormatException.hpp>\r
+\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+//\r
+// constants used to process raw data (fBuffer)\r
+//\r
+// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}['Z']\r
+// [{+|-}hh:mm']\r
+//\r
+\r
+static const XMLCh DURATION_STARTER = chLatin_P; // 'P'\r
+static const XMLCh DURATION_Y = chLatin_Y; // 'Y'\r
+static const XMLCh DURATION_M = chLatin_M; // 'M'\r
+static const XMLCh DURATION_D = chLatin_D; // 'D'\r
+static const XMLCh DURATION_H = chLatin_H; // 'H'\r
+static const XMLCh DURATION_S = chLatin_S; // 'S'\r
+\r
+static const XMLCh DATE_SEPARATOR = chDash; // '-'\r
+static const XMLCh TIME_SEPARATOR = chColon; // ':'\r
+static const XMLCh TIMEZONE_SEPARATOR = chColon; // ':'\r
+static const XMLCh DATETIME_SEPARATOR = chLatin_T; // 'T'\r
+static const XMLCh MILISECOND_SEPARATOR = chPeriod; // '.'\r
+\r
+static const XMLCh UTC_STD_CHAR = chLatin_Z; // 'Z'\r
+static const XMLCh UTC_POS_CHAR = chPlus; // '+'\r
+static const XMLCh UTC_NEG_CHAR = chDash; // '-'\r
+\r
+static const XMLCh UTC_SET[] = {UTC_STD_CHAR //"Z+-"\r
+ , UTC_POS_CHAR\r
+ , UTC_NEG_CHAR\r
+ , chNull};\r
+\r
+static const int YMD_MIN_SIZE = 10; // CCYY-MM-DD\r
+static const int YMONTH_MIN_SIZE = 7; // CCYY_MM\r
+static const int TIME_MIN_SIZE = 8; // hh:mm:ss\r
+static const int TIMEZONE_SIZE = 5; // hh:mm\r
+static const int DAY_SIZE = 5; // ---DD\r
+//static const int MONTH_SIZE = 6; // --MM--\r
+static const int MONTHDAY_SIZE = 7; // --MM-DD\r
+static const int NOT_FOUND = -1;\r
+\r
+//define constants to be used in assigning default values for\r
+//all date/time excluding duration\r
+static const int YEAR_DEFAULT = 2000;\r
+static const int MONTH_DEFAULT = 01;\r
+static const int DAY_DEFAULT = 15;\r
+\r
+// order-relation on duration is a partial order. The dates below are used to\r
+// for comparison of 2 durations, based on the fact that\r
+// duration x and y is x<=y iff s+x<=s+y\r
+// see 3.2.6 duration W3C schema datatype specs\r
+//\r
+// the dates are in format: {CCYY,MM,DD, H, S, M, MS, timezone}\r
+const int DateTime::DATETIMES[][TOTAL_SIZE] =\r
+{\r
+ {1696, 9, 1, 0, 0, 0, 0, UTC_STD},\r
+ {1697, 2, 1, 0, 0, 0, 0, UTC_STD},\r
+ {1903, 3, 1, 0, 0, 0, 0, UTC_STD},\r
+ {1903, 7, 1, 0, 0, 0, 0, UTC_STD}\r
+};\r
+\r
+// ---------------------------------------------------------------------------\r
+// local methods\r
+// ---------------------------------------------------------------------------\r
+static inline int fQuotient(int a, int b)\r
+{\r
+ div_t div_result = div(a, b);\r
+ return div_result.quot;\r
+}\r
+\r
+static inline int fQuotient(int temp, int low, int high)\r
+{\r
+ return fQuotient(temp - low, high - low);\r
+}\r
+\r
+static inline int mod(int a, int b, int quotient)\r
+{\r
+ return (a - quotient*b) ;\r
+}\r
+\r
+static inline int modulo (int temp, int low, int high)\r
+{\r
+ //modulo(a - low, high - low) + low\r
+ int a = temp - low;\r
+ int b = high - low;\r
+ return (mod (a, b, fQuotient(a, b)) + low) ;\r
+}\r
+\r
+static inline bool isLeapYear(int year)\r
+{\r
+ return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));\r
+}\r
+\r
+static int maxDayInMonthFor(int year, int month)\r
+{\r
+\r
+ if ( month == 4 || month == 6 || month == 9 || month == 11 )\r
+ {\r
+ return 30;\r
+ }\r
+ else if ( month==2 )\r
+ {\r
+ if ( isLeapYear(year) )\r
+ return 29;\r
+ else\r
+ return 28;\r
+ }\r
+ else\r
+ {\r
+ return 31;\r
+ }\r
+\r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// static methods : for duration\r
+// ---------------------------------------------------------------------------\r
+/**\r
+ * Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")\r
+ *\r
+ * 3.2.6.2 Order relation on duration\r
+ *\r
+ * In general, the order-relation on duration is a partial order since there is no\r
+ * determinate relationship between certain durations such as one month (P1M) and 30 days (P30D).\r
+ * The order-relation of two duration values x and y is x < y iff s+x < s+y for each qualified\r
+ * dateTime s in the list below.\r
+ *\r
+ * These values for s cause the greatest deviations in the addition of dateTimes and durations\r
+ *\r
+ **/\r
+int DateTime::compare(const DateTime* const pDate1\r
+ , const DateTime* const pDate2\r
+ , bool strict)\r
+{\r
+ //REVISIT: this is unoptimazed vs of comparing 2 durations\r
+ // Algorithm is described in 3.2.6.2 W3C Schema Datatype specs\r
+ //\r
+\r
+ int resultA, resultB = XMLDateTime::INDETERMINATE;\r
+\r
+ //try and see if the objects are equal\r
+ if ( (resultA = compareOrder(pDate1, pDate2)) == XMLDateTime::EQUAL)\r
+ return XMLDateTime::EQUAL;\r
+\r
+ //long comparison algorithm is required\r
+ DateTime tempA, *pTempA = &tempA;\r
+ DateTime tempB, *pTempB = &tempB;\r
+\r
+ addDuration(pTempA, pDate1, 0);\r
+ addDuration(pTempB, pDate2, 0);\r
+ resultA = compareOrder(pTempA, pTempB);\r
+ if ( resultA == XMLDateTime::INDETERMINATE )\r
+ return XMLDateTime::INDETERMINATE;\r
+\r
+ addDuration(pTempA, pDate1, 1);\r
+ addDuration(pTempB, pDate2, 1);\r
+ resultB = compareOrder(pTempA, pTempB);\r
+ resultA = compareResult(resultA, resultB, strict);\r
+ if ( resultA == XMLDateTime::INDETERMINATE )\r
+ return XMLDateTime::INDETERMINATE;\r
+\r
+ addDuration(pTempA, pDate1, 2);\r
+ addDuration(pTempB, pDate2, 2);\r
+ resultB = compareOrder(pTempA, pTempB);\r
+ resultA = compareResult(resultA, resultB, strict);\r
+ if ( resultA == XMLDateTime::INDETERMINATE )\r
+ return XMLDateTime::INDETERMINATE;\r
+\r
+ addDuration(pTempA, pDate1, 3);\r
+ addDuration(pTempB, pDate2, 3);\r
+ resultB = compareOrder(pTempA, pTempB);\r
+ resultA = compareResult(resultA, resultB, strict);\r
+\r
+ return resultA;\r
+\r
+}\r
+\r
+//\r
+// Form a new DateTime with duration and baseDate array\r
+// Note: C++ Java\r
+// fNewDate duration\r
+// fDuration date\r
+//\r
+\r
+void DateTime::addDuration(DateTime* fNewDate\r
+ , const DateTime* const fDuration\r
+ , int index)\r
+\r
+{\r
+\r
+ //REVISIT: some code could be shared between normalize() and this method,\r
+ // however is it worth moving it? The structures are different...\r
+ //\r
+\r
+ fNewDate->reset();\r
+ //add months (may be modified additionaly below)\r
+ int temp = DATETIMES[index][Month] + fDuration->fValue[Month];\r
+ fNewDate->fValue[Month] = modulo(temp, 1, 13);\r
+ int carry = fQuotient(temp, 1, 13);\r
+\r
+ //add years (may be modified additionaly below)\r
+ fNewDate->fValue[CentYear] =\r
+ DATETIMES[index][CentYear] + fDuration->fValue[CentYear] + carry;\r
+\r
+ //add seconds\r
+ temp = DATETIMES[index][Second] + fDuration->fValue[Second];\r
+ carry = fQuotient (temp, 60);\r
+ fNewDate->fValue[Second] = mod(temp, 60, carry);\r
+ \r
+ //add minutes\r
+ temp = DATETIMES[index][Minute] + fDuration->fValue[Minute] + carry;\r
+ carry = fQuotient(temp, 60);\r
+ fNewDate->fValue[Minute] = mod(temp, 60, carry);\r
+\r
+ //add hours\r
+ temp = DATETIMES[index][Hour] + fDuration->fValue[Hour] + carry;\r
+ carry = fQuotient(temp, 24);\r
+ fNewDate->fValue[Hour] = mod(temp, 24, carry);\r
+ \r
+ fNewDate->fValue[Day] =\r
+ DATETIMES[index][Day] + fDuration->fValue[Day] + carry;\r
+\r
+ while ( true )\r
+ {\r
+ temp = maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]);\r
+ if ( fNewDate->fValue[Day] < 1 )\r
+ { //original fNewDate was negative\r
+ fNewDate->fValue[Day] +=\r
+ maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]-1);\r
+ carry = -1;\r
+ }\r
+ else if ( fNewDate->fValue[Day] > temp )\r
+ {\r
+ fNewDate->fValue[Day] -= temp;\r
+ carry = 1;\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+\r
+ temp = fNewDate->fValue[Month] + carry;\r
+ fNewDate->fValue[Month] = modulo(temp, 1, 13);\r
+ fNewDate->fValue[CentYear] += fQuotient(temp, 1, 13);\r
+ }\r
+\r
+ //fNewDate->fValue[utc] = UTC_STD_CHAR;\r
+ fNewDate->fValue[utc] = UTC_STD;\r
+}\r
+\r
+int DateTime::compareResult(int resultA\r
+ , int resultB\r
+ , bool strict)\r
+{\r
+\r
+ if ( resultB == XMLDateTime::INDETERMINATE )\r
+ {\r
+ return XMLDateTime::INDETERMINATE;\r
+ }\r
+ else if ( (resultA != resultB) &&\r
+ strict )\r
+ {\r
+ return XMLDateTime::INDETERMINATE;\r
+ }\r
+ else if ( (resultA != resultB) &&\r
+ !strict )\r
+ {\r
+ if ( (resultA != XMLDateTime::EQUAL) &&\r
+ (resultB != XMLDateTime::EQUAL) )\r
+ {\r
+ return XMLDateTime::INDETERMINATE;\r
+ }\r
+ else\r
+ {\r
+ return (resultA != XMLDateTime::EQUAL)? resultA : resultB;\r
+ }\r
+ }\r
+\r
+ return resultA;\r
+ \r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// static methods : for others\r
+// ---------------------------------------------------------------------------\r
+int DateTime::compare(const DateTime* const pDate1\r
+ , const DateTime* const pDate2)\r
+{\r
+\r
+ if (pDate1->fValue[utc] == pDate2->fValue[utc])\r
+ {\r
+ return DateTime::compareOrder(pDate1, pDate2);\r
+ }\r
+\r
+ int c1, c2;\r
+\r
+ if ( pDate1->isNormalized())\r
+ {\r
+ c1 = compareResult(pDate1, pDate2, false, UTC_POS);\r
+ c2 = compareResult(pDate1, pDate2, false, UTC_NEG);\r
+ return getRetVal(c1, c2);\r
+ }\r
+ else if ( pDate2->isNormalized())\r
+ {\r
+ c1 = compareResult(pDate1, pDate2, true, UTC_POS);\r
+ c2 = compareResult(pDate1, pDate2, true, UTC_NEG);\r
+ return getRetVal(c1, c2);\r
+ }\r
+\r
+ return XMLDateTime::INDETERMINATE; \r
+}\r
+\r
+int DateTime::compareResult(const DateTime* const pDate1\r
+ , const DateTime* const pDate2\r
+ , bool set2Left\r
+ , int utc_type)\r
+{\r
+ DateTime tmpDate = (set2Left ? *pDate1 : *pDate2);\r
+\r
+ tmpDate.fTimeZone[hh] = 14;\r
+ tmpDate.fTimeZone[mm] = 0;\r
+ tmpDate.fValue[utc] = utc_type;\r
+ tmpDate.normalize();\r
+\r
+ return (set2Left? DateTime::compareOrder(&tmpDate, pDate2) :\r
+ DateTime::compareOrder(pDate1, &tmpDate));\r
+}\r
+\r
+int DateTime::compareOrder(const DateTime* const lValue\r
+ , const DateTime* const rValue)\r
+ //, MemoryManager* const memMgr)\r
+{\r
+ //\r
+ // If any of the them is not normalized() yet,\r
+ // we need to do something here.\r
+ //\r
+ DateTime lTemp = *lValue;\r
+ DateTime rTemp = *rValue;\r
+\r
+ lTemp.normalize();\r
+ rTemp.normalize();\r
+\r
+ for ( int i = 0 ; i < TOTAL_SIZE; i++ )\r
+ {\r
+ if ( lTemp.fValue[i] < rTemp.fValue[i] )\r
+ {\r
+ return XMLDateTime::LESS_THAN;\r
+ }\r
+ else if ( lTemp.fValue[i] > rTemp.fValue[i] )\r
+ {\r
+ return XMLDateTime::GREATER_THAN;\r
+ }\r
+ }\r
+\r
+ if ( lTemp.fHasTime)\r
+ {\r
+ if ( lTemp.fMiliSecond < rTemp.fMiliSecond )\r
+ {\r
+ return XMLDateTime::LESS_THAN;\r
+ }\r
+ else if ( lTemp.fMiliSecond > rTemp.fMiliSecond )\r
+ {\r
+ return XMLDateTime::GREATER_THAN;\r
+ }\r
+ }\r
+\r
+ return XMLDateTime::EQUAL;\r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// ctor and dtor\r
+// ---------------------------------------------------------------------------\r
+DateTime::~DateTime()\r
+{\r
+ delete[] fBuffer;\r
+}\r
+\r
+DateTime::DateTime()\r
+: fStart(0)\r
+, fEnd(0)\r
+, fBufferMaxLen(0)\r
+, fBuffer(0)\r
+, fMiliSecond(0)\r
+, fHasTime(false)\r
+{\r
+ reset();\r
+}\r
+\r
+DateTime::DateTime(const XMLCh* const aString)\r
+: fStart(0)\r
+, fEnd(0)\r
+, fBufferMaxLen(0)\r
+, fBuffer(0)\r
+, fMiliSecond(0)\r
+, fHasTime(false)\r
+{\r
+ setBuffer(aString);\r
+}\r
+\r
+DateTime::DateTime(time_t epoch)\r
+: fStart(0)\r
+, fEnd(0)\r
+, fBufferMaxLen(0)\r
+, fBuffer(0)\r
+, fMiliSecond(0)\r
+, fHasTime(false)\r
+{\r
+#ifndef HAVE_GMTIME_R\r
+ struct tm* ptime=gmtime(&epoch);\r
+#else\r
+ struct tm res;\r
+ struct tm* ptime=gmtime_r(&epoch,&res);\r
+#endif\r
+ char timebuf[32];\r
+ strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);\r
+ auto_ptr_XMLCh timeptr(timebuf);\r
+ setBuffer(timeptr.get());\r
+}\r
+\r
+// -----------------------------------------------------------------------\r
+// Copy ctor and Assignment operators\r
+// -----------------------------------------------------------------------\r
+\r
+DateTime::DateTime(const DateTime &toCopy)\r
+: fBufferMaxLen(0)\r
+, fBuffer(0)\r
+{\r
+ copy(toCopy);\r
+}\r
+\r
+DateTime& DateTime::operator=(const DateTime& rhs)\r
+{\r
+ if (this == &rhs)\r
+ return *this;\r
+\r
+ copy(rhs);\r
+ return *this;\r
+}\r
+\r
+// -----------------------------------------------------------------------\r
+// Implementation of Abstract Interface\r
+// -----------------------------------------------------------------------\r
+\r
+//\r
+// We may simply return the handle to fBuffer\r
+//\r
+const XMLCh* DateTime::getRawData() const\r
+{\r
+ //assertBuffer();\r
+ return fBuffer;\r
+}\r
+\r
+\r
+const XMLCh* DateTime::getFormattedString() const\r
+{\r
+ return getRawData();\r
+}\r
+\r
+int DateTime::getSign() const\r
+{\r
+ return 0;\r
+}\r
+\r
+time_t DateTime::getEpoch() const\r
+{\r
+ struct tm t;\r
+ t.tm_sec=getSecond();\r
+ t.tm_min=getMinute();\r
+ t.tm_hour=getHour();\r
+ t.tm_mday=getDay();\r
+ t.tm_mon=getMonth()-1;\r
+ t.tm_year=getYear()-1900;\r
+ t.tm_isdst=0;\r
+#if defined(HAVE_TIMEGM)\r
+ return timegm(&t);\r
+#else\r
+ // Windows, and hopefully most others...?\r
+ return mktime(&t) - timezone;\r
+#endif\r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// Parsers\r
+// ---------------------------------------------------------------------------\r
+\r
+//\r
+// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}[TimeZone]\r
+//\r
+void DateTime::parseDateTime()\r
+{\r
+ initParser();\r
+ getDate();\r
+\r
+ //fStart is supposed to point to 'T'\r
+ if (fBuffer[fStart++] != DATETIME_SEPARATOR)\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gDay_invalid\r
+ , fBuffer);\r
+\r
+ getTime();\r
+ validateDateTime();\r
+ normalize();\r
+ fHasTime = true;\r
+}\r
+\r
+//\r
+// [-]{CCYY-MM-DD}[TimeZone]\r
+//\r
+void DateTime::parseDate()\r
+{\r
+ initParser();\r
+ getDate();\r
+ parseTimeZone();\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+void DateTime::parseTime()\r
+{\r
+ initParser();\r
+\r
+ // time initialize to default values\r
+ fValue[CentYear]= YEAR_DEFAULT;\r
+ fValue[Month] = MONTH_DEFAULT;\r
+ fValue[Day] = DAY_DEFAULT;\r
+\r
+ getTime();\r
+\r
+ validateDateTime();\r
+ normalize();\r
+ fHasTime = true;\r
+}\r
+\r
+//\r
+// {---DD}[TimeZone]\r
+// 01234\r
+//\r
+void DateTime::parseDay()\r
+{\r
+ initParser();\r
+\r
+ if (fBuffer[0] != DATE_SEPARATOR ||\r
+ fBuffer[1] != DATE_SEPARATOR ||\r
+ fBuffer[2] != DATE_SEPARATOR )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gDay_invalid\r
+ , fBuffer);\r
+ }\r
+\r
+ //initialize values\r
+ fValue[CentYear] = YEAR_DEFAULT;\r
+ fValue[Month] = MONTH_DEFAULT;\r
+ fValue[Day] = parseInt(fStart+3, fStart+5);\r
+\r
+ if ( DAY_SIZE < fEnd )\r
+ {\r
+ int sign = findUTCSign(DAY_SIZE);\r
+ if ( sign < 0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gDay_invalid\r
+ , fBuffer);\r
+ }\r
+ else\r
+ {\r
+ getTimeZone(sign);\r
+ }\r
+ }\r
+\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+//\r
+// {--MM--}[TimeZone]\r
+// {--MM}[TimeZone]\r
+// 012345\r
+//\r
+void DateTime::parseMonth()\r
+{\r
+ initParser();\r
+\r
+ if (fBuffer[0] != DATE_SEPARATOR ||\r
+ fBuffer[1] != DATE_SEPARATOR )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gMth_invalid\r
+ , fBuffer);\r
+ }\r
+\r
+ //set constants\r
+ fValue[CentYear] = YEAR_DEFAULT;\r
+ fValue[Day] = DAY_DEFAULT;\r
+ fValue[Month] = parseInt(2, 4);\r
+\r
+ // REVISIT: allow both --MM and --MM-- now. \r
+ // need to remove the following lines to disallow --MM-- \r
+ // when the errata is officially in the rec. \r
+ fStart = 4;\r
+ if ( fEnd >= fStart+2 && fBuffer[fStart] == DATE_SEPARATOR && fBuffer[fStart+1] == DATE_SEPARATOR ) \r
+ { \r
+ fStart += 2; \r
+ } \r
+\r
+ //\r
+ // parse TimeZone if any\r
+ //\r
+ if ( fStart < fEnd )\r
+ {\r
+ int sign = findUTCSign(fStart);\r
+ if ( sign < 0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gMth_invalid\r
+ , fBuffer);\r
+ }\r
+ else\r
+ {\r
+ getTimeZone(sign);\r
+ }\r
+ }\r
+\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+//\r
+//[-]{CCYY}[TimeZone]\r
+// 0 1234\r
+//\r
+void DateTime::parseYear()\r
+{\r
+ initParser();\r
+\r
+ // skip the first '-' and search for timezone\r
+ //\r
+ int sign = findUTCSign((fBuffer[0] == chDash) ? 1 : 0);\r
+\r
+ if (sign == NOT_FOUND)\r
+ {\r
+ fValue[CentYear] = parseIntYear(fEnd);\r
+ }\r
+ else\r
+ {\r
+ fValue[CentYear] = parseIntYear(sign);\r
+ getTimeZone(sign);\r
+ }\r
+\r
+ //initialize values\r
+ fValue[Month] = MONTH_DEFAULT;\r
+ fValue[Day] = DAY_DEFAULT; //java is 1\r
+\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+//\r
+//{--MM-DD}[TimeZone]\r
+// 0123456\r
+//\r
+void DateTime::parseMonthDay()\r
+{\r
+ initParser();\r
+\r
+ if (fBuffer[0] != DATE_SEPARATOR ||\r
+ fBuffer[1] != DATE_SEPARATOR ||\r
+ fBuffer[4] != DATE_SEPARATOR )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gMthDay_invalid\r
+ , fBuffer);\r
+ }\r
+\r
+\r
+ //initialize\r
+ fValue[CentYear] = YEAR_DEFAULT;\r
+ fValue[Month] = parseInt(2, 4); \r
+ fValue[Day] = parseInt(5, 7);\r
+\r
+ if ( MONTHDAY_SIZE < fEnd )\r
+ {\r
+ int sign = findUTCSign(MONTHDAY_SIZE);\r
+ if ( sign<0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_gMthDay_invalid\r
+ , fBuffer);\r
+ }\r
+ else\r
+ {\r
+ getTimeZone(sign);\r
+ }\r
+ }\r
+\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+void DateTime::parseYearMonth()\r
+{\r
+ initParser();\r
+\r
+ // get date\r
+ getYearMonth();\r
+ fValue[Day] = DAY_DEFAULT;\r
+ parseTimeZone();\r
+\r
+ validateDateTime();\r
+ normalize();\r
+}\r
+\r
+//\r
+//PnYn MnDTnH nMnS: -P1Y2M3DT10H30M\r
+//\r
+// [-]{'P'{[n'Y'][n'M'][n'D']['T'][n'H'][n'M'][n'S']}}\r
+//\r
+// Note: the n above shall be >= 0\r
+// if no time element found, 'T' shall be absent\r
+//\r
+void DateTime::parseDuration()\r
+{\r
+ initParser();\r
+\r
+ // must start with '-' or 'P'\r
+ //\r
+ XMLCh c = fBuffer[fStart++];\r
+ if ( (c != DURATION_STARTER) &&\r
+ (c != chDash) )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_Start_dashP\r
+ , fBuffer);\r
+ }\r
+\r
+ // 'P' must ALWAYS be present in either case\r
+ if ( (c == chDash) &&\r
+ (fBuffer[fStart++]!= DURATION_STARTER ))\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_noP\r
+ , fBuffer);\r
+ }\r
+\r
+ // java code\r
+ //date[utc]=(c=='-')?'-':0;\r
+ //fValue[utc] = UTC_STD;\r
+ fValue[utc] = (fBuffer[0] == chDash? UTC_NEG : UTC_STD);\r
+\r
+ int negate = ( fBuffer[0] == chDash ? -1 : 1);\r
+\r
+ //\r
+ // No negative value is allowed after 'P'\r
+ //\r
+ // eg P-1234, invalid\r
+ //\r
+ if (indexOf(fStart, fEnd, chDash) != NOT_FOUND)\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_DashNotFirst\r
+ , fBuffer);\r
+ }\r
+\r
+ //at least one number and designator must be seen after P\r
+ bool designator = false;\r
+\r
+ int endDate = indexOf(fStart, fEnd, DATETIME_SEPARATOR);\r
+ if ( endDate == NOT_FOUND )\r
+ {\r
+ endDate = fEnd; // 'T' absent\r
+ }\r
+\r
+ //find 'Y'\r
+ int end = indexOf(fStart, endDate, DURATION_Y);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan year\r
+ fValue[CentYear] = negate * parseInt(fStart, end);\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ end = indexOf(fStart, endDate, DURATION_M);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan month\r
+ fValue[Month] = negate * parseInt(fStart, end);\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ end = indexOf(fStart, endDate, DURATION_D);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan day\r
+ fValue[Day] = negate * parseInt(fStart,end);\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ if ( (fEnd == endDate) && // 'T' absent\r
+ (fStart != fEnd) ) // something after Day\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_inv_b4T\r
+ , fBuffer);\r
+ }\r
+\r
+ if ( fEnd != endDate ) // 'T' present\r
+ {\r
+ //scan hours, minutes, seconds\r
+ //\r
+\r
+ // skip 'T' first\r
+ end = indexOf(++fStart, fEnd, DURATION_H);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan hours\r
+ fValue[Hour] = negate * parseInt(fStart, end);\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ end = indexOf(fStart, fEnd, DURATION_M);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan min\r
+ fValue[Minute] = negate * parseInt(fStart, end);\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ end = indexOf(fStart, fEnd, DURATION_S);\r
+ if ( end != NOT_FOUND )\r
+ {\r
+ //scan seconds\r
+ int mlsec = indexOf (fStart, end, MILISECOND_SEPARATOR);\r
+\r
+ /***\r
+ * Schema Errata: E2-23\r
+ * at least one digit must follow the decimal point if it appears. \r
+ * That is, the value of the seconds component must conform \r
+ * to the following pattern: [0-9]+(.[0-9]+)? \r
+ */\r
+ if ( mlsec != NOT_FOUND )\r
+ {\r
+ /***\r
+ * make usure there is something after the '.' and before the end.\r
+ */\r
+ if ( mlsec+1 == end )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_inv_seconds\r
+ , fBuffer);\r
+ }\r
+\r
+ fValue[Second] = negate * parseInt(fStart, mlsec);\r
+ fMiliSecond = negate * parseMiliSecond(mlsec+1, end);\r
+ }\r
+ else\r
+ {\r
+ fValue[Second] = negate * parseInt(fStart,end);\r
+ }\r
+\r
+ fStart = end+1;\r
+ designator = true;\r
+ }\r
+\r
+ // no additional data should appear after last item\r
+ // P1Y1M1DT is illigal value as well\r
+ if ( (fStart != fEnd) ||\r
+ fBuffer[--fStart] == DATETIME_SEPARATOR )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_NoTimeAfterT\r
+ , fBuffer);\r
+ }\r
+ }\r
+\r
+ if ( !designator )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_dur_NoElementAtAll\r
+ , fBuffer);\r
+ }\r
+\r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// Scanners\r
+// ---------------------------------------------------------------------------\r
+\r
+//\r
+// [-]{CCYY-MM-DD}\r
+//\r
+// Note: CCYY could be more than 4 digits\r
+// Assuming fStart point to the beginning of the Date Section\r
+// fStart updated to point to the position right AFTER the second 'D'\r
+// Since the lenght of CCYY might be variable, we can't check format upfront\r
+//\r
+void DateTime::getDate()\r
+{\r
+\r
+ // Ensure enough chars in buffer\r
+ if ( (fStart+YMD_MIN_SIZE) > fEnd)\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_date_incomplete\r
+ , fBuffer);\r
+\r
+ getYearMonth(); // Scan YearMonth and\r
+ // fStart point to the next '-'\r
+\r
+ if (fBuffer[fStart++] != DATE_SEPARATOR)\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_date_invalid\r
+ , fBuffer);\r
+ //("CCYY-MM must be followed by '-' sign");\r
+ }\r
+\r
+ fValue[Day] = parseInt(fStart, fStart+2);\r
+ fStart += 2 ; //fStart points right after the Day\r
+\r
+ return;\r
+}\r
+\r
+//\r
+// hh:mm:ss[.msssss]['Z']\r
+// hh:mm:ss[.msssss][['+'|'-']hh:mm]\r
+// 012345678\r
+//\r
+// Note: Assuming fStart point to the beginning of the Time Section\r
+// fStart updated to point to the position right AFTER the second 's'\r
+// or ms if any\r
+//\r
+void DateTime::getTime()\r
+{\r
+\r
+ // Ensure enough chars in buffer\r
+ if ( (fStart+TIME_MIN_SIZE) > fEnd)\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_time_incomplete\r
+ , fBuffer);\r
+ //"Imcomplete Time Format"\r
+\r
+ // check (fixed) format first\r
+ if ((fBuffer[fStart + 2] != TIME_SEPARATOR) ||\r
+ (fBuffer[fStart + 5] != TIME_SEPARATOR) )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_time_invalid\r
+ , fBuffer);\r
+ //("Error in parsing time" );\r
+ }\r
+\r
+ //\r
+ // get hours, minute and second\r
+ //\r
+ fValue[Hour] = parseInt(fStart + 0, fStart + 2);\r
+ fValue[Minute] = parseInt(fStart + 3, fStart + 5);\r
+ fValue[Second] = parseInt(fStart + 6, fStart + 8);\r
+ fStart += 8;\r
+\r
+ // to see if any ms and/or utc part after that\r
+ if (fStart >= fEnd)\r
+ return;\r
+\r
+ //find UTC sign if any\r
+ int sign = findUTCSign(fStart);\r
+\r
+ //parse miliseconds\r
+ int milisec = (fBuffer[fStart] == MILISECOND_SEPARATOR)? fStart : NOT_FOUND;\r
+ if ( milisec != NOT_FOUND )\r
+ {\r
+ fStart++; // skip the '.'\r
+ // make sure we have some thing between the '.' and fEnd\r
+ if (fStart >= fEnd)\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_ms_noDigit\r
+ , fBuffer);\r
+ //("ms shall be present once '.' is present" );\r
+ }\r
+\r
+ if ( sign == NOT_FOUND )\r
+ {\r
+ fMiliSecond = parseMiliSecond(fStart, fEnd); //get ms between '.' and fEnd\r
+ fStart = fEnd;\r
+ }\r
+ else\r
+ {\r
+ fMiliSecond = parseMiliSecond(fStart, sign); //get ms between UTC sign and fEnd\r
+ }\r
+ }\r
+ else if(sign == 0 || sign != fStart)\r
+ {\r
+ // seconds has more than 2 digits\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_min_invalid\r
+ , fBuffer);\r
+ }\r
+\r
+ //parse UTC time zone (hh:mm)\r
+ if ( sign > 0 ) {\r
+ getTimeZone(sign);\r
+ }\r
+\r
+}\r
+\r
+//\r
+// [-]{CCYY-MM}\r
+//\r
+// Note: CCYY could be more than 4 digits\r
+// fStart updated to point AFTER the second 'M' (probably meet the fEnd)\r
+//\r
+void DateTime::getYearMonth()\r
+{\r
+\r
+ // Ensure enough chars in buffer\r
+ if ( (fStart+YMONTH_MIN_SIZE) > fEnd)\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_ym_incomplete\r
+ , fBuffer);\r
+ //"Imcomplete YearMonth Format";\r
+\r
+ // skip the first leading '-'\r
+ int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;\r
+\r
+ //\r
+ // search for year separator '-'\r
+ //\r
+ int yearSeparator = indexOf(start, fEnd, DATE_SEPARATOR);\r
+ if ( yearSeparator == NOT_FOUND)\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_ym_invalid\r
+ , fBuffer);\r
+ //("Year separator is missing or misplaced");\r
+\r
+ fValue[CentYear] = parseIntYear(yearSeparator);\r
+ fStart = yearSeparator + 1; //skip the '-' and point to the first M\r
+\r
+ //\r
+ //gonna check we have enough byte for month\r
+ //\r
+ if ((fStart + 2) > fEnd )\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_ym_noMonth\r
+ , fBuffer);\r
+ //"no month in buffer"\r
+\r
+ fValue[Month] = parseInt(fStart, yearSeparator + 3);\r
+ fStart += 2; //fStart points right after the MONTH\r
+\r
+ return;\r
+}\r
+\r
+void DateTime::parseTimeZone()\r
+{\r
+ if ( fStart < fEnd )\r
+ {\r
+ int sign = findUTCSign(fStart);\r
+ if ( sign < 0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_tz_noUTCsign\r
+ , fBuffer);\r
+ //("Error in month parsing");\r
+ }\r
+ else\r
+ {\r
+ getTimeZone(sign);\r
+ }\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+//\r
+// 'Z'\r
+// ['+'|'-']hh:mm\r
+//\r
+// Note: Assuming fStart points to the beginning of TimeZone section\r
+// fStart updated to meet fEnd\r
+//\r
+void DateTime::getTimeZone(const int sign)\r
+{\r
+\r
+ if ( fBuffer[sign] == UTC_STD_CHAR )\r
+ {\r
+ if ((sign + 1) != fEnd )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_tz_stuffAfterZ\r
+ , fBuffer);\r
+ //"Error in parsing time zone");\r
+ } \r
+\r
+ return; \r
+ }\r
+\r
+ //\r
+ // otherwise, it has to be this format\r
+ // '[+|-]'hh:mm\r
+ // 1 23456 7\r
+ // sign fEnd\r
+ //\r
+ if ( ( ( sign + TIMEZONE_SIZE + 1) != fEnd ) ||\r
+ ( fBuffer[sign + 3] != TIMEZONE_SEPARATOR ) )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_tz_invalid\r
+ , fBuffer);\r
+ //("Error in parsing time zone");\r
+ }\r
+\r
+ fTimeZone[hh] = parseInt(sign+1, sign+3); \r
+ fTimeZone[mm] = parseInt(sign+4, fEnd);\r
+ \r
+ return;\r
+}\r
+\r
+// ---------------------------------------------------------------------------\r
+// Validator and normalizer\r
+// ---------------------------------------------------------------------------\r
+\r
+/**\r
+ * If timezone present - normalize dateTime [E Adding durations to dateTimes]\r
+ *\r
+ * @param date CCYY-MM-DDThh:mm:ss+03\r
+ * @return CCYY-MM-DDThh:mm:ssZ\r
+ */\r
+void DateTime::normalize()\r
+{\r
+\r
+ if ((fValue[utc] == UTC_UNKNOWN) ||\r
+ (fValue[utc] == UTC_STD) )\r
+ return;\r
+\r
+ int negate = (fValue[utc] == UTC_POS)? -1: 1;\r
+\r
+ // add mins\r
+ int temp = fValue[Minute] + negate * fTimeZone[mm];\r
+ int carry = fQuotient(temp, 60);\r
+ fValue[Minute] = mod(temp, 60, carry);\r
+\r
+ //add hours\r
+ temp = fValue[Hour] + negate * fTimeZone[hh] + carry;\r
+ carry = fQuotient(temp, 24);\r
+ fValue[Hour] = mod(temp, 24, carry);\r
+\r
+ fValue[Day] += carry;\r
+\r
+ while (1)\r
+ {\r
+ temp = maxDayInMonthFor(fValue[CentYear], fValue[Month]);\r
+ if (fValue[Day] < 1)\r
+ {\r
+ fValue[Day] += maxDayInMonthFor(fValue[CentYear], fValue[Month] - 1);\r
+ carry = -1;\r
+ }\r
+ else if ( fValue[Day] > temp )\r
+ {\r
+ fValue[Day] -= temp;\r
+ carry = 1;\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+\r
+ temp = fValue[Month] + carry;\r
+ fValue[Month] = modulo(temp, 1, 13);\r
+ fValue[CentYear] += fQuotient(temp, 1, 13);\r
+ }\r
+\r
+ // set to normalized\r
+ fValue[utc] = UTC_STD;\r
+\r
+ return;\r
+}\r
+\r
+void DateTime::validateDateTime() const\r
+{\r
+\r
+ //REVISIT: should we throw an exception for not valid dates\r
+ // or reporting an error message should be sufficient?\r
+ if ( fValue[CentYear] == 0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_year_zero\r
+ , fBuffer);\r
+ //"The year \"0000\" is an illegal year value");\r
+ }\r
+\r
+ if ( fValue[Month] < 1 ||\r
+ fValue[Month] > 12 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_mth_invalid\r
+ , fBuffer);\r
+ //"The month must have values 1 to 12");\r
+ }\r
+\r
+ //validate days\r
+ if ( fValue[Day] > maxDayInMonthFor( fValue[CentYear], fValue[Month]) ||\r
+ fValue[Day] == 0 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_day_invalid\r
+ , fBuffer);\r
+ //"The day must have values 1 to 31");\r
+ }\r
+\r
+ //validate hours\r
+ if ((fValue[Hour] < 0) ||\r
+ (fValue[Hour] > 24) ||\r
+ ((fValue[Hour] == 24) && ((fValue[Minute] !=0) ||\r
+ (fValue[Second] !=0) ||\r
+ (fMiliSecond !=0))))\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_hour_invalid\r
+ , fBuffer);\r
+ //("Hour must have values 0-23");\r
+ }\r
+\r
+ //validate minutes\r
+ if ( fValue[Minute] < 0 ||\r
+ fValue[Minute] > 59 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_min_invalid\r
+ , fBuffer);\r
+ //"Minute must have values 0-59");\r
+ }\r
+\r
+ //validate seconds\r
+ if ( fValue[Second] < 0 ||\r
+ fValue[Second] > 60 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_second_invalid\r
+ , fBuffer);\r
+ //"Second must have values 0-60");\r
+ }\r
+\r
+ //validate time-zone hours\r
+ if ( (abs(fTimeZone[hh]) > 14) ||\r
+ ((abs(fTimeZone[hh]) == 14) && (fTimeZone[mm] != 0)) )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_tz_hh_invalid\r
+ , fBuffer);\r
+ //"Time zone should have range -14..+14");\r
+ }\r
+\r
+ //validate time-zone minutes\r
+ if ( abs(fTimeZone[mm]) > 59 )\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_min_invalid\r
+ , fBuffer);\r
+ //("Minute must have values 0-59");\r
+ }\r
+ \r
+ return;\r
+}\r
+\r
+// -----------------------------------------------------------------------\r
+// locator and converter\r
+// -----------------------------------------------------------------------\r
+int DateTime::indexOf(const int start, const int end, const XMLCh ch) const\r
+{\r
+ for ( int i = start; i < end; i++ )\r
+ if ( fBuffer[i] == ch )\r
+ return i;\r
+\r
+ return NOT_FOUND;\r
+}\r
+\r
+int DateTime::findUTCSign (const int start)\r
+{\r
+ int pos;\r
+ for ( int index = start; index < fEnd; index++ )\r
+ {\r
+ pos = XMLString::indexOf(UTC_SET, fBuffer[index]);\r
+ if ( pos != NOT_FOUND)\r
+ {\r
+ fValue[utc] = pos+1; // refer to utcType, there is 1 diff\r
+ return index;\r
+ }\r
+ }\r
+\r
+ return NOT_FOUND;\r
+}\r
+\r
+//\r
+// Note:\r
+// start: starting point in fBuffer\r
+// end: ending point in fBuffer (exclusive)\r
+// fStart NOT updated\r
+//\r
+int DateTime::parseInt(const int start, const int end) const\r
+{\r
+ unsigned int retVal = 0;\r
+ for (int i=start; i < end; i++) {\r
+\r
+ if (fBuffer[i] < chDigit_0 || fBuffer[i] > chDigit_9)\r
+ ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);\r
+\r
+ retVal = (retVal * 10) + (unsigned int) (fBuffer[i] - chDigit_0);\r
+ }\r
+\r
+ return (int) retVal;\r
+}\r
+\r
+//\r
+// Note:\r
+// start: pointing to the first digit after the '.'\r
+// end: pointing to one position after the last digit\r
+// fStart NOT updated\r
+//\r
+double DateTime::parseMiliSecond(const int start, const int end) const\r
+{\r
+\r
+ unsigned int miliSecLen = (end-1) - (start-1) + 1; //to include the '.'\r
+ XMLCh* miliSecData = new XMLCh[miliSecLen + 1];\r
+ ArrayJanitor<XMLCh> janMili(miliSecData);\r
+ XMLString::copyNString(miliSecData, &(fBuffer[start-1]), miliSecLen);\r
+ *(miliSecData + miliSecLen) = chNull;\r
+\r
+ char *nptr = XMLString::transcode(miliSecData);\r
+ ArrayJanitor<char> jan(nptr);\r
+ size_t strLen = strlen(nptr);\r
+ char *endptr = 0;\r
+ errno = 0;\r
+\r
+ //printf("milisec=<%s>\n", nptr);\r
+\r
+ double retVal = strtod(nptr, &endptr);\r
+\r
+ // check if all chars are valid char\r
+ if ( (endptr - nptr) != strLen)\r
+ ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);\r
+\r
+ // we don't check underflow occurs since\r
+ // nothing we can do about it.\r
+ return retVal;\r
+}\r
+\r
+//\r
+// [-]CCYY\r
+//\r
+// Note: start from fStart\r
+// end (exclusive)\r
+// fStart NOT updated\r
+//\r
+int DateTime::parseIntYear(const int end) const\r
+{\r
+ // skip the first leading '-'\r
+ int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;\r
+\r
+ int length = end - start;\r
+ if (length < 4)\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_year_tooShort\r
+ , fBuffer);\r
+ //"Year must have 'CCYY' format");\r
+ }\r
+ else if (length > 4 &&\r
+ fBuffer[start] == chDigit_0)\r
+ {\r
+ ThrowXML1(SchemaDateTimeException\r
+ , XMLExcepts::DateTime_year_leadingZero\r
+ , fBuffer);\r
+ //"Leading zeros are required if the year value would otherwise have fewer than four digits;\r
+ // otherwise they are forbidden");\r
+ }\r
+\r
+ bool negative = (fBuffer[0] == chDash);\r
+ int yearVal = parseInt((negative ? 1 : 0), end);\r
+ return ( negative ? (-1) * yearVal : yearVal );\r
+}\r
+\r
+/***\r
+ * E2-41\r
+ *\r
+ * 3.2.7.2 Canonical representation\r
+ * \r
+ * Except for trailing fractional zero digits in the seconds representation, \r
+ * '24:00:00' time representations, and timezone (for timezoned values), \r
+ * the mapping from literals to values is one-to-one. Where there is more \r
+ * than one possible representation, the canonical representation is as follows: \r
+ * redundant trailing zero digits in fractional-second literals are prohibited. \r
+ * An hour representation of '24' is prohibited. Timezoned values are canonically\r
+ * represented by appending 'Z' to the nontimezoned representation. (All \r
+ * timezoned dateTime values are UTC.) \r
+ *\r
+ * .'24:00:00' -> '00:00:00'\r
+ * .milisecond: trailing zeros removed\r
+ * .'Z'\r
+ *\r
+ ***/\r
+XMLCh* DateTime::getDateTimeCanonicalRepresentation() const\r
+{\r
+ XMLCh *miliStartPtr, *miliEndPtr;\r
+ searchMiliSeconds(miliStartPtr, miliEndPtr);\r
+ size_t miliSecondsLen = miliEndPtr - miliStartPtr;\r
+\r
+ XMLCh* retBuf = new XMLCh[21 + miliSecondsLen + 2];\r
+ XMLCh* retPtr = retBuf;\r
+\r
+ // (-?) cc+yy-mm-dd'T'hh:mm:ss'Z' ('.'s+)?\r
+ // 2+ 8 1 8 1\r
+ //\r
+ int additionalLen = fillYearString(retPtr, CentYear);\r
+ if(additionalLen != 0)\r
+ {\r
+ // very bad luck; have to resize the buffer...\r
+ XMLCh *tmpBuf = new XMLCh[additionalLen+21+miliSecondsLen +2];\r
+ XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);\r
+ retPtr = tmpBuf+(retPtr-retBuf);\r
+ delete[] retBuf;\r
+ retBuf = tmpBuf;\r
+ }\r
+ *retPtr++ = DATE_SEPARATOR;\r
+ fillString(retPtr, Month, 2);\r
+ *retPtr++ = DATE_SEPARATOR;\r
+ fillString(retPtr, Day, 2);\r
+ *retPtr++ = DATETIME_SEPARATOR;\r
+\r
+ fillString(retPtr, Hour, 2);\r
+ if (fValue[Hour] == 24)\r
+ {\r
+ *(retPtr - 2) = chDigit_0;\r
+ *(retPtr - 1) = chDigit_0;\r
+ }\r
+ *retPtr++ = TIME_SEPARATOR;\r
+ fillString(retPtr, Minute, 2);\r
+ *retPtr++ = TIME_SEPARATOR;\r
+ fillString(retPtr, Second, 2);\r
+\r
+ if (miliSecondsLen)\r
+ {\r
+ *retPtr++ = chPeriod;\r
+ XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);\r
+ retPtr += miliSecondsLen;\r
+ }\r
+\r
+ *retPtr++ = UTC_STD_CHAR;\r
+ *retPtr = chNull;\r
+\r
+ return retBuf;\r
+}\r
+\r
+/***\r
+ * 3.2.8 time\r
+ *\r
+ * . either the time zone must be omitted or, \r
+ * if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z". \r
+ *\r
+ * . Additionally, the canonical representation for midnight is 00:00:00.\r
+ *\r
+***/\r
+XMLCh* DateTime::getTimeCanonicalRepresentation() const\r
+{\r
+ XMLCh *miliStartPtr, *miliEndPtr;\r
+ searchMiliSeconds(miliStartPtr, miliEndPtr);\r
+ size_t miliSecondsLen = miliEndPtr - miliStartPtr;\r
+\r
+ XMLCh* retBuf = new XMLCh[10 + miliSecondsLen + 2];\r
+ XMLCh* retPtr = retBuf;\r
+\r
+ // 'hh:mm:ss'Z' ('.'s+)?\r
+ // 8 1\r
+ //\r
+\r
+ fillString(retPtr, Hour, 2);\r
+ if (fValue[Hour] == 24)\r
+ {\r
+ *(retPtr - 2) = chDigit_0;\r
+ *(retPtr - 1) = chDigit_0;\r
+ }\r
+ *retPtr++ = TIME_SEPARATOR;\r
+ fillString(retPtr, Minute, 2);\r
+ *retPtr++ = TIME_SEPARATOR;\r
+ fillString(retPtr, Second, 2);\r
+\r
+ if (miliSecondsLen)\r
+ {\r
+ *retPtr++ = chPeriod;\r
+ XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);\r
+ retPtr += miliSecondsLen;\r
+ }\r
+\r
+ *retPtr++ = UTC_STD_CHAR;\r
+ *retPtr = chNull;\r
+\r
+ return retBuf;\r
+}\r
+\r
+void DateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const\r
+{\r
+ XMLCh strBuffer[16];\r
+ assert(expLen < 16);\r
+ XMLString::binToText(fValue[ind], strBuffer, expLen, 10);\r
+ int actualLen = XMLString::stringLen(strBuffer);\r
+ int i;\r
+ //append leading zeros\r
+ for (i = 0; i < expLen - actualLen; i++)\r
+ {\r
+ *ptr++ = chDigit_0;\r
+ }\r
+\r
+ for (i = 0; i < actualLen; i++)\r
+ {\r
+ *ptr++ = strBuffer[i];\r
+ }\r
+\r
+}\r
+\r
+int DateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const\r
+{\r
+ XMLCh strBuffer[16];\r
+ // let's hope we get no years of 15 digits...\r
+ XMLString::binToText(fValue[ind], strBuffer, 15, 10);\r
+ int actualLen = XMLString::stringLen(strBuffer);\r
+ // don't forget that years can be negative...\r
+ int negativeYear = 0;\r
+ if(strBuffer[0] == chDash)\r
+ {\r
+ *ptr++ = strBuffer[0];\r
+ negativeYear = 1;\r
+ }\r
+ int i;\r
+ //append leading zeros\r
+ for (i = 0; i < 4 - actualLen+negativeYear; i++)\r
+ {\r
+ *ptr++ = chDigit_0;\r
+ }\r
+\r
+ for (i = negativeYear; i < actualLen; i++)\r
+ {\r
+ *ptr++ = strBuffer[i];\r
+ }\r
+ if(actualLen > 4)\r
+ return actualLen-4;\r
+ return 0;\r
+}\r
+\r
+/***\r
+ *\r
+ * .check if the rawData has the mili second component\r
+ * .capture the substring\r
+ *\r
+ ***/\r
+void DateTime::searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const\r
+{\r
+ miliStartPtr = miliEndPtr = 0;\r
+\r
+ int milisec = XMLString::indexOf(fBuffer, MILISECOND_SEPARATOR);\r
+ if (milisec == -1)\r
+ return;\r
+\r
+ miliStartPtr = fBuffer + milisec + 1;\r
+ miliEndPtr = miliStartPtr;\r
+ while (*miliEndPtr)\r
+ {\r
+ if ((*miliEndPtr < chDigit_0) || (*miliEndPtr > chDigit_9))\r
+ break;\r
+\r
+ miliEndPtr++;\r
+ }\r
+\r
+ //remove trailing zeros\r
+ while( *(miliEndPtr - 1) == chDigit_0)\r
+ miliEndPtr--;\r
+\r
+ return;\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright 2001-2006 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file DateTime.h\r
+ * \r
+ * Manipulation of XML date/time data. \r
+ */\r
+\r
+#ifndef _XML_DATETIME_H\r
+#define _XML_DATETIME_H\r
+\r
+#include <xmltooling/base.h>\r
+\r
+#if defined (_MSC_VER)\r
+ #pragma warning( push )\r
+ #pragma warning( disable : 4244 )\r
+#endif\r
+\r
+#include <xercesc/util/XMLDateTime.hpp>\r
+\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
+namespace xmltooling\r
+{\r
+ /**\r
+ * Class for manipulating XML date/time information.\r
+ * \r
+ * This is mostly copied from Xerces-C, but they haven't produced a usable date/time\r
+ * class, so we had to incorporate a version of it for now. It can't be inherited\r
+ * since the fields needed are private.\r
+ */\r
+ class XMLTOOL_API DateTime\r
+ {\r
+ public:\r
+ /// @cond OFF\r
+ DateTime();\r
+ DateTime(const XMLCh* const);\r
+ DateTime(time_t epoch);\r
+ DateTime(const DateTime&);\r
+ DateTime& operator=(const DateTime&);\r
+ ~DateTime();\r
+ \r
+ inline void setBuffer(const XMLCh* const);\r
+ \r
+ const XMLCh* getRawData() const;\r
+ const XMLCh* getFormattedString() const;\r
+ int getSign() const;\r
+ \r
+ XMLCh* getDateTimeCanonicalRepresentation() const;\r
+ XMLCh* getTimeCanonicalRepresentation() const;\r
+ \r
+ void parseDateTime();\r
+ void parseDate();\r
+ void parseTime();\r
+ void parseDay();\r
+ void parseMonth();\r
+ void parseYear();\r
+ void parseMonthDay();\r
+ void parseYearMonth();\r
+ void parseDuration();\r
+ \r
+ static int compare(const DateTime* const, const DateTime* const);\r
+ static int compare(const DateTime* const, const DateTime* const, bool);\r
+ static int compareOrder(const DateTime* const, const DateTime* const); \r
+ \r
+ int getYear() const {return fValue[CentYear];}\r
+ int getMonth() const {return fValue[Month];}\r
+ int getDay() const {return fValue[Day];}\r
+ int getHour() const {return fValue[Hour];}\r
+ int getMinute() const {return fValue[Minute];}\r
+ int getSecond() const {return fValue[Second];}\r
+ time_t getEpoch() const;\r
+ \r
+ /// @endcond\r
+ private:\r
+ enum valueIndex {\r
+ CentYear = 0,\r
+ Month ,\r
+ Day ,\r
+ Hour ,\r
+ Minute ,\r
+ Second ,\r
+ MiliSecond , //not to be used directly\r
+ utc ,\r
+ TOTAL_SIZE\r
+ };\r
+ \r
+ enum utcType {\r
+ UTC_UNKNOWN = 0,\r
+ UTC_STD , // set in parse() or normalize()\r
+ UTC_POS , // set in parse()\r
+ UTC_NEG // set in parse()\r
+ };\r
+ \r
+ enum timezoneIndex {\r
+ hh = 0,\r
+ mm ,\r
+ TIMEZONE_ARRAYSIZE\r
+ };\r
+ \r
+ static int compareResult(int, int, bool);\r
+ static void addDuration(DateTime* pDuration, const DateTime* const pBaseDate, int index);\r
+ static int compareResult(const DateTime* const, const DateTime* const, bool, int);\r
+ static inline int getRetVal(int, int);\r
+ \r
+ inline void reset();\r
+ //inline void assertBuffer() const;\r
+ inline void copy(const DateTime&);\r
+ \r
+ inline void initParser();\r
+ inline bool isNormalized() const;\r
+ \r
+ void getDate();\r
+ void getTime();\r
+ void getYearMonth();\r
+ void getTimeZone(const int);\r
+ void parseTimeZone();\r
+ \r
+ int findUTCSign(const int start);\r
+ int indexOf(const int start, const int end, const XMLCh ch) const;\r
+ int parseInt(const int start, const int end) const;\r
+ int parseIntYear(const int end) const;\r
+ double parseMiliSecond(const int start, const int end) const;\r
+ \r
+ void validateDateTime() const;\r
+ void normalize();\r
+ void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;\r
+ int fillYearString(XMLCh*& ptr, valueIndex ind) const;\r
+ void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;\r
+ \r
+ bool operator==(const DateTime& toCompare) const;\r
+ \r
+ static const int DATETIMES[][TOTAL_SIZE];\r
+ int fValue[TOTAL_SIZE];\r
+ int fTimeZone[TIMEZONE_ARRAYSIZE];\r
+ int fStart;\r
+ int fEnd;\r
+ int fBufferMaxLen;\r
+ XMLCh* fBuffer;\r
+ \r
+ double fMiliSecond;\r
+ bool fHasTime;\r
+ };\r
+\r
+ inline void DateTime::setBuffer(const XMLCh* const aString)\r
+ {\r
+ reset();\r
+ fEnd = XMLString::stringLen(aString);\r
+ if (fEnd > 0) {\r
+ if (fEnd > fBufferMaxLen) {\r
+ delete[] fBuffer;\r
+ fBufferMaxLen = fEnd + 8;\r
+ fBuffer = new XMLCh[fBufferMaxLen+1];\r
+ }\r
+ memcpy(fBuffer, aString, (fEnd+1) * sizeof(XMLCh));\r
+ }\r
+ }\r
+ \r
+ inline void DateTime::reset()\r
+ {\r
+ for ( int i=0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
+ fValue[i] = 0;\r
+ \r
+ fMiliSecond = 0;\r
+ fHasTime = false;\r
+ fTimeZone[hh] = fTimeZone[mm] = 0;\r
+ fStart = fEnd = 0;\r
+ \r
+ if (fBuffer)\r
+ *fBuffer = 0;\r
+ }\r
+ \r
+ inline void DateTime::copy(const DateTime& rhs)\r
+ {\r
+ for ( int i = 0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
+ fValue[i] = rhs.fValue[i];\r
+ \r
+ fMiliSecond = rhs.fMiliSecond;\r
+ fHasTime = rhs.fHasTime;\r
+ fTimeZone[hh] = rhs.fTimeZone[hh];\r
+ fTimeZone[mm] = rhs.fTimeZone[mm];\r
+ fStart = rhs.fStart;\r
+ fEnd = rhs.fEnd;\r
+ \r
+ if (fEnd > 0) {\r
+ if (fEnd > fBufferMaxLen) {\r
+ delete[] fBuffer;\r
+ fBufferMaxLen = rhs.fBufferMaxLen;\r
+ fBuffer = new XMLCh[fBufferMaxLen+1];\r
+ }\r
+ memcpy(fBuffer, rhs.fBuffer, (fEnd+1) * sizeof(XMLCh));\r
+ }\r
+ }\r
+ \r
+ inline void DateTime::initParser()\r
+ {\r
+ fStart = 0; // to ensure scan from the very first beginning\r
+ // in case the pointer is updated accidentally by someone else.\r
+ }\r
+ \r
+ inline bool DateTime::isNormalized() const\r
+ {\r
+ return (fValue[XMLDateTime::utc] == XMLDateTime::UTC_STD ? true : false);\r
+ }\r
+ \r
+ inline int DateTime::getRetVal(int c1, int c2)\r
+ {\r
+ if ((c1 == XMLDateTime::LESS_THAN && c2 == XMLDateTime::GREATER_THAN) ||\r
+ (c1 == XMLDateTime::GREATER_THAN && c2 == XMLDateTime::LESS_THAN))\r
+ return XMLDateTime::INDETERMINATE;\r
+ \r
+ return (c1 != XMLDateTime::INDETERMINATE) ? c1 : c2;\r
+ }\r
+\r
+}\r
+\r
+#endif\r
Name="util"\r
>\r
<File\r
+ RelativePath=".\util\DateTime.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\util\NDC.cpp"\r
>\r
</File>\r
Name="util"\r
>\r
<File\r
+ RelativePath=".\util\DateTime.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\util\NDC.h"\r
>\r
</File>\r