]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi-2da-entrega/src/devque.cpp
Tag de 2da entrega.
[z.facultad/75.74/practicos.git] / practicas / pipi-2da-entrega / src / devque.cpp
1 #include "devque.h"
2 #include <cstring>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #ifdef DEBUG
9 #include <iostream>
10 #endif
11
12 struct Frame
13 {
14     Dev::mac_type mac;
15     size_t size;
16     char frame[1];
17 };
18
19 DevQue::DevQue(mac_type mac, key_t key, size_t mtu)
20     throw (std::runtime_error, std::logic_error):
21         Dev(mac, mtu)
22 {
23     que_id = msgget(key, IPC_CREAT | 0666);
24     if (que_id == -1)
25         throw std::runtime_error("No se pudo crear la cola");
26 }
27
28 void DevQue::transmit(const std::string& data, const mac_type& mac)
29     throw (std::runtime_error, std::logic_error)
30 {
31     if (data.size() > mtu)
32         throw std::logic_error("Tamaño de datos mayor al MTU");
33     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
34     if (!f)
35         throw std::runtime_error("No se puede reservar memoria");
36     f->mac = mac;
37     f->size = data.size();
38     memcpy(f->frame, data.c_str(), data.size());
39     int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0);
40 #ifdef DEBUG2
41     std::cout << "DevQue::transmit(msgtype/mac = " << f->mac << ", size = "
42         << f->size << ")\n";
43 #endif
44     free(f);
45     if (res == -1)
46         throw std::runtime_error("Error al poner en la cola");
47 }
48
49 std::string DevQue::receive() throw (std::runtime_error)
50 {
51     return receive(mac);
52 }
53
54 std::string DevQue::receive(mac_type& mac) throw (std::runtime_error)
55 {
56     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
57     if (!f)
58         throw std::runtime_error("No se puede reservar memoria");
59     int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0);
60     if (res == -1)
61     {
62         free(f);
63         throw std::runtime_error("Error al sacar de la cola");
64     }
65     std::string s((char*) f->frame, f->size);
66     if (mac == 0)
67         mac = f->mac;
68     free(f);
69 #ifdef DEBUG2
70     std::cout << "DevQue::receive(msgtype/mac = " << mac << ", size = "
71         << s.size() << ")\n";
72 #endif
73     return s;
74 }
75
76 /// Indica cuantos elementos hay en la cola
77 size_t DevQue::size() const
78 {
79     struct msqid_ds minfo;
80     msgctl(que_id, IPC_STAT, &minfo);
81     return minfo.msg_qnum;
82 }
83
84 /// Indica si está vacía la cola
85 bool DevQue::empty() const
86 {
87     return size() == 0;
88 }
89
90 // vim: set et sw=4 sts=4 :