<commit_before>/*
   This file is part of the clang-lazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "checkmanager.h"
#include "detachingtemporary.h"
#include "Utils.h"
#include "StringUtils.h"

#include <clang/AST/DeclCXX.h>
#include <clang/AST/Expr.h>
#include <clang/AST/ExprCXX.h>

using namespace clang;
using namespace std;

DetachingTemporary::DetachingTemporary(const std::string &name)
    : DetachingBase(name)
{
    // Extra stuff that isn't really related to detachments but doesn't make sense to call on temporaries
    m_writeMethodsByType["QString"] = {"push_back", "push_front", "clear", "chop"};
    m_writeMethodsByType["QList"] = {"takeAt", "takeFirst", "takeLast", "removeOne", "removeAll", "erase"};
    m_writeMethodsByType["QVector"] = { "fill", "insert"};
    m_writeMethodsByType["QMap"] = { "erase", "insert", "insertMulti", "remove", "take", "unite" };
    m_writeMethodsByType["QHash"] = { "erase", "insert", "insertMulti", "remove", "take", "unite"};
    m_writeMethodsByType["QMultiHash"] = m_writeMethodsByType["QHash"];
    m_writeMethodsByType["QMultiMap"] = m_writeMethodsByType["QMap"];
    m_writeMethodsByType["QLinkedList"] = {"takeFirst", "takeLast", "removeOne", "removeAll", "erase"};
    m_writeMethodsByType["QSet"] = {"erase", "insert", "intersect", "unite", "subtract"};
    m_writeMethodsByType["QStack"] = {"push", "swap"};
    m_writeMethodsByType["QQueue"] = {"enqueue", "swap"};
    m_writeMethodsByType["QListSpecialMethods"] = {"sort", "replaceInStrings", "removeDuplicates"};
    m_writeMethodsByType["QStringList"] = m_writeMethodsByType["QListSpecialMethods"];
}

bool isAllowedChainedClass(const std::string &className)
{
    static const vector<string> allowed = {"QString", "QByteArray", "QVariant"};
    return find(allowed.cbegin(), allowed.cend(), className) != allowed.cend();
}

bool isAllowedChainedMethod(const std::string &methodName)
{
    static const vector<string> allowed = {"QMap::keys", "QMap::values", "QHash::keys", "QMap::values",
                                           "QApplication::topLevelWidgets", "QAbstractItemView::selectedIndexes",
                                           "QListWidget::selectedItems", "QFile::encodeName", "QFile::decodeName",
                                           "QItemSelectionModel::selectedRows", "QTreeWidget::selectedItems",
                                           "QTableWidget::selectedItems", "QNetworkReply::rawHeaderList",
                                           "Mailbox::address", "QItemSelection::indexes", "QItemSelectionModel::selectedIndexes",
                                           "QMimeData::formats", "i18n"};
    return find(allowed.cbegin(), allowed.cend(), methodName) != allowed.cend();
}

void DetachingTemporary::VisitStmt(clang::Stmt *stm)
{
    CallExpr *callExpr = dyn_cast<CallExpr>(stm);
    if (!callExpr)
        return;

    // For a chain like getList().first(), returns {first(), getList()}
    vector<CallExpr *> callExprs = Utils::callListForChain(callExpr);
    if (callExprs.size() < 2)
        return;

    CallExpr *firstCallToBeEvaluated = callExprs.at(callExprs.size() - 1); // This is the call to getList()
    FunctionDecl *firstFunc = firstCallToBeEvaluated->getDirectCallee();
    if (!firstFunc)
        return;

    QualType qt = firstFunc->getReturnType();
    const Type *firstFuncReturnType = qt.getTypePtrOrNull();
    if (!firstFuncReturnType)
        return;

    if (firstFuncReturnType->isReferenceType() || firstFuncReturnType->isPointerType())
        return;

    if (qt.isConstQualified()) {
        return; // const doesn't detach
    }

    CXXMethodDecl *firstMethod = dyn_cast<CXXMethodDecl>(firstFunc);
    if (isAllowedChainedMethod(StringUtils::qualifiedMethodName(firstFunc))) {
        return;
    }

    if (firstMethod && isAllowedChainedClass(firstMethod->getParent()->getNameAsString())) {
        return;
    }

    // Check if this is a QGlobalStatic
    if (firstMethod && firstMethod->getParent()->getNameAsString() == "QGlobalStatic") {
        return;
    }

    CallExpr *secondCallToBeEvaluated = callExprs.at(callExprs.size() - 2); // This is the call to first()
    FunctionDecl *detachingFunc = secondCallToBeEvaluated->getDirectCallee();
    CXXMethodDecl *detachingMethod = detachingFunc ? dyn_cast<CXXMethodDecl>(detachingFunc) : nullptr;
    const Type *detachingMethodReturnType = detachingMethod ? detachingMethod->getReturnType().getTypePtrOrNull() : nullptr;
    if (!detachingMethod || !detachingMethodReturnType)
        return;

    // Check if it's one of the implicit shared classes
    CXXRecordDecl *classDecl = detachingMethod->getParent();
    const std::string className = classDecl->getNameAsString();

    auto it = m_methodsByType.find(className);
    auto it2 = m_writeMethodsByType.find(className);

    std::vector<std::string> allowedFunctions;
    std::vector<std::string> allowedWriteFunctions;
    if (it != m_methodsByType.end()) {
        allowedFunctions = it->second;
    }

    if (it2 != m_writeMethodsByType.end()) {
        allowedWriteFunctions = it2->second;
    }

    // Check if it's one of the detaching methods
    const std::string functionName = detachingMethod->getNameAsString();

    string error;

    const bool isReadFunction = std::find(allowedFunctions.cbegin(), allowedFunctions.cend(), functionName) != allowedFunctions.cend();
    const bool isWriteFunction = std::find(allowedWriteFunctions.cbegin(), allowedWriteFunctions.cend(), functionName) != allowedWriteFunctions.cend();

    if (isReadFunction || isWriteFunction) {

        bool returnTypeIsIterator = false;
        CXXRecordDecl *returnRecord = detachingMethodReturnType->getAsCXXRecordDecl();
        if (returnRecord) {
            returnTypeIsIterator = returnRecord->getNameAsString() == "iterator";
        }

        if (isWriteFunction && (detachingMethodReturnType->isVoidType() || returnTypeIsIterator)) {
            error = std::string("Modifying temporary container is pointless and it also detaches");
        } else {
            error = std::string("Don't call ") + StringUtils::qualifiedMethodName(detachingMethod) + std::string("() on temporary");
        }
    }

    if (!error.empty())
        emitWarning(stm->getLocStart(), error.c_str());
}

bool DetachingTemporary::isDetachingMethod(CXXMethodDecl *method) const
{
    if (!method)
        return false;

    CXXRecordDecl *record = method->getParent();
    if (!record)
        return false;

    if (DetachingBase::isDetachingMethod(method))
        return true;

    const string className = record->getNameAsString();

    auto it = m_writeMethodsByType.find(className);
    if (it != m_writeMethodsByType.cend()) {
        const auto &methods = it->second;
        auto it2 = find(methods.cbegin(), methods.cend(), method->getNameAsString());
        if (it2 != methods.cend())
            return true;
    }

    return false;
}

REGISTER_CHECK_WITH_FLAGS("detaching-temporary", DetachingTemporary, CheckLevel1)
<commit_msg>detaching-temporary: Blacklist++<commit_after>/*
   This file is part of the clang-lazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "checkmanager.h"
#include "detachingtemporary.h"
#include "Utils.h"
#include "StringUtils.h"

#include <clang/AST/DeclCXX.h>
#include <clang/AST/Expr.h>
#include <clang/AST/ExprCXX.h>

using namespace clang;
using namespace std;

DetachingTemporary::DetachingTemporary(const std::string &name)
    : DetachingBase(name)
{
    // Extra stuff that isn't really related to detachments but doesn't make sense to call on temporaries
    m_writeMethodsByType["QString"] = {"push_back", "push_front", "clear", "chop"};
    m_writeMethodsByType["QList"] = {"takeAt", "takeFirst", "takeLast", "removeOne", "removeAll", "erase"};
    m_writeMethodsByType["QVector"] = { "fill", "insert"};
    m_writeMethodsByType["QMap"] = { "erase", "insert", "insertMulti", "remove", "take", "unite" };
    m_writeMethodsByType["QHash"] = { "erase", "insert", "insertMulti", "remove", "take", "unite"};
    m_writeMethodsByType["QMultiHash"] = m_writeMethodsByType["QHash"];
    m_writeMethodsByType["QMultiMap"] = m_writeMethodsByType["QMap"];
    m_writeMethodsByType["QLinkedList"] = {"takeFirst", "takeLast", "removeOne", "removeAll", "erase"};
    m_writeMethodsByType["QSet"] = {"erase", "insert", "intersect", "unite", "subtract"};
    m_writeMethodsByType["QStack"] = {"push", "swap"};
    m_writeMethodsByType["QQueue"] = {"enqueue", "swap"};
    m_writeMethodsByType["QListSpecialMethods"] = {"sort", "replaceInStrings", "removeDuplicates"};
    m_writeMethodsByType["QStringList"] = m_writeMethodsByType["QListSpecialMethods"];
}

bool isAllowedChainedClass(const std::string &className)
{
    static const vector<string> allowed = {"QString", "QByteArray", "QVariant"};
    return find(allowed.cbegin(), allowed.cend(), className) != allowed.cend();
}

bool isAllowedChainedMethod(const std::string &methodName)
{
    static const vector<string> allowed = {"QMap::keys", "QMap::values", "QHash::keys", "QMap::values",
                                           "QApplication::topLevelWidgets", "QAbstractItemView::selectedIndexes",
                                           "QListWidget::selectedItems", "QFile::encodeName", "QFile::decodeName",
                                           "QItemSelectionModel::selectedRows", "QTreeWidget::selectedItems",
                                           "QTableWidget::selectedItems", "QNetworkReply::rawHeaderList",
                                           "Mailbox::address", "QItemSelection::indexes", "QItemSelectionModel::selectedIndexes",
                                           "QMimeData::formats", "i18n", "QAbstractTransition::targetStates"};
    return find(allowed.cbegin(), allowed.cend(), methodName) != allowed.cend();
}

void DetachingTemporary::VisitStmt(clang::Stmt *stm)
{
    CallExpr *callExpr = dyn_cast<CallExpr>(stm);
    if (!callExpr)
        return;

    // For a chain like getList().first(), returns {first(), getList()}
    vector<CallExpr *> callExprs = Utils::callListForChain(callExpr);
    if (callExprs.size() < 2)
        return;

    CallExpr *firstCallToBeEvaluated = callExprs.at(callExprs.size() - 1); // This is the call to getList()
    FunctionDecl *firstFunc = firstCallToBeEvaluated->getDirectCallee();
    if (!firstFunc)
        return;

    QualType qt = firstFunc->getReturnType();
    const Type *firstFuncReturnType = qt.getTypePtrOrNull();
    if (!firstFuncReturnType)
        return;

    if (firstFuncReturnType->isReferenceType() || firstFuncReturnType->isPointerType())
        return;

    if (qt.isConstQualified()) {
        return; // const doesn't detach
    }

    CXXMethodDecl *firstMethod = dyn_cast<CXXMethodDecl>(firstFunc);
    if (isAllowedChainedMethod(StringUtils::qualifiedMethodName(firstFunc))) {
        return;
    }

    if (firstMethod && isAllowedChainedClass(firstMethod->getParent()->getNameAsString())) {
        return;
    }

    // Check if this is a QGlobalStatic
    if (firstMethod && firstMethod->getParent()->getNameAsString() == "QGlobalStatic") {
        return;
    }

    CallExpr *secondCallToBeEvaluated = callExprs.at(callExprs.size() - 2); // This is the call to first()
    FunctionDecl *detachingFunc = secondCallToBeEvaluated->getDirectCallee();
    CXXMethodDecl *detachingMethod = detachingFunc ? dyn_cast<CXXMethodDecl>(detachingFunc) : nullptr;
    const Type *detachingMethodReturnType = detachingMethod ? detachingMethod->getReturnType().getTypePtrOrNull() : nullptr;
    if (!detachingMethod || !detachingMethodReturnType)
        return;

    // Check if it's one of the implicit shared classes
    CXXRecordDecl *classDecl = detachingMethod->getParent();
    const std::string className = classDecl->getNameAsString();

    auto it = m_methodsByType.find(className);
    auto it2 = m_writeMethodsByType.find(className);

    std::vector<std::string> allowedFunctions;
    std::vector<std::string> allowedWriteFunctions;
    if (it != m_methodsByType.end()) {
        allowedFunctions = it->second;
    }

    if (it2 != m_writeMethodsByType.end()) {
        allowedWriteFunctions = it2->second;
    }

    // Check if it's one of the detaching methods
    const std::string functionName = detachingMethod->getNameAsString();

    string error;

    const bool isReadFunction = std::find(allowedFunctions.cbegin(), allowedFunctions.cend(), functionName) != allowedFunctions.cend();
    const bool isWriteFunction = std::find(allowedWriteFunctions.cbegin(), allowedWriteFunctions.cend(), functionName) != allowedWriteFunctions.cend();

    if (isReadFunction || isWriteFunction) {

        bool returnTypeIsIterator = false;
        CXXRecordDecl *returnRecord = detachingMethodReturnType->getAsCXXRecordDecl();
        if (returnRecord) {
            returnTypeIsIterator = returnRecord->getNameAsString() == "iterator";
        }

        if (isWriteFunction && (detachingMethodReturnType->isVoidType() || returnTypeIsIterator)) {
            error = std::string("Modifying temporary container is pointless and it also detaches");
        } else {
            error = std::string("Don't call ") + StringUtils::qualifiedMethodName(detachingMethod) + std::string("() on temporary");
        }
    }

    if (!error.empty())
        emitWarning(stm->getLocStart(), error.c_str());
}

bool DetachingTemporary::isDetachingMethod(CXXMethodDecl *method) const
{
    if (!method)
        return false;

    CXXRecordDecl *record = method->getParent();
    if (!record)
        return false;

    if (DetachingBase::isDetachingMethod(method))
        return true;

    const string className = record->getNameAsString();

    auto it = m_writeMethodsByType.find(className);
    if (it != m_writeMethodsByType.cend()) {
        const auto &methods = it->second;
        auto it2 = find(methods.cbegin(), methods.cend(), method->getNameAsString());
        if (it2 != methods.cend())
            return true;
    }

    return false;
}

REGISTER_CHECK_WITH_FLAGS("detaching-temporary", DetachingTemporary, CheckLevel1)
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fwkutil.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: jl $ $Date: 2004-05-18 12:50:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_FWKUTIL_HXX
#define INCLUDED_JVMFWK_FWKUTIL_HXX

#include "osl/mutex.hxx"
#include "osl/module.hxx"
#include "rtl/byteseq.hxx"
#include "libxml/parser.h"
#include "libxml/xpath.h"

#define ENVIRONMENT_VAR_JRE_PATH "JAVA_HOME"

namespace jfw
{
osl::Mutex * getFwkMutex();

rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData);
rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data);

rtl::OUString getPlatform();
/** //Todo
    Gets the directory where the user data is written
    Can have these values:
    - ~/.StarOffice/user/config (used in office)
    - arbitrary directory determined by environment variable
    - tmp directory (running out of office, e.g. regcomp)

    @return
    File URL of the directory
 */
