Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E651110943 for ; Wed, 12 Jun 2013 17:15:56 +0000 (UTC) Received: (qmail 6869 invoked by uid 500); 12 Jun 2013 17:15:35 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 6788 invoked by uid 500); 12 Jun 2013 17:15:34 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 5456 invoked by uid 99); 12 Jun 2013 17:15:19 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Jun 2013 17:15:19 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 046468A3A51; Wed, 12 Jun 2013 17:15:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: filmaj@apache.org To: commits@cordova.apache.org Date: Wed, 12 Jun 2013 17:15:59 -0000 Message-Id: <6e742828311f4689bcb6de42d694a92e@git.apache.org> In-Reply-To: <892da121a6f547df8657f2c4836f57c1@git.apache.org> References: <892da121a6f547df8657f2c4836f57c1@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [43/56] [abbrv] [partial] start of lazy loading: axe all vendored-in libs http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/TunnelRequest.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/TunnelRequest.java b/lib/cordova-android/framework/src/com/squareup/okhttp/TunnelRequest.java deleted file mode 100644 index 5260b87..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/TunnelRequest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * 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.squareup.okhttp; - -import com.squareup.okhttp.internal.http.RawHeaders; - -import static com.squareup.okhttp.internal.Util.getDefaultPort; - -/** - * Routing and authentication information sent to an HTTP proxy to create a - * HTTPS to an origin server. Everything in the tunnel request is sent - * unencrypted to the proxy server. - * - *

See RFC 2817, Section - * 5.2. - */ -public final class TunnelRequest { - final String host; - final int port; - final String userAgent; - final String proxyAuthorization; - - /** - * @param host the origin server's hostname. Not null. - * @param port the origin server's port, like 80 or 443. - * @param userAgent the client's user-agent. Not null. - * @param proxyAuthorization proxy authorization, or null if the proxy is - * used without an authorization header. - */ - public TunnelRequest(String host, int port, String userAgent, String proxyAuthorization) { - if (host == null) throw new NullPointerException("host == null"); - if (userAgent == null) throw new NullPointerException("userAgent == null"); - this.host = host; - this.port = port; - this.userAgent = userAgent; - this.proxyAuthorization = proxyAuthorization; - } - - /** - * If we're creating a TLS tunnel, send only the minimum set of headers. - * This avoids sending potentially sensitive data like HTTP cookies to - * the proxy unencrypted. - */ - RawHeaders getRequestHeaders() { - RawHeaders result = new RawHeaders(); - result.setRequestLine("CONNECT " + host + ":" + port + " HTTP/1.1"); - - // Always set Host and User-Agent. - result.set("Host", port == getDefaultPort("https") ? host : (host + ":" + port)); - result.set("User-Agent", userAgent); - - // Copy over the Proxy-Authorization header if it exists. - if (proxyAuthorization != null) { - result.set("Proxy-Authorization", proxyAuthorization); - } - - // Always set the Proxy-Connection to Keep-Alive for the benefit of - // HTTP/1.0 proxies like Squid. - result.set("Proxy-Connection", "Keep-Alive"); - return result; - } -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/AbstractOutputStream.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/AbstractOutputStream.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/AbstractOutputStream.java deleted file mode 100644 index 78c9691..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/AbstractOutputStream.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * 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.squareup.okhttp.internal; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An output stream for an HTTP request body. - * - *

Since a single socket's output stream may be used to write multiple HTTP - * requests to the same server, subclasses should not close the socket stream. - */ -public abstract class AbstractOutputStream extends OutputStream { - protected boolean closed; - - @Override public final void write(int data) throws IOException { - write(new byte[] { (byte) data }); - } - - protected final void checkNotClosed() throws IOException { - if (closed) { - throw new IOException("stream closed"); - } - } - - /** Returns true if this stream was closed locally. */ - public boolean isClosed() { - return closed; - } -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Base64.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Base64.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Base64.java deleted file mode 100644 index 79cd020..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Base64.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -/** - * @author Alexander Y. Kleymenov - */ - -package com.squareup.okhttp.internal; - -import java.io.UnsupportedEncodingException; - -import static com.squareup.okhttp.internal.Util.EMPTY_BYTE_ARRAY; - -/** - * Base64 encoder/decoder. - * In violation of the RFC, this encoder doesn't wrap lines at 76 columns. - */ -public final class Base64 { - private Base64() { - } - - public static byte[] decode(byte[] in) { - return decode(in, in.length); - } - - public static byte[] decode(byte[] in, int len) { - // approximate output length - int length = len / 4 * 3; - // return an empty array on empty or short input without padding - if (length == 0) { - return EMPTY_BYTE_ARRAY; - } - // temporary array - byte[] out = new byte[length]; - // number of padding characters ('=') - int pad = 0; - byte chr; - // compute the number of the padding characters - // and adjust the length of the input - for (; ; len--) { - chr = in[len - 1]; - // skip the neutral characters - if ((chr == '\n') || (chr == '\r') || (chr == ' ') || (chr == '\t')) { - continue; - } - if (chr == '=') { - pad++; - } else { - break; - } - } - // index in the output array - int outIndex = 0; - // index in the input array - int inIndex = 0; - // holds the value of the input character - int bits = 0; - // holds the value of the input quantum - int quantum = 0; - for (int i = 0; i < len; i++) { - chr = in[i]; - // skip the neutral characters - if ((chr == '\n') || (chr == '\r') || (chr == ' ') || (chr == '\t')) { - continue; - } - if ((chr >= 'A') && (chr <= 'Z')) { - // char ASCII value - // A 65 0 - // Z 90 25 (ASCII - 65) - bits = chr - 65; - } else if ((chr >= 'a') && (chr <= 'z')) { - // char ASCII value - // a 97 26 - // z 122 51 (ASCII - 71) - bits = chr - 71; - } else if ((chr >= '0') && (chr <= '9')) { - // char ASCII value - // 0 48 52 - // 9 57 61 (ASCII + 4) - bits = chr + 4; - } else if (chr == '+') { - bits = 62; - } else if (chr == '/') { - bits = 63; - } else { - return null; - } - // append the value to the quantum - quantum = (quantum << 6) | (byte) bits; - if (inIndex % 4 == 3) { - // 4 characters were read, so make the output: - out[outIndex++] = (byte) (quantum >> 16); - out[outIndex++] = (byte) (quantum >> 8); - out[outIndex++] = (byte) quantum; - } - inIndex++; - } - if (pad > 0) { - // adjust the quantum value according to the padding - quantum = quantum << (6 * pad); - // make output - out[outIndex++] = (byte) (quantum >> 16); - if (pad == 1) { - out[outIndex++] = (byte) (quantum >> 8); - } - } - // create the resulting array - byte[] result = new byte[outIndex]; - System.arraycopy(out, 0, result, 0, outIndex); - return result; - } - - private static final byte[] MAP = new byte[] { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', '+', '/' - }; - - public static String encode(byte[] in) { - int length = (in.length + 2) * 4 / 3; - byte[] out = new byte[length]; - int index = 0, end = in.length - in.length % 3; - for (int i = 0; i < end; i += 3) { - out[index++] = MAP[(in[i] & 0xff) >> 2]; - out[index++] = MAP[((in[i] & 0x03) << 4) | ((in[i + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[i + 1] & 0x0f) << 2) | ((in[i + 2] & 0xff) >> 6)]; - out[index++] = MAP[(in[i + 2] & 0x3f)]; - } - switch (in.length % 3) { - case 1: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[(in[end] & 0x03) << 4]; - out[index++] = '='; - out[index++] = '='; - break; - case 2: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[((in[end] & 0x03) << 4) | ((in[end + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[end + 1] & 0x0f) << 2)]; - out[index++] = '='; - break; - } - try { - return new String(out, 0, index, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } - } -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/DiskLruCache.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/DiskLruCache.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/DiskLruCache.java deleted file mode 100644 index f7fcb1e..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/DiskLruCache.java +++ /dev/null @@ -1,926 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * 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.squareup.okhttp.internal; - -import java.io.BufferedWriter; -import java.io.Closeable; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A cache that uses a bounded amount of space on a filesystem. Each cache - * entry has a string key and a fixed number of values. Each key must match - * the regex [a-z0-9_-]{1,64}. Values are byte sequences, - * accessible as streams or files. Each value must be between {@code 0} and - * {@code Integer.MAX_VALUE} bytes in length. - * - *

The cache stores its data in a directory on the filesystem. This - * directory must be exclusive to the cache; the cache may delete or overwrite - * files from its directory. It is an error for multiple processes to use the - * same cache directory at the same time. - * - *

This cache limits the number of bytes that it will store on the - * filesystem. When the number of stored bytes exceeds the limit, the cache will - * remove entries in the background until the limit is satisfied. The limit is - * not strict: the cache may temporarily exceed it while waiting for files to be - * deleted. The limit does not include filesystem overhead or the cache - * journal so space-sensitive applications should set a conservative limit. - * - *

Clients call {@link #edit} to create or update the values of an entry. An - * entry may have only one editor at one time; if a value is not available to be - * edited then {@link #edit} will return null. - *

    - *
  • When an entry is being created it is necessary to - * supply a full set of values; the empty value should be used as a - * placeholder if necessary. - *
  • When an entry is being edited, it is not necessary - * to supply data for every value; values default to their previous - * value. - *
- * Every {@link #edit} call must be matched by a call to {@link Editor#commit} - * or {@link Editor#abort}. Committing is atomic: a read observes the full set - * of values as they were before or after the commit, but never a mix of values. - * - *

Clients call {@link #get} to read a snapshot of an entry. The read will - * observe the value at the time that {@link #get} was called. Updates and - * removals after the call do not impact ongoing reads. - * - *

This class is tolerant of some I/O errors. If files are missing from the - * filesystem, the corresponding entries will be dropped from the cache. If - * an error occurs while writing a cache value, the edit will fail silently. - * Callers should handle other problems by catching {@code IOException} and - * responding appropriately. - */ -public final class DiskLruCache implements Closeable { - static final String JOURNAL_FILE = "journal"; - static final String JOURNAL_FILE_TEMP = "journal.tmp"; - static final String JOURNAL_FILE_BACKUP = "journal.bkp"; - static final String MAGIC = "libcore.io.DiskLruCache"; - static final String VERSION_1 = "1"; - static final long ANY_SEQUENCE_NUMBER = -1; - static final Pattern LEGAL_KEY_PATTERN = Pattern.compile("[a-z0-9_-]{1,64}"); - private static final String CLEAN = "CLEAN"; - private static final String DIRTY = "DIRTY"; - private static final String REMOVE = "REMOVE"; - private static final String READ = "READ"; - - /* - * This cache uses a journal file named "journal". A typical journal file - * looks like this: - * libcore.io.DiskLruCache - * 1 - * 100 - * 2 - * - * CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054 - * DIRTY 335c4c6028171cfddfbaae1a9c313c52 - * CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342 - * REMOVE 335c4c6028171cfddfbaae1a9c313c52 - * DIRTY 1ab96a171faeeee38496d8b330771a7a - * CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234 - * READ 335c4c6028171cfddfbaae1a9c313c52 - * READ 3400330d1dfc7f3f7f4b8d4d803dfcf6 - * - * The first five lines of the journal form its header. They are the - * constant string "libcore.io.DiskLruCache", the disk cache's version, - * the application's version, the value count, and a blank line. - * - * Each of the subsequent lines in the file is a record of the state of a - * cache entry. Each line contains space-separated values: a state, a key, - * and optional state-specific values. - * o DIRTY lines track that an entry is actively being created or updated. - * Every successful DIRTY action should be followed by a CLEAN or REMOVE - * action. DIRTY lines without a matching CLEAN or REMOVE indicate that - * temporary files may need to be deleted. - * o CLEAN lines track a cache entry that has been successfully published - * and may be read. A publish line is followed by the lengths of each of - * its values. - * o READ lines track accesses for LRU. - * o REMOVE lines track entries that have been deleted. - * - * The journal file is appended to as cache operations occur. The journal may - * occasionally be compacted by dropping redundant lines. A temporary file named - * "journal.tmp" will be used during compaction; that file should be deleted if - * it exists when the cache is opened. - */ - - private final File directory; - private final File journalFile; - private final File journalFileTmp; - private final File journalFileBackup; - private final int appVersion; - private long maxSize; - private final int valueCount; - private long size = 0; - private Writer journalWriter; - private final LinkedHashMap lruEntries = - new LinkedHashMap(0, 0.75f, true); - private int redundantOpCount; - - /** - * To differentiate between old and current snapshots, each entry is given - * a sequence number each time an edit is committed. A snapshot is stale if - * its sequence number is not equal to its entry's sequence number. - */ - private long nextSequenceNumber = 0; - - /** This cache uses a single background thread to evict entries. */ - final ThreadPoolExecutor executorService = - new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue()); - private final Callable cleanupCallable = new Callable() { - public Void call() throws Exception { - synchronized (DiskLruCache.this) { - if (journalWriter == null) { - return null; // Closed. - } - trimToSize(); - if (journalRebuildRequired()) { - rebuildJournal(); - redundantOpCount = 0; - } - } - return null; - } - }; - - private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) { - this.directory = directory; - this.appVersion = appVersion; - this.journalFile = new File(directory, JOURNAL_FILE); - this.journalFileTmp = new File(directory, JOURNAL_FILE_TEMP); - this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP); - this.valueCount = valueCount; - this.maxSize = maxSize; - } - - /** - * Opens the cache in {@code directory}, creating a cache if none exists - * there. - * - * @param directory a writable directory - * @param valueCount the number of values per cache entry. Must be positive. - * @param maxSize the maximum number of bytes this cache should use to store - * @throws IOException if reading or writing the cache directory fails - */ - public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) - throws IOException { - if (maxSize <= 0) { - throw new IllegalArgumentException("maxSize <= 0"); - } - if (valueCount <= 0) { - throw new IllegalArgumentException("valueCount <= 0"); - } - - // If a bkp file exists, use it instead. - File backupFile = new File(directory, JOURNAL_FILE_BACKUP); - if (backupFile.exists()) { - File journalFile = new File(directory, JOURNAL_FILE); - // If journal file also exists just delete backup file. - if (journalFile.exists()) { - backupFile.delete(); - } else { - renameTo(backupFile, journalFile, false); - } - } - - // Prefer to pick up where we left off. - DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); - if (cache.journalFile.exists()) { - try { - cache.readJournal(); - cache.processJournal(); - cache.journalWriter = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(cache.journalFile, true), Util.US_ASCII)); - return cache; - } catch (IOException journalIsCorrupt) { - Platform.get().logW("DiskLruCache " + directory + " is corrupt: " - + journalIsCorrupt.getMessage() + ", removing"); - cache.delete(); - } - } - - // Create a new empty cache. - directory.mkdirs(); - cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); - cache.rebuildJournal(); - return cache; - } - - private void readJournal() throws IOException { - StrictLineReader reader = new StrictLineReader(new FileInputStream(journalFile), Util.US_ASCII); - try { - String magic = reader.readLine(); - String version = reader.readLine(); - String appVersionString = reader.readLine(); - String valueCountString = reader.readLine(); - String blank = reader.readLine(); - if (!MAGIC.equals(magic) - || !VERSION_1.equals(version) - || !Integer.toString(appVersion).equals(appVersionString) - || !Integer.toString(valueCount).equals(valueCountString) - || !"".equals(blank)) { - throw new IOException("unexpected journal header: [" + magic + ", " + version + ", " - + valueCountString + ", " + blank + "]"); - } - - int lineCount = 0; - while (true) { - try { - readJournalLine(reader.readLine()); - lineCount++; - } catch (EOFException endOfJournal) { - break; - } - } - redundantOpCount = lineCount - lruEntries.size(); - } finally { - Util.closeQuietly(reader); - } - } - - private void readJournalLine(String line) throws IOException { - int firstSpace = line.indexOf(' '); - if (firstSpace == -1) { - throw new IOException("unexpected journal line: " + line); - } - - int keyBegin = firstSpace + 1; - int secondSpace = line.indexOf(' ', keyBegin); - final String key; - if (secondSpace == -1) { - key = line.substring(keyBegin); - if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) { - lruEntries.remove(key); - return; - } - } else { - key = line.substring(keyBegin, secondSpace); - } - - Entry entry = lruEntries.get(key); - if (entry == null) { - entry = new Entry(key); - lruEntries.put(key, entry); - } - - if (secondSpace != -1 && firstSpace == CLEAN.length() && line.startsWith(CLEAN)) { - String[] parts = line.substring(secondSpace + 1).split(" "); - entry.readable = true; - entry.currentEditor = null; - entry.setLengths(parts); - } else if (secondSpace == -1 && firstSpace == DIRTY.length() && line.startsWith(DIRTY)) { - entry.currentEditor = new Editor(entry); - } else if (secondSpace == -1 && firstSpace == READ.length() && line.startsWith(READ)) { - // This work was already done by calling lruEntries.get(). - } else { - throw new IOException("unexpected journal line: " + line); - } - } - - /** - * Computes the initial size and collects garbage as a part of opening the - * cache. Dirty entries are assumed to be inconsistent and will be deleted. - */ - private void processJournal() throws IOException { - deleteIfExists(journalFileTmp); - for (Iterator i = lruEntries.values().iterator(); i.hasNext(); ) { - Entry entry = i.next(); - if (entry.currentEditor == null) { - for (int t = 0; t < valueCount; t++) { - size += entry.lengths[t]; - } - } else { - entry.currentEditor = null; - for (int t = 0; t < valueCount; t++) { - deleteIfExists(entry.getCleanFile(t)); - deleteIfExists(entry.getDirtyFile(t)); - } - i.remove(); - } - } - } - - /** - * Creates a new journal that omits redundant information. This replaces the - * current journal if it exists. - */ - private synchronized void rebuildJournal() throws IOException { - if (journalWriter != null) { - journalWriter.close(); - } - - Writer writer = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(journalFileTmp), Util.US_ASCII)); - try { - writer.write(MAGIC); - writer.write("\n"); - writer.write(VERSION_1); - writer.write("\n"); - writer.write(Integer.toString(appVersion)); - writer.write("\n"); - writer.write(Integer.toString(valueCount)); - writer.write("\n"); - writer.write("\n"); - - for (Entry entry : lruEntries.values()) { - if (entry.currentEditor != null) { - writer.write(DIRTY + ' ' + entry.key + '\n'); - } else { - writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); - } - } - } finally { - writer.close(); - } - - if (journalFile.exists()) { - renameTo(journalFile, journalFileBackup, true); - } - renameTo(journalFileTmp, journalFile, false); - journalFileBackup.delete(); - - journalWriter = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(journalFile, true), Util.US_ASCII)); - } - - private static void deleteIfExists(File file) throws IOException { - if (file.exists() && !file.delete()) { - throw new IOException(); - } - } - - private static void renameTo(File from, File to, boolean deleteDestination) throws IOException { - if (deleteDestination) { - deleteIfExists(to); - } - if (!from.renameTo(to)) { - throw new IOException(); - } - } - - /** - * Returns a snapshot of the entry named {@code key}, or null if it doesn't - * exist is not currently readable. If a value is returned, it is moved to - * the head of the LRU queue. - */ - public synchronized Snapshot get(String key) throws IOException { - checkNotClosed(); - validateKey(key); - Entry entry = lruEntries.get(key); - if (entry == null) { - return null; - } - - if (!entry.readable) { - return null; - } - - // Open all streams eagerly to guarantee that we see a single published - // snapshot. If we opened streams lazily then the streams could come - // from different edits. - InputStream[] ins = new InputStream[valueCount]; - try { - for (int i = 0; i < valueCount; i++) { - ins[i] = new FileInputStream(entry.getCleanFile(i)); - } - } catch (FileNotFoundException e) { - // A file must have been deleted manually! - for (int i = 0; i < valueCount; i++) { - if (ins[i] != null) { - Util.closeQuietly(ins[i]); - } else { - break; - } - } - return null; - } - - redundantOpCount++; - journalWriter.append(READ + ' ' + key + '\n'); - if (journalRebuildRequired()) { - executorService.submit(cleanupCallable); - } - - return new Snapshot(key, entry.sequenceNumber, ins, entry.lengths); - } - - /** - * Returns an editor for the entry named {@code key}, or null if another - * edit is in progress. - */ - public Editor edit(String key) throws IOException { - return edit(key, ANY_SEQUENCE_NUMBER); - } - - private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException { - checkNotClosed(); - validateKey(key); - Entry entry = lruEntries.get(key); - if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER && (entry == null - || entry.sequenceNumber != expectedSequenceNumber)) { - return null; // Snapshot is stale. - } - if (entry == null) { - entry = new Entry(key); - lruEntries.put(key, entry); - } else if (entry.currentEditor != null) { - return null; // Another edit is in progress. - } - - Editor editor = new Editor(entry); - entry.currentEditor = editor; - - // Flush the journal before creating files to prevent file leaks. - journalWriter.write(DIRTY + ' ' + key + '\n'); - journalWriter.flush(); - return editor; - } - - /** Returns the directory where this cache stores its data. */ - public File getDirectory() { - return directory; - } - - /** - * Returns the maximum number of bytes that this cache should use to store - * its data. - */ - public long getMaxSize() { - return maxSize; - } - - /** - * Changes the maximum number of bytes the cache can store and queues a job - * to trim the existing store, if necessary. - */ - public synchronized void setMaxSize(long maxSize) { - this.maxSize = maxSize; - executorService.submit(cleanupCallable); - } - - /** - * Returns the number of bytes currently being used to store the values in - * this cache. This may be greater than the max size if a background - * deletion is pending. - */ - public synchronized long size() { - return size; - } - - private synchronized void completeEdit(Editor editor, boolean success) throws IOException { - Entry entry = editor.entry; - if (entry.currentEditor != editor) { - throw new IllegalStateException(); - } - - // If this edit is creating the entry for the first time, every index must have a value. - if (success && !entry.readable) { - for (int i = 0; i < valueCount; i++) { - if (!editor.written[i]) { - editor.abort(); - throw new IllegalStateException("Newly created entry didn't create value for index " + i); - } - if (!entry.getDirtyFile(i).exists()) { - editor.abort(); - return; - } - } - } - - for (int i = 0; i < valueCount; i++) { - File dirty = entry.getDirtyFile(i); - if (success) { - if (dirty.exists()) { - File clean = entry.getCleanFile(i); - dirty.renameTo(clean); - long oldLength = entry.lengths[i]; - long newLength = clean.length(); - entry.lengths[i] = newLength; - size = size - oldLength + newLength; - } - } else { - deleteIfExists(dirty); - } - } - - redundantOpCount++; - entry.currentEditor = null; - if (entry.readable | success) { - entry.readable = true; - journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); - if (success) { - entry.sequenceNumber = nextSequenceNumber++; - } - } else { - lruEntries.remove(entry.key); - journalWriter.write(REMOVE + ' ' + entry.key + '\n'); - } - journalWriter.flush(); - - if (size > maxSize || journalRebuildRequired()) { - executorService.submit(cleanupCallable); - } - } - - /** - * We only rebuild the journal when it will halve the size of the journal - * and eliminate at least 2000 ops. - */ - private boolean journalRebuildRequired() { - final int redundantOpCompactThreshold = 2000; - return redundantOpCount >= redundantOpCompactThreshold // - && redundantOpCount >= lruEntries.size(); - } - - /** - * Drops the entry for {@code key} if it exists and can be removed. Entries - * actively being edited cannot be removed. - * - * @return true if an entry was removed. - */ - public synchronized boolean remove(String key) throws IOException { - checkNotClosed(); - validateKey(key); - Entry entry = lruEntries.get(key); - if (entry == null || entry.currentEditor != null) { - return false; - } - - for (int i = 0; i < valueCount; i++) { - File file = entry.getCleanFile(i); - if (!file.delete()) { - throw new IOException("failed to delete " + file); - } - size -= entry.lengths[i]; - entry.lengths[i] = 0; - } - - redundantOpCount++; - journalWriter.append(REMOVE + ' ' + key + '\n'); - lruEntries.remove(key); - - if (journalRebuildRequired()) { - executorService.submit(cleanupCallable); - } - - return true; - } - - /** Returns true if this cache has been closed. */ - public boolean isClosed() { - return journalWriter == null; - } - - private void checkNotClosed() { - if (journalWriter == null) { - throw new IllegalStateException("cache is closed"); - } - } - - /** Force buffered operations to the filesystem. */ - public synchronized void flush() throws IOException { - checkNotClosed(); - trimToSize(); - journalWriter.flush(); - } - - /** Closes this cache. Stored values will remain on the filesystem. */ - public synchronized void close() throws IOException { - if (journalWriter == null) { - return; // Already closed. - } - for (Entry entry : new ArrayList(lruEntries.values())) { - if (entry.currentEditor != null) { - entry.currentEditor.abort(); - } - } - trimToSize(); - journalWriter.close(); - journalWriter = null; - } - - private void trimToSize() throws IOException { - while (size > maxSize) { - Map.Entry toEvict = lruEntries.entrySet().iterator().next(); - remove(toEvict.getKey()); - } - } - - /** - * Closes the cache and deletes all of its stored values. This will delete - * all files in the cache directory including files that weren't created by - * the cache. - */ - public void delete() throws IOException { - close(); - Util.deleteContents(directory); - } - - private void validateKey(String key) { - Matcher matcher = LEGAL_KEY_PATTERN.matcher(key); - if (!matcher.matches()) { - throw new IllegalArgumentException("keys must match regex [a-z0-9_-]{1,64}: \"" + key + "\""); - } - } - - private static String inputStreamToString(InputStream in) throws IOException { - return Util.readFully(new InputStreamReader(in, Util.UTF_8)); - } - - /** A snapshot of the values for an entry. */ - public final class Snapshot implements Closeable { - private final String key; - private final long sequenceNumber; - private final InputStream[] ins; - private final long[] lengths; - - private Snapshot(String key, long sequenceNumber, InputStream[] ins, long[] lengths) { - this.key = key; - this.sequenceNumber = sequenceNumber; - this.ins = ins; - this.lengths = lengths; - } - - /** - * Returns an editor for this snapshot's entry, or null if either the - * entry has changed since this snapshot was created or if another edit - * is in progress. - */ - public Editor edit() throws IOException { - return DiskLruCache.this.edit(key, sequenceNumber); - } - - /** Returns the unbuffered stream with the value for {@code index}. */ - public InputStream getInputStream(int index) { - return ins[index]; - } - - /** Returns the string value for {@code index}. */ - public String getString(int index) throws IOException { - return inputStreamToString(getInputStream(index)); - } - - /** Returns the byte length of the value for {@code index}. */ - public long getLength(int index) { - return lengths[index]; - } - - public void close() { - for (InputStream in : ins) { - Util.closeQuietly(in); - } - } - } - - private static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() { - @Override - public void write(int b) throws IOException { - // Eat all writes silently. Nom nom. - } - }; - - /** Edits the values for an entry. */ - public final class Editor { - private final Entry entry; - private final boolean[] written; - private boolean hasErrors; - private boolean committed; - - private Editor(Entry entry) { - this.entry = entry; - this.written = (entry.readable) ? null : new boolean[valueCount]; - } - - /** - * Returns an unbuffered input stream to read the last committed value, - * or null if no value has been committed. - */ - public InputStream newInputStream(int index) throws IOException { - synchronized (DiskLruCache.this) { - if (entry.currentEditor != this) { - throw new IllegalStateException(); - } - if (!entry.readable) { - return null; - } - try { - return new FileInputStream(entry.getCleanFile(index)); - } catch (FileNotFoundException e) { - return null; - } - } - } - - /** - * Returns the last committed value as a string, or null if no value - * has been committed. - */ - public String getString(int index) throws IOException { - InputStream in = newInputStream(index); - return in != null ? inputStreamToString(in) : null; - } - - /** - * Returns a new unbuffered output stream to write the value at - * {@code index}. If the underlying output stream encounters errors - * when writing to the filesystem, this edit will be aborted when - * {@link #commit} is called. The returned output stream does not throw - * IOExceptions. - */ - public OutputStream newOutputStream(int index) throws IOException { - synchronized (DiskLruCache.this) { - if (entry.currentEditor != this) { - throw new IllegalStateException(); - } - if (!entry.readable) { - written[index] = true; - } - File dirtyFile = entry.getDirtyFile(index); - FileOutputStream outputStream; - try { - outputStream = new FileOutputStream(dirtyFile); - } catch (FileNotFoundException e) { - // Attempt to recreate the cache directory. - directory.mkdirs(); - try { - outputStream = new FileOutputStream(dirtyFile); - } catch (FileNotFoundException e2) { - // We are unable to recover. Silently eat the writes. - return NULL_OUTPUT_STREAM; - } - } - return new FaultHidingOutputStream(outputStream); - } - } - - /** Sets the value at {@code index} to {@code value}. */ - public void set(int index, String value) throws IOException { - Writer writer = null; - try { - writer = new OutputStreamWriter(newOutputStream(index), Util.UTF_8); - writer.write(value); - } finally { - Util.closeQuietly(writer); - } - } - - /** - * Commits this edit so it is visible to readers. This releases the - * edit lock so another edit may be started on the same key. - */ - public void commit() throws IOException { - if (hasErrors) { - completeEdit(this, false); - remove(entry.key); // The previous entry is stale. - } else { - completeEdit(this, true); - } - committed = true; - } - - /** - * Aborts this edit. This releases the edit lock so another edit may be - * started on the same key. - */ - public void abort() throws IOException { - completeEdit(this, false); - } - - public void abortUnlessCommitted() { - if (!committed) { - try { - abort(); - } catch (IOException ignored) { - } - } - } - - private class FaultHidingOutputStream extends FilterOutputStream { - private FaultHidingOutputStream(OutputStream out) { - super(out); - } - - @Override public void write(int oneByte) { - try { - out.write(oneByte); - } catch (IOException e) { - hasErrors = true; - } - } - - @Override public void write(byte[] buffer, int offset, int length) { - try { - out.write(buffer, offset, length); - } catch (IOException e) { - hasErrors = true; - } - } - - @Override public void close() { - try { - out.close(); - } catch (IOException e) { - hasErrors = true; - } - } - - @Override public void flush() { - try { - out.flush(); - } catch (IOException e) { - hasErrors = true; - } - } - } - } - - private final class Entry { - private final String key; - - /** Lengths of this entry's files. */ - private final long[] lengths; - - /** True if this entry has ever been published. */ - private boolean readable; - - /** The ongoing edit or null if this entry is not being edited. */ - private Editor currentEditor; - - /** The sequence number of the most recently committed edit to this entry. */ - private long sequenceNumber; - - private Entry(String key) { - this.key = key; - this.lengths = new long[valueCount]; - } - - public String getLengths() throws IOException { - StringBuilder result = new StringBuilder(); - for (long size : lengths) { - result.append(' ').append(size); - } - return result.toString(); - } - - /** Set lengths using decimal numbers like "10123". */ - private void setLengths(String[] strings) throws IOException { - if (strings.length != valueCount) { - throw invalidLengths(strings); - } - - try { - for (int i = 0; i < strings.length; i++) { - lengths[i] = Long.parseLong(strings[i]); - } - } catch (NumberFormatException e) { - throw invalidLengths(strings); - } - } - - private IOException invalidLengths(String[] strings) throws IOException { - throw new IOException("unexpected journal line: " + java.util.Arrays.toString(strings)); - } - - public File getCleanFile(int i) { - return new File(directory, key + "." + i); - } - - public File getDirtyFile(int i) { - return new File(directory, key + "." + i + ".tmp"); - } - } -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Dns.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Dns.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Dns.java deleted file mode 100644 index 69b2d37..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Dns.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2012 Square, Inc. - * - * 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.squareup.okhttp.internal; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Domain name service. Prefer this over {@link InetAddress#getAllByName} to - * make code more testable. - */ -public interface Dns { - Dns DEFAULT = new Dns() { - @Override public InetAddress[] getAllByName(String host) throws UnknownHostException { - return InetAddress.getAllByName(host); - } - }; - - InetAddress[] getAllByName(String host) throws UnknownHostException; -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/FaultRecoveringOutputStream.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/FaultRecoveringOutputStream.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/FaultRecoveringOutputStream.java deleted file mode 100644 index c32b27a..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/FaultRecoveringOutputStream.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2013 Square, Inc. - * - * 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.squareup.okhttp.internal; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import static com.squareup.okhttp.internal.Util.checkOffsetAndCount; - -/** - * An output stream wrapper that recovers from failures in the underlying stream - * by replacing it with another stream. This class buffers a fixed amount of - * data under the assumption that failures occur early in a stream's life. - * If a failure occurs after the buffer has been exhausted, no recovery is - * attempted. - * - *

Subclasses must override {@link #replacementStream} which will request a - * replacement stream each time an {@link IOException} is encountered on the - * current stream. - */ -public abstract class FaultRecoveringOutputStream extends AbstractOutputStream { - private final int maxReplayBufferLength; - - /** Bytes to transmit on the replacement stream, or null if no recovery is possible. */ - private ByteArrayOutputStream replayBuffer; - private OutputStream out; - - /** - * @param maxReplayBufferLength the maximum number of successfully written - * bytes to buffer so they can be replayed in the event of an error. - * Failure recoveries are not possible once this limit has been exceeded. - */ - public FaultRecoveringOutputStream(int maxReplayBufferLength, OutputStream out) { - if (maxReplayBufferLength < 0) throw new IllegalArgumentException(); - this.maxReplayBufferLength = maxReplayBufferLength; - this.replayBuffer = new ByteArrayOutputStream(maxReplayBufferLength); - this.out = out; - } - - @Override public final void write(byte[] buffer, int offset, int count) throws IOException { - if (closed) throw new IOException("stream closed"); - checkOffsetAndCount(buffer.length, offset, count); - - while (true) { - try { - out.write(buffer, offset, count); - - if (replayBuffer != null) { - if (count + replayBuffer.size() > maxReplayBufferLength) { - // Failure recovery is no longer possible once we overflow the replay buffer. - replayBuffer = null; - } else { - // Remember the written bytes to the replay buffer. - replayBuffer.write(buffer, offset, count); - } - } - return; - } catch (IOException e) { - if (!recover(e)) throw e; - } - } - } - - @Override public final void flush() throws IOException { - if (closed) { - return; // don't throw; this stream might have been closed on the caller's behalf - } - while (true) { - try { - out.flush(); - return; - } catch (IOException e) { - if (!recover(e)) throw e; - } - } - } - - @Override public final void close() throws IOException { - if (closed) { - return; - } - while (true) { - try { - out.close(); - closed = true; - return; - } catch (IOException e) { - if (!recover(e)) throw e; - } - } - } - - /** - * Attempt to replace {@code out} with another equivalent stream. Returns true - * if a suitable replacement stream was found. - */ - private boolean recover(IOException e) { - if (replayBuffer == null) { - return false; // Can't recover because we've dropped data that we would need to replay. - } - - while (true) { - OutputStream replacementStream = null; - try { - replacementStream = replacementStream(e); - if (replacementStream == null) { - return false; - } - replaceStream(replacementStream); - return true; - } catch (IOException replacementStreamFailure) { - // The replacement was also broken. Loop to ask for another replacement. - Util.closeQuietly(replacementStream); - e = replacementStreamFailure; - } - } - } - - /** - * Returns true if errors in the underlying stream can currently be recovered. - */ - public boolean isRecoverable() { - return replayBuffer != null; - } - - /** - * Replaces the current output stream with {@code replacementStream}, writing - * any replay bytes to it if they exist. The current output stream is closed. - */ - public final void replaceStream(OutputStream replacementStream) throws IOException { - if (!isRecoverable()) { - throw new IllegalStateException(); - } - if (this.out == replacementStream) { - return; // Don't replace a stream with itself. - } - replayBuffer.writeTo(replacementStream); - Util.closeQuietly(out); - out = replacementStream; - } - - /** - * Returns a replacement output stream to recover from {@code e} thrown by the - * previous stream. Returns a new OutputStream if recovery was successful, in - * which case all previously-written data will be replayed. Returns null if - * the failure cannot be recovered. - */ - protected abstract OutputStream replacementStream(IOException e) throws IOException; -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/NamedRunnable.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/NamedRunnable.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/NamedRunnable.java deleted file mode 100644 index ce430b2..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/NamedRunnable.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2013 Square, Inc. - * - * 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.squareup.okhttp.internal; - -/** - * Runnable implementation which always sets its thread name. - */ -public abstract class NamedRunnable implements Runnable { - private String name; - - public NamedRunnable(String name) { - this.name = name; - } - - @Override public final void run() { - String oldName = Thread.currentThread().getName(); - Thread.currentThread().setName(name); - try { - execute(); - } finally { - Thread.currentThread().setName(oldName); - } - } - - protected abstract void execute(); -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Platform.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Platform.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Platform.java deleted file mode 100644 index 6b4ac34..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Platform.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2012 Square, Inc. - * Copyright (C) 2012 The Android Open Source Project - * - * 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.squareup.okhttp.internal; - -import com.squareup.okhttp.OkHttpClient; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.net.NetworkInterface; -import java.net.Socket; -import java.net.SocketException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; -import javax.net.ssl.SSLSocket; - -/** - * Access to Platform-specific features necessary for SPDY and advanced TLS. - * - *

SPDY

- * SPDY requires a TLS extension called NPN (Next Protocol Negotiation) that's - * available in Android 4.1+ and OpenJDK 7+ (with the npn-boot extension). It - * also requires a recent version of {@code DeflaterOutputStream} that is - * public API in Java 7 and callable via reflection in Android 4.1+. - */ -public class Platform { - private static final Platform PLATFORM = findPlatform(); - - private Constructor deflaterConstructor; - - public static Platform get() { - return PLATFORM; - } - - public void logW(String warning) { - System.out.println(warning); - } - - public void tagSocket(Socket socket) throws SocketException { - } - - public void untagSocket(Socket socket) throws SocketException { - } - - public URI toUriLenient(URL url) throws URISyntaxException { - return url.toURI(); // this isn't as good as the built-in toUriLenient - } - - /** - * Attempt a TLS connection with useful extensions enabled. This mode - * supports more features, but is less likely to be compatible with older - * HTTPS servers. - */ - public void enableTlsExtensions(SSLSocket socket, String uriHost) { - } - - /** - * Attempt a secure connection with basic functionality to maximize - * compatibility. Currently this uses SSL 3.0. - */ - public void supportTlsIntolerantServer(SSLSocket socket) { - socket.setEnabledProtocols(new String[] {"SSLv3"}); - } - - /** Returns the negotiated protocol, or null if no protocol was negotiated. */ - public byte[] getNpnSelectedProtocol(SSLSocket socket) { - return null; - } - - /** - * Sets client-supported protocols on a socket to send to a server. The - * protocols are only sent if the socket implementation supports NPN. - */ - public void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) { - } - - /** - * Returns a deflater output stream that supports SYNC_FLUSH for SPDY name - * value blocks. This throws an {@link UnsupportedOperationException} on - * Java 6 and earlier where there is no built-in API to do SYNC_FLUSH. - */ - public OutputStream newDeflaterOutputStream(OutputStream out, Deflater deflater, - boolean syncFlush) { - try { - Constructor constructor = deflaterConstructor; - if (constructor == null) { - constructor = deflaterConstructor = DeflaterOutputStream.class.getConstructor( - OutputStream.class, Deflater.class, boolean.class); - } - return constructor.newInstance(out, deflater, syncFlush); - } catch (NoSuchMethodException e) { - throw new UnsupportedOperationException("Cannot SPDY; no SYNC_FLUSH available"); - } catch (InvocationTargetException e) { - throw e.getCause() instanceof RuntimeException ? (RuntimeException) e.getCause() - : new RuntimeException(e.getCause()); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new AssertionError(); - } - } - - /** - * Returns the maximum transmission unit of the network interface used by - * {@code socket}, or a reasonable default if this platform doesn't expose the - * MTU to the application layer. - * - *

The returned value should only be used as an optimization; such as to - * size buffers efficiently. - */ - public int getMtu(Socket socket) throws IOException { - return 1400; // Smaller than 1500 to leave room for headers on interfaces like PPPoE. - } - - /** Attempt to match the host runtime to a capable Platform implementation. */ - private static Platform findPlatform() { - Method getMtu; - try { - getMtu = NetworkInterface.class.getMethod("getMTU"); - } catch (NoSuchMethodException e) { - return new Platform(); // No Java 1.6 APIs. It's either Java 1.5, Android 2.2 or earlier. - } - - // Attempt to find Android 2.3+ APIs. - Class openSslSocketClass; - Method setUseSessionTickets; - Method setHostname; - try { - openSslSocketClass = Class.forName("org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl"); - setUseSessionTickets = openSslSocketClass.getMethod("setUseSessionTickets", boolean.class); - setHostname = openSslSocketClass.getMethod("setHostname", String.class); - - // Attempt to find Android 4.1+ APIs. - try { - Method setNpnProtocols = openSslSocketClass.getMethod("setNpnProtocols", byte[].class); - Method getNpnSelectedProtocol = openSslSocketClass.getMethod("getNpnSelectedProtocol"); - return new Android41(getMtu, openSslSocketClass, setUseSessionTickets, setHostname, - setNpnProtocols, getNpnSelectedProtocol); - } catch (NoSuchMethodException ignored) { - return new Android23(getMtu, openSslSocketClass, setUseSessionTickets, setHostname); - } - } catch (ClassNotFoundException ignored) { - // This isn't an Android runtime. - } catch (NoSuchMethodException ignored) { - // This isn't Android 2.3 or better. - } - - // Attempt to find the Jetty's NPN extension for OpenJDK. - try { - String npnClassName = "org.eclipse.jetty.npn.NextProtoNego"; - Class nextProtoNegoClass = Class.forName(npnClassName); - Class providerClass = Class.forName(npnClassName + "$Provider"); - Class clientProviderClass = Class.forName(npnClassName + "$ClientProvider"); - Class serverProviderClass = Class.forName(npnClassName + "$ServerProvider"); - Method putMethod = nextProtoNegoClass.getMethod("put", SSLSocket.class, providerClass); - Method getMethod = nextProtoNegoClass.getMethod("get", SSLSocket.class); - return new JdkWithJettyNpnPlatform(getMtu, putMethod, getMethod, clientProviderClass, - serverProviderClass); - } catch (ClassNotFoundException ignored) { - // NPN isn't on the classpath. - } catch (NoSuchMethodException ignored) { - // The NPN version isn't what we expect. - } - - return getMtu != null ? new Java5(getMtu) : new Platform(); - } - - private static class Java5 extends Platform { - private final Method getMtu; - - private Java5(Method getMtu) { - this.getMtu = getMtu; - } - - @Override public int getMtu(Socket socket) throws IOException { - try { - NetworkInterface networkInterface = NetworkInterface.getByInetAddress( - socket.getLocalAddress()); - return (Integer) getMtu.invoke(networkInterface); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - if (e.getCause() instanceof IOException) throw (IOException) e.getCause(); - throw new RuntimeException(e.getCause()); - } - } - } - - /** - * Android version 2.3 and newer support TLS session tickets and server name - * indication (SNI). - */ - private static class Android23 extends Java5 { - protected final Class openSslSocketClass; - private final Method setUseSessionTickets; - private final Method setHostname; - - private Android23(Method getMtu, Class openSslSocketClass, Method setUseSessionTickets, - Method setHostname) { - super(getMtu); - this.openSslSocketClass = openSslSocketClass; - this.setUseSessionTickets = setUseSessionTickets; - this.setHostname = setHostname; - } - - @Override public void enableTlsExtensions(SSLSocket socket, String uriHost) { - super.enableTlsExtensions(socket, uriHost); - if (openSslSocketClass.isInstance(socket)) { - // This is Android: use reflection on OpenSslSocketImpl. - try { - setUseSessionTickets.invoke(socket, true); - setHostname.invoke(socket, uriHost); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - } - } - - /** Android version 4.1 and newer support NPN. */ - private static class Android41 extends Android23 { - private final Method setNpnProtocols; - private final Method getNpnSelectedProtocol; - - private Android41(Method getMtu, Class openSslSocketClass, Method setUseSessionTickets, - Method setHostname, Method setNpnProtocols, Method getNpnSelectedProtocol) { - super(getMtu, openSslSocketClass, setUseSessionTickets, setHostname); - this.setNpnProtocols = setNpnProtocols; - this.getNpnSelectedProtocol = getNpnSelectedProtocol; - } - - @Override public void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) { - if (!openSslSocketClass.isInstance(socket)) { - return; - } - try { - setNpnProtocols.invoke(socket, new Object[] {npnProtocols}); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - @Override public byte[] getNpnSelectedProtocol(SSLSocket socket) { - if (!openSslSocketClass.isInstance(socket)) { - return null; - } - try { - return (byte[]) getNpnSelectedProtocol.invoke(socket); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - } - - /** - * OpenJDK 7 plus {@code org.mortbay.jetty.npn/npn-boot} on the boot class - * path. - */ - private static class JdkWithJettyNpnPlatform extends Java5 { - private final Method getMethod; - private final Method putMethod; - private final Class clientProviderClass; - private final Class serverProviderClass; - - public JdkWithJettyNpnPlatform(Method getMtu, Method putMethod, Method getMethod, - Class clientProviderClass, Class serverProviderClass) { - super(getMtu); - this.putMethod = putMethod; - this.getMethod = getMethod; - this.clientProviderClass = clientProviderClass; - this.serverProviderClass = serverProviderClass; - } - - @Override public void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) { - try { - List strings = new ArrayList(); - for (int i = 0; i < npnProtocols.length; ) { - int length = npnProtocols[i++]; - strings.add(new String(npnProtocols, i, length, "US-ASCII")); - i += length; - } - Object provider = Proxy.newProxyInstance(Platform.class.getClassLoader(), - new Class[] {clientProviderClass, serverProviderClass}, - new JettyNpnProvider(strings)); - putMethod.invoke(null, socket, provider); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } - } - - @Override public byte[] getNpnSelectedProtocol(SSLSocket socket) { - try { - JettyNpnProvider provider = - (JettyNpnProvider) Proxy.getInvocationHandler(getMethod.invoke(null, socket)); - if (!provider.unsupported && provider.selected == null) { - Logger logger = Logger.getLogger(OkHttpClient.class.getName()); - logger.log(Level.INFO, - "NPN callback dropped so SPDY is disabled. " + "Is npn-boot on the boot class path?"); - return null; - } - return provider.unsupported ? null : provider.selected.getBytes("US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(); - } catch (InvocationTargetException e) { - throw new AssertionError(); - } catch (IllegalAccessException e) { - throw new AssertionError(); - } - } - } - - /** - * Handle the methods of NextProtoNego's ClientProvider and ServerProvider - * without a compile-time dependency on those interfaces. - */ - private static class JettyNpnProvider implements InvocationHandler { - private final List protocols; - private boolean unsupported; - private String selected; - - public JettyNpnProvider(List protocols) { - this.protocols = protocols; - } - - @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String methodName = method.getName(); - Class returnType = method.getReturnType(); - if (args == null) { - args = Util.EMPTY_STRING_ARRAY; - } - if (methodName.equals("supports") && boolean.class == returnType) { - return true; - } else if (methodName.equals("unsupported") && void.class == returnType) { - this.unsupported = true; - return null; - } else if (methodName.equals("protocols") && args.length == 0) { - return protocols; - } else if (methodName.equals("selectProtocol") - && String.class == returnType - && args.length == 1 - && (args[0] == null || args[0] instanceof List)) { - // TODO: use OpenSSL's algorithm which uses both lists - List serverProtocols = (List) args[0]; - this.selected = protocols.get(0); - return selected; - } else if (methodName.equals("protocolSelected") && args.length == 1) { - this.selected = (String) args[0]; - return null; - } else { - return method.invoke(this, args); - } - } - } -} http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/StrictLineReader.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/StrictLineReader.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/StrictLineReader.java deleted file mode 100644 index 3ddc693..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/StrictLineReader.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * 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.squareup.okhttp.internal; - -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; - -/** - * Buffers input from an {@link InputStream} for reading lines. - * - *

This class is used for buffered reading of lines. For purposes of this class, a line ends with - * "\n" or "\r\n". End of input is reported by throwing {@code EOFException}. Unterminated line at - * end of input is invalid and will be ignored, the caller may use {@code hasUnterminatedLine()} - * to detect it after catching the {@code EOFException}. - * - *

This class is intended for reading input that strictly consists of lines, such as line-based - * cache entries or cache journal. Unlike the {@link java.io.BufferedReader} which in conjunction - * with {@link java.io.InputStreamReader} provides similar functionality, this class uses different - * end-of-input reporting and a more restrictive definition of a line. - * - *

This class supports only charsets that encode '\r' and '\n' as a single byte with value 13 - * and 10, respectively, and the representation of no other character contains these values. - * We currently check in constructor that the charset is one of US-ASCII, UTF-8 and ISO-8859-1. - * The default charset is US_ASCII. - */ -public class StrictLineReader implements Closeable { - private static final byte CR = (byte) '\r'; - private static final byte LF = (byte) '\n'; - - private final InputStream in; - private final Charset charset; - - /* - * Buffered data is stored in {@code buf}. As long as no exception occurs, 0 <= pos <= end - * and the data in the range [pos, end) is buffered for reading. At end of input, if there is - * an unterminated line, we set end == -1, otherwise end == pos. If the underlying - * {@code InputStream} throws an {@code IOException}, end may remain as either pos or -1. - */ - private byte[] buf; - private int pos; - private int end; - - /** - * Constructs a new {@code LineReader} with the specified charset and the default capacity. - * - * @param in the {@code InputStream} to read data from. - * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are - * supported. - * @throws NullPointerException if {@code in} or {@code charset} is null. - * @throws IllegalArgumentException if the specified charset is not supported. - */ - public StrictLineReader(InputStream in, Charset charset) { - this(in, 8192, charset); - } - - /** - * Constructs a new {@code LineReader} with the specified capacity and charset. - * - * @param in the {@code InputStream} to read data from. - * @param capacity the capacity of the buffer. - * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are - * supported. - * @throws NullPointerException if {@code in} or {@code charset} is null. - * @throws IllegalArgumentException if {@code capacity} is negative or zero - * or the specified charset is not supported. - */ - public StrictLineReader(InputStream in, int capacity, Charset charset) { - if (in == null || charset == null) { - throw new NullPointerException(); - } - if (capacity < 0) { - throw new IllegalArgumentException("capacity <= 0"); - } - if (!(charset.equals(Util.US_ASCII))) { - throw new IllegalArgumentException("Unsupported encoding"); - } - - this.in = in; - this.charset = charset; - buf = new byte[capacity]; - } - - /** - * Closes the reader by closing the underlying {@code InputStream} and - * marking this reader as closed. - * - * @throws IOException for errors when closing the underlying {@code InputStream}. - */ - public void close() throws IOException { - synchronized (in) { - if (buf != null) { - buf = null; - in.close(); - } - } - } - - /** - * Reads the next line. A line ends with {@code "\n"} or {@code "\r\n"}, - * this end of line marker is not included in the result. - * - * @return the next line from the input. - * @throws IOException for underlying {@code InputStream} errors. - * @throws EOFException for the end of source stream. - */ - public String readLine() throws IOException { - synchronized (in) { - if (buf == null) { - throw new IOException("LineReader is closed"); - } - - // Read more data if we are at the end of the buffered data. - // Though it's an error to read after an exception, we will let {@code fillBuf()} - // throw again if that happens; thus we need to handle end == -1 as well as end == pos. - if (pos >= end) { - fillBuf(); - } - // Try to find LF in the buffered data and return the line if successful. - for (int i = pos; i != end; ++i) { - if (buf[i] == LF) { - int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i; - String res = new String(buf, pos, lineEnd - pos, charset.name()); - pos = i + 1; - return res; - } - } - - // Let's anticipate up to 80 characters on top of those already read. - ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) { - @Override - public String toString() { - int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count; - try { - return new String(buf, 0, length, charset.name()); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); // Since we control the charset this will never happen. - } - } - }; - - while (true) { - out.write(buf, pos, end - pos); - // Mark unterminated line in case fillBuf throws EOFException or IOException. - end = -1; - fillBuf(); - // Try to find LF in the buffered data and return the line if successful. - for (int i = pos; i != end; ++i) { - if (buf[i] == LF) { - if (i != pos) { - out.write(buf, pos, i - pos); - } - pos = i + 1; - return out.toString(); - } - } - } - } - } - - /** - * Read an {@code int} from a line containing its decimal representation. - * - * @return the value of the {@code int} from the next line. - * @throws IOException for underlying {@code InputStream} errors or conversion error. - * @throws EOFException for the end of source stream. - */ - public int readInt() throws IOException { - String intString = readLine(); - try { - return Integer.parseInt(intString); - } catch (NumberFormatException e) { - throw new IOException("expected an int but was \"" + intString + "\""); - } - } - - /** - * Reads new input data into the buffer. Call only with pos == end or end == -1, - * depending on the desired outcome if the function throws. - */ - private void fillBuf() throws IOException { - int result = in.read(buf, 0, buf.length); - if (result == -1) { - throw new EOFException(); - } - pos = 0; - end = result; - } -} - http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/09ee1837/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Util.java ---------------------------------------------------------------------- diff --git a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Util.java b/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Util.java deleted file mode 100644 index 290e5ea..0000000 --- a/lib/cordova-android/framework/src/com/squareup/okhttp/internal/Util.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * 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.squareup.okhttp.internal; - -import java.io.Closeable; -import java.io.EOFException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringWriter; -import java.net.Socket; -import java.net.URI; -import java.net.URL; -import java.nio.ByteOrder; -import java.nio.charset.Charset; -import java.util.concurrent.atomic.AtomicReference; - -/** Junk drawer of utility methods. */ -public final class Util { - public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static final String[] EMPTY_STRING_ARRAY = new String[0]; - - /** A cheap and type-safe constant for the ISO-8859-1 Charset. */ - public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - - /** A cheap and type-safe constant for the US-ASCII Charset. */ - public static final Charset US_ASCII = Charset.forName("US-ASCII"); - - /** A cheap and type-safe constant for the UTF-8 Charset. */ - public static final Charset UTF_8 = Charset.forName("UTF-8"); - private static AtomicReference skipBuffer = new AtomicReference(); - - private Util() { - } - - public static int getEffectivePort(URI uri) { - return getEffectivePort(uri.getScheme(), uri.getPort()); - } - - public static int getEffectivePort(URL url) { - return getEffectivePort(url.getProtocol(), url.getPort()); - } - - private static int getEffectivePort(String scheme, int specifiedPort) { - return specifiedPort != -1 ? specifiedPort : getDefaultPort(scheme); - } - - public static int getDefaultPort(String scheme) { - if ("http".equalsIgnoreCase(scheme)) { - return 80; - } else if ("https".equalsIgnoreCase(scheme)) { - return 443; - } else { - return -1; - } - } - - public static void checkOffsetAndCount(int arrayLength, int offset, int count) { - if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) { - throw new ArrayIndexOutOfBoundsException(); - } - } - - public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { - if (order == ByteOrder.BIG_ENDIAN) { - dst[offset++] = (byte) ((value >> 24) & 0xff); - dst[offset++] = (byte) ((value >> 16) & 0xff); - dst[offset++] = (byte) ((value >> 8) & 0xff); - dst[offset] = (byte) ((value >> 0) & 0xff); - } else { - dst[offset++] = (byte) ((value >> 0) & 0xff); - dst[offset++] = (byte) ((value >> 8) & 0xff); - dst[offset++] = (byte) ((value >> 16) & 0xff); - dst[offset] = (byte) ((value >> 24) & 0xff); - } - } - - /** Returns true if two possibly-null objects are equal. */ - public static boolean equal(Object a, Object b) { - return a == b || (a != null && a.equals(b)); - } - - /** - * Closes {@code closeable}, ignoring any checked exceptions. Does nothing - * if {@code closeable} is null. - */ - public static void closeQuietly(Closeable closeable) { - if (closeable != null) { - try { - closeable.close(); - } catch (RuntimeException rethrown) { - throw rethrown; - } catch (Exception ignored) { - } - } - } - - /** - * Closes {@code socket}, ignoring any checked exceptions. Does nothing if - * {@code socket} is null. - */ - public static void closeQuietly(Socket socket) { - if (socket != null) { - try { - socket.close(); - } catch (RuntimeException rethrown) { - throw rethrown; - } catch (Exception ignored) { - } - } - } - - /** - * Closes {@code a} and {@code b}. If either close fails, this completes - * the other close and rethrows the first encountered exception. - */ - public static void closeAll(Closeable a, Closeable b) throws IOException { - Throwable thrown = null; - try { - a.close(); - } catch (Throwable e) { - thrown = e; - } - try { - b.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - if (thrown == null) return; - if (thrown instanceof IOException) throw (IOException) thrown; - if (thrown instanceof RuntimeException) throw (RuntimeException) thrown; - if (thrown instanceof Error) throw (Error) thrown; - throw new AssertionError(thrown); - } - - /** - * Deletes the contents of {@code dir}. Throws an IOException if any file - * could not be deleted, or if {@code dir} is not a readable directory. - */ - public static void deleteContents(File dir) throws IOException { - File[] files = dir.listFiles(); - if (files == null) { - throw new IOException("not a readable directory: " + dir); - } - for (File file : files) { - if (file.isDirectory()) { - deleteContents(file); - } - if (!file.delete()) { - throw new IOException("failed to delete file: " + file); - } - } - } - - /** - * Implements InputStream.read(int) in terms of InputStream.read(byte[], int, int). - * InputStream assumes that you implement InputStream.read(int) and provides default - * implementations of the others, but often the opposite is more efficient. - */ - public static int readSingleByte(InputStream in) throws IOException { - byte[] buffer = new byte[1]; - int result = in.read(buffer, 0, 1); - return (result != -1) ? buffer[0] & 0xff : -1; - } - - /** - * Implements OutputStream.write(int) in terms of OutputStream.write(byte[], int, int). - * OutputStream assumes that you implement OutputStream.write(int) and provides default - * implementations of the others, but often the opposite is more efficient. - */ - public static void writeSingleByte(OutputStream out, int b) throws IOException { - byte[] buffer = new byte[1]; - buffer[0] = (byte) (b & 0xff); - out.write(buffer); - } - - /** - * Fills 'dst' with bytes from 'in', throwing EOFException if insufficient bytes are available. - */ - public static void readFully(InputStream in, byte[] dst) throws IOException { - readFully(in, dst, 0, dst.length); - } - - /** - * Reads exactly 'byteCount' bytes from 'in' (into 'dst' at offset 'offset'), and throws - * EOFException if insufficient bytes are available. - * - * Used to implement {@link java.io.DataInputStream#readFully(byte[], int, int)}. - */ - public static void readFully(InputStream in, byte[] dst, int offset, int byteCount) - throws IOException { - if (byteCount == 0) { - return; - } - if (in == null) { - throw new NullPointerException("in == null"); - } - if (dst == null) { - throw new NullPointerException("dst == null"); - } - checkOffsetAndCount(dst.length, offset, byteCount); - while (byteCount > 0) { - int bytesRead = in.read(dst, offset, byteCount); - if (bytesRead < 0) { - throw new EOFException(); - } - offset += bytesRead; - byteCount -= bytesRead; - } - } - - /** Returns the remainder of 'reader' as a string, closing it when done. */ - public static String readFully(Reader reader) throws IOException { - try { - StringWriter writer = new StringWriter(); - char[] buffer = new char[1024]; - int count; - while ((count = reader.read(buffer)) != -1) { - writer.write(buffer, 0, count); - } - return writer.toString(); - } finally { - reader.close(); - } - } - - public static void skipAll(InputStream in) throws IOException { - do { - in.skip(Long.MAX_VALUE); - } while (in.read() != -1); - } - - /** - * Call {@code in.read()} repeatedly until either the stream is exhausted or - * {@code byteCount} bytes have been read. - * - *

This method reuses the skip buffer but is careful to never use it at - * the same time that another stream is using it. Otherwise streams that use - * the caller's buffer for consistency checks like CRC could be clobbered by - * other threads. A thread-local buffer is also insufficient because some - * streams may call other streams in their skip() method, also clobbering the - * buffer. - */ - public static long skipByReading(InputStream in, long byteCount) throws IOException { - // acquire the shared skip buffer. - byte[] buffer = skipBuffer.getAndSet(null); - if (buffer == null) { - buffer = new byte[4096]; - } - - long skipped = 0; - while (skipped < byteCount) { - int toRead = (int) Math.min(byteCount - skipped, buffer.length); - int read = in.read(buffer, 0, toRead); - if (read == -1) { - break; - } - skipped += read; - if (read < toRead) { - break; - } - } - - // release the shared skip buffer. - skipBuffer.set(buffer); - - return skipped; - } - - /** - * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed. - * Returns the total number of bytes transferred. - */ - public static int copy(InputStream in, OutputStream out) throws IOException { - int total = 0; - byte[] buffer = new byte[8192]; - int c; - while ((c = in.read(buffer)) != -1) { - total += c; - out.write(buffer, 0, c); - } - return total; - } - - /** - * Returns the ASCII characters up to but not including the next "\r\n", or - * "\n". - * - * @throws java.io.EOFException if the stream is exhausted before the next newline - * character. - */ - public static String readAsciiLine(InputStream in) throws IOException { - // TODO: support UTF-8 here instead - StringBuilder result = new StringBuilder(80); - while (true) { - int c = in.read(); - if (c == -1) { - throw new EOFException(); - } else if (c == '\n') { - break; - } - - result.append((char) c); - } - int length = result.length(); - if (length > 0 && result.charAt(length - 1) == '\r') { - result.setLength(length - 1); - } - return result.toString(); - } -}