• 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 
30 using namespace TDEABC;
31 
32 static TQString backslash( "\\\\" );
33 static TQString comma( "\\," );
34 static TQString newline( "\\n" );
35 static TQString cr( "\\r" );
36 
37 static 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 
45 static 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 
53 VCardParser::VCardParser()
54 {
55 }
56 
57 VCardParser::~VCardParser()
58 {
59 }
60 
61 VCard::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 
198 TQString 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 }
TDEStdAccel::key
int key(StdAccel) KDE_DEPRECATED
KCodecs::quotedPrintableDecode
static TQCString quotedPrintableDecode(const TQByteArray &in)
KCodecs::base64Decode
static TQCString base64Decode(const TQByteArray &in)
KCodecs::quotedPrintableEncode
static TQCString quotedPrintableEncode(const TQByteArray &in, bool useCRLF=true)
TDEABC
static data, shared by ALL addressee objects
Definition: address.h:48
TDEStdAccel::find
const TDEShortcut & find()
KCodecs::base64Encode
static TQCString base64Encode(const TQByteArray &in, bool insertLFs=false)

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeabc by doxygen 1.8.8
This website is maintained by Timothy Pearson.