forked from pieter/gitx
-
Notifications
You must be signed in to change notification settings - Fork 2
/
NSFileHandleExt.m
74 lines (60 loc) · 2.08 KB
/
NSFileHandleExt.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* Extension for NSFileHandle to make it capable of easy network programming
*
* Version 1.0, get the newest from http://michael.stapelberg.de/NSFileHandleExt.php
*
* Copyright 2007 Michael Stapelberg
*
* Distributed under BSD-License, see http://michael.stapelberg.de/BSD.php
*
*/
#define CONN_TIMEOUT 5
#define BUFFER_SIZE 256
@implementation NSFileHandle(NSFileHandleExt)
-(NSString*)readLine {
// If the socket is closed, return an empty string
if ([self fileDescriptor] <= 0)
return @"";
int fd = [self fileDescriptor];
// Allocate BUFFER_SIZE bytes to store the line
int bufferSize = BUFFER_SIZE;
char *buffer = (char*)malloc(bufferSize + 1);
if (buffer == NULL)
[[NSException exceptionWithName:@"No memory left" reason:@"No more memory for allocating buffer" userInfo:nil] raise];
int bytesReceived = 0, n = 1;
while (n > 0) {
n = read(fd, buffer + bytesReceived++, 1);
if (n < 0) {
if (errno == EINTR) {
n = 1;
bytesReceived--;
} else {
[[NSException exceptionWithName:@"Socket error" reason:@"Remote host closed connection" userInfo:nil] raise];
}
}
if (bytesReceived >= bufferSize) {
// Make buffer bigger
bufferSize += BUFFER_SIZE;
buffer = (char*)realloc(buffer, bufferSize + 1);
if (buffer == NULL)
[[NSException exceptionWithName:@"No memory left" reason:@"No more memory for allocating buffer" userInfo:nil] raise];
}
switch (*(buffer + bytesReceived - 1)) {
case '\n':
buffer[bytesReceived-1] = '\0';
NSString* s = [NSString stringWithCString: buffer encoding: NSUTF8StringEncoding];
if ([s length] == 0)
s = [NSString stringWithCString: buffer encoding: NSISOLatin1StringEncoding];
return s;
case '\r':
bytesReceived--;
}
}
buffer[bytesReceived-1] = '\0';
NSString *retVal = [NSString stringWithCString: buffer encoding: NSUTF8StringEncoding];
if ([retVal length] == 0)
retVal = [NSString stringWithCString: buffer encoding: NSISOLatin1StringEncoding];
free(buffer);
return retVal;
}
@end