• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef ANDROID_ASYNC_UTILS_H
17 #define ANDROID_ASYNC_UTILS_H
18 
19 #include "android/looper.h"
20 #include "android/sockets.h"
21 
22 /* A set of useful data types to perform asynchronous operations.
23  *
24  * IMPORTANT NOTE:
25  *    In case of network disconnection, read() and write() just return 0
26  *    the first time they are called. As a convenience, these functions
27  *    will return ASYNC_ERROR and set 'errno' to ECONNRESET instead.
28  */
29 typedef enum {
30     ASYNC_COMPLETE = 0,   /* asynchronous operation completed */
31     ASYNC_ERROR,          /* an error occurred, look at errno */
32     ASYNC_NEED_MORE       /* more data is needed, try again later */
33 } AsyncStatus;
34 
35 /**************************************************************************
36  **************************************************************************
37  *****
38  *****  A S Y N C   R E A D E R
39  *****
40  *****/
41 
42 /* An AsyncReader makes it easier to read a given number of bytes into
43  * a target buffer asynchronously. Usage is the following:
44  *
45  * 1/ setup the reader with asyncReader_init(ar, buffer, buffsize,io);
46  * 2/ call asyncReader_read(ar, io), where 'io' is a LoopIo whenever
47  *    you can receive data, i.e. just after the init() or in your
48  *    own callback.
49  */
50 typedef struct {
51     uint8_t*  buffer;
52     size_t    buffsize;
53     size_t    pos;
54     LoopIo*   io;
55 } AsyncReader;
56 
57 /* Setup an ASyncReader, by giving the address of the read buffer,
58  * and the number of bytes we want to read.
59  *
60  * This also calls loopIo_wantRead(io) for you.
61  */
62 void asyncReader_init(AsyncReader* ar,
63                       void*        buffer,
64                       size_t       buffsize,
65                       LoopIo*      io);
66 
67 /* Try to read data from 'io' and return the state of the read operation.
68  *
69  * Returns:
70  *    ASYNC_COMPLETE: If the read operation was complete. This will also
71  *                    call loopIo_dontWantRead(io) for you.
72  *
73  *    ASYNC_ERROR: If an error occured (see errno). The error will be
74  *                 ECONNRESET in case of disconnection.
75  *
76  *    ASYNC_NEED_MORE: If there was not enough incoming data to complete
77  *                     the read (or if 'events' doesn't contain LOOP_IO_READ).
78  */
79 AsyncStatus  asyncReader_read(AsyncReader*  ar);
80 
81 /**************************************************************************
82  **************************************************************************
83  *****
84  *****  A S Y N C   W R I T E R
85  *****
86  *****/
87 
88 /* An AsyncWriter is the counterpart of an AsyncReader, but for writing
89  * data to a file descriptor asynchronously.
90  */
91 typedef struct {
92     const uint8_t* buffer;
93     size_t         buffsize;
94     size_t         pos;
95     LoopIo*        io;
96 } AsyncWriter;
97 
98 /* Setup an ASyncWriter, by giving the address of the write buffer,
99  * and the number of bytes we want to write.
100  *
101  * This also calls loopIo_wantWrite(io) for you.
102  */
103 void asyncWriter_init(AsyncWriter*  aw,
104                       const void*   buffer,
105                       size_t        buffsize,
106                       LoopIo*       io);
107 
108 /* Try to write data to 'io' and return the state of the write operation.
109  *
110  * Returns:
111  *    ASYNC_COMPLETE: If the write operation was complete. This will also
112  *                    call loopIo_dontWantWrite(io) for you.
113  *
114  *    ASYNC_ERROR: If an error occured (see errno). The error will be
115  *                 ECONNRESET in case of disconnection.
116  *
117  *    ASYNC_NEED_MORE: If not all bytes could be sent yet (or if 'events'
118  *                     doesn't contain LOOP_IO_WRITE).
119  */
120 AsyncStatus asyncWriter_write(AsyncWriter* aw);
121 
122 
123 /**************************************************************************
124  **************************************************************************
125  *****
126  *****  A S Y N C   L I N E   R E A D E R
127  *****
128  *****/
129 
130 /* An AsyncLineReader allows you to read one line of text asynchronously.
131  * The biggest difference with AsyncReader is that you don't know the line
132  * size in advance, so the object will read data byte-by-byte until it
133  * encounters a '\n'.
134  */
135 typedef struct {
136     uint8_t*  buffer;
137     size_t    buffsize;
138     size_t    pos;
139     LoopIo*   io;
140     char      eol;
141 } AsyncLineReader;
142 
143 /* Setup an AsyncLineReader to read at most 'buffsize' characters (bytes)
144  * into 'buffer'. The reader will stop when it finds a '\n' which will be
145  * part of the buffer by default.
146  *
147  * NOTE: buffsize must be > 0. If not, asyncLineReader_getLine will return
148  *       ASYNC_ERROR with errno == ENOMEM.
149  *
150  *        buffsize must also sufficiently big to hold the final '\n'.
151  *
152  * Also calls loopIo_wantRead(io) for you.
153  */
154 void asyncLineReader_init(AsyncLineReader* alr,
155                           void*            buffer,
156                           size_t           buffsize,
157                           LoopIo*          io);
158 
159 /* Sets line terminator character for the reader.
160  * By default, asyncLineReader_init will set EOL to be '\n'. Sometimes it's more
161  * convenient to have '\0' as line terminator, so "line" reader easily becomes
162  * a "string" reader.
163  */
164 AINLINED void
asyncLineReader_setEOL(AsyncLineReader * alr,char eol)165 asyncLineReader_setEOL(AsyncLineReader* alr, char eol)
166 {
167     alr->eol = eol;
168 }
169 
170 /* Try to read line characters from 'io'.
171  * Returns:
172  *    ASYNC_COMPLETE: An end-of-line was detected, call asyncLineReader_getLine
173  *                    to extract the line content.
174  *
175  *    ASYNC_ERROR: An error occured. Note that in case of disconnection,
176  *                 errno will be set to ECONNRESET, but you should be able
177  *                 to call asyncLineReader_getLine to read the partial line
178  *                 that was read.
179  *
180  *                 In case of overflow, errno will be set to ENOMEM.
181  *
182  *    ASYNC_NEED_MORE: If there was not enough incoming data (or events
183  *                     does not contain LOOP_IO_READ).
184  */
185 AsyncStatus asyncLineReader_read(AsyncLineReader* alr);
186 
187 /* Return a pointer to the NON-ZERO-TERMINATED line characters, if any.
188  * If 'pLength" is not NULL, the function sets '*pLength' to the length
189  * in bytes of the line.
190  *
191  * Returns:
192  *    NULL if 'buffsize' was initially 0, otherwise, a pointer to 'buffer'
193  *    as passed in asyncLineReader_setup().
194  *
195  *    NOTE: The data is *not* zero terminated, but its last character
196  *           should be '\n' unless an error occured.
197  */
198 const char* asyncLineReader_getLineRaw(AsyncLineReader* alr, int *pLength);
199 
200 /* Return a pointer to the ZERO-TERMINATED line, with final '\n' or '\r\n'
201  * stripped. This will be NULL in case of error though.
202  */
203 const char* asyncLineReader_getLine(AsyncLineReader* alr);
204 
205 /**************************************************************************
206  **************************************************************************
207  *****
208  *****  A S Y N C   C O N N E C T O R
209  *****
210  *****/
211 
212 /* Asynchronous connection to a socket
213  */
214 typedef struct {
215     int     error;
216     int     state;
217     LoopIo* io;
218 } AsyncConnector;
219 
220 AsyncStatus
221 asyncConnector_init(AsyncConnector*    ac,
222                     const SockAddress* address,
223                     LoopIo*            io);
224 
225 AsyncStatus
226 asyncConnector_run(AsyncConnector* ac);
227 
228 /* Stops connection in progress.
229  * Return:
230  *  0 if connection in progress has been stopped, or -1 if no connection has been
231  *  in progress.
232  */
233 int
234 asyncConnector_stop(AsyncConnector* ac);
235 
236 #endif /* ANDROID_ASYNC_UTILS_H */
237