Files
textmate/Frameworks/authorization/src/connection.cc
2012-08-28 21:32:46 +02:00

103 lines
2.6 KiB
C++

#include "connection.h"
#include <oak/debug.h>
namespace
{
template <int T> class width_tag_t { };
template <typename T> T to_network (T value, width_tag_t<2>) { return CFSwapInt16HostToBig(value); }
template <typename T> T to_network (T value, width_tag_t<4>) { return CFSwapInt32HostToBig(value); }
template <typename T> T to_network (T value, width_tag_t<8>) { return CFSwapInt64HostToBig(value); }
template <typename T> T to_network (T value) { return to_network(value, width_tag_t<sizeof(T)>()); }
template <typename T> T from_network (T value, width_tag_t<2>) { return CFSwapInt16BigToHost(value); }
template <typename T> T from_network (T value, width_tag_t<4>) { return CFSwapInt32BigToHost(value); }
template <typename T> T from_network (T value, width_tag_t<8>) { return CFSwapInt64BigToHost(value); }
template <typename T> T from_network (T value) { return from_network(value, width_tag_t<sizeof(T)>()); }
}
connection_t::connection_t (int socket) : _socket(socket)
{
}
connection_t::connection_t (std::string const& socketPath)
{
_socket = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { 0, AF_UNIX };
ASSERT_LT(socketPath.size(), sizeof(addr.sun_path));
strcpy(addr.sun_path, socketPath.c_str());
addr.sun_len = SUN_LEN(&addr);
connect(_socket, (sockaddr*)&addr, sizeof(addr));
}
connection_t& connection_t::operator<< (bool value)
{
write(_socket, &value, sizeof(value));
return *this;
}
connection_t& connection_t::operator<< (int value)
{
value = to_network(value);
write(_socket, &value, sizeof(value));
return *this;
}
connection_t& connection_t::operator<< (size_t value)
{
value = to_network(value);
write(_socket, &value, sizeof(value));
return *this;
}
connection_t& connection_t::operator<< (char const* str)
{
return *this << std::string(str);
}
connection_t& connection_t::operator<< (std::string const& value)
{
*this << value.size();
write(_socket, value.data(), value.size());
return *this;
}
connection_t& connection_t::operator>> (bool& res)
{
read(_socket, &res, sizeof(res));
return *this;
}
connection_t& connection_t::operator>> (int& res)
{
read(_socket, &res, sizeof(res));
res = from_network(res);
return *this;
}
connection_t& connection_t::operator>> (size_t& res)
{
read(_socket, &res, sizeof(res));
res = from_network(res);
return *this;
}
connection_t& connection_t::operator>> (std::string& res)
{
std::string::size_type size = 0;
*this >> size;
res.resize(size);
for(size_t i = 0; i < size; )
{
ssize_t len = read(_socket, &res[0] + i, size - i);
if(len == -1)
{
perror("read");
abort();
}
i += len;
}
return *this;
}