int fb_DevFileReadLineEncodWstr( FB_FILE *handle, FB_WCHAR *dst, ssize_t max_chars )
{
	int res;

	FB_LOCK();

	FILE* fp = (FILE *)handle->opaque;
	if( fp == stdout || fp == stderr )
		fp = stdin;

	if( fp == NULL ) {
		FB_UNLOCK();
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
	}

	/* Clear string first, we're only using += concat assign below... */
	dst[0] = _LC('\0');

	/* Read one byte at a time until CR and/or LF is found.
	   The fb_FileGetDataEx() will handle the decoding. The length to read
	   is specified in wchars, not bytes, because we're passing TRUE for
	   is_unicode. */
	while( TRUE ) {
		FB_WCHAR c[2];
		size_t len;

		res = fb_FileGetDataEx( handle, 0, c, 1, &len, FALSE, TRUE );
		if( (res != FB_RTERROR_OK) || (len == 0) )
			break;

		/* CR? Check for following LF too, and skip it if it's there */
		if( c[0] == _LC('\r') ) {
			res = fb_FileGetDataEx( handle, 0, c, 1, &len, FALSE, TRUE );
			if( (res != FB_RTERROR_OK) || (len == 0) )
				break;

			/* No LF? Ok then, don't skip it yet */
			if( c[0] != _LC('\n') )
				fb_FilePutBackEx( handle, c, 1 );

			break;
		}

		/* LF? */
		if( c[0] == _LC('\n') ) {
			break;
		}

		/* Any other char? Append to string, and continue... */
		c[1] = _LC('\0');
		fb_WstrConcatAssign( dst, max_chars, c );
	}

	FB_UNLOCK();

	return res;
}
示例#2
0
/*:::::*/
static FB_WCHAR hReadChar( FB_INPUTCTX *ctx )
{
    /* device? */
    if( FB_HANDLE_USED(ctx->handle) )
    {
        int res;
        FB_WCHAR c;

        size_t len;
        res = fb_FileGetDataEx( ctx->handle, 0, &c, 1, &len, FALSE, TRUE );
        if( (res != FB_RTERROR_OK) || (len == 0) )
            return WEOF;

        return c;
    }
    /* console.. */
    else
    {
		if( ctx->index >= FB_STRSIZE( &ctx->str.len ) )
			return WEOF;
		else
			return (unsigned char)ctx->str.data[ctx->index++];
	}

}
示例#3
0
/*:::::*/
int fb_FileGetWstrEx( FB_FILE *handle, fb_off_t pos, FB_WCHAR *dst, int dst_chars, size_t *bytesread )
{
    int res;

	if( bytesread )
		*bytesread = 0;

    if( !FB_HANDLE_USED(handle) )
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );

	/* perform call ... but only if there's data ... */
    if( (dst != NULL) && (dst_chars > 0) )
    {
        size_t chars;
        res = fb_FileGetDataEx( handle, pos, (void *)dst, dst_chars, &chars, TRUE, TRUE );

        /* add the null-term */
        if( res == FB_RTERROR_OK )
        	dst[chars] = _LC('\0');

		if( bytesread )
			*bytesread = chars;
    }
    else
		res = fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );

	return res;
}
示例#4
0
/*:::::*/
static int hReadChar
	(
		FB_INPUTCTX *ctx
	)
{
    /* device? */
    if( FB_HANDLE_USED(ctx->handle) )
    {
        int res;
        int c;

        size_t len;
        res = fb_FileGetDataEx( ctx->handle, 0, &c, 1, &len, FALSE, FALSE );
        if( (res != FB_RTERROR_OK) || (len == 0) )
            return EOF;

        return c & 0x000000FF;
    }
    /* console.. */
    else
    {
		if( ctx->index >= FB_STRSIZE( &ctx->str ) )
			return EOF;
		else
			return ctx->str.data[ctx->index++];
	}

}
示例#5
0
/*:::::*/
FBCALL int fb_FileGetLargeIOB( int fnum, long long pos, void *dst, unsigned int chars, unsigned int *bytesread )
{
	return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum), 
							 pos, 
							 dst, 
							 chars, 
							 bytesread, 
							 TRUE, 
							 FALSE );
}
示例#6
0
/*:::::*/
FBCALL int fb_FileGetLarge( int fnum, long long pos, void *dst, unsigned int chars )
{
	return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum), 
							 pos, 
							 dst, 
							 chars, 
							 NULL, 
							 TRUE, 
							 FALSE );
}
示例#7
0
/* Can fb_FileGetData() be removed? it's not used by the rtlib
 * nor is it referenced by fbc?  Compatibility with old libs? [jeffm]
 */
