text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

package com.android.vending.billing;
/**
 * InAppBillingService is the service that provides in-app billing version 3 and beyond.
 * This service provides the following features:
 * 1. Provides a new API to get details of in-app items published for the app including
 *    price, type, title and description.
 * 2. The purchase flow is synchronous and purchase information is available immediately
 *    after it completes.
 * 3. Purchase information of in-app purchases is maintained within the Google Play system
 *    till the purchase is consumed.
 * 4. An API to consume a purchase of an inapp item. All purchases of one-time
 *    in-app items are consumable and thereafter can be purchased again.
 * 5. An API to get current purchases of the user immediately. This will not contain any
 *    consumed purchases.
 *
 * All calls will give a response code with the following possible values
 * RESULT_OK = 0 - success
 * RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog
 * RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down
 * RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested
 * RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase
 * RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API
 * RESULT_ERROR = 6 - Fatal error during the API action
 * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
 * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
 */
public interface IInAppBillingService extends android.os.IInterface
    {
        /** Local-side IPC implementation stub class. */
        public static abstract class Stub extends android.os.Binder implements com.android.vending.billing.IInAppBillingService
        {
            private static final java.lang.String DESCRIPTOR = "com.android.vending.billing.IInAppBillingService";
            /** Construct the stub at attach it to the interface. */
            public Stub()
            {
                this.attachInterface(this, DESCRIPTOR);
            }
            /**
             * Cast an IBinder object into an com.android.vending.billing.IInAppBillingService interface,
             * generating a proxy if needed.
             */
            public static com.android.vending.billing.IInAppBillingService asInterface(android.os.IBinder obj)
            {
                if ((obj==null)) {
                    return null;
                }
                android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
                if (((iin!=null)&&(iin instanceof com.android.vending.billing.IInAppBillingService))) {
                    return ((com.android.vending.billing.IInAppBillingService)iin);
                }
                return new com.android.vending.billing.IInAppBillingService.Stub.Proxy(obj);
            }
            @Override public android.os.IBinder asBinder()
            {
                return this;
            }
            @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
            {
                switch (code)
                {
                    case INTERFACE_TRANSACTION:
                    {
                        reply.writeString(DESCRIPTOR);
                        return true;
                    }
                    case TRANSACTION_isBillingSupported:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        int _result = this.isBillingSupported(_arg0, _arg1, _arg2);
                        reply.writeNoException();
                        reply.writeInt(_result);
                        return true;
                    }
                    case TRANSACTION_getSkuDetails:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        android.os.Bundle _arg3;
                        if ((0!=data.readInt())) {
                            _arg3 = android.os.Bundle.CREATOR.createFromParcel(data);
                        }
                        else {
                            _arg3 = null;
                        }
                        android.os.Bundle _result = this.getSkuDetails(_arg0, _arg1, _arg2, _arg3);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_getBuyIntent:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        java.lang.String _arg3;
                        _arg3 = data.readString();
                        java.lang.String _arg4;
                        _arg4 = data.readString();
                        android.os.Bundle _result = this.getBuyIntent(_arg0, _arg1, _arg2, _arg3, _arg4);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_getPurchases:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        java.lang.String _arg3;
                        _arg3 = data.readString();
                        android.os.Bundle _result = this.getPurchases(_arg0, _arg1, _arg2, _arg3);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_consumePurchase:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        int _result = this.consumePurchase(_arg0, _arg1, _arg2);
                        reply.writeNoException();
                        reply.writeInt(_result);
                        return true;
                    }
                    case TRANSACTION_stub:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        int _result = this.stub(_arg0, _arg1, _arg2);
                        reply.writeNoException();
                        reply.writeInt(_result);
                        return true;
                    }
                    case TRANSACTION_getBuyIntentToReplaceSkus:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.util.List<java.lang.String> _arg2;
                        _arg2 = data.createStringArrayList();
                        java.lang.String _arg3;
                        _arg3 = data.readString();
                        java.lang.String _arg4;
                        _arg4 = data.readString();
                        java.lang.String _arg5;
                        _arg5 = data.readString();
                        android.os.Bundle _result = this.getBuyIntentToReplaceSkus(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_getBuyIntentExtraParams:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        java.lang.String _arg3;
                        _arg3 = data.readString();
                        java.lang.String _arg4;
                        _arg4 = data.readString();
                        android.os.Bundle _arg5;
                        if ((0!=data.readInt())) {
                            _arg5 = android.os.Bundle.CREATOR.createFromParcel(data);
                        }
                        else {
                            _arg5 = null;
                        }
                        android.os.Bundle _result = this.getBuyIntentExtraParams(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_getPurchaseHistory:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        java.lang.String _arg3;
                        _arg3 = data.readString();
                        android.os.Bundle _arg4;
                        if ((0!=data.readInt())) {
                            _arg4 = android.os.Bundle.CREATOR.createFromParcel(data);
                        }
                        else {
                            _arg4 = null;
                        }
                        android.os.Bundle _result = this.getPurchaseHistory(_arg0, _arg1, _arg2, _arg3, _arg4);
                        reply.writeNoException();
                        if ((_result!=null)) {
                            reply.writeInt(1);
                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                        }
                        else {
                            reply.writeInt(0);
                        }
                        return true;
                    }
                    case TRANSACTION_isBillingSupportedExtraParams:
                    {
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        java.lang.String _arg1;
                        _arg1 = data.readString();
                        java.lang.String _arg2;
                        _arg2 = data.readString();
                        android.os.Bundle _arg3;
                        if ((0!=data.readInt())) {
                            _arg3 = android.os.Bundle.CREATOR.createFromParcel(data);
                        }
                        else {
                            _arg3 = null;
                        }
                        int _result = this.isBillingSupportedExtraParams(_arg0, _arg1, _arg2, _arg3);
                        reply.writeNoException();
                        reply.writeInt(_result);
                        return true;
                    }
                }
                return super.onTransact(code, data, reply, flags);
            }
            private static class Proxy implements com.android.vending.billing.IInAppBillingService
            {
                private android.os.IBinder mRemote;
                Proxy(android.os.IBinder remote)
                {
                    mRemote = remote;
                }
                @Override public android.os.IBinder asBinder()
                {
                    return mRemote;
                }
                public java.lang.String getInterfaceDescriptor()
                {
                    return DESCRIPTOR;
                }
                @Override public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    int _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        mRemote.transact(Stub.TRANSACTION_isBillingSupported, _data, _reply, 0);
                        _reply.readException();
                        _result = _reply.readInt();
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Provides details of a list of SKUs
                 * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
                 * with a list JSON strings containing the productId, price, title and description.
                 * This API can be called with a maximum of 20 SKUs.
                 * @param apiVersion billing API version that the app is using
                 * @param packageName the package name of the calling app
                 * @param type of the in-app items ("inapp" for one-time purchases
                 *        and "subs" for subscriptions)
                 * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
                 * @return Bundle containing the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
                 *                         on failures.
                 *         "DETAILS_LIST" with a StringArrayList containing purchase information
                 *                        in JSON format similar to:
                 *                        '{ "productId" : "exampleSku",
                 *                           "type" : "inapp",
                 *                           "price" : "$5.00",
                 *                           "price_currency": "USD",
                 *                           "price_amount_micros": 5000000,
                 *                           "title : "Example Title",
                 *                           "description" : "This is an example description" }'
                 */
                @Override public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        if ((skusBundle!=null)) {
                            _data.writeInt(1);
                            skusBundle.writeToParcel(_data, 0);
                        }
                        else {
                            _data.writeInt(0);
                        }
                        mRemote.transact(Stub.TRANSACTION_getSkuDetails, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
                 * the type, a unique purchase token and an optional developer payload.
                 * @param apiVersion billing API version that the app is using
                 * @param packageName package name of the calling app
                 * @param sku the SKU of the in-app item as published in the developer console
                 * @param type of the in-app item being purchased ("inapp" for one-time purchases
                 *        and "subs" for subscriptions)
                 * @param developerPayload optional argument to be sent back with the purchase information
                 * @return Bundle containing the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
                 *                         on failures.
                 *         "BUY_INTENT" - PendingIntent to start the purchase flow
                 *
                 * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
                 * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
                 * If the purchase is successful, the result data will contain the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
                 *                         codes on failures.
                 *         "INAPP_PURCHASE_DATA" - String in JSON format similar to
                 *                                 '{"orderId":"12999763169054705758.1371079406387615",
                 *                                   "packageName":"com.example.app",
                 *                                   "productId":"exampleSku",
                 *                                   "purchaseTime":1345678900000,
                 *                                   "purchaseToken" : "122333444455555",
                 *                                   "developerPayload":"example developer payload" }'
                 *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
                 *                                  was signed with the private key of the developer
                 */
                @Override public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(sku);
                        _data.writeString(type);
                        _data.writeString(developerPayload);
                        mRemote.transact(Stub.TRANSACTION_getBuyIntent, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Returns the current SKUs owned by the user of the type and package name specified along with
                 * purchase information and a signature of the data to be validated.
                 * This will return all SKUs that have been purchased in V3 and managed items purchased using
                 * V1 and V2 that have not been consumed.
                 * @param apiVersion billing API version that the app is using
                 * @param packageName package name of the calling app
                 * @param type of the in-app items being requested ("inapp" for one-time purchases
                 *        and "subs" for subscriptions)
                 * @param continuationToken to be set as null for the first call, if the number of owned
                 *        skus are too many, a continuationToken is returned in the response bundle.
                 *        This method can be called again with the continuation token to get the next set of
                 *        owned skus.
                 * @return Bundle containing the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
                 on failures.
                 *         "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
                 *         "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
                 *         "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
                 *                                      of the purchase information
                 *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
                 *                                      next set of in-app purchases. Only set if the
                 *                                      user has more owned skus than the current list.
                 */
                @Override public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        _data.writeString(continuationToken);
                        mRemote.transact(Stub.TRANSACTION_getPurchases, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                @Override public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    int _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(purchaseToken);
                        mRemote.transact(Stub.TRANSACTION_consumePurchase, _data, _reply, 0);
                        _reply.readException();
                        _result = _reply.readInt();
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                @Override public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    int _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        mRemote.transact(Stub.TRANSACTION_stub, _data, _reply, 0);
                        _reply.readException();
                        _result = _reply.readInt();
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Returns a pending intent to launch the purchase flow for upgrading or downgrading a
                 * subscription. The existing owned SKU(s) should be provided along with the new SKU that
                 * the user is upgrading or downgrading to.
                 * @param apiVersion billing API version that the app is using, must be 5 or later
                 * @param packageName package name of the calling app
                 * @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
                 *        if null or empty this method will behave like {@link #getBuyIntent}
                 * @param newSku the SKU that the user is upgrading or downgrading to
                 * @param type of the item being purchased, currently must be "subs"
                 * @param developerPayload optional argument to be sent back with the purchase information
                 * @return Bundle containing the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
                 *                         on failures.
                 *         "BUY_INTENT" - PendingIntent to start the purchase flow
                 *
                 * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
                 * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
                 * If the purchase is successful, the result data will contain the following key-value pairs
                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
                 *                         codes on failures.
                 *         "INAPP_PURCHASE_DATA" - String in JSON format similar to
                 *                                 '{"orderId":"12999763169054705758.1371079406387615",
                 *                                   "packageName":"com.example.app",
                 *                                   "productId":"exampleSku",
                 *                                   "purchaseTime":1345678900000,
                 *                                   "purchaseToken" : "122333444455555",
                 *                                   "developerPayload":"example developer payload" }'
                 *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
                 *                                  was signed with the private key of the developer
                 */
                @Override public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeStringList(oldSkus);
                        _data.writeString(newSku);
                        _data.writeString(type);
                        _data.writeString(developerPayload);
                        mRemote.transact(Stub.TRANSACTION_getBuyIntentToReplaceSkus, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Returns a pending intent to launch the purchase flow for an in-app item. This method is
                 * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
                 * parameter. This parameter is a Bundle of optional keys and values that affect the
                 * operation of the method.
                 * @param apiVersion billing API version that the app is using, must be 6 or later
                 * @param packageName package name of the calling app
                 * @param sku the SKU of the in-app item as published in the developer console
                 * @param type of the in-app item being purchased ("inapp" for one-time purchases
                 *        and "subs" for subscriptions)
                 * @param developerPayload optional argument to be sent back with the purchase information
                 * @extraParams a Bundle with the following optional keys:
                 *        "skusToReplace" - List<String> - an optional list of SKUs that the user is
                 *                          upgrading or downgrading from.
                 *                          Pass this field if the purchase is upgrading or downgrading
                 *                          existing subscriptions.
                 *                          The specified SKUs are replaced with the SKUs that the user is
                 *                          purchasing. Google Play replaces the specified SKUs at the start of
                 *                          the next billing cycle.
                 * "replaceSkusProration" - Boolean - whether the user should be credited for any unused
                 *                          subscription time on the SKUs they are upgrading or downgrading.
                 *                          If you set this field to true, Google Play swaps out the old SKUs
                 *                          and credits the user with the unused value of their subscription
                 *                          time on a pro-rated basis.
                 *                          Google Play applies this credit to the new subscription, and does
                 *                          not begin billing the user for the new subscription until after
                 *                          the credit is used up.
                 *                          If you set this field to false, the user does not receive credit for
                 *                          any unused subscription time and the recurrence date does not
                 *                          change.
                 *                          Default value is true. Ignored if you do not pass skusToReplace.
                 *            "accountId" - String - an optional obfuscated string that is uniquely
                 *                          associated with the user's account in your app.
                 *                          If you pass this value, Google Play can use it to detect irregular
                 *                          activity, such as many devices making purchases on the same
                 *                          account in a short period of time.
                 *                          Do not use the developer ID or the user's Google ID for this field.
                 *                          In addition, this field should not contain the user's ID in
                 *                          cleartext.
                 *                          We recommend that you use a one-way hash to generate a string from
                 *                          the user's ID, and store the hashed string in this field.
                 *                   "vr" - Boolean - an optional flag indicating whether the returned intent
                 *                          should start a VR purchase flow. The apiVersion must also be 7 or
                 *                          later to use this flag.
                 */
                @Override public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(sku);
                        _data.writeString(type);
                        _data.writeString(developerPayload);
                        if ((extraParams!=null)) {
                            _data.writeInt(1);
                            extraParams.writeToParcel(_data, 0);
                        }
                        else {
                            _data.writeInt(0);
                        }
                        mRemote.transact(Stub.TRANSACTION_getBuyIntentExtraParams, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                /**
                 * Returns the most recent purchase made by the user for each SKU, even if that purchase is
                 * expired, canceled, or consumed.
                 * @param apiVersion billing API version that the app is using, must be 6 or later
                 * @param packageName package name of the calling app
                 * @param type of the in-app items being requested ("inapp" for one-time purchases
                 *        and "subs" for subscriptions)
                 * @param continuationToken to be set as null for the first call, if the number of owned
                 *        skus is too large, a continuationToken is returned in the response bundle.
                 *        This method can be called again with the continuation token to get the next set of
                 *        owned skus.
                 * @param extraParams a Bundle with extra params that would be appended into http request
                 *        query string. Not used at this moment. Reserved for future functionality.
                 * @return Bundle containing the following key-value pairs
                 *         "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
                 *         {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
                 *
                 *         "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
                 *         "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
                 *         "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
                 *                                      of the purchase information
                 *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
                 *                                      next set of in-app purchases. Only set if the
                 *                                      user has more owned skus than the current list.
                 */
                @Override public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    android.os.Bundle _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        _data.writeString(continuationToken);
                        if ((extraParams!=null)) {
                            _data.writeInt(1);
                            extraParams.writeToParcel(_data, 0);
                        }
                        else {
                            _data.writeInt(0);
                        }
                        mRemote.transact(Stub.TRANSACTION_getPurchaseHistory, _data, _reply, 0);
                        _reply.readException();
                        if ((0!=_reply.readInt())) {
                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);
                        }
                        else {
                            _result = null;
                        }
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
                @Override public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException
                {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    int _result;
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeInt(apiVersion);
                        _data.writeString(packageName);
                        _data.writeString(type);
                        if ((extraParams!=null)) {
                            _data.writeInt(1);
                            extraParams.writeToParcel(_data, 0);
                        }
                        else {
                            _data.writeInt(0);
                        }
                        mRemote.transact(Stub.TRANSACTION_isBillingSupportedExtraParams, _data, _reply, 0);
                        _reply.readException();
                        _result = _reply.readInt();
                    }
                    finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                    return _result;
                }
            }
            static final int TRANSACTION_isBillingSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
            static final int TRANSACTION_getSkuDetails = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
            static final int TRANSACTION_getBuyIntent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
            static final int TRANSACTION_getPurchases = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
            static final int TRANSACTION_consumePurchase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
            static final int TRANSACTION_stub = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
            static final int TRANSACTION_getBuyIntentToReplaceSkus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
            static final int TRANSACTION_getBuyIntentExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
            static final int TRANSACTION_getPurchaseHistory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
            static final int TRANSACTION_isBillingSupportedExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
        }
        public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;
        /**
         * Provides details of a list of SKUs
         * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
         * with a list JSON strings containing the productId, price, title and description.
         * This API can be called with a maximum of 20 SKUs.
         * @param apiVersion billing API version that the app is using
         * @param packageName the package name of the calling app
         * @param type of the in-app items ("inapp" for one-time purchases
         *        and "subs" for subscriptions)
         * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
         * @return Bundle containing the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
         *                         on failures.
         *         "DETAILS_LIST" with a StringArrayList containing purchase information
         *                        in JSON format similar to:
         *                        '{ "productId" : "exampleSku",
         *                           "type" : "inapp",
         *                           "price" : "$5.00",
         *                           "price_currency": "USD",
         *                           "price_amount_micros": 5000000,
         *                           "title : "Example Title",
         *                           "description" : "This is an example description" }'
         */
        public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException;
        /**
         * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
         * the type, a unique purchase token and an optional developer payload.
         * @param apiVersion billing API version that the app is using
         * @param packageName package name of the calling app
         * @param sku the SKU of the in-app item as published in the developer console
         * @param type of the in-app item being purchased ("inapp" for one-time purchases
         *        and "subs" for subscriptions)
         * @param developerPayload optional argument to be sent back with the purchase information
         * @return Bundle containing the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
         *                         on failures.
         *         "BUY_INTENT" - PendingIntent to start the purchase flow
         *
         * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
         * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
         * If the purchase is successful, the result data will contain the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
         *                         codes on failures.
         *         "INAPP_PURCHASE_DATA" - String in JSON format similar to
         *                                 '{"orderId":"12999763169054705758.1371079406387615",
         *                                   "packageName":"com.example.app",
         *                                   "productId":"exampleSku",
         *                                   "purchaseTime":1345678900000,
         *                                   "purchaseToken" : "122333444455555",
         *                                   "developerPayload":"example developer payload" }'
         *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
         *                                  was signed with the private key of the developer
         */
        public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException;
        /**
         * Returns the current SKUs owned by the user of the type and package name specified along with
         * purchase information and a signature of the data to be validated.
         * This will return all SKUs that have been purchased in V3 and managed items purchased using
         * V1 and V2 that have not been consumed.
         * @param apiVersion billing API version that the app is using
         * @param packageName package name of the calling app
         * @param type of the in-app items being requested ("inapp" for one-time purchases
         *        and "subs" for subscriptions)
         * @param continuationToken to be set as null for the first call, if the number of owned
         *        skus are too many, a continuationToken is returned in the response bundle.
         *        This method can be called again with the continuation token to get the next set of
         *        owned skus.
         * @return Bundle containing the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
         on failures.
         *         "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
         *         "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
         *         "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
         *                                      of the purchase information
         *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
         *                                      next set of in-app purchases. Only set if the
         *                                      user has more owned skus than the current list.
         */
        public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException;
        public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException;
        public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;
        /**
         * Returns a pending intent to launch the purchase flow for upgrading or downgrading a
         * subscription. The existing owned SKU(s) should be provided along with the new SKU that
         * the user is upgrading or downgrading to.
         * @param apiVersion billing API version that the app is using, must be 5 or later
         * @param packageName package name of the calling app
         * @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
         *        if null or empty this method will behave like {@link #getBuyIntent}
         * @param newSku the SKU that the user is upgrading or downgrading to
         * @param type of the item being purchased, currently must be "subs"
         * @param developerPayload optional argument to be sent back with the purchase information
         * @return Bundle containing the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
         *                         on failures.
         *         "BUY_INTENT" - PendingIntent to start the purchase flow
         *
         * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
         * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
         * If the purchase is successful, the result data will contain the following key-value pairs
         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
         *                         codes on failures.
         *         "INAPP_PURCHASE_DATA" - String in JSON format similar to
         *                                 '{"orderId":"12999763169054705758.1371079406387615",
         *                                   "packageName":"com.example.app",
         *                                   "productId":"exampleSku",
         *                                   "purchaseTime":1345678900000,
         *                                   "purchaseToken" : "122333444455555",
         *                                   "developerPayload":"example developer payload" }'
         *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
         *                                  was signed with the private key of the developer
         */
        public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException;
        /**
         * Returns a pending intent to launch the purchase flow for an in-app item. This method is
         * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
         * parameter. This parameter is a Bundle of optional keys and values that affect the
         * operation of the method.
         * @param apiVersion billing API version that the app is using, must be 6 or later
         * @param packageName package name of the calling app
         * @param sku the SKU of the in-app item as published in the developer console
         * @param type of the in-app item being purchased ("inapp" for one-time purchases
         *        and "subs" for subscriptions)
         * @param developerPayload optional argument to be sent back with the purchase information
         * @extraParams a Bundle with the following optional keys:
         *        "skusToReplace" - List<String> - an optional list of SKUs that the user is
         *                          upgrading or downgrading from.
         *                          Pass this field if the purchase is upgrading or downgrading
         *                          existing subscriptions.
         *                          The specified SKUs are replaced with the SKUs that the user is
         *                          purchasing. Google Play replaces the specified SKUs at the start of
         *                          the next billing cycle.
         * "replaceSkusProration" - Boolean - whether the user should be credited for any unused
         *                          subscription time on the SKUs they are upgrading or downgrading.
         *                          If you set this field to true, Google Play swaps out the old SKUs
         *                          and credits the user with the unused value of their subscription
         *                          time on a pro-rated basis.
         *                          Google Play applies this credit to the new subscription, and does
         *                          not begin billing the user for the new subscription until after
         *                          the credit is used up.
         *                          If you set this field to false, the user does not receive credit for
         *                          any unused subscription time and the recurrence date does not
         *                          change.
         *                          Default value is true. Ignored if you do not pass skusToReplace.
         *            "accountId" - String - an optional obfuscated string that is uniquely
         *                          associated with the user's account in your app.
         *                          If you pass this value, Google Play can use it to detect irregular
         *                          activity, such as many devices making purchases on the same
         *                          account in a short period of time.
         *                          Do not use the developer ID or the user's Google ID for this field.
         *                          In addition, this field should not contain the user's ID in
         *                          cleartext.
         *                          We recommend that you use a one-way hash to generate a string from
         *                          the user's ID, and store the hashed string in this field.
         *                   "vr" - Boolean - an optional flag indicating whether the returned intent
         *                          should start a VR purchase flow. The apiVersion must also be 7 or
         *                          later to use this flag.
         */
        public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException;
        /**
         * Returns the most recent purchase made by the user for each SKU, even if that purchase is
         * expired, canceled, or consumed.
         * @param apiVersion billing API version that the app is using, must be 6 or later
         * @param packageName package name of the calling app
         * @param type of the in-app items being requested ("inapp" for one-time purchases
         *        and "subs" for subscriptions)
         * @param continuationToken to be set as null for the first call, if the number of owned
         *        skus is too large, a continuationToken is returned in the response bundle.
         *        This method can be called again with the continuation token to get the next set of
         *        owned skus.
         * @param extraParams a Bundle with extra params that would be appended into http request
         *        query string. Not used at this moment. Reserved for future functionality.
         * @return Bundle containing the following key-value pairs
         *         "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
         *         {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
         *
         *         "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
         *         "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
         *         "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
         *                                      of the purchase information
         *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
         *                                      next set of in-app purchases. Only set if the
         *                                      user has more owned skus than the current list.
         */
        public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException;
        public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException;
    }


