1 /* 2 * URLStream.java 3 * 4 * Copyright (C) 2010 Mark Evenson 5 * $Id$ 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 * 21 * As a special exception, the copyright holders of this library give you 22 * permission to link this library with independent modules to produce an 23 * executable, regardless of the license terms of these independent 24 * modules, and to copy and distribute the resulting executable under 25 * terms of your choice, provided that you also meet, for each linked 26 * independent module, the terms and conditions of the license of that 27 * module. An independent module is a module which is not derived from 28 * or based on this library. If you modify this library, you may extend 29 * this exception to your version of the library, but you are not 30 * obligated to do so. If you do not wish to do so, delete this 31 * exception statement from your version. 32 */ 33 34 package org.armedbear.lisp; 35 36 import static org.armedbear.lisp.Lisp.*; 37 38 import java.io.File; 39 import java.io.InputStream; 40 import java.io.Reader; 41 import java.io.FileNotFoundException; 42 import java.io.IOException; 43 import java.io.InputStreamReader; 44 import java.io.BufferedReader; 45 46 /** 47 * Stream interface for a URL. 48 * 49 * Currently only supports reading from the stream. 50 */ 51 public final class URLStream extends Stream 52 { 53 private final Pathname pathname; 54 private final InputStream input; 55 private final Reader reader; 56 private final int bytesPerUnit; 57 URLStream(Pathname pathname, LispObject elementType, LispObject direction, LispObject ifExists, LispObject format)58 public URLStream(Pathname pathname, 59 LispObject elementType, LispObject direction, 60 LispObject ifExists, LispObject format) 61 throws IOException 62 { 63 super(Symbol.URL_STREAM); 64 Debug.assertTrue(direction == Keyword.INPUT); 65 isInputStream = true; 66 67 super.setExternalFormat(format); 68 69 this.pathname = pathname; 70 this.elementType = elementType; 71 72 this.input = pathname.getInputStream(); 73 if (elementType == Symbol.CHARACTER || elementType == Symbol.BASE_CHAR) { 74 isCharacterStream = true; 75 bytesPerUnit = 1; 76 InputStreamReader isr = new InputStreamReader(input); 77 this.reader = (Reader) new BufferedReader(isr); 78 initAsCharacterInputStream(this.reader); 79 } else { 80 isBinaryStream = true; 81 int width = Fixnum.getValue(elementType.cadr()); 82 bytesPerUnit = width / 8; 83 this.reader = null; 84 initAsBinaryInputStream(this.input); 85 } 86 } 87 88 @Override typeOf()89 public LispObject typeOf() 90 { 91 return Symbol.URL_STREAM; 92 } 93 94 @Override classOf()95 public LispObject classOf() 96 { 97 return BuiltInClass.URL_STREAM; 98 } 99 100 @Override typep(LispObject typeSpecifier)101 public LispObject typep(LispObject typeSpecifier) 102 { 103 if (typeSpecifier == Symbol.URL_STREAM) 104 return T; 105 if (typeSpecifier == BuiltInClass.URL_STREAM) 106 return T; 107 return super.typep(typeSpecifier); 108 } 109 110 @Override setExternalFormat(LispObject format)111 public void setExternalFormat(LispObject format) { 112 super.setExternalFormat(format); 113 } 114 getPathname()115 public Pathname getPathname() 116 { 117 return pathname; 118 } 119 120 // unused 20200418 ME getReader()121 public Reader getReader() 122 { 123 return reader; 124 } 125 126 /** 127 * Accessing the underlying java.io.InputStream can be helpful 128 * when utlizing Java-side frameworks like Apache Jena built on 129 * the java.io abstractions. State should only be mutated if you 130 * know what you are doing. 131 * 132 * c.f. <https://gitlab.common-lisp.net/mevenson/jeannie/> 133 **/ getInputStream()134 public InputStream getInputStream() 135 { 136 return input; 137 } 138 139 // unused 20200418 ME getBytesPerUnit()140 public int getBytesPerUnit() { 141 return bytesPerUnit; 142 } 143 @Override _close()144 public void _close() 145 { 146 try { 147 if (input != null) { 148 input.close(); 149 } 150 if (reader != null) { 151 reader.close(); 152 } 153 setOpen(false); 154 } 155 catch (IOException e) { 156 error(new StreamError(this, e)); 157 } 158 } 159 160 @Override printObject()161 public String printObject() 162 { 163 StringBuffer sb = new StringBuffer(); 164 sb.append(Symbol.URL_STREAM.printObject()); 165 String namestring = pathname.getNamestring(); 166 if (namestring != null) { 167 sb.append(" "); 168 sb.append(namestring); 169 } 170 return unreadableString(sb.toString()); 171 } 172 } 173