From ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kabc/vcardparser/Makefile.am | 31 ++++ kabc/vcardparser/README.testing | 15 ++ kabc/vcardparser/checkvcard.pl | 75 ++++++++ kabc/vcardparser/testread.cpp | 89 ++++++++++ kabc/vcardparser/testread2.cpp | 42 +++++ kabc/vcardparser/tests/vcard1.vcf | 13 ++ kabc/vcardparser/tests/vcard1.vcf.ref | 15 ++ kabc/vcardparser/tests/vcard2.vcf | 11 ++ kabc/vcardparser/tests/vcard2.vcf.ref | 12 ++ kabc/vcardparser/tests/vcard3.vcf | 11 ++ kabc/vcardparser/tests/vcard3.vcf.ref | 12 ++ kabc/vcardparser/tests/vcard4.vcf | 14 ++ kabc/vcardparser/tests/vcard4.vcf.ref | 14 ++ kabc/vcardparser/tests/vcard5.vcf | 313 ++++++++++++++++++++++++++++++++++ kabc/vcardparser/tests/vcard5.vcf.ref | 313 ++++++++++++++++++++++++++++++++++ kabc/vcardparser/tests/vcard6.vcf | 10 ++ kabc/vcardparser/tests/vcard6.vcf.ref | 10 ++ kabc/vcardparser/tests/vcard7.vcf | 7 + kabc/vcardparser/tests/vcard7.vcf.ref | 8 + kabc/vcardparser/testutils.cpp | 99 +++++++++++ kabc/vcardparser/testutils.h | 14 ++ kabc/vcardparser/testwrite.cpp | 134 +++++++++++++++ kabc/vcardparser/vcard.cpp | 109 ++++++++++++ kabc/vcardparser/vcard.h | 91 ++++++++++ kabc/vcardparser/vcardline.cpp | 151 ++++++++++++++++ kabc/vcardparser/vcardline.h | 115 +++++++++++++ kabc/vcardparser/vcardparser.cpp | 287 +++++++++++++++++++++++++++++++ kabc/vcardparser/vcardparser.h | 44 +++++ 28 files changed, 2059 insertions(+) create mode 100644 kabc/vcardparser/Makefile.am create mode 100644 kabc/vcardparser/README.testing create mode 100755 kabc/vcardparser/checkvcard.pl create mode 100644 kabc/vcardparser/testread.cpp create mode 100644 kabc/vcardparser/testread2.cpp create mode 100644 kabc/vcardparser/tests/vcard1.vcf create mode 100644 kabc/vcardparser/tests/vcard1.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard2.vcf create mode 100644 kabc/vcardparser/tests/vcard2.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard3.vcf create mode 100644 kabc/vcardparser/tests/vcard3.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard4.vcf create mode 100644 kabc/vcardparser/tests/vcard4.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard5.vcf create mode 100644 kabc/vcardparser/tests/vcard5.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard6.vcf create mode 100644 kabc/vcardparser/tests/vcard6.vcf.ref create mode 100644 kabc/vcardparser/tests/vcard7.vcf create mode 100644 kabc/vcardparser/tests/vcard7.vcf.ref create mode 100644 kabc/vcardparser/testutils.cpp create mode 100644 kabc/vcardparser/testutils.h create mode 100644 kabc/vcardparser/testwrite.cpp create mode 100644 kabc/vcardparser/vcard.cpp create mode 100644 kabc/vcardparser/vcard.h create mode 100644 kabc/vcardparser/vcardline.cpp create mode 100644 kabc/vcardparser/vcardline.h create mode 100644 kabc/vcardparser/vcardparser.cpp create mode 100644 kabc/vcardparser/vcardparser.h (limited to 'kabc/vcardparser') diff --git a/kabc/vcardparser/Makefile.am b/kabc/vcardparser/Makefile.am new file mode 100644 index 000000000..42e55cb4b --- /dev/null +++ b/kabc/vcardparser/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes) + +noinst_LTLIBRARIES = libvcards.la +libvcards_la_SOURCES = vcard.cpp vcardline.cpp vcardparser.cpp + +vcardsincludedir = $(includedir)/kabc +vcardsinclude_HEADERS = vcard.h vcardline.h vcardparser.h + +check_PROGRAMS = testread testwrite testread2 + +testread_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testread_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testread_SOURCES = testread.cpp + +testread2_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testread2_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testread2_SOURCES = testread2.cpp testutils.cpp + +testwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testwrite_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testwrite_SOURCES = testwrite.cpp + +TESTFILES = vcard1.vcf vcard2.vcf vcard3.vcf vcard4.vcf vcard6.vcf vcard7.vcf + +check-local: testread + rm -f FAILED; \ + for i in $(TESTFILES); \ + do perl $(top_srcdir)/kabc/vcardparser/checkvcard.pl \ + $(top_srcdir)/kabc/vcardparser/tests/$$i; \ + done; \ + [ ! -e FAILED ] diff --git a/kabc/vcardparser/README.testing b/kabc/vcardparser/README.testing new file mode 100644 index 000000000..a7794931d --- /dev/null +++ b/kabc/vcardparser/README.testing @@ -0,0 +1,15 @@ +For testing the vcardparser there are some test files and a small testsuite +automatically checking for regressions. The tests directory contains some vCard +files and correpsonding reference output files (with an additional ".ref" +suffix). For running the geression test do "make check". This will compile some +test programs, parse the test files, write them out as vCard again and compare +the output to the reference file. The check fails, if there are unexpected +differences and shows which lines differed. + +For creating a new test put a vCard file to be parsed into the tests directory. +Create a reference file by running "testread" on the test file. It will put out +the parsed data as vCard again on stdout. Carefully check the output, manually +correct any errors and save the result as reference file in the tests directory. +Now add the filename to the TESTFILES variable in Makefile.am and run "make +check". If the check fails adapt the reference file or fix the bugs in the +parser, whatever is appropriate. diff --git a/kabc/vcardparser/checkvcard.pl b/kabc/vcardparser/checkvcard.pl new file mode 100755 index 000000000..67160ea4a --- /dev/null +++ b/kabc/vcardparser/checkvcard.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +if ( @ARGV != 1 ) { + print STDERR "Missing arg: filename\n"; + exit 1; +} + +$file = $ARGV[0]; + +if ( !open( IN, "$file" ) ) { + print STDERR "Unable to open '$file'\n"; + exit 1; +} + +while( ) { + if (/^VERSION:(.*)$/ ) { + $version = $1; + if ( $version eq "2.1" ) { $options = "--vcard21"; } + } +} + +close IN; + +$ref = "$file.ref"; + +if ( !open( REF, "$ref" ) ) { + print STDERR "Unable to open $ref\n"; + exit 1; +} + +while( ) { + push @ref, $_; +} + +close REF; + +if ( !open( READ, "./testread $file $options 2> /dev/null |" ) ) { + print STDERR "Unable to open testread\n"; + exit 1; +} + +print "Checking '$file':\n"; + +$gotsomething = 0; +$error = 0; +$i = 0; +while( ) { + $gotsomething = 1; + $out = $_; + $ref = @ref[$i++]; + + if ( $out ne $ref ) { + if ( $ref =~ /^UID/ && $out =~ /^UID/ ) { next; } + $error++; + print " Expected : $ref"; + print " Parser output : $out"; + } +} + +close READ; + +if ( $gotsomething == 0 ) { + print "\n FAILED: testread didn't output anything\n"; + system "touch FAILED"; + exit 1; +} +if ( $error > 0 ) { + print "\n FAILED: $error errors found.\n"; + system "touch FAILED"; + exit 1; +} else { + print " OK\n"; +} + +exit 0; diff --git a/kabc/vcardparser/testread.cpp b/kabc/vcardparser/testread.cpp new file mode 100644 index 000000000..52fe81a11 --- /dev/null +++ b/kabc/vcardparser/testread.cpp @@ -0,0 +1,89 @@ +/* + This file is part of libkabc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "vcardconverter.h" +#include "vcard.h" + +static const KCmdLineOptions options[] = +{ + {"vcard21", I18N_NOOP("vCard 2.1"), 0}, + {"+inputfile", I18N_NOOP("Input file"), 0}, + KCmdLineLastOption +}; + +int main( int argc, char **argv ) +{ + KApplication::disableAutoDcopRegistration(); + + KAboutData aboutData( "testread", "vCard test reader", "0.1" ); + aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app( false, false ); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if ( args->count() != 1 ) { + std::cerr << "Missing argument" << std::endl; + return 1; + } + + QString inputFile( args->arg( 0 ) ); + + QFile file( inputFile ); + if ( !file.open( IO_ReadOnly ) ) { + qDebug( "Unable to open file '%s' for reading!", file.name().latin1() ); + return 1; + } + + QString text; + + QTextStream s( &file ); + s.setEncoding( QTextStream::Latin1 ); + text = s.read(); + file.close(); + + KABC::VCardConverter converter; + KABC::Addressee::List list = converter.parseVCards( text ); + + if ( args->isSet( "vcard21" ) ) { + text = converter.createVCards( list, KABC::VCardConverter::v2_1 ); // uses version 2.1 + } else { + text = converter.createVCards( list ); // uses version 3.0 + } + + std::cout << text.utf8(); + + return 0; +} diff --git a/kabc/vcardparser/testread2.cpp b/kabc/vcardparser/testread2.cpp new file mode 100644 index 000000000..19a02e3c9 --- /dev/null +++ b/kabc/vcardparser/testread2.cpp @@ -0,0 +1,42 @@ +#include "testutils.h" +#include +#include +#include + +using namespace KABC; + +int +main() +{ + Addressee::List l = vCardsAsAddresseeList(); + QString vcards = vCardsAsText(); + + VCardConverter vct; + + Addressee::List parsed = vct.parseVCards( vcards ); + + if ( l.size() != parsed.size() ) { + kdDebug()<<"\tSize - FAILED : "< +#include +#include + +using namespace KABC; + +Addressee +vcard1() +{ + Addressee addr; + + addr.setName( "Frank Dawson" ); + addr.setOrganization( "Lotus Development Corporation" ); + addr.setUrl( KURL( "http://home.earthlink.net/~fdawson") ); + addr.insertEmail( "fdawson@earthlink.net" ); + addr.insertEmail( "Frank_Dawson@Lotus.com", true ); + addr.insertPhoneNumber( PhoneNumber("+1-919-676-9515",PhoneNumber::Voice|PhoneNumber::Msg + |PhoneNumber::Work ) ); + addr.insertPhoneNumber( PhoneNumber("+1-919-676-9564",PhoneNumber::Fax |PhoneNumber::Work )); + Address a( Address::Work | Address::Postal | Address::Parcel ); + a.setStreet( "6544 Battleford Drive" ); + a.setLocality( "Raleigh" ); + a.setRegion( "NC" ); + a.setPostalCode( "27613-3502" ); + a.setCountry( "U.S.A." ); + addr.insertAddress( a ); + return addr; +} + +Addressee +vcard2() +{ + Addressee addr; + + addr.setName( "Tim Howes" ); + addr.setOrganization( "Netscape Communications Corp." ); + addr.insertEmail( "howes@netscape.com" ); + addr.insertPhoneNumber( PhoneNumber("+1-415-937-3419",PhoneNumber::Voice|PhoneNumber::Msg + |PhoneNumber::Work) ); + addr.insertPhoneNumber( PhoneNumber("+1-415-528-4164",PhoneNumber::Fax |PhoneNumber::Work) ); + Address a( Address::Work ); + a.setStreet( "501 E. Middlefield Rd." ); + a.setLocality( "Mountain View" ); + a.setRegion( "CA" ); + a.setPostalCode( "94043" ); + a.setCountry( "U.S.A." ); + addr.insertAddress( a ); + return addr; +} + +Addressee +vcard3() +{ + Addressee addr; + + addr.setName( "ian geiser" ); + addr.setOrganization( "Source eXtreme" ); + addr.insertEmail( "geiseri@yahoo.com" ); + addr.setTitle( "VP of Engineering" ); + return addr; +} + + +QString +vcardAsText( const QString& location ) +{ + QString line; + QFile file( location ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream stream( &file ); + if ( !stream.eof() ) { + line = stream.read(); + } + file.close(); + } + return line; +} + +Addressee::List +vCardsAsAddresseeList() +{ + Addressee::List l; + + l.append( vcard1() ); + l.append( vcard2() ); + l.append( vcard3() ); + + return l; +} + +QString +vCardsAsText() +{ + QString vcards = vcardAsText( "tests/vcard1.vcf" ); + vcards += vcardAsText( "tests/vcard2.vcf" ); + vcards += vcardAsText( "tests/vcard3.vcf" ); + + return vcards; +} diff --git a/kabc/vcardparser/testutils.h b/kabc/vcardparser/testutils.h new file mode 100644 index 000000000..369912ac0 --- /dev/null +++ b/kabc/vcardparser/testutils.h @@ -0,0 +1,14 @@ +#ifndef TESTUTILS_H +#define TESTUTILS_H + +#include +#include + +KABC::Addressee vcard1(); +KABC::Addressee vcard2(); +KABC::Addressee vcard3(); +KABC::Addressee::List vCardsAsAddresseeList(); +QString vCardAsText( const QString& location ); +QString vCardsAsText(); + +#endif diff --git a/kabc/vcardparser/testwrite.cpp b/kabc/vcardparser/testwrite.cpp new file mode 100644 index 000000000..7d2f77c83 --- /dev/null +++ b/kabc/vcardparser/testwrite.cpp @@ -0,0 +1,134 @@ +/* + This file is part of libkabc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "vcardconverter.h" + +int main( int argc, char **argv ) +{ + KAboutData aboutData( "testwrite", "vCard test writer", "0.1" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication app( false, false ); + + + KABC::Addressee addressee; + + addressee.setNameFromString( "Mr. Tobias Koenig Jr." ); + addressee.setNickName( "tokoe" ); + addressee.setBirthday( QDate( 1982, 7, 19 ) ); + addressee.setMailer( "mutt1.2" ); + addressee.setTimeZone( KABC::TimeZone( +2 ) ); + + KABC::Geo geo; + geo.setLatitude( 30 ); + geo.setLongitude( 51 ); + addressee.setGeo( geo ); + + addressee.setTitle( "nerd" ); + addressee.setRole( "Maintainer" ); + addressee.setOrganization( "KDE" ); + addressee.setNote( "nerver\ntouch a running system" ); + addressee.setProductId( "testId" ); + addressee.setRevision( QDateTime::currentDateTime() ); + addressee.setSortString( "koenig" ); + addressee.setUrl( KURL( "http://wgess16.dyndns.org") ); + addressee.setSecrecy( KABC::Secrecy( KABC::Secrecy::Confidential ) ); +/* + QImage img; + img.load( "testimg.png", "PNG" ); + KABC::Picture photo; + photo.setData( img ); + addressee.setPhoto( photo ); + + QImage img2; + img2.load( "testimg.png", "PNG" ); + KABC::Picture logo; + logo.setData( img2 ); + addressee.setLogo( logo ); + + QFile soundFile( "testsound.wav" ); + soundFile.open( IO_ReadOnly ); + QByteArray data = soundFile.readAll(); + soundFile.close(); + KABC::Sound sound; + sound.setData( data ); + addressee.setSound( sound ); +*/ + addressee.insertEmail( "tokoe@kde.org", true ); + addressee.insertEmail( "tokoe82@yahoo.de", true ); + + KABC::PhoneNumber phone1( "3541523475", KABC::PhoneNumber::Pref | KABC::PhoneNumber::Home ); + KABC::PhoneNumber phone2( "+46745673475", KABC::PhoneNumber::Work ); + addressee.insertPhoneNumber( phone1 ); + addressee.insertPhoneNumber( phone2 ); + + KABC::Key key( "secret key", KABC::Key::X509 ); + addressee.insertKey( key ); + + QStringList categories; + categories << "Friends" << "School" << "KDE"; + addressee.setCategories( categories ); + + KABC::Address a( KABC::Address::Work | KABC::Address::Postal | KABC::Address::Parcel ); + a.setStreet( "6544 Battleford Drive" ); + a.setLocality( "Raleigh" ); + a.setRegion( "NC" ); + a.setPostalCode( "27613-3502" ); + a.setCountry( "U.S.A." ); + addressee.insertAddress( a ); + + addressee.insertCustom( "1hsdf", "ertuer", "iurt" ); + addressee.insertCustom( "2hsdf", "ertuer", "iurt" ); + addressee.insertCustom( "3hsdf", "ertuer", "iurt" ); + + KABC::Addressee::List list; + for ( int i = 0; i < 1000; ++i ) { + KABC::Addressee addr = addressee; + addr.setUid( QString::number( i ) ); + list.append( addr ); + } + + KABC::VCardConverter converter; + QString txt = converter.createVCards( list ); + + QFile file( "out.vcf" ); + file.open( IO_WriteOnly ); + + QTextStream s( &file ); + s.setEncoding( QTextStream::UnicodeUTF8 ); + s << txt; + file.close(); + + return 0; +} diff --git a/kabc/vcardparser/vcard.cpp b/kabc/vcardparser/vcard.cpp new file mode 100644 index 000000000..410a958d1 --- /dev/null +++ b/kabc/vcardparser/vcard.cpp @@ -0,0 +1,109 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "vcard.h" + +using namespace KABC; + +VCard::VCard() +{ +} + +VCard::VCard( const VCard& vcard ) +{ + mLineMap = vcard.mLineMap; +} + +VCard::~VCard() +{ +} + +VCard& VCard::operator=( const VCard& vcard ) +{ + if ( &vcard == this ) + return *this; + + mLineMap = vcard.mLineMap; + + return *this; +} + +void VCard::clear() +{ + mLineMap.clear(); +} + +QStringList VCard::identifiers() const +{ + return mLineMap.keys(); +} + +void VCard::addLine( const VCardLine& line ) +{ + mLineMap[ line.identifier() ].append( line ); +} + +VCardLine::List VCard::lines( const QString& identifier ) const +{ + LineMap::ConstIterator it = mLineMap.find( identifier ); + if ( it == mLineMap.end() ) + return VCardLine::List(); + + return *it; +} + +VCardLine VCard::line( const QString& identifier ) const +{ + LineMap::ConstIterator it = mLineMap.find( identifier ); + if ( it == mLineMap.end() ) + return VCardLine(); + + if ( (*it).isEmpty() ) + return VCardLine(); + else + return (*it).first(); +} + +void VCard::setVersion( Version version ) +{ + mLineMap.erase( "VERSION" ); + + VCardLine line; + line.setIdentifier( "VERSION" ); + if ( version == v2_1 ) + line.setIdentifier( "2.1" ); + else if ( version == v3_0 ) + line.setIdentifier( "3.0" ); + + mLineMap[ "VERSION" ].append( line ); +} + +VCard::Version VCard::version() const +{ + LineMap::ConstIterator versionEntry = mLineMap.find( "VERSION" ); + if ( versionEntry == mLineMap.end() ) + return v3_0; + + VCardLine line = ( *versionEntry )[ 0 ]; + if ( line.value() == "2.1" ) + return v2_1; + else + return v3_0; +} diff --git a/kabc/vcardparser/vcard.h b/kabc/vcardparser/vcard.h new file mode 100644 index 000000000..73fcd1ea2 --- /dev/null +++ b/kabc/vcardparser/vcard.h @@ -0,0 +1,91 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VCARDPARSER_VCARD_H +#define VCARDPARSER_VCARD_H + +#include "vcardline.h" +#include +#include +#include + +namespace KABC { + +class VCard +{ + public: + typedef QValueList List; + typedef QMap< QString, VCardLine::List > LineMap; + + enum Version { v2_1, v3_0 }; + + VCard(); + VCard( const VCard& ); + + ~VCard(); + + VCard& operator=( const VCard& ); + + /** + * Removes all lines from the vCard. + */ + void clear(); + + /** + * Returns a list of all identifiers that exists in the + * vCard. + */ + QStringList identifiers() const; + + /** + * Adds a VCardLine to the VCard + */ + void addLine( const VCardLine& line ); + + /** + * Returns all lines of the vcard with a special identifier. + */ + VCardLine::List lines( const QString& identifier ) const; + + /** + * Returns only the first line of the vcard with a special identifier. + */ + VCardLine line( const QString& identifier ) const; + + /** + * Set the version of the vCard. + */ + void setVersion( Version version ); + + /** + * Returns the version of this vCard. + */ + Version version() const; + + private: + LineMap mLineMap; + + class VCardPrivate; + VCardPrivate *d; +}; + +} + +#endif diff --git a/kabc/vcardparser/vcardline.cpp b/kabc/vcardparser/vcardline.cpp new file mode 100644 index 000000000..247604ebb --- /dev/null +++ b/kabc/vcardparser/vcardline.cpp @@ -0,0 +1,151 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "vcardline.h" + +using namespace KABC; + +class VCardLine::VCardLinePrivate +{ + public: + QString mGroup; +}; + +VCardLine::VCardLine() + : d( 0 ) +{ +} + +VCardLine::VCardLine( const QString &identifier ) + : d( 0 ) +{ + mIdentifier = identifier; +} + +VCardLine::VCardLine( const QString &identifier, const QVariant &value ) + : d( 0 ) +{ + mIdentifier = identifier; + mValue = value; +} + +VCardLine::VCardLine( const VCardLine& line ) + : d( 0 ) +{ + mParamMap = line.mParamMap; + mValue = line.mValue; + mIdentifier = line.mIdentifier; +} + +VCardLine::~VCardLine() +{ + delete d; + d = 0; +} + +VCardLine& VCardLine::operator=( const VCardLine& line ) +{ + if ( &line == this ) + return *this; + + mParamMap = line.mParamMap; + mValue = line.mValue; + mIdentifier = line.mIdentifier; + + return *this; +} + +void VCardLine::setIdentifier( const QString& identifier ) +{ + mIdentifier = identifier; +} + +QString VCardLine::identifier() const +{ + return mIdentifier; +} + +void VCardLine::setValue( const QVariant& value ) +{ + mValue = value; +} + +QVariant VCardLine::value() const +{ + return mValue; +} + +void VCardLine::setGroup( const QString& group ) +{ + if ( !d ) + d = new VCardLinePrivate(); + + d->mGroup = group; +} + +QString VCardLine::group() const +{ + if ( d ) + return d->mGroup; + else + return QString(); +} + +bool VCardLine::hasGroup() const +{ + if ( !d ) + return false; + else + return d->mGroup.isEmpty(); +} + +QStringList VCardLine::parameterList() const +{ + return mParamMap.keys(); +} + +void VCardLine::addParameter( const QString& param, const QString& value ) +{ + QStringList &list = mParamMap[ param ]; + if ( list.findIndex( value ) == -1 ) // not included yet + list.append( value ); +} + +QStringList VCardLine::parameters( const QString& param ) const +{ + ParamMap::ConstIterator it = mParamMap.find( param ); + if ( it == mParamMap.end() ) + return QStringList(); + else + return *it; +} + +QString VCardLine::parameter( const QString& param ) const +{ + ParamMap::ConstIterator it = mParamMap.find( param ); + if ( it == mParamMap.end() ) + return QString::null; + else { + if ( (*it).isEmpty() ) + return QString::null; + else + return (*it).first(); + } +} diff --git a/kabc/vcardparser/vcardline.h b/kabc/vcardparser/vcardline.h new file mode 100644 index 000000000..d6ad9dd77 --- /dev/null +++ b/kabc/vcardparser/vcardline.h @@ -0,0 +1,115 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VCARDLINE_H +#define VCARDLINE_H + +#include +#include +#include +#include +#include + +namespace KABC { + +class VCardLine +{ + public: + typedef QValueList List; + typedef QMap ParamMap; + + VCardLine(); + VCardLine( const QString &identifier ); + VCardLine( const QString &identifier, const QVariant &value ); + VCardLine( const VCardLine& ); + + ~VCardLine(); + + VCardLine& operator=( const VCardLine& ); + + /** + * Sets the identifier of this line e.g. UID, FN, CLASS + */ + void setIdentifier( const QString& identifier ); + + /** + * Returns the identifier of this line. + */ + QString identifier() const; + + /** + * Sets the value of of this line. + */ + void setValue( const QVariant& value ); + + /** + * Returns the value of this line. + */ + QVariant value() const; + + /** + * Sets the group the line belongs to. + */ + void setGroup( const QString& group ); + + /** + * Returns the group the line belongs to. + */ + QString group() const; + + /** + * Returns whether the line belongs to a group. + */ + bool hasGroup() const; + + /** + * Returns all parameters. + */ + QStringList parameterList() const; + + /** + * Add a new parameter to the line. + */ + void addParameter( const QString& param, const QString& value ); + + /** + * Returns the values of a special parameter. + * You can get a list of all parameters with paramList(). + */ + QStringList parameters( const QString& param ) const; + + /** + * Returns only the first value of a special parameter. + * You can get a list of all parameters with paramList(). + */ + QString parameter( const QString& param ) const; + + private: + ParamMap mParamMap; + QString mIdentifier; + QVariant mValue; + + class VCardLinePrivate; + VCardLinePrivate *d; +}; + +} + +#endif diff --git a/kabc/vcardparser/vcardparser.cpp b/kabc/vcardparser/vcardparser.cpp new file mode 100644 index 000000000..34c13c68a --- /dev/null +++ b/kabc/vcardparser/vcardparser.cpp @@ -0,0 +1,287 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include "vcardparser.h" + +#define FOLD_WIDTH 75 + +using namespace KABC; + +static QString backslash( "\\\\" ); +static QString comma( "\\," ); +static QString newline( "\\n" ); +static QString cr( "\\r" ); + +static void addEscapes( QString &str ) +{ + str.replace( '\\', backslash ); + str.replace( ',', comma ); + str.replace( '\r', cr ); + str.replace( '\n', newline ); +} + +static void removeEscapes( QString &str ) +{ + str.replace( cr, "\\r" ); + str.replace( newline, "\n" ); + str.replace( comma, "," ); + str.replace( backslash, "\\" ); +} + +VCardParser::VCardParser() +{ +} + +VCardParser::~VCardParser() +{ +} + +VCard::List VCardParser::parseVCards( const QString& text ) +{ + static QRegExp sep( "[\x0d\x0a]" ); + + VCard currentVCard; + VCard::List vCardList; + QString currentLine; + + const QStringList lines = QStringList::split( sep, text ); + QStringList::ConstIterator it; + + bool inVCard = false; + QStringList::ConstIterator linesEnd( lines.end() ); + for ( it = lines.begin(); it != linesEnd; ++it ) { + + if ( (*it).isEmpty() ) // empty line + continue; + + if ( (*it)[ 0 ] == ' ' || (*it)[ 0 ] == '\t' ) { // folded line => append to previous + currentLine += QString( *it ).remove( 0, 1 ); + continue; + } else { + if ( inVCard && !currentLine.isEmpty() ) { // now parse the line + int colon = currentLine.find( ':' ); + if ( colon == -1 ) { // invalid line + currentLine = (*it); + continue; + } + + VCardLine vCardLine; + const QString key = currentLine.left( colon ).stripWhiteSpace(); + QString value = currentLine.mid( colon + 1 ); + + QStringList params = QStringList::split( ';', key ); + + // check for group + if ( params[0].find( '.' ) != -1 ) { + const QStringList groupList = QStringList::split( '.', params[0] ); + vCardLine.setGroup( groupList[0] ); + vCardLine.setIdentifier( groupList[1] ); + } else + vCardLine.setIdentifier( params[0] ); + + if ( params.count() > 1 ) { // find all parameters + QStringList::ConstIterator paramIt = params.begin(); + for ( ++paramIt; paramIt != params.end(); ++paramIt ) { + QStringList pair = QStringList::split( '=', *paramIt ); + if ( pair.size() == 1 ) { + // correct the fucking 2.1 'standard' + if ( pair[0].lower() == "quoted-printable" ) { + pair[0] = "encoding"; + pair[1] = "quoted-printable"; + } else if ( pair[0].lower() == "base64" ) { + pair[0] = "encoding"; + pair[1] = "base64"; + } else { + pair.prepend( "type" ); + } + } + // This is pretty much a faster pair[1].contains( ',' )... + if ( pair[1].find( ',' ) != -1 ) { // parameter in type=x,y,z format + const QStringList args = QStringList::split( ',', pair[ 1 ] ); + QStringList::ConstIterator argIt; + for ( argIt = args.begin(); argIt != args.end(); ++argIt ) + vCardLine.addParameter( pair[0].lower(), *argIt ); + } else + vCardLine.addParameter( pair[0].lower(), pair[1] ); + } + } + + removeEscapes( value ); + + QByteArray output; + bool wasBase64Encoded = false; + + params = vCardLine.parameterList(); + if ( params.findIndex( "encoding" ) != -1 ) { // have to decode the data + QByteArray input; + input = QCString(value.latin1()); + if ( vCardLine.parameter( "encoding" ).lower() == "b" || + vCardLine.parameter( "encoding" ).lower() == "base64" ) { + KCodecs::base64Decode( input, output ); + wasBase64Encoded = true; + } + else if ( vCardLine.parameter( "encoding" ).lower() == "quoted-printable" ) { + // join any qp-folded lines + while ( value.at( value.length() - 1 ) == '=' && it != linesEnd ) { + value = value.remove( value.length() - 1, 1 ) + (*it); + ++it; + } + input = QCString(value.latin1()); + KCodecs::quotedPrintableDecode( input, output ); + } + } else { + output = QCString(value.latin1()); + } + + if ( params.findIndex( "charset" ) != -1 ) { // have to convert the data + QTextCodec *codec = + QTextCodec::codecForName( vCardLine.parameter( "charset" ).latin1() ); + if ( codec ) { + vCardLine.setValue( codec->toUnicode( output ) ); + } else { + vCardLine.setValue( QString::fromUtf8( output ) ); + } + } else if ( wasBase64Encoded ) { + vCardLine.setValue( output ); + } else { // if charset not given, assume it's in UTF-8 (as used in previous KDE versions) + vCardLine.setValue( QString::fromUtf8( output ) ); + } + + currentVCard.addLine( vCardLine ); + } + + // we do not save the start and end tag as vcardline + if ( (*it).lower().startsWith( "begin:vcard" ) ) { + inVCard = true; + currentLine.setLength( 0 ); + currentVCard.clear(); // flush vcard + continue; + } + + if ( (*it).lower().startsWith( "end:vcard" ) ) { + inVCard = false; + vCardList.append( currentVCard ); + currentLine.setLength( 0 ); + currentVCard.clear(); // flush vcard + continue; + } + + currentLine = (*it); + } + } + + return vCardList; +} + +QString VCardParser::createVCards( const VCard::List& list ) +{ + QString text; + QString textLine; + QString encodingType; + QStringList idents; + QStringList params; + QStringList values; + QStringList::ConstIterator identIt; + QStringList::Iterator paramIt; + QStringList::ConstIterator valueIt; + + VCardLine::List lines; + VCardLine::List::ConstIterator lineIt; + VCard::List::ConstIterator cardIt; + + bool hasEncoding; + + text.reserve( list.size() * 300 ); // reserve memory to be more efficient + + // iterate over the cards + VCard::List::ConstIterator listEnd( list.end() ); + for ( cardIt = list.begin(); cardIt != listEnd; ++cardIt ) { + text.append( "BEGIN:VCARD\r\n" ); + + idents = (*cardIt).identifiers(); + for ( identIt = idents.constBegin(); identIt != idents.constEnd(); ++identIt ) { + lines = (*cardIt).lines( (*identIt) ); + + // iterate over the lines + for ( lineIt = lines.constBegin(); lineIt != lines.constEnd(); ++lineIt ) { + if ( !(*lineIt).value().asString().isEmpty() ) { + if ( (*lineIt).hasGroup() ) + textLine = (*lineIt).group() + "." + (*lineIt).identifier(); + else + textLine = (*lineIt).identifier(); + + params = (*lineIt).parameterList(); + hasEncoding = false; + if ( params.count() > 0 ) { // we have parameters + for ( paramIt = params.begin(); paramIt != params.end(); ++paramIt ) { + if ( (*paramIt) == "encoding" ) { + hasEncoding = true; + encodingType = (*lineIt).parameter( "encoding" ).lower(); + } + + values = (*lineIt).parameters( *paramIt ); + for ( valueIt = values.constBegin(); valueIt != values.constEnd(); ++valueIt ) { + textLine.append( ";" + (*paramIt).upper() ); + if ( !(*valueIt).isEmpty() ) + textLine.append( "=" + (*valueIt) ); + } + } + } + + if ( hasEncoding ) { // have to encode the data + QByteArray input, output; + if ( encodingType == "b" ) { + input = (*lineIt).value().toByteArray(); + KCodecs::base64Encode( input, output ); + } else if ( encodingType == "quoted-printable" ) { + input = (*lineIt).value().toString().utf8(); + input.resize( input.size() - 1 ); // strip \0 + KCodecs::quotedPrintableEncode( input, output, false ); + } + + QString value( output ); + addEscapes( value ); + textLine.append( ":" + value ); + } else { + QString value( (*lineIt).value().asString() ); + addEscapes( value ); + textLine.append( ":" + value ); + } + + if ( textLine.length() > FOLD_WIDTH ) { // we have to fold the line + for ( uint i = 0; i <= ( textLine.length() / FOLD_WIDTH ); ++i ) + text.append( ( i == 0 ? "" : " " ) + textLine.mid( i * FOLD_WIDTH, FOLD_WIDTH ) + "\r\n" ); + } else + text.append( textLine + "\r\n" ); + } + } + } + + text.append( "END:VCARD\r\n" ); + text.append( "\r\n" ); + } + + return text; +} diff --git a/kabc/vcardparser/vcardparser.h b/kabc/vcardparser/vcardparser.h new file mode 100644 index 000000000..31e13424c --- /dev/null +++ b/kabc/vcardparser/vcardparser.h @@ -0,0 +1,44 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VCARDPARSER_H +#define VCARDPARSER_H + +#include "vcard.h" + +namespace KABC { + +class VCardParser +{ + public: + VCardParser(); + ~VCardParser(); + + static VCard::List parseVCards( const QString& text ); + static QString createVCards( const VCard::List& list ); + + private: + class VCardParserPrivate; + VCardParserPrivate *d; +}; + +} + +#endif -- cgit v1.2.1