<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/engine/verify_updates_command.h"

#include <string>

#include "base/location.h"
#include "chrome/browser/sync/engine/syncer.h"
#include "chrome/browser/sync/engine/syncer_proto_util.h"
#include "chrome/browser/sync/engine/syncer_types.h"
#include "chrome/browser/sync/engine/syncer_util.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/syncable/syncable.h"

namespace browser_sync {

using syncable::ScopedDirLookup;
using syncable::WriteTransaction;

using syncable::GET_BY_ID;
using syncable::SYNCER;

VerifyUpdatesCommand::VerifyUpdatesCommand() {}
VerifyUpdatesCommand::~VerifyUpdatesCommand() {}

bool VerifyUpdatesCommand::HasCustomGroupsToChange() const {
  return true;
}

std::set<ModelSafeGroup> VerifyUpdatesCommand::GetGroupsToChange(
    const sessions::SyncSession& session) const {
  std::set<ModelSafeGroup> groups_with_updates;

  const GetUpdatesResponse& updates =
      session.status_controller().updates_response().get_updates();
  for (int i = 0; i < updates.entries().size(); i++) {
    groups_with_updates.insert(
        GetGroupForModelType(syncable::GetModelType(updates.entries(i)),
                             session.routing_info()));
  }

  return groups_with_updates;
}

void VerifyUpdatesCommand::ModelChangingExecuteImpl(
    sessions::SyncSession* session) {
  DVLOG(1) << "Beginning Update Verification";
  ScopedDirLookup dir(session->context()->directory_manager(),
                      session->context()->account_name());
  if (!dir.good()) {
    LOG(ERROR) << "Scoped dir lookup failed!";
    return;
  }
  WriteTransaction trans(FROM_HERE, SYNCER, dir);
  sessions::StatusController* status = session->mutable_status_controller();
  const GetUpdatesResponse& updates = status->updates_response().get_updates();
  int update_count = updates.entries().size();

  DVLOG(1) << update_count << " entries to verify";
  for (int i = 0; i < update_count; i++) {
    const SyncEntity& update =
        *reinterpret_cast<const SyncEntity *>(&(updates.entries(i)));
    ModelSafeGroup g = GetGroupForModelType(update.GetModelType(),
                                            session->routing_info());
    if (g != status->group_restriction())
      continue;

    VerifyUpdateResult result = VerifyUpdate(&trans, update,
                                             session->routing_info());
    status->mutable_update_progress()->AddVerifyResult(result.value, update);
    status->increment_num_updates_downloaded_by(1);
    if (update.deleted())
      status->increment_num_tombstone_updates_downloaded_by(1);
  }
}

namespace {
// In the event that IDs match, but tags differ AttemptReuniteClient tag
// will have refused to unify the update.
// We should not attempt to apply it at all since it violates consistency
// rules.
VerifyResult VerifyTagConsistency(const SyncEntity& entry,
                                  const syncable::MutableEntry& same_id) {
  if (entry.has_client_defined_unique_tag() &&
      entry.client_defined_unique_tag() !=
          same_id.Get(syncable::UNIQUE_CLIENT_TAG)) {
    return VERIFY_FAIL;
  }
  return VERIFY_UNDECIDED;
}
}  // namespace

VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate(
    syncable::WriteTransaction* trans, const SyncEntity& entry,
    const ModelSafeRoutingInfo& routes) {
  syncable::Id id = entry.id();
  VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE};

  const bool deleted = entry.has_deleted() && entry.deleted();
  const bool is_directory = entry.IsFolder();
  const syncable::ModelType model_type = entry.GetModelType();

  if (!id.ServerKnows()) {
    LOG(ERROR) << "Illegal negative id in received updates";
    return result;
  }
  {
    const std::string name = SyncerProtoUtil::NameFromSyncEntity(entry);
    if (name.empty() && !deleted) {
      LOG(ERROR) << "Zero length name in non-deleted update";
      return result;
    }
  }

  syncable::MutableEntry same_id(trans, GET_BY_ID, id);
  result.value = SyncerUtil::VerifyNewEntry(entry, &same_id, deleted);

  syncable::ModelType placement_type = !deleted ? entry.GetModelType()
      : same_id.good() ? same_id.GetModelType() : syncable::UNSPECIFIED;
  result.placement = GetGroupForModelType(placement_type, routes);

  if (VERIFY_UNDECIDED == result.value) {
    result.value = VerifyTagConsistency(entry, same_id);
  }

  if (VERIFY_UNDECIDED == result.value) {
    if (deleted)
      result.value = VERIFY_SUCCESS;
  }

  // If we have an existing entry, we check here for updates that break
  // consistency rules.
  if (VERIFY_UNDECIDED == result.value) {
    result.value = SyncerUtil::VerifyUpdateConsistency(trans, entry, &same_id,
        deleted, is_directory, model_type);
  }

  if (VERIFY_UNDECIDED == result.value)
    result.value = VERIFY_SUCCESS;  // No news is good news.

  return result;  // This might be VERIFY_SUCCESS as well
}

}  // namespace browser_sync
<commit_msg>Revert 113319 - [Sync] Set HasCustomGroupsToChange() to true for VerifyUpdatesCommand<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/engine/verify_updates_command.h"

#include <string>

#include "base/location.h"
#include "chrome/browser/sync/engine/syncer.h"
#include "chrome/browser/sync/engine/syncer_proto_util.h"
#include "chrome/browser/sync/engine/syncer_types.h"
#include "chrome/browser/sync/engine/syncer_util.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/syncable/syncable.h"

namespace browser_sync {

using syncable::ScopedDirLookup;
using syncable::WriteTransaction;

using syncable::GET_BY_ID;
using syncable::SYNCER;

VerifyUpdatesCommand::VerifyUpdatesCommand() {}
VerifyUpdatesCommand::~VerifyUpdatesCommand() {}

bool VerifyUpdatesCommand::HasCustomGroupsToChange() const {
  // TODO(akalin): Set to true.
  return false;
}

std::set<ModelSafeGroup> VerifyUpdatesCommand::GetGroupsToChange(
    const sessions::SyncSession& session) const {
  std::set<ModelSafeGroup> groups_with_updates;

  const GetUpdatesResponse& updates =
      session.status_controller().updates_response().get_updates();
  for (int i = 0; i < updates.entries().size(); i++) {
    groups_with_updates.insert(
        GetGroupForModelType(syncable::GetModelType(updates.entries(i)),
                             session.routing_info()));
  }

  return groups_with_updates;
}

void VerifyUpdatesCommand::ModelChangingExecuteImpl(
    sessions::SyncSession* session) {
  DVLOG(1) << "Beginning Update Verification";
  ScopedDirLookup dir(session->context()->directory_manager(),
                      session->context()->account_name());
  if (!dir.good()) {
    LOG(ERROR) << "Scoped dir lookup failed!";
    return;
  }
  WriteTransaction trans(FROM_HERE, SYNCER, dir);
  sessions::StatusController* status = session->mutable_status_controller();
  const GetUpdatesResponse& updates = status->updates_response().get_updates();
  int update_count = updates.entries().size();

  DVLOG(1) << update_count << " entries to verify";
  for (int i = 0; i < update_count; i++) {
    const SyncEntity& update =
        *reinterpret_cast<const SyncEntity *>(&(updates.entries(i)));
    ModelSafeGroup g = GetGroupForModelType(update.GetModelType(),
                                            session->routing_info());
    if (g != status->group_restriction())
      continue;

    VerifyUpdateResult result = VerifyUpdate(&trans, update,
                                             session->routing_info());
    status->mutable_update_progress()->AddVerifyResult(result.value, update);
    status->increment_num_updates_downloaded_by(1);
    if (update.deleted())
      status->increment_num_tombstone_updates_downloaded_by(1);
  }
}

namespace {
// In the event that IDs match, but tags differ AttemptReuniteClient tag
// will have refused to unify the update.
// We should not attempt to apply it at all since it violates consistency
// rules.
VerifyResult VerifyTagConsistency(const SyncEntity& entry,
                                  const syncable::MutableEntry& same_id) {
  if (entry.has_client_defined_unique_tag() &&
      entry.client_defined_unique_tag() !=
          same_id.Get(syncable::UNIQUE_CLIENT_TAG)) {
    return VERIFY_FAIL;
  }
  return VERIFY_UNDECIDED;
}
}  // namespace

VerifyUpdatesCommand::VerifyUpdateResult VerifyUpdatesCommand::VerifyUpdate(
    syncable::WriteTransaction* trans, const SyncEntity& entry,
    const ModelSafeRoutingInfo& routes) {
  syncable::Id id = entry.id();
  VerifyUpdateResult result = {VERIFY_FAIL, GROUP_PASSIVE};

  const bool deleted = entry.has_deleted() && entry.deleted();
  const bool is_directory = entry.IsFolder();
  const syncable::ModelType model_type = entry.GetModelType();

  if (!id.ServerKnows()) {
    LOG(ERROR) << "Illegal negative id in received updates";
    return result;
  }
  {
    const std::string name = SyncerProtoUtil::NameFromSyncEntity(entry);
    if (name.empty() && !deleted) {
      LOG(ERROR) << "Zero length name in non-deleted update";
      return result;
    }
  }

  syncable::MutableEntry same_id(trans, GET_BY_ID, id);
  result.value = SyncerUtil::VerifyNewEntry(entry, &same_id, deleted);

  syncable::ModelType placement_type = !deleted ? entry.GetModelType()
      : same_id.good() ? same_id.GetModelType() : syncable::UNSPECIFIED;
  result.placement = GetGroupForModelType(placement_type, routes);

  if (VERIFY_UNDECIDED == result.value) {
    result.value = VerifyTagConsistency(entry, same_id);
  }

  if (VERIFY_UNDECIDED == result.value) {
    if (deleted)
      result.value = VERIFY_SUCCESS;
  }

  // If we have an existing entry, we check here for updates that break
  // consistency rules.
  if (VERIFY_UNDECIDED == result.value) {
    result.value = SyncerUtil::VerifyUpdateConsistency(trans, entry, &same_id,
        deleted, is_directory, model_type);
  }

  if (VERIFY_UNDECIDED == result.value)
    result.value = VERIFY_SUCCESS;  // No news is good news.

  return result;  // This might be VERIFY_SUCCESS as well
}

}  // namespace browser_sync
<|endoftext|>


