gloox  1.0.9
jinglefiletransfer.cpp
1 /*
2  Copyright (c) 2013 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #include "jinglefiletransfer.h"
15 
16 #include "tag.h"
17 #include "gloox.h"
18 #include "util.h"
19 
20 #include <cstdlib>
21 
22 namespace gloox
23 {
24 
25  namespace Jingle
26  {
27 
28  static const char* typeValues [] = {
29  "offer",
30  "request",
31  "checksum",
32  "abort",
33  "received"
34  };
35 
37  : m_type( type ), m_files( files )
38  {
39  }
40 
42  : m_type( Invalid )
43  {
44  if( !tag || tag->xmlns() != XMLNS_JINGLE_FILE_TRANSFER )
45  return;
46 
47  std::string name = tag->name();
48  if( name == "description" )
49  {
50  const Tag* c = tag->findTag( "description/offer|description/request" );
51  if( c )
52  {
53  parseFileList( c->findChildren( "file" ) );
54  name = c->name();
55  }
56  }
57  else if( name == "checksum" || name == "abort" || name == "received" )
58  {
59  parseFileList( tag->findChildren( "file" ) );
60  }
61 
62  m_type = (Type)util::lookup( name, typeValues );
63  }
64 
65  void FileTransfer::parseFileList( const TagList& files )
66  {
67  TagList::const_iterator it = files.begin();
68  for( ; it != files.end(); ++it )
69  {
70  File f;
71  Tag *t = (*it)->findChild( "name" );
72  f.name = t ? t->cdata() : EmptyString;
73  t = (*it)->findChild( "desc" );
74  f.desc = t ? t->cdata() : EmptyString;
75  t = (*it)->findChild( "date" );
76  f.date = t ? t->cdata() : EmptyString;
77  t = (*it)->findChild( "size" );
78  f.size = t ? atoi( t->cdata().c_str() ) : -1;
79  t = (*it)->findChild( "range" );
80  if( t )
81  {
82  f.range = true;
83  f.offset = t->hasAttribute( "offset" ) ? atoi( t->findAttribute( "offset" ).c_str() ) : -1;
84  }
85  t = (*it)->findChild( "hash", XMLNS, XMLNS_HASHES );
86  if( t )
87  {
88  f.hash_algo = t->findAttribute( "algo" );
89  f.hash = t->cdata();
90  }
91  m_files.push_back( f );
92  }
93  }
94 
96  {
97  StringList sl;
98  sl.push_back( XMLNS_JINGLE_FILE_TRANSFER );
99  return sl;
100  }
101 
102  const std::string& FileTransfer::filterString() const
103  {
104  static const std::string filter = "content/description[@xmlns='" + XMLNS_JINGLE_FILE_TRANSFER + "']"
105  "|jingle/abort[@xmlns='" + XMLNS_JINGLE_FILE_TRANSFER + "']"
106  "|jingle/received[@xmlns='" + XMLNS_JINGLE_FILE_TRANSFER + "']"
107  "|jingle/checksum[@xmlns='" + XMLNS_JINGLE_FILE_TRANSFER + "']";
108  return filter;
109  }
110 
111  Plugin* FileTransfer::newInstance( const Tag* tag ) const
112  {
113  return new FileTransfer( tag );
114  }
115 
117  {
118  if( m_type == Invalid )
119  return 0;
120 
121  Tag* r = 0;
122 
123  switch( m_type )
124  {
125  case Offer:
126  case Request:
127  {
128  r = new Tag( "description", XMLNS, XMLNS_JINGLE_FILE_TRANSFER );
129  Tag* o = new Tag( r, util::lookup( m_type, typeValues ) );
130  FileList::const_iterator it = m_files.begin();
131  for( ; it != m_files.end(); ++it )
132  {
133  Tag* f = new Tag( o, "file" );
134  new Tag( f, "date", (*it).date );
135  new Tag( f, "name", (*it).name );
136  new Tag( f, "desc", (*it).desc );
137  new Tag( f, "size", util::long2string( (*it).size ) );
138  Tag* h = new Tag( f, "hash", XMLNS, XMLNS_HASHES );
139  h->addAttribute( "algo", (*it).hash_algo );
140  h->setCData( (*it).hash );
141  if( (*it).range )
142  new Tag( f, "range", "offset", (*it).offset ? util::long2string( (*it).offset ) : EmptyString );
143  }
144  break;
145  }
146  case Abort:
147  case Checksum:
148  case Received:
149  {
150  r = new Tag( util::lookup( m_type, typeValues ), XMLNS, XMLNS_JINGLE_FILE_TRANSFER );
151  FileList::const_iterator it = m_files.begin();
152  Tag* f = new Tag( r, "file" );
153  new Tag( f, "date", (*it).date );
154  new Tag( f, "name", (*it).name );
155  new Tag( f, "desc", (*it).desc );
156  new Tag( f, "size", util::long2string( (*it).size ) );
157  Tag* h = new Tag( f, "hash", XMLNS, XMLNS_HASHES );
158  h->addAttribute( "algo", (*it).hash_algo );
159  h->setCData( (*it).hash );
160  if( (*it).range )
161  new Tag( f, "range" );
162  break;
163  }
164  default:
165  break;
166  }
167 
168  return r;
169  }
170 
171  }
172 
173 }