• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeabc
 

tdeabc

  • tdeabc
  • vcardparser
vcardparser.cpp
1/*
2 This file is part of libtdeabc.
3 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <tqregexp.h>
22#include <tqtextcodec.h>
23
24#include <kmdcodec.h>
25
26#include "vcardparser.h"
27
28#define FOLD_WIDTH 75
29
30using namespace TDEABC;
31
32static TQString backslash( "\\\\" );
33static TQString comma( "\\," );
34static TQString newline( "\\n" );
35static TQString cr( "\\r" );
36
37static void addEscapes( TQString &str )
38{
39 str.replace( '\\', backslash );
40 str.replace( ',', comma );
41 str.replace( '\r', cr );
42 str.replace( '\n', newline );
43}
44
45static void removeEscapes( TQString &str )
46{
47 str.replace( cr, "\\r" );
48 str.replace( newline, "\n" );
49 str.replace( comma, "," );
50 str.replace( backslash, "\\" );
51}
52
53VCardParser::VCardParser()
54{
55}
56
57VCardParser::~VCardParser()
58{
59}
60
61VCard::List VCardParser::parseVCards( const TQString& text )
62{
63 static TQRegExp sep( "[\x0d\x0a]" );
64
65 VCard currentVCard;
66 VCard::List vCardList;
67 TQString currentLine;
68
69 const TQStringList lines = TQStringList::split( sep, text );
70 TQStringList::ConstIterator it;
71
72 bool inVCard = false;
73 TQStringList::ConstIterator linesEnd( lines.end() );
74 for ( it = lines.begin(); it != linesEnd; ++it ) {
75
76 if ( (*it).isEmpty() ) // empty line
77 continue;
78
79 if ( (*it)[ 0 ] == ' ' || (*it)[ 0 ] == '\t' ) { // folded line => append to previous
80 currentLine += TQString( *it ).remove( 0, 1 );
81 continue;
82 } else {
83 if ( inVCard && !currentLine.isEmpty() ) { // now parse the line
84 int colon = currentLine.find( ':' );
85 if ( colon == -1 ) { // invalid line
86 currentLine = (*it);
87 continue;
88 }
89
90 VCardLine vCardLine;
91 const TQString key = currentLine.left( colon ).stripWhiteSpace();
92 TQString value = currentLine.mid( colon + 1 );
93
94 TQStringList params = TQStringList::split( ';', key );
95
96 // check for group
97 if ( params[0].find( '.' ) != -1 ) {
98 const TQStringList groupList = TQStringList::split( '.', params[0] );
99 vCardLine.setGroup( groupList[0] );
100 vCardLine.setIdentifier( groupList[1] );
101 } else
102 vCardLine.setIdentifier( params[0] );
103
104 if ( params.count() > 1 ) { // find all parameters
105 TQStringList::ConstIterator paramIt = params.begin();
106 for ( ++paramIt; paramIt != params.end(); ++paramIt ) {
107 TQStringList pair = TQStringList::split( '=', *paramIt );
108 if ( pair.size() == 1 ) {
109 // correct the 2.1 'standard'
110 if ( pair[0].lower() == "quoted-printable" ) {
111 pair[0] = "encoding";
112 pair[1] = "quoted-printable";
113 } else if ( pair[0].lower() == "base64" ) {
114 pair[0] = "encoding";
115 pair[1] = "base64";
116 } else {
117 pair.prepend( "type" );
118 }
119 }
120 // This is pretty much a faster pair[1].contains( ',' )...
121 if ( pair[1].find( ',' ) != -1 ) { // parameter in type=x,y,z format
122 const TQStringList args = TQStringList::split( ',', pair[ 1 ] );
123 TQStringList::ConstIterator argIt;
124 for ( argIt = args.begin(); argIt != args.end(); ++argIt )
125 vCardLine.addParameter( pair[0].lower(), *argIt );
126 } else
127 vCardLine.addParameter( pair[0].lower(), pair[1] );
128 }
129 }
130
131 removeEscapes( value );
132
133 TQByteArray output;
134 bool wasBase64Encoded = false;
135
136 params = vCardLine.parameterList();
137 if ( params.findIndex( "encoding" ) != -1 ) { // have to decode the data
138 TQByteArray input;
139 input = TQCString(value.latin1());
140 if ( vCardLine.parameter( "encoding" ).lower() == "b" ||
141 vCardLine.parameter( "encoding" ).lower() == "base64" ) {
142 KCodecs::base64Decode( input, output );
143 wasBase64Encoded = true;
144 }
145 else if ( vCardLine.parameter( "encoding" ).lower() == "quoted-printable" ) {
146 // join any qp-folded lines
147 while ( value.at( value.length() - 1 ) == '=' && it != linesEnd ) {
148 value = value.remove( value.length() - 1, 1 ) + (*it);
149 ++it;
150 }
151 input = TQCString(value.latin1());
152 KCodecs::quotedPrintableDecode( input, output );
153 }
154 } else { //assume it's in UTF-8 (as used in previous KDE versions)
155 output = TQCString(value.utf8());
156 }
157
158 if ( params.findIndex( "charset" ) != -1 ) { // have to convert the data
159 TQTextCodec *codec =
160 TQTextCodec::codecForName( vCardLine.parameter( "charset" ).latin1() );
161 if ( codec ) {
162 vCardLine.setValue( codec->toUnicode( output ) );
163 } else {
164 vCardLine.setValue( TQString(TQString::fromUtf8( output )) );
165 }
166 } else if ( wasBase64Encoded ) {
167 vCardLine.setValue( output );
168 } else { // if charset not given, assume it's in UTF-8 (as used in previous KDE versions)
169 vCardLine.setValue( TQString(TQString::fromUtf8( output )) );
170 }
171
172 currentVCard.addLine( vCardLine );
173 }
174
175 // we do not save the start and end tag as vcardline
176 if ( (*it).lower().startsWith( "begin:vcard" ) ) {
177 inVCard = true;
178 currentLine.setLength( 0 );
179 currentVCard.clear(); // flush vcard
180 continue;
181 }
182
183 if ( (*it).lower().startsWith( "end:vcard" ) ) {
184 inVCard = false;
185 vCardList.append( currentVCard );
186 currentLine.setLength( 0 );
187 currentVCard.clear(); // flush vcard
188 continue;
189 }
190
191 currentLine = (*it);
192 }
193 }
194
195 return vCardList;
196}
197
198TQString VCardParser::createVCards( const VCard::List& list )
199{
200 TQString text;
201 TQString textLine;
202 TQString encodingType;
203 TQStringList idents;
204 TQStringList params;
205 TQStringList values;
206 TQStringList::ConstIterator identIt;
207 TQStringList::Iterator paramIt;
208 TQStringList::ConstIterator valueIt;
209
210 VCardLine::List lines;
211 VCardLine::List::ConstIterator lineIt;
212 VCard::List::ConstIterator cardIt;
213
214 bool hasEncoding;
215
216 text.reserve( list.size() * 300 ); // reserve memory to be more efficient
217
218 // iterate over the cards
219 VCard::List::ConstIterator listEnd( list.end() );
220 for ( cardIt = list.begin(); cardIt != listEnd; ++cardIt ) {
221 text.append( "BEGIN:VCARD\r\n" );
222
223 idents = (*cardIt).identifiers();
224 for ( identIt = idents.constBegin(); identIt != idents.constEnd(); ++identIt ) {
225 lines = (*cardIt).lines( (*identIt) );
226
227 // iterate over the lines
228 for ( lineIt = lines.constBegin(); lineIt != lines.constEnd(); ++lineIt ) {
229 if ( !(*lineIt).value().asString().isEmpty() ) {
230 if ((*lineIt).identifier() != TQString("URI")) {
231 if ( (*lineIt).hasGroup() )
232 textLine = (*lineIt).group() + "." + (*lineIt).identifier();
233 else
234 textLine = (*lineIt).identifier();
235
236 params = (*lineIt).parameterList();
237 hasEncoding = false;
238 if ( params.count() > 0 ) { // we have parameters
239 for ( paramIt = params.begin(); paramIt != params.end(); ++paramIt ) {
240 if ( (*paramIt) == "encoding" ) {
241 hasEncoding = true;
242 encodingType = (*lineIt).parameter( "encoding" ).lower();
243 }
244
245 values = (*lineIt).parameters( *paramIt );
246 for ( valueIt = values.constBegin(); valueIt != values.constEnd(); ++valueIt ) {
247 textLine.append( ";" + (*paramIt).upper() );
248 if ( !(*valueIt).isEmpty() )
249 textLine.append( "=" + (*valueIt) );
250 }
251 }
252 }
253
254 if ( hasEncoding ) { // have to encode the data
255 TQByteArray input, output;
256 if ( encodingType == "b" ) {
257 input = (*lineIt).value().toByteArray();
258 KCodecs::base64Encode( input, output );
259 } else if ( encodingType == "quoted-printable" ) {
260 input = (*lineIt).value().toString().utf8();
261 input.resize( input.size() - 1 ); // strip \0
262 KCodecs::quotedPrintableEncode( input, output, false );
263 }
264
265 TQString value( output );
266 addEscapes( value );
267 textLine.append( ":" + value );
268 } else {
269 TQString value( (*lineIt).value().asString() );
270 addEscapes( value );
271 textLine.append( ":" + value );
272 }
273
274 if ( textLine.length() > FOLD_WIDTH ) { // we have to fold the line
275 for ( uint i = 0; i <= ( textLine.length() / FOLD_WIDTH ); ++i )
276 text.append( ( i == 0 ? "" : " " ) + textLine.mid( i * FOLD_WIDTH, FOLD_WIDTH ) + "\r\n" );
277 } else
278 text.append( textLine + "\r\n" );
279 }
280 else {
281 // URIs can be full of weird symbols, etc. so bypass all checks
282 textLine = (*lineIt).identifier();
283 TQString value( (*lineIt).value().asString() );
284 addEscapes( value );
285 textLine.append( ":" + value );
286 text.append( textLine + "\r\n" );
287 }
288 }
289 }
290 }
291
292 text.append( "END:VCARD\r\n" );
293 text.append( "\r\n" );
294 }
295
296 return text;
297}
KCodecs::quotedPrintableDecode
static TQCString quotedPrintableDecode(const TQByteArray &in)
KCodecs::base64Decode
static TQCString base64Decode(const TQByteArray &in)
KCodecs::base64Encode
static TQCString base64Encode(const TQByteArray &in, bool insertLFs=false)
KCodecs::quotedPrintableEncode
static TQCString quotedPrintableEncode(const TQByteArray &in, bool useCRLF=true)
TDEABC
static data, shared by ALL addressee objects
Definition: address.h:48
TDEStdAccel::key
int key(StdAccel id)
TDEStdAccel::find
const TDEShortcut & find()

tdeabc

Skip menu "tdeabc"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeabc

Skip menu "tdeabc"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeabc by doxygen 1.9.4
This website is maintained by Timothy Pearson.