/*
* $Id: IOModule.java,v 1.25 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.io;
import anvil.core.Any;
import anvil.core.AnyString;
import anvil.core.AnyUtils;
import anvil.core.Array;
import anvil.core.AnyList;
import anvil.core.Serialization;
import anvil.core.UnserializationException;
import anvil.script.Context;
import anvil.java.util.BindingEnumeration;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.IOException;
/// @module anvil.io
/// Provides for system input and output through data streams,
/// serialization and the file system.
///
public class IOModule
{
/// @const separator
/// The system-dependent path-separator character.
public static final Any separator = new AnyString(File.separator);
/// @const pathSeparator
/// The system-dependent default name-separator character.
public static final Any pathSeparator = new AnyString(File.pathSeparator);
/// @function load
/// Loads serialized data from file.
/// @synopsis object load(File file)
/// @synopsis object load(string file)
/// @param file File to load from
/// @throws CorruptedSerialization If serialized data is corrupted.
/// @throws IOError If an I/O error occurs
public static final Object[] p_load = { null, "file" };
public static final Any load(Context context, Any file)
{
try {
File source = toFile(file);
context.checkRead(source.getPath());
FileInputStream in = new FileInputStream(source);
Any struct = Serialization.unserialize(context, in);
in.close();
return struct;
} catch (UnserializationException e) {
throw context.CorruptedSerialization();
} catch (IOException e) {
throw context.exception(e);
}
}
/// @function save
/// Serializes data to file.
/// @synopsis boolean save(File file, object data)
/// @synopsis boolean save(string file, object data)
/// @param file Filename to save to
/// @param data Data to serialize
/// @throws IOError If an I/O error occurs
public static final Object[] p_save = { null, "file", "struct" };
public static final Any save(Context context, Any file, Any struct)
{
try {
File source = toFile(file);
context.checkWrite(source.getPath());
FileOutputStream out = new FileOutputStream(source);
Serialization.serialize(context, struct, out);
out.close();
return Any.TRUE;
} catch (IOException e) {
throw context.exception(e);
}
}
private static String[] toStringArray(Array list)
{
int n = list.size();
String[] array = new String[n];
int i = 0;
BindingEnumeration e = list.keysAndElements();
while(e.hasMoreElements()) {
array[i++] = e.nextKey().toString() + "=" + e.nextElement().toString();
}
return array;
}
static final String toPathname(Any f)
{
if (f == null) {
return null;
}
if (f instanceof AnyFile) {
return ((File)f.toObject()).getAbsolutePath();
} else {
return f.toString();
}
}
private static final File toFile(Any f)
{
if (f == null) {
return null;
}
if (f instanceof AnyFile) {
return (File)f.toObject();
} else {
return new File(f.toString());
}
}
/// @function listRoots
/// Lists all the file system roots of the system.
/// @synopsis list listRoots()
/// @return List of Files
public static final Any listRoots()
{
File[] list = File.listRoots();
if (list == null) {
return Any.NULL;
}
int n = list.length;
Any[] files = new Any[n];
for(int i=0; i<n; i++) {
files[i] = Any.create(list[i]);
}
return new AnyList(files);
}
/// @function createTempFile
/// Creates temporary file with given 'prefix' and 'suffix' to optional
/// 'path'. If path is omitted system's default temporary directory is used.
/// @synopsis File createTempFile(string prefix, string suffix)
/// @synopsis File createTempFile(string prefix, string suffix, File path)
/// @synopsis File createTempFile(string prefix, string suffix, string path)
/// @param prefix Prefix of created file
/// @param suffix Suffix of create file
/// @param path Path into which the file is created
/// @return Temporary file
/// @throws IOError If an I/O error occurs
public static final Object[] p_createTempFile = { "prefix", "suffix", "*path", null };
public static final Any createTempFile(Context context, String prefix,
String suffix, Any path)
{
File file = null;
if (path != null) {
if (path instanceof AnyFile) {
file = (File)path.toObject();
} else {
file = new File(path.toString());
}
context.checkWrite(file.getPath());
}
try {
if (file != null) {
return new AnyFile(File.createTempFile(prefix, suffix, file));
} else {
return new AnyFile(File.createTempFile(prefix, suffix));
}
} catch (IOException e) {
throw context.exception(e);
}
}
/// @function readText
/// Reads the contents of a file into a text string.
/// @synopsis string readText(File file)
/// @synopsis string readText(string file)
/// @param file File to read
/// @throws IOError If an I/O error occurs
public static final Object[] p_readText = { "file" };
public static final Any readText(Context context, Any file)
{
try {
File source = toFile(file);
context.checkRead(source.getPath());
BufferedReader reader = new BufferedReader(new FileReader(source));
StringBuffer buf = new StringBuffer();
String line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
buf.append(line);
buf.append('\n');
}
reader.close();
return Any.create(buf.toString());
} catch (IOException e) {
throw context.exception(e);
}
}
private static final int RETURN_PROCESS = 0;
private static final int PASSTHRU_AND_RETURN_EXIT_VALUE = 1;
private static final Any doExec(Context context, Any cmd, Any env, int action)
{
String[] cmdarray;
String[] envarray = null;
cmdarray = AnyUtils.toStringArray(cmd);
if (cmdarray.length > 0) {
context.checkExec(cmdarray[0]);
}
if (env != null) {
if (env.isArray()) {
envarray = toStringArray(env.toArray());
} else {
envarray = AnyUtils.toStringArray(env);
}
}
try {
Process process = Runtime.getRuntime().exec(cmdarray, envarray);
switch(action) {
case RETURN_PROCESS:
return new AnyProcess(process);
/*case WAIT_AND_RETURN_EXIT_VALUE:
for(;;) {
try {
process.waitFor();
break;
} catch (InterruptedException e) {
}
}
return Any.create(process.exitValue());*/
case PASSTHRU_AND_RETURN_EXIT_VALUE:
byte[] buffer = new byte[512];
InputStream input = process.getInputStream();
for(;;) {
int read = input.read(buffer, 0, 512);
if (read == -1) {
break;
}
if (read > 0) {
context.print(buffer, 0, read);
}
}
for(;;) {
try {
process.waitFor();
break;
} catch (InterruptedException e) {
}
}
return Any.create(process.exitValue());
default:
return Any.NULL;
}
} catch (IOException e) {
throw context.exception(e);
}
}
/// @function exec
/// Executes given command and return process datatype.
/// @synopsis Process exec(sequence arguments)
/// @synopsis Process exec(sequence arguments, array environment)
/// @param arguments Sequence of arguments
/// @param environment Process environment
/// @return a process datatype
public static final Object[] p_exec = { null, "command", "*environment", null };
public static final Any exec(Context context, Any cmd, Any env)
{
return doExec(context, cmd, env, RETURN_PROCESS);
}
/// @function passthru
/// Executes given command and prints its output.
/// @synopsis int passthru(sequence arguments)
/// @synopsis int passthru(sequence arguments, array environment)
/// @param arguments Sequence of arguments
/// @param environment Process environment
/// @return the exit value returned by the command
public static final Object[] p_passthru = { null, "command", "*environment", null };
public static final Any passthru(Context context, Any cmd, Any env)
{
return doExec(context, cmd, env, PASSTHRU_AND_RETURN_EXIT_VALUE);
}
public static final anvil.script.compiler.NativeNamespace __module__ =
new anvil.script.compiler.NativeNamespace(
"io",
IOModule.class,
new Class[] {
AnyFile.class,
AnyInputStream.class,
AnyOutputStream.class,
AnyProcess.class,
AnyFile.class,
anvil.core.Throwables.IOError.EndOfFile.class,
anvil.core.Throwables.IOError.FileNotFound.class,
anvil.core.Throwables.IOError.InterruptedIO.class,
anvil.core.Throwables.IOError.SyncFailed.class,
anvil.core.Throwables.IOError.class,
},
//DOC{{
""+
" @module anvil.io\n" +
" Provides for system input and output through data streams, \n" +
" serialization and the file system. \n" +
"\n" +
" @const separator\n" +
" The system-dependent path-separator character.\n" +
" @const pathSeparator\n" +
" The system-dependent default name-separator character.\n" +
" @function load\n" +
" Loads serialized data from file.\n" +
" @synopsis object load(File file)\n" +
" @synopsis object load(string file)\n" +
" @param file File to load from\n" +
" @throws CorruptedSerialization If serialized data is corrupted.\n" +
" @throws IOError If an I/O error occurs\n" +
" @function save\n" +
" Serializes data to file.\n" +
" @synopsis boolean save(File file, object data)\n" +
" @synopsis boolean save(string file, object data)\n" +
" @param file Filename to save to\n" +
" @param data Data to serialize\n" +
" @throws IOError If an I/O error occurs\n" +
" @function listRoots\n" +
" Lists all the file system roots of the system.\n" +
" @synopsis list listRoots()\n" +
" @return List of Files\n" +
" @function createTempFile \n" +
" Creates temporary file with given 'prefix' and 'suffix' to optional\n" +
" 'path'. If path is omitted system's default temporary directory is used.\n" +
" @synopsis File createTempFile(string prefix, string suffix)\n" +
" @synopsis File createTempFile(string prefix, string suffix, File path)\n" +
" @synopsis File createTempFile(string prefix, string suffix, string path)\n" +
" @param prefix Prefix of created file\n" +
" @param suffix Suffix of create file\n" +
" @param path Path into which the file is created\n" +
" @return Temporary file\n" +
" @throws IOError If an I/O error occurs\n" +
" @function readText\n" +
" Reads the contents of a file into a text string.\n" +
" @synopsis string readText(File file)\n" +
" @synopsis string readText(string file)\n" +
" @param file File to read\n" +
" @throws IOError If an I/O error occurs\n" +
" @function exec\n" +
" Executes given command and return process datatype.\n" +
" @synopsis Process exec(sequence arguments)\n" +
" @synopsis Process exec(sequence arguments, array environment)\n" +
" @param arguments Sequence of arguments\n" +
" @param environment Process environment \n" +
" @return a process datatype\n" +
" @function passthru\n" +
" Executes given command and prints its output. \n" +
" @synopsis int passthru(sequence arguments)\n" +
" @synopsis int passthru(sequence arguments, array environment)\n" +
" @param arguments Sequence of arguments\n" +
" @param environment Process environment \n" +
" @return the exit value returned by the command\n"
//}}DOC
);
}