<commit_before><commit_msg>linux: drop NOTIMPLEMENTED in GotFocus()<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: AGroup.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2001-10-17 18:13:31 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_GROUP_HXX_
#define _CONNECTIVITY_ADABAS_GROUP_HXX_

#ifndef _CONNECTIVITY_SDBCX_GROUP_HXX_
#include "connectivity/sdbcx/VGroup.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_AWRAPADOX_HXX_
#include "ado/Awrapadox.hxx"
#endif

namespace connectivity
{
    namespace ado
    {
        typedef sdbcx::OGroup OGroup_ADO;
        class OCatalog;

        class OAdoGroup :   public OGroup_ADO
        {
            WpADOGroup      m_aGroup;
            OCatalog*       m_pCatalog;

            sal_Int32       MapRight(RightsEnum _eNum);
            RightsEnum      Map2Right(sal_Int32 _eNum);
            ObjectTypeEnum  MapObjectType(sal_Int32 _ObjType);
        protected:
            virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const;
            virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue)throw (::com::sun::star::uno::Exception);

        public:
            virtual void refreshUsers();
        public:
            OAdoGroup(OCatalog* _pParent,sal_Bool _bCase, ADOGroup* _pGroup=NULL);
            OAdoGroup(OCatalog* _pParent,sal_Bool _bCase, const ::rtl::OUString& _Name);

            virtual void SAL_CALL acquire() throw();
            virtual void SAL_CALL release() throw();
            // com::sun::star::lang::XUnoTunnel
            virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();

            // XAuthorizable
            virtual sal_Int32 SAL_CALL getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

            WpADOGroup getImpl() const { return m_aGroup; }
        };
    }
}
#endif // _CONNECTIVITY_ADABAS_GROUP_HXX_

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.342); FILE MERGED 2005/09/05 17:25:01 rt 1.5.342.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AGroup.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:50:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_GROUP_HXX_
#define _CONNECTIVITY_ADABAS_GROUP_HXX_

#ifndef _CONNECTIVITY_SDBCX_GROUP_HXX_
#include "connectivity/sdbcx/VGroup.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_AWRAPADOX_HXX_
#include "ado/Awrapadox.hxx"
#endif

namespace connectivity
{
    namespace ado
    {
        typedef sdbcx::OGroup OGroup_ADO;
        class OCatalog;

        class OAdoGroup :   public OGroup_ADO
        {
            WpADOGroup      m_aGroup;
            OCatalog*       m_pCatalog;

            sal_Int32       MapRight(RightsEnum _eNum);
            RightsEnum      Map2Right(sal_Int32 _eNum);
            ObjectTypeEnum  MapObjectType(sal_Int32 _ObjType);
        protected:
            virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const;
            virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue)throw (::com::sun::star::uno::Exception);

        public:
            virtual void refreshUsers();
        public:
            OAdoGroup(OCatalog* _pParent,sal_Bool _bCase, ADOGroup* _pGroup=NULL);
            OAdoGroup(OCatalog* _pParent,sal_Bool _bCase, const ::rtl::OUString& _Name);

            virtual void SAL_CALL acquire() throw();
            virtual void SAL_CALL release() throw();
            // com::sun::star::lang::XUnoTunnel
            virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();

            // XAuthorizable
            virtual sal_Int32 SAL_CALL getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

            WpADOGroup getImpl() const { return m_aGroup; }
        };
    }
}
#endif // _CONNECTIVITY_ADABAS_GROUP_HXX_

<|endoftext|>


<commit_before>#include <blackhole/sink/elasticsearch.hpp>

#include "../global.hpp"

using namespace blackhole;
using blackhole::sink::elasticsearch_t;

TEST(elasticsearch_t, Class) {
    elasticsearch_t sink;
    UNUSED(sink);
}

TEST(elasticsearch_t, Manual) {
    elasticsearch_t sink;
    for (int i = 0; i < 200; ++i) {
        sink.consume((boost::format("{\"key\":%d}") % i).str());
    }
}
<commit_msg>[Testing] Simplify.<commit_after>#include <blackhole/sink/elasticsearch.hpp>

#include "../global.hpp"

using namespace blackhole;

TEST(elasticsearch_t, Class) {
    using blackhole::sink::elasticsearch_t;
    elasticsearch_t sink;
    UNUSED(sink);
}

TEST(elasticsearch_t, Manual) {
    using blackhole::sink::elasticsearch_t;
    elasticsearch_t sink;
    std::string msg = "{}";
    boost::algorithm::replace_all(msg, "'", "\"");
    for (int i = 0; i < 200; ++i) {
        sink.consume(msg);
    }
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#include "vcl/svapp.hxx"
#include "tools/fsys.hxx"
#include "tools/urlobj.hxx"
#include "osl/mutex.hxx"

#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"

#include "plugin/impl.hxx"

#pragma warning (push,1)
#pragma warning (disable:4005)

#include <prewin.h>
#include <string.h>
#include <tchar.h>
#include <objbase.h>
#include <postwin.h>

#pragma warning (pop)

#include <list>
#include <map>
#include <algorithm>

using namespace rtl;
using namespace std;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::plugin;

typedef map< OString, OUString, less< OString > > PluginLocationMap;

#if OSL_DEBUG_LEVEL > 1
#include <stdio.h>

static void logPlugin( OUString const & path_ )
{
    static FILE * s_file = 0;
    if (! s_file)
        s_file = fopen( "d:\\plugins.log", "a+" );
    OString path( OUStringToOString( path_, RTL_TEXTENCODING_ASCII_US ) );
    fprintf( s_file, "%s\n", path.getStr() );
}
#endif

//__________________________________________________________________________________________________
static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
{
    // append dll name pattern we are looking for
    TCHAR arPluginsPath[MAX_PATH];
    arPluginsPath[0] = 0;

    if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
    {
        const char * p = ::getenv( "ProgramFiles" );
        if (p)
        {
            ::lstrcpy( arPluginsPath, p );
            pPluginsPath += 14;
        }
    }
    ::lstrcat( arPluginsPath, pPluginsPath );
    ::lstrcat( arPluginsPath, _T("\\") );

    TCHAR arPluginsPattern[MAX_PATH];
    ::lstrcpy( arPluginsPattern, arPluginsPath );
    ::lstrcat( arPluginsPattern, _T("NP*.DLL") );

    WIN32_FIND_DATA aFindData;
    HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );

    while (hFind != INVALID_HANDLE_VALUE)
    {
        OString aName( aFindData.cFileName );
        aName.toAsciiLowerCase();

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            TCHAR arComplete[MAX_PATH];
            ::lstrcpy( arComplete, arPluginsPath );
            ::lstrcat( arComplete, aFindData.cFileName );

            OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
            rPlugins[ aName ] = path;
#if OSL_DEBUG_LEVEL > 1
            logPlugin( path );
#endif
        }

        if (! ::FindNextFile( hFind, &aFindData ))
            break;
    }

    if (hFind != INVALID_HANDLE_VALUE)
        ::FindClose( hFind );
}
//__________________________________________________________________________________________________
static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
{
    TCHAR arPluginsPath[MAX_PATH];
    DWORD dwPluginsPathSize = sizeof(arPluginsPath);
    arPluginsPath[dwPluginsPathSize-1] = 0;

    OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
    ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );

    addPluginsFromPath( arPluginsPath, rPlugins );
}