rtl::OUString getJavaSettingsDirectory();

enum JFW_MODE
{
    /** The mode is unknown.
     */
    JFW_MODE_INDETERMINED,
    /** This library is loaded in an office process.
     */
    JFW_MODE_OFFICE,
    /** We are NOT in an office process. The javavendors.xml is located next to
        the jvmfwk.dll, the javasettings.xml is NEIHER created, NOR read or written.
        As class path the environment variable CLASSPATH is used. The JRE, which
        is to be used is determined by the environment variable JAVA_HOME. It must
        contain a file URL to the JRE.
     */
    JFW_MODE_ENV_SIMPLE
};

JFW_MODE getMode();
/** Get the file URL to the javasettings.xml
 */
rtl::OUString getUserSettingsURL();
rtl::OString getUserSettingsPath();

/** returns .../javasettings_wnt_x86.xml.

    Or other platform suffixes
 */
rtl::OUString getSharedSettingsURL();
rtl::OString getSharedSettingsPath();
/** returns .../javasettings.xml.

 */
rtl::OUString getSharedSettingsURLNoPlatformSuffix();
rtl::OString getSharedSettingsPathNoPlatformSuffix();

rtl::OUString getBaseInstallation();
rtl::OUString getVendorSettingsURL();

rtl::OString getVendorSettingsPath();

