1 /******************************************************************************* 2 * Copyright (c) 2003, 2018 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 15 package org.eclipse.equinox.internal.cm.reliablefile; 16 17 import java.io.*; 18 19 //This is a copy of org.eclipse.osgi.framework.internal.reliablefile.ReliableFileInputStream 20 21 /** 22 * A ReliableFile FileInputStream replacement class. 23 * This class can be used just like FileInputStream. The class 24 * is in partnership with ReliableFileOutputStream to avoid losing 25 * file data by using multiple files. 26 * 27 * @see ReliableFileOutputStream 28 */ 29 public class ReliableFileInputStream extends FilterInputStream { 30 /** 31 * ReliableFile object for this file. 32 */ 33 private ReliableFile reliable; 34 35 /** 36 * size of crc and signature 37 */ 38 private int sigSize; 39 40 /** 41 * current position reading from file 42 */ 43 private int readPos; 44 45 /** 46 * total file length available for reading 47 */ 48 private int length; 49 50 /** 51 * Constructs a new ReliableFileInputStream on the file named <code>name</code>. If the 52 * file does not exist, the <code>FileNotFoundException</code> is thrown. 53 * The <code>name</code> may be absolute or relative 54 * to the System property <code>"user.dir"</code>. 55 * 56 * @param name the file on which to stream reads. 57 * @exception java.io.IOException If an error occurs opening the file. 58 */ ReliableFileInputStream(String name)59 public ReliableFileInputStream(String name) throws IOException { 60 this(ReliableFile.getReliableFile(name), ReliableFile.GENERATION_LATEST, ReliableFile.OPEN_BEST_AVAILABLE); 61 } 62 63 /** 64 * Constructs a new ReliableFileInputStream on the File <code>file</code>. If the 65 * file does not exist, the <code>FileNotFoundException</code> is thrown. 66 * 67 * @param file the File on which to stream reads. 68 * @exception java.io.IOException If an error occurs opening the file. 69 */ ReliableFileInputStream(File file)70 public ReliableFileInputStream(File file) throws IOException { 71 this(ReliableFile.getReliableFile(file), ReliableFile.GENERATION_LATEST, ReliableFile.OPEN_BEST_AVAILABLE); 72 } 73 74 /** 75 * Constructs a new ReliableFileInputStream on the File <code>file</code>. If the 76 * file does not exist, the <code>FileNotFoundException</code> is thrown. 77 * 78 * @param file the File on which to stream reads. 79 * @param generation a specific generation requested. 80 * @param openMask mask used to open data. 81 * are invalid (corrupt, missing, etc). 82 * @exception java.io.IOException If an error occurs opening the file. 83 */ ReliableFileInputStream(File file, int generation, int openMask)84 public ReliableFileInputStream(File file, int generation, int openMask) throws IOException { 85 this(ReliableFile.getReliableFile(file), generation, openMask); 86 } 87 88 /** 89 * 90 * @param reliable The ReliableFile on which to read. 91 * @param generation a specific generation requested. 92 * @param openMask mask used to open data. 93 * are invalid (corrupt, missing, etc). 94 * @throws IOException If an error occurs opening the file. 95 */ ReliableFileInputStream(ReliableFile reliable, int generation, int openMask)96 private ReliableFileInputStream(ReliableFile reliable, int generation, int openMask) throws IOException { 97 super(reliable.getInputStream(generation, openMask)); 98 99 this.reliable = reliable; 100 sigSize = reliable.getSignatureSize(); 101 readPos = 0; 102 length = super.available(); 103 if (sigSize > length) 104 length = 0; // shouldn't ever happen 105 else 106 length -= sigSize; 107 } 108 109 /** 110 * Closes this input stream and releases any system resources associated 111 * with the stream. 112 * 113 * @exception java.io.IOException If an error occurs closing the file. 114 */ 115 @Override close()116 public synchronized void close() throws IOException { 117 if (reliable != null) { 118 try { 119 super.close(); 120 } finally { 121 reliable.closeInputFile(); 122 reliable = null; 123 } 124 } 125 } 126 127 /** 128 * Override default FilterInputStream method. 129 * @see FilterInputStream#read(byte[], int, int) 130 */ 131 @Override read(byte b[], int off, int len)132 public synchronized int read(byte b[], int off, int len) throws IOException { 133 if (readPos >= length) { 134 return -1; 135 } 136 int num = super.read(b, off, len); 137 138 if (num != -1) { 139 if (num + readPos > length) { 140 num = length - readPos; 141 } 142 readPos += num; 143 } 144 return num; 145 } 146 147 /** 148 * Override default FilterInputStream method. 149 * @see FilterInputStream#read(byte[]) 150 */ 151 @Override read(byte b[])152 public synchronized int read(byte b[]) throws IOException { 153 return read(b, 0, b.length); 154 } 155 156 /** 157 * Override default FilterInputStream method. 158 * @see FilterInputStream#read() 159 */ 160 @Override read()161 public synchronized int read() throws IOException { 162 if (readPos >= length) { 163 return -1; 164 } 165 int num = super.read(); 166 167 if (num != -1) { 168 readPos++; 169 } 170 return num; 171 } 172 173 /** 174 * Override default available method. 175 * @see FilterInputStream#available() 176 */ 177 @Override available()178 public synchronized int available() { 179 if (readPos < length) // just in case 180 return (length - readPos); 181 return 0; 182 } 183 184 /** 185 * Override default skip method. 186 * @see FilterInputStream#skip(long) 187 */ 188 @Override skip(long n)189 public synchronized long skip(long n) throws IOException { 190 long len = super.skip(n); 191 if (readPos + len > length) 192 len = length - readPos; 193 readPos += len; 194 return len; 195 } 196 197 /** 198 * Override default markSupported method. 199 * @see FilterInputStream#markSupported() 200 */ 201 @Override markSupported()202 public boolean markSupported() { 203 return false; 204 } 205 206 /** 207 * Override default mark method. 208 * @see FilterInputStream#mark(int) 209 */ 210 @Override mark(int readlimit)211 public void mark(int readlimit) { 212 //ignore 213 } 214 215 /** 216 * Override default reset method. 217 * @see FilterInputStream#reset() 218 */ 219 @Override reset()220 public void reset() throws IOException { 221 throw new IOException("reset not supported."); //$NON-NLS-1$ 222 } 223 } 224