source: trunk/gcc/libjava/java/io/natFileDescriptorWin32.cc

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.7 KB
Line 
1// natFileDescriptorWin32.cc - Native part of FileDescriptor class.
2
3/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
4 Foundation, Inc.
5
6 This file is part of libgcj.
7
8This software is copyrighted work licensed under the terms of the
9Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10details. */
11
12// FIXME: In order to support interrupting of IO operations, we
13// need to change to use the windows asynchronous IO functions
14
15#include <config.h>
16
17#include <stdio.h>
18#include <string.h>
19
20#include <windows.h>
21#undef STRICT
22
23#include <gcj/cni.h>
24#include <jvm.h>
25#include <java/io/FileDescriptor.h>
26#include <java/io/SyncFailedException.h>
27#include <java/io/IOException.h>
28#include <java/io/InterruptedIOException.h>
29#include <java/io/EOFException.h>
30#include <java/lang/ArrayIndexOutOfBoundsException.h>
31#include <java/lang/NullPointerException.h>
32#include <java/lang/String.h>
33#include <java/lang/Thread.h>
34#include <java/io/FileNotFoundException.h>
35
36// FIXME: casting a FILE (pointer) to a jint will not work on Win64 --
37// we should be using gnu.gcj.RawData's.
38
39void
40java::io::FileDescriptor::init(void)
41{
42 in = new java::io::FileDescriptor((jint)(GetStdHandle (STD_INPUT_HANDLE)));
43 out = new java::io::FileDescriptor((jint)(GetStdHandle (STD_OUTPUT_HANDLE)));
44 err = new java::io::FileDescriptor((jint)(GetStdHandle (STD_ERROR_HANDLE)));
45}
46
47static char *
48winerr (void)
49{
50 static LPVOID last = NULL;
51 LPVOID old = NULL;
52
53 if (last)
54 old = last;
55
56 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
57 FORMAT_MESSAGE_FROM_SYSTEM |
58 FORMAT_MESSAGE_IGNORE_INSERTS,
59 NULL,
60 GetLastError(),
61 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
62 (LPTSTR) &last,
63 0,
64 NULL);
65
66 if (old)
67 LocalFree (old);
68
69 return (char *)last;
70}
71
72jboolean
73java::io::FileDescriptor::valid (void) {
74 BY_HANDLE_FILE_INFORMATION info;
75 return GetFileInformationByHandle ((HANDLE)fd, &info) != 0;
76}
77
78void
79java::io::FileDescriptor::sync (void) {
80 if (! FlushFileBuffers ((HANDLE)fd))
81 throw new SyncFailedException (JvNewStringLatin1 (winerr ()));
82}
83
84jint
85java::io::FileDescriptor::open (jstring path, jint jflags) {
86
87 HANDLE handle = NULL;
88 DWORD access = 0;
89 DWORD create = OPEN_EXISTING;
90 char buf[MAX_PATH] = "";
91
92 jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf);
93 buf[total] = '\0';
94
95 JvAssert((jflags & READ) || (jflags & WRITE));
96
97 if ((jflags & READ) && (jflags & WRITE))
98 {
99 access = GENERIC_READ | GENERIC_WRITE;
100 if (jflags & APPEND)
101 create = OPEN_ALWAYS;
102 else
103 create = CREATE_ALWAYS;
104 }
105 else if(jflags & READ)
106 access = GENERIC_READ;
107 else
108 {
109 access = GENERIC_WRITE;
110 if (jflags & APPEND)
111 create = OPEN_ALWAYS;
112 else
113 create = CREATE_ALWAYS;
114 }
115
116 handle = CreateFile(buf, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, 0, NULL);
117
118 if (handle == INVALID_HANDLE_VALUE)
119 {
120 char msg[MAX_PATH + 1000];
121 sprintf (msg, "%s: %s", buf, winerr ());
122 throw new FileNotFoundException (JvNewStringLatin1 (msg));
123 }
124
125 // For APPEND mode, move the file pointer to the end of the file.
126 if (jflags & APPEND)
127 {
128 DWORD low = SetFilePointer (handle, 0, NULL, FILE_END);
129 if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
130 throw new FileNotFoundException (JvNewStringLatin1 (winerr ()));
131 }
132 return (jint)handle;
133}
134
135void
136java::io::FileDescriptor::write (jint b)
137{
138 DWORD bytesWritten;
139 jbyte buf = (jbyte)b;
140
141 if (WriteFile ((HANDLE)fd, &buf, 1, &bytesWritten, NULL))
142 {
143 if (java::lang::Thread::interrupted())
144 {
145 InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
146 iioe->bytesTransferred = bytesWritten;
147 throw iioe;
148 }
149 if (bytesWritten != 1)
150 throw new IOException (JvNewStringLatin1 (winerr ()));
151 }
152 else
153 throw new IOException (JvNewStringLatin1 (winerr ()));
154 // FIXME: loop until bytesWritten == 1
155}
156
157void
158java::io::FileDescriptor::write(jbyteArray b, jint offset, jint len)
159{
160 if (! b)
161 throw new java::lang::NullPointerException;
162 if(offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
163 throw new java::lang::ArrayIndexOutOfBoundsException;
164
165 jbyte *buf = elements (b) + offset;
166 DWORD bytesWritten;
167 if (WriteFile ((HANDLE)fd, buf, len, &bytesWritten, NULL))
168 {
169 if (java::lang::Thread::interrupted())
170 {
171 InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
172 iioe->bytesTransferred = bytesWritten;
173 throw iioe;
174 }
175 }
176 else
177 throw new IOException (JvNewStringLatin1 (winerr ()));
178 // FIXME: loop until bytesWritten == len
179}
180
181void
182java::io::FileDescriptor::close (void)
183{
184 HANDLE save = (HANDLE)fd;
185 fd = (jint)INVALID_HANDLE_VALUE;
186 if (! CloseHandle (save))
187 throw new IOException (JvNewStringLatin1 (winerr ()));
188}
189
190void
191java::io::FileDescriptor::setLength(jlong pos)
192{
193 LONG liOrigFilePointer;
194 LONG liNewFilePointer;
195 LONG liEndFilePointer;
196
197 // Get the original file pointer.
198 if (SetFilePointer((HANDLE) fd, (LONG) 0, &liOrigFilePointer,
199 FILE_CURRENT) != (BOOL) 0
200 && (GetLastError() != NO_ERROR))
201 throw new IOException (JvNewStringLatin1 (winerr ()));
202
203 // Get the length of the file.
204 if (SetFilePointer((HANDLE) fd, (LONG) 0, &liEndFilePointer,
205 FILE_END) != (BOOL) 0
206 && (GetLastError() != NO_ERROR))
207 throw new IOException (JvNewStringLatin1 (winerr ()));
208
209 if ((jlong)liEndFilePointer == pos)
210 {
211 // Restore the file pointer.
212 if (liOrigFilePointer != liEndFilePointer)
213 {
214 if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
215 FILE_BEGIN) != (BOOL) 0
216 && (GetLastError() != NO_ERROR))
217 throw new IOException (JvNewStringLatin1 (winerr ()));
218 }
219 return;
220 }
221
222 // Seek to the new end of file.
223 if (SetFilePointer((HANDLE) fd, (LONG) pos, &liNewFilePointer,
224 FILE_BEGIN) != (BOOL) 0
225 && (GetLastError() != NO_ERROR))
226 throw new IOException (JvNewStringLatin1 (winerr ()));
227
228 // Truncate the file at this point.
229 if (SetEndOfFile((HANDLE) fd) != (BOOL) 0 && (GetLastError() != NO_ERROR))
230 throw new IOException (JvNewStringLatin1 (winerr ()));
231
232 if (liOrigFilePointer < liNewFilePointer)
233 {
234 // Restore the file pointer.
235 if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
236 FILE_BEGIN) != (BOOL) 0
237 && (GetLastError() != NO_ERROR))
238 throw new IOException (JvNewStringLatin1 (winerr ()));
239 }
240}
241
242jint
243java::io::FileDescriptor::seek (jlong pos, jint whence, jboolean eof_trunc)
244{
245 JvAssert (whence == SET || whence == CUR);
246
247 jlong len = length();
248 jlong here = getFilePointer();
249
250 if (eof_trunc
251 && ((whence == SET && pos > len) || (whence == CUR && here + pos > len)))
252 {
253 whence = SET;
254 pos = len;
255 }
256
257 LONG high = pos >> 32;
258 DWORD low = SetFilePointer ((HANDLE)fd, (DWORD)(0xffffffff & pos), &high, whence == SET ? FILE_BEGIN : FILE_CURRENT);
259 if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
260 throw new IOException (JvNewStringLatin1 (winerr ()));
261 return low;
262}
263
264jlong
265java::io::FileDescriptor::getFilePointer(void)
266{
267 LONG high = 0;
268 DWORD low = SetFilePointer ((HANDLE)fd, 0, &high, FILE_CURRENT);
269 if ((low == 0xffffffff) && (GetLastError() != NO_ERROR))
270 throw new IOException (JvNewStringLatin1 (winerr ()));
271 return (((jlong)high) << 32L) | (jlong)low;
272}
273
274jlong
275java::io::FileDescriptor::length(void)
276{
277 DWORD high;
278 DWORD low;
279
280 low = GetFileSize ((HANDLE)fd, &high);
281 // FIXME: Error checking
282 return (((jlong)high) << 32L) | (jlong)low;
283}
284
285jint
286java::io::FileDescriptor::read(void)
287{
288 CHAR buf;
289 DWORD read;
290
291 if (! ReadFile ((HANDLE)fd, &buf, 1, &read, NULL))
292 {
293 if (GetLastError () == ERROR_BROKEN_PIPE)
294 return -1;
295 else
296 throw new IOException (JvNewStringLatin1 (winerr ()));
297 }
298
299 if (! read)
300 return -1;
301 else
302 return (jint)(buf & 0xff);
303}
304
305jint
306java::io::FileDescriptor::read(jbyteArray buffer, jint offset, jint count)
307{
308 if (! buffer)
309 throw new java::lang::NullPointerException;
310
311 jsize bsize = JvGetArrayLength (buffer);
312 if (offset < 0 || count < 0 || offset + count > bsize)
313 throw new java::lang::ArrayIndexOutOfBoundsException;
314
315 // Must return 0 if an attempt is made to read 0 bytes.
316 if (count == 0)
317 return 0;
318
319 jbyte *bytes = elements (buffer) + offset;
320
321 DWORD read;
322 if (! ReadFile((HANDLE)fd, bytes, count, &read, NULL))
323 {
324 if (GetLastError () == ERROR_BROKEN_PIPE)
325 return -1;
326 else
327 throw new IOException (JvNewStringLatin1 (winerr ()));
328 }
329
330 if (read == 0) return -1;
331
332 return (jint)read;
333}
334
335jint
336java::io::FileDescriptor::available(void)
337{
338 // FIXME:
339 return length() - getFilePointer();
340}
Note: See TracBrowser for help on using the repository browser.