/* * Copyright 2014 Igor Maznitsa (http://www.igormaznitsa.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.igormaznitsa.prol.io; import com.igormaznitsa.prol.logic.*; import com.igormaznitsa.prol.data.Term; import com.igormaznitsa.prol.data.TermInteger; import com.igormaznitsa.prol.parser.ProlReader; import com.igormaznitsa.prol.parser.ProlTokenizer; import com.igormaznitsa.prol.parser.ProlTokenizer.ProlTokenizerResult; import com.igormaznitsa.prol.parser.ProlTreeBuilder; import java.io.IOException; import java.io.Reader; /** * The class implements a text input stream which is used by a prol engine to * read from an input stream. * * @author Igor Maznitsa (igor.maznitsa@igormaznitsa.com) * @see com.igormaznitsa.prol.io.ProlStream * @see com.igormaznitsa.prol.io.ProlTextReader */ public class ProlTextInputStream implements ProlStream, ProlTextReader { /** * The variable contains a prol tokenizer which is used to read tokens from an * input stream */ private final ProlTokenizer tokenizer; /** * The variable contains a prol reader to read chars from an input stream */ private final ProlReader reader; /** * The variable contains a prol tree builder to make tree from read terms */ private ProlTreeBuilder treeBuilder; /** * The variable contains the context which is the owner for the stream */ private final ProlContext context; /** * The variable contains the identifier of the stream as a String */ private final String resourceId; /** * The term describes the stream to be used in a prolog engine */ private final Term thisTerm; /** * A constructor (it is used by memory pipes so it is protected) * * @param reader a reader which will be used to read chars, must not be null * @param context the owner context for the reader, must not be null * @throws IOException it will be thrown if there is any IO error during the * operation */ protected ProlTextInputStream(final Reader reader, final ProlContext context) throws IOException { super(); this.resourceId = ".local"; this.context = context; this.reader = new ProlReader(reader); this.tokenizer = new ProlTokenizer(); thisTerm = new Term(resourceId); } /** * A constructor * * @param resourceId the resource identifier of the stream, must not be null * @param context the owner context for the reader, must not be null * @throws IOException it will be thrown if there is any IO error during the * operation */ public ProlTextInputStream(final String resourceId, final ProlContext context) throws IOException { super(); if (resourceId == null) { throw new IllegalArgumentException("The resource ID must not be null"); } this.resourceId = resourceId; this.context = context; final Reader inReader = context.getStreamManager().getReaderForResource(resourceId); if (inReader == null) { throw new IOException("Resource \'" + resourceId + "\' has not been found"); } this.reader = new ProlReader(inReader); this.tokenizer = new ProlTokenizer(); thisTerm = new Term(resourceId); } @Override public String getResourceId() { return this.resourceId; } @Override public ProlContext getContext() { return this.context; } @Override public synchronized void close() throws IOException { reader.close(); } @Override public synchronized Term readToken() throws IOException { ProlTokenizerResult result = tokenizer.nextToken(reader, context.getKnowledgeBase()); if (result == null) { return END_OF_FILE; } return result.getTerm(); } @Override public synchronized Term readTerm() throws IOException { if (treeBuilder == null) { treeBuilder = new ProlTreeBuilder(context); } Term term = treeBuilder.readPhraseAndMakeTree(tokenizer, reader); if (term == null) { return END_OF_FILE; } else { return term; } } @Override public synchronized TermInteger readChar() throws IOException { int chr = reader.read(); return new TermInteger(chr); } @Override public Term getAsTerm() { return thisTerm; } }