text:
package com.juce;

import com.google.firebase.messaging.*;

public final class JuceFirebaseMessagingService extends FirebaseMessagingService
{
    private native void firebaseRemoteMessageReceived (RemoteMessage message);
    private native void firebaseRemoteMessagesDeleted();
    private native void firebaseRemoteMessageSent (String messageId);
    private native void firebaseRemoteMessageSendError (String messageId, String error);

    @Override
    public void onMessageReceived (RemoteMessage message)
    {
        firebaseRemoteMessageReceived (message);
    }

    @Override
    public void onDeletedMessages()
    {
        firebaseRemoteMessagesDeleted();
    }

    @Override
    public void onMessageSent (String messageId)
    {
        firebaseRemoteMessageSent (messageId);
    }

    @Override
    public void onSendError (String messageId, Exception e)
    {
        firebaseRemoteMessageSendError (messageId, e.toString());
    }
}

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    A simple implementation of a Logger that writes to a file.

    @see Logger
*/
class JUCE_API  FileLogger  : public Logger
{
public:
    //==============================================================================
    /** Creates a FileLogger for a given file.

        @param fileToWriteTo    the file that to use - new messages will be appended
                                to the file. If the file doesn't exist, it will be created,
                                along with any parent directories that are needed.
        @param welcomeMessage   when opened, the logger will write a header to the log, along
                                with the current date and time, and this welcome message
        @param maxInitialFileSizeBytes  if this is zero or greater, then if the file already exists
                                but is larger than this number of bytes, then the start of the
                                file will be truncated to keep the size down. This prevents a log
                                file getting ridiculously large over time. The file will be truncated
                                at a new-line boundary. If this value is less than zero, no size limit
                                will be imposed; if it's zero, the file will always be deleted. Note that
                                the size is only checked once when this object is created - any logging
                                that is done later will be appended without any checking
    */
    FileLogger (const File& fileToWriteTo,
                const String& welcomeMessage,
                const int64 maxInitialFileSizeBytes = 128 * 1024);

