ObjFW  Diff

Differences From Artifact [74effa40b4]:

To Artifact [d1cbeea7d2]:


27
28
29
30
31
32
33
34

35
36

37
38
39
40
41
42
43
27
28
29
30
31
32
33

34
35

36
37
38
39
40
41
42
43







-
+

-
+







#import "OFString.h"

@class OFStream;
@class OFDataArray;
@class OFException;

#ifdef OF_HAVE_BLOCKS
typedef BOOL (^of_stream_async_read_block_t)(OFStream*, void*, size_t,
typedef bool (^of_stream_async_read_block_t)(OFStream*, void*, size_t,
    OFException*);
typedef BOOL (^of_stream_async_read_line_block_t)(OFStream*, OFString*,
typedef bool (^of_stream_async_read_line_block_t)(OFStream*, OFString*,
    OFException*);
#endif

/*!
 * @brief A base class for different types of streams.
 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
55
56
57
58
59
60
61
62

63
64
65
66
67
68



69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
55
56
57
58
59
60
61

62
63
64
65



66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+



-
-
-
+
+
+







-
+







 *	 override these methods without the lowlevel prefix, you *will* break
 *	 caching and get broken results!
 */
@interface OFStream: OFObject <OFCopying>
{
	char *_readBuffer, *_writeBuffer;
	size_t _readBufferLength, _writeBufferLength;
	BOOL _writeBufferEnabled, _blocking, _waitingForDelimiter;
	bool _writeBufferEnabled, _blocking, _waitingForDelimiter;
}

#ifdef OF_HAVE_PROPERTIES
@property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled;
@property (getter=isBlocking) BOOL blocking;
@property (readonly, getter=isAtEndOfStream) BOOL atEndOfStream;
@property (getter=isWriteBufferEnabled) bool writeBufferEnabled;
@property (getter=isBlocking) bool blocking;
@property (readonly, getter=isAtEndOfStream) bool atEndOfStream;
#endif

/*!
 * @brief Returns a boolean whether the end of the stream has been reached.
 *
 * @return A boolean whether the end of the stream has been reached
 */
- (BOOL)isAtEndOfStream;
- (bool)isAtEndOfStream;

/*!
 * @brief Reads *at most* size bytes from the stream into a buffer.
 *
 * On network streams, this might read less than the specified number of bytes.
 * If you want to read exactly the specified number of bytes, use
 * @ref readIntoBuffer:exactLength:. Note that a read can even return 0 bytes -
121
122
123
124
125
126
127
128

129
130
131
132


133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159


160
161

162
163
164
165
166
167
168
121
122
123
124
125
126
127

128
129
130


131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157


158
159
160

161
162
163
164
165
166
167
168







-
+


-
-
+
+

-
+




















-
+


-
-
+
+

-
+







 * you still need to check @ref isAtEndOfStream.
 *
 * @param buffer The buffer into which the data is read.
 *		 The buffer must not be free'd before the async read completed!
 * @param length The length of the data that should be read at most.
 *		 The buffer *must* be *at least* this big!
 * @param target The target on which the selector should be called when the
 *		 data has been received. If the method returns YES, it will be
 *		 data has been received. If the method returns true, it will be
 *		 called again with the same buffer and maximum length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   bool (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 */
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		     target: (id)target
		   selector: (SEL)selector;

/*!
 * @brief Asyncronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
 * Unlike @ref asyncReadIntoBuffer:length:target:selector:, this method does
 * not call the method when less than the specified length has been read -
 * instead, it waits until it got exactly the specified length, the stream has
 * ended or an exception occurred.
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read.
 *		 The buffer *must* be *at least* this big!
 * @param target The target on which the selector should be called when the
 *		 data has been received. If the method returns YES, it will be
 *		 data has been received. If the method returns true, it will be
 *		 called again with the same buffer and exact length when more
 *		 data has been received. If you want the next method in the
 *		 queue to handle the data received next, you need to return NO
 *		 from the method.
 *		 queue to handle the data received next, you need to return
 *		 false from the method.
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, void *buffer, size_t size,
 *		   bool (OFStream *stream, void *buffer, size_t size,
 *		   OFException *exception).
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
		 exactLength: (size_t)length
		      target: (id)target
		    selector: (SEL)selector;

178
179
180
181
182
183
184
185

186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
178
179
180
181
182
183
184

185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209

210
211
212
213
214
215
216
217







-
+


-
+


















-
+


-
+







 * you still need to check @ref isAtEndOfStream.
 *
 * @param buffer The buffer into which the data is read.
 *		 The buffer must not be free'd before the async read completed!
 * @param length The length of the data that should be read at most.
 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again with the same
 *		If the block returns true, it will be called again with the same
 *		buffer and maximum length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return NO from the block.
 *		received next, you need to return false from the block.
 */
- (void)asyncReadIntoBuffer: (void*)buffer
		     length: (size_t)length
		      block: (of_stream_async_read_block_t)block;

/*!
 * @brief Asyncronously reads exactly the specified length bytes from the
 *	  stream into a buffer.
 *
 * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke
 * the block when less than the specified length has been read - instead, it
 * waits until it got exactly the specified length, the stream has ended or an
 * exception occurred.
 *
 * @param buffer The buffer into which the data is read
 * @param length The length of the data that should be read.
 *		 The buffer *must* be *at least* this big!
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again with the same
 *		If the block returns true, it will be called again with the same
 *		buffer and exact length when more data has been received. If
 *		you want the next block in the queue to handle the data
 *		received next, you need to return NO from the block.
 *		received next, you need to return false from the block.
 */
 - (void)asyncReadIntoBuffer: (void*)buffer
		 exactLength: (size_t)length
		       block: (of_stream_async_read_block_t)block;
#endif

/*!
561
562
563
564
565
566
567
568

569
570
571

572
573

574
575
576
577
578
579
580
581
582
583
584
585

586
587
588

589
590

591
592
593
594
595
596
597
598
599
600
601
602
603

604
605


606
607
608
609
610
611
612
613
614
615

616
617


618
619
620
621
622
623
624
561
562
563
564
565
566
567

568
569
570

571
572

573
574
575
576
577
578
579
580
581
582
583
584

585
586
587

588
589

590
591
592
593
594
595
596
597
598
599
600
601
602

603
604

605
606
607
608
609
610
611
612
613
614
615

616
617

618
619
620
621
622
623
624
625
626







-
+


-
+

-
+











-
+


-
+

-
+












-
+

-
+
+









-
+

-
+
+







- (OFString*)readLineWithEncoding: (of_string_encoding_t)encoding;

/*!
 * @brief Asyncronously reads until a newline, \\0, end of stream or an
 *	  exception occurs.
 *
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 been received. If the method returns true, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 *		 return false from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   bool (OFStream *stream, OFString *line,
 *		   OFException *exception).
 */
- (void)asyncReadLineWithTarget: (id)target
		       selector: (SEL)selector;

/*!
 * @brief Asyncronously reads with the specified encoding until a newline, \\0,
 *	  end of stream or an exception occurs.
 *
 * @param encoding The encoding used by the stream
 * @param target The target on which to call the selector when the data has
 *		 been received. If the method returns YES, it will be called
 *		 been received. If the method returns true, it will be called
 *		 again when the next line has been received. If you want the
 *		 next method in the queue to handle the next line, you need to
 *		 return NO from the method
 *		 return false from the method
 * @param selector The selector to call on the target. The signature must be
 *		   BOOL (OFStream *stream, OFString *line,
 *		   bool (OFStream *stream, OFString *line,
 *		   OFException *exception).
 */
- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			   target: (id)target
			 selector: (SEL)selector;

#ifdef OF_HAVE_BLOCKS
/*!
 * @brief Asyncronously reads until a newline, \\0, end of stream or an
 *	  exception occurs.
 *
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again when the next
 *		If the block returns true, it will be called again when the next
 *		line has been received. If you want the next block in the queue
 *		to handle the next line, you need to return NO from the block.
 *		to handle the next line, you need to return false from the
 *		block.
 */
- (void)asyncReadLineWithBlock: (of_stream_async_read_line_block_t)block;

/*!
 * @brief Asyncronously reads with the specified encoding until a newline, \\0,
 *	  end of stream or an exception occurs.
 *
 * @param encoding The encoding used by the stream
 * @param block The block to call when the data has been received.
 *		If the block returns YES, it will be called again when the next
 *		If the block returns true, it will be called again when the next
 *		line has been received. If you want the next block in the queue
 *		to handle the next line, you need to return NO from the block.
 *		to handle the next line, you need to return false from the
 *		block.
 */
- (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding
			    block: (of_stream_async_read_line_block_t)block;
#endif

/*!
 * @brief Tries to read a line from the stream (see readLine) and returns nil if
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701

702
703
704
705
706
707
708
689
690
691
692
693
694
695

696
697
698
699
700
701
702

703
704
705
706
707
708
709
710







-
+






-
+







			 encoding: (of_string_encoding_t)encoding;

/*!
 * @brief Returns a boolen whether writes are buffered.
 *
 * @return A boolean whether writes are buffered
 */
- (BOOL)isWriteBufferEnabled;
- (bool)isWriteBufferEnabled;

/*!
 * @brief Enables or disables the write buffer.
 *
 * @param enable Whether the write buffer should be enabled or disabled
 */
- (void)setWriteBufferEnabled: (BOOL)enable;
- (void)setWriteBufferEnabled: (bool)enable;

/*!
 * @brief Writes everythig in the write buffer to the stream.
 */
- (void)flushWriteBuffer;

/*!
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015







-
+









-
+







- (size_t)numberOfBytesInReadBuffer;

/*!
 * @brief Returns whether the stream is in blocking mode.
 *
 * @return Whether the stream is in blocking mode
 */
- (BOOL)isBlocking;
- (bool)isBlocking;

/*!
 * @brief Enables or disables non-blocking I/O.
 *
 * By default, a stream is in blocking mode.
 * On Win32, this currently only works for sockets!
 *
 * @param enable Whether the stream should be blocking
 */
- (void)setBlocking: (BOOL)enable;
- (void)setBlocking: (bool)enable;

/*!
 * @brief Returns the file descriptor for the read end of the stream.
 *
 * @return The file descriptor for the read end of the stream
 */
- (int)fileDescriptorForReading;
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071

1072
1064
1065
1066
1067
1068
1069
1070

1071
1072

1073
1074







-
+

-
+

 * @warning Do not call this directly!
 *
 * Override this method with your actual end of stream checking implementation
 * when subclassing!
 *
 * @return Whether the lowlevel is at the end of the stream
 */
- (BOOL)lowlevelIsAtEndOfStream;
- (bool)lowlevelIsAtEndOfStream;

- (BOOL)OF_isWaitingForDelimiter;
- (bool)OF_isWaitingForDelimiter;
@end