//__________________________________________________________________________________________________
static void add_IE_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    TCHAR arCurrent[MAX_PATH];
    DWORD dwType, dwCurrentSize = sizeof(arCurrent);

    if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
                        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
                               (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
            (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
        {
            // add \\Plugins
            ::lstrcat( arCurrent, _T("\\Plugins") );

            addPluginsFromPath( arCurrent, rPlugins );
        }
        ::RegCloseKey( hKey );
    }
}

//--------------------------------------------------------------------------------------------------
static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    // 4.7
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
    // 6
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Install Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        int n = size / sizeof (TCHAR);
        if ('\\' != value[ n -2 ])
        {
            value[ n -1 ] = '\\';
            value[ n ] = 0;
        }
        addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
    }
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
}
//--------------------------------------------------------------------------------------------------
static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
{
    add_NS_keys( hKey, rPlugins );

    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_NS_lookupRecursive( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Path"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
        INetURLObject aURL( aUPath );
        OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            rPlugins[ aName ] = aUPath;
#if OSL_DEBUG_LEVEL > 1
            logPlugin( aUPath );
#endif
        }
    }
}
static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_MozPlugin( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_NS_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    // Netscape
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla - plugins
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_MozillaPlugin( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
}

//__________________________________________________________________________________________________
static void add_SO_Plugins( PluginLocationMap & rPlugins )
{
    const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();

    const OUString * pPaths = rPaths.getConstArray();
    for ( UINT32 nPos = rPaths.getLength(); nPos--; )
    {
        addPluginsFromPath( pPaths[nPos], rPlugins );
    }
}

//__________________________________________________________________________________________________
Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
{
    Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
    static Sequence<PluginDescription > s_aDescriptions( 0 );
    static bool s_bInit = FALSE;

    if (! s_bInit)
    {
        // collect all distinct plugin dlls
        PluginLocationMap aPlugins;
        add_SO_Plugins( aPlugins );
        add_NS_Plugins( aPlugins );
        add_IE_Plugins( aPlugins );

        // collect mime types of plugin dlls
        for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
              iPos != aPlugins.end();
              ++iPos )
        {
            TCHAR arFileName[MAX_PATH];
            DWORD dwDummy, dwSize;

            // DLL name
            OUString aName( (*iPos).second.getStr() );

            OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
            ::strcpy( arFileName, aStr.getStr() );
            dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );

            if ( !dwSize )
                continue;

            char * pVersionData = new char[dwSize];
            if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
            {
                // optional comment
                OUString aComment;

                TCHAR * pInfo = NULL, * pInfo2 = NULL;
                UINT nSize = 0;
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
                                     (void**)&pInfo, &nSize ) && pInfo)
                {
                    aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
                }

                // mandatory mime type and file extensions
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
                                     (void**)&pInfo, &nSize ) && pInfo &&
                    ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
                                     (void**)&pInfo2, &nSize ) && pInfo2)
                {
                    OString aStr2( pInfo2 );
                    OString aExt( aStr2 );
                    OString aStr( pInfo );
                    OString aMIME( aStr );
                    aMIME.trim();

                    // count mime tokens
                    USHORT nToken = 0;
                    if (aMIME.getLength())
                    {
                        ++nToken;
                        for ( sal_Int32 n = aMIME.getLength(); n--; )
                        {
                            if (aMIME[ n ] == '|')
                            {
                                ++nToken;
                            }
                        }
                    }
                    sal_Int32 nIndex = 0, nIndex2 = 0;

                    UINT32 nStart = s_aDescriptions.getLength();
                    s_aDescriptions.realloc( nStart + nToken );
                    PluginDescription* pDescriptions = s_aDescriptions.getArray();
                    // for every MIME Type
                    sal_Int32 nTok = 0;
                    while (true)
                    {
                        if (nIndex < 0 || nIndex2 < 0)
                            break;

                        PluginDescription & rDescr = pDescriptions[nStart+nTok];
                        OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
                        OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
                        if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
                            continue;

                        rDescr.Mimetype = OUString(
                            aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
                        if (! rDescr.Mimetype.getLength())
                            break;

                        OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
                        rDescr.PluginName = aName;
                        rDescr.Description = aComment;

                        sal_Int32 nPos = 0, nLen = aExtToken.getLength();
                        OUString aExtensions = nLen ? OUString(RTL_CONSTASCII_USTRINGPARAM("*.")) : OUString(RTL_CONSTASCII_USTRINGPARAM("*.*"));

                        for ( ; nPos < nLen; ++nPos )
                        {
                            sal_Unicode c = aExtToken[nPos];
                            switch (c)
                            {
                            case ',':
                            case ';':
                                aExtensions += OUString(RTL_CONSTASCII_USTRINGPARAM(";*."));
                            case ' ':
                                break;
                            case '*':
                                if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
                                {
                                    ++nPos;
                                    break;
                                }
                            default:
                                aExtensions += OUString( &c, 1 );
                            }
                        }
                        rDescr.Extension = aExtensions;

                        ++nTok;
                    }

                    if (nToken != nTok)
                    {
                        s_aDescriptions.realloc( nTok );
                    }
                }
#if OSL_DEBUG_LEVEL > 1
                else
                    DBG_ERROR( "### cannot get MIME type or extensions!" );
#endif
            }
            if (pVersionData)
                delete[] pVersionData;
        }

        s_bInit = TRUE;
    }
    return s_aDescriptions;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Remove hard-coded debug stuff<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#include "vcl/svapp.hxx"
#include "tools/fsys.hxx"
#include "tools/urlobj.hxx"
#include "osl/mutex.hxx"

#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"

#include "plugin/impl.hxx"

#pragma warning (push,1)
#pragma warning (disable:4005)

#include <prewin.h>
#include <string.h>
#include <tchar.h>
#include <objbase.h>
#include <postwin.h>

#pragma warning (pop)

#include <list>
#include <map>
#include <algorithm>

using namespace rtl;
using namespace std;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::plugin;

typedef map< OString, OUString, less< OString > > PluginLocationMap;

//__________________________________________________________________________________________________
static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
{
    // append dll name pattern we are looking for
    TCHAR arPluginsPath[MAX_PATH];
    arPluginsPath[0] = 0;

    if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
    {
        const char * p = ::getenv( "ProgramFiles" );
        if (p)
        {
            ::lstrcpy( arPluginsPath, p );
            pPluginsPath += 14;
        }
    }
    ::lstrcat( arPluginsPath, pPluginsPath );
    ::lstrcat( arPluginsPath, _T("\\") );

    TCHAR arPluginsPattern[MAX_PATH];
    ::lstrcpy( arPluginsPattern, arPluginsPath );
    ::lstrcat( arPluginsPattern, _T("NP*.DLL") );

    WIN32_FIND_DATA aFindData;
    HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );

    while (hFind != INVALID_HANDLE_VALUE)
    {
        OString aName( aFindData.cFileName );
        aName.toAsciiLowerCase();

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            TCHAR arComplete[MAX_PATH];
            ::lstrcpy( arComplete, arPluginsPath );
            ::lstrcat( arComplete, aFindData.cFileName );

            OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
            rPlugins[ aName ] = path;
        }

        if (! ::FindNextFile( hFind, &aFindData ))
            break;
    }

    if (hFind != INVALID_HANDLE_VALUE)
        ::FindClose( hFind );
}
//__________________________________________________________________________________________________
static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
{
    TCHAR arPluginsPath[MAX_PATH];
    DWORD dwPluginsPathSize = sizeof(arPluginsPath);
    arPluginsPath[dwPluginsPathSize-1] = 0;

    OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
    ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );

    addPluginsFromPath( arPluginsPath, rPlugins );
}

//__________________________________________________________________________________________________
static void add_IE_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    TCHAR arCurrent[MAX_PATH];
    DWORD dwType, dwCurrentSize = sizeof(arCurrent);

    if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
                        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
                               (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
            (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
        {
            // add \\Plugins
            ::lstrcat( arCurrent, _T("\\Plugins") );

            addPluginsFromPath( arCurrent, rPlugins );
        }
        ::RegCloseKey( hKey );
    }
}

