Remove dynamic exceptions
[anna.git] / source / comm / handler / DatagramSocket.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <anna/core/tracing/Logger.hpp>
10 #include <anna/core/functions.hpp>
11 #include <anna/core/mt/Guard.hpp>
12
13 #include <anna/xml/Node.hpp>
14 #include <anna/xml/Attribute.hpp>
15
16 #include <anna/comm/DatagramSocket.hpp>
17 #include <anna/comm/Communicator.hpp>
18 #include <anna/comm/Device.hpp>
19 #include <anna/comm/Transport.hpp>
20 #include <anna/comm/Receiver.hpp>
21
22 #include <anna/comm/handler/DatagramSocket.hpp>
23
24 using namespace std;
25 using namespace anna;
26
27 void comm::handler::DatagramSocket::initialize()
28 noexcept(false) {
29   if(a_datagramSocket == NULL) {
30     string msg(asString());
31     msg += " | comm::DatagramSocket was not established";
32     throw RuntimeException(msg, ANNA_FILE_LOCATION);
33   }
34
35   if(a_datagramSocket->isConnected() == false)
36     a_datagramSocket->connect();
37
38   setfd(a_datagramSocket->getfd());
39 }
40
41 comm::ClientSocket* comm::handler::DatagramSocket::getClientSocket()
42 {
43   return a_datagramSocket;
44 }
45
46 void comm::handler::DatagramSocket::apply()
47 noexcept(false) {
48   Guard guard(a_datagramSocket, "anna::comm::DatagramSocket from anna::comm::handler::DatagramSocket::apply");
49   comm::DatagramSocket::Notify::_v notify = a_datagramSocket->receive();
50
51   if(notify == comm::DatagramSocket::Notify::Corrupt) {
52     a_datagramSocket->forgot();
53     return;
54   }
55
56   if(notify != comm::DatagramSocket::Notify::ReceiveData)
57     return;
58
59   const Message* message;
60   const DataBlock* dataBlock;
61   Transport* transport = a_datagramSocket->getTransport();
62   Receiver* receiver = a_datagramSocket->getReceiver();
63
64   while((dataBlock = a_datagramSocket->fetch()) != NULL && canContinue()) {
65     try {
66       try {
67         message = transport->decode(*dataBlock);
68       } catch(RuntimeException& ex) {
69         a_datagramSocket->forgot();
70         ex.trace();
71         message = NULL;
72         break;
73       }
74
75       if(receiver == NULL)
76         a_communicator->eventReceiveMessage(*a_datagramSocket, *message);
77       else
78         receiver->apply(*a_datagramSocket, *message);
79     } catch(RuntimeException& ex) {
80       ex.trace();
81     }
82   }
83 }
84
85 /*
86  * Se invoca desde Communicator::detach.
87  *
88  * [Tx] -> Communicator
89  */
90 void comm::handler::DatagramSocket::finalize()
91 {
92   if(a_datagramSocket == NULL)
93     return;
94
95   a_datagramSocket->close();
96   a_datagramSocket = NULL;
97 }
98
99 string comm::handler::DatagramSocket::asString() const
100 {
101   string result("comm::handler::DatagramSocket { ");
102   result += comm::Handler::asString();
103   result += " | ";
104   result += functions::asString(a_datagramSocket);
105   return result += " }";
106 }
107
108 xml::Node* comm::handler::DatagramSocket::asXML(xml::Node* parent) const
109 {
110   xml::Node* result = parent->createChild("comm.handler.DatagramSocket");
111   comm::Handler::asAttribute(result);
112
113   if(a_datagramSocket)
114     a_datagramSocket->asXML(result);
115
116   return result;
117 }
118
119