    /** Destructor. */
    ~FileLogger();

    //==============================================================================
    /** Returns the file that this logger is writing to. */
    const File& getLogFile() const noexcept               { return logFile; }

    //==============================================================================
    /** Helper function to create a log file in the correct place for this platform.

        The method might return nullptr if the file can't be created for some reason.

        @param logFileSubDirectoryName      the name of the subdirectory to create inside the logs folder (as
                                            returned by getSystemLogFileFolder). It's best to use something
                                            like the name of your application here.
        @param logFileName                  the name of the file to create, e.g. "MyAppLog.txt".
        @param welcomeMessage               a message that will be written to the log when it's opened.
        @param maxInitialFileSizeBytes      (see the FileLogger constructor for more info on this)
    */
    static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName,
                                               const String& logFileName,
                                               const String& welcomeMessage,
                                               const int64 maxInitialFileSizeBytes = 128 * 1024);

    /** Helper function to create a log file in the correct place for this platform.

        The filename used is based on the root and suffix strings provided, along with a
        time and date string, meaning that a new, empty log file will be always be created
        rather than appending to an exising one.

        The method might return nullptr if the file can't be created for some reason.

        @param logFileSubDirectoryName      the name of the subdirectory to create inside the logs folder (as
                                            returned by getSystemLogFileFolder). It's best to use something
                                            like the name of your application here.
        @param logFileNameRoot              the start of the filename to use, e.g. "MyAppLog_". This will have
                                            a timestamp and the logFileNameSuffix appended to it
        @param logFileNameSuffix            the file suffix to use, e.g. ".txt"
        @param welcomeMessage               a message that will be written to the log when it's opened.
    */
    static FileLogger* createDateStampedLogger (const String& logFileSubDirectoryName,
                                                const String& logFileNameRoot,
                                                const String& logFileNameSuffix,
                                                const String& welcomeMessage);

    //==============================================================================
    /** Returns an OS-specific folder where log-files should be stored.

        On Windows this will return a logger with a path such as:
        c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName]

        On the Mac it'll create something like:
        ~/Library/Logs/[logFileSubDirectoryName]/[logFileName]

        @see createDefaultAppLogger
    */
    static File getSystemLogFileFolder();

    // (implementation of the Logger virtual method)
    void logMessage (const String&);

    //==============================================================================
    /** This is a utility function which removes lines from the start of a text
        file to make sure that its total size is below the given size.
    */
    static void trimFileSize (const File& file, int64 maxFileSize);

