mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-18 00:54:19 +00:00
Whitespace
This commit is contained in:
parent
4710fd7b1f
commit
f4c67f6fa7
13 changed files with 2548 additions and 2549 deletions
|
|
@ -1,58 +1,58 @@
|
|||
package com.roli.juce;
|
||||
|
||||
import android.app.DialogFragment;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class FragmentOverlay extends DialogFragment
|
||||
{
|
||||
@Override
|
||||
public void onCreate (Bundle state)
|
||||
{
|
||||
super.onCreate (state);
|
||||
cppThis = getArguments ().getLong ("cppThis");
|
||||
|
||||
if (cppThis != 0)
|
||||
onCreateNative (cppThis, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart ()
|
||||
{
|
||||
super.onStart ();
|
||||
|
||||
if (cppThis != 0)
|
||||
onStartNative (cppThis);
|
||||
}
|
||||
|
||||
public void onRequestPermissionsResult (int requestCode,
|
||||
String[] permissions,
|
||||
int[] grantResults)
|
||||
{
|
||||
if (cppThis != 0)
|
||||
onRequestPermissionsResultNative (cppThis, requestCode,
|
||||
permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult (int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (cppThis != 0)
|
||||
onActivityResultNative (cppThis, requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
public void close ()
|
||||
{
|
||||
cppThis = 0;
|
||||
dismiss ();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long cppThis = 0;
|
||||
|
||||
private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data);
|
||||
private native void onCreateNative (long myself, Bundle state);
|
||||
private native void onStartNative (long myself);
|
||||
private native void onRequestPermissionsResultNative (long myself, int requestCode,
|
||||
String[] permissions, int[] grantResults);
|
||||
}
|
||||
package com.roli.juce;
|
||||
|
||||
import android.app.DialogFragment;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class FragmentOverlay extends DialogFragment
|
||||
{
|
||||
@Override
|
||||
public void onCreate (Bundle state)
|
||||
{
|
||||
super.onCreate (state);
|
||||
cppThis = getArguments ().getLong ("cppThis");
|
||||
|
||||
if (cppThis != 0)
|
||||
onCreateNative (cppThis, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart ()
|
||||
{
|
||||
super.onStart ();
|
||||
|
||||
if (cppThis != 0)
|
||||
onStartNative (cppThis);
|
||||
}
|
||||
|
||||
public void onRequestPermissionsResult (int requestCode,
|
||||
String[] permissions,
|
||||
int[] grantResults)
|
||||
{
|
||||
if (cppThis != 0)
|
||||
onRequestPermissionsResultNative (cppThis, requestCode,
|
||||
permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult (int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (cppThis != 0)
|
||||
onActivityResultNative (cppThis, requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
public void close ()
|
||||
{
|
||||
cppThis = 0;
|
||||
dismiss ();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long cppThis = 0;
|
||||
|
||||
private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data);
|
||||
private native void onCreateNative (long myself, Bundle state);
|
||||
private native void onStartNative (long myself);
|
||||
private native void onRequestPermissionsResultNative (long myself, int requestCode,
|
||||
String[] permissions, int[] grantResults);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,407 +1,407 @@
|
|||
package com.roli.juce;
|
||||
|
||||
import java.lang.Runnable;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
public class JuceHTTPStream
|
||||
{
|
||||
public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse,
|
||||
String headersToUse, int timeOutMsToUse,
|
||||
int[] statusCodeToUse, StringBuffer responseHeadersToUse,
|
||||
int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException
|
||||
{
|
||||
isPost = isPostToUse;
|
||||
postData = postDataToUse;
|
||||
headers = headersToUse;
|
||||
timeOutMs = timeOutMsToUse;
|
||||
statusCode = statusCodeToUse;
|
||||
responseHeaders = responseHeadersToUse;
|
||||
totalLength = -1;
|
||||
numRedirectsToFollow = numRedirectsToFollowToUse;
|
||||
httpRequestCmd = httpRequestCmdToUse;
|
||||
|
||||
connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd);
|
||||
}
|
||||
|
||||
public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData,
|
||||
String headers, int timeOutMs, int[] statusCode,
|
||||
StringBuffer responseHeaders, int numRedirectsToFollow,
|
||||
String httpRequestCmd)
|
||||
{
|
||||
// timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL)
|
||||
if (timeOutMs < 0)
|
||||
timeOutMs = 0;
|
||||
else if (timeOutMs == 0)
|
||||
timeOutMs = 30000;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
{
|
||||
JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers,
|
||||
timeOutMs, statusCode, responseHeaders,
|
||||
numRedirectsToFollow, httpRequestCmd);
|
||||
|
||||
return httpStream;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData,
|
||||
String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException
|
||||
{
|
||||
HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection());
|
||||
|
||||
try
|
||||
{
|
||||
newConnection.setInstanceFollowRedirects(false);
|
||||
newConnection.setConnectTimeout(timeOutMs);
|
||||
newConnection.setReadTimeout(timeOutMs);
|
||||
|
||||
// headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines.
|
||||
// So convert headers string to an array, with an element for each line
|
||||
String headerLines[] = headers.split("\\n");
|
||||
|
||||
// Set request headers
|
||||
for (int i = 0; i < headerLines.length; ++i)
|
||||
{
|
||||
int pos = headerLines[i].indexOf(":");
|
||||
|
||||
if (pos > 0 && pos < headerLines[i].length())
|
||||
{
|
||||
String field = headerLines[i].substring(0, pos);
|
||||
String value = headerLines[i].substring(pos + 1);
|
||||
|
||||
if (value.length() > 0)
|
||||
newConnection.setRequestProperty(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
newConnection.setRequestMethod(httpRequestCmd);
|
||||
|
||||
if (isPost)
|
||||
{
|
||||
newConnection.setDoOutput(true);
|
||||
|
||||
if (postData != null)
|
||||
{
|
||||
OutputStream out = newConnection.getOutputStream();
|
||||
out.write(postData);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
return newConnection;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
newConnection.disconnect();
|
||||
throw new IOException("Connection error");
|
||||
}
|
||||
}
|
||||
|
||||
private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException
|
||||
{
|
||||
synchronized (createFutureLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return null;
|
||||
|
||||
streamFuture = executor.submit(new Callable<BufferedInputStream>()
|
||||
{
|
||||
@Override
|
||||
public BufferedInputStream call() throws IOException
|
||||
{
|
||||
return new BufferedInputStream(isInput ? connection.getInputStream()
|
||||
: connection.getErrorStream());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return streamFuture.get();
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
return null;
|
||||
} catch (CancellationException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean connect()
|
||||
{
|
||||
boolean result = false;
|
||||
int numFollowedRedirects = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = doConnect();
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
if (++numFollowedRedirects > numRedirectsToFollow)
|
||||
break;
|
||||
|
||||
int status = statusCode[0];
|
||||
|
||||
if (status == 301 || status == 302 || status == 303 || status == 307)
|
||||
{
|
||||
// Assumes only one occurrence of "Location"
|
||||
int pos1 = responseHeaders.indexOf("Location:") + 10;
|
||||
int pos2 = responseHeaders.indexOf("\n", pos1);
|
||||
|
||||
if (pos2 > pos1)
|
||||
{
|
||||
String currentLocation = connection.getURL().toString();
|
||||
String newLocation = responseHeaders.substring(pos1, pos2);
|
||||
|
||||
try
|
||||
{
|
||||
// Handle newLocation whether it's absolute or relative
|
||||
URL baseUrl = new URL(currentLocation);
|
||||
URL newUrl = new URL(baseUrl, newLocation);
|
||||
String transformedNewLocation = newUrl.toString();
|
||||
|
||||
if (transformedNewLocation != currentLocation)
|
||||
{
|
||||
// Clear responseHeaders before next iteration
|
||||
responseHeaders.delete(0, responseHeaders.length());
|
||||
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return false;
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
try
|
||||
{
|
||||
connection = createConnection(transformedNewLocation, isPost,
|
||||
postData, headers, timeOutMs,
|
||||
httpRequestCmd);
|
||||
} catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final boolean doConnect()
|
||||
{
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
inputStream = getCancellableStream(true);
|
||||
} catch (ExecutionException e)
|
||||
{
|
||||
if (connection.getResponseCode() < 400)
|
||||
{
|
||||
statusCode[0] = connection.getResponseCode();
|
||||
connection.disconnect();
|
||||
return false;
|
||||
}
|
||||
} finally
|
||||
{
|
||||
statusCode[0] = connection.getResponseCode();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (statusCode[0] >= 400)
|
||||
inputStream = getCancellableStream(false);
|
||||
else
|
||||
inputStream = getCancellableStream(true);
|
||||
} catch (ExecutionException e)
|
||||
{
|
||||
}
|
||||
|
||||
for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())
|
||||
{
|
||||
if (entry.getKey() != null && entry.getValue() != null)
|
||||
{
|
||||
responseHeaders.append(entry.getKey() + ": "
|
||||
+ android.text.TextUtils.join(",", entry.getValue()) + "\n");
|
||||
|
||||
if (entry.getKey().compareTo("Content-Length") == 0)
|
||||
totalLength = Integer.decode(entry.getValue().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DisconnectionRunnable implements Runnable
|
||||
{
|
||||
public DisconnectionRunnable(HttpURLConnection theConnection,
|
||||
InputStream theInputStream,
|
||||
ReentrantLock theCreateStreamLock,
|
||||
Object theCreateFutureLock,
|
||||
Future<BufferedInputStream> theStreamFuture)
|
||||
{
|
||||
connectionToDisconnect = theConnection;
|
||||
inputStream = theInputStream;
|
||||
createStreamLock = theCreateStreamLock;
|
||||
createFutureLock = theCreateFutureLock;
|
||||
streamFuture = theStreamFuture;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!createStreamLock.tryLock())
|
||||
{
|
||||
synchronized (createFutureLock)
|
||||
{
|
||||
if (streamFuture != null)
|
||||
streamFuture.cancel(true);
|
||||
}
|
||||
|
||||
createStreamLock.lock();
|
||||
}
|
||||
|
||||
if (connectionToDisconnect != null)
|
||||
connectionToDisconnect.disconnect();
|
||||
|
||||
if (inputStream != null)
|
||||
inputStream.close();
|
||||
} catch (IOException e)
|
||||
{
|
||||
} finally
|
||||
{
|
||||
createStreamLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private HttpURLConnection connectionToDisconnect;
|
||||
private InputStream inputStream;
|
||||
private ReentrantLock createStreamLock;
|
||||
private Object createFutureLock;
|
||||
Future<BufferedInputStream> streamFuture;
|
||||
}
|
||||
|
||||
public final void release()
|
||||
{
|
||||
DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection,
|
||||
inputStream,
|
||||
createStreamLock,
|
||||
createFutureLock,
|
||||
streamFuture);
|
||||
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
hasBeenCancelled.set(true);
|
||||
|
||||
connection = null;
|
||||
}
|
||||
|
||||
Thread disconnectionThread = new Thread(disconnectionRunnable);
|
||||
disconnectionThread.start();
|
||||
}
|
||||
|
||||
public final int read(byte[] buffer, int numBytes)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
try
|
||||
{
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (inputStream != null)
|
||||
num = inputStream.read(buffer, 0, numBytes);
|
||||
}
|
||||
} catch (IOException e)
|
||||
{
|
||||
}
|
||||
|
||||
if (num > 0)
|
||||
position += num;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public final long getPosition()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
public final long getTotalLength()
|
||||
{
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
public final boolean isExhausted()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public final boolean setPosition(long newPos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPost;
|
||||
private byte[] postData;
|
||||
private String headers;
|
||||
private int timeOutMs;
|
||||
String httpRequestCmd;
|
||||
private HttpURLConnection connection;
|
||||
private int[] statusCode;
|
||||
private StringBuffer responseHeaders;
|
||||
private int totalLength;
|
||||
private int numRedirectsToFollow;
|
||||
private InputStream inputStream;
|
||||
private long position;
|
||||
private final ReentrantLock createStreamLock = new ReentrantLock();
|
||||
private final Object createFutureLock = new Object();
|
||||
private AtomicBoolean hasBeenCancelled = new AtomicBoolean();
|
||||
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
|
||||
Future<BufferedInputStream> streamFuture;
|
||||
}
|
||||
package com.roli.juce;
|
||||
|
||||
import java.lang.Runnable;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
public class JuceHTTPStream
|
||||
{
|
||||
public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse,
|
||||
String headersToUse, int timeOutMsToUse,
|
||||
int[] statusCodeToUse, StringBuffer responseHeadersToUse,
|
||||
int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException
|
||||
{
|
||||
isPost = isPostToUse;
|
||||
postData = postDataToUse;
|
||||
headers = headersToUse;
|
||||
timeOutMs = timeOutMsToUse;
|
||||
statusCode = statusCodeToUse;
|
||||
responseHeaders = responseHeadersToUse;
|
||||
totalLength = -1;
|
||||
numRedirectsToFollow = numRedirectsToFollowToUse;
|
||||
httpRequestCmd = httpRequestCmdToUse;
|
||||
|
||||
connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd);
|
||||
}
|
||||
|
||||
public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData,
|
||||
String headers, int timeOutMs, int[] statusCode,
|
||||
StringBuffer responseHeaders, int numRedirectsToFollow,
|
||||
String httpRequestCmd)
|
||||
{
|
||||
// timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL)
|
||||
if (timeOutMs < 0)
|
||||
timeOutMs = 0;
|
||||
else if (timeOutMs == 0)
|
||||
timeOutMs = 30000;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
{
|
||||
JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers,
|
||||
timeOutMs, statusCode, responseHeaders,
|
||||
numRedirectsToFollow, httpRequestCmd);
|
||||
|
||||
return httpStream;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData,
|
||||
String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException
|
||||
{
|
||||
HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection());
|
||||
|
||||
try
|
||||
{
|
||||
newConnection.setInstanceFollowRedirects(false);
|
||||
newConnection.setConnectTimeout(timeOutMs);
|
||||
newConnection.setReadTimeout(timeOutMs);
|
||||
|
||||
// headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines.
|
||||
// So convert headers string to an array, with an element for each line
|
||||
String headerLines[] = headers.split("\\n");
|
||||
|
||||
// Set request headers
|
||||
for (int i = 0; i < headerLines.length; ++i)
|
||||
{
|
||||
int pos = headerLines[i].indexOf(":");
|
||||
|
||||
if (pos > 0 && pos < headerLines[i].length())
|
||||
{
|
||||
String field = headerLines[i].substring(0, pos);
|
||||
String value = headerLines[i].substring(pos + 1);
|
||||
|
||||
if (value.length() > 0)
|
||||
newConnection.setRequestProperty(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
newConnection.setRequestMethod(httpRequestCmd);
|
||||
|
||||
if (isPost)
|
||||
{
|
||||
newConnection.setDoOutput(true);
|
||||
|
||||
if (postData != null)
|
||||
{
|
||||
OutputStream out = newConnection.getOutputStream();
|
||||
out.write(postData);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
return newConnection;
|
||||
} catch (Throwable e)
|
||||
{
|
||||
newConnection.disconnect();
|
||||
throw new IOException("Connection error");
|
||||
}
|
||||
}
|
||||
|
||||
private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException
|
||||
{
|
||||
synchronized (createFutureLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return null;
|
||||
|
||||
streamFuture = executor.submit(new Callable<BufferedInputStream>()
|
||||
{
|
||||
@Override
|
||||
public BufferedInputStream call() throws IOException
|
||||
{
|
||||
return new BufferedInputStream(isInput ? connection.getInputStream()
|
||||
: connection.getErrorStream());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return streamFuture.get();
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
return null;
|
||||
} catch (CancellationException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean connect()
|
||||
{
|
||||
boolean result = false;
|
||||
int numFollowedRedirects = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = doConnect();
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
if (++numFollowedRedirects > numRedirectsToFollow)
|
||||
break;
|
||||
|
||||
int status = statusCode[0];
|
||||
|
||||
if (status == 301 || status == 302 || status == 303 || status == 307)
|
||||
{
|
||||
// Assumes only one occurrence of "Location"
|
||||
int pos1 = responseHeaders.indexOf("Location:") + 10;
|
||||
int pos2 = responseHeaders.indexOf("\n", pos1);
|
||||
|
||||
if (pos2 > pos1)
|
||||
{
|
||||
String currentLocation = connection.getURL().toString();
|
||||
String newLocation = responseHeaders.substring(pos1, pos2);
|
||||
|
||||
try
|
||||
{
|
||||
// Handle newLocation whether it's absolute or relative
|
||||
URL baseUrl = new URL(currentLocation);
|
||||
URL newUrl = new URL(baseUrl, newLocation);
|
||||
String transformedNewLocation = newUrl.toString();
|
||||
|
||||
if (transformedNewLocation != currentLocation)
|
||||
{
|
||||
// Clear responseHeaders before next iteration
|
||||
responseHeaders.delete(0, responseHeaders.length());
|
||||
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return false;
|
||||
|
||||
connection.disconnect();
|
||||
|
||||
try
|
||||
{
|
||||
connection = createConnection(transformedNewLocation, isPost,
|
||||
postData, headers, timeOutMs,
|
||||
httpRequestCmd);
|
||||
} catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final boolean doConnect()
|
||||
{
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (hasBeenCancelled.get())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
inputStream = getCancellableStream(true);
|
||||
} catch (ExecutionException e)
|
||||
{
|
||||
if (connection.getResponseCode() < 400)
|
||||
{
|
||||
statusCode[0] = connection.getResponseCode();
|
||||
connection.disconnect();
|
||||
return false;
|
||||
}
|
||||
} finally
|
||||
{
|
||||
statusCode[0] = connection.getResponseCode();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (statusCode[0] >= 400)
|
||||
inputStream = getCancellableStream(false);
|
||||
else
|
||||
inputStream = getCancellableStream(true);
|
||||
} catch (ExecutionException e)
|
||||
{
|
||||
}
|
||||
|
||||
for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())
|
||||
{
|
||||
if (entry.getKey() != null && entry.getValue() != null)
|
||||
{
|
||||
responseHeaders.append(entry.getKey() + ": "
|
||||
+ android.text.TextUtils.join(",", entry.getValue()) + "\n");
|
||||
|
||||
if (entry.getKey().compareTo("Content-Length") == 0)
|
||||
totalLength = Integer.decode(entry.getValue().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DisconnectionRunnable implements Runnable
|
||||
{
|
||||
public DisconnectionRunnable(HttpURLConnection theConnection,
|
||||
InputStream theInputStream,
|
||||
ReentrantLock theCreateStreamLock,
|
||||
Object theCreateFutureLock,
|
||||
Future<BufferedInputStream> theStreamFuture)
|
||||
{
|
||||
connectionToDisconnect = theConnection;
|
||||
inputStream = theInputStream;
|
||||
createStreamLock = theCreateStreamLock;
|
||||
createFutureLock = theCreateFutureLock;
|
||||
streamFuture = theStreamFuture;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!createStreamLock.tryLock())
|
||||
{
|
||||
synchronized (createFutureLock)
|
||||
{
|
||||
if (streamFuture != null)
|
||||
streamFuture.cancel(true);
|
||||
}
|
||||
|
||||
createStreamLock.lock();
|
||||
}
|
||||
|
||||
if (connectionToDisconnect != null)
|
||||
connectionToDisconnect.disconnect();
|
||||
|
||||
if (inputStream != null)
|
||||
inputStream.close();
|
||||
} catch (IOException e)
|
||||
{
|
||||
} finally
|
||||
{
|
||||
createStreamLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private HttpURLConnection connectionToDisconnect;
|
||||
private InputStream inputStream;
|
||||
private ReentrantLock createStreamLock;
|
||||
private Object createFutureLock;
|
||||
Future<BufferedInputStream> streamFuture;
|
||||
}
|
||||
|
||||
public final void release()
|
||||
{
|
||||
DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection,
|
||||
inputStream,
|
||||
createStreamLock,
|
||||
createFutureLock,
|
||||
streamFuture);
|
||||
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
hasBeenCancelled.set(true);
|
||||
|
||||
connection = null;
|
||||
}
|
||||
|
||||
Thread disconnectionThread = new Thread(disconnectionRunnable);
|
||||
disconnectionThread.start();
|
||||
}
|
||||
|
||||
public final int read(byte[] buffer, int numBytes)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
try
|
||||
{
|
||||
synchronized (createStreamLock)
|
||||
{
|
||||
if (inputStream != null)
|
||||
num = inputStream.read(buffer, 0, numBytes);
|
||||
}
|
||||
} catch (IOException e)
|
||||
{
|
||||
}
|
||||
|
||||
if (num > 0)
|
||||
position += num;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public final long getPosition()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
public final long getTotalLength()
|
||||
{
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
public final boolean isExhausted()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public final boolean setPosition(long newPos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPost;
|
||||
private byte[] postData;
|
||||
private String headers;
|
||||
private int timeOutMs;
|
||||
String httpRequestCmd;
|
||||
private HttpURLConnection connection;
|
||||
private int[] statusCode;
|
||||
private StringBuffer responseHeaders;
|
||||
private int totalLength;
|
||||
private int numRedirectsToFollow;
|
||||
private InputStream inputStream;
|
||||
private long position;
|
||||
private final ReentrantLock createStreamLock = new ReentrantLock();
|
||||
private final Object createFutureLock = new Object();
|
||||
private AtomicBoolean hasBeenCancelled = new AtomicBoolean();
|
||||
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
|
||||
Future<BufferedInputStream> streamFuture;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue