home *** CD-ROM | disk | FTP | other *** search
- #include "async.h"
-
- #ifndef MIN
- #define MIN(a,b) ( ( a ) < ( b ) ? ( a ) : ( b ) )
- #endif
-
-
- _ASM _ARGS LONG
- ReadLineAsync( _REG( a0 ) AsyncFile *file, _REG( a1 ) STRPTR buffer, _REG( d0 ) LONG bufSize )
- {
- /* Optimizations... Perhaps I should leave that for the compiler? :) */
- LONG ch, /* Read char */
- left, /* Bytes left in user buffer */
- bytesLeft; /* Bytes left in asyncio buffer */
- UBYTE *offset, /* Buffer with unread data */
- sch; /* Dummy read buffer */
-
- left = bufSize;
- bytesLeft = file->af_BytesLeft;
- offset = file->af_Offset;
-
- /* I find this implementation rather messy, but I don't
- * really know how to improve the readability while keeping
- * it (small and) fast! I do _not_ want to call
- * ReadCharAsync() for each char... ;)
- */
-
- do
- {
- /* Empty read buffer? */
- if( !bytesLeft )
- {
- /* Yep, refill it. af_Offset doesn't need to be set. */
- file->af_BytesLeft = 0;
-
- if( !( ch = ReadAsync( file, &sch, 1 ) ) )
- {
- break; /* EOF */
- }
-
- /* Reset variables. -+1 to "undo" the above read.
- * That way we don't need to handle the char
- * just read here.
- */
- offset = file->af_Offset - 1;
- bytesLeft = file->af_BytesLeft + 1;
- }
- else
- {
- if( left )
- {
- /* There is space left in the user buffer, so
- * copy as much as we can to it.
- */
- LONG i, j;
-
- i = j = MIN( bytesLeft, left );
-
- /* Copy string to buffer */
- do
- {
- ch = *buffer++ = *offset++;
- --i;
- } while( i && ( ch != '\n' ) );
-
- i = j - i; /* Number of bytes copied */
- bytesLeft -= i; /* Want to keep these out of */
- left -= i; /* the while loop above... */
- }
- else
- {
- /* Skip to EOL */
- do
- {
- ch = *offset++;
- } while( --bytesLeft && ( ch != '\n' ) );
- }
- }
- } while( ch != '\n' );
-
- /* Restore AsyncIO variables.. */
- file->af_BytesLeft = bytesLeft;
- file->af_Offset = offset;
-
- /* Truncate buffer correctly */
- if( !left )
- {
- /* Buffer is full, so overwrite last byte with terminating null */
- --buffer;
-
- /* Don't include NULL in return count */
- ++left;
-
- if( ch == '\n' )
- {
- /* LF must be the last char in the string */
- *( buffer - 1 ) = ch;
- }
- }
-
- *buffer = 0;
-
- if( ch == -1 )
- {
- /* Return error */
- return( -1 );
- }
- else
- {
- /* Return number of bytes read into buffer */
- return( bufSize - left );
- }
- }
-