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 const char *data = value.data(); 00092 00093 tmp.setRawData( data, valuelen ); 00094 ret = assembleLine( fieldname, tmp, linelen, url ); 00095 tmp.resetRawData( data, valuelen ); 00096 return ret; 00097 00098 } 00099 00100 QCString LDIF::assembleLine( const QString &fieldname, const QString &value, 00101 uint linelen, bool url ) 00102 { 00103 return assembleLine( fieldname, value.utf8(), linelen, url ); 00104 } 00105 00106 bool LDIF::splitLine( const QCString &line, QString &fieldname, QByteArray &value ) 00107 { 00108 int position; 00109 QByteArray tmp; 00110 int linelen; 00111 const char *data; 00112 00113 // kdDebug(5700) << "splitLine line: " << QString::fromUtf8(line) << endl; 00114 00115 position = line.find( ":" ); 00116 if ( position == -1 ) { 00117 // strange: we did not find a fieldname 00118 fieldname = ""; 00119 QCString str; 00120 str = line.stripWhiteSpace(); 00121 linelen = str.length(); 00122 data = str.data(); 00123 tmp.setRawData( data, linelen ); 00124 value = tmp.copy(); 00125 tmp.resetRawData( data, linelen ); 00126 // kdDebug(5700) << "value : " << value[0] << endl; 00127 return false; 00128 } 00129 00130 linelen = line.length(); 00131 00132 if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) { 00133 // String is BASE64 encoded -> decode it now. 00134 fieldname = QString::fromUtf8( 00135 line.left( position ).stripWhiteSpace() ); 00136 if ( linelen <= ( position + 3 ) ) { 00137 value.resize( 0 ); 00138 return false; 00139 } 00140 data = &line.data()[ position + 3 ]; 00141 tmp.setRawData( data, linelen - position - 3 ); 00142 KCodecs::base64Decode( tmp, value ); 00143 tmp.resetRawData( data, linelen - position - 3 ); 00144 return false; 00145 } 00146 00147 if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) { 00148 // String is an URL. 00149 fieldname = QString::fromUtf8( 00150 line.left( position ).stripWhiteSpace() ); 00151 if ( linelen <= ( position + 3 ) ) { 00152 value.resize( 0 ); 00153 return false; 00154 } 00155 data = &line.data()[ position + 3]; 00156 tmp.setRawData( data, linelen - position - 3 ); 00157 value = tmp.copy(); 00158 tmp.resetRawData( data, linelen - position - 3 ); 00159 return true; 00160 } 00161 00162 fieldname = QString::fromUtf8(line.left( position ).stripWhiteSpace()); 00163 if ( linelen <= ( position + 2 ) ) { 00164 value.resize( 0 ); 00165 return false; 00166 } 00167 data = &line.data()[ position + 2 ]; 00168 tmp.setRawData( data, linelen - position - 2 ); 00169 value = tmp.copy(); 00170 tmp.resetRawData( data, linelen - position - 2 ); 00171 return false; 00172 } 00173 00174 bool LDIF::splitControl( const QCString &line, QString &oid, bool &critical, 00175 QByteArray &value ) 00176 { 00177 QString tmp; 00178 critical = false; 00179 bool url = splitLine( line, tmp, value ); 00180 00181 kdDebug(5700) << "splitControl: value: " << QString::fromUtf8(value, value.size()) << endl; 00182 if ( tmp.isEmpty() ) { 00183 tmp = QString::fromUtf8( value, value.size() ); 00184 value.resize( 0 ); 00185 } 00186 if ( tmp.right( 4 ) == "true" ) { 00187 critical = true; 00188 tmp.truncate( tmp.length() - 5 ); 00189 } else if ( tmp.right( 5 ) == "false" ) { 00190 critical = false; 00191 tmp.truncate( tmp.length() - 6 ); 00192 } 00193 oid = tmp; 00194 return url; 00195 } 00196 00197 LDIF::ParseVal LDIF::processLine() 00198 { 00199 00200 if ( mIsComment ) return None; 00201 00202 ParseVal retval = None; 00203 if ( mLastParseVal == EndEntry ) mEntryType = Entry_None; 00204 00205 mUrl = splitLine( line, mAttr, mVal ); 00206 00207 QString attrLower = mAttr.lower(); 00208 00209 switch ( mEntryType ) { 00210 case Entry_None: 00211 if ( attrLower == "version" ) { 00212 if ( !mDn.isEmpty() ) retval = Err; 00213 } else if ( attrLower == "dn" ) { 00214 kdDebug(5700) << "ldapentry dn: " << QString::fromUtf8( mVal, mVal.size() ) << endl; 00215 mDn = QString::fromUtf8( mVal, mVal.size() ); 00216 mModType = Mod_None; 00217 retval = NewEntry; 00218 } else if ( attrLower == "changetype" ) { 00219 if ( mDn.isEmpty() ) 00220 retval = Err; 00221 else { 00222 QString tmpval = QString::fromUtf8( mVal, mVal.size() ); 00223 kdDebug(5700) << "changetype: " << tmpval << endl; 00224 if ( tmpval == "add" ) mEntryType = Entry_Add; 00225 else if ( tmpval == "delete" ) mEntryType = Entry_Del; 00226 else if ( tmpval == "modrdn" || tmpval == "moddn" ) { 00227 mNewRdn = ""; 00228 mNewSuperior = ""; 00229 mDelOldRdn = true; 00230 mEntryType = Entry_Modrdn; 00231 } 00232 else if ( tmpval == "modify" ) mEntryType = Entry_Mod; 00233 else retval = Err; 00234 } 00235 } else if ( attrLower == "control" ) { 00236 mUrl = splitControl( QCString( mVal, mVal.size() + 1 ), mOid, mCritical, mVal ); 00237 retval = Control; 00238 } else if ( !mAttr.isEmpty() && mVal.size() > 0 ) { 00239 mEntryType = Entry_Add; 00240 retval = Item; 00241 } 00242 break; 00243 case Entry_Add: 00244 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00245 retval = EndEntry; 00246 else 00247 retval = Item; 00248 break; 00249 case Entry_Del: 00250 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00251 retval = EndEntry; 00252 else 00253 retval = Err; 00254 break; 00255 case Entry_Mod: 00256 if ( mModType == Mod_None ) { 00257 kdDebug(5700) << "kio_ldap: new modtype " << mAttr << endl; 00258 if ( mAttr.isEmpty() && mVal.size() == 0 ) { 00259 retval = EndEntry; 00260 } else if ( attrLower == "add" ) { 00261 mModType = Mod_Add; 00262 } else if ( attrLower == "replace" ) { 00263 mModType = Mod_Replace; 00264 mAttr = QString::fromUtf8( mVal, mVal.size() ); 00265 mVal.resize( 0 ); 00266 retval = Item; 00267 } else if ( attrLower == "delete" ) { 00268 mModType = Mod_Del; 00269 mAttr = QString::fromUtf8( mVal, mVal.size() ); 00270 mVal.resize( 0 ); 00271 retval = Item; 00272 } else { 00273 retval = Err; 00274 } 00275 } else { 00276 if ( mAttr.isEmpty() ) { 00277 if ( QString::fromUtf8( mVal, mVal.size() ) == "-" ) { 00278 mModType = Mod_None; 00279 } else if ( mVal.size() == 0 ) { 00280 retval = EndEntry; 00281 } else 00282 retval = Err; 00283 } else 00284 retval = Item; 00285 } 00286 break; 00287 case Entry_Modrdn: 00288 if ( mAttr.isEmpty() && mVal.size() == 0 ) 00289 retval = EndEntry; 00290 else if ( attrLower == "newrdn" ) 00291 mNewRdn = QString::fromUtf8( mVal, mVal.size() ); 00292 else if ( attrLower == "newsuperior" ) 00293 mNewSuperior = QString::fromUtf8( mVal, mVal.size() ); 00294 else if ( attrLower == "deleteoldrdn" ) { 00295 if ( mVal.size() > 0 && mVal[0] == '0' ) 00296 mDelOldRdn = false; 00297 else if ( mVal.size() > 0 && mVal[0] == '1' ) 00298 mDelOldRdn = true; 00299 else 00300 retval = Err; 00301 } else 00302 retval = Err; 00303 break; 00304 } 00305 return retval; 00306 } 00307 00308 LDIF::ParseVal LDIF::nextItem() 00309 { 00310 ParseVal retval = None; 00311 char c=0; 00312 00313 while( retval == None ) { 00314 if ( mPos < mLdif.size() ) { 00315 c = mLdif[mPos]; 00316 mPos++; 00317 if ( mIsNewLine && c == '\r' ) continue; //handle \n\r line end 00318 if ( mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding 00319 mIsNewLine = false; 00320 continue; 00321 } 00322 if ( mIsNewLine ) { 00323 mIsNewLine = false; 00324 retval = processLine(); 00325 mLastParseVal = retval; 00326 line.resize( 0 ); 00327 mIsComment = ( c == '#' ); 00328 } 00329 if ( c == '\n' || c == '\r' ) { 00330 mLineNo++; 00331 mIsNewLine = true; 00332 continue; 00333 } 00334 } else { 00335 retval = MoreData; 00336 break; 00337 } 00338 00339 if ( !mIsComment ) line += c; 00340 } 00341 return retval; 00342 } 00343 00344 void LDIF::endLDIF() 00345 { 00346 QByteArray tmp( 3 ); 00347 tmp[ 0 ] = '\n'; 00348 tmp[ 1 ] = '\n'; 00349 tmp[ 2 ] = '\n'; 00350 mLdif = tmp; 00351 mPos = 0; 00352 } 00353 00354 void LDIF::startParsing() 00355 { 00356 mPos = mLineNo = 0; 00357 mDelOldRdn = false; 00358 mEntryType = Entry_None; 00359 mModType = Mod_None; 00360 mDn = mNewRdn = mNewSuperior = ""; 00361 line = ""; 00362 mIsNewLine = false; 00363 mIsComment = false; 00364 mLastParseVal = None; 00365 }
KDE Logo
This file is part of the documentation for kabc Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 23:27:21 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003