| @@ -59,6 +59,9 @@ public: | |||||
| if (getNDKPath().toString().isEmpty()) | if (getNDKPath().toString().isEmpty()) | ||||
| getNDKPath() = "${user.home}/SDKs/android-ndk-r5"; | getNDKPath() = "${user.home}/SDKs/android-ndk-r5"; | ||||
| if (getInternetNeeded().toString().isEmpty()) | |||||
| getInternetNeeded() = true; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -87,10 +90,14 @@ public: | |||||
| props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false)); | props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false)); | ||||
| props.getLast()->setTooltip ("The path to the Android NDK folder on the target build machine"); | props.getLast()->setTooltip ("The path to the Android NDK folder on the target build machine"); | ||||
| props.add (new BooleanPropertyComponent (getInternetNeeded(), "Internet Access", "Specify internet access permission in the manifest")); | |||||
| props.getLast()->setTooltip ("If enabled, this will set the android.permission.INTERNET flag in the manifest."); | |||||
| } | } | ||||
| Value getSDKPath() const { return getSetting (Ids::androidSDKPath); } | Value getSDKPath() const { return getSetting (Ids::androidSDKPath); } | ||||
| Value getNDKPath() const { return getSetting (Ids::androidNDKPath); } | Value getNDKPath() const { return getSetting (Ids::androidNDKPath); } | ||||
| Value getInternetNeeded() const { return getSetting (Ids::androidInternetNeeded); } | |||||
| //============================================================================== | //============================================================================== | ||||
| void create() | void create() | ||||
| @@ -149,6 +156,12 @@ private: | |||||
| screens->setAttribute ("android:xlargeScreens", "true"); | screens->setAttribute ("android:xlargeScreens", "true"); | ||||
| screens->setAttribute ("android:anyDensity", "true"); | screens->setAttribute ("android:anyDensity", "true"); | ||||
| if (getInternetNeeded().getValue()) | |||||
| { | |||||
| XmlElement* permission = manifest->createNewChildElement ("uses-permission"); | |||||
| permission->setAttribute ("android:name", "android.permission.INTERNET"); | |||||
| } | |||||
| XmlElement* app = manifest->createNewChildElement ("application"); | XmlElement* app = manifest->createNewChildElement ("application"); | ||||
| app->setAttribute ("android:label", "@string/app_name"); | app->setAttribute ("android:label", "@string/app_name"); | ||||
| app->setAttribute ("android:icon", "@drawable/icon"); | app->setAttribute ("android:icon", "@drawable/icon"); | ||||
| @@ -115,6 +115,7 @@ namespace Ids | |||||
| DECLARE_ID (hidden); | DECLARE_ID (hidden); | ||||
| DECLARE_ID (androidSDKPath); | DECLARE_ID (androidSDKPath); | ||||
| DECLARE_ID (androidNDKPath); | DECLARE_ID (androidNDKPath); | ||||
| DECLARE_ID (androidInternetNeeded); | |||||
| const Identifier class_ ("class"); | const Identifier class_ ("class"); | ||||
| const Identifier id_ ("id"); | const Identifier id_ ("id"); | ||||
| @@ -148,9 +148,9 @@ public: | |||||
| private: | private: | ||||
| StringPool identifierPool; | StringPool identifierPool; | ||||
| static DISPID getHashFromString (const juce_wchar* s) throw() | |||||
| static DISPID getHashFromString (const String::CharPointerType& s) throw() | |||||
| { | { | ||||
| return (DISPID) (pointer_sized_int) s; | |||||
| return (DISPID) (pointer_sized_int) s.getAddress(); | |||||
| } | } | ||||
| IDispatchHelper (const IDispatchHelper&); | IDispatchHelper (const IDispatchHelper&); | ||||
| @@ -22240,7 +22240,7 @@ int AudioThumbnail::getNumChannels() const throw() | |||||
| double AudioThumbnail::getTotalLength() const throw() | double AudioThumbnail::getTotalLength() const throw() | ||||
| { | { | ||||
| return totalSamples / sampleRate; | |||||
| return sampleRate > 0 ? (totalSamples / sampleRate) : 0; | |||||
| } | } | ||||
| bool AudioThumbnail::isFullyLoaded() const throw() | bool AudioThumbnail::isFullyLoaded() const throw() | ||||
| @@ -242738,13 +242738,13 @@ public: | |||||
| : handle (0), refCount (1) | : handle (0), refCount (1) | ||||
| { | { | ||||
| name = name.replaceCharacter ('\\', '/'); | name = name.replaceCharacter ('\\', '/'); | ||||
| handle = CreateMutexW (0, TRUE, ("Global\\" + name).toUTF16().getAddress()); | |||||
| handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer()); | |||||
| // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to | // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to | ||||
| // a local one. (A local one also sometimes fails on other machines so neither type appears to be | // a local one. (A local one also sometimes fails on other machines so neither type appears to be | ||||
| // universally reliable) | // universally reliable) | ||||
| if (handle == 0) | if (handle == 0) | ||||
| handle = CreateMutexW (0, TRUE, ("Local\\" + name).toUTF16().getAddress()); | |||||
| handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer()); | |||||
| if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) | if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) | ||||
| { | { | ||||
| @@ -242865,7 +242865,7 @@ namespace WindowsFileHelpers | |||||
| { | { | ||||
| // (mess with the string to make sure it's not sharing its internal storage) | // (mess with the string to make sure it's not sharing its internal storage) | ||||
| path = (path + " ").dropLastCharacters(1); | path = (path + " ").dropLastCharacters(1); | ||||
| WCHAR* p = const_cast <WCHAR*> (path.toUTF16().getAddress()); | |||||
| WCHAR* p = const_cast <WCHAR*> (path.toWideCharPointer()); | |||||
| if (PathStripToRoot (p)) | if (PathStripToRoot (p)) | ||||
| return String ((const WCHAR*) p); | return String ((const WCHAR*) p); | ||||
| @@ -242974,7 +242974,7 @@ bool File::moveToTrash() const | |||||
| // The string we pass in must be double null terminated.. | // The string we pass in must be double null terminated.. | ||||
| String doubleNullTermPath (getFullPathName() + " "); | String doubleNullTermPath (getFullPathName() + " "); | ||||
| WCHAR* const p = const_cast <WCHAR*> (doubleNullTermPath.toUTF16().getAddress()); | |||||
| WCHAR* const p = const_cast <WCHAR*> (doubleNullTermPath.toWideCharPointer()); | |||||
| p [getFullPathName().length()] = 0; | p [getFullPathName().length()] = 0; | ||||
| fos.wFunc = FO_DELETE; | fos.wFunc = FO_DELETE; | ||||
| @@ -244205,7 +244205,7 @@ void PlatformUtilities::setRegistryValue (const String& regValuePath, | |||||
| if (k != 0) | if (k != 0) | ||||
| { | { | ||||
| RegSetValueEx (k, valueName.toUTF16(), 0, REG_SZ, | RegSetValueEx (k, valueName.toUTF16(), 0, REG_SZ, | ||||
| (const BYTE*) value.toUTF16().getAddress(), | |||||
| (const BYTE*) value.toWideCharPointer(), | |||||
| CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())); | CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())); | ||||
| RegCloseKey (k); | RegCloseKey (k); | ||||
| @@ -248390,7 +248390,7 @@ const Image juce_createIconForFile (const File& file) | |||||
| WORD iconNum = 0; | WORD iconNum = 0; | ||||
| HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), | HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), | ||||
| const_cast <WCHAR*> (file.getFullPathName().toUTF16().getAddress()), &iconNum); | |||||
| const_cast <WCHAR*> (file.getFullPathName().toWideCharPointer()), &iconNum); | |||||
| if (icon != 0) | if (icon != 0) | ||||
| { | { | ||||
| @@ -248807,7 +248807,7 @@ namespace FileChooserHelpers | |||||
| FileChooserCallbackInfo* info = (FileChooserCallbackInfo*) lpData; | FileChooserCallbackInfo* info = (FileChooserCallbackInfo*) lpData; | ||||
| if (msg == BFFM_INITIALIZED) | if (msg == BFFM_INITIALIZED) | ||||
| SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) info->initialPath.toUTF16().getAddress()); | |||||
| SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) info->initialPath.toWideCharPointer()); | |||||
| else if (msg == BFFM_VALIDATEFAILEDW) | else if (msg == BFFM_VALIDATEFAILEDW) | ||||
| info->returnedString = (LPCWSTR) lParam; | info->returnedString = (LPCWSTR) lParam; | ||||
| else if (msg == BFFM_VALIDATEFAILEDA) | else if (msg == BFFM_VALIDATEFAILEDA) | ||||
| @@ -250013,7 +250013,7 @@ public: | |||||
| if (headers != 0) | if (headers != 0) | ||||
| { | { | ||||
| V_VT (&headersVar) = VT_BSTR; | V_VT (&headersVar) = VT_BSTR; | ||||
| V_BSTR (&headersVar) = SysAllocString ((const OLECHAR*) headers->joinIntoString ("\r\n").toUTF16().getAddress()); | |||||
| V_BSTR (&headersVar) = SysAllocString ((const OLECHAR*) headers->joinIntoString ("\r\n").toWideCharPointer()); | |||||
| } | } | ||||
| if (postData != 0 && postData->getSize() > 0) | if (postData != 0 && postData->getSize() > 0) | ||||
| @@ -250041,7 +250041,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| browser->Navigate ((BSTR) (const OLECHAR*) url.toUTF16().getAddress(), | |||||
| browser->Navigate ((BSTR) (const OLECHAR*) url.toWideCharPointer(), | |||||
| &flags, &frame, | &flags, &frame, | ||||
| &postDataVar, &headersVar); | &postDataVar, &headersVar); | ||||
| @@ -285405,80 +285405,78 @@ class WebInputStream : public InputStream | |||||
| { | { | ||||
| public: | public: | ||||
| WebInputStream (const String& address, bool isPost, const MemoryBlock& postData, | |||||
| WebInputStream (String address, bool isPost, const MemoryBlock& postData, | |||||
| URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, | URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, | ||||
| const String& headers, int timeOutMs, StringPairArray* responseHeaders) | const String& headers, int timeOutMs, StringPairArray* responseHeaders) | ||||
| { | { | ||||
| if (! address.contains ("://")) | |||||
| address = "http://" + address; | |||||
| JNIEnv* env = getEnv(); | |||||
| jbyteArray postDataArray = 0; | jbyteArray postDataArray = 0; | ||||
| if (postData.getSize() > 0) | if (postData.getSize() > 0) | ||||
| { | { | ||||
| postDataArray = getEnv()->NewByteArray (postData.getSize()); | |||||
| getEnv()->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); | |||||
| postDataArray = env->NewByteArray (postData.getSize()); | |||||
| env->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); | |||||
| } | } | ||||
| LocalRef<jobject> responseHeaderBuffer (getEnv()->NewObject (android.stringBufferClass, android.stringBufferConstructor)); | |||||
| LocalRef<jobject> responseHeaderBuffer (env->NewObject (android.stringBufferClass, android.stringBufferConstructor)); | |||||
| stream = GlobalRef (android.activity.callObjectMethod (android.createHTTPStream, | |||||
| javaString (address).get(), | |||||
| (jboolean) isPost, | |||||
| postDataArray, | |||||
| javaString (headers).get(), | |||||
| (jint) timeOutMs, | |||||
| responseHeaderBuffer.get())); | |||||
| stream = GlobalRef (env->CallStaticObjectMethod (android.activityClass, | |||||
| android.createHTTPStream, | |||||
| javaString (address).get(), | |||||
| (jboolean) isPost, | |||||
| postDataArray, | |||||
| javaString (headers).get(), | |||||
| (jint) timeOutMs, | |||||
| responseHeaderBuffer.get())); | |||||
| getEnv()->DeleteLocalRef (postDataArray); | |||||
| if (postDataArray != 0) | |||||
| env->DeleteLocalRef (postDataArray); | |||||
| if (stream != 0) | if (stream != 0) | ||||
| { | { | ||||
| StringArray headerLines; | StringArray headerLines; | ||||
| { | { | ||||
| LocalRef<jstring> headersString ((jstring) getEnv()->CallObjectMethod (responseHeaderBuffer.get(), | |||||
| android.stringBufferToString)); | |||||
| LocalRef<jstring> headersString ((jstring) env->CallObjectMethod (responseHeaderBuffer.get(), | |||||
| android.stringBufferToString)); | |||||
| headerLines.addLines (juceString (headersString)); | headerLines.addLines (juceString (headersString)); | ||||
| } | } | ||||
| for (int i = 0; i < headerLines.size(); ++i) | |||||
| if (responseHeaders != 0) | |||||
| { | { | ||||
| const String& header = headerLines[i]; | |||||
| const String key (header.upToFirstOccurrenceOf (": ", false, false)); | |||||
| const String value (header.fromFirstOccurrenceOf (": ", false, false)); | |||||
| const String previousValue ((*responseHeaders) [key]); | |||||
| for (int i = 0; i < headerLines.size(); ++i) | |||||
| { | |||||
| const String& header = headerLines[i]; | |||||
| const String key (header.upToFirstOccurrenceOf (": ", false, false)); | |||||
| const String value (header.fromFirstOccurrenceOf (": ", false, false)); | |||||
| const String previousValue ((*responseHeaders) [key]); | |||||
| responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); | |||||
| responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ~WebInputStream() | ~WebInputStream() | ||||
| { | { | ||||
| stream.callVoidMethod (android.httpStreamRelease); | |||||
| } | |||||
| bool isExhausted() | |||||
| { | |||||
| return stream != 0 && stream.callBooleanMethod (android.isExhausted); | |||||
| } | |||||
| int64 getPosition() | |||||
| { | |||||
| return stream != 0 ? stream.callLongMethod (android.getPosition) : 0; | |||||
| } | |||||
| int64 getTotalLength() | |||||
| { | |||||
| return stream != 0 ? stream.callLongMethod (android.getTotalLength) : 0; | |||||
| if (stream != 0) | |||||
| stream.callVoidMethod (android.httpStreamRelease); | |||||
| } | } | ||||
| bool setPosition (int64 wantedPos) | |||||
| { | |||||
| return stream != 0 && stream.callBooleanMethod (android.setPosition, (jlong) wantedPos); | |||||
| } | |||||
| bool isExhausted() { return stream != 0 && stream.callBooleanMethod (android.isExhausted); } | |||||
| int64 getTotalLength() { return stream != 0 ? stream.callLongMethod (android.getTotalLength) : 0; } | |||||
| int64 getPosition() { return stream != 0 ? stream.callLongMethod (android.getPosition) : 0; } | |||||
| bool setPosition (int64 wantedPos) { return stream != 0 && stream.callBooleanMethod (android.setPosition, (jlong) wantedPos); } | |||||
| int read (void* buffer, int bytesToRead) | int read (void* buffer, int bytesToRead) | ||||
| { | { | ||||
| if (stream == 0) | |||||
| return 0; | |||||
| JNIEnv* env = getEnv(); | JNIEnv* env = getEnv(); | ||||
| jbyteArray javaArray = env->NewByteArray (bytesToRead); | jbyteArray javaArray = env->NewByteArray (bytesToRead); | ||||
| @@ -285486,7 +285484,7 @@ public: | |||||
| int numBytes = stream.callIntMethod (android.httpStreamRead, javaArray, (jint) bytesToRead); | int numBytes = stream.callIntMethod (android.httpStreamRead, javaArray, (jint) bytesToRead); | ||||
| if (numBytes > 0) | if (numBytes > 0) | ||||
| env->GetByteArrayRegion (javaArray, 0, numBytes, (jbyte*) buffer); | |||||
| env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast <jbyte*> (buffer)); | |||||
| env->DeleteLocalRef (javaArray); | env->DeleteLocalRef (javaArray); | ||||
| return numBytes; | return numBytes; | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 45 | |||||
| #define JUCE_BUILDNUMBER 46 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -720,7 +720,7 @@ int AudioThumbnail::getNumChannels() const throw() | |||||
| double AudioThumbnail::getTotalLength() const throw() | double AudioThumbnail::getTotalLength() const throw() | ||||
| { | { | ||||
| return totalSamples / sampleRate; | |||||
| return sampleRate > 0 ? (totalSamples / sampleRate) : 0; | |||||
| } | } | ||||
| bool AudioThumbnail::isFullyLoaded() const throw() | bool AudioThumbnail::isFullyLoaded() const throw() | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 45 | |||||
| #define JUCE_BUILDNUMBER 46 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -60,6 +60,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_Socket.h" | #include "juce_Socket.h" | ||||
| #include "../../threads/juce_ScopedLock.h" | #include "../../threads/juce_ScopedLock.h" | ||||
| #include "../../threads/juce_Thread.h" | #include "../../threads/juce_Thread.h" | ||||
| #include "../../utilities/juce_DeletedAtShutdown.h" | |||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| typedef int juce_socklen_t; | typedef int juce_socklen_t; | ||||
| @@ -38,8 +38,12 @@ import android.graphics.RectF; | |||||
| import android.graphics.Rect; | import android.graphics.Rect; | ||||
| import android.text.ClipboardManager; | import android.text.ClipboardManager; | ||||
| import com.juce.ComponentPeerView; | import com.juce.ComponentPeerView; | ||||
| import java.io.BufferedInputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.OutputStream; | |||||
| import java.net.URL; | import java.net.URL; | ||||
| import java.net.HttpURLConnection; | |||||
| //============================================================================== | //============================================================================== | ||||
| public final class JuceAppActivity extends Activity | public final class JuceAppActivity extends Activity | ||||
| @@ -201,27 +205,49 @@ public final class JuceAppActivity extends Activity | |||||
| //============================================================================== | //============================================================================== | ||||
| public static class HTTPStream | public static class HTTPStream | ||||
| { | { | ||||
| public HTTPStream() | |||||
| public HTTPStream (HttpURLConnection connection_) throws IOException | |||||
| { | { | ||||
| connection = connection_; | |||||
| inputStream = new BufferedInputStream (connection.getInputStream()); | |||||
| } | } | ||||
| public final void release() | public final void release() | ||||
| { | { | ||||
| try | |||||
| { | |||||
| inputStream.close(); | |||||
| } | |||||
| catch (IOException e) | |||||
| {} | |||||
| connection.disconnect(); | |||||
| } | } | ||||
| public final int read (byte[] buffer, int numBytes) | public final int read (byte[] buffer, int numBytes) | ||||
| { | { | ||||
| return 0; | |||||
| int num = 0; | |||||
| try | |||||
| { | |||||
| num = inputStream.read (buffer, 0, numBytes); | |||||
| } | |||||
| catch (IOException e) | |||||
| {} | |||||
| if (num > 0) | |||||
| position += num; | |||||
| return num; | |||||
| } | } | ||||
| public final long getPosition() | public final long getPosition() | ||||
| { | { | ||||
| return 0; | |||||
| return position; | |||||
| } | } | ||||
| public final long getTotalLength() | public final long getTotalLength() | ||||
| { | { | ||||
| return 0; | |||||
| return -1; | |||||
| } | } | ||||
| public final boolean isExhausted() | public final boolean isExhausted() | ||||
| @@ -233,6 +259,10 @@ public final class JuceAppActivity extends Activity | |||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| private HttpURLConnection connection; | |||||
| private InputStream inputStream; | |||||
| private long position; | |||||
| } | } | ||||
| public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, | public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, | ||||
| @@ -240,11 +270,32 @@ public final class JuceAppActivity extends Activity | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| URL u = new URL (address); | |||||
| HttpURLConnection connection = (HttpURLConnection) (new URL (address).openConnection()); | |||||
| return new HTTPStream (); | |||||
| if (connection != null) | |||||
| { | |||||
| try | |||||
| { | |||||
| if (isPost) | |||||
| { | |||||
| connection.setConnectTimeout (timeOutMs); | |||||
| connection.setDoOutput (true); | |||||
| connection.setChunkedStreamingMode (0); | |||||
| OutputStream out = connection.getOutputStream(); | |||||
| out.write (postData); | |||||
| out.flush(); | |||||
| } | |||||
| return new HTTPStream (connection); | |||||
| } | |||||
| catch (Throwable e) | |||||
| { | |||||
| connection.disconnect(); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| catch (java.net.MalformedURLException e) | |||||
| catch (Throwable e) | |||||
| {} | {} | ||||
| return null; | return null; | ||||
| @@ -51,81 +51,79 @@ class WebInputStream : public InputStream | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| WebInputStream (const String& address, bool isPost, const MemoryBlock& postData, | |||||
| WebInputStream (String address, bool isPost, const MemoryBlock& postData, | |||||
| URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, | URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, | ||||
| const String& headers, int timeOutMs, StringPairArray* responseHeaders) | const String& headers, int timeOutMs, StringPairArray* responseHeaders) | ||||
| { | { | ||||
| if (! address.contains ("://")) | |||||
| address = "http://" + address; | |||||
| JNIEnv* env = getEnv(); | |||||
| jbyteArray postDataArray = 0; | jbyteArray postDataArray = 0; | ||||
| if (postData.getSize() > 0) | if (postData.getSize() > 0) | ||||
| { | { | ||||
| postDataArray = getEnv()->NewByteArray (postData.getSize()); | |||||
| getEnv()->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); | |||||
| postDataArray = env->NewByteArray (postData.getSize()); | |||||
| env->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); | |||||
| } | } | ||||
| LocalRef<jobject> responseHeaderBuffer (getEnv()->NewObject (android.stringBufferClass, android.stringBufferConstructor)); | |||||
| LocalRef<jobject> responseHeaderBuffer (env->NewObject (android.stringBufferClass, android.stringBufferConstructor)); | |||||
| stream = GlobalRef (android.activity.callObjectMethod (android.createHTTPStream, | |||||
| javaString (address).get(), | |||||
| (jboolean) isPost, | |||||
| postDataArray, | |||||
| javaString (headers).get(), | |||||
| (jint) timeOutMs, | |||||
| responseHeaderBuffer.get())); | |||||
| stream = GlobalRef (env->CallStaticObjectMethod (android.activityClass, | |||||
| android.createHTTPStream, | |||||
| javaString (address).get(), | |||||
| (jboolean) isPost, | |||||
| postDataArray, | |||||
| javaString (headers).get(), | |||||
| (jint) timeOutMs, | |||||
| responseHeaderBuffer.get())); | |||||
| getEnv()->DeleteLocalRef (postDataArray); | |||||
| if (postDataArray != 0) | |||||
| env->DeleteLocalRef (postDataArray); | |||||
| if (stream != 0) | if (stream != 0) | ||||
| { | { | ||||
| StringArray headerLines; | StringArray headerLines; | ||||
| { | { | ||||
| LocalRef<jstring> headersString ((jstring) getEnv()->CallObjectMethod (responseHeaderBuffer.get(), | |||||
| android.stringBufferToString)); | |||||
| LocalRef<jstring> headersString ((jstring) env->CallObjectMethod (responseHeaderBuffer.get(), | |||||
| android.stringBufferToString)); | |||||
| headerLines.addLines (juceString (headersString)); | headerLines.addLines (juceString (headersString)); | ||||
| } | } | ||||
| for (int i = 0; i < headerLines.size(); ++i) | |||||
| if (responseHeaders != 0) | |||||
| { | { | ||||
| const String& header = headerLines[i]; | |||||
| const String key (header.upToFirstOccurrenceOf (": ", false, false)); | |||||
| const String value (header.fromFirstOccurrenceOf (": ", false, false)); | |||||
| const String previousValue ((*responseHeaders) [key]); | |||||
| responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); | |||||
| for (int i = 0; i < headerLines.size(); ++i) | |||||
| { | |||||
| const String& header = headerLines[i]; | |||||
| const String key (header.upToFirstOccurrenceOf (": ", false, false)); | |||||
| const String value (header.fromFirstOccurrenceOf (": ", false, false)); | |||||
| const String previousValue ((*responseHeaders) [key]); | |||||
| responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ~WebInputStream() | ~WebInputStream() | ||||
| { | { | ||||
| stream.callVoidMethod (android.httpStreamRelease); | |||||
| if (stream != 0) | |||||
| stream.callVoidMethod (android.httpStreamRelease); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| bool isExhausted() | |||||
| { | |||||
| return stream != 0 && stream.callBooleanMethod (android.isExhausted); | |||||
| } | |||||
| int64 getPosition() | |||||
| { | |||||
| return stream != 0 ? stream.callLongMethod (android.getPosition) : 0; | |||||
| } | |||||
| int64 getTotalLength() | |||||
| { | |||||
| return stream != 0 ? stream.callLongMethod (android.getTotalLength) : 0; | |||||
| } | |||||
| bool setPosition (int64 wantedPos) | |||||
| { | |||||
| return stream != 0 && stream.callBooleanMethod (android.setPosition, (jlong) wantedPos); | |||||
| } | |||||
| bool isExhausted() { return stream != 0 && stream.callBooleanMethod (android.isExhausted); } | |||||
| int64 getTotalLength() { return stream != 0 ? stream.callLongMethod (android.getTotalLength) : 0; } | |||||
| int64 getPosition() { return stream != 0 ? stream.callLongMethod (android.getPosition) : 0; } | |||||
| bool setPosition (int64 wantedPos) { return stream != 0 && stream.callBooleanMethod (android.setPosition, (jlong) wantedPos); } | |||||
| int read (void* buffer, int bytesToRead) | int read (void* buffer, int bytesToRead) | ||||
| { | { | ||||
| if (stream == 0) | |||||
| return 0; | |||||
| JNIEnv* env = getEnv(); | JNIEnv* env = getEnv(); | ||||
| jbyteArray javaArray = env->NewByteArray (bytesToRead); | jbyteArray javaArray = env->NewByteArray (bytesToRead); | ||||
| @@ -133,7 +131,7 @@ public: | |||||
| int numBytes = stream.callIntMethod (android.httpStreamRead, javaArray, (jint) bytesToRead); | int numBytes = stream.callIntMethod (android.httpStreamRead, javaArray, (jint) bytesToRead); | ||||
| if (numBytes > 0) | if (numBytes > 0) | ||||
| env->GetByteArrayRegion (javaArray, 0, numBytes, (jbyte*) buffer); | |||||
| env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast <jbyte*> (buffer)); | |||||
| env->DeleteLocalRef (javaArray); | env->DeleteLocalRef (javaArray); | ||||
| return numBytes; | return numBytes; | ||||
| @@ -56,7 +56,7 @@ namespace FileChooserHelpers | |||||
| FileChooserCallbackInfo* info = (FileChooserCallbackInfo*) lpData; | FileChooserCallbackInfo* info = (FileChooserCallbackInfo*) lpData; | ||||
| if (msg == BFFM_INITIALIZED) | if (msg == BFFM_INITIALIZED) | ||||
| SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) info->initialPath.toUTF16().getAddress()); | |||||
| SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) info->initialPath.toWideCharPointer()); | |||||
| else if (msg == BFFM_VALIDATEFAILEDW) | else if (msg == BFFM_VALIDATEFAILEDW) | ||||
| info->returnedString = (LPCWSTR) lParam; | info->returnedString = (LPCWSTR) lParam; | ||||
| else if (msg == BFFM_VALIDATEFAILEDA) | else if (msg == BFFM_VALIDATEFAILEDA) | ||||
| @@ -60,7 +60,7 @@ namespace WindowsFileHelpers | |||||
| { | { | ||||
| // (mess with the string to make sure it's not sharing its internal storage) | // (mess with the string to make sure it's not sharing its internal storage) | ||||
| path = (path + " ").dropLastCharacters(1); | path = (path + " ").dropLastCharacters(1); | ||||
| WCHAR* p = const_cast <WCHAR*> (path.toUTF16().getAddress()); | |||||
| WCHAR* p = const_cast <WCHAR*> (path.toWideCharPointer()); | |||||
| if (PathStripToRoot (p)) | if (PathStripToRoot (p)) | ||||
| return String ((const WCHAR*) p); | return String ((const WCHAR*) p); | ||||
| @@ -173,7 +173,7 @@ bool File::moveToTrash() const | |||||
| // The string we pass in must be double null terminated.. | // The string we pass in must be double null terminated.. | ||||
| String doubleNullTermPath (getFullPathName() + " "); | String doubleNullTermPath (getFullPathName() + " "); | ||||
| WCHAR* const p = const_cast <WCHAR*> (doubleNullTermPath.toUTF16().getAddress()); | |||||
| WCHAR* const p = const_cast <WCHAR*> (doubleNullTermPath.toWideCharPointer()); | |||||
| p [getFullPathName().length()] = 0; | p [getFullPathName().length()] = 0; | ||||
| fos.wFunc = FO_DELETE; | fos.wFunc = FO_DELETE; | ||||
| @@ -105,7 +105,7 @@ void PlatformUtilities::setRegistryValue (const String& regValuePath, | |||||
| if (k != 0) | if (k != 0) | ||||
| { | { | ||||
| RegSetValueEx (k, valueName.toUTF16(), 0, REG_SZ, | RegSetValueEx (k, valueName.toUTF16(), 0, REG_SZ, | ||||
| (const BYTE*) value.toUTF16().getAddress(), | |||||
| (const BYTE*) value.toWideCharPointer(), | |||||
| CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())); | CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())); | ||||
| RegCloseKey (k); | RegCloseKey (k); | ||||
| @@ -349,13 +349,13 @@ public: | |||||
| : handle (0), refCount (1) | : handle (0), refCount (1) | ||||
| { | { | ||||
| name = name.replaceCharacter ('\\', '/'); | name = name.replaceCharacter ('\\', '/'); | ||||
| handle = CreateMutexW (0, TRUE, ("Global\\" + name).toUTF16().getAddress()); | |||||
| handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer()); | |||||
| // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to | // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to | ||||
| // a local one. (A local one also sometimes fails on other machines so neither type appears to be | // a local one. (A local one also sometimes fails on other machines so neither type appears to be | ||||
| // universally reliable) | // universally reliable) | ||||
| if (handle == 0) | if (handle == 0) | ||||
| handle = CreateMutexW (0, TRUE, ("Local\\" + name).toUTF16().getAddress()); | |||||
| handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer()); | |||||
| if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) | if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) | ||||
| { | { | ||||
| @@ -90,7 +90,7 @@ public: | |||||
| if (headers != 0) | if (headers != 0) | ||||
| { | { | ||||
| V_VT (&headersVar) = VT_BSTR; | V_VT (&headersVar) = VT_BSTR; | ||||
| V_BSTR (&headersVar) = SysAllocString ((const OLECHAR*) headers->joinIntoString ("\r\n").toUTF16().getAddress()); | |||||
| V_BSTR (&headersVar) = SysAllocString ((const OLECHAR*) headers->joinIntoString ("\r\n").toWideCharPointer()); | |||||
| } | } | ||||
| if (postData != 0 && postData->getSize() > 0) | if (postData != 0 && postData->getSize() > 0) | ||||
| @@ -118,7 +118,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| browser->Navigate ((BSTR) (const OLECHAR*) url.toUTF16().getAddress(), | |||||
| browser->Navigate ((BSTR) (const OLECHAR*) url.toWideCharPointer(), | |||||
| &flags, &frame, | &flags, &frame, | ||||
| &postDataVar, &headersVar); | &postDataVar, &headersVar); | ||||
| @@ -2596,7 +2596,7 @@ const Image juce_createIconForFile (const File& file) | |||||
| WORD iconNum = 0; | WORD iconNum = 0; | ||||
| HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), | HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), | ||||
| const_cast <WCHAR*> (file.getFullPathName().toUTF16().getAddress()), &iconNum); | |||||
| const_cast <WCHAR*> (file.getFullPathName().toWideCharPointer()), &iconNum); | |||||
| if (icon != 0) | if (icon != 0) | ||||
| { | { | ||||