int fb_FileGetData( int fnum, fb_off_t pos, void *dst, size_t chars, int adjust_rec_pos )
{
    return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
    						 pos,
    						 dst,
    						 chars,
							 NULL,
    						 adjust_rec_pos,
    						 FALSE );
}
示例#8
0
static int fb_hFileLineInputEx
	(
		FB_FILE *handle,
		void *dst,
		ssize_t dst_len,
		int fillrem
	)
{
	ssize_t len, readlen;
	char		buffer[BUFFER_LEN];
    eInputMode  mode = eIM_Invalid;

    if( !FB_HANDLE_USED(handle) )
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );

    FB_LOCK();

    if( handle->hooks->pfnReadLine != NULL ) {
        mode = eIM_ReadLine;
    } else if( handle->hooks->pfnRead != NULL &&
               handle->hooks->pfnEof != NULL )
    {
        mode = eIM_Read;
    }

    if( mode==eIM_Invalid ) {
        FB_UNLOCK();
        return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
    }

    switch( mode ) {
    case eIM_Read:
        /* This is the VFS-compatible way to read a line ... but it's slow */
        len = readlen = 0;
        while (!handle->hooks->pfnEof(handle)) {
            int do_add = FALSE, do_break = FALSE;
            size_t read_len;
            int res = fb_FileGetDataEx( handle, 0, buffer+len, 1, &read_len, FALSE, FALSE );
            if( res==FB_RTERROR_OK && read_len==1) {
                char ch = buffer[len];
                if( ch==13 ) {
                    res = fb_FileGetDataEx( handle, 0, &ch, 1, &read_len, FALSE, FALSE );
                    if( res==FB_RTERROR_OK && ch!=10 && read_len==1) {
                        fb_FilePutBackEx( handle, &ch, 1 );
                    }
                    ch = 10;
                }
                if( ch==10 ) {
                    do_add = do_break = TRUE;
                } else {
                    do_add = len==(sizeof(buffer)-1);
                }
            } else {
                do_add = len!=0;
            }
            if( do_add || handle->hooks->pfnEof( handle ) ) {
                /* create temporary string to ensure that NUL's are preserved ...
                 * this function wants the length WITH the NUL character!!! */
                buffer[len] = 0;
                FBSTRING *src = fb_StrAllocTempDescF( buffer, len + 1);
                if( readlen==0 ) {
                    fb_StrAssign( dst, dst_len, src, -1, fillrem );
                } else {
                    fb_StrConcatAssign ( dst, dst_len, src, -1, fillrem );
                }
                readlen += len;
                len = 0;
            } else {
                ++len;
            }
            if( res!=FB_RTERROR_OK || do_break )
                break;
        }
        if( readlen == 0 ) {
            /* del destine string */
            if( dst_len == -1 )
                fb_StrDelete( (FBSTRING *)dst );
            else
                *(char *)dst = '\0';
        }
        break;
    case eIM_ReadLine:
        /* The read line mode is the most comfortable ... but IMHO it's
         * only useful for special devices (like SCRN:) */
        {
            /* destine is a var-len string? read directly */
            if( dst_len == -1 )
            {
            	handle->hooks->pfnReadLine( handle, dst );
            }
            /* fixed-len or unknown size (ie: pointers)? use a temp var-len */
            else
            {
			FBSTRING str_result = { 0, 0, 0 };

            	/* read complete line (may include NULs) */
            	handle->hooks->pfnReadLine( handle, &str_result );

            	/* add contents of tempporary string to result buffer */
            	fb_StrAssign( dst, dst_len, (void *)&str_result, -1, fillrem );

            	/* delete result */
            	fb_StrDelete( &str_result );
            }

        }
        break;
    case eIM_Invalid:
        /* the "invalid" mode was already handled above ... so we don't
         * need to do anything here ... */
        break;
    }

    FB_UNLOCK();

	return fb_ErrorSetNum( FB_RTERROR_OK );
}
示例#9
0
FBCALL FB_WCHAR *fb_FileWstrInput( ssize_t chars, int fnum )
{
    FB_FILE *handle;
	FB_WCHAR *dst;
    size_t len;
    int res = FB_RTERROR_OK;

	fb_DevScrnInit_ReadWstr( );

	FB_LOCK();

    handle = FB_FILE_TO_HANDLE(fnum);
    if( !FB_HANDLE_USED(handle) )
    {
		FB_UNLOCK();
		return NULL;
	}

    dst = fb_wstr_AllocTemp( chars );
    if( dst != NULL )
    {
        ssize_t read_chars = 0;
        if( FB_HANDLE_IS_SCREEN(handle) )
        {
            while( read_chars != chars )
            {
                res = fb_FileGetDataEx( handle,
                                        0,
                                        (void *)&dst[read_chars],
										chars - read_chars,
                                        &len,
                                        TRUE,
                                        TRUE );
                if( res != FB_RTERROR_OK )
                    break;

                read_chars += len;
            }
        }
        else
        {
            res = fb_FileGetDataEx( handle,
                                    0,
                                    (void *)dst,
									chars,
                                    &len,
                                    TRUE,
                                    TRUE );
			read_chars = chars;
        }

		if( res == FB_RTERROR_OK )
		{
			dst[read_chars] = _LC('\0');
		}
		else
		{
			fb_wstr_Del( dst );
			dst = NULL;
		}

    }
    else
        res = FB_RTERROR_OUTOFMEM;

	FB_UNLOCK();

    return dst;
}