rtl::OUString getDirFromFile(const rtl::OUString& usFilePath);

rtl::OUString getFileFromURL(const rtl::OUString& sFileURL);

rtl::OUString searchFileNextToThisLib(const rtl::OUString & sFile);
class CNodeJava;
/** creates the -Djava.class.path option with the complete classpath.
    If param mode is JFW_MODE_ENV_SIMPLE then the param javaSettings is ignored.
 */
javaFrameworkError makeClassPathOption(
    JFW_MODE mode, CNodeJava & javaSettings, /*out*/rtl::OString & sOption);

struct PluginLibrary;
class VersionInfo;
class CJavaInfo;

javaFrameworkError getVendorPluginURLs(
    const xmlDocPtr doc,
    const xmlXPathContextPtr  context,
    std::vector<PluginLibrary> * vecPlugins);
bool isAccessibilitySupportDesired();

javaFrameworkError getVersionInformation(
    const xmlDocPtr doc,
    const xmlXPathContextPtr context,
    const rtl::OString & sVendor,
    VersionInfo *pVersionInfo);

/** Gets the file URL to the plubin library for the currently selected Java.
 */
javaFrameworkError getPluginLibrary(
    const rtl::OUString & sVendor, rtl::OUString & sLibPathe);

/** Called from writeJavaInfoData. It sets the process identifier. When
java is to be started, then the current id is compared to the one set by
this function. If they are identical then the Java was selected in the
same process. If that Java needs a prepared environment, such as a
LD_LIBRARY_PATH, then it must not be started in this process.
*/
void setJavaSelected();

/** Determines if the currently selected Java was set in this process.

    @see setProcessId()
 */
bool wasJavaSelectedInSameProcess();
/**
    @param pDoc
       must not be freed within the function.
    @param pJavaInfoNode
       must not be freed within the function.
 */
