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