kabc Library API Documentation

ldif.cpp

00001 /* 00002 This file is part of libkabc. 00003 Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <kdebug.h> 00022 #include <kmdcodec.h> 00023 00024 #include "ldif.h" 00025 00026 using namespace KABC; 00027 00028 LDIF::LDIF() 00029 { 00030 startParsing(); 00031 } 00032 00033 LDIF::~LDIF() 00034 { 00035 } 00036 00037 QCString LDIF::assembleLine( const QString &fieldname, const QByteArray &value, 00038 uint linelen, bool url ) 00039 { 00040 bool safe = false; 00041 bool isDn; 00042 QCString result; 00043 uint i; 00044 00045 if ( url ) { 00046 result = fieldname.utf8() + ":< " + QCString( value.data(), value.size()+1 ); 00047 } else { 00048 isDn = fieldname.lower() == "dn"; 00049 //SAFE-INIT-CHAR 00050 if ( value.size() > 0 && value[0] > 0 && value[0] != '\n' && 00051 value[0] != '\r' && value[0] != ':' && value[0] != '<' ) safe = true; 00052 00053 //SAFE-CHAR 00054 if ( safe ) { 00055 for ( i=1; i < value.size(); i++ ) { 00056 //allow utf-8 in Distinguished Names 00057 if ( ( isDn && value[i] == 0 ) || 00058 ( !isDn && value[i] <= 0 ) || 00059 value[i] == '\r' || value[i] == '\n' ) { 00060 safe = false; 00061 break; 00062 } 00063 } 00064 } 00065 00066 if ( value.size() == 0 ) safe = true; 00067 00068 if( safe ) { 00069 result = fieldname.utf8() + ": " + QCString( value.data(), value.size()+1 ); 00070 } else { 00071 result = fieldname.utf8() + ":: " + KCodecs::base64Encode( value, false ); 00072 } 00073 00074 if ( linelen > 0 ) { 00075 i = (fieldname.length()+2) > linelen ? fieldname.length()+2 : linelen; 00076 while ( i < result.length() ) { 00077 result.insert( i, "\n " ); 00078 i += linelen+2; 00079 } 00080 } 00081 } 00082 return result; 00083 } 00084 00085 QCString LDIF::assembleLine( const QString &fieldname, const QCString &value, 00086 uint linelen, bool url ) 00087 { 00088 QCString ret; 00089 QByteArray tmp; 00090 uint valuelen = value.length(); 00091 tmp.setRawData( value, valuelen ); 00092 ret = assembleLine( fieldname, tmp, linelen, url ); 00093 tmp.resetRawData( value, valuelen ); 00094 return ret; 00095 00096 } 00097 00098 QCString LDIF::assembleLine( const QString &fieldname, const QString &value, 00099 uint linelen, bool url ) 00100 { 00101 return assembleLine( fieldname, value.utf8(), linelen, url ); 00102 } 00103 00104 bool LDIF::splitLine( const QCString &line, QString &fieldname, QByteArray &value ) 00105 { 00106 int position; 00107 QByteArray tmp; 00108 int linelen; 00109 00110 // kdDebug(5700) << "splitLine line: " << QString::fromUtf8(line) << endl; 00111 00112 position = line.find( ":" ); 00113 if ( position == -1 ) { 00114 // strange: we did not find a fieldname 00115 fieldname = ""; 00116 QCString str; 00117 str = line.stripWhiteSpace(); 00118 linelen = str.length(); 00119 tmp.setRawData( str.data(), linelen ); 00120 value = tmp.copy(); 00121 tmp.resetRawData( str.data(), linelen ); 00122 // kdDebug(5700) << "value : " << value[0] << endl; 00123 return false; 00124 } 00125 00126 linelen = line.length(); 00127 00128 if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) { 00129 // String is BASE64 encoded -> decode it now. 00130 fieldname = QString::fromUtf8( 00131 line.left( position ).stripWhiteSpace() ); 00132 if ( linelen <= ( position + 3 ) ) { 00133 value.resize( 0 ); 00134 return false; 00135 } 00136 tmp.setRawData( &line.data()[ position + 3 ], linelen - position - 3 ); 00137 KCodecs::base64Decode( tmp, value ); 00138 tmp.resetRawData( &line.data()[ position + 3 ], linelen - position - 3 ); 00139 return false; 00140 } 00141 00142 if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) { 00143 // String is an URL. 00144 fieldname = QString::fromUtf8( 00145 line.left( position ).stripWhiteSpace() ); 00146 if ( linelen <= ( position + 3 ) ) { 00147 value.resize( 0 ); 00148 return false; 00149 } 00150 tmp.setRawData( &line.data()[ position + 3 ], linelen - position - 3 ); 00151 value = tmp.copy(); 00152 tmp.resetRawData( &line.data()[ position + 3 ], linelen - position - 3 ); 00153 return true; 00154 } 00155 00156 fieldname = QString::fromUtf8(line.left( position ).stripWhiteSpace()); 00157 if ( linelen <= ( position + 2 ) ) { 00158 value.resize( 0 ); 00159 return false; 00160 } 00161 tmp.setRawData( &line.data()[ position + 2 ], linelen - position - 2 ); 00162 value = tmp.copy(); 00163 tmp.resetRawData( &line.data()[ position + 2 ], linelen - position - 2 ); 00164 return false; 00165 } 00166 00167 bool LDIF::splitControl( const QCString &line, QString &oid, bool &critical, 00168 QByteArray &value ) 00169 { 00170 QString tmp; 00171 critical = false; 00172 bool url = splitLine( line, tmp, value ); 00173 00174 kdDebug(5700) << "splitControl: value: " << QString::fromUtf8(value, value.size()) << endl; 00175 if ( tmp.isEmpty() ) { 00176 tmp = QString::fromUtf8( value, value.size() ); 00177 value.resize( 0 ); 00178 } 00179 if ( tmp.right( 4 ) == "true" ) { 00180 critical = true; 00181 tmp.truncate( tmp.length() - 5 ); 00182 } else if ( tmp.right( 5 ) == "false" ) { 00183 critical = false; 00184 tmp.truncate( tmp.length() - 6 ); 00185 } 00186 oid = tmp; 00187 return url; 00188 } 00189 00190 LDIF::ParseVal LDIF::processLine() 00191 { 00192 00193 if ( mIsComment ) return None; 00194 00195 ParseVal retval = None; 00196 if ( mLastParseVal == EndEntry ) mEntryType = Entry_None; 00197 00198 mUrl = splitLine( line, mAttr, mVal ); 00199 00200 QString attrLower = mAttr.lower(); 00201 00202 switch ( mEntryType ) { 00203 case Entry_None: 00204 if ( attrLower == "version" ) { 00205 if ( !mDn.isEmpty() ) retval = Err; 00206 } else if ( attrLower == "dn" ) { 00207 kdDebug(5700) << "ldapentry dn: " << QString::fromUtf8( mVal, mVal.size() ) << endl; 00208 mDn = QString::fromUtf8( mVal, mVal.size() ); 00209 mModType = Mod_None; 00210 retval = NewEntry; 00211 } else if ( attrLower == "changetype" ) { 00212 if ( mDn.isEmpty() ) 00213 retval = Err; 00214 else { 00215 QString tmpval = QString::fromUtf8( mVal, mVal.size() ); 00216 kdDebug(5700) << "changetype: " << tmpval << endl; 00217 if ( tmpval == "add" ) mEntryType = Entry_Add; 00218 else if ( tmpval == "delete" ) mEntryType = Entry_Del; 00219 else if ( tmpval == "modrdn" || tmpval == "moddn" ) { 00220 mNewRdn = ""; 00221 mNewSuperior = ""; 00222 mDelOldRdn = true; 00223 mEntryType = Entry_Modrdn; 00224 } 00225 else if ( tmpval == "modify" ) mEntryType = Entry_Mod; 00226 else retval = Err; 00227 } 00228 } else if ( attrLower == "control" ) { 00229 mUrl = splitControl( QCString( mVal, mVal.size() + 1 ), mOid, mCritical, mVal ); 00230 retval = Control; 00231 } else if ( !mAttr.isEmpty() && mVal.size() > 0 ) { 00232 mEntryType = Entry_Add; 00233 retval = Item; 00234 } 00235 break; 00236 case Entry_Add: 00237 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00238 retval = EndEntry; 00239 else 00240 retval = Item; 00241 break; 00242 case Entry_Del: 00243 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00244 retval = EndEntry; 00245 else 00246 retval = Err; 00247 break; 00248 case Entry_Mod: 00249 if ( mModType == Mod_None ) { 00250 kdDebug(5700) << "kio_ldap: new modtype " << mAttr << endl; 00251 if ( mAttr.isEmpty() && mVal.size() == 0 ) { 00252 retval = EndEntry; 00253 } else if ( attrLower == "add" ) { 00254 mModType = Mod_Add; 00255 } else if ( attrLower == "replace" ) { 00256 mModType = Mod_Replace; 00257 mAttr = QString::fromUtf8( mVal, mVal.size() ); 00258 mVal.resize( 0 ); 00259 retval = Item; 00260 } else if ( attrLower == "delete" ) { 00261 mModType = Mod_Del; 00262 mAttr = QString::fromUtf8( mVal, mVal.size() ); 00263 mVal.resize( 0 ); 00264 retval = Item; 00265 } else { 00266 retval = Err; 00267 } 00268 } else { 00269 if ( mAttr.isEmpty() ) { 00270 if ( QString::fromUtf8( mVal, mVal.size() ) == "-" ) { 00271 mModType = Mod_None; 00272 } else if ( mVal.size() == 0 ) { 00273 retval = EndEntry; 00274 } else 00275 retval = Err; 00276 } else 00277 retval = Item; 00278 } 00279 break; 00280 case Entry_Modrdn: 00281 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00282 retval = EndEntry; 00283 else if ( attrLower == "newrdn" ) 00284 mNewRdn = QString::fromUtf8( mVal, mVal.size() ); 00285 else if ( attrLower == "newsuperior" ) 00286 mNewSuperior = QString::fromUtf8( mVal, mVal.size() ); 00287 else if ( attrLower == "deleteoldrdn" ) { 00288 if ( mVal.size() > 0 && mVal[0] == '0' ) 00289 mDelOldRdn = false; 00290 else if ( mVal.size() > 0 && mVal[0] == '1' ) 00291 mDelOldRdn = true; 00292 else 00293 retval = Err; 00294 } else 00295 retval = Err; 00296 break; 00297 } 00298 return retval; 00299 } 00300 00301 LDIF::ParseVal LDIF::nextItem() 00302 { 00303 ParseVal retval = None; 00304 char c=0; 00305 00306 while( retval == None ) { 00307 if ( mPos < mLdif.size() ) { 00308 c = mLdif[mPos]; 00309 mPos++; 00310 if ( mIsNewLine && c == '\r' ) continue; //handle \n\r line end 00311 if ( mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding 00312 mIsNewLine = false; 00313 continue; 00314 } 00315 if ( mIsNewLine ) { 00316 mIsNewLine = false; 00317 retval = processLine(); 00318 mLastParseVal = retval; 00319 line.resize( 0 ); 00320 mIsComment = ( c == '#' ); 00321 } 00322 if ( c == '\n' || c == '\r' ) { 00323 mLineNo++; 00324 mIsNewLine = true; 00325 continue; 00326 } 00327 } else { 00328 retval = MoreData; 00329 break; 00330 } 00331 00332 if ( !mIsComment ) line += c; 00333 } 00334 return retval; 00335 } 00336 00337 void LDIF::endLDIF() 00338 { 00339 mLdif.resize( 3 ); 00340 mLdif[ 0 ] = '\n'; 00341 mLdif[ 1 ] = '\n'; 00342 mLdif[ 2 ] = '\n'; 00343 mPos = 0; 00344 } 00345 00346 void LDIF::startParsing() 00347 { 00348 mPos = mLineNo = 0; 00349 mDelOldRdn = false; 00350 mEntryType = Entry_None; 00351 mModType = Mod_None; 00352 mDn = mNewRdn = mNewSuperior = ""; 00353 line = ""; 00354 mIsNewLine = false; 00355 mIsComment = false; 00356 mLastParseVal = None; 00357 }
KDE Logo
This file is part of the documentation for kabc Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:44:37 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003