2 #define WIN32_LEAN_AND_MEAN
11 #include <arpa/inet.h>
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
28 namespace ftc_detail {
32 #define TEC_INVALID_SOCKET INVALID_SOCKET
33 #define TEC_SOCKET_ERROR SOCKET_ERROR
36 #define TEC_INVALID_SOCKET (-1)
37 #define TEC_SOCKET_ERROR (-1)
70 ::LocalFree(static_cast<HLOCAL>
72 (static_cast<const void*>(buffer))));
79 const char*
message()
const {
return buffer; }
82 const char* b = buffer;
94 #elif defined(TEC_WINDOWS)
95 const char* buffer = 0;
96 DWORD r = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
97 | FORMAT_MESSAGE_FROM_SYSTEM
98 | FORMAT_MESSAGE_IGNORE_INSERTS
99 , 0, WSAGetLastError()
100 , 0, static_cast<LPTSTR>(static_cast<void*>(&buffer))
140 int get()
const {
return sock; }
164 throw FtcException(static_cast<FtcErrorCode>(static_cast<unsigned char>(static_cast<char>(status))), message);
177 WSABUF buffers = {1, &status};
178 DWORD count = 0, flags = 0;
179 int r = WSARecv(socket, &buffers, 1, &count, &flags
191 ssize_t r =
::recv(socket, &status, 1, 0);
203 #if defined(LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(TEC_WINDOWS)
206 std::vector<char> reverse_endian(size);
207 std::copy(buffer, buffer + size, reverse_endian.rbegin());
208 std::memcpy(buffer, &reverse_endian[0], size);
217 char v[
sizeof(
unsigned long long) == 8?1:0];
220 send(socket, &command, 1);
223 recv(socket, recv_buffer,
sizeof(recv_buffer));
227 unsigned long long return_value;
228 std::memcpy(&return_value, recv_buffer
229 , (std::min)(
sizeof(return_value),
sizeof(recv_buffer)));
235 std::size_t total = 0;
239 WSABUF buffers = {size,
const_cast<char*
>(buffer)};
241 int r = WSASend(socket, &buffers, 1, &count, 0, 0, 0);
254 r =
::send(socket, &buffer[total], size-total, 0);
255 }
while(r == -1 && errno == EINTR);
270 std::size_t total = 0;
274 WSABUF buffers = {size, buffer};
277 int r = ::WSARecv(socket, &buffers, 1, &count, &flags, 0, 0);
290 r =
::recv(socket, &buffer[total], size-total, 0);
291 }
while(r == -1 && errno == EINTR);
309 ftc::ftc(
const char*
id,
const char id_size,
bool writable,
const char* host
310 ,
unsigned short port,
const char* accessKey,
const char key_size)
314 , identifier_size (id_size)
318 , access_key(accessKey)
319 , access_key_size(key_size)
325 if(!writable && !readonly)
328 writable = !readonly;
331 WORD wVersionRequested = MAKEWORD(2,2);
333 int err = WSAStartup(wVersionRequested, &wsaData);
340 ftc_detail::socket s(::socket(AF_INET, SOCK_STREAM, 0));
347 hostent* h = gethostbyname(hostname);
356 {AF_INET, htons(tcp_port)};
358 std::memcpy(&addr.sin_addr.s_addr, h->h_addr_list[0],
sizeof(addr.sin_addr.s_addr));
360 if(::connect(s.get(),
static_cast<struct sockaddr*
>(
static_cast<void*
>(&addr))
371 char size = access_key_size;
381 buffer[0] = writable;
382 buffer[1] = identifier_size;
423 char buf_start[1+8] = {5};
424 std::memcpy(&buf_start[1], static_cast<const char*>(static_cast<const void*>(&p))
425 , (std::min<std::size_t>)(
sizeof(p), 8u));
427 , (std::min<std::size_t>)(8u,
sizeof(p)));
456 char buf_start[1+8] = {3};
457 std::memcpy(&buf_start[1], static_cast<const char*>(static_cast<const void*>(&s))
458 , (std::min<std::size_t>)(
sizeof(s), 8u));
460 , (std::min<std::size_t>)(8u,
sizeof(s)));
474 unsigned long long ftc::read(
char* data,
unsigned long long size,
unsigned long long p)
478 char buf_start[1+8+8] = {7};
479 std::memcpy(&buf_start[1], static_cast<const char*>(static_cast<const void*>(&p))
480 , (std::min<std::size_t>)(
sizeof(p),
sizeof(buf_start)-1));
481 std::memcpy(&buf_start[1+8], static_cast<const char*>(static_cast<const void*>(&size))
482 , (std::min<std::size_t>)(
sizeof(size),
sizeof(buf_start)-1));
484 , (std::min<std::size_t>)(8u,
sizeof(p)));
486 , (std::min<std::size_t>)(8u,
sizeof(p)));
489 char* current = data;
490 char* last = data + size;
491 while(current != last)
494 WSABUF buffers = {last-current, current};
495 DWORD count = 0, flags = 0;
500 r = ::WSARecv(sock, &buffers, 1, &count, &flags, 0, 0);
501 if(r == -1 && WSAGetLastError() == WSAENOBUFS
502 && buffers.len > ftc_detail::win32_minimum_buffer_size*2)
516 return current - data;
522 r =
::recv(sock, current, last-current, 0);
523 }
while(r == -1 && errno == EINTR);
530 return current - data;
533 assert(current <= last);
539 unsigned long long ftc::write(
char const* data,
unsigned long long size,
unsigned long long p)
545 char buf_start[1+8+8] = {8};
546 std::memcpy(&buf_start[1], static_cast<const char*>(static_cast<const void*>(&p))
547 , (std::min<std::size_t>)(
sizeof(p), 8u));
548 std::memcpy(&buf_start[1+8], static_cast<const char*>(static_cast<const void*>(&size))
549 , (std::min<std::size_t>)(
sizeof(size), 8u));
551 , (std::min<std::size_t>)(8u,
sizeof(p)));
553 , (std::min<std::size_t>)(8u,
sizeof(size)));
556 const char* current = data
557 , *last = data + size;
558 while(current != last)
561 WSABUF buffers = {last-current,
const_cast<char*
>(current)};
567 r = ::WSASend(sock, &buffers, 1, &count, 0, 0, 0);
568 if(r == -1 && WSAGetLastError() == WSAENOBUFS
569 && buffers.len > ftc_detail::win32_minimum_buffer_size*2)
583 return current - data;
589 r =
::send(sock, current, last-current, 0);
590 }
while(r == -1 && errno == EINTR);
597 return current - data;
600 assert(current <= last);
610 unsigned long long ftc::transferTo(
unsigned long long position,
unsigned long long nbytes, FILE* fd,
char* buffer)
618 std::vector<char> new_buffer((std::min)(1024u*1024u, static_cast<unsigned int>(nbytes)));
620 unsigned long long bytes_to_read = nbytes;
622 while(bytes_to_read != 0)
624 unsigned long long r =
read(&new_buffer[0], new_buffer.size(), position);
626 return nbytes - bytes_to_read;
630 #pragma warning(push)
631 #pragma warning(disable:4244) // warning C4244: 'argument' :
634 fwrite(&new_buffer[0], r, 1, fd);
TEC_FTC_DECL bool isOpen()
Indica se o arquivo está aberto.
#define TEC_INVALID_SOCKET
Essa exceção é lançada quando uma falha desconhecida aconteceu.
const char * message() const
Essa exceção é lançada quando o servidor atingiu o número máximo de clientes.
TEC_FTC_DECL unsigned long long write(const char *data, unsigned long long nbytes, unsigned long long position)
Escreve uma quantidade de bytes no arquivo.
int recv_status(socket_type socket)
TEC_FTC_DECL unsigned long long getSize() const
Retorna o tamanho atual do arquivo.
void endian_swap(char *, std::size_t)
TEC_FTC_DECL void open(bool readonly)
Abre o arquivo remoto.
TEC_FTC_DECL ftc(const char *id, const char id_size, bool writable, const char *host, unsigned short port, const char *accessKey, const char key_size)
Construtor.
errno_buffer(const char *buffer)
Essa exceção é lançada quando o arquivo está reservado para acesso exclusivo.
TEC_FTC_DECL void setPosition(unsigned long long position)
Posiciona o cursor de leitura no arquivo.
Essa exceção é lançada quando uma operação falha por causa de falta de permissões para realizar-la...
TEC_FTC_DECL unsigned long long read(char *data, unsigned long long nbytes, unsigned long long position)
Le uma quantidade de bytes a partir de uma dada posição.
errno_buffer & operator=(errno_buffer &o)
Define a excecao base da biblioteca FTC.
errno_buffer(errno_buffer_ref r)
void throw_exception(const char *message)
TEC_FTC_DECL ~ftc()
Destrutor.
void recv(socket_type socket, char *buffer, std::size_t size)
TEC_FTC_DECL unsigned long long transferTo(unsigned long long position, unsigned long long nbytes, FILE *fd, char *buffer)
Transfere os dados do arquivo remoto diretamente para um arquivo local.
TEC_FTC_DECL unsigned long long getReadBufferSize()
Retorna o tamanho atual do buffer de leitura.
TEC_FTC_DECL void setSize(unsigned long long size)
Define o tamanho do arquivo. Pode ser usado para alocar um espaço ou truncar o arquivo.
void close(socket_type s)
Essa exceção é lançada quando a chave de acesso utilizada na conexão é inválida.
unsigned long long return_long_long_command(socket_type socket, char command)
void send(socket_type socket, const char *buffer, std::size_t size)
errno_buffer errno_message()
Essa exceção é lançada quando o arquivo não é encontrado no servidor.
TEC_FTC_DECL unsigned long long getPosition()
Retorna a atual posição do cursor de leitura no arquivo.
TEC_FTC_DECL void close()
Fecha o arquivo.
errno_buffer_ref(const char *buffer)
TEC_FTC_DECL void setReadBufferSize(unsigned long long size)
Define o tamanho do buffer de leitura utilizado na leitura do arquivo.
Essa exceção é lançada quando o metodo close é chamado sem que o arquivo remoto esteja aberto...
errno_buffer(errno_buffer &o)