private:
    //==============================================================================
    File logFile;
    CriticalSection logLock;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger)
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

Logger::Logger() {}

Logger::~Logger()
{
    // You're deleting this logger while it's still being used!
    // Always call Logger::setCurrentLogger (nullptr) before deleting the active logger.
    jassert (currentLogger != this);
}

Logger* Logger::currentLogger = nullptr;

void Logger::setCurrentLogger (Logger* const newLogger) noexcept    { currentLogger = newLogger; }
Logger* Logger::getCurrentLogger()  noexcept                        { return currentLogger; }

void Logger::writeToLog (const String& message)
{
    if (currentLogger != nullptr)
        currentLogger->logMessage (message);
    else
        outputDebugString (message);
}

#if JUCE_LOG_ASSERTIONS || JUCE_DEBUG
void JUCE_API JUCE_CALLTYPE logAssertion (const char* const filename, const int lineNum) noexcept
{
    String m ("JUCE Assertion failure in ");
    m << File::createFileWithoutCheckingPath (filename).getFileName() << ':' << lineNum;

   #if JUCE_LOG_ASSERTIONS
    Logger::writeToLog (m);
   #else
    DBG (m);
   #endif
}
#endif

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Acts as an application-wide logging class.

    A subclass of Logger can be created and passed into the Logger::setCurrentLogger
    method and this will then be used by all calls to writeToLog.

    The logger class also contains methods for writing messages to the debugger's
    output stream.

    @see FileLogger