//--------------------------------------------------------------------------------------------------
static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    // 4.7
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
    // 6
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Install Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        int n = size / sizeof (TCHAR);
        if ('\\' != value[ n -2 ])
        {
            value[ n -1 ] = '\\';
            value[ n ] = 0;
        }
        addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
    }
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
}
//--------------------------------------------------------------------------------------------------
static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
{
    add_NS_keys( hKey, rPlugins );

    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_NS_lookupRecursive( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Path"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
        INetURLObject aURL( aUPath );
        OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            rPlugins[ aName ] = aUPath;
        }
    }
}
static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_MozPlugin( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_NS_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    // Netscape
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla - plugins
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_MozillaPlugin( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
}

//__________________________________________________________________________________________________
static void add_SO_Plugins( PluginLocationMap & rPlugins )
{
    const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();

    const OUString * pPaths = rPaths.getConstArray();
    for ( UINT32 nPos = rPaths.getLength(); nPos--; )
    {
        addPluginsFromPath( pPaths[nPos], rPlugins );
    }
}

//__________________________________________________________________________________________________
Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
{
    Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
    static Sequence<PluginDescription > s_aDescriptions( 0 );
    static bool s_bInit = FALSE;

    if (! s_bInit)
    {
        // collect all distinct plugin dlls
        PluginLocationMap aPlugins;
        add_SO_Plugins( aPlugins );
        add_NS_Plugins( aPlugins );
        add_IE_Plugins( aPlugins );

        // collect mime types of plugin dlls
        for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
              iPos != aPlugins.end();
              ++iPos )
        {
            TCHAR arFileName[MAX_PATH];
            DWORD dwDummy, dwSize;

            // DLL name
            OUString aName( (*iPos).second.getStr() );

            OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
            ::strcpy( arFileName, aStr.getStr() );
            dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );

            if ( !dwSize )
                continue;

            char * pVersionData = new char[dwSize];
            if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
            {
                // optional comment
                OUString aComment;

                TCHAR * pInfo = NULL, * pInfo2 = NULL;
                UINT nSize = 0;
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
                                     (void**)&pInfo, &nSize ) && pInfo)
                {
                    aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
                }

                // mandatory mime type and file extensions
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
                                     (void**)&pInfo, &nSize ) && pInfo &&
                    ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
                                     (void**)&pInfo2, &nSize ) && pInfo2)
                {
                    OString aStr2( pInfo2 );
                    OString aExt( aStr2 );
                    OString aStr( pInfo );
                    OString aMIME( aStr );
                    aMIME.trim();

                    // count mime tokens
                    USHORT nToken = 0;
                    if (aMIME.getLength())
                    {
                        ++nToken;
                        for ( sal_Int32 n = aMIME.getLength(); n--; )
                        {
                            if (aMIME[ n ] == '|')
                            {
                                ++nToken;
                            }
                        }
                    }
                    sal_Int32 nIndex = 0, nIndex2 = 0;

                    UINT32 nStart = s_aDescriptions.getLength();
                    s_aDescriptions.realloc( nStart + nToken );
                    PluginDescription* pDescriptions = s_aDescriptions.getArray();
                    // for every MIME Type
                    sal_Int32 nTok = 0;
                    while (true)
                    {
                        if (nIndex < 0 || nIndex2 < 0)
                            break;

                        PluginDescription & rDescr = pDescriptions[nStart+nTok];
                        OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
                        OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
                        if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
                            continue;

                        rDescr.Mimetype = OUString(
                            aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
                        if (! rDescr.Mimetype.getLength())
                            break;

                        OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
                        rDescr.PluginName = aName;
                        rDescr.Description = aComment;

                        sal_Int32 nPos = 0, nLen = aExtToken.getLength();
                        OUString aExtensions = nLen ? OUString(RTL_CONSTASCII_USTRINGPARAM("*.")) : OUString(RTL_CONSTASCII_USTRINGPARAM("*.*"));

                        for ( ; nPos < nLen; ++nPos )
                        {
                            sal_Unicode c = aExtToken[nPos];
                            switch (c)
                            {
                            case ',':
                            case ';':
                                aExtensions += OUString(RTL_CONSTASCII_USTRINGPARAM(";*."));
                            case ' ':
                                break;
                            case '*':
                                if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
                                {
                                    ++nPos;
                                    break;
                                }
                            default:
                                aExtensions += OUString( &c, 1 );
                            }
                        }
                        rDescr.Extension = aExtensions;

                        ++nTok;
                    }

                    if (nToken != nTok)
                    {
                        s_aDescriptions.realloc( nTok );
                    }
                }
#if OSL_DEBUG_LEVEL > 1
                else
                    DBG_ERROR( "### cannot get MIME type or extensions!" );
#endif
            }
            if (pVersionData)
                delete[] pVersionData;
        }

        s_bInit = TRUE;
    }
    return s_aDescriptions;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>Coverity: Remove unnecessary GetPasswordFormAt call.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/ref_counted.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/test/automation/dom_element_proxy.h"
#include "chrome/test/automation/javascript_execution_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

// Tests the DOMAutomation framework for manipulating DOMElements within
// browser tests.
class DOMAutomationTest : public InProcessBrowserTest {
 public:
  DOMAutomationTest() {
    EnableDOMAutomation();
    JavaScriptExecutionController::set_timeout(30000);
  }

  GURL GetTestURL(const char* path) {
    std::string url_path = "files/dom_automation/";
    url_path.append(path);
    return test_server()->GetURL(url_path);
  }
};

typedef DOMElementProxy::By By;