javaFrameworkError writeElementJavaInfo(xmlDoc* pDoc,
                                        xmlNode* pJavaInfoNode,
                                        const jfw::CJavaInfo & aInfo);

javaFrameworkError buildClassPathFromDirectory(const rtl::OUString & relPath,
                                               rtl::OUString & sClassPath);

rtl::OUString retrieveClassPath( ::rtl::OUString const & macro );

// class CProcessId
// {
//     sal_uInt8 m_arId[16];
//     bool m_bValid;
// public:
//     CProcessId();
//     /**
//        If the argument is NULL or the object is invalid then
//        false is returned.
//      */
//     bool operator == (const sal_uInt8 * arId) const;
//     void set();
//     bool isValid() const;
// };

}
#endif
<commit_msg>INTEGRATION: CWS jl8 (1.8.4); FILE MERGED 2004/07/06 16:03:15 jl 1.8.4.2: #i30342# 2004/06/24 13:02:03 jl 1.8.4.1: #i30342#<commit_after>/*************************************************************************
 *
 *  $RCSfile: fwkutil.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2004-07-23 11:55:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_FWKUTIL_HXX
#define INCLUDED_JVMFWK_FWKUTIL_HXX

#include "osl/mutex.hxx"
#include "osl/module.hxx"
#include "rtl/byteseq.hxx"
#include "libxml/parser.h"
#include "libxml/xpath.h"

#define ENVIRONMENT_VAR_JRE_PATH "JAVA_HOME"

namespace jfw
{
osl::Mutex * getFwkMutex();

rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData);
rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data);

rtl::OUString getPlatform();
/** //Todo
    Gets the directory where the user data is written
    Can have these values:
    - ~/.StarOffice/user/config (used in office)
    - arbitrary directory determined by environment variable
    - tmp directory (running out of office, e.g. regcomp)

    @return
    File URL of the directory
 */
rtl::OUString getJavaSettingsDirectory();

enum JFW_MODE
{
    /** The mode is unknown.
     */
    JFW_MODE_INDETERMINED,
    /** This library is loaded in an office process.
     */
    JFW_MODE_OFFICE,
    /** We are NOT in an office process. The javavendors.xml is located next to
        the jvmfwk.dll, the javasettings.xml is NEIHER created, NOR read or written.
        As class path the environment variable CLASSPATH is used. The JRE, which
        is to be used is determined by the environment variable JAVA_HOME. It must
        contain a file URL to the JRE.
     */
    JFW_MODE_ENV_SIMPLE
};

JFW_MODE getMode();
/** Get the file URL to the javasettings.xml
 */
rtl::OUString getUserSettingsURL();
rtl::OString getUserSettingsPath();

/** returns .../javasettings_wnt_x86.xml.

    Or other platform suffixes
 */
rtl::OUString getSharedSettingsURL();
rtl::OString getSharedSettingsPath();
/** returns .../javasettings.xml.

 */
rtl::OUString getSharedSettingsURLNoPlatformSuffix();
rtl::OString getSharedSettingsPathNoPlatformSuffix();

rtl::OUString getBaseInstallation();
rtl::OUString getVendorSettingsURL();

rtl::OString getVendorSettingsPath();

rtl::OUString getDirFromFile(const rtl::OUString& usFilePath);

rtl::OUString getFileFromURL(const rtl::OUString& sFileURL);

rtl::OUString searchFileNextToThisLib(const rtl::OUString & sFile);
class CNodeJava;
/** creates the -Djava.class.path option with the complete classpath.
    If param mode is JFW_MODE_ENV_SIMPLE then the param javaSettings is ignored.
 */
javaFrameworkError makeClassPathOption(
    JFW_MODE mode, CNodeJava & javaSettings, /*out*/rtl::OString & sOption);

struct PluginLibrary;
class VersionInfo;
class CJavaInfo;

javaFrameworkError getVendorPluginURLs(
    const xmlDocPtr doc,
    const xmlXPathContextPtr  context,
    std::vector<PluginLibrary> * vecPlugins);

javaFrameworkError getSupportedVendors(
    const xmlDocPtr doc,
    const xmlXPathContextPtr  context,
    std::vector<rtl::OUString> * vecVendors);

bool isAccessibilitySupportDesired();

javaFrameworkError getVersionInformation(
    const xmlDocPtr doc,
    const xmlXPathContextPtr context,
    const rtl::OUString & sVendor,
    VersionInfo *pVersionInfo);

/** Gets the file URL to the plubin library for the currently selected Java.
 */
javaFrameworkError getPluginLibrary(
    const rtl::OUString & sVendor, rtl::OUString & sLibPathe);

/** Called from writeJavaInfoData. It sets the process identifier. When
java is to be started, then the current id is compared to the one set by
this function. If they are identical then the Java was selected in the
same process. If that Java needs a prepared environment, such as a
LD_LIBRARY_PATH, then it must not be started in this process.
*/
void setJavaSelected();

/** Determines if the currently selected Java was set in this process.

    @see setProcessId()
 */
bool wasJavaSelectedInSameProcess();
/**
    @param pDoc
       must not be freed within the function.
    @param pJavaInfoNode
       must not be freed within the function.
 */
javaFrameworkError writeElementJavaInfo(xmlDoc* pDoc,
                                        xmlNode* pJavaInfoNode,
                                        const jfw::CJavaInfo & aInfo);

javaFrameworkError buildClassPathFromDirectory(const rtl::OUString & relPath,
                                               rtl::OUString & sClassPath);

rtl::OUString retrieveClassPath( ::rtl::OUString const & macro );