*/
class JUCE_API  Logger
{
public:
    //==============================================================================
    /** Destructor. */
    virtual ~Logger();

    //==============================================================================
    /** Sets the current logging class to use.

        Note that the object passed in will not be owned or deleted by the logger, so
        the caller must make sure that it is not deleted while still being used.
        A null pointer can be passed-in to reset the system to the default logger.
    */
    static void JUCE_CALLTYPE setCurrentLogger (Logger* newLogger) noexcept;

    /** Returns the current logger, or nullptr if no custom logger has been set. */
    static Logger* JUCE_CALLTYPE getCurrentLogger() noexcept;

    /** Writes a string to the current logger.

        This will pass the string to the logger's logMessage() method if a logger
        has been set.

        @see logMessage
    */
    static void JUCE_CALLTYPE writeToLog (const String& message);

    //==============================================================================
    /** Writes a message to the standard error stream.

        This can be called directly, or by using the DBG() macro in
        juce_PlatformDefs.h (which will avoid calling the method in non-debug builds).
    */
    static void JUCE_CALLTYPE outputDebugString (const String& text);

protected:
    //==============================================================================
    Logger();

    /** This is overloaded by subclasses to implement custom logging behaviour.
        @see setCurrentLogger
    */
    virtual void logMessage (const String& message) = 0;

private:
    static Logger* currentLogger;
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

FileLogger::FileLogger (const File& file,
                        const String& welcomeMessage,
                        const int64 maxInitialFileSizeBytes)
    : logFile (file)
{
    if (maxInitialFileSizeBytes >= 0)
        trimFileSize (logFile, maxInitialFileSizeBytes);

    if (! file.exists())
        file.create();  // (to create the parent directories)

    String welcome;
    welcome << newLine
            << "**********************************************************" << newLine
            << welcomeMessage << newLine
            << "Log started: " << Time::getCurrentTime().toString (true, true) << newLine;

    FileLogger::logMessage (welcome);
}

FileLogger::~FileLogger() {}

//==============================================================================
void FileLogger::logMessage (const String& message)
{
    const ScopedLock sl (logLock);
    DBG (message);
    FileOutputStream out (logFile, 256);
    out << message << newLine;
}

void FileLogger::trimFileSize (const File& file, int64 maxFileSizeBytes)
{
    if (maxFileSizeBytes <= 0)
    {
        file.deleteFile();
    }
    else
    {
        const int64 fileSize = file.getSize();

        if (fileSize > maxFileSizeBytes)
        {
            TemporaryFile tempFile (file);

            {
                FileOutputStream out (tempFile.getFile());
                FileInputStream in (file);

                if (! (out.openedOk() && in.openedOk()))
                    return;

                in.setPosition (fileSize - maxFileSizeBytes);

                for (;;)
                {
                    const char c = in.readByte();
                    if (c == 0)
                        return;

                    if (c == '\n' || c == '\r')
                    {
                        out << c;
                        break;
                    }
                }

                out.writeFromInputStream (in, -1);
            }

            tempFile.overwriteTargetFileWithTemporary();
        }
    }
}

//==============================================================================
File FileLogger::getSystemLogFileFolder()
{
   #if JUCE_MAC
    return File ("~/Library/Logs");
   #else
    return File::getSpecialLocation (File::userApplicationDataDirectory);
   #endif
}

FileLogger* FileLogger::createDefaultAppLogger (const String& logFileSubDirectoryName,
                                                const String& logFileName,
                                                const String& welcomeMessage,
                                                const int64 maxInitialFileSizeBytes)
{
    return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName)
                                                   .getChildFile (logFileName),
                           welcomeMessage, maxInitialFileSizeBytes);
}