#if defined(OS_WIN)
// See http://crbug.com/61636
#define MAYBE_FindByXPath FLAKY_FindByXPath
#else
#define MAYBE_FindByXPath FindByXPath
#endif

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, MAYBE_FindByXPath) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_div = main_doc->FindElement(By::XPath("//div"));
  ASSERT_TRUE(first_div);
  ASSERT_NO_FATAL_FAILURE(first_div->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//div"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::XPath("//nosuchtag")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//nosuchtag"), &elements));
  elements.clear();
  ASSERT_EQ(0u, elements.size());

  // Find with invalid xpath.
  ASSERT_FALSE(main_doc->FindElement(By::XPath("'invalid'")));
  ASSERT_FALSE(main_doc->FindElement(By::XPath(" / / ")));
  ASSERT_FALSE(main_doc->FindElements(By::XPath("'invalid'"), &elements));
  ASSERT_FALSE(main_doc->FindElements(By::XPath(" / / "), &elements));

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::XPath("/html/body/span"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::XPath("./span"));
  }
  ASSERT_EQ(3, nested_count);
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, FindBySelectors) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_myclass =
      main_doc->FindElement(By::Selectors(".myclass"));
  ASSERT_TRUE(first_myclass);
  ASSERT_NO_FATAL_FAILURE(first_myclass->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::Selectors(".myclass"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::Selectors("#nosuchid")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::Selectors("#nosuchid"), &elements));
  ASSERT_EQ(0u, elements.size());

  // Find with invalid selectors.
  ASSERT_FALSE(main_doc->FindElement(By::Selectors("1#2")));
  ASSERT_FALSE(main_doc->FindElements(By::Selectors("1#2"), &elements));

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::Selectors("span"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::Selectors("span"));
  }
  ASSERT_EQ(3, nested_count);
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, FindByText) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_text = main_doc->FindElement(By::Text("div_text"));
  ASSERT_TRUE(first_text);
  ASSERT_NO_FATAL_FAILURE(first_text->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::Text("div_text"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::Text("nosuchtext")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::Text("nosuchtext"), &elements));
  ASSERT_EQ(0u, elements.size());

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::Text("span_text"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::Text("span_text"));
  }
  ASSERT_EQ(3, nested_count);

  // Find only visible text.
  DOMElementProxyRef shown_td = main_doc->FindElement(By::Text("table_text"));
  ASSERT_TRUE(shown_td);
  ASSERT_NO_FATAL_FAILURE(shown_td->EnsureNameMatches("shown"));

  // Find text in inputs.
  ASSERT_TRUE(main_doc->FindElement(By::Text("textarea_text")));
  ASSERT_TRUE(main_doc->FindElement(By::Text("input_text")));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitFor1VisibleElement) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef div =
      main_doc->WaitFor1VisibleElement(By::Selectors("div"));
  ASSERT_TRUE(div.get());
  ASSERT_NO_FATAL_FAILURE(div->EnsureInnerHTMLMatches("div_inner"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitForElementsToDisappear) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  ASSERT_TRUE(main_doc->WaitForElementsToDisappear(By::Selectors("img")));
  std::vector<DOMElementProxyRef> img_elements;
  ASSERT_TRUE(main_doc->FindElements(By::Selectors("img"), &img_elements));
  ASSERT_EQ(0u, img_elements.size());
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, EnsureAttributeEventuallyMatches) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef anchor = main_doc->FindElement(By::Selectors("a"));
  ASSERT_TRUE(anchor.get());
  ASSERT_NO_FATAL_FAILURE(anchor->EnsureAttributeEventuallyMatches(
      "href", "http://www.google.com"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Frames) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("frames/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Get both frame elements.
  std::vector<DOMElementProxyRef> frame_elements;
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//frame"), &frame_elements));
  ASSERT_EQ(2u, frame_elements.size());

  // Get both frames, checking their contents are correct.
  DOMElementProxyRef frame1 = frame_elements[0]->GetContentDocument();
  DOMElementProxyRef frame2 = frame_elements[1]->GetContentDocument();
  ASSERT_TRUE(frame1 && frame2);
  DOMElementProxyRef frame_div =
      frame1->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 1"));
  frame_div = frame2->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 2"));

  // Get both inner iframes, checking their contents are correct.
  DOMElementProxyRef iframe1 =
      frame1->GetDocumentFromFrame("0");
  DOMElementProxyRef iframe2 =
      frame2->GetDocumentFromFrame("0");
  ASSERT_TRUE(iframe1 && iframe2);
  frame_div = iframe1->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 1"));
  frame_div = iframe2->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 2"));

  // Get nested frame.
  ASSERT_EQ(iframe1.get(), main_doc->GetDocumentFromFrame("0", "0").get());
  ASSERT_EQ(iframe2.get(), main_doc->GetDocumentFromFrame("1", "0").get());
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Events) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("events/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Click link and make sure text changes.
  DOMElementProxyRef link = main_doc->FindElement(By::Selectors("a"));
  ASSERT_TRUE(link && link->Click());
  ASSERT_NO_FATAL_FAILURE(link->EnsureTextMatches("clicked"));

  // Click input button and make sure textfield changes.
  DOMElementProxyRef button = main_doc->FindElement(By::Selectors("#button"));
  DOMElementProxyRef textfield =
      main_doc->FindElement(By::Selectors("#textfield"));
  ASSERT_TRUE(textfield && button && button->Click());
  ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("clicked"));

  // Type in the textfield.
  ASSERT_TRUE(textfield->SetText("test"));
  ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("test"));

  // Type in the textarea.
  DOMElementProxyRef textarea =
      main_doc->FindElement(By::Selectors("textarea"));
  ASSERT_TRUE(textarea && textarea->Type("test"));
  ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches("textareatest"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, StringEscape) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("string_escape/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef textarea =
      main_doc->FindElement(By::Selectors("textarea"));
  ASSERT_TRUE(textarea);
  ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(WideToUTF8(L"\u00FF")));

  const wchar_t* set_and_expect_strings[] = {
      L"\u00FF and \u00FF",
      L"\n \t \\",
      L"' \""
  };
  for (size_t i = 0; i < 3; i++) {
    ASSERT_TRUE(textarea->SetText(WideToUTF8(set_and_expect_strings[i])));
    ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(
        WideToUTF8(set_and_expect_strings[i])));
  }
}

}  // namespace
<commit_msg>Disable flaky tests that are hanging.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/ref_counted.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/test/automation/dom_element_proxy.h"
#include "chrome/test/automation/javascript_execution_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

// Tests the DOMAutomation framework for manipulating DOMElements within
// browser tests.
class DOMAutomationTest : public InProcessBrowserTest {
 public:
  DOMAutomationTest() {
    EnableDOMAutomation();
    JavaScriptExecutionController::set_timeout(30000);
  }

  GURL GetTestURL(const char* path) {
    std::string url_path = "files/dom_automation/";
    url_path.append(path);
    return test_server()->GetURL(url_path);
  }
};

typedef DOMElementProxy::By By;

#if defined(OS_WIN)
// See http://crbug.com/61636
#define MAYBE_FindByXPath DISABLED_FindByXPath
#define MAYBE_FindBySelectors DISABLED_FindByXPath
#define MAYBE_FindByText DISABLED_FindByText
#else
#define MAYBE_FindByXPath FindByXPath
#define MAYBE_FindBySelectors FindBySelectors
#define MAYBE_FindByText FindByText
#endif

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, MAYBE_FindByXPath) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_div = main_doc->FindElement(By::XPath("//div"));
  ASSERT_TRUE(first_div);
  ASSERT_NO_FATAL_FAILURE(first_div->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//div"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::XPath("//nosuchtag")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//nosuchtag"), &elements));
  elements.clear();
  ASSERT_EQ(0u, elements.size());

  // Find with invalid xpath.
  ASSERT_FALSE(main_doc->FindElement(By::XPath("'invalid'")));
  ASSERT_FALSE(main_doc->FindElement(By::XPath(" / / ")));
  ASSERT_FALSE(main_doc->FindElements(By::XPath("'invalid'"), &elements));
  ASSERT_FALSE(main_doc->FindElements(By::XPath(" / / "), &elements));

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::XPath("/html/body/span"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::XPath("./span"));
  }
  ASSERT_EQ(3, nested_count);
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, FindBySelectors) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_myclass =
      main_doc->FindElement(By::Selectors(".myclass"));
  ASSERT_TRUE(first_myclass);
  ASSERT_NO_FATAL_FAILURE(first_myclass->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::Selectors(".myclass"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::Selectors("#nosuchid")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::Selectors("#nosuchid"), &elements));
  ASSERT_EQ(0u, elements.size());

  // Find with invalid selectors.
  ASSERT_FALSE(main_doc->FindElement(By::Selectors("1#2")));
  ASSERT_FALSE(main_doc->FindElements(By::Selectors("1#2"), &elements));

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::Selectors("span"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::Selectors("span"));
  }
  ASSERT_EQ(3, nested_count);
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, FindByText) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("find_elements/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Find first element.
  DOMElementProxyRef first_text = main_doc->FindElement(By::Text("div_text"));
  ASSERT_TRUE(first_text);
  ASSERT_NO_FATAL_FAILURE(first_text->EnsureNameMatches("0"));

  // Find many elements.
  std::vector<DOMElementProxyRef> elements;
  ASSERT_TRUE(main_doc->FindElements(By::Text("div_text"), &elements));
  ASSERT_EQ(2u, elements.size());
  for (size_t i = 0; i < elements.size(); i++) {
    ASSERT_NO_FATAL_FAILURE(elements[i]->EnsureNameMatches(
        base::UintToString(i)));
  }

  // Find 0 elements.
  ASSERT_FALSE(main_doc->FindElement(By::Text("nosuchtext")));
  elements.clear();
  ASSERT_TRUE(main_doc->FindElements(By::Text("nosuchtext"), &elements));
  ASSERT_EQ(0u, elements.size());

  // Find nested elements.
  int nested_count = 0;
  std::string span_name;
  DOMElementProxyRef node = main_doc->FindElement(By::Text("span_text"));
  while (node) {
    nested_count++;
    span_name.append("span");
    ASSERT_NO_FATAL_FAILURE(node->EnsureNameMatches(span_name));
    node = node->FindElement(By::Text("span_text"));
  }
  ASSERT_EQ(3, nested_count);

  // Find only visible text.
  DOMElementProxyRef shown_td = main_doc->FindElement(By::Text("table_text"));
  ASSERT_TRUE(shown_td);
  ASSERT_NO_FATAL_FAILURE(shown_td->EnsureNameMatches("shown"));

  // Find text in inputs.
  ASSERT_TRUE(main_doc->FindElement(By::Text("textarea_text")));
  ASSERT_TRUE(main_doc->FindElement(By::Text("input_text")));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitFor1VisibleElement) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef div =
      main_doc->WaitFor1VisibleElement(By::Selectors("div"));
  ASSERT_TRUE(div.get());
  ASSERT_NO_FATAL_FAILURE(div->EnsureInnerHTMLMatches("div_inner"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, WaitForElementsToDisappear) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  ASSERT_TRUE(main_doc->WaitForElementsToDisappear(By::Selectors("img")));
  std::vector<DOMElementProxyRef> img_elements;
  ASSERT_TRUE(main_doc->FindElements(By::Selectors("img"), &img_elements));
  ASSERT_EQ(0u, img_elements.size());
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, EnsureAttributeEventuallyMatches) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("wait/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef anchor = main_doc->FindElement(By::Selectors("a"));
  ASSERT_TRUE(anchor.get());
  ASSERT_NO_FATAL_FAILURE(anchor->EnsureAttributeEventuallyMatches(
      "href", "http://www.google.com"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Frames) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("frames/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Get both frame elements.
  std::vector<DOMElementProxyRef> frame_elements;
  ASSERT_TRUE(main_doc->FindElements(By::XPath("//frame"), &frame_elements));
  ASSERT_EQ(2u, frame_elements.size());

  // Get both frames, checking their contents are correct.
  DOMElementProxyRef frame1 = frame_elements[0]->GetContentDocument();
  DOMElementProxyRef frame2 = frame_elements[1]->GetContentDocument();
  ASSERT_TRUE(frame1 && frame2);
  DOMElementProxyRef frame_div =
      frame1->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 1"));
  frame_div = frame2->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("frame 2"));

  // Get both inner iframes, checking their contents are correct.
  DOMElementProxyRef iframe1 =
      frame1->GetDocumentFromFrame("0");
  DOMElementProxyRef iframe2 =
      frame2->GetDocumentFromFrame("0");
  ASSERT_TRUE(iframe1 && iframe2);
  frame_div = iframe1->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 1"));
  frame_div = iframe2->FindElement(By::XPath("/html/body/div"));
  ASSERT_TRUE(frame_div);
  ASSERT_NO_FATAL_FAILURE(frame_div->EnsureInnerHTMLMatches("iframe 2"));

  // Get nested frame.
  ASSERT_EQ(iframe1.get(), main_doc->GetDocumentFromFrame("0", "0").get());
  ASSERT_EQ(iframe2.get(), main_doc->GetDocumentFromFrame("1", "0").get());
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, Events) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(), GetTestURL("events/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  // Click link and make sure text changes.
  DOMElementProxyRef link = main_doc->FindElement(By::Selectors("a"));
  ASSERT_TRUE(link && link->Click());
  ASSERT_NO_FATAL_FAILURE(link->EnsureTextMatches("clicked"));

  // Click input button and make sure textfield changes.
  DOMElementProxyRef button = main_doc->FindElement(By::Selectors("#button"));
  DOMElementProxyRef textfield =
      main_doc->FindElement(By::Selectors("#textfield"));
  ASSERT_TRUE(textfield && button && button->Click());
  ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("clicked"));

  // Type in the textfield.
  ASSERT_TRUE(textfield->SetText("test"));
  ASSERT_NO_FATAL_FAILURE(textfield->EnsureTextMatches("test"));

  // Type in the textarea.
  DOMElementProxyRef textarea =
      main_doc->FindElement(By::Selectors("textarea"));
  ASSERT_TRUE(textarea && textarea->Type("test"));
  ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches("textareatest"));
}

