]> git.llucax.com Git - z.facultad/75.74/practicos.git/blobdiff - practicas/pipi/src/resolvproto.cpp
Se generaliza el devque para seguir (ab)usándolo como cola y poder pedir de
[z.facultad/75.74/practicos.git] / practicas / pipi / src / resolvproto.cpp
index e71100488934ce83f856057c98cd8565371d255b..55e960c570375c925ed82e92852eebcc1209a6ca 100644 (file)
@@ -1,50 +1,35 @@
 #include "resolvproto.h"
-#include "libtcp.h"
 #include <cstdlib>
 #include <algorithm>
 #include <iterator>
 
-/// Constructor
-ResolvProtoRequest::ResolvProtoRequest(int fd)
-{
-    recv(fd);
-}
-
 /// Constructor
 ResolvProtoRequest::ResolvProtoRequest(std::string name, uint8_t query_type):
     query_type(query_type), name(name)
 {}
 
-/// Envía por socket
-void ResolvProtoRequest::send(int sockfd) const
-    throw (std::runtime_error)
+/// Constructor a partir de un buffer
+ResolvProtoRequest::ResolvProtoRequest(std::string buf)
+{
+    memcpy(&query_type, buf.c_str(), sizeof(uint8_t));
+    uint16_t size;
+    memcpy(&size, buf.c_str() + sizeof(uint8_t), sizeof(uint16_t));
+    name.assign(buf.c_str() + sizeof(uint8_t) + sizeof(uint16_t), size);
+}
+
+/// Convierte a un buffer
+ResolvProtoRequest::operator std::string () const
 {
-    if (libtcp_send(sockfd, &query_type, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al enviar query_type por socket");
+    std::string buf((char*)&query_type, sizeof(uint8_t));
     uint16_t size = name.size();
-    if (libtcp_send(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t))
-        throw std::runtime_error("Error al enviar size por socket");
-    if (libtcp_send(sockfd, name.c_str(), size) != size)
-        throw std::runtime_error("Error al enviar name por socket");
+    buf.append((char*)&size, sizeof(uint16_t));
+    buf.append(name);
+    return buf;
 }
 
-/// Recibe por socket
-void ResolvProtoRequest::recv(int sockfd)
-    throw (std::runtime_error)
+size_t ResolvProtoRequest::packet_size() const
 {
-    if (libtcp_receive_bin(sockfd, &query_type, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al recibir query_type por socket");
-    uint16_t size;
-    if (libtcp_receive_bin(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t))
-        throw std::runtime_error("Error al recibir size por socket");
-    char* buf = (char*) malloc(size);
-    if (libtcp_receive_bin(sockfd, buf, size) != size)
-    {
-        free(buf);
-        throw std::runtime_error("Error al recibir name por socket");
-    }
-    name.assign(buf, size);
-    free(buf);
+    return sizeof(uint8_t) + sizeof(uint16_t) + name.size();
 }
 
 /// Impresión de request
@@ -55,64 +40,62 @@ std::ostream& operator<< (std::ostream& os, const ResolvProtoRequest& rpr)
 }
 
 /// Constructor
-ResolvProtoResponse::ResolvProtoResponse(int fd)
+ResolvProtoResponse::ResolvProtoResponse(): ret(R_NOTFOUND), ttl(0)
 {
-    recv(fd);
 }
 
 /// Constructor
-ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl):
-    ret(ret), ttl(ttl)
+ResolvProtoResponse::ResolvProtoResponse(std::string buf)
+{
+    memcpy(&ret, buf.c_str(), sizeof(uint8_t));
+    memcpy(&ttl, buf.c_str() + sizeof(uint8_t), sizeof(uint32_t));
+    uint8_t count;
+    memcpy(&count, buf.c_str() + sizeof(uint8_t) + sizeof(uint32_t),
+            sizeof(uint8_t));
+    ips.reserve(count);
+    for (uint8_t i = 0; i < count; ++i)
+    {
+        uint32_t ip;
+        memcpy(&ip, buf.c_str() + 2 * sizeof(uint8_t)
+                + sizeof(uint32_t) * (i + 1), sizeof(uint32_t));
+        ips.push_back(ip);
+    }
+}
+
+/// Constructor
+ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl,
+        const ipvec_t& ips):
+    ret(ret), ttl(ttl), ips(ips)
 {}
 
-/// Envía por socket
-void ResolvProtoResponse::send(int sockfd) const
-    throw (std::runtime_error)
+/// Convierte a buffer
+ResolvProtoResponse::operator std::string () const
 {
-    if (libtcp_send(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al enviar ret por socket");
-    if (libtcp_send(sockfd, &ttl, sizeof(uint32_t)) != sizeof(uint32_t))
-        throw std::runtime_error("Error al enviar ttl por socket");
+    std::string buf((char*)&ret, sizeof(uint8_t));
+    buf.append((char*)&ttl, sizeof(uint32_t));
     uint8_t count = ips.size();
-    if (libtcp_send(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al enviar count por socket");
+    buf.append((char*)&count, sizeof(uint8_t));
     for (ipvec_t::const_iterator i = ips.begin(); i != ips.end(); ++i)
     {
         uint32_t ip = *i;
-        if (libtcp_send(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
-            throw std::runtime_error("Error al enviar IPAddr por socket");
+        buf.append((char*)&ip, sizeof(uint32_t));
     }
+    return buf;
 }
 
-/// Recibe por socket
-void ResolvProtoResponse::recv(int sockfd)
-    throw (std::runtime_error)
+size_t ResolvProtoResponse::packet_size() const
 {
-    if (libtcp_receive_bin(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al recibir ret por socket");
-    if (libtcp_receive_bin(sockfd, &ttl, sizeof(uint32_t)) != sizeof(uint32_t))
-        throw std::runtime_error("Error al recibir ttl por socket");
-    uint8_t count;
-    if (libtcp_receive_bin(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
-        throw std::runtime_error("Error al recibir count por socket");
-    ips.clear();
-    ips.reserve(count);
-    for (uint8_t i = 0; i < count; ++i)
-    {
-        uint32_t ip;
-        if (libtcp_receive_bin(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
-            throw std::runtime_error("Error al recibir IPAddr por socket");
-        ips.push_back(ip);
-    }
+    return 2 * sizeof(uint8_t) + (ips.size() + 1) * sizeof(uint32_t);
 }
 
 /// Impresión de response
 std::ostream& operator<< (std::ostream& os, const ResolvProtoResponse& rpr)
 {
-    if (rpr.ips.empty())
-        return os;
     os << "ResolvProtoResponse(ret=" << unsigned(rpr.ret)
-        << ", ttl=" << rpr.ttl << ", ";
+        << ", ttl=" << rpr.ttl;
+    if (rpr.ips.empty())
+        return os << ")";
+    os << ", ";
     std::copy(rpr.ips.begin(), rpr.ips.end() - 1,
             std::ostream_iterator< IPAddr >(os, ", "));
     return os << rpr.ips.back() << ")";