FileLogger* FileLogger::createDateStampedLogger (const String& logFileSubDirectoryName,
                                                 const String& logFileNameRoot,
                                                 const String& logFileNameSuffix,
                                                 const String& welcomeMessage)
{
    return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName)
                                                   .getChildFile (logFileNameRoot + Time::getCurrentTime().formatted ("%Y-%m-%d_%H-%M-%S"))
                                                   .withFileExtension (logFileNameSuffix)
                                                   .getNonexistentSibling(),
                           welcomeMessage, 0);
}

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Used to convert strings to localised foreign-language versions.

    This is basically a look-up table of strings and their translated equivalents.
    It can be loaded from a text file, so that you can supply a set of localised
    versions of strings that you use in your app.

    To use it in your code, simply call the translate() method on each string that
    might have foreign versions, and if none is found, the method will just return
    the original string.

    The translation file should start with some lines specifying a description of
    the language it contains, and also a list of ISO country codes where it might
    be appropriate to use the file. After that, each line of the file should contain
    a pair of quoted strings with an '=' sign.

    E.g. for a french translation, the file might be:

    @code
    language: French
    countries: fr be mc ch lu

    "hello" = "bonjour"
    "goodbye" = "au revoir"
    @endcode

    If the strings need to contain a quote character, they can use '\"' instead, and
    if the first non-whitespace character on a line isn't a quote, then it's ignored,
    (you can use this to add comments).

    Note that this is a singleton class, so don't create or destroy the object directly.
    There's also a TRANS(text) macro defined to make it easy to use the this.

    E.g. @code
    printSomething (TRANS("hello"));
    @endcode

    This macro is used in the Juce classes themselves, so your application has a chance to
    intercept and translate any internal Juce text strings that might be shown. (You can easily
    get a list of all the messages by searching for the TRANS() macro in the Juce source
    code).
