• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

  • tdeio
  • tdeio
dataprotocol.cpp
1// dataprotocol.cpp
2// ==================
3//
4// Implementation of the data protocol (rfc 2397)
5//
6// Author: Leo Savernik
7// Email: l.savernik@aon.at
8// (C) 2002, 2003 by Leo Savernik
9// Created: Sam Dez 28 14:11:18 CET 2002
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU Lesser General Public License as *
15 * published by the Free Software Foundation; version 2. *
16 * *
17 ***************************************************************************/
18
19#include "dataprotocol.h"
20
21#include <kdebug.h>
22#include <kmdcodec.h>
23#include <kurl.h>
24#include <tdeio/global.h>
25
26#include <tqcstring.h>
27#include <tqstring.h>
28#include <tqstringlist.h>
29#include <tqtextcodec.h>
30
31#ifdef DATAKIOSLAVE
32# include <kinstance.h>
33# include <stdlib.h>
34#endif
35#ifdef TESTKIO
36# include <iostream>
37#endif
38
39#if !defined(DATAKIOSLAVE) && !defined(TESTKIO)
40# define DISPATCH(f) dispatch_##f
41#else
42# define DISPATCH(f) f
43#endif
44
45using namespace TDEIO;
46#ifdef DATAKIOSLAVE
47extern "C" {
48
49 int kdemain( int argc, char **argv ) {
50 TDEInstance instance( "tdeio_data" );
51
52 kdDebug(7101) << "*** Starting tdeio_data " << endl;
53
54 if (argc != 4) {
55 kdDebug(7101) << "Usage: tdeio_data protocol domain-socket1 domain-socket2" << endl;
56 exit(-1);
57 }
58
59 DataProtocol slave(argv[2], argv[3]);
60 slave.dispatchLoop();
61
62 kdDebug(7101) << "*** tdeio_data Done" << endl;
63 return 0;
64 }
65}
66#endif
67
69struct DataHeader {
70 TQString mime_type; // mime type of content (lowercase)
71 MetaData attributes; // attribute/value pairs (attribute lowercase,
72 // value unchanged)
73 bool is_base64; // true if data is base64 encoded
74 TQString url; // reference to decoded url
75 int data_offset; // zero-indexed position within url
76 // where the real data begins. May point beyond
77 // the end to indicate that there is no data
78 TQString *charset; // shortcut to charset (it always exists)
79};
80
81// constant string data
82const TQChar text_plain_str[] = { 't','e','x','t','/','p','l','a','i','n' };
83const TQChar charset_str[] = { 'c','h','a','r','s','e','t' };
84const TQChar us_ascii_str[] = { 'u','s','-','a','s','c','i','i' };
85const TQChar base64_str[] = { 'b','a','s','e','6','4' };
86
95static int find(const TQString &buf, int begin, TQChar c1, TQChar c2 = '\0',
96 TQChar c3 = '\0') {
97 int pos = begin;
98 int size = (int)buf.length();
99 while (pos < size) {
100 TQChar ch = buf[pos];
101 if (ch == c1
102 || (c2 != '\0' && ch == c2)
103 || (c3 != '\0' && ch == c3))
104 break;
105 pos++;
106 }/*wend*/
107 return pos;
108}
109
120inline TQString extract(const TQString &buf, int &pos, TQChar c1,
121 TQChar c2 = '\0', TQChar c3 = '\0') {
122 int oldpos = pos;
123 pos = find(buf,oldpos,c1,c2,c3);
124 return TQString(buf.unicode() + oldpos, pos - oldpos);
125}
126
133inline void ignoreWS(const TQString &buf, int &pos) {
134 int size = (int)buf.length();
135 TQChar ch = buf[pos];
136 while (pos < size && (ch == ' ' || ch == '\t' || ch == '\n'
137 || ch == '\r'))
138 ch = buf[++pos];
139}
140
149static TQString parseQuotedString(const TQString &buf, int &pos) {
150 int size = (int)buf.length();
151 TQString res;
152 pos++; // jump over leading quote
153 bool escaped = false; // if true means next character is literal
154 bool parsing = true; // true as long as end quote not found
155 while (parsing && pos < size) {
156 TQChar ch = buf[pos++];
157 if (escaped) {
158 res += ch;
159 escaped = false;
160 } else {
161 switch (ch) {
162 case '"': parsing = false; break;
163 case '\\': escaped = true; break;
164 default: res += ch; break;
165 }/*end switch*/
166 }/*end if*/
167 }/*wend*/
168 return res;
169}
170
176static void parseDataHeader(const KURL &url, DataHeader &header_info) {
177 TQConstString text_plain(text_plain_str,sizeof text_plain_str/sizeof text_plain_str[0]);
178 TQConstString charset(charset_str,sizeof charset_str/sizeof charset_str[0]);
179 TQConstString us_ascii(us_ascii_str,sizeof us_ascii_str/sizeof us_ascii_str[0]);
180 TQConstString base64(base64_str,sizeof base64_str/sizeof base64_str[0]);
181 // initialize header info members
182 header_info.mime_type = text_plain.string();
183 header_info.charset = &header_info.attributes.insert(
184 charset.string(),us_ascii.string())
185 .data();
186 header_info.is_base64 = false;
187
188 // decode url and save it
189 TQString &raw_url = header_info.url = TQString::fromLatin1("data:") + url.path();
190 int raw_url_len = (int)raw_url.length();
191
192 // jump over scheme part (must be "data:", we don't even check that)
193 header_info.data_offset = raw_url.find(':');
194 header_info.data_offset++; // jump over colon or to begin if scheme was missing
195
196 // read mime type
197 if (header_info.data_offset >= raw_url_len) return;
198 TQString mime_type = extract(raw_url,header_info.data_offset,';',',')
199 .stripWhiteSpace();
200 if (!mime_type.isEmpty()) header_info.mime_type = mime_type;
201
202 if (header_info.data_offset >= raw_url_len) return;
203 // jump over delimiter token and return if data reached
204 if (raw_url[header_info.data_offset++] == ',') return;
205
206 // read all attributes and store them
207 bool data_begin_reached = false;
208 while (!data_begin_reached && header_info.data_offset < raw_url_len) {
209 // read attribute
210 TQString attribute = extract(raw_url,header_info.data_offset,'=',';',',')
211 .stripWhiteSpace();
212 if (header_info.data_offset >= raw_url_len
213 || raw_url[header_info.data_offset] != '=') {
214 // no assigment, must be base64 option
215 if (attribute == base64.string())
216 header_info.is_base64 = true;
217 } else {
218 header_info.data_offset++; // jump over '=' token
219
220 // read value
221 ignoreWS(raw_url,header_info.data_offset);
222 if (header_info.data_offset >= raw_url_len) return;
223
224 TQString value;
225 if (raw_url[header_info.data_offset] == '"') {
226 value = parseQuotedString(raw_url,header_info.data_offset);
227 ignoreWS(raw_url,header_info.data_offset);
228 } else
229 value = extract(raw_url,header_info.data_offset,';',',')
230 .stripWhiteSpace();
231
232 // add attribute to map
233 header_info.attributes[attribute.lower()] = value;
234
235 }/*end if*/
236 if (header_info.data_offset < raw_url_len
237 && raw_url[header_info.data_offset] == ',')
238 data_begin_reached = true;
239 header_info.data_offset++; // jump over separator token
240 }/*wend*/
241}
242
243#ifdef DATAKIOSLAVE
244DataProtocol::DataProtocol(const TQCString &pool_socket, const TQCString &app_socket)
245 : SlaveBase("tdeio_data", pool_socket, app_socket) {
246#else
247DataProtocol::DataProtocol() {
248#endif
249 kdDebug() << "DataProtocol::DataProtocol()" << endl;
250}
251
252/* --------------------------------------------------------------------- */
253
254DataProtocol::~DataProtocol() {
255 kdDebug() << "DataProtocol::~DataProtocol()" << endl;
256}
257
258/* --------------------------------------------------------------------- */
259
260void DataProtocol::get(const KURL& url) {
261 ref();
262 //kdDebug() << "===============================================================================================================================================================================" << endl;
263 kdDebug() << "tdeio_data@"<<this<<"::get(const KURL& url)" << endl ;
264
265 DataHeader hdr;
266 parseDataHeader(url,hdr);
267
268 int size = (int)hdr.url.length();
269 int data_ofs = TQMIN(hdr.data_offset,size);
270 // FIXME: string is copied, would be nice if we could have a reference only
271 TQString url_data = hdr.url.mid(data_ofs);
272 TQCString outData;
273
274#ifdef TESTKIO
275// cout << "current charset: \"" << *hdr.charset << "\"" << endl;
276#endif
277 if (hdr.is_base64) {
278 // base64 stuff is expected to contain the correct charset, so we just
279 // decode it and pass it to the receiver
280 KCodecs::base64Decode(url_data.local8Bit(),outData);
281 } else {
282 // FIXME: This is all flawed, must be reworked thoroughly
283 // non encoded data must be converted to the given charset
284 TQTextCodec *codec = TQTextCodec::codecForName(hdr.charset->latin1());
285 if (codec != 0) {
286 outData = codec->fromUnicode(url_data);
287 } else {
288 // if there is no approprate codec, just use local encoding. This
289 // should work for >90% of all cases.
290 outData = url_data.local8Bit();
291 }/*end if*/
292 }/*end if*/
293
294 //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
295 //kdDebug() << "emit mimeType@"<<this << endl ;
296 mimeType(hdr.mime_type);
297 //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
298 //kdDebug() << "emit totalSize@"<<this << endl ;
299 totalSize(outData.size());
300
301 //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
302 //kdDebug() << "emit setMetaData@"<<this << endl ;
303#if defined(TESTKIO) || defined(DATAKIOSLAVE)
304 MetaData::ConstIterator it;
305 for (it = hdr.attributes.begin(); it != hdr.attributes.end(); ++it) {
306 setMetaData(it.key(),it.data());
307 }/*next it*/
308#else
309 setAllMetaData(hdr.attributes);
310#endif
311
312 //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
313 //kdDebug() << "emit sendMetaData@"<<this << endl ;
314 sendMetaData();
315 //kdDebug() << "^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C" << endl;
316// kdDebug() << "(1) queue size " << dispatchQueue.size() << endl;
317 // empiric studies have shown that this shouldn't be queued & dispatched
318 /*DISPATCH*/(data(outData));
319// kdDebug() << "(2) queue size " << dispatchQueue.size() << endl;
320 DISPATCH(data(TQByteArray()));
321// kdDebug() << "(3) queue size " << dispatchQueue.size() << endl;
322 DISPATCH(finished());
323// kdDebug() << "(4) queue size " << dispatchQueue.size() << endl;
324 deref();
325}
326
327/* --------------------------------------------------------------------- */
328
329void DataProtocol::mimetype(const KURL &url) {
330 ref();
331 DataHeader hdr;
332 parseDataHeader(url,hdr);
333 mimeType(hdr.mime_type);
334 finished();
335 deref();
336}
337
338/* --------------------------------------------------------------------- */
339
TDEIO::DataProtocol
This tdeioslave provides support of data urls as specified by rfc 2397.
Definition dataprotocol.h:51
TDEIO::DataSlave::setAllMetaData
void setAllMetaData(const MetaData &)
Sets metadata.
Definition dataslave.cpp:163
TDEIO::DataSlave::sendMetaData
void sendMetaData()
Sends metadata set with setAllMetaData.
Definition dataslave.cpp:167
TDEIO::MetaData
MetaData is a simple map of key/value strings.
Definition global.h:516
TDEIO::SlaveBase
There are two classes that specifies the protocol between application (job) and tdeioslave.
Definition slavebase.h:46
TDEIO
A namespace for TDEIO globals.
Definition authinfo.h:29

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • 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 tdeio/tdeio by doxygen 1.9.8
This website is maintained by Timothy Pearson.