tobicore  7.0.0
 All Classes Functions Variables Typedefs Enumerator Friends Groups Pages
IDSerializerRapid.cpp
1 /*
2  Copyright (C) 2009-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
3  Michele Tavella <michele.tavella@epfl.ch>
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program 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
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "IDSerializerRapid.hpp"
20 #include "IDTypes.hpp"
21 #include <tobicore/TCException.hpp>
22 #include <tobicore/TCTools.hpp>
23 #include <tobicore/rapidxml.hpp>
24 #include <tobicore/rapidxml_print.hpp>
25 #include <iostream>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <vector>
29 
30 #ifdef __BORLANDC__
31 using namespace std;
32 #endif
33 using namespace rapidxml;
34 
35 IDSerializerRapid::IDSerializerRapid(IDMessage* const message, const bool indent,
36  const bool declaration)
37  : IDSerializer(message) {
38  this->_indent = indent;
39  this->_declaration = declaration;
40 }
41 
42 //-----------------------------------------------------------------------------
43 
45 }
46 
47 //-----------------------------------------------------------------------------
48 
49 std::string* IDSerializerRapid::Serialize(std::string* buffer) {
50  if(buffer == NULL)
51  return NULL;
52  if(IDSerializer::message == NULL)
53  throw TCException("iD message not set, cannot serialize");
54 
55  buffer->clear();
56 
57  // XML document and buffers
58  xml_document<> doc;
59  std::string xml_as_string;
60  std::string xml_no_indent;
61 
62  // XML declaration
63  if(this->_declaration) {
64  xml_node<>* decl = doc.allocate_node(node_declaration);
65  decl->append_attribute(doc.allocate_attribute("version", "1.0"));
66  decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
67  doc.append_node(decl);
68  }
69 
70  char cacheFidx[16], cacheEvent[128];
71  TCTools::itoa(IDSerializer::message->GetBlockIdx(), cacheFidx);
72  TCTools::itoa(IDSerializer::message->GetEvent(), cacheEvent);
73  IDFvalue fvalue = IDSerializer::message->GetFamily();
74 
75  std::string timestamp, reference;
76  IDSerializer::message->absolute.Get(&timestamp);
77  IDSerializer::message->relative.Get(&reference);
78 
79  // Root node
80  xml_node<>* root = doc.allocate_node(node_element, IDMESSAGE_ROOTNODE);
81  root->append_attribute(doc.allocate_attribute(IDMESSAGE_VERSIONNODE,
82  IDMESSAGE_VERSION));
83  root->append_attribute(doc.allocate_attribute(IDMESSAGE_DESCRIPTIONNODE,
84  IDSerializer::message->_description.c_str()));
85  root->append_attribute(doc.allocate_attribute(IDMESSAGE_FRAMENODE_2,
86  cacheFidx));
87  root->append_attribute(doc.allocate_attribute(IDMESSAGE_FAMILYNODE,
88  fvalue.c_str()));
89  root->append_attribute(doc.allocate_attribute(IDMESSAGE_EVENTNODE,
90  cacheEvent));
91  root->append_attribute(doc.allocate_attribute(IDMESSAGE_TIMESTAMPNODE_2,
92  timestamp.c_str()));
93  root->append_attribute(doc.allocate_attribute(IDMESSAGE_REFERENCENODE_2,
94  reference.c_str()));
95  doc.append_node(root);
96 
97  if(this->_indent)
98  print(std::back_inserter(*buffer), doc);
99  else
100  print(std::back_inserter(*buffer), doc, print_no_indenting);
101 
102  return buffer;
103 }
104 
105 //-----------------------------------------------------------------------------
106 
107 std::string* IDSerializerRapid::Deserialize(std::string* const buffer)
108 {
109  if(buffer == NULL)
110  throw TCException("iD buffer-pointer is NULL",
111  #ifdef _WIN32
112  __FUNCSIG__
113  #else
114  __PRETTY_FUNCTION__
115  #endif
116  );
117 
118  xml_document<> doc;
119  std::string cache;
120  std::vector<char> xml_copy(buffer->begin(), buffer->end());
121  xml_copy.push_back('\0');
122  doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);
123 
124  xml_node<>* rootnode = doc.first_node(IDMESSAGE_ROOTNODE);
125  if(rootnode == NULL)
126  throw TCException("iD root node not found",
127  #ifdef _WIN32
128  __FUNCSIG__
129  #else
130  __PRETTY_FUNCTION__
131  #endif
132  );
133 
134  /* Check version */
135  cache = rootnode->first_attribute(IDMESSAGE_VERSIONNODE)->value();
136  if(cache.compare(IDMESSAGE_VERSION_SUPPORTED) == 0 )
137  {
138  // Get frame number
139  cache.clear();
140  cache = rootnode->first_attribute(IDMESSAGE_FRAMENODE)->value();
141  IDSerializer::message->SetBlockIdx(atol(cache.c_str()));
142 
143  // Get timestamp
144  cache.clear();
145  cache = rootnode->first_attribute(IDMESSAGE_TIMESTAMPNODE)->value();
147  cache.clear();
148  cache = rootnode->first_attribute(IDMESSAGE_REFERENCENODE)->value();
150 
151  cache = rootnode->first_attribute(IDMESSAGE_DESCRIPTIONNODE)->value();
152  IDSerializer::message->SetDescription(cache);
153 
154  cache = rootnode->first_attribute(IDMESSAGE_FAMILYNODE)->value();
155  if(cache.compare(IDTYPES_FAMILY_BIOSIG) == 0)
156  IDSerializer::message->SetFamilyType(IDMessage::FamilyBiosig);
157  else
158  IDSerializer::message->SetFamilyType(IDMessage::FamilyUndef);
159 
160  cache.clear();
161  cache = rootnode->first_attribute(IDMESSAGE_EVENTNODE)->value();
162  IDSerializer::message->SetEvent(atoi(cache.c_str()));
163 
164  return buffer;
165  }
166  else if( cache.compare(IDMESSAGE_VERSION) == 0 )
167  {
168  // Get frame number
169  cache.clear();
170  cache = rootnode->first_attribute(IDMESSAGE_FRAMENODE_2)->value();
171  IDSerializer::message->SetBlockIdx(atol(cache.c_str()));
172 
173  // Get timestamp
174  cache.clear();
175  cache = rootnode->first_attribute(IDMESSAGE_TIMESTAMPNODE_2)->value();
177  cache.clear();
178  cache = rootnode->first_attribute(IDMESSAGE_REFERENCENODE_2)->value();
180 
181  cache = rootnode->first_attribute(IDMESSAGE_DESCRIPTIONNODE)->value();
182  IDSerializer::message->SetDescription(cache);
183 
184  cache = rootnode->first_attribute(IDMESSAGE_FAMILYNODE)->value();
185  if(cache.compare(IDTYPES_FAMILY_BIOSIG) == 0)
186  IDSerializer::message->SetFamilyType(IDMessage::FamilyBiosig);
187  else
188  IDSerializer::message->SetFamilyType(IDMessage::FamilyUndef);
189 
190  cache.clear();
191  cache = rootnode->first_attribute(IDMESSAGE_EVENTNODE)->value();
192  IDSerializer::message->SetEvent(atoi(cache.c_str()));
193 
194  if(rootnode->first_attribute(IDMESSAGE_SOURCENODE))
195  {
196  cache.clear();
197  cache = rootnode->first_attribute(IDMESSAGE_SOURCENODE)->value();
198  IDSerializer::message->SetSource(cache);
199  }
200 
201  return buffer;
202  }
203  else
204  {
205  std::string info("iD version mismatch: ");
206  info.append(IDMESSAGE_VERSION);
207  info.append("/");
208  info.append(cache);
209  throw TCException(info,
210  #ifdef _WIN32
211  __FUNCSIG__
212  #else
213  __PRETTY_FUNCTION__
214  #endif
215  );
216  }
217 
218 
219 }
220 
221 //-----------------------------------------------------------------------------