// class CProcessId
// {
//     sal_uInt8 m_arId[16];
//     bool m_bValid;
// public:
//     CProcessId();
//     /**
//        If the argument is NULL or the object is invalid then
//        false is returned.
//      */
//     bool operator == (const sal_uInt8 * arId) const;
//     void set();
//     bool isValid() const;
// };

}
#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2552
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1492088 by johtaylo@johtaylo-jtincrementor2-increment on 2017/12/08 03:00:14<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2553
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2788
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1716952 by chui@ocl-promo-incrementor on 2018/12/06 03:00:18<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2789
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2495
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1457669 by johtaylo@johtaylo-jtincrementor-increment on 2017/09/12 03:00:05<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2496
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2471
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1444919 by johtaylo@johtaylo-jtincrementor-increment on 2017/08/09 03:00:05<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2472
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2011
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1229676 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/01/21 03:00:11<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2012
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2333
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1361545 by johtaylo@johtaylo-jtincrementor-increment on 2017/01/13 03:00:03<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2334
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2279
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1343667 by johtaylo@johtaylo-jtincrementor-increment on 2016/11/19 03:00:04<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2280
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2126
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1273675 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/05/27 03:00:13<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2127
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
//  Object.cpp
//  Test02
//
//  Created by Golden Compass on 9/17/14.
//  Copyright (c) 2014 Golden Compass. All rights reserved.
//

#include "Object.h"

Sphere::Sphere(vec3 _center, float _radius)
{
    center = _center;
    radius = _radius;
}
//bool Sphere::isIntersectByRay(const vec3& ray)
//{
//
//    return false;
//}

Plane::Plane(float _a, float _b, float _c, float _d)
{
    a = _a;
    b = _b;
    c = _c;
    d = _d;
}

// ax + by + cz + d = 0
Plane::Plane(vec3 point, vec3 normal)
{
    a = normal.x;
    b = normal.y;
    c = normal.z;
    d = -(a*point.x) - (b*point.y) - (c*point.z);
}<commit_msg>working copy…<commit_after>//
//  Object.cpp
//  Test02
//
//  Created by Golden Compass on 9/17/14.
//  Copyright (c) 2014 Golden Compass. All rights reserved.
//

#include "Object.h"

Sphere::Sphere(vec3 _center, float _radius)
{
    center = _center;
    radius = _radius;
}
//bool Sphere::isIntersectByRay(const vec3& ray)
//{
//
//    return false;
//}

Plane::Plane(float _a, float _b, float _c, float _d)
{
    a = _a;
    b = _b;
    c = _c;
    d = _d;
}

// ax + by + cz + d = 0
Plane::Plane(vec3 point, vec3 normal)
{
    a = normal.x;
    b = normal.y;
    c = normal.z;
    d = -(a*point.x) - (b*point.y) - (c*point.z);
}<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2067
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1249106 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/03/19 03:00:11<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2068
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2097
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1258907 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/04/18 03:00:24<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2098
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2340
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1364218 by johtaylo@johtaylo-jtincrementor-increment on 2017/01/20 03:00:45<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2341
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1620
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1070744 by gandryey@gera-ubuntu14 on 2014/08/27 13:47:50<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1621
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include <future>
#include <string>
#include <vector>

#include "firebase/firestore.h"
#include "firebase_test_framework.h"
#include "firestore_integration_test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "util/bundle_builder.h"
#include "util/event_accumulator.h"
#include "util/future_test_util.h"

// These test cases are in sync with native iOS client SDK test
//   Firestore/Example/Tests/Integration/API/FIRBundlesTests.mm
// and native Android client SDK test
//   firebase_firestore/tests/integration_tests/src/com/google/firebase/firestore/BundleTest.java
// The iOS test names start with the mandatory test prefix while Android test
// names do not. Here we use the Android test names.

namespace firebase {
namespace firestore {
namespace {

// Query names from the testing bundle in bundle_builder.cc
constexpr char kLimitQueryName[] = "limit";
constexpr char kLimitToLastQueryName[] = "limit-to-last";

MATCHER_P(
    InProgressWithLoadedDocuments,
    expected_documents,
    std::string("Is a valid InProgress update with documents_loaded() == ") +
        std::to_string(expected_documents)) {
  std::string state_string =
      arg.state() == LoadBundleTaskProgress::State::kInProgress
          ? "kInProgress"
          : (arg.state() == LoadBundleTaskProgress::State::kError ? "kError"
                                                                  : "kSuccess");
  *result_listener << "progress state() is " << state_string
                   << " documents_loaded() is: " << arg.documents_loaded()
                   << " total_documents() is: " << arg.total_documents()
                   << " bytes_loaded() is: " << arg.bytes_loaded()
                   << " total_bytes() is: " << arg.total_bytes();
  return arg.state() == LoadBundleTaskProgress::State::kInProgress &&
         arg.documents_loaded() == expected_documents &&
         arg.documents_loaded() <= arg.total_documents() &&
         arg.bytes_loaded() <= arg.total_bytes();
}

void VerifySuccessProgress(LoadBundleTaskProgress progress) {
  EXPECT_EQ(progress.state(), LoadBundleTaskProgress::State::kSuccess);
  EXPECT_EQ(progress.documents_loaded(), progress.total_documents());
  EXPECT_EQ(progress.bytes_loaded(), progress.total_bytes());
}

void VerifyErrorProgress(LoadBundleTaskProgress progress) {
  EXPECT_EQ(progress.state(), LoadBundleTaskProgress::State::kError);
  EXPECT_EQ(progress.documents_loaded(), 0);
  EXPECT_EQ(progress.bytes_loaded(), 0);
}

std::string CreateTestBundle(Firestore* db) {
  return CreateBundle(db->app()->options().project_id());
}

class BundleTest : public FirestoreIntegrationTest {
 protected:
  void SetUp() override {
    FirestoreIntegrationTest::SetUp();
    // Clear the storage to avoid tests interfering with each other, since they
    // will be loading the same bundle file.
    ASSERT_THAT(TestFirestore()->ClearPersistence(), FutureSucceeds());
  }

  template <typename T>
  T AwaitResult(const Future<T>& future) {
    auto* ptr = Await(future);
    EXPECT_NE(ptr, nullptr);
    // Return default instance instead of crashing.
    if (ptr == nullptr) {
      return {};
    }

    return *ptr;
  }

  void VerifyQueryResults(Firestore* db) {
    {
      auto snapshot = AwaitResult(db->Collection("coll-1").Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("a")},
                                             {"bar", FieldValue::Integer(1)}},
                               MapFieldValue{{"k", FieldValue::String("b")},
                                             {"bar", FieldValue::Integer(2)}}));
    }

