001: /*
002: * @(#)read.java 1.3 05/06/14
003: *
004: * Copyright (c) 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package org.pnuts.io;
010:
011: import pnuts.io.CharacterEncoding;
012: import pnuts.lang.*;
013: import java.io.*;
014: import java.net.*;
015: import org.pnuts.lib.PathHelper;
016:
017: public class read extends PnutsFunction {
018:
019: private final static Object DEFAULT_STREAM = new Object();
020:
021: public read() {
022: super ("read");
023: }
024:
025: public boolean defined(int narg) {
026: return (narg == 1 || narg == 2);
027: }
028:
029: protected Object exec(Object[] args, Context context) {
030: Object a1 = null;
031: Object a2 = null;
032: int nargs = args.length;
033: if (nargs == 1) {
034: a1 = args[0];
035: a2 = DEFAULT_STREAM;
036: } else if (nargs == 2) {
037: a1 = args[0];
038: a2 = args[1];
039: } else {
040: undefined(args, context);
041: }
042: int nread = 0;
043: InputStream in = null;
044: OutputStream out = null;
045: Reader reader = null;
046: Writer writer = null;
047: InputStream inputStreamToClose = null;
048: OutputStream outputStreamToClose = null;
049: boolean a1isInputStream = false;
050: boolean a1isReader = false;
051: try {
052: if (a1 instanceof InputStream) {
053: a1isInputStream = true;
054: in = (InputStream) a1;
055: } else if (a1 instanceof File) {
056: a1isInputStream = true;
057: in = inputStreamToClose = new FileInputStream((File) a1);
058: } else if (a1 instanceof String) {
059: a1isInputStream = true;
060: in = new FileInputStream(PathHelper.getFile(
061: (String) a1, context));
062: ;
063: inputStreamToClose = in;
064: } else if (a1 instanceof URL) {
065: a1isInputStream = true;
066: in = ((URL) a1).openStream();
067: inputStreamToClose = in;
068: } else if (a1 instanceof Reader) {
069: a1isReader = true;
070: reader = (Reader) a1;
071: } else {
072: throw new IllegalArgumentException(String.valueOf(a1));
073: }
074: boolean a2isOutputStream = false;
075: boolean a2isWriter = false;
076: boolean a2isNull = false;
077: if (a2 instanceof OutputStream) {
078: a2isOutputStream = true;
079: out = (OutputStream) a2;
080: } else if (a2 instanceof File) {
081: a2isOutputStream = true;
082: out = outputStreamToClose = new FileOutputStream(
083: (File) a2);
084: } else if (a2 instanceof String) {
085: a2isOutputStream = true;
086: out = new FileOutputStream(PathHelper.getFile(
087: (String) a2, context));
088: outputStreamToClose = out;
089: } else if (a2 instanceof Writer) {
090: a2isWriter = true;
091: writer = (Writer) a2;
092: } else if (a2 == null) {
093: a2isNull = true;
094: } else if (a2 == DEFAULT_STREAM) {
095: } else {
096: throw new IllegalArgumentException(String.valueOf(a2));
097: }
098:
099: if (a1isInputStream) {
100: if (a2 == DEFAULT_STREAM) {
101: a2 = context.getOutputStream();
102: out = (OutputStream) a2;
103: a2isOutputStream = true;
104: }
105: if (out != null && a2isOutputStream) {
106: byte[] buf = new byte[8192];
107: int n;
108: while ((n = in.read(buf, 0, buf.length)) >= 0) {
109: out.write(buf, 0, n);
110: nread += n;
111: }
112: out.flush();
113: } else if (a2isWriter) {
114: CountingInputStream cin = new CountingInputStream(
115: in);
116: char[] buf = new char[8192];
117: reader = CharacterEncoding.getReader(cin, context);
118: int n;
119: while ((n = reader.read(buf, 0, buf.length)) >= 0) {
120: writer.write(buf, 0, n);
121: }
122: nread += cin.count();
123: writer.flush();
124: } else if (a2 == null) {
125: byte[] buf = new byte[8192];
126: int n;
127: while ((n = in.read(buf, 0, buf.length)) >= 0) {
128: nread += n;
129: }
130: } else {
131: throw new IllegalArgumentException();
132: }
133: } else if (a1isReader) {
134: if (a2 == DEFAULT_STREAM) {
135: a2 = context.getWriter();
136: a2isWriter = true;
137: }
138: char[] buf = new char[8192];
139: int n;
140: if (a2isOutputStream) {
141: writer = CharacterEncoding.getWriter(
142: (OutputStream) a2, context);
143: while ((n = reader.read(buf, 0, buf.length)) >= 0) {
144: writer.write(buf, 0, n);
145: nread += n;
146: }
147: writer.flush();
148: } else if (a2isWriter) {
149: writer = (Writer) a2;
150: while ((n = reader.read(buf, 0, buf.length)) >= 0) {
151: writer.write(buf, 0, n);
152: nread += n;
153: }
154: writer.flush();
155: } else if (a2 == null) {
156: while ((n = reader.read(buf, 0, buf.length)) >= 0) {
157: nread += n;
158: }
159: } else {
160: throw new IllegalArgumentException();
161: }
162: } else {
163: throw new IllegalArgumentException();
164: }
165: return new Integer(nread);
166: } catch (IOException e) {
167: throw new PnutsException(e, context);
168: } finally {
169: if (inputStreamToClose != null) {
170: try {
171: inputStreamToClose.close();
172: } catch (IOException e) {
173: }
174: }
175: if (outputStreamToClose != null) {
176: try {
177: outputStreamToClose.close();
178: } catch (IOException e) {
179: }
180: }
181: }
182: }
183:
184: static class CountingInputStream extends FilterInputStream {
185: int nread = 0;
186:
187: public CountingInputStream(InputStream in) {
188: super (in);
189: }
190:
191: public int read() throws IOException {
192: int c = in.read();
193: if (c != -1) {
194: nread++;
195: }
196: return c;
197: }
198:
199: public int read(byte[] buf, int offset, int len)
200: throws IOException {
201: int n = in.read(buf, offset, len);
202: if (n >= 0) {
203: nread += n;
204: }
205: return n;
206: }
207:
208: public int count() {
209: return nread;
210: }
211: }
212:
213: public String toString() {
214: return "function read(input, output)";
215: }
216: }
|