IN_PROC_BROWSER_TEST_F(DOMAutomationTest, StringEscape) {
  ASSERT_TRUE(test_server()->Start());
  ui_test_utils::NavigateToURL(browser(),
                               GetTestURL("string_escape/test.html"));
  DOMElementProxyRef main_doc = ui_test_utils::GetActiveDOMDocument(browser());

  DOMElementProxyRef textarea =
      main_doc->FindElement(By::Selectors("textarea"));
  ASSERT_TRUE(textarea);
  ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(WideToUTF8(L"\u00FF")));

  const wchar_t* set_and_expect_strings[] = {
      L"\u00FF and \u00FF",
      L"\n \t \\",
      L"' \""
  };
  for (size_t i = 0; i < 3; i++) {
    ASSERT_TRUE(textarea->SetText(WideToUTF8(set_and_expect_strings[i])));
    ASSERT_NO_FATAL_FAILURE(textarea->EnsureTextMatches(
        WideToUTF8(set_and_expect_strings[i])));
  }
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/keyboard_codes.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "views/event.h"

// This functionality currently works on Windows and on Linux when
// toolkit_views is defined (i.e. for Chrome OS). It's not needed
// on the Mac, and it's not yet implemented on Linux.
#if defined(TOOLKIT_VIEWS)

namespace {

class KeyboardAccessTest : public UITest {
 public:
  KeyboardAccessTest() {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  // Use the keyboard to select "New Tab" from the app menu.
  // This test depends on the fact that there is one menu and that
  // New Tab is the first item in the menu. If the menus change,
  // this test will need to be changed to reflect that.
  //
  // If alternate_key_sequence is true, use "Alt" instead of "F10" to
  // open the menu bar, and "Down" instead of "Enter" to open a menu.
  void TestMenuKeyboardAccess(bool alternate_key_sequence, int modifiers);

  DISALLOW_COPY_AND_ASSIGN(KeyboardAccessTest);
};

void KeyboardAccessTest::TestMenuKeyboardAccess(bool alternate_key_sequence,
                                                int modifiers) {
  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window = browser->GetWindow();
  ASSERT_TRUE(window.get());

  // Navigate to a page in the first tab, which makes sure that focus is
  // set to the browser window.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  ASSERT_TRUE(tab->NavigateToURL(GURL("about:")));

  // The initial tab index should be 0.
  int tab_index = -1;
  ASSERT_TRUE(browser->GetActiveTabIndex(&tab_index));
  ASSERT_EQ(0, tab_index);

  // Get the focused view ID, then press a key to activate the
  // page menu, then wait until the focused view changes.
  int original_view_id = -1;
  ASSERT_TRUE(window->GetFocusedViewID(&original_view_id));

  app::KeyboardCode menu_key =
      alternate_key_sequence ? app::VKEY_MENU : app::VKEY_F10;
#if defined(OS_CHROMEOS)
  // Chrome OS has different function key accelerators, so we always use the
  // menu key there.
  menu_key = app::VKEY_MENU;
#endif
  ASSERT_TRUE(window->SimulateOSKeyPress(menu_key, modifiers));

  if (modifiers) {
    // Verify Chrome does not move the view focus. We should not move the view
    // focus when typing a menu key with modifier keys, such as shift keys or
    // control keys.
    int new_view_id = -1;
    ASSERT_TRUE(window->GetFocusedViewID(&new_view_id));
    ASSERT_EQ(original_view_id, new_view_id);
    return;
  }

  int new_view_id = -1;
  ASSERT_TRUE(window->WaitForFocusedViewIDToChange(
      original_view_id, &new_view_id));

  ASSERT_TRUE(browser->StartTrackingPopupMenus());

  if (alternate_key_sequence)
    ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_DOWN, 0));
  else
    ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_RETURN, 0));

  // Wait until the popup menu actually opens.
  ASSERT_TRUE(browser->WaitForPopupMenuToOpen());

  // Press DOWN to select the first item, then RETURN to select it.
  ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_DOWN, 0));
  ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_RETURN, 0));

  // Wait for the new tab to appear.
  ASSERT_TRUE(browser->WaitForTabCountToBecome(2));

  // Make sure that the new tab index is 1.
  ASSERT_TRUE(browser->GetActiveTabIndex(&tab_index));
  ASSERT_EQ(1, tab_index);
}

TEST_F(KeyboardAccessTest, TestMenuKeyboardAccess) {
  TestMenuKeyboardAccess(false, 0);
}

TEST_F(KeyboardAccessTest, TestAltMenuKeyboardAccess) {
  TestMenuKeyboardAccess(true, 0);
}

TEST_F(KeyboardAccessTest, TestShiftAltMenuKeyboardAccess) {
  TestMenuKeyboardAccess(true, views::Event::EF_SHIFT_DOWN);
}

// Test that JavaScript cannot intercept reserved keyboard accelerators like
// ctrl-t to open a new tab or ctrl-f4 to close a tab.
TEST_F(KeyboardAccessTest, ReserveKeyboardAccelerators) {
  const std::string kBadPage =
      "";
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser);
  ASSERT_TRUE(browser->AppendTab(GURL("data:text/html," + kBadPage)));
  int tab_count = 0;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(tab_count, 2);

  int active_tab = 0;
  ASSERT_TRUE(browser->GetActiveTabIndex(&active_tab));
  ASSERT_EQ(active_tab, 1);

  scoped_refptr<WindowProxy> window(browser->GetWindow());
  ASSERT_TRUE(window);
  ASSERT_TRUE(window->SimulateOSKeyPress(
      app::VKEY_TAB, views::Event::EF_CONTROL_DOWN));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));