    {
      Query limit = AwaitResult(db->NamedQuery(kLimitQueryName));
      auto limit_snapshot = AwaitResult(limit.Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(limit_snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("b")},
                                             {"bar", FieldValue::Integer(2)}}));
    }

    {
      Query limit_to_last = AwaitResult(db->NamedQuery(kLimitToLastQueryName));
      auto limit_to_last_snapshot =
          AwaitResult(limit_to_last.Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(limit_to_last_snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("a")},
                                             {"bar", FieldValue::Integer(1)}}));
    }
  }
};

TEST_F(BundleTest, CanLoadBundlesWithoutProgressUpdates) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  Future<LoadBundleTaskProgress> result = db->LoadBundle(bundle);

  VerifySuccessProgress(AwaitResult(result));
  VerifyQueryResults(db);
}

TEST_F(BundleTest, CanLoadBundlesWithProgressUpdates) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result = db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      });

  auto final_progress = AwaitResult(result);

  // 4 progresses will be reported: initial, document 1, document 2, final
  // success.
  ASSERT_EQ(progresses.size(), 4);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  EXPECT_THAT(progresses[1], InProgressWithLoadedDocuments(1));
  EXPECT_THAT(progresses[2], InProgressWithLoadedDocuments(2));
  VerifySuccessProgress(progresses[3]);
  EXPECT_EQ(progresses[3], final_progress);

  VerifyQueryResults(db);
}

TEST_F(BundleTest, CanDeleteFirestoreFromProgressUpdate) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  std::promise<void> db_deleted;
  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result =
      db->LoadBundle(bundle, [this, db, &progresses, &db_deleted](
                                 const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
        // Delete firestore before the final progress.
        if (progresses.size() == 3) {
          DeleteFirestore(db);
          db_deleted.set_value();
        }
      });

  // Wait for the notification that the instance is deleted before verifying.
  db_deleted.get_future().wait();

  // This future is not completed, and returns back a nullptr for result when it
  // times out.
  EXPECT_EQ(Await(result), nullptr);

  // 3 progresses will be reported: initial, document 1, document 2.
  // Final progress update is missing because Firestore is deleted before that.
  ASSERT_EQ(progresses.size(), 3);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  EXPECT_THAT(progresses[1], InProgressWithLoadedDocuments(1));
  EXPECT_THAT(progresses[2], InProgressWithLoadedDocuments(2));
}

TEST_F(BundleTest, LoadBundlesForASecondTimeSkips) {
  // TODO(wuandy): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);
  LoadBundleTaskProgress first_load = AwaitResult(db->LoadBundle(bundle));
  VerifySuccessProgress(first_load);

  std::vector<LoadBundleTaskProgress> progresses;
  LoadBundleTaskProgress second_load = AwaitResult(db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      }));

  // There will be 4 progress updates if it does not skip loading.
  ASSERT_EQ(progresses.size(), 1);
  VerifySuccessProgress(progresses[0]);
  EXPECT_EQ(progresses[0], second_load);

  VerifyQueryResults(db);
}

TEST_F(BundleTest, LoadInvalidBundlesShouldFail) {
  // TODO(wuandy): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  std::vector<std::string> invalid_bundles{
      "invalid bundle obviously", "\"(╯°□°）╯︵ ┻━┻\"",
      "\xc3\x28"  // random bytes
  };
  for (const auto& bundle : invalid_bundles) {
    std::vector<LoadBundleTaskProgress> progresses;
    Future<LoadBundleTaskProgress> result = db->LoadBundle(
        bundle, [&progresses](const LoadBundleTaskProgress& progress) {
          progresses.push_back(progress);
        });
    Await(result);

    EXPECT_NE(result.error(), Error::kErrorOk);
    ASSERT_EQ(progresses.size(), 1);
    VerifyErrorProgress(progresses[0]);
  }
}

TEST_F(BundleTest, LoadBundleWithDocumentsAlreadyPulledFromBackend) {
  Firestore* db = TestFirestore();
  auto collection = db->Collection("coll-1");
  WriteDocuments(collection,
                 {
                     {"a", {{"bar", FieldValue::String("newValueA")}}},
                     {"b", {{"bar", FieldValue::String("newValueB")}}},
                 });
  EventAccumulator<QuerySnapshot> accumulator;
  ListenerRegistration limit_registration =
      accumulator.listener()->AttachTo(&collection);
  accumulator.AwaitRemoteEvent();

  // The test bundle is holding ancient documents, so no events are generated as
  // a result. The case where a bundle has newer doc than cache can only be
  // tested in spec tests.
  accumulator.FailOnNextEvent();

  auto bundle = CreateTestBundle(db);
  VerifySuccessProgress(AwaitResult(db->LoadBundle(bundle)));

  EXPECT_THAT(QuerySnapshotToValues(*Await(collection.Get(Source::kCache))),
              testing::ElementsAre(
                  MapFieldValue{{"bar", FieldValue::String("newValueA")}},
                  MapFieldValue{{"bar", FieldValue::String("newValueB")}}));

  {
    Query limit = AwaitResult(db->NamedQuery(kLimitQueryName));
    EXPECT_THAT(QuerySnapshotToValues(AwaitResult(limit.Get(Source::kCache))),
                testing::ElementsAre(
                    MapFieldValue{{"bar", FieldValue::String("newValueB")}}));
  }

  {
    Query limit_to_last = AwaitResult(db->NamedQuery(kLimitToLastQueryName));
    EXPECT_THAT(
        QuerySnapshotToValues(AwaitResult(limit_to_last.Get(Source::kCache))),
        testing::ElementsAre(
            MapFieldValue{{"bar", FieldValue::String("newValueA")}}));
  }
}

TEST_F(BundleTest, LoadedDocumentsShouldNotBeGarbageCollectedRightAway) {
  Firestore* db = TestFirestore();
  // This test really only makes sense with memory persistence, as disk
  // persistence only ever lazily deletes data.
  auto new_settings = db->settings();
  new_settings.set_persistence_enabled(false);
  db->set_settings(new_settings);

  auto bundle = CreateTestBundle(db);
  VerifySuccessProgress(AwaitResult(db->LoadBundle(bundle)));

  // Read a different collection. This will trigger GC.
  Await(db->Collection("coll-other").Get());

  // Read the loaded documents, expecting them to exist in cache. With memory
  // GC, the documents would get GC-ed if we did not hold the document keys in
  // an "umbrella" target. See LocalStore for details.
  VerifyQueryResults(db);
}