*/
class JUCE_API  LocalisedStrings
{
public:
    //==============================================================================
    /** Creates a set of translations from the text of a translation file.

        When you create one of these, you can call setCurrentMappings() to make it
        the set of mappings that the system's using.
    */
    LocalisedStrings (const String& fileContents, bool ignoreCaseOfKeys);

    /** Creates a set of translations from a file.

        When you create one of these, you can call setCurrentMappings() to make it
        the set of mappings that the system's using.
    */
    LocalisedStrings (const File& fileToLoad, bool ignoreCaseOfKeys);

    LocalisedStrings (const LocalisedStrings&);
    LocalisedStrings& operator= (const LocalisedStrings&);

    /** Destructor. */
    ~LocalisedStrings();

    //==============================================================================
    /** Selects the current set of mappings to be used by the system.

        The object you pass in will be automatically deleted when no longer needed, so
        don't keep a pointer to it. You can also pass in nullptr to remove the current
        mappings.

        See also the TRANS() macro, which uses the current set to do its translation.

        @see translateWithCurrentMappings
    */
    static void setCurrentMappings (LocalisedStrings* newTranslations);

    /** Returns the currently selected set of mappings.

        This is the object that was last passed to setCurrentMappings(). It may
        be nullptr if none has been created.
    */
    static LocalisedStrings* getCurrentMappings();

    /** Tries to translate a string using the currently selected set of mappings.

        If no mapping has been set, or if the mapping doesn't contain a translation
        for the string, this will just return the original string.

        See also the TRANS() macro, which uses this method to do its translation.

        @see setCurrentMappings, getCurrentMappings
    */
    static String translateWithCurrentMappings (const String& text);

    /** Tries to translate a string using the currently selected set of mappings.

        If no mapping has been set, or if the mapping doesn't contain a translation
        for the string, this will just return the original string.

        See also the TRANS() macro, which uses this method to do its translation.

        @see setCurrentMappings, getCurrentMappings
    */
    static String translateWithCurrentMappings (const char* text);

    //==============================================================================
    /** Attempts to look up a string and return its localised version.
        If the string isn't found in the list, the original string will be returned.
    */
    String translate (const String& text) const;

    /** Attempts to look up a string and return its localised version.
        If the string isn't found in the list, the resultIfNotFound string will be returned.
    */
    String translate (const String& text, const String& resultIfNotFound) const;

    /** Returns the name of the language specified in the translation file.

        This is specified in the file using a line starting with "language:", e.g.
        @code
        language: german
        @endcode
    */
    String getLanguageName() const                        { return languageName; }

    /** Returns the list of suitable country codes listed in the translation file.

        These is specified in the file using a line starting with "countries:", e.g.
        @code
        countries: fr be mc ch lu
        @endcode

        The country codes are supposed to be 2-character ISO complient codes.
    */
    const StringArray& getCountryCodes() const            { return countryCodes; }

    /** Provides access to the actual list of mappings. */
    const StringPairArray& getMappings() const            { return translations; }

    //==============================================================================
    /** Adds and merges another set of translations into this set.

        Note that the language name and country codes of the new LocalisedStrings
        object must match that of this object - an assertion will be thrown if they
        don't match.

        Any existing values will have their mappings overwritten by the new ones.
    */
    void addStrings (const LocalisedStrings&);

    /** Gives this object a set of strings to use as a fallback if a string isn't found.
        The object that is passed-in will be owned and deleted by this object
        when no longer needed. It can be nullptr to clear the existing fallback object.
    */
    void setFallback (LocalisedStrings* fallbackStrings);

private:
    //==============================================================================
    String languageName;
    StringArray countryCodes;
    StringPairArray translations;
    ScopedPointer<LocalisedStrings> fallback;
    friend struct ContainerDeletePolicy<LocalisedStrings>;

    void loadFromText (const String&, bool ignoreCase);

    JUCE_LEAK_DETECTOR (LocalisedStrings)
};

//==============================================================================
#ifndef TRANS
 /** Uses the LocalisedStrings class to translate the given string literal.
     This macro is provided for backwards-compatibility, and just calls the translate()
     function. In new code, it's recommended that you just call translate() directly
     instead, and avoid using macros.
     @see translate(), LocalisedStrings
 */
 #define TRANS(stringLiteral) juce::translate (stringLiteral)
#endif

/** A dummy version of the TRANS macro, used to indicate a string literal that should be
    added to the translation file by source-code scanner tools.

    Wrapping a string literal in this macro has no effect, but by using it around strings
    that your app needs to translate at a later stage, it lets automatic code-scanning tools
    find this string and add it to the list of strings that need translation.
*/
#define NEEDS_TRANS(stringLiteral) (stringLiteral)

/** Uses the LocalisedStrings class to translate the given string literal.
    @see LocalisedStrings
*/
JUCE_API String translate (const String& stringLiteral);

/** Uses the LocalisedStrings class to translate the given string literal.
    @see LocalisedStrings
*/
JUCE_API String translate (const char* stringLiteral);

/** Uses the LocalisedStrings class to translate the given string literal.
    @see LocalisedStrings
*/
JUCE_API String translate (CharPointer_UTF8 stringLiteral);

/** Uses the LocalisedStrings class to translate the given string literal.
    @see LocalisedStrings
*/
JUCE_API String translate (const String& stringLiteral, const String& resultIfNotFound);

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    A StringPool holds a set of shared strings, which reduces storage overheads and improves
    comparison speed when dealing with many duplicate strings.

    When you add a string to a pool using getPooledString, it'll return a character
    array containing the same string. This array is owned by the pool, and the same array
    is returned every time a matching string is asked for. This means that it's trivial to
    compare two pooled strings for equality, as you can simply compare their pointers. It
    also cuts down on storage if you're using many copies of the same string.
*/
class JUCE_API  StringPool
{
public:
    //==============================================================================
    /** Creates an empty pool. */
    StringPool() noexcept;

    /** Destructor */
    ~StringPool();

    //==============================================================================
    /** Returns a pointer to a shared copy of the string that is passed in.
        The pool will always return the same String object when asked for a string that matches it.
    */
    String getPooledString (const String& original);

    /** Returns a pointer to a copy of the string that is passed in.
        The pool will always return the same String object when asked for a string that matches it.
    */
    String getPooledString (const char* original);

    /** Returns a pointer to a shared copy of the string that is passed in.
        The pool will always return the same String object when asked for a string that matches it.
    */
    String getPooledString (StringRef original);

    /** Returns a pointer to a copy of the string that is passed in.
        The pool will always return the same String object when asked for a string that matches it.
    */
    String getPooledString (String::CharPointerType start, String::CharPointerType end);

    //==============================================================================
    /** Scans the pool, and removes any strings that are unreferenced.
        You don't generally need to call this - it'll be called automatically when the pool grows
        large enough to warrant it.
    */
    void garbageCollect();

    /** Returns a shared global pool which is used for things like Identifiers, XML parsing. */
    static StringPool& getGlobalPool() noexcept;

private:
    Array<String> strings;
    CriticalSection lock;
    uint32 lastGarbageCollectionTime;

    void garbageCollectIfNeeded();

    JUCE_DECLARE_NON_COPYABLE (StringPool)
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/** This class is used for represent a new-line character sequence.

    To write a new-line to a stream, you can use the predefined 'newLine' variable, e.g.
    @code
    myOutputStream << "Hello World" << newLine << newLine;
    @endcode

    The exact character sequence that will be used for the new-line can be set and
    retrieved with OutputStream::setNewLineString() and OutputStream::getNewLineString().
*/
class JUCE_API  NewLine
{
public:
    /** Returns the default new-line sequence that the library uses.
        @see OutputStream::setNewLineString()
    */
    static const char* getDefault() noexcept        { return "\r\n"; }

    /** Returns the default new-line sequence that the library uses.
        @see getDefault()
    */
    operator String() const                         { return getDefault(); }

    /** Returns the default new-line sequence that the library uses.
        @see OutputStream::setNewLineString()
    */
    operator StringRef() const noexcept             { return getDefault(); }
};

//==============================================================================
/** A predefined object representing a new-line, which can be written to a string or stream.

    To write a new-line to a stream, you can use the predefined 'newLine' variable like this:
    @code
    myOutputStream << "Hello World" << newLine << newLine;
    @endcode
*/
extern NewLine newLine;

//==============================================================================
/** Writes a new-line sequence to a string.
    You can use the predefined object 'newLine' to invoke this, e.g.
    @code
    myString << "Hello World" << newLine << newLine;
    @endcode
*/
inline String& operator<< (String& string1, const NewLine&) { return string1 += NewLine::getDefault(); }
inline String& operator+= (String& s1, const NewLine&)      { return s1 += NewLine::getDefault(); }

inline String operator+ (const NewLine&, const NewLine&)    { return String (NewLine::getDefault()) + NewLine::getDefault(); }
inline String operator+ (String s1, const NewLine&)         { return s1 += NewLine::getDefault(); }
inline String operator+ (const NewLine&, const char* s2)    { return String (NewLine::getDefault()) + s2; }

} // namespace juce