Change license header.
[shibboleth/cpp-sp.git] / shibsp / remoting / impl / ddf.cpp
index c11a5e5..6da3947 100644 (file)
@@ -1,22 +1,26 @@
-/*
- *  Copyright 2001-2009 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
  *
- * 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
+ * UCAID licenses this file to you 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
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
  */
 
 /**
  * ddf.cpp
- * 
+ *
  * C++ DDF abstraction for interpretive RPC
  */
 
@@ -49,7 +53,7 @@ size_t ddf_strlen(const char* s)
 
 char* ddf_strdup(const char* s)
 {
-    return (s && *s) ? strdup(s) : NULL;
+    return (s && *s) ? strdup(s) : nullptr;
 }
 
 #define MAX_NAME_LEN 255
@@ -62,22 +66,19 @@ char* ddf_strdup(const char* s)
    The name buffer is returned from the function. */
 char* ddf_token(const char** path, char* name)
 {
-    const char* temp=NULL;
-    
-    *name='\0';
-    if (*path==NULL || **path=='\0')
+    *name=0;
+    if (*path==nullptr || **path==0)
         return name;
 
-    temp=strchr(*path,'.');
-    if (temp==NULL)
-    {
-        strcpy(name,*path);
-        *path=NULL;
+    const char* temp=strchr(*path,'.');
+    if (temp==nullptr) {
+        strncpy(name,*path,MAX_NAME_LEN);
+        name[MAX_NAME_LEN]=0;
+        *path=nullptr;
     }
-    else if (temp>*path)
-    {
+    else if (temp>*path) {
         strncpy(name,*path,temp-*path);
-        name[temp-*path]='\0';
+        name[temp-*path]=0;
         *path=temp+1;
     }
     else
@@ -88,7 +89,7 @@ char* ddf_token(const char** path, char* name)
 // body implementation
 
 struct shibsp::ddf_body_t {
-    ddf_body_t() : name(NULL), parent(NULL), next(NULL), prev(NULL), type(DDF_EMPTY) {}
+    ddf_body_t() : name(nullptr), parent(nullptr), next(nullptr), prev(nullptr), type(DDF_EMPTY) {}
 
     char* name;                     // name of node
     ddf_body_t* parent;             // parent node, if any
@@ -122,6 +123,10 @@ struct shibsp::ddf_body_t {
 
 // library implementation
 
+DDF::DDF() : m_handle(nullptr)
+{
+}
+
 DDF::DDF(const char* n)
 {
     m_handle=new(nothrow) ddf_body_t;
@@ -158,15 +163,15 @@ DDF::DDF(const char* n, void* val)
 
 DDF& DDF::destroy()
 {
-    remove().empty().name(NULL);
+    remove().empty().name(nullptr);
     delete m_handle;
-    m_handle=NULL;
+    m_handle=nullptr;
     return *this;
 }
 
 DDF DDF::copy() const
 {
-    if (m_handle==NULL)
+    if (m_handle==nullptr)
         return DDF();
 
     switch (m_handle->type) {
@@ -194,7 +199,7 @@ DDF DDF::copy() const
                 temp.m_handle=child;
                 DDF temp2=temp.copy();
                 copy.add(temp2);
-                if (copy.m_handle==NULL)
+                if (copy.m_handle==nullptr)
                     return copy;
                 if (m_handle->value.children.current==child)
                     copy.m_handle->value.children.current=copy.m_handle->value.children.last;
@@ -208,7 +213,7 @@ DDF DDF::copy() const
 
 const char* DDF::name() const
 {
-    return (m_handle) ? m_handle->name : NULL;
+    return (m_handle) ? m_handle->name : nullptr;
 }
 
 DDF& DDF::name(const char* name)
@@ -226,7 +231,7 @@ DDF& DDF::name(const char* name)
                 destroy();
         }
         else
-            m_handle->name=NULL;
+            m_handle->name=nullptr;
     }
     return *this;
 }
@@ -273,7 +278,7 @@ bool DDF::ispointer() const
 
 const char* DDF::string() const
 {
-    return isstring() ? m_handle->value.string : NULL;
+    return isstring() ? m_handle->value.string : nullptr;
 }
 
 long DDF::integer() const
@@ -285,6 +290,7 @@ long DDF::integer() const
             case ddf_body_t::DDF_FLOAT:
                 return static_cast<long>(m_handle->value.floating);
             case ddf_body_t::DDF_STRING:
+            case ddf_body_t::DDF_STRING_UNSAFE:
                 return m_handle->value.string ? atol(m_handle->value.string) : 0;
             case ddf_body_t::DDF_STRUCT:
             case ddf_body_t::DDF_LIST:
@@ -303,6 +309,7 @@ double DDF::floating() const
             case ddf_body_t::DDF_FLOAT:
                 return m_handle->value.floating;
             case ddf_body_t::DDF_STRING:
+            case ddf_body_t::DDF_STRING_UNSAFE:
                 return m_handle->value.string ? atof(m_handle->value.string) : 0;
             case ddf_body_t::DDF_STRUCT:
             case ddf_body_t::DDF_LIST:
@@ -314,7 +321,7 @@ double DDF::floating() const
 
 void* DDF::pointer() const
 {
-    return ispointer() ? m_handle->value.pointer : NULL;
+    return ispointer() ? m_handle->value.pointer : nullptr;
 }
 
 size_t DDF::strlen() const
@@ -324,8 +331,8 @@ size_t DDF::strlen() const
 
 bool DDF::operator==(const char* s) const
 {
-    if (string()==NULL || s==NULL)
-        return (string()==NULL && s==NULL);
+    if (string()==nullptr || s==nullptr)
+        return (string()==nullptr && s==nullptr);
     else
         return (::strcmp(string(),s)==0);
 }
@@ -335,6 +342,7 @@ DDF& DDF::empty()
     if (m_handle) {
         switch (m_handle->type) {
             case ddf_body_t::DDF_STRING:
+            case ddf_body_t::DDF_STRING_UNSAFE:
                 if (m_handle->value.string)
                     free(m_handle->value.string);
                 break;
@@ -365,6 +373,16 @@ DDF& DDF::string(char* val, bool copyit, bool safe)
     return *this;
 }
 
+DDF& DDF::string(const char* val)
+{
+    return string(const_cast<char*>(val), true);
+}
+
+DDF& DDF::unsafe_string(const char* val)
+{
+    return string(const_cast<char*>(val), true, false);
+}
+
 DDF& DDF::string(long val)
 {
     char buf[20];
@@ -421,9 +439,9 @@ DDF& DDF::structure()
 {
     if (empty().m_handle) {
         m_handle->type=ddf_body_t::DDF_STRUCT;
-        m_handle->value.children.first=NULL;
-        m_handle->value.children.last=NULL;
-        m_handle->value.children.current=NULL;
+        m_handle->value.children.first=nullptr;
+        m_handle->value.children.last=nullptr;
+        m_handle->value.children.current=nullptr;
         m_handle->value.children.count=0;
     }
     return *this;
@@ -433,9 +451,9 @@ DDF& DDF::list()
 {
     if (empty().m_handle) {
         m_handle->type=ddf_body_t::DDF_LIST;
-        m_handle->value.children.first=NULL;
-        m_handle->value.children.last=NULL;
-        m_handle->value.children.current=NULL;
+        m_handle->value.children.first=nullptr;
+        m_handle->value.children.last=nullptr;
+        m_handle->value.children.current=nullptr;
         m_handle->value.children.count=0;
     }
     return *this;
@@ -541,9 +559,9 @@ DDF& DDF::remove()
         m_handle->parent->value.children.current=m_handle->prev;
 
     m_handle->parent->value.children.count--;
-    m_handle->parent=NULL;
-    m_handle->next=NULL;
-    m_handle->prev=NULL;
+    m_handle->parent=nullptr;
+    m_handle->next=nullptr;
+    m_handle->prev=nullptr;
     return *this;
 }
 
@@ -551,7 +569,7 @@ DDF DDF::parent() const
 {
     DDF p;
 
-    p.m_handle=(m_handle ? m_handle->parent : NULL);
+    p.m_handle=(m_handle ? m_handle->parent : nullptr);
     return p;
 }
 
@@ -600,6 +618,11 @@ DDF DDF::previous()
     return p;
 }
 
+DDF DDF::operator[](const char* path) const
+{
+    return getmember(path);
+}
+
 DDF DDF::operator[](unsigned long index) const
 {
     DDF d;
@@ -617,7 +640,7 @@ DDF DDF::addmember(const char* path)
 {
     char name[MAX_NAME_LEN+1];
     const char* path_ptr=path;
-    
+
     if (m_handle && ddf_strlen(ddf_token(&path_ptr,name))>0) {
         if (!isstruct())
             structure();
@@ -645,18 +668,32 @@ DDF DDF::addmember(const char* path)
 
 DDF DDF::getmember(const char* path) const
 {
+    DDF current;
     char name[MAX_NAME_LEN+1];
     const char* path_ptr=path;
-    DDF current;
 
-    if (isstruct() && ddf_strlen(ddf_token(&path_ptr,name))>0) {
-        current.m_handle=m_handle->value.children.first;
-        while (current.m_handle && strcmp(current.m_handle->name,name)!=0)
-            current.m_handle=current.m_handle->next;
-
-        if (current.m_handle && ddf_strlen(path_ptr)>0)
-            current=current.getmember(path_ptr);
+    ddf_token(&path_ptr, name);
+    if (*name == 0)
+        return current;
+    else if (*name == '[') {
+        unsigned long i = strtoul(name+1, nullptr, 10);
+        if (islist() && i < m_handle->value.children.count)
+            current=operator[](i);
+        else if (i == 0)
+            current = *this;
+    }
+    else if (isstruct()) {
+        current.m_handle = m_handle->value.children.first;
+        while (current.m_handle && strcmp(current.m_handle->name,name) != 0)
+            current.m_handle = current.m_handle->next;
+    }
+    else if (islist()) {
+        current.m_handle = m_handle->value.children.first;
+        return current.getmember(path);
     }
+
+    if (current.m_handle && path_ptr && *path_ptr)
+        current = current.getmember(path_ptr);
     return current;
 }
 
@@ -675,7 +712,7 @@ void DDF::dump(FILE* f, int indent) const
     ddf_print_indent(f,indent);
     if (m_handle) {
         switch (m_handle->type) {
-            
+
             case ddf_body_t::DDF_EMPTY:
                 fprintf(f,"empty");
                 if (m_handle->name)
@@ -695,7 +732,7 @@ void DDF::dump(FILE* f, int indent) const
                     putc('"',f);
                 }
                 else
-                    fprintf(f,"NULL");
+                    fprintf(f,"nullptr");
                 break;
 
             case ddf_body_t::DDF_INT:
@@ -758,7 +795,7 @@ void DDF::dump(FILE* f, int indent) const
                 if (m_handle->value.pointer)
                     fprintf(f,"%p",m_handle->value.pointer);
                 else
-                    fprintf(f,"NULL");
+                    fprintf(f,"nullptr");
                 break;
 
             default:
@@ -766,7 +803,7 @@ void DDF::dump(FILE* f, int indent) const
         }
     }
     else
-        fprintf(f,"NULL");
+        fprintf(f,"nullptr");
     fprintf(f,";\n");
 }
 
@@ -800,7 +837,7 @@ void serialize(ddf_body_t* p, ostream& os, bool name_attr=true)
 {
     if (p) {
         switch (p->type) {
-            
+
             case ddf_body_t::DDF_STRING:
             case ddf_body_t::DDF_STRING_UNSAFE:
                 os << "<string";
@@ -956,8 +993,8 @@ static const XMLCh _unsafe[] =  UNICODE_LITERAL_6(u,n,s,a,f,e);
 
 DDF deserialize(DOMElement* root, bool lowercase)
 {
-    DDF obj(NULL);
-    auto_ptr_char name_val(root->getAttributeNS(NULL, _name));
+    DDF obj(nullptr);
+    auto_ptr_char name_val(root->getAttributeNS(nullptr, _name));
     if (name_val.get() && *name_val.get()) {
         if (lowercase)
             for (char* pch=const_cast<char*>(name_val.get()); *pch=tolower(*pch); pch++);
@@ -973,7 +1010,7 @@ DDF deserialize(DOMElement* root, bool lowercase)
     if (XMLString::equals(tag,_string)) {
         DOMNode* child=root->getFirstChild();
         if (child && child->getNodeType()==DOMNode::TEXT_NODE) {
-            const XMLCh* unsafe = root->getAttributeNS(NULL, _unsafe);
+            const XMLCh* unsafe = root->getAttributeNS(nullptr, _unsafe);
             if (unsafe && *unsafe==chDigit_1) {
                 // If it's unsafe, it's not UTF-8 data, so we have to convert to ASCII and decode it.
                 char* encoded = XMLString::transcode(child->getNodeValue());
@@ -983,8 +1020,7 @@ DDF deserialize(DOMElement* root, bool lowercase)
             }
             else {
                 char* val = toUTF8(child->getNodeValue(), true);    // use malloc
-                if (val)
-                    obj.string(val, false); // don't re-copy the string
+                obj.string(val, false); // don't re-copy the string
             }
         }
     }