rocksock_readline: change semantics: trailing \n is removed
[rofl0r-rocksock.git] / rocksock_readline.c
blobc04bef860aedd04edd59c625b0129d4d259248f8
1 /*
2 * author: rofl0r (C) 2011-2013
3 * License: LGPL 2.1+ with static linking exception
4 */
6 #undef _POSIX_C_SOURCE
7 #define _POSIX_C_SOURCE 200809L
8 #undef _GNU_SOURCE
9 #define _GNU_SOURCE
11 #include <stddef.h>
12 #include "rocksock_internal.h"
14 #ifndef ROCKSOCK_FILENAME
15 #define ROCKSOCK_FILENAME __FILE__
16 #endif
18 // tries to read exactly one line, until '\n', then overwrites the \n with \0
19 // bytesread contains the number of bytes read till \n was encountered
20 // (so 0 in case \n was the first char).
21 // returns RS_E_OUT_OF_BUFFER if the line doesnt fit into the buffer.
22 int rocksock_readline(rocksock* sock, char* buffer, size_t bufsize, size_t* bytesread) {
23 // TODO: make more efficient by peeking into the buffer (Flag MSG_PEEK to recv), instead of reading byte by byte
24 // would need a different approach for ssl though.
25 if (!sock) return RS_E_NULL;
26 if (!buffer || !bufsize || !bytesread)
27 return rocksock_seterror(sock, RS_ET_OWN, RS_E_NULL,
28 ROCKSOCK_FILENAME, __LINE__);
29 char* ptr = buffer;
30 size_t bytesread2 = 0;
31 int ret;
32 *bytesread = 0;
33 while(*bytesread < bufsize) {
34 ret = rocksock_recv(sock, ptr, 1, 1, &bytesread2);
35 if(ret || !bytesread2) return ret;
36 *bytesread += bytesread2;
37 if(ptr > buffer + bufsize)
38 break;
39 if(*bytesread > bufsize) {
40 *bytesread = bufsize;
41 break;
43 if(*ptr == '\n') {
44 *ptr = 0;
45 *bytesread -= 1;
46 return 0;
48 ptr++;
50 return rocksock_seterror(sock, RS_ET_OWN, RS_E_OUT_OF_BUFFER,
51 ROCKSOCK_FILENAME, __LINE__);