TEST_F(BundleTest, LoadDocumentsFromOtherProjectsShouldFail) {
  Firestore* db = TestFirestore();
  auto bundle = CreateBundle("other-project");
  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result = db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      });
  Await(result);

  EXPECT_NE(result.error(), Error::kErrorOk);
  ASSERT_EQ(progresses.size(), 2);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  VerifyErrorProgress(progresses[1]);
}

TEST_F(BundleTest, GetInvalidNamedQuery) {
  Firestore* db = TestFirestore();
  {
    auto future = db->NamedQuery("DOES_NOT_EXIST");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
  {
    auto future = db->NamedQuery("");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
  {
    auto future = db->NamedQuery("\xc3\x28");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
}

}  // namespace
}  // namespace firestore
}  // namespace firebase
<commit_msg>Disable more bundles tests that fail in Windows CI (#440)<commit_after>#include <future>
#include <string>
#include <vector>

#include "firebase/firestore.h"
#include "firebase_test_framework.h"
#include "firestore_integration_test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "util/bundle_builder.h"
#include "util/event_accumulator.h"
#include "util/future_test_util.h"

// These test cases are in sync with native iOS client SDK test
//   Firestore/Example/Tests/Integration/API/FIRBundlesTests.mm
// and native Android client SDK test
//   firebase_firestore/tests/integration_tests/src/com/google/firebase/firestore/BundleTest.java
// The iOS test names start with the mandatory test prefix while Android test
// names do not. Here we use the Android test names.

namespace firebase {
namespace firestore {
namespace {

// Query names from the testing bundle in bundle_builder.cc
constexpr char kLimitQueryName[] = "limit";
constexpr char kLimitToLastQueryName[] = "limit-to-last";

MATCHER_P(
    InProgressWithLoadedDocuments,
    expected_documents,
    std::string("Is a valid InProgress update with documents_loaded() == ") +
        std::to_string(expected_documents)) {
  std::string state_string =
      arg.state() == LoadBundleTaskProgress::State::kInProgress
          ? "kInProgress"
          : (arg.state() == LoadBundleTaskProgress::State::kError ? "kError"
                                                                  : "kSuccess");
  *result_listener << "progress state() is " << state_string
                   << " documents_loaded() is: " << arg.documents_loaded()
                   << " total_documents() is: " << arg.total_documents()
                   << " bytes_loaded() is: " << arg.bytes_loaded()
                   << " total_bytes() is: " << arg.total_bytes();
  return arg.state() == LoadBundleTaskProgress::State::kInProgress &&
         arg.documents_loaded() == expected_documents &&
         arg.documents_loaded() <= arg.total_documents() &&
         arg.bytes_loaded() <= arg.total_bytes();
}

void VerifySuccessProgress(LoadBundleTaskProgress progress) {
  EXPECT_EQ(progress.state(), LoadBundleTaskProgress::State::kSuccess);
  EXPECT_EQ(progress.documents_loaded(), progress.total_documents());
  EXPECT_EQ(progress.bytes_loaded(), progress.total_bytes());
}

void VerifyErrorProgress(LoadBundleTaskProgress progress) {
  EXPECT_EQ(progress.state(), LoadBundleTaskProgress::State::kError);
  EXPECT_EQ(progress.documents_loaded(), 0);
  EXPECT_EQ(progress.bytes_loaded(), 0);
}

std::string CreateTestBundle(Firestore* db) {
  return CreateBundle(db->app()->options().project_id());
}

class BundleTest : public FirestoreIntegrationTest {
 protected:
  void SetUp() override {
    FirestoreIntegrationTest::SetUp();
    // Clear the storage to avoid tests interfering with each other, since they
    // will be loading the same bundle file.
    ASSERT_THAT(TestFirestore()->ClearPersistence(), FutureSucceeds());
  }

  template <typename T>
  T AwaitResult(const Future<T>& future) {
    auto* ptr = Await(future);
    EXPECT_NE(ptr, nullptr);
    // Return default instance instead of crashing.
    if (ptr == nullptr) {
      return {};
    }

    return *ptr;
  }

  void VerifyQueryResults(Firestore* db) {
    {
      auto snapshot = AwaitResult(db->Collection("coll-1").Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("a")},
                                             {"bar", FieldValue::Integer(1)}},
                               MapFieldValue{{"k", FieldValue::String("b")},
                                             {"bar", FieldValue::Integer(2)}}));
    }

    {
      Query limit = AwaitResult(db->NamedQuery(kLimitQueryName));
      auto limit_snapshot = AwaitResult(limit.Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(limit_snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("b")},
                                             {"bar", FieldValue::Integer(2)}}));
    }

    {
      Query limit_to_last = AwaitResult(db->NamedQuery(kLimitToLastQueryName));
      auto limit_to_last_snapshot =
          AwaitResult(limit_to_last.Get(Source::kCache));
      EXPECT_THAT(
          QuerySnapshotToValues(limit_to_last_snapshot),
          testing::ElementsAre(MapFieldValue{{"k", FieldValue::String("a")},
                                             {"bar", FieldValue::Integer(1)}}));
    }
  }
};

TEST_F(BundleTest, CanLoadBundlesWithoutProgressUpdates) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  Future<LoadBundleTaskProgress> result = db->LoadBundle(bundle);

  VerifySuccessProgress(AwaitResult(result));
  VerifyQueryResults(db);
}

TEST_F(BundleTest, CanLoadBundlesWithProgressUpdates) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result = db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      });

  auto final_progress = AwaitResult(result);

  // 4 progresses will be reported: initial, document 1, document 2, final
  // success.
  ASSERT_EQ(progresses.size(), 4);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  EXPECT_THAT(progresses[1], InProgressWithLoadedDocuments(1));
  EXPECT_THAT(progresses[2], InProgressWithLoadedDocuments(2));
  VerifySuccessProgress(progresses[3]);
  EXPECT_EQ(progresses[3], final_progress);

  VerifyQueryResults(db);
}

TEST_F(BundleTest, CanDeleteFirestoreFromProgressUpdate) {
  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);

  std::promise<void> db_deleted;
  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result =
      db->LoadBundle(bundle, [this, db, &progresses, &db_deleted](
                                 const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
        // Delete firestore before the final progress.
        if (progresses.size() == 3) {
          DeleteFirestore(db);
          db_deleted.set_value();
        }
      });

  // Wait for the notification that the instance is deleted before verifying.
  db_deleted.get_future().wait();

  // This future is not completed, and returns back a nullptr for result when it
  // times out.
  EXPECT_EQ(Await(result), nullptr);

  // 3 progresses will be reported: initial, document 1, document 2.
  // Final progress update is missing because Firestore is deleted before that.
  ASSERT_EQ(progresses.size(), 3);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  EXPECT_THAT(progresses[1], InProgressWithLoadedDocuments(1));
  EXPECT_THAT(progresses[2], InProgressWithLoadedDocuments(2));
}

TEST_F(BundleTest, LoadBundlesForASecondTimeSkips) {
  // TODO(wuandy): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  auto bundle = CreateTestBundle(db);
  LoadBundleTaskProgress first_load = AwaitResult(db->LoadBundle(bundle));
  VerifySuccessProgress(first_load);

  std::vector<LoadBundleTaskProgress> progresses;
  LoadBundleTaskProgress second_load = AwaitResult(db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      }));

  // There will be 4 progress updates if it does not skip loading.
  ASSERT_EQ(progresses.size(), 1);
  VerifySuccessProgress(progresses[0]);
  EXPECT_EQ(progresses[0], second_load);

  VerifyQueryResults(db);
}

TEST_F(BundleTest, LoadInvalidBundlesShouldFail) {
  // TODO(wuandy): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  std::vector<std::string> invalid_bundles{
      "invalid bundle obviously", "\"(╯°□°）╯︵ ┻━┻\"",
      "\xc3\x28"  // random bytes
  };
  for (const auto& bundle : invalid_bundles) {
    std::vector<LoadBundleTaskProgress> progresses;
    Future<LoadBundleTaskProgress> result = db->LoadBundle(
        bundle, [&progresses](const LoadBundleTaskProgress& progress) {
          progresses.push_back(progress);
        });
    Await(result);

    EXPECT_NE(result.error(), Error::kErrorOk);
    ASSERT_EQ(progresses.size(), 1);
    VerifyErrorProgress(progresses[0]);
  }
}

TEST_F(BundleTest, LoadBundleWithDocumentsAlreadyPulledFromBackend) {
  // TODO(wuandy, b/189477267): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  auto collection = db->Collection("coll-1");
  WriteDocuments(collection,
                 {
                     {"a", {{"bar", FieldValue::String("newValueA")}}},
                     {"b", {{"bar", FieldValue::String("newValueB")}}},
                 });
  EventAccumulator<QuerySnapshot> accumulator;
  ListenerRegistration limit_registration =
      accumulator.listener()->AttachTo(&collection);
  accumulator.AwaitRemoteEvent();

  // The test bundle is holding ancient documents, so no events are generated as
  // a result. The case where a bundle has newer doc than cache can only be
  // tested in spec tests.
  accumulator.FailOnNextEvent();

  auto bundle = CreateTestBundle(db);
  VerifySuccessProgress(AwaitResult(db->LoadBundle(bundle)));

  EXPECT_THAT(QuerySnapshotToValues(*Await(collection.Get(Source::kCache))),
              testing::ElementsAre(
                  MapFieldValue{{"bar", FieldValue::String("newValueA")}},
                  MapFieldValue{{"bar", FieldValue::String("newValueB")}}));

  {
    Query limit = AwaitResult(db->NamedQuery(kLimitQueryName));
    EXPECT_THAT(QuerySnapshotToValues(AwaitResult(limit.Get(Source::kCache))),
                testing::ElementsAre(
                    MapFieldValue{{"bar", FieldValue::String("newValueB")}}));
  }

  {
    Query limit_to_last = AwaitResult(db->NamedQuery(kLimitToLastQueryName));
    EXPECT_THAT(
        QuerySnapshotToValues(AwaitResult(limit_to_last.Get(Source::kCache))),
        testing::ElementsAre(
            MapFieldValue{{"bar", FieldValue::String("newValueA")}}));
  }
}

TEST_F(BundleTest, LoadedDocumentsShouldNotBeGarbageCollectedRightAway) {
  // TODO(wuandy, b/189477267): This test fails on Windows CI, but
  // local run is fine. We need to figure out why and re-enable it.
  SKIP_TEST_ON_WINDOWS;

  Firestore* db = TestFirestore();
  // This test really only makes sense with memory persistence, as disk
  // persistence only ever lazily deletes data.
  auto new_settings = db->settings();
  new_settings.set_persistence_enabled(false);
  db->set_settings(new_settings);

  auto bundle = CreateTestBundle(db);
  VerifySuccessProgress(AwaitResult(db->LoadBundle(bundle)));

  // Read a different collection. This will trigger GC.
  Await(db->Collection("coll-other").Get());

  // Read the loaded documents, expecting them to exist in cache. With memory
  // GC, the documents would get GC-ed if we did not hold the document keys in
  // an "umbrella" target. See LocalStore for details.
  VerifyQueryResults(db);
}

TEST_F(BundleTest, LoadDocumentsFromOtherProjectsShouldFail) {
  Firestore* db = TestFirestore();
  auto bundle = CreateBundle("other-project");
  std::vector<LoadBundleTaskProgress> progresses;
  Future<LoadBundleTaskProgress> result = db->LoadBundle(
      bundle, [&progresses](const LoadBundleTaskProgress& progress) {
        progresses.push_back(progress);
      });
  Await(result);

  EXPECT_NE(result.error(), Error::kErrorOk);
  ASSERT_EQ(progresses.size(), 2);
  EXPECT_THAT(progresses[0], InProgressWithLoadedDocuments(0));
  VerifyErrorProgress(progresses[1]);
}

TEST_F(BundleTest, GetInvalidNamedQuery) {
  Firestore* db = TestFirestore();
  {
    auto future = db->NamedQuery("DOES_NOT_EXIST");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
  {
    auto future = db->NamedQuery("");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
  {
    auto future = db->NamedQuery("\xc3\x28");
    Await(future);
    EXPECT_EQ(future.status(), FutureStatus::kFutureStatusComplete);
    EXPECT_EQ(future.error(), Error::kErrorNotFound);
  }
}

}  // namespace
}  // namespace firestore
}  // namespace firebase
<|endoftext|>