/** * Indicates whether this reader is ready to be read without blocking. * * @return {@code true} if this reader will not block when {@code read} is called, {@code false} * if unknown or blocking will occur. * @throws IOException if this reader is closed or some other I/O error occurs. * @see #read() * @see #read(char[], int, int) * @see #readLine() */ @Override public boolean ready() throws IOException { synchronized (lock) { if (isClosed()) { throw new IOException(Msg.getString("K005b")); // $NON-NLS-1$ } return ((end - pos) > 0) || in.ready(); } }
/** * Reads at most {@code length} bytes from the filtered stream and stores them in the byte array * {@code buffer} starting at {@code offset}. Returns the number of bytes actually read or -1 if * no bytes have been read and the end of this stream has been reached. * * <p>The line number count is incremented if a line terminator is encountered. Recognized line * terminator sequences are {@code '\r'}, {@code '\n'} and {@code "\r\n"}. Line terminator * sequences are always translated into {@code '\n'}. * * @param buffer the array in which to store the bytes read. * @param offset the initial position in {@code buffer} to store the bytes read from this stream. * @param length the maximum number of bytes to store in {@code buffer}. * @return the number of bytes actually read or -1 if the end of the filtered stream has been * reached while reading. * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code length < 0}, or if {@code * offset + length} is greater than the length of {@code buffer}. * @throws IOException if this stream is closed or another IOException occurs. * @throws NullPointerException if {@code buffer} is {@code null}. * @since Android 1.0 */ @Override public int read(byte[] buffer, int offset, int length) throws IOException { // BEGIN android-changed if (buffer == null) { throw new NullPointerException(Msg.getString("K0047")); // $NON-NLS-1$ } // avoid int overflow // Exception priorities (in case of multiple errors) differ from // RI, but are spec-compliant. // removed redundant check, used (offset | length) < 0 // instead of (offset < 0) || (length < 0) to safe one operation if ((offset | length) < 0 || length > buffer.length - offset) { throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); // $NON-NLS-1$ } // END android-changed for (int i = 0; i < length; i++) { int currentChar; try { currentChar = read(); } catch (IOException e) { if (i != 0) { return i; } throw e; } if (currentChar == -1) { return i == 0 ? -1 : i; } buffer[offset + i] = (byte) currentChar; } return length; }
/** Bind using a SOCKS server. */ private void socksBind() throws IOException { try { netImpl.connect(fd, trafficClass, socksGetServerAddress(), socksGetServerPort()); } catch (Exception e) { throw new IOException(Msg.getString("K003f", e)); // $NON-NLS-1$ } // There must be a connection to an application host for the bind to // work. if (lastConnectedAddress == null) { throw new SocketException(Msg.getString("K0040")); // $NON-NLS-1$ } // Use the last connected address and port in the bind request. socksSendRequest(Socks4Message.COMMAND_BIND, lastConnectedAddress, lastConnectedPort); Socks4Message reply = socksReadReply(); if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) { throw new IOException(reply.getErrorString(reply.getCommandOrResult())); } // A peculiarity of socks 4 - if the address returned is 0, use the // original socks server address. if (reply.getIP() == 0) { address = socksGetServerAddress(); } else { // IPv6 support not yet required as // currently the Socks4Message.getIP() only returns int, // so only works with IPv4 4byte addresses byte[] replyBytes = new byte[4]; NetUtil.intToBytes(reply.getIP(), replyBytes, 0); address = InetAddress.getByAddress(replyBytes); } localport = reply.getPort(); }
/** * Returns the {@code InetAddress} corresponding to the array of bytes, and the given hostname. In * the case of an IPv4 address there must be exactly 4 bytes and for IPv6 exactly 16 bytes. If * not, an {@code UnknownHostException} is thrown. The host name and IP address are not validated. * The hostname either be a machine alias or a valid IPv6 or IPv4 address format. The high order * byte is {@code ipAddress[0]}. * * @param hostName string representation of hostname or IP address. * @param ipAddress either a 4 (IPv4) or 16 (IPv6) byte array. * @param scope_id the scope id for a scoped address. If not a scoped address just pass in 0. * @return the InetAddress * @throws UnknownHostException */ static InetAddress getByAddressInternal(String hostName, byte[] ipAddress, int scope_id) throws UnknownHostException { if (ipAddress == null) { // We don't throw NullPointerException here for RI compatibility, // but we do say "address is null" (K0331), instead of "addr is of // illegal length". throw new UnknownHostException(Msg.getString("K0331", hostName)); // $NON-NLS-1$ } switch (ipAddress.length) { case 4: return new Inet4Address(ipAddress.clone()); case 16: // First check to see if the address is an IPv6-mapped // IPv4 address. If it is, then we can make it a IPv4 // address, otherwise, we'll create an IPv6 address. if (isIPv4MappedAddress(ipAddress)) { return new Inet4Address(ipv4MappedToIPv4(ipAddress)); } else { return new Inet6Address(ipAddress.clone(), scope_id); } default: if (hostName != null) { // "Invalid IP Address is neither 4 or 16 bytes: <hostName>" throw new UnknownHostException(Msg.getString("K0332", hostName)); // $NON-NLS-1$ } else { // "Invalid IP Address is neither 4 or 16 bytes" throw new UnknownHostException(Msg.getString("K0339")); // $NON-NLS-1$ } } }
@Override public int read(byte[] buf, int offset, int length) throws IOException { // Force buf null check first, and avoid int overflow if (offset > buf.length || offset < 0) { // K002e=Offset out of bounds \: {0} throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); // $NON-NLS-1$ } if (length < 0 || buf.length - offset < length) { // K0031=Length out of bounds \: {0} throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); // $NON-NLS-1$ } if (bytesRemaining <= 0) { readChunkSize(); } if (atEnd) { disconnect(false); return -1; } if (length > bytesRemaining) { length = bytesRemaining; } int result = is.read(buf, offset, length); if (result > 0) { bytesRemaining -= result; // if user has set useCache to true and cache exists, write to // it if (useCaches && null != cacheOut) { cacheOut.write(buf, offset, result); } } return result; }
/** * Reads at most {@code length} bytes from the filtered stream and stores them in the byte array * {@code buffer} starting at {@code offset}. Returns the number of bytes actually read or -1 if * no bytes have been read and the end of this stream has been reached. * * <p>The line number count is incremented if a line terminator is encountered. Recognized line * terminator sequences are {@code '\r'}, {@code '\n'} and {@code "\r\n"}. Line terminator * sequences are always translated into {@code '\n'}. * * @param buffer the array in which to store the bytes read. * @param offset the initial position in {@code buffer} to store the bytes read from this stream. * @param length the maximum number of bytes to store in {@code buffer}. * @return the number of bytes actually read or -1 if the end of the filtered stream has been * reached while reading. * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code length < 0}, or if {@code * offset + length} is greater than the length of {@code buffer}. * @throws IOException if this stream is closed or another IOException occurs. * @throws NullPointerException if {@code buffer} is {@code null}. */ @Override public int read(byte[] buffer, int offset, int length) throws IOException { // Force buffer null check first! if (offset > buffer.length || offset < 0) { // K002e=Offset out of bounds \: {0} throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); // $NON-NLS-1$ } if (length < 0 || length > buffer.length - offset) { // K0031=Length out of bounds \: {0} throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); // $NON-NLS-1$ } for (int i = 0; i < length; i++) { int currentChar; try { currentChar = read(); } catch (IOException e) { if (i != 0) { return i; } throw e; } if (currentChar == -1) { return i == 0 ? -1 : i; } buffer[offset + i] = (byte) currentChar; } return length; }
@Override public OutputStream getOutputStream() throws IOException { if (!doOutput) { throw new ProtocolException(Msg.getString("K008e")); // $NON-NLS-1$ } // you can't write after you read if (sentRequest) { throw new ProtocolException(Msg.getString("K0090")); // $NON-NLS-1$ } if (os != null) { return os; } // they are requesting a stream to write to. This implies a POST method if (method == GET) { method = POST; } // If the request method is neither PUT or POST, then you're not writing if (method != PUT && method != POST) { throw new ProtocolException(Msg.getString("K008f", method)); // $NON-NLS-1$ } int limit = -1; String contentLength = reqHeader.get("Content-Length"); // $NON-NLS-1$ if (contentLength != null) { limit = Integer.parseInt(contentLength); } String encoding = reqHeader.get("Transfer-Encoding"); // $NON-NLS-1$ if (httpVersion > 0 && encoding != null) { encoding = encoding.toLowerCase(); if ("chunked".equals(encoding)) { // $NON-NLS-1$ sendChunked = true; limit = -1; } } // if user has set chunk/fixedLength mode, use that value if (chunkLength > 0) { sendChunked = true; limit = -1; } if (fixedContentLength >= 0) { limit = fixedContentLength; } if ((httpVersion > 0 && sendChunked) || limit >= 0) { os = new HttpOutputStream(limit); doRequest(); return os; } if (!connected) { // connect and see if there is cache available. connect(); } return os = new HttpOutputStream(); }
/** * Resets this reader's position to the last {@code mark()} location. Invocations of {@code * read()} and {@code skip()} will occur from this new location. * * @throws IOException if this reader is closed or no mark has been set. * @see #mark(int) * @see #markSupported() */ @Override public void reset() throws IOException { synchronized (lock) { if (isClosed()) { throw new IOException(Msg.getString("K005b")); // $NON-NLS-1$ } if (mark == -1) { throw new IOException(Msg.getString("K005c")); // $NON-NLS-1$ } pos = mark; } }
@Override protected synchronized OutputStream getOutputStream() throws IOException { if (!fd.valid()) { throw new SocketException(Msg.getString("K003d")); // $NON-NLS-1$ } return new SocketOutputStream(this); }
/** * Tries to reach this {@code InetAddress}. This method first tries to use ICMP <i>(ICMP ECHO * REQUEST)</i>. When first step fails, a TCP connection on port 7 (Echo) of the remote host is * established. * * @param netif the network interface on which to connection should be established. * @param ttl the maximum count of hops (time-to-live). * @param timeout timeout in milliseconds before the test fails if no connection could be * established. * @return {@code true} if this address is reachable, {@code false} otherwise. * @throws IOException if an error occurs during an I/O operation. * @throws IllegalArgumentException if ttl or timeout is less than zero. */ public boolean isReachable(NetworkInterface netif, final int ttl, final int timeout) throws IOException { if (0 > ttl || 0 > timeout) { throw new IllegalArgumentException(Msg.getString("K0051")); // $NON-NLS-1$ } boolean reachable = false; if (null == netif) { // network interface is null, binds to no address // BEGIN android-changed // reachable = NETIMPL.isReachableByICMP(this, null, ttl, timeout); // if (!reachable) { reachable = isReachableByTCP(this, null, timeout); // } // END android-changed } else { // Not Bind to any address if (null == netif.addresses) { return false; } // binds to all address on this NetworkInterface, tries ICMP ping // first // BEGIN android-changed // reachable = isReachableByICMPUseMultiThread(netif, ttl, timeout); // if (!reachable) { // tries TCP echo if ICMP ping fails reachable = isReachableByMultiThread(netif, ttl, timeout); // } // END adnroid-changed } return reachable; }
@Override public Map<String, List<String>> getRequestProperties() { if (connected) { throw new IllegalStateException(Msg.getString("K0091")); // $NON-NLS-1$ } return reqHeader.getFieldMap(); }
@Override public synchronized void write(int data) throws IOException { if (closed) { throw new IOException(Msg.getString("K0059")); // $NON-NLS-1$ } if (limit >= 0) { if (limit == 0) { throw new IOException(Msg.getString("K00b2")); // $NON-NLS-1$ } limit--; } cache.write(data); if (writeToSocket && cache.size() >= cacheLength) { sendCache(false); } }
/** * Skips {@code amount} characters in this reader. Subsequent {@code read()}s will not return * these characters unless {@code reset()} is used. Skipping characters may invalidate a mark if * {@code markLimit} is surpassed. * * @param amount the maximum number of characters to skip. * @return the number of characters actually skipped. * @throws IllegalArgumentException if {@code amount < 0}. * @throws IOException if this reader is closed or some other I/O error occurs. * @see #mark(int) * @see #markSupported() * @see #reset() */ @Override public long skip(long amount) throws IOException { if (amount < 0) { throw new IllegalArgumentException(); } synchronized (lock) { if (isClosed()) { throw new IOException(Msg.getString("K005b")); // $NON-NLS-1$ } if (amount < 1) { return 0; } if (end - pos >= amount) { pos += amount; return amount; } long read = end - pos; pos = end; while (read < amount) { if (fillBuf() == -1) { return read; } if (end - pos >= amount - read) { pos += amount - read; return amount; } // Couldn't get all the characters, skip what we read read += (end - pos); pos = end; } return amount; } }
/** * Constructs a new BufferedReader on the Reader {@code in}. The buffer size is specified by the * parameter {@code size}. * * @param in the Reader that is buffered. * @param size the size of the buffer to allocate. * @throws IllegalArgumentException if {@code size <= 0}. */ public BufferedReader(Reader in, int size) { super(in); if (size <= 0) { throw new IllegalArgumentException(Msg.getString("K0058")); // $NON-NLS-1$ } this.in = in; buf = new char[size]; }
@Override public synchronized void write(byte[] buffer, int offset, int count) throws IOException { if (closed) { throw new IOException(Msg.getString("K0059")); // $NON-NLS-1$ } if (buffer == null) { throw new NullPointerException(); } // avoid int overflow if (offset < 0 || count < 0 || offset > buffer.length || buffer.length - offset < count) { throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); // $NON-NLS-1$ } if (limit >= 0) { if (count > limit) { throw new IOException(Msg.getString("K00b2")); // $NON-NLS-1$ } limit -= count; cache.write(buffer, offset, count); if (limit == 0) { socketOut.write(cache.toByteArray()); } } else { if (!writeToSocket || cache.size() + count < cacheLength) { cache.write(buffer, offset, count); } else { output(Integer.toHexString(cacheLength) + "\r\n"); // $NON-NLS-1$ int writeNum = cacheLength - cache.size(); cache.write(buffer, offset, writeNum); socketOut.write(cache.toByteArray()); output("\r\n"); // $NON-NLS-1$ cache.reset(); int left = count - writeNum; int position = offset + writeNum; while (left > cacheLength) { output(Integer.toHexString(cacheLength) + "\r\n"); // $NON-NLS-1$ socketOut.write(buffer, position, cacheLength); output("\r\n"); // $NON-NLS-1$ left = left - cacheLength; position = position + cacheLength; } cache.write(buffer, position, left); } } }
// BEGIN android-changed // static native InetAddress getHostByAddrImpl(byte[] addr) // throws UnknownHostException; static InetAddress getHostByAddrImpl(byte[] addr) throws UnknownHostException { if (addr.length == 4) { return new Inet4Address(addr, getnameinfo(addr)); } else if (addr.length == 16) { return new Inet6Address(addr, getnameinfo(addr)); } else { throw new UnknownHostException(Msg.getString("K0339")); // $NON-NLS-1$ } }
private void setProxy(String proxy) { int index = proxy.indexOf(':'); if (index == -1) { proxyName = proxy; hostPort = defaultPort; } else { proxyName = proxy.substring(0, index); String port = proxy.substring(index + 1); try { hostPort = Integer.parseInt(port); } catch (NumberFormatException e) { throw new IllegalArgumentException(Msg.getString("K00af", port)); // $NON-NLS-1$ } if (hostPort < 0 || hostPort > 65535) { throw new IllegalArgumentException(Msg.getString("K00b0")); // $NON-NLS-1$ } } }
/** * Constructs a new BufferedReader with <code>out</code> as the Writer on which buffer write * operations. The buffer size is set to <code>size</code>. * * @param out The Writer to buffer character writing on. * @param size The size of the buffer to use. */ public BufferedWriter(Writer out, int size) { super(out); if (size > 0) { this.out = out; this.buf = new char[size]; } else { throw new IllegalArgumentException(Msg.getString("K0058")); // $NON-NLS-1$ } }
@Override public void setRequestProperty(String field, String newValue) { if (connected) { throw new IllegalStateException(Msg.getString("K0092")); // $NON-NLS-1$ } if (field == null) { throw new NullPointerException(); } reqHeader.set(field, newValue); }
@Override public void addRequestProperty(String field, String value) { if (connected) { throw new IllegalAccessError(Msg.getString("K0092")); // $NON-NLS-1$ } if (field == null) { throw new NullPointerException(); } reqHeader.add(field, value); }
@Override public synchronized void flush() throws IOException { if (closed) { throw new IOException(Msg.getString("K0059")); // $NON-NLS-1$ } if (writeToSocket) { sendCache(false); socketOut.flush(); } }
/** Issue the STOR command to the server with the file as the parameter */ private void sendFile() throws IOException { int reply; write( "STOR " //$NON-NLS-1$ + url.getFile().substring(url.getFile().lastIndexOf('/') + 1, url.getFile().length()) + "\r\n"); //$NON-NLS-1$ reply = getReply(); if (!(reply == FTP_OPENDATA || reply == FTP_OK || reply == FTP_DATAOPEN)) { throw new IOException(Msg.getString("K009a")); // $NON-NLS-1$ } }
/** * Writes {@code count} characters starting at {@code offset} in {@code buf} to this writer. The * characters are immediately converted to bytes by the character converter and stored in a local * buffer. If the buffer gets full as a result of the conversion, this writer is flushed. * * @param buf the array containing characters to write. * @param offset the index of the first character in {@code buf} to write. * @param count the maximum number of characters to write. * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code count < 0}, or if {@code * offset + count} is greater than the size of {@code buf}. * @throws IOException if this writer has already been closed or another I/O error occurs. */ @Override public void write(char[] buf, int offset, int count) throws IOException { synchronized (lock) { checkStatus(); // BEGIN android-changed // Exception priorities (in case of multiple errors) differ from // RI, but are spec-compliant. // made implicit null check explicit, // used (offset | count) < 0 instead of (offset < 0) || (count < 0) // to safe one operation if (buf == null) { throw new NullPointerException(Msg.getString("K0047")); // $NON-NLS-1$ } if ((offset | count) < 0 || offset > buf.length - count) { throw new IndexOutOfBoundsException(Msg.getString("K002f")); // $NON-NLS-1$ } // END android-changed CharBuffer chars = CharBuffer.wrap(buf, offset, count); convert(chars); } }
private void login() throws IOException { int reply; reply = getReply(); if (reply == FTP_USERREADY) { } else { throw new IOException(Msg.getString("K0097", url.getHost())); // $NON-NLS-1$ } write("USER " + username + "\r\n"); // $NON-NLS-1$ //$NON-NLS-2$ reply = getReply(); if (reply == FTP_PASWD || reply == FTP_LOGGEDIN) { } else { throw new IOException(Msg.getString("K0098", url.getHost())); // $NON-NLS-1$ } if (reply == FTP_PASWD) { write("PASS " + password + "\r\n"); // $NON-NLS-1$ //$NON-NLS-2$ reply = getReply(); if (!(reply == FTP_OK || reply == FTP_USERREADY || reply == FTP_LOGGEDIN)) { throw new IOException(Msg.getString("K0098", url.getHost())); // $NON-NLS-1$ } } }
/** * Writes {@code count} characters starting at {@code offset} in {@code str} to this writer. The * characters are immediately converted to bytes by the character converter and stored in a local * buffer. If the buffer gets full as a result of the conversion, this writer is flushed. * * @param str the string containing characters to write. * @param offset the start position in {@code str} for retrieving characters. * @param count the maximum number of characters to write. * @throws IOException if this writer has already been closed or another I/O error occurs. * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code count < 0}, or if {@code * offset + count} is bigger than the length of {@code str}. */ @Override public void write(String str, int offset, int count) throws IOException { synchronized (lock) { // avoid int overflow // BEGIN android-changed // Exception priorities (in case of multiple errors) differ from RI, // but are spec-compliant. // made implicit null check explicit, used (offset | count) < 0 // instead of (offset < 0) || (count < 0) to safe one operation if (str == null) { throw new NullPointerException(Msg.getString("K0047")); // $NON-NLS-1$ } if ((offset | count) < 0 || offset > str.length() - count) { throw new StringIndexOutOfBoundsException(Msg.getString("K002f")); // $NON-NLS-1$ } // END android-changed checkStatus(); CharBuffer chars = CharBuffer.wrap(str, offset, count + offset); convert(chars); } }
private void port() throws IOException { write( "PORT " //$NON-NLS-1$ + controlSocket.getLocalAddress().getHostAddress().replace('.', ',') + ',' + (dataPort >> 8) + ',' + (dataPort & 255) + "\r\n"); //$NON-NLS-1$ if (getReply() != FTP_OK) { throw new IOException(Msg.getString("K0099")); // $NON-NLS-1$ } }
private void getFile() throws IOException { int reply; String file = url.getFile(); write("RETR " + file + "\r\n"); // $NON-NLS-1$ //$NON-NLS-2$ reply = getReply(); if (reply == FTP_NOTFOUND && file.length() > 0 && file.charAt(0) == '/') { write("RETR " + file.substring(1) + "\r\n"); // $NON-NLS-1$ //$NON-NLS-2$ reply = getReply(); } if (!(reply == FTP_OPENDATA || reply == FTP_TRANSFEROK)) { throw new FileNotFoundException(Msg.getString("K0096", reply)); // $NON-NLS-1$ } }
/** * Sets a mark position in this reader. The parameter {@code markLimit} indicates how many * characters can be read before the mark is invalidated. Calling {@code reset()} will reposition * the reader back to the marked position if {@code markLimit} has not been surpassed. * * @param markLimit the number of characters that can be read before the mark is invalidated. * @throws IllegalArgumentException if {@code markLimit < 0}. * @throws IOException if an error occurs while setting a mark in this reader. * @see #markSupported() * @see #reset() */ @Override public void mark(int markLimit) throws IOException { if (markLimit < 0) { throw new IllegalArgumentException(); } synchronized (lock) { if (isClosed()) { throw new IOException(Msg.getString("K005b")); // $NON-NLS-1$ } this.markLimit = markLimit; mark = pos; } }
/** * Reads a single character from this reader and returns it with the two higher-order bytes set to * 0. If possible, BufferedReader returns a character from the buffer. If there are no characters * available in the buffer, it fills the buffer and then returns a character. It returns -1 if * there are no more characters in the source reader. * * @return the character read or -1 if the end of the source reader has been reached. * @throws IOException if this reader is closed or some other I/O error occurs. */ @Override public int read() throws IOException { synchronized (lock) { if (isClosed()) { throw new IOException(Msg.getString("K005b")); // $NON-NLS-1$ } /* Are there buffered characters available? */ if (pos < end || fillBuf() != -1) { return buf[pos++]; } return -1; } }
@Override public synchronized void close() throws IOException { if (closed) { return; } closed = true; if (writeToSocket) { if (limit > 0) { throw new IOException(Msg.getString("K00a4")); // $NON-NLS-1$ } sendCache(closed); } disconnect(false); }