FreeBASIC
0.91.0
Main Page
Data Structures
Files
File List
Globals
file_lineinp.c
Go to the documentation of this file.
1
/* line input function */
2
3
#include "
fb.h
"
4
5
#define BUFFER_LEN 1024
6
7
typedef
enum
_eInputMode
{
8
eIM_Invalid
,
9
eIM_ReadLine
,
10
eIM_Read
11
}
eInputMode
;
12
13
static
int
fb_hFileLineInputEx
14
(
15
FB_FILE
*
handle
,
16
void
*dst,
17
ssize_t dst_len,
18
int
fillrem
19
)
20
{
21
ssize_t len, readlen;
22
char
buffer
[
BUFFER_LEN
];
23
eInputMode
mode =
eIM_Invalid
;
24
25
if
( !
FB_HANDLE_USED
(handle) )
26
return
fb_ErrorSetNum
(
FB_RTERROR_ILLEGALFUNCTIONCALL
);
27
28
FB_LOCK
();
29
30
if
( handle->
hooks
->
pfnReadLine
!=
NULL
) {
31
mode =
eIM_ReadLine
;
32
}
else
if
( handle->
hooks
->
pfnRead
!=
NULL
&&
33
handle->
hooks
->
pfnEof
!=
NULL
)
34
{
35
mode =
eIM_Read
;
36
}
37
38
if
( mode==
eIM_Invalid
) {
39
FB_UNLOCK
();
40
return
fb_ErrorSetNum
(
FB_RTERROR_ILLEGALFUNCTIONCALL
);
41
}
42
43
switch
( mode ) {
44
case
eIM_Read
:
45
/* This is the VFS-compatible way to read a line ... but it's slow */
46
len = readlen = 0;
47
while
(!handle->
hooks
->
pfnEof
(handle)) {
48
int
do_add =
FALSE
, do_break =
FALSE
;
49
size_t
read_len;
50
int
res =
fb_FileGetDataEx
( handle, 0, buffer+len, 1, &read_len,
FALSE
,
FALSE
);
51
if
( res==
FB_RTERROR_OK
&& read_len==1) {
52
char
ch = buffer[len];
53
if
( ch==13 ) {
54
res =
fb_FileGetDataEx
( handle, 0, &ch, 1, &read_len,
FALSE
,
FALSE
);
55
if
( res==
FB_RTERROR_OK
&& ch!=10 && read_len==1) {
56
fb_FilePutBackEx
( handle, &ch, 1 );
57
}
58
ch = 10;
59
}
60
if
( ch==10 ) {
61
do_add = do_break =
TRUE
;
62
}
else
{
63
do_add = len==(
sizeof
(
buffer
)-1);
64
}
65
}
else
{
66
do_add = len!=0;
67
}
68
if
( do_add || handle->
hooks
->
pfnEof
( handle ) ) {
69
/* create temporary string to ensure that NUL's are preserved ...
70
* this function wants the length WITH the NUL character!!! */
71
buffer[len] = 0;
72
FBSTRING
*src =
fb_StrAllocTempDescF
( buffer, len + 1);
73
if
( readlen==0 ) {
74
fb_StrAssign
( dst, dst_len, src, -1, fillrem );
75
}
else
{
76
fb_StrConcatAssign
( dst, dst_len, src, -1, fillrem );
77
}
78
readlen += len;
79
len = 0;
80
}
else
{
81
++len;
82
}
83
if
( res!=
FB_RTERROR_OK
|| do_break )
84
break
;
85
}
86
if
( readlen == 0 ) {
87
/* del destine string */
88
if
( dst_len == -1 )
89
fb_StrDelete
( (
FBSTRING
*)dst );
90
else
91
*(
char
*)dst =
'\0'
;
92
}
93
break
;
94
case
eIM_ReadLine
:
95
/* The read line mode is the most comfortable ... but IMHO it's
96
* only useful for special devices (like SCRN:) */
97
{
98
/* destine is a var-len string? read directly */
99
if
( dst_len == -1 )
100
{
101
handle->
hooks
->
pfnReadLine
( handle, dst );
102
}
103
/* fixed-len or unknown size (ie: pointers)? use a temp var-len */
104
else
105
{
106
FBSTRING
str_result = { 0 };
107
108
/* read complete line (may include NULs) */
109
handle->
hooks
->
pfnReadLine
( handle, &str_result );
110
111
/* add contents of tempporary string to result buffer */
112
fb_StrAssign
( dst, dst_len, (
void
*)&str_result, -1, fillrem );
113
114
/* delete result */
115
fb_StrDelete
( &str_result );
116
}
117
118
}
119
break
;
120
case
eIM_Invalid
:
121
/* the "invalid" mode was already handled above ... so we don't
122
* need to do anything here ... */
123
break
;
124
}
125
126
FB_UNLOCK
();
127
128
return
fb_ErrorSetNum
(
FB_RTERROR_OK
);
129
}
130
131
FBCALL
int
fb_FileLineInput
(
int
fnum,
void
*dst, ssize_t dst_len,
int
fillrem )
132
{
133
return
fb_hFileLineInputEx
(
FB_FILE_TO_HANDLE
(fnum), dst, dst_len, fillrem );
134
}
rtlib
file_lineinp.c
Generated on Thu Jan 23 2014 19:40:11 for FreeBASIC by
1.8.4