]> git.sur5r.net Git - openldap/commitdiff
Initial code for Ldif classes
authorRalf Haferkamp <ralf@openldap.org>
Mon, 17 Mar 2008 16:08:51 +0000 (16:08 +0000)
committerRalf Haferkamp <ralf@openldap.org>
Mon, 17 Mar 2008 16:08:51 +0000 (16:08 +0000)
contrib/ldapc++/src/LDAPMessage.h
contrib/ldapc++/src/LdifReader.cpp [new file with mode: 0644]
contrib/ldapc++/src/LdifReader.h [new file with mode: 0644]

index b5a06958e06992953f4b8bdc23063640698dd76c..cf88bac1298dd5fd1c9ad636c6b0a591d4331bf3 100644 (file)
@@ -21,7 +21,7 @@ class LDAPRequest;
  */
 class LDAPMsg{
     public:
-        //public Constants defining the Message types
+        //public Constants defining the response message types
         static const int BIND_RESPONSE=LDAP_RES_BIND;
         static const int SEARCH_ENTRY=LDAP_RES_SEARCH_ENTRY;
         static const int SEARCH_DONE=LDAP_RES_SEARCH_RESULT;
@@ -32,6 +32,17 @@ class LDAPMsg{
         static const int MODDN_RESPONSE=LDAP_RES_MODDN;
         static const int COMPARE_RESPONSE=LDAP_RES_COMPARE;
         static const int EXTENDED_RESPONSE=LDAP_RES_EXTENDED;
+        //public Constants defining the request message types
+        static const int BIND_REQUEST=LDAP_REQ_BIND;
+        static const int UNBIND_REQUEST=LDAP_REQ_UNBIND;
+        static const int SEARCH_REQUEST=LDAP_REQ_SEARCH;
+        static const int MODIFY_REQUEST=LDAP_REQ_MODIFY;
+        static const int ADD_REQUEST=LDAP_REQ_ADD;
+        static const int DELETE_REQUEST=LDAP_REQ_DELETE;
+        static const int MODRDN_REQUEST=LDAP_REQ_MODRDN;
+        static const int COMPARE_REQUEST=LDAP_REQ_COMPARE;
+        static const int ABANDON_REQUEST=LDAP_REQ_ABANDON;
+        static const int EXTENDED_REQUEST=LDAP_REQ_EXTENDED;
        
         /**
          * The destructor has no implemenation, because this is an abstract
diff --git a/contrib/ldapc++/src/LdifReader.cpp b/contrib/ldapc++/src/LdifReader.cpp
new file mode 100644 (file)
index 0000000..1ccd43b
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2008, OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "LdifReader.h"
+#include "LDAPMessage.h"
+#include "LDAPEntry.h"
+#include "LDAPAttributeList.h"
+#include "LDAPAttribute.h"
+#include "LDAPUrl.h"
+#include "debug.h"
+
+#include <string>
+
+#include <sasl/saslutil.h> // For base64 routines
+
+LdifReader::LdifReader( std::istream &input ) : m_ldifstream(input)
+{
+    DEBUG(LDAP_DEBUG_TRACE, "<> LdifReader::LdifReader()" << std::endl);
+}
+
+int LdifReader::readNextRecord()
+{
+    DEBUG(LDAP_DEBUG_TRACE, "-> LdifReader::readRecord()" << std::endl);
+    std::string line;
+    std::string type;
+    std::string value;
+    int numLine = 0;
+    int recordType = 0;
+    m_currentRecord.clear();
+
+    while ( !this->getLdifLine(line) && line != "" )
+    {
+        DEBUG(LDAP_DEBUG_TRACE, "  Line: " << line << std::endl );
+        int rc = this->splitLine(line, type, value);
+        if ( rc )
+        {
+            DEBUG(LDAP_DEBUG_TRACE, " Error while splitting ldif line" 
+                    << std::endl);
+        }
+        if ( numLine == 0 )
+        {
+            if ( type == "dn" ) // Record should start with the DN ...
+            {
+                DEBUG(LDAP_DEBUG_TRACE, " Record DN:" << value << std::endl);
+            }
+            else if ( type == "include" ) // ... or it might be an "include" line
+            {
+                DEBUG(LDAP_DEBUG_TRACE, " Include directive: " << value << std::endl);
+                //this->readIncludeLine(value);
+            }
+            else
+            {
+                DEBUG(LDAP_DEBUG_TRACE, " Record doesn't start with a DN" 
+                            << std::endl);
+                return 0;
+            }
+        }
+        if ( numLine == 1 ) // might contain "changtype" to indicate a change request
+        {
+            if ( type == "changetype" ) 
+            {
+                if ( value == "modify" )
+                {
+                    recordType = LDAPMsg::MODIFY_REQUEST;
+                }
+                else if ( value == "add" )
+                {
+                    recordType = LDAPMsg::ADD_REQUEST;
+                }
+                else if ( value == "delete" )
+                {
+                    recordType = LDAPMsg::DELETE_REQUEST;
+                }
+                else if ( value == "modrdn" )
+                {   
+                    recordType = LDAPMsg::MODRDN_REQUEST;
+                }
+                else
+                {
+                    DEBUG(LDAP_DEBUG_TRACE, " Unknown change request <" << value << ">" << std::endl);
+                    return 0;
+                }
+            }
+            else
+            {
+                recordType = LDAPMsg::SEARCH_ENTRY;
+            }
+        }
+        m_currentRecord.push_back(std::pair<std::string, std::string>(type, value));
+        numLine++;
+    }
+    DEBUG(LDAP_DEBUG_TRACE, "<- LdifReader::readRecord()" << std::endl);
+    m_curRecType = recordType;
+    return recordType;
+}
+
+LDAPEntry LdifReader::getEntryRecord()
+{
+    if ( m_curRecType != LDAPMsg::SEARCH_ENTRY )
+    {
+        // Error
+    }
+    std::list<std::pair<std::string, std::string> >::const_iterator i = m_currentRecord.begin();
+    LDAPEntry resEntry(i->second);
+    i++;
+    LDAPAttribute curAttr(i->first);
+    LDAPAttributeList *curAl = new LDAPAttributeList();
+    for ( ; i != m_currentRecord.end(); i++ )
+    {
+        if ( i->first == curAttr.getName() )
+        {
+            curAttr.addValue(i->second);
+        }
+        else
+        {
+            if ( curAl->getAttributeByName( i->first ) ) 
+                    // Attribute exists already -> Syntax Error
+            {
+                // Error
+            }
+            else
+            {
+                curAl->addAttribute( curAttr );
+                curAttr = LDAPAttribute( i->first, i->second );
+            }
+        }
+    }
+    curAl->addAttribute( curAttr );
+    resEntry.setAttributes( curAl );
+    return resEntry;
+}
+
+int LdifReader::getLdifLine(std::string &ldifline)
+{
+    DEBUG(LDAP_DEBUG_TRACE, "-> LdifReader::getLdifLine()" << std::endl);
+
+    if ( ! getline(m_ldifstream, ldifline) )
+    {
+        return -1;
+    }
+
+    while ( m_ldifstream &&
+        (m_ldifstream.peek() == ' ' || m_ldifstream.peek() == '\t'))
+    {
+        std::string cat;
+        m_ldifstream.ignore();
+        getline(m_ldifstream, cat);
+        ldifline += cat;
+    }
+
+    DEBUG(LDAP_DEBUG_TRACE, "<- LdifReader::getLdifLine()" << std::endl);
+    return 0;
+}
+
+int LdifReader::splitLine(const std::string& line, 
+            std::string &type,
+            std::string &value)
+{
+    std::string::size_type pos = line.find(':');
+    if ( pos == std::string::npos )
+    {
+        DEBUG(LDAP_DEBUG_ANY, "Invalid LDIF line. Not `:` separator" 
+                << std::endl );
+        return -1;
+    }
+    type = line.substr(0, pos);
+    if ( pos == line.size() )
+    {
+        // empty value
+        value = "";
+        return 0;
+    }
+    pos++;
+    char delim = line[pos];
+    if ( delim == ':' || delim == '<' )
+    {
+        pos++;
+    }
+    for( ; pos < line.size() && isspace(line[pos]); pos++ )
+    { /* empty */ }
+
+    value = line.substr(pos);
+
+    if ( delim == ':' )
+    {
+        // Base64 encoded value
+        DEBUG(LDAP_DEBUG_TRACE, "  base64 encoded value" << std::endl );
+        char outbuf[value.size()];
+        int rc = sasl_decode64(value.c_str(), value.size(), 
+                outbuf, value.size(), NULL);
+        if( rc == SASL_OK )
+        {
+            value = std::string(outbuf);
+        }
+        else if ( rc == SASL_BADPROT )
+        {
+            value = "";
+            DEBUG( LDAP_DEBUG_TRACE, " invalid base64 content" << std::endl );
+            return -1;
+        }
+        else if ( rc == SASL_BUFOVER )
+        {
+            value = "";
+            DEBUG( LDAP_DEBUG_TRACE, " not enough space in output buffer" 
+                    << std::endl );
+            return -1;
+        }
+    }
+    else if ( delim == '<' )
+    {
+        // URL value
+        DEBUG(LDAP_DEBUG_TRACE, "  url value" << std::endl );
+        return -1;
+    }
+    else 
+    {
+        // "normal" value
+        DEBUG(LDAP_DEBUG_TRACE, "  string value" << std::endl );
+    }
+    DEBUG(LDAP_DEBUG_TRACE, "  Type: <" << type << ">" << std::endl );
+    DEBUG(LDAP_DEBUG_TRACE, "  Value: <" << value << ">" << std::endl );
+    return 0;
+}
+
+std::string LdifReader::readIncludeLine( const std::string& line ) const
+{
+    std::string::size_type pos = sizeof("file:") - 1;
+    std::string scheme = line.substr( 0, pos );
+    std::string file;
+
+    // only file:// URLs supported currently
+    if ( scheme != "file:" )
+    {
+        DEBUG( LDAP_DEBUG_TRACE, "unsupported scheme: " << scheme 
+                << std::endl);
+    }
+    else if ( line[pos] == '/' )
+    {
+        if ( line[pos+1] == '/' )
+        {
+            pos += 2;
+        }
+        file = line.substr(pos, std::string::npos);
+        DEBUG( LDAP_DEBUG_TRACE, "target file: " << file << std::endl);
+    }
+    return file;
+}
diff --git a/contrib/ldapc++/src/LdifReader.h b/contrib/ldapc++/src/LdifReader.h
new file mode 100644 (file)
index 0000000..3b6c721
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008, OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#ifndef LDIF_READER_H
+#define LDIF_READER_H
+
+#include <LDAPEntry.h>
+#include <iosfwd>
+#include <list>
+
+typedef std::list< std::pair<std::string, std::string> > LdifRecord;
+class LdifReader
+{
+    public:
+        LdifReader( std::istream &input );
+        int readNextRecord();
+        LDAPEntry getEntryRecord();
+
+    private:
+        int getLdifLine(std::string &line);
+
+        int splitLine(const std::string& line, 
+                    std::string &type,
+                    std::string &value );
+
+        std::string readIncludeLine( const std::string &line) const;
+
+        std::istream &m_ldifstream;
+        LdifRecord m_currentRecord;
+        int m_curRecType;
+};
+
+#endif /* LDIF_READER_H */