#if !defined(OS_MACOSX)  // see BrowserWindowCocoa::GetCommandId
  ASSERT_TRUE(browser->ActivateTab(1));
  ASSERT_TRUE(window->SimulateOSKeyPress(
      app::VKEY_F4, views::Event::EF_CONTROL_DOWN));
  ASSERT_TRUE(browser->WaitForTabCountToBecome(1));
#endif
}

}  // namespace

#endif  // defined(TOOLKIT_VIEWS)
<commit_msg>Disable KeyboardAccessTest.ReserveKeyboardAccelerators on ChromeOS<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/keyboard_codes.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "views/event.h"

// This functionality currently works on Windows and on Linux when
// toolkit_views is defined (i.e. for Chrome OS). It's not needed
// on the Mac, and it's not yet implemented on Linux.
#if defined(TOOLKIT_VIEWS)

namespace {

class KeyboardAccessTest : public UITest {
 public:
  KeyboardAccessTest() {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  // Use the keyboard to select "New Tab" from the app menu.
  // This test depends on the fact that there is one menu and that
  // New Tab is the first item in the menu. If the menus change,
  // this test will need to be changed to reflect that.
  //
  // If alternate_key_sequence is true, use "Alt" instead of "F10" to
  // open the menu bar, and "Down" instead of "Enter" to open a menu.
  void TestMenuKeyboardAccess(bool alternate_key_sequence, int modifiers);

  DISALLOW_COPY_AND_ASSIGN(KeyboardAccessTest);
};

void KeyboardAccessTest::TestMenuKeyboardAccess(bool alternate_key_sequence,
                                                int modifiers) {
  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window = browser->GetWindow();
  ASSERT_TRUE(window.get());

  // Navigate to a page in the first tab, which makes sure that focus is
  // set to the browser window.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  ASSERT_TRUE(tab->NavigateToURL(GURL("about:")));

  // The initial tab index should be 0.
  int tab_index = -1;
  ASSERT_TRUE(browser->GetActiveTabIndex(&tab_index));
  ASSERT_EQ(0, tab_index);

  // Get the focused view ID, then press a key to activate the
  // page menu, then wait until the focused view changes.
  int original_view_id = -1;
  ASSERT_TRUE(window->GetFocusedViewID(&original_view_id));

  app::KeyboardCode menu_key =
      alternate_key_sequence ? app::VKEY_MENU : app::VKEY_F10;
#if defined(OS_CHROMEOS)
  // Chrome OS has different function key accelerators, so we always use the
  // menu key there.
  menu_key = app::VKEY_MENU;
#endif
  ASSERT_TRUE(window->SimulateOSKeyPress(menu_key, modifiers));

  if (modifiers) {
    // Verify Chrome does not move the view focus. We should not move the view
    // focus when typing a menu key with modifier keys, such as shift keys or
    // control keys.
    int new_view_id = -1;
    ASSERT_TRUE(window->GetFocusedViewID(&new_view_id));
    ASSERT_EQ(original_view_id, new_view_id);
    return;
  }

  int new_view_id = -1;
  ASSERT_TRUE(window->WaitForFocusedViewIDToChange(
      original_view_id, &new_view_id));

  ASSERT_TRUE(browser->StartTrackingPopupMenus());

  if (alternate_key_sequence)
    ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_DOWN, 0));
  else
    ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_RETURN, 0));

  // Wait until the popup menu actually opens.
  ASSERT_TRUE(browser->WaitForPopupMenuToOpen());

  // Press DOWN to select the first item, then RETURN to select it.
  ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_DOWN, 0));
  ASSERT_TRUE(window->SimulateOSKeyPress(app::VKEY_RETURN, 0));

  // Wait for the new tab to appear.
  ASSERT_TRUE(browser->WaitForTabCountToBecome(2));

  // Make sure that the new tab index is 1.
  ASSERT_TRUE(browser->GetActiveTabIndex(&tab_index));
  ASSERT_EQ(1, tab_index);
}

TEST_F(KeyboardAccessTest, TestMenuKeyboardAccess) {
  TestMenuKeyboardAccess(false, 0);
}

TEST_F(KeyboardAccessTest, TestAltMenuKeyboardAccess) {
  TestMenuKeyboardAccess(true, 0);
}

TEST_F(KeyboardAccessTest, TestShiftAltMenuKeyboardAccess) {
  TestMenuKeyboardAccess(true, views::Event::EF_SHIFT_DOWN);
}

// TODO(isherman): This test times out on ChromeOS.  We should merge it with
// BrowserKeyEventsTest.ReservedAccelerators, but just disable for now.
#if defined(OS_CHROMEOS)
#define MAYBE_ReserveKeyboardAccelerators DISABLED_ReserveKeyboardAccelerators
#else
#define MAYBE_ReserveKeyboardAccelerators ReserveKeyboardAccelerators
#endif

// Test that JavaScript cannot intercept reserved keyboard accelerators like
// ctrl-t to open a new tab or ctrl-f4 to close a tab.
TEST_F(KeyboardAccessTest, MAYBE_ReserveKeyboardAccelerators) {
  const std::string kBadPage =
      "";
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser);
  ASSERT_TRUE(browser->AppendTab(GURL("data:text/html," + kBadPage)));
  int tab_count = 0;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(tab_count, 2);

  int active_tab = 0;
  ASSERT_TRUE(browser->GetActiveTabIndex(&active_tab));
  ASSERT_EQ(active_tab, 1);

  scoped_refptr<WindowProxy> window(browser->GetWindow());
  ASSERT_TRUE(window);
  ASSERT_TRUE(window->SimulateOSKeyPress(
      app::VKEY_TAB, views::Event::EF_CONTROL_DOWN));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));

#if !defined(OS_MACOSX)  // see BrowserWindowCocoa::GetCommandId
  ASSERT_TRUE(browser->ActivateTab(1));
  ASSERT_TRUE(window->SimulateOSKeyPress(
      app::VKEY_F4, views::Event::EF_CONTROL_DOWN));
  ASSERT_TRUE(browser->WaitForTabCountToBecome(1));
#endif
}

}  // namespace

#endif  // defined(TOOLKIT_VIEWS)
<|endoftext|>


<commit_before>#include "NTClient.h"
using namespace std;

