forked from ImortisInglorian/fbrtLib
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdev_file_encod_open.bas
176 lines (139 loc) · 4.02 KB
/
dev_file_encod_open.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/' UTF-encoded file devices open '/
#include "fb.bi"
dim shared as FB_FILE_HOOKS hooks_dev_file = ( _
@fb_DevFileEof, _
@fb_DevFileClose, _
@fb_DevFileSeek, _
@fb_DevFileTell, _
@fb_DevFileReadEncod, _
@fb_DevFileReadEncodWstr, _
@fb_DevFileWriteEncod, _
@fb_DevFileWriteEncodWstr, _
@fb_DevFileLock, _
@fb_DevFileUnlock, _
@fb_DevFileReadLineEncod, _
@fb_DevFileReadLineEncodWstr, _
NULL, _
@fb_DevFileFlush)
extern "C"
private function hCheckBOM( handle as FB_FILE ptr ) as long
dim as long res, bom = 0
dim as FILE ptr fp = cast(FILE ptr, handle->opaque)
if ( handle->mode = FB_FILE_MODE_APPEND ) then
fseek( fp, 0, SEEK_SET )
end if
select case ( handle->encod )
case FB_FILE_ENCOD_UTF8:
if ( fread( @bom, 3, 1, fp ) <> 1 ) then
return 0
end if
res = (bom = &h00BFBBEF)
case FB_FILE_ENCOD_UTF16:
if ( fread( @bom, sizeof( UTF_16 ), 1, fp ) <> 1 ) then
return 0
end if
/' !!!FIXME!!! only litle-endian supported '/
res = (bom = &h0000FEFF)
case FB_FILE_ENCOD_UTF32:
if ( fread( @bom, sizeof( UTF_32 ), 1, fp ) <> 1 ) then
return 0
end if
/' !!!FIXME!!! only litle-endian supported '/
res = (bom = &h0000FEFF)
case else:
res = 0
end select
if ( handle->mode = FB_FILE_MODE_APPEND ) then
fseek( fp, 0, SEEK_END )
end if
return res
end function
private function hWriteBOM( handle as FB_FILE ptr ) as long
dim as long bom
dim as FILE ptr fp = cast(FILE ptr, handle->opaque)
select case ( handle->encod )
case FB_FILE_ENCOD_UTF8:
bom = &h00BFBBEF
if ( fwrite( @bom, 3, 1, fp ) <> 1 ) then
return 0
end if
case FB_FILE_ENCOD_UTF16:
/' !!!FIXME!!! only litle-endian supported '/
bom = &h0000FEFF
if ( fwrite( @bom, sizeof( UTF_16 ), 1, fp ) <> 1 ) then
return 0
end if
case FB_FILE_ENCOD_UTF32:
/' !!!FIXME!!! only litle-endian supported '/
bom = &h0000FEFF
if ( fwrite( @bom, sizeof( UTF_32 ), 1, fp ) <> 1 ) then
return 0
end if
case else:
return 0
end select
return 1
end function
function fb_DevFileOpenEncod ( handle as FB_FILE ptr, filename as ubyte ptr, fname_len as size_t ) as long
dim as FILE ptr fp = NULL
dim as ubyte ptr openmask
dim as ubyte ptr fname
FB_LOCK()
fname = cast(ubyte ptr, malloc(fname_len + 1))
memcpy(fname, filename, fname_len)
fname[fname_len] = 0
/' Convert directory separators to whatever the current platform supports '/
fb_hConvertPath( fname )
handle->hooks = @hooks_dev_file
openmask = NULL
select case ( handle->mode )
case FB_FILE_MODE_APPEND:
/' will create the file if it doesn't exist '/
openmask = sadd("ab")
case FB_FILE_MODE_INPUT:
/' will fail if file doesn't exist '/
openmask = sadd("rb")
case FB_FILE_MODE_OUTPUT:
/' will create the file if it doesn't exist '/
openmask = sadd("wb")
case else:
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL )
end select
/' try opening '/
fp = fopen( fname, openmask )
if ( fp = NULL ) then
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND )
end if
fb_hSetFileBufSize( fp )
handle->opaque = fp
if ( handle->access = FB_FILE_ACCESS_ANY) then
handle->access = FB_FILE_ACCESS_READWRITE
end if
/' handle BOM '/
select case ( handle->mode )
case FB_FILE_MODE_APPEND, FB_FILE_MODE_INPUT:
if ( hCheckBOM( handle ) = 0 ) then
fclose( fp )
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND )
end if
case FB_FILE_MODE_OUTPUT:
if ( hWriteBOM( handle ) = 0 ) then
fclose( fp )
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND )
end if
end select
/' calc file size '/
handle->size = fb_DevFileGetSize( fp, handle->mode, handle->encod, TRUE )
if ( handle->size = -1 ) then
fclose( fp )
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL )
end if
FB_UNLOCK()
return fb_ErrorSetNum( FB_RTERROR_OK )
end function
end extern