]> gerrit.simantics Code Review - simantics/r.git/blob - org.simantics.r.scl/src/org/rosuda/REngine/Rserve/RFileOutputStream.java
(refs #6833) Test RExp inheritance in SCL
[simantics/r.git] / org.simantics.r.scl / src / org / rosuda / REngine / Rserve / RFileOutputStream.java
1 // JRclient library - client interface to Rserve, see http://www.rosuda.org/Rserve/
2 // Copyright (C) 2003 Simon Urbanek
3 // --- for licensing information see LICENSE file in the original JRclient distribution ---
4 //
5 //  RFileOutputStream.java
6 //
7 //  Created by Simon Urbanek on Wed Oct 22 2003.
8 //
9
10 package org.rosuda.REngine.Rserve;
11
12 import java.io.*;
13 import org.rosuda.REngine.*;
14 import org.rosuda.REngine.Rserve.protocol.*;
15
16 /** <b>RFileOutputStream</b> is an {@link OutputStream} to transfer files
17 from the client to <b>Rserve</b> server. It is used very much like
18 a {@link FileOutputStream}. Currently mark and seek is not supported.
19 The current implementation is also "one-shot" only, that means the file
20 can be written only once.
21 @version $Id$
22 */
23
24 public class RFileOutputStream extends OutputStream {
25     /** RTalk class to use for communication with the Rserve */
26     RTalk rt;
27     /** set to <code>true</code> when {@link #close} was called.
28     Any subsequent read requests on closed stream  result in an
29 {@link IOException} or error result */
30     boolean closed;
31
32     /** tries to create a file on the R server, using specified {@link RTalk} object
33         and filename. Be aware that the filename has to be specified in host
34         format (which is usually unix). In general you should not use directories
35         since Rserve provides an own directory for every connection. Future Rserve
36         servers may even strip all directory navigation characters for security
37         purposes. Therefore only filenames without path specification are considered
38         valid, the behavior in respect to absolute paths in filenames is undefined.
39         @param rti RTalk object for communication with Rserve
40         @param fb filename of the file to create (existing file will be overwritten)
41         */
42     RFileOutputStream(RTalk rti, String fn) throws IOException {
43         rt=rti;
44         RPacket rp=rt.request(RTalk.CMD_createFile,fn);
45         if (rp==null || !rp.isOk())
46             throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
47         closed=false;
48     }
49
50     /** writes one byte to the file. This function should be avoided, since
51     {@link RFileOutputStream} provides no buffering. This means that each
52         call to this function leads to a complete packet exchange between
53         the server and the client. Use {@link #write(byte[])} instead
54         whenever possible. In fact this function calls <code>write(b,0,1)</code>.
55         @param b byte to write
56         */
57     public void write(int b) throws IOException {
58         byte[] ba=new byte[1];
59         write(ba,0,1);
60     }
61
62     /** writes the content of b into the file. This methods is equivalent to calling <code>write(b,0,b.length)</code>.
63         @param b content to write
64         */
65     public void write(byte b[]) throws IOException {
66         write(b,0,b.length);
67     }
68
69     /** Writes specified number of bytes to the remote file.
70         @param b buffer containing the bytes to write
71         @param off offset where to start
72         @param len number of bytes to write
73         */
74     public void write(byte[] b, int off, int len) throws IOException {
75         if (closed) throw new IOException("File is not open");
76         if (len<0) len=0;
77         boolean isLarge=(len>0xfffff0);
78         byte[] hdr=RTalk.newHdr(RTalk.DT_BYTESTREAM,len);
79         RPacket rp=rt.request(RTalk.CMD_writeFile,hdr,b,off,len);
80         if (rp==null || !rp.isOk())
81             throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
82     }
83
84     /** close stream - is not related to the actual RConnection, calling
85         close does not close the RConnection.
86         */
87     public void close() throws IOException {
88         RPacket rp=rt.request(RTalk.CMD_closeFile,(byte[])null);
89         if (rp==null || !rp.isOk())
90             throw new IOException((rp==null)?"Connection to Rserve failed":("Request return code: "+rp.getStat()));
91         closed=true;
92     }
93
94     /** currently (Rserve 0.3) there is no way to force flush on the remote side, hence this function is noop. Future versions of Rserve may support this feature though. At any rate, it is safe to call it. */
95     public void flush() {
96     }
97 }