Home | History | Annotate | Download | only in android
      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