aboutsummaryrefslogtreecommitdiff
path: root/src/builtin/PRED_open_4.java
blob: 24e482cc56c60a23e15a578503bbad7253d1974c (plain)
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
package com.googlecode.prolog_cafe.builtin;
import com.googlecode.prolog_cafe.lang.*;
import java.io.*;
/**
   <code>open/4</code><br>
   @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
   @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
   @version 1.0
*/
public class PRED_open_4 extends Predicate.P4 {
    private static final SymbolTerm SYM_NIL         = SymbolTerm.makeSymbol("[]");
    private static final SymbolTerm SYM_TEXT        = SymbolTerm.makeSymbol("text");
    private static final SymbolTerm SYM_READ        = SymbolTerm.makeSymbol("read");
    private static final SymbolTerm SYM_WRITE       = SymbolTerm.makeSymbol("write");
    private static final SymbolTerm SYM_APPEND      = SymbolTerm.makeSymbol("append");
    private static final SymbolTerm SYM_INPUT       = SymbolTerm.makeSymbol("input");
    private static final SymbolTerm SYM_OUTPUT      = SymbolTerm.makeSymbol("output");
    private static final SymbolTerm SYM_ALIAS_1     = SymbolTerm.makeSymbol("alias", 1);
    private static final SymbolTerm SYM_MODE_1      = SymbolTerm.makeSymbol("mode", 1);
    private static final SymbolTerm SYM_TYPE_1      = SymbolTerm.makeSymbol("type", 1);
    private static final SymbolTerm SYM_FILE_NAME_1 = SymbolTerm.makeSymbol("file_name", 1);

    public PRED_open_4(Term a1, Term a2, Term a3, Term a4, Operation cont) {
        arg1 = a1;
        arg2 = a2;
        arg3 = a3;
        arg4 = a4;
        this.cont = cont;
    }

    public Operation exec(Prolog engine) {
        engine.setB0();
	File file;
	Term alias = null;
	Term opts = SYM_NIL;
	JavaObjectTerm streamObject;
        Term a1, a2, a3, a4;
        a1 = arg1;
        a2 = arg2;
        a3 = arg3;
        a4 = arg4;

	// stream
	a3 = a3.dereference();
	if (! a3.isVariable())
	    throw new IllegalTypeException(this, 3, "variable", a3);
	// source_sink
	a1 = a1.dereference();
	if (a1.isVariable())
	    throw new PInstantiationException(this, 1);
	if (! a1.isSymbol())
	    throw new IllegalDomainException(this, 1, "source_sink", a1);
	file = new File(((SymbolTerm) a1).name());
	// io_mode
	a2 = a2.dereference();
	if (a2.isVariable())
	    throw new PInstantiationException(this, 2);
	if (! a2.isSymbol()) 
	    throw new IllegalTypeException(this, 2, "atom", a2);
	try {
	    if (a2.equals(SYM_READ)) {
		if (! file.exists())
		    throw new ExistenceException(this, 1, "source_sink", a1, "");
		PushbackReader in = 
		    new PushbackReader(new BufferedReader(new FileReader(file)), engine.PUSHBACK_SIZE);
		streamObject = new JavaObjectTerm(in);
		opts = new ListTerm(SYM_INPUT, opts);
	    } else if (a2.equals(SYM_WRITE)) {
		PrintWriter out = 
		    new PrintWriter(new BufferedWriter(new FileWriter(file, false)));
		streamObject = new JavaObjectTerm(out);
		opts = new ListTerm(SYM_OUTPUT, opts);
	    } else if (a2.equals(SYM_APPEND)) {
		PrintWriter out = 
		    new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
		streamObject = new JavaObjectTerm(out);
		opts = new ListTerm(SYM_OUTPUT, opts);
	    } else {
		throw new IllegalDomainException(this, 2, "io_mode", a2);
	    }
	} catch (IOException e) {
	    throw new PermissionException(this, "open", "source_sink", a1, "");
	}
	if (engine.getStreamManager().containsKey(streamObject))
	    throw new InternalException("stream object is duplicated");
	// stream_options
	a4 = a4.dereference();
	Term tmp = a4;
	while (! tmp.isNil()) {
	    if (tmp.isVariable())
		throw new PInstantiationException(this, 4);
	    if (! tmp.isList())
		throw new IllegalTypeException(this, 4, "list", a4);
	    Term car = ((ListTerm) tmp).car().dereference();
	    if (car.isVariable())
		throw new PInstantiationException(this, 4);
	    if (car.isStructure()) {
		SymbolTerm functor = ((StructureTerm) car).functor();
		Term[] args = ((StructureTerm) car).args();
		if (functor.equals(SYM_ALIAS_1)) {
		    alias = args[0].dereference();
		    if (! alias.isSymbol())
			throw new IllegalDomainException(this, 4, "stream_option", car);
		    if (engine.getStreamManager().containsKey(alias))
			throw new PermissionException(this, "open", "source_sink", car, "");
		} else {
		    throw new IllegalDomainException(this, 4, "stream_option", car);
		}
	    } else {
		throw new IllegalDomainException(this, 4, "stream_option", car);
	    }
	    tmp = ((ListTerm) tmp).cdr().dereference();
	}
	opts = new ListTerm(new StructureTerm(SYM_TYPE_1, SYM_TEXT), opts);
	opts = new ListTerm(new StructureTerm(SYM_MODE_1, a2), opts);
	opts = new ListTerm(new StructureTerm(SYM_FILE_NAME_1, SymbolTerm.makeSymbol(file.getAbsolutePath())), opts);
	if (alias != null) {
	    engine.getStreamManager().put(alias, streamObject);
	    opts = new ListTerm(new StructureTerm(SYM_ALIAS_1, alias), opts);
	}
	((VariableTerm)a3).bind(streamObject, engine.trail);
	engine.getStreamManager().put(streamObject, opts);
        return cont;
    }
}