1 /* 2 * This file is part of the LibreOffice project. 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 * 8 * This file incorporates work covered by the following license notice: 9 * 10 * Licensed to the Apache Software Foundation (ASF) under one or more 11 * contributor license agreements. See the NOTICE file distributed 12 * with this work for additional information regarding copyright 13 * ownership. The ASF licenses this file to you under the Apache 14 * License, Version 2.0 (the "License"); you may not use this file 15 * except in compliance with the License. You may obtain a copy of 16 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 17 */ 18 package com.sun.star.lib.uno.adapter; 19 20 import java.io.IOException; 21 22 import com.sun.star.io.XInputStream; 23 24 import java.io.InputStream; 25 26 /** 27 * The <code>XInputStreamToInputStreamAdapter</code> wraps 28 * the UNO <code>XInputStream</code> object in a Java 29 * <code>InputStream</code>. This allows users to access 30 * an <code>XInputStream</code> as if it were an 31 * <code>InputStream</code>. 32 */ 33 public final class XInputStreamToInputStreamAdapter extends InputStream { 34 35 /** 36 * Internal handle to the XInputStream 37 */ 38 private final XInputStream xin; 39 40 /** 41 * Constructor. 42 * 43 * @param in The <code>XInputStream</code> to be 44 * accessed as an <code>InputStream</code>. 45 */ XInputStreamToInputStreamAdapter(XInputStream in)46 public XInputStreamToInputStreamAdapter (XInputStream in) { 47 xin = in; 48 } 49 50 @Override available()51 public int available() throws IOException { 52 53 int bytesAvail; 54 55 try { 56 bytesAvail = xin.available(); 57 } catch (Exception e) { 58 IOException newEx = new IOException(e.getMessage()); 59 newEx.initCause(e); 60 throw newEx; 61 } 62 63 return bytesAvail; 64 } 65 66 @Override close()67 public void close() throws IOException { 68 try { 69 xin.closeInput(); 70 } catch (Exception e) { 71 IOException newEx = new IOException(e.getMessage()); 72 newEx.initCause(e); 73 throw newEx; 74 } 75 } 76 77 @Override read()78 public int read () throws IOException { 79 byte [][] tmp = new byte [1][1]; 80 try { 81 long bytesRead = xin.readBytes(tmp, 1); 82 83 if (bytesRead <= 0) { 84 return (-1); 85 } else { 86 int tmpInt = tmp[0][0]; 87 if (tmpInt< 0 ){ 88 tmpInt = 256 +tmpInt; 89 } 90 return tmpInt; 91 } 92 93 } catch (Exception e) { 94 IOException newEx = new IOException(e.getMessage()); 95 newEx.initCause(e); 96 throw newEx; 97 } 98 } 99 100 @Override read(byte[] b)101 public int read (byte[] b) throws IOException { 102 103 byte [][] tmp = new byte [1][b.length]; 104 int bytesRead; 105 106 try { 107 bytesRead = xin.readBytes(tmp, b.length); 108 if (bytesRead <= 0) { 109 return -1; 110 } else if (bytesRead < b.length) { 111 System.arraycopy(tmp[0], 0, b, 0, bytesRead); 112 } else { 113 System.arraycopy(tmp[0], 0, b, 0, b.length); 114 } 115 } catch (Exception e) { 116 IOException newEx = new IOException(e.getMessage()); 117 newEx.initCause(e); 118 throw newEx; 119 } 120 121 return bytesRead; 122 } 123 124 @Override read(byte[] b, int off, int len)125 public int read(byte[] b, int off, int len) throws IOException { 126 byte [][] tmp = new byte [1][b.length]; 127 try { 128 long bytesRead; 129 int av = xin.available(); 130 if ( av != 0 && len > av) { 131 bytesRead = xin.readBytes(tmp, av); 132 } 133 else{ 134 bytesRead = xin.readBytes(tmp,len); 135 } 136 // Casting bytesRead to an int is okay, since the user can 137 // only pass in an integer length to read, so the bytesRead 138 // must <= len. 139 140 if (bytesRead <= 0) { 141 return -1; 142 } else if (bytesRead < len) { 143 System.arraycopy(tmp[0], 0, b, off, (int)bytesRead); 144 } else { 145 System.arraycopy(tmp[0], 0, b, off, len); 146 } 147 148 return ((int)bytesRead); 149 } catch (Exception e) { 150 IOException newEx = new IOException(e.getMessage()); 151 newEx.initCause(e); 152 throw newEx; 153 } 154 } 155 156 @Override skip(long n)157 public long skip(long n) throws IOException { 158 159 int avail; 160 long tmpLongVal = n; 161 int tmpIntVal; 162 163 try { 164 avail = xin.available(); 165 } catch (Exception e) { 166 IOException newEx = new IOException(e.getMessage()); 167 newEx.initCause(e); 168 throw newEx; 169 } 170 171 do { 172 if (tmpLongVal >= Integer.MAX_VALUE) { 173 tmpIntVal = Integer.MAX_VALUE; 174 } else { 175 // Casting is safe here. 176 tmpIntVal = (int)tmpLongVal; 177 } 178 tmpLongVal -= tmpIntVal; 179 180 try { 181 xin.skipBytes(tmpIntVal); 182 } catch (Exception e) { 183 IOException newEx = new IOException(e.getMessage()); 184 newEx.initCause(e); 185 throw newEx; 186 } 187 } while (tmpLongVal > 0); 188 189 if ( avail != 0 && avail < n) { 190 return avail; 191 } else { 192 return n; 193 } 194 } 195 196 /** 197 * Tests if this input stream supports the mark and reset methods. 198 * The markSupported method of 199 * <code>XInputStreamToInputStreamAdapter</code> returns false. 200 * 201 * @return false 202 */ 203 @Override markSupported()204 public boolean markSupported() { 205 return false; 206 } 207 208 @Override mark(int readlimit)209 public synchronized void mark(int readlimit) { 210 // Not supported. 211 } 212 213 @Override reset()214 public synchronized void reset() throws IOException { 215 // Not supported. 216 } 217 } 218 219