• 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 "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 } AsyncLineReader;
141 
142 /* Setup an AsyncLineReader to read at most 'buffsize' characters (bytes)
143  * into 'buffer'. The reader will stop when it finds a '\n' which will be
144  * part of the buffer by default.
145  *
146  * NOTE: buffsize must be > 0. If not, asyncLineReader_getLine will return
147  *       ASYNC_ERROR with errno == ENOMEM.
148  *
149  *        buffsize must also sufficiently big to hold the final '\n'.
150  *
151  * Also calls loopIo_wantRead(io) for you.
152  */
153 void asyncLineReader_init(AsyncLineReader* alr,
154                           void*            buffer,
155                           size_t           buffsize,
156                           LoopIo*          io);
157 
158 /* Try to read line characters from 'io'.
159  * Returns:
160  *    ASYNC_COMPLETE: An end-of-line was detected, call asyncLineReader_getLine
161  *                    to extract the line content.
162  *
163  *    ASYNC_ERROR: An error occured. Note that in case of disconnection,
164  *                 errno will be set to ECONNRESET, but you should be able
165  *                 to call asyncLineReader_getLine to read the partial line
166  *                 that was read.
167  *
168  *                 In case of overflow, errno will be set to ENOMEM.
169  *
170  *    ASYNC_NEED_MORE: If there was not enough incoming data (or events
171  *                     does not contain LOOP_IO_READ).
172  */
173 AsyncStatus asyncLineReader_read(AsyncLineReader* alr);
174 
175 /* Return a pointer to the NON-ZERO-TERMINATED line characters, if any.
176  * If 'pLength" is not NULL, the function sets '*pLength' to the length
177  * in bytes of the line.
178  *
179  * Returns:
180  *    NULL if 'buffsize' was initially 0, otherwise, a pointer to 'buffer'
181  *    as passed in asyncLineReader_setup().
182  *
183  *    NOTE: The data is *not* zero terminated, but its last character
184  *           should be '\n' unless an error occured.
185  */
186 const char* asyncLineReader_getLineRaw(AsyncLineReader* alr, int *pLength);
187 
188 /* Return a pointer to the ZERO-TERMINATED line, with final '\n' or '\r\n'
189  * stripped. This will be NULL in case of error though.
190  */
191 const char* asyncLineReader_getLine(AsyncLineReader* alr);
192 
193 /**************************************************************************
194  **************************************************************************
195  *****
196  *****  A S Y N C   C O N N E C T O R
197  *****
198  *****/
199 
200 /* Asynchronous connection to a socket
201  */
202 typedef struct {
203     int     error;
204     int     state;
205     LoopIo* io;
206 } AsyncConnector;
207 
208 AsyncStatus
209 asyncConnector_init(AsyncConnector*    ac,
210                     const SockAddress* address,
211                     LoopIo*            io);
212 
213 AsyncStatus
214 asyncConnector_run(AsyncConnector* ac);
215 
216 #endif /* ANDROID_ASYNC_UTILS_H */
217