NTClient::NTClient() {
	hasError = false;
	firstConnect = true;
	connected = false;
}
bool NTClient::login(string username, string password) {
	uname = username;
	pword = password;
	bool ret = true;
	string data = string("username=");
	data += uname;
	data += "&password=";
	data += pword;
	data += "&adb=1&tz=America%2FChicago"; // No need to have anything other than Chicago timezone
	httplib::SSLClient loginReq(NITROTYPE_HOSTNAME, HTTPS_PORT);
	shared_ptr<httplib::Response> res = loginReq.post(NT_LOGIN_ENDPOINT, data, "application/x-www-form-urlencoded; charset=UTF-8");
	if (res) {
		bool foundLoginCookie = false;
		for (int i = 0; i < res->cookies.size(); ++i) {
			string cookie = res->cookies.at(i);
			addCookie(Utils::extractCKey(cookie), Utils::extractCValue(cookie));
			if (cookie.find("ntuserrem=") == 0) {
				foundLoginCookie = true;
				token = Utils::extractCValue(cookie);
				cout << "Retrieved login token: " << token << endl;
				// addCookie("ntuserrem", token);
			}
		}
		if (!foundLoginCookie) {
			ret = false;
			cout << "Unable to locate the login cookie. Maybe try a different account?\n";
		}
	} else {
		ret = false;
		cout << "Login request failed. This might be a network issue. Maybe try resetting your internet connection?\n";
	}
	bool success = getPrimusSID();
	if (!success) return false;
	return ret;
}
bool NTClient::connect() {
	wsh = new Hub();
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream uristream;
	uristream  << "wss://realtime1.nitrotype.com:443/realtime/?_primuscb=" << tnow << "-0&EIO=3&transport=websocket&sid=" << primusSid << "&t=" << tnow << "&b64=1";
	string wsURI = uristream.str();
	cout << "Connecting to endpoint: " << wsURI << endl;
	if (firstConnect) {
		addListeners();
	}
	// cout << "Cookies: " << rawCookieStr << endl << endl;
	// Create override headers
	SMap customHeaders;
	customHeaders["Cookie"] = rawCookieStr;
	customHeaders["Origin"] = "https://www.nitrotype.com";
	customHeaders["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36";
	// customHeaders["Host"] = "realtime1.nitrotype.com";
	wsh->connect(wsURI, (void*)this, customHeaders, 7000);
	// wsh->connect(wsURI);
	if (firstConnect) {
		wsh->run();
		firstConnect = false;
	}
	return true;
}
void NTClient::addCookie(string key, string val) {
	SPair sp = SPair(key, val);
	cookies.push_back(sp);
}
bool NTClient::getPrimusSID() {
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream squery;
	squery << "?_primuscb=" << tnow << "-0&EIO=3&transport=polling&t=" << tnow << "-0&b64=1";
	string queryStr = squery.str();

	httplib::SSLClient loginReq(NT_REALTIME_HOST, HTTPS_PORT);
	string path = NT_PRIMUS_ENDPOINT + queryStr;
	shared_ptr<httplib::Response> res = loginReq.get(path.c_str(), rawCookieStr.c_str());
	if (res) {
		json jres = json::parse(res->body.substr(4, res->body.length()));
		primusSid = jres["sid"];
		cout << "Resolved primus SID: " << primusSid << endl;
		// addCookie("io", primusSid);
	} else {
		cout << "Error retrieving primus handshake data.\n";
		return false;
	}
	return true;
}
string NTClient::getJoinPacket(int avgSpeed) {
	stringstream ss;
	ss << "4{\"stream\":\"race\",\"msg\":\"join\",\"payload\":{\"debugging\":false,\"avgSpeed\":"
	<< avgSpeed
	<< ",\"forceEarlyPlace\":true,\"track\":\"desert\",\"music\":\"city_nights\"}}";
	return ss.str();
}
void NTClient::addListeners() {
	assert(wsh != nullptr);
	wsh->onError([this](void* udata) {
		cout << "Failed to connect to WebSocket server." << endl;
		hasError = true;
	});
	wsh->onConnection([this](WebSocket<CLIENT>* wsocket, HttpRequest req) {
		cout << "Connected to the realtime server." << endl;
		onConnection(wsocket, req);
	});
	wsh->onDisconnection([this](WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
		cout << "Disconnected from the realtime server." << endl;
		onDisconnection(wsocket, code, msg, len);
	});
	wsh->onMessage([this](WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
		onMessage(ws, msg, len, opCode);
	});
}
void NTClient::onDisconnection(WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
	cout << "Disconn message: " << string(msg, len) << endl;
	cout << "Disconn code: " << code << endl;
}
void NTClient::onMessage(WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
	if (opCode != OpCode::TEXT) {
		cout << "The realtime server did not send a text packet for some reason, ignoring.\n";
		return;
	}
	string smsg = string(msg, len);
	cout << "Recieved WebSocket message: '" << smsg << "'\n";
}
void NTClient::onConnection(WebSocket<CLIENT>* wsocket, HttpRequest req) {
	// Send a probe, which is required for connection
	wsocket->send("2probe", OpCode::TEXT);
	cout << "Requesting for a race in 1 second." << endl;
	this_thread::sleep_for(chrono::seconds(1));
	string joinTo = getJoinPacket(20); // 100 WPM just to test
	cout << joinTo << endl;
	wsocket->send(joinTo.c_str());
}<commit_msg>Improve websocket communication<commit_after>#include "NTClient.h"
using namespace std;

NTClient::NTClient() {
	hasError = false;
	firstConnect = true;
	connected = false;
}
bool NTClient::login(string username, string password) {
	uname = username;
	pword = password;
	bool ret = true;
	string data = string("username=");
	data += uname;
	data += "&password=";
	data += pword;
	data += "&adb=1&tz=America%2FChicago"; // No need to have anything other than Chicago timezone
	httplib::SSLClient loginReq(NITROTYPE_HOSTNAME, HTTPS_PORT);
	shared_ptr<httplib::Response> res = loginReq.post(NT_LOGIN_ENDPOINT, data, "application/x-www-form-urlencoded; charset=UTF-8");
	if (res) {
		bool foundLoginCookie = false;
		for (int i = 0; i < res->cookies.size(); ++i) {
			string cookie = res->cookies.at(i);
			addCookie(Utils::extractCKey(cookie), Utils::extractCValue(cookie));
			if (cookie.find("ntuserrem=") == 0) {
				foundLoginCookie = true;
				token = Utils::extractCValue(cookie);
				cout << "Retrieved login token: " << token << endl;
				// addCookie("ntuserrem", token);
			}
		}
		if (!foundLoginCookie) {
			ret = false;
			cout << "Unable to locate the login cookie. Maybe try a different account?\n";
		}
	} else {
		ret = false;
		cout << "Login request failed. This might be a network issue. Maybe try resetting your internet connection?\n";
	}
	bool success = getPrimusSID();
	if (!success) return false;
	return ret;
}
bool NTClient::connect() {
	wsh = new Hub();
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream uristream;
	uristream  << "wss://realtime1.nitrotype.com:443/realtime/?_primuscb=" << tnow << "-0&EIO=3&transport=websocket&sid=" << primusSid << "&t=" << tnow << "&b64=1";
	string wsURI = uristream.str();
	cout << "Connecting to endpoint: " << wsURI << endl;
	if (firstConnect) {
		addListeners();
	}
	// cout << "Cookies: " << rawCookieStr << endl << endl;
	// Create override headers
	SMap customHeaders;
	customHeaders["Cookie"] = rawCookieStr;
	customHeaders["Origin"] = "https://www.nitrotype.com";
	customHeaders["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36";
	// customHeaders["Host"] = "realtime1.nitrotype.com";
	wsh->connect(wsURI, (void*)this, customHeaders, 7000);
	// wsh->connect(wsURI);
	if (firstConnect) {
		wsh->run();
		firstConnect = false;
	}
	return true;
}
void NTClient::addCookie(string key, string val) {
	SPair sp = SPair(key, val);
	cookies.push_back(sp);
}
bool NTClient::getPrimusSID() {
	time_t tnow = time(0);
	rawCookieStr = Utils::stringifyCookies(&cookies);
	stringstream squery;
	squery << "?_primuscb=" << tnow << "-0&EIO=3&transport=polling&t=" << tnow << "-0&b64=1";
	string queryStr = squery.str();

	httplib::SSLClient loginReq(NT_REALTIME_HOST, HTTPS_PORT);
	string path = NT_PRIMUS_ENDPOINT + queryStr;
	shared_ptr<httplib::Response> res = loginReq.get(path.c_str(), rawCookieStr.c_str());
	if (res) {
		json jres = json::parse(res->body.substr(4, res->body.length()));
		primusSid = jres["sid"];
		cout << "Resolved primus SID: " << primusSid << endl;
		// addCookie("io", primusSid);
	} else {
		cout << "Error retrieving primus handshake data.\n";
		return false;
	}
	return true;
}
string NTClient::getJoinPacket(int avgSpeed) {
	stringstream ss;
	ss << "4{\"stream\":\"race\",\"msg\":\"join\",\"payload\":{\"debugging\":false,\"avgSpeed\":"
	<< avgSpeed
	<< ",\"forceEarlyPlace\":true,\"track\":\"desert\",\"music\":\"city_nights\"}}";
	return ss.str();
}
void NTClient::addListeners() {
	assert(wsh != nullptr);
	wsh->onError([this](void* udata) {
		cout << "Failed to connect to WebSocket server." << endl;
		hasError = true;
	});
	wsh->onConnection([this](WebSocket<CLIENT>* wsocket, HttpRequest req) {
		cout << "Realtime socket open." << endl;
		onConnection(wsocket, req);
	});
	wsh->onDisconnection([this](WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
		cout << "Disconnected from the realtime server." << endl;
		onDisconnection(wsocket, code, msg, len);
	});
	wsh->onMessage([this](WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
		onMessage(ws, msg, len, opCode);
	});
}
void NTClient::onDisconnection(WebSocket<CLIENT>* wsocket, int code, char* msg, size_t len) {
	cout << "Disconn message: " << string(msg, len) << endl;
	cout << "Disconn code: " << code << endl;
}
void NTClient::onMessage(WebSocket<CLIENT>* ws, char* msg, size_t len, OpCode opCode) {
	if (opCode != OpCode::TEXT) {
		cout << "The realtime server did not send a text packet for some reason, ignoring.\n";
		return;
	}
	string smsg = string(msg, len);
	cout << "Recieved WebSocket message: '" << smsg << "'\n";
}
void NTClient::onConnection(WebSocket<CLIENT>* wsocket, HttpRequest req) {
	// Send a probe, which is required for connection
	wsocket->send("2probe", OpCode::TEXT);
	cout << "Requesting for a race in 2 seconds." << endl;
	this_thread::sleep_for(chrono::seconds(2));
	string joinTo = getJoinPacket(20); // 20 WPM just to test
	cout << joinTo << endl;
	wsocket->send(joinTo.c_str(), OpCode::TEXT);
}<|endoftext|>