<commit_before>// Copyright (c) 2009 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 "config.h"

#include "CachedCSSStyleSheet.h"
#include "CachedResource.h"
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
#include "DocLoader.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FrameLoader.h"
#include "PlatformString.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include "ScriptString.h"
#include "TextEncoding.h"
#include <wtf/CurrentTime.h>
#undef LOG

#include "base/basictypes.h"
#include "base/values.h"
#include "googleurl/src/gurl.h"
#include "webkit/glue/devtools/net_agent_impl.h"
#include "webkit/glue/glue_util.h"

using namespace WebCore;

NetAgentImpl::NetAgentImpl(NetAgentDelegate* delegate)
    : delegate_(delegate),
      document_(NULL),
      main_loader_(NULL),
      last_cached_identifier_(-2),
      attached_(false)  {
}

NetAgentImpl::~NetAgentImpl() {
  SetDocument(NULL);
  DidCommitMainResourceLoad();
  deleteAllValues(pending_resources_);
  pending_resources_.clear();
}

void NetAgentImpl::SetDocument(Document* doc) {
  document_ = doc;
}

void NetAgentImpl::Attach() {
  for (FinishedResources::iterator it = finished_resources_.begin();
       it != finished_resources_.end(); ++it) {
    DictionaryValue value;
    Serialize(*it->second, &value);
    delegate_->DidFinishLoading(it->first, value);
  }
  attached_ = true;
}

void NetAgentImpl::Detach() {
  attached_ = false;
}

void NetAgentImpl::DidCommitMainResourceLoad() {
  for (FinishedResources::iterator it = finished_resources_.begin();
       it != finished_resources_.end(); ++it) {
    delete it->second;
  }
  finished_resources_.clear();
  main_loader_ = NULL;
}

void NetAgentImpl::AssignIdentifierToRequest(
    DocumentLoader* loader,
    int identifier,
    const ResourceRequest& request) {
}

void NetAgentImpl::WillSendRequest(
    DocumentLoader* loader,
    int identifier,
    const ResourceRequest& request) {
  if (pending_resources_.contains(identifier)) {
    // We are going through redirect, nuke old resource.
    delete pending_resources_.get(identifier);
  }

  Resource* resource = new Resource();
  KURL url = request.url();
  resource->start_time = WTF::currentTime();
  resource->url = request.url();
  resource->request_headers = request.httpHeaderFields();

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->WillSendRequest(identifier, value);
  }
}

void NetAgentImpl::DidReceiveResponse(
    DocumentLoader* loader,
    int identifier,
    const ResourceResponse &response) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }

  KURL url = response.url();
  Resource* resource = pending_resources_.get(identifier);
  resource->response_received_time = WTF::currentTime();
  resource->expected_content_length =
      static_cast<int>(response.expectedContentLength());
  resource->http_status_code = response.httpStatusCode();
  resource->mime_type = response.mimeType();
  resource->suggested_filename = response.suggestedFilename();
  resource->response_headers = response.httpHeaderFields();

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->DidReceiveResponse(identifier, value);
  }
}

void NetAgentImpl::DidReceiveContentLength(
    DocumentLoader* loader,
    int identifier,
    int length) {
}

void NetAgentImpl::DidFinishLoading(
    DocumentLoader* loader,
    int identifier) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }

  // This is the first command being dispatched after
  // DidCommitMainResourceLoad, we know that the first resource to be reported
  // as loaded is main resource.
  if (!main_loader_.get()) {
    main_loader_ = loader;
  }

  Resource* resource = pending_resources_.get(identifier);
  resource->end_time = WTF::currentTime();

  pending_resources_.remove(identifier);
  finished_resources_.append(std::make_pair(identifier, resource));

  // Start removing resources from the cache once there are too many of them.
  if (finished_resources_.size() > 200) {
    for (int i = 0; i < 50; ++i) {
      xml_http_sources_.remove(finished_resources_[i].first);
      delete finished_resources_[i].second;
    }
    finished_resources_.remove(0, 50);
  }

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->DidFinishLoading(identifier, value);
  }
}

void NetAgentImpl::DidFailLoading(
    DocumentLoader* loader,
    int identifier,
    const ResourceError& error) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }
  Resource* resource = pending_resources_.get(identifier);
  resource->error_code = error.errorCode();
  resource->error_description = error.localizedDescription();
  DidFinishLoading(loader, identifier);
}

void NetAgentImpl::DidLoadResourceFromMemoryCache(
    DocumentLoader* loader,
    const ResourceRequest& request,
    const ResourceResponse& response,
    int length) {
  int identifier = last_cached_identifier_--;
}

void NetAgentImpl::DidLoadResourceByXMLHttpRequest(
    int identifier,
    const WebCore::ScriptString& source) {
  xml_http_sources_.set(identifier, source);
}

void NetAgentImpl::GetResourceContent(
    int call_id,
    int identifier,
    const String& url) {
  if (!document_) {
    return;
  }

  String source;

  WebCore::ScriptString script = xml_http_sources_.get(identifier);
  if (!script.isNull()) {
    source = String(script);
  } else if (main_loader_.get() && main_loader_->requestURL() == url) {
    RefPtr<SharedBuffer> buffer = main_loader_->mainResourceData();
    String text_encoding_name = document_->inputEncoding();
    if (buffer) {
      WebCore::TextEncoding encoding(text_encoding_name);
      if (!encoding.isValid())
        encoding = WindowsLatin1Encoding();
      source = encoding.decode(buffer->data(), buffer->size());
    }
  } else {
    CachedResource* cached_resource = document_->
        docLoader()->cachedResource(url);
    if (!cached_resource) {
      delegate_->GetResourceContentResult(call_id, "");
      return;
    }
    if (cached_resource->isPurgeable()) {
      // If the resource is purgeable then make it unpurgeable to get its data.
      // This might fail, in which case we return an empty string.
      if (!cached_resource->makePurgeable(false)) {
        delegate_->GetResourceContentResult(call_id, "");
        return;
      }
    }

    // Try to get the decoded source.  Only applies to some CachedResource
    // types.
    switch (cached_resource->type()) {
      case CachedResource::CSSStyleSheet: {
        CachedCSSStyleSheet *sheet =
            reinterpret_cast<CachedCSSStyleSheet*>(cached_resource);
        source = sheet->sheetText();
        break;
      }
      case CachedResource::Script: {
        CachedScript *script =
            reinterpret_cast<CachedScript*>(cached_resource);
        source = script->script();
        break;
      }
#if ENABLE(XSLT)
      case CachedResource::XSLStyleSheet: {
        CachedXSLStyleSheet *sheet =
            reinterpret_cast<CachedXSLStyleSheet*>(cached_resource);
        source = sheet->sheet();
        break;
      }
#endif
      default:
        break;
    }
  }
  delegate_->GetResourceContentResult(call_id,
      webkit_glue::StringToStdString(source));
}

// static
Value* NetAgentImpl::BuildValueForHeaders(const HTTPHeaderMap& headers) {
  OwnPtr<DictionaryValue> value(new DictionaryValue());
  HTTPHeaderMap::const_iterator end = headers.end();
  for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) {
    value->SetString(webkit_glue::StringToStdWString(it->first),
        webkit_glue::StringToStdString(it->second));
  }
  return value.release();
}

// static
void NetAgentImpl::Serialize(const Resource& resource,
                             DictionaryValue* value) {
  value->SetReal(L"startTime", resource.start_time);
  value->SetReal(L"responseReceivedTime", resource.response_received_time);
  value->SetReal(L"endTime", resource.end_time);

  value->SetString(L"url",
                   webkit_glue::StringToStdString(resource.url.string()));
  value->SetString(L"domain",
                   webkit_glue::StringToStdString(resource.url.host()));
  value->SetString(L"path",
                   webkit_glue::StringToStdString(resource.url.path()));
  value->SetString(
      L"lastPathComponent",
      webkit_glue::StringToStdString(resource.url.lastPathComponent()));

  value->SetString(L"mimeType",
      webkit_glue::StringToStdWString(resource.mime_type));
  value->SetString(L"suggestedFilename",
      webkit_glue::StringToStdWString(resource.suggested_filename));

  value->SetInteger(L"expectedContentLength",
                    resource.expected_content_length);
  value->SetInteger(L"responseStatusCode", resource.http_status_code);

  value->Set(L"requestHeaders",
             BuildValueForHeaders(resource.request_headers));
  value->Set(L"responseHeaders",
             BuildValueForHeaders(resource.response_headers));

  if (resource.error_code) {
    value->SetInteger(L"errorCode", resource.error_code);
    value->SetString(L"localizedDescription",
        webkit_glue::StringToStdString(resource.error_description));
  }
}
<commit_msg>DevTools: fix memory leak. TBR=yurys<commit_after>// Copyright (c) 2009 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 "config.h"

#include "CachedCSSStyleSheet.h"
#include "CachedResource.h"
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
#include "DocLoader.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FrameLoader.h"
#include "PlatformString.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include "ScriptString.h"
#include "TextEncoding.h"
#include <wtf/CurrentTime.h>
#undef LOG

#include "base/basictypes.h"
#include "base/values.h"
#include "googleurl/src/gurl.h"
#include "webkit/glue/devtools/net_agent_impl.h"
#include "webkit/glue/glue_util.h"

using namespace WebCore;

NetAgentImpl::NetAgentImpl(NetAgentDelegate* delegate)
    : delegate_(delegate),
      document_(NULL),
      main_loader_(NULL),
      last_cached_identifier_(-2),
      attached_(false)  {
}

NetAgentImpl::~NetAgentImpl() {
  SetDocument(NULL);
  DidCommitMainResourceLoad();
  deleteAllValues(pending_resources_);
  pending_resources_.clear();
}

void NetAgentImpl::SetDocument(Document* doc) {
  document_ = doc;
}

void NetAgentImpl::Attach() {
  for (FinishedResources::iterator it = finished_resources_.begin();
       it != finished_resources_.end(); ++it) {
    DictionaryValue value;
    Serialize(*it->second, &value);
    delegate_->DidFinishLoading(it->first, value);
  }
  attached_ = true;
}

void NetAgentImpl::Detach() {
  attached_ = false;
}

void NetAgentImpl::DidCommitMainResourceLoad() {
  for (FinishedResources::iterator it = finished_resources_.begin();
       it != finished_resources_.end(); ++it) {
    delete it->second;
  }
  finished_resources_.clear();
  main_loader_ = NULL;
}

void NetAgentImpl::AssignIdentifierToRequest(
    DocumentLoader* loader,
    int identifier,
    const ResourceRequest& request) {
}

void NetAgentImpl::WillSendRequest(
    DocumentLoader* loader,
    int identifier,
    const ResourceRequest& request) {
  if (pending_resources_.contains(identifier)) {
    // We are going through redirect, nuke old resource.
    delete pending_resources_.get(identifier);
  }

  Resource* resource = new Resource();
  pending_resources_.set(identifier, resource);
  KURL url = request.url();
  resource->start_time = WTF::currentTime();
  resource->url = request.url();
  resource->request_headers = request.httpHeaderFields();

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->WillSendRequest(identifier, value);
  }
}

void NetAgentImpl::DidReceiveResponse(
    DocumentLoader* loader,
    int identifier,
    const ResourceResponse &response) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }

  KURL url = response.url();
  Resource* resource = pending_resources_.get(identifier);
  resource->response_received_time = WTF::currentTime();
  resource->expected_content_length =
      static_cast<int>(response.expectedContentLength());
  resource->http_status_code = response.httpStatusCode();
  resource->mime_type = response.mimeType();
  resource->suggested_filename = response.suggestedFilename();
  resource->response_headers = response.httpHeaderFields();

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->DidReceiveResponse(identifier, value);
  }
}

void NetAgentImpl::DidReceiveContentLength(
    DocumentLoader* loader,
    int identifier,
    int length) {
}

void NetAgentImpl::DidFinishLoading(
    DocumentLoader* loader,
    int identifier) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }

  // This is the first command being dispatched after
  // DidCommitMainResourceLoad, we know that the first resource to be reported
  // as loaded is main resource.
  if (!main_loader_.get()) {
    main_loader_ = loader;
  }

  Resource* resource = pending_resources_.get(identifier);
  resource->end_time = WTF::currentTime();

  pending_resources_.remove(identifier);
  finished_resources_.append(std::make_pair(identifier, resource));

  // Start removing resources from the cache once there are too many of them.
  if (finished_resources_.size() > 200) {
    for (int i = 0; i < 50; ++i) {
      xml_http_sources_.remove(finished_resources_[i].first);
      delete finished_resources_[i].second;
    }
    finished_resources_.remove(0, 50);
  }

  if (attached_) {
    DictionaryValue value;
    Serialize(*resource, &value);
    delegate_->DidFinishLoading(identifier, value);
  }
}

void NetAgentImpl::DidFailLoading(
    DocumentLoader* loader,
    int identifier,
    const ResourceError& error) {
  if (!pending_resources_.contains(identifier)) {
    return;
  }
  Resource* resource = pending_resources_.get(identifier);
  resource->error_code = error.errorCode();
  resource->error_description = error.localizedDescription();
  DidFinishLoading(loader, identifier);
}

void NetAgentImpl::DidLoadResourceFromMemoryCache(
    DocumentLoader* loader,
    const ResourceRequest& request,
    const ResourceResponse& response,
    int length) {
  int identifier = last_cached_identifier_--;
}

void NetAgentImpl::DidLoadResourceByXMLHttpRequest(
    int identifier,
    const WebCore::ScriptString& source) {
  xml_http_sources_.set(identifier, source);
}

void NetAgentImpl::GetResourceContent(
    int call_id,
    int identifier,
    const String& url) {
  if (!document_) {
    return;
  }

  String source;

  WebCore::ScriptString script = xml_http_sources_.get(identifier);
  if (!script.isNull()) {
    source = String(script);
  } else if (main_loader_.get() && main_loader_->requestURL() == url) {
    RefPtr<SharedBuffer> buffer = main_loader_->mainResourceData();
    String text_encoding_name = document_->inputEncoding();
    if (buffer) {
      WebCore::TextEncoding encoding(text_encoding_name);
      if (!encoding.isValid())
        encoding = WindowsLatin1Encoding();
      source = encoding.decode(buffer->data(), buffer->size());
    }
  } else {
    CachedResource* cached_resource = document_->
        docLoader()->cachedResource(url);
    if (!cached_resource) {
      delegate_->GetResourceContentResult(call_id, "");
      return;
    }
    if (cached_resource->isPurgeable()) {
      // If the resource is purgeable then make it unpurgeable to get its data.
      // This might fail, in which case we return an empty string.
      if (!cached_resource->makePurgeable(false)) {
        delegate_->GetResourceContentResult(call_id, "");
        return;
      }
    }

    // Try to get the decoded source.  Only applies to some CachedResource
    // types.
    switch (cached_resource->type()) {
      case CachedResource::CSSStyleSheet: {
        CachedCSSStyleSheet *sheet =
            reinterpret_cast<CachedCSSStyleSheet*>(cached_resource);
        source = sheet->sheetText();
        break;
      }
      case CachedResource::Script: {
        CachedScript *script =
            reinterpret_cast<CachedScript*>(cached_resource);
        source = script->script();
        break;
      }
#if ENABLE(XSLT)
      case CachedResource::XSLStyleSheet: {
        CachedXSLStyleSheet *sheet =
            reinterpret_cast<CachedXSLStyleSheet*>(cached_resource);
        source = sheet->sheet();
        break;
      }
#endif
      default:
        break;
    }
  }
  delegate_->GetResourceContentResult(call_id,
      webkit_glue::StringToStdString(source));
}

// static
Value* NetAgentImpl::BuildValueForHeaders(const HTTPHeaderMap& headers) {
  OwnPtr<DictionaryValue> value(new DictionaryValue());
  HTTPHeaderMap::const_iterator end = headers.end();
  for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) {
    value->SetString(webkit_glue::StringToStdWString(it->first),
        webkit_glue::StringToStdString(it->second));
  }
  return value.release();
}

// static
void NetAgentImpl::Serialize(const Resource& resource,
                             DictionaryValue* value) {
  value->SetReal(L"startTime", resource.start_time);
  value->SetReal(L"responseReceivedTime", resource.response_received_time);
  value->SetReal(L"endTime", resource.end_time);

  value->SetString(L"url",
                   webkit_glue::StringToStdString(resource.url.string()));
  value->SetString(L"domain",
                   webkit_glue::StringToStdString(resource.url.host()));
  value->SetString(L"path",
                   webkit_glue::StringToStdString(resource.url.path()));
  value->SetString(
      L"lastPathComponent",
      webkit_glue::StringToStdString(resource.url.lastPathComponent()));

  value->SetString(L"mimeType",
      webkit_glue::StringToStdWString(resource.mime_type));
  value->SetString(L"suggestedFilename",
      webkit_glue::StringToStdWString(resource.suggested_filename));

  value->SetInteger(L"expectedContentLength",
                    resource.expected_content_length);
  value->SetInteger(L"responseStatusCode", resource.http_status_code);

  value->Set(L"requestHeaders",
             BuildValueForHeaders(resource.request_headers));
  value->Set(L"responseHeaders",
             BuildValueForHeaders(resource.response_headers));

  if (resource.error_code) {
    value->SetInteger(L"errorCode", resource.error_code);
    value->SetString(L"localizedDescription",
        webkit_glue::StringToStdString(resource.error_description));
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__

#include "base/hashmap.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"

template<class ENTRY>
struct PerfectCacheLineState
{
    PerfectCacheLineState() { m_permission = AccessPermission_NUM; }
    AccessPermission m_permission;
    ENTRY m_entry;
};

template<class ENTRY>
inline std::ostream&
operator<<(std::ostream& out, const PerfectCacheLineState<ENTRY>& obj)
{
    return out;
}

template<class ENTRY>
class PerfectCacheMemory
{
  public:
    PerfectCacheMemory();

    static void printConfig(std::ostream& out);

    // perform a cache access and see if we hit or not.  Return true
    // on a hit.
    bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry);

    // tests to see if an address is present in the cache
    bool isTagPresent(const Address& address) const;

    // Returns true if there is:
    //   a) a tag match on this address or there is
    //   b) an Invalid line in the same cache "way"
    bool cacheAvail(const Address& address) const;

    // find an Invalid entry and sets the tag appropriate for the address
    void allocate(const Address& address);

    void deallocate(const Address& address);

    // Returns with the physical address of the conflicting cache line
    Address cacheProbe(const Address& newAddress) const;

    // looks an address up in the cache
    ENTRY& lookup(const Address& address);
    const ENTRY& lookup(const Address& address) const;

    // Get/Set permission of cache block
    AccessPermission getPermission(const Address& address) const;
    void changePermission(const Address& address, AccessPermission new_perm);

    // Print cache contents
    void print(std::ostream& out) const;

  private:
    // Private copy constructor and assignment operator
    PerfectCacheMemory(const PerfectCacheMemory& obj);
    PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);

    // Data Members (m_prefix)
    m5::hash_map<Address, PerfectCacheLineState<ENTRY> > m_map;
};

template<class ENTRY>
inline std::ostream&
operator<<(std::ostream& out, const PerfectCacheMemory<ENTRY>& obj)
{
    obj.print(out);
    out << std::flush;
    return out;
}

template<class ENTRY>
inline
PerfectCacheMemory<ENTRY>::PerfectCacheMemory()
{
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::printConfig(std::ostream& out)
{
}

template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg,
                                          bool& block_stc, ENTRY*& entry)
{
    panic("not implemented");
    return true;
}

// tests to see if an address is present in the cache
template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
{
    return m_map.count(line_address(address)) > 0;
}

template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const
{
    return true;
}

// find an Invalid or already allocated entry and sets the tag
// appropriate for the address
template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::allocate(const Address& address)
{
    PerfectCacheLineState<ENTRY> line_state;
    line_state.m_permission = AccessPermission_Invalid;
    line_state.m_entry = ENTRY();
    m_map[line_address(address)] = line_state;
}

// deallocate entry
template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::deallocate(const Address& address)
{
    m_map.erase(line_address(address));
}

// Returns with the physical address of the conflicting cache line
template<class ENTRY>
inline Address
PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const
{
    panic("cacheProbe called in perfect cache");
    return newAddress;
}

// looks an address up in the cache
template<class ENTRY>
inline ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address)
{
    return m_map[line_address(address)].m_entry;
}

// looks an address up in the cache
template<class ENTRY>
inline const ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address) const
{
    return m_map[line_address(address)].m_entry;
}

template<class ENTRY>
inline AccessPermission
PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
{
    return m_map[line_address(address)].m_permission;
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::changePermission(const Address& address,
                                            AccessPermission new_perm)
{
    Address line_address = address;
    line_address.makeLineAddress();
    PerfectCacheLineState<ENTRY>& line_state = m_map[line_address];
    AccessPermission old_perm = line_state.m_permission;
    line_state.m_permission = new_perm;
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::print(std::ostream& out) const
{
}

#endif // __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
<commit_msg>PerfectCacheMemory: Remove references to CacheMsg The definition for the class CacheMsg was removed long back. Some declaration had still survived, which was recently removed. Since the PerfectCacheMemory class relied on this particular declaration, its absence let to compilation breaking down. Hence this patch.<commit_after>/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__

#include "base/hashmap.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh"

template<class ENTRY>
struct PerfectCacheLineState
{
    PerfectCacheLineState() { m_permission = AccessPermission_NUM; }
    AccessPermission m_permission;
    ENTRY m_entry;
};

template<class ENTRY>
inline std::ostream&
operator<<(std::ostream& out, const PerfectCacheLineState<ENTRY>& obj)
{
    return out;
}

template<class ENTRY>
class PerfectCacheMemory
{
  public:
    PerfectCacheMemory();

    static void printConfig(std::ostream& out);

    // tests to see if an address is present in the cache
    bool isTagPresent(const Address& address) const;

    // Returns true if there is:
    //   a) a tag match on this address or there is
    //   b) an Invalid line in the same cache "way"
    bool cacheAvail(const Address& address) const;

    // find an Invalid entry and sets the tag appropriate for the address
    void allocate(const Address& address);

    void deallocate(const Address& address);

    // Returns with the physical address of the conflicting cache line
    Address cacheProbe(const Address& newAddress) const;

    // looks an address up in the cache
    ENTRY& lookup(const Address& address);
    const ENTRY& lookup(const Address& address) const;

    // Get/Set permission of cache block
    AccessPermission getPermission(const Address& address) const;
    void changePermission(const Address& address, AccessPermission new_perm);

    // Print cache contents
    void print(std::ostream& out) const;

  private:
    // Private copy constructor and assignment operator
    PerfectCacheMemory(const PerfectCacheMemory& obj);
    PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);

    // Data Members (m_prefix)
    m5::hash_map<Address, PerfectCacheLineState<ENTRY> > m_map;
};

template<class ENTRY>
inline std::ostream&
operator<<(std::ostream& out, const PerfectCacheMemory<ENTRY>& obj)
{
    obj.print(out);
    out << std::flush;
    return out;
}

template<class ENTRY>
inline
PerfectCacheMemory<ENTRY>::PerfectCacheMemory()
{
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::printConfig(std::ostream& out)
{
}

// tests to see if an address is present in the cache
template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
{
    return m_map.count(line_address(address)) > 0;
}

template<class ENTRY>
inline bool
PerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const
{
    return true;
}

// find an Invalid or already allocated entry and sets the tag
// appropriate for the address
template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::allocate(const Address& address)
{
    PerfectCacheLineState<ENTRY> line_state;
    line_state.m_permission = AccessPermission_Invalid;
    line_state.m_entry = ENTRY();
    m_map[line_address(address)] = line_state;
}

// deallocate entry
template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::deallocate(const Address& address)
{
    m_map.erase(line_address(address));
}

// Returns with the physical address of the conflicting cache line
template<class ENTRY>
inline Address
PerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const
{
    panic("cacheProbe called in perfect cache");
    return newAddress;
}

// looks an address up in the cache
template<class ENTRY>
inline ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address)
{
    return m_map[line_address(address)].m_entry;
}

// looks an address up in the cache
template<class ENTRY>
inline const ENTRY&
PerfectCacheMemory<ENTRY>::lookup(const Address& address) const
{
    return m_map[line_address(address)].m_entry;
}

template<class ENTRY>
inline AccessPermission
PerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
{
    return m_map[line_address(address)].m_permission;
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::changePermission(const Address& address,
                                            AccessPermission new_perm)
{
    Address line_address = address;
    line_address.makeLineAddress();
    PerfectCacheLineState<ENTRY>& line_state = m_map[line_address];
    AccessPermission old_perm = line_state.m_permission;
    line_state.m_permission = new_perm;
}

template<class ENTRY>
inline void
PerfectCacheMemory<ENTRY>::print(std::ostream& out) const
{
}

#endif // __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 <tchar.h>

#include "webkit/glue/plugins/plugin_list.h"

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const TCHAR kRegistryApps[] =
    _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
const TCHAR kRegistryFirefox[] = _T("firefox.exe");
const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
const TCHAR kRegistryPath[] = _T("Path");
const TCHAR kRegistryFirefoxInstalled[] =
    _T("SOFTWARE\\Mozilla\\Mozilla Firefox");
const TCHAR kRegistryJava[] =
    _T("Software\\JavaSoft\\Java Runtime Environment");
const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
const TCHAR kRegistryJavaHome[] = _T("JavaHome");

// The application path where we expect to find plugins.
void GetAppDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath app_path;
  if (!webkit_glue::GetApplicationDirectory(&app_path))
    return;

  app_path = app_path.AppendASCII("plugins");
  plugin_dirs->insert(app_path);
}

// The executable path where we expect to find plugins.
void GetExeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath exe_path;
  if (!webkit_glue::GetExeDirectory(&exe_path))
    return;

  exe_path = exe_path.AppendASCII("plugins");
  plugin_dirs->insert(exe_path);
}

// Gets the installed path for a registered app.
bool GetInstalledPath(const TCHAR* app, FilePath* out) {
  std::wstring reg_path(kRegistryApps);
  reg_path.append(L"\\");
  reg_path.append(app);

  RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
  std::wstring path;
  if (key.ReadValue(kRegistryPath, &path)) {
    *out = FilePath(path);
    return true;
  }

  return false;
}

// Search the registry at the given path and detect plugin directories.
void GetPluginsInRegistryDirectory(
    HKEY root_key,
    const std::wstring& registry_folder,
    std::set<FilePath>* plugin_dirs) {
  for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
       iter.Valid(); ++iter) {
    // Use the registry to gather plugin across the file system.
    std::wstring reg_path = registry_folder;
    reg_path.append(L"\\");
    reg_path.append(iter.Name());
    RegKey key(root_key, reg_path.c_str());

    std::wstring path;
    if (key.ReadValue(kRegistryPath, &path))
      plugin_dirs->insert(FilePath(path).DirName());
  }
}

// Enumerate through the registry key to find all installed FireFox paths.
// FireFox 3 beta and version 2 can coexist. See bug: 1025003
void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
  RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
  for (; it.Valid(); ++it) {
    std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
                             it.Name() + L"\\Main";
    RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
    std::wstring install_dir;
    if (!key.ReadValue(L"Install Directory", &install_dir))
      continue;
    out->push_back(FilePath(install_dir));
  }
}

// Get plugin directory locations from the Firefox install path.  This is kind
// of a kludge, but it helps us locate the flash player for users that
// already have it for firefox.  Not having to download yet-another-plugin
// is a good thing.
void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
  std::vector<FilePath> paths;
  GetFirefoxInstalledPaths(&paths);
  for (unsigned int i = 0; i < paths.size(); ++i) {
    plugin_dirs->insert(paths[i].Append(L"plugins"));
  }

  GetPluginsInRegistryDirectory(
      HKEY_CURRENT_USER, kRegistryMozillaPlugins, plugin_dirs);
  GetPluginsInRegistryDirectory(
      HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, plugin_dirs);

  FilePath firefox_app_data_plugin_path;
  if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
    firefox_app_data_plugin_path =
        firefox_app_data_plugin_path.AppendASCII("Mozilla")
                                    .AppendASCII("plugins");
    plugin_dirs->insert(firefox_app_data_plugin_path);
  }
}

// Hardcoded logic to detect Acrobat plugins locations.
void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
      !GetInstalledPath(kRegistryAcrobat, &path)) {
    return;
  }

  plugin_dirs->insert(path.Append(L"Browser"));
}

// Hardcoded logic to detect QuickTime plugin location.
void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryQuickTime, &path))
    plugin_dirs->insert(path.Append(L"plugins"));
}

// Hardcoded logic to detect Windows Media Player plugin location.
void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryWindowsMedia, &path))
    plugin_dirs->insert(path);

  // If the Windows Media Player Firefox plugin is installed before Firefox,
  // the plugin will get written under PFiles\Plugins on one the drives
  // (usually, but not always, the last letter).
  int size = GetLogicalDriveStrings(0, NULL);
  if (size) {
    scoped_array<wchar_t> strings(new wchar_t[size]);
    if (GetLogicalDriveStrings(size, strings.get())) {
      wchar_t* next_drive = strings.get();
      while (*next_drive) {
        if (GetDriveType(next_drive) == DRIVE_FIXED) {
          FilePath pfiles(next_drive);
          pfiles = pfiles.Append(L"PFiles\\Plugins");
          if (file_util::PathExists(pfiles))
            plugin_dirs->insert(pfiles);
        }
        next_drive = &next_drive[wcslen(next_drive) + 1];
      }
    }
  }
}

// Hardcoded logic to detect Java plugin location.
void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
  // Load the new NPAPI Java plugin
  // 1. Open the main JRE key under HKLM
  RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);

  // 2. Read the current Java version
  std::wstring java_version;
  if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
    java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);

  if (!java_version.empty()) {
    java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);

    // 3. Install path of the JRE binaries is specified in "JavaHome"
    //    value under the Java version key.
    std::wstring java_plugin_directory;
    if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {

      // 4. The new plugin resides under the 'bin/new_plugin'
      //    subdirectory.
      DCHECK(!java_plugin_directory.empty());
      java_plugin_directory.append(L"\\bin\\new_plugin");

      // 5. We don't know the exact name of the DLL but it's in the form
      //    NP*.dll so just invoke LoadPlugins on this path.
      plugin_dirs->insert(FilePath(java_plugin_directory));
    }
  }
}

}

namespace NPAPI
{

void PluginList::PlatformInit() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // We use a set for uniqueness, which we require, over order, which we do not.
  std::set<FilePath> dirs;

  // Load from the application-specific area
  GetAppDirectory(&dirs);

  // Load from the executable area
  GetExeDirectory(&dirs);

  // Load Java
  GetJavaDirectory(&dirs);

  // Load firefox plugins too.  This is mainly to try to locate
  // a pre-installed Flash player.
  GetFirefoxDirectory(&dirs);

  // Firefox hard-codes the paths of some popular plugins to ensure that
  // the plugins are found.  We are going to copy this as well.
  GetAcrobatDirectory(&dirs);
  GetQuicktimeDirectory(&dirs);
  GetWindowsMediaDirectory(&dirs);

  for (std::set<FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
    plugin_dirs->push_back(*i);
}

void PluginList::LoadPluginsFromDir(const FilePath &path,
                                    std::vector<WebPluginInfo>* plugins) {
  WIN32_FIND_DATA find_file_data;
  HANDLE find_handle;

  std::wstring dir = path.value();
  // FindFirstFile requires that you specify a wildcard for directories.
  dir.append(L"\\NP*.DLL");

  find_handle = FindFirstFile(dir.c_str(), &find_file_data);
  if (find_handle == INVALID_HANDLE_VALUE)
    return;

  do {
    if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      FilePath filename = path.Append(find_file_data.cFileName);
      LoadPlugin(filename, plugins);
    }
  } while (FindNextFile(find_handle, &find_file_data) != 0);

  DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
  FindClose(find_handle);
}

// Compares Windows style version strings (i.e. 1,2,3,4).  Returns true if b's
// version is newer than a's, or false if it's equal or older.
bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
  std::vector<std::wstring> a_ver, b_ver;
  SplitString(a, ',', &a_ver);
  SplitString(b, ',', &b_ver);
  if (a_ver.size() != b_ver.size())
    return false;
  for (size_t i = 0; i < a_ver.size(); i++) {
    int cur_a = StringToInt(a_ver[i]);
    int cur_b = StringToInt(b_ver[i]);
    if (cur_a > cur_b)
      return false;
    if (cur_a < cur_b)
      return true;
  }
  return false;
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  // Version check

  for (size_t i = 0; i < plugins->size(); ++i) {
    if ((*plugins)[i].path.BaseName() == info.path.BaseName() &&
        !IsNewerVersion((*plugins)[i].version, info.version)) {
      return false;  // We already have a loaded plugin whose version is newer.
    }
  }

  // Troublemakers

  std::wstring filename = StringToLowerASCII(info.path.BaseName().value());
  // Depends on XPCOM.
  if (filename == kMozillaActiveXPlugin)
    return false;

  // Disable the Yahoo Application State plugin as it crashes the plugin
  // process on return from NPObjectStub::OnInvoke. Please refer to
  // http://b/issue?id=1372124 for more information.
  if (filename == kYahooApplicationStatePlugin)
    return false;

  // Disable the WangWang protocol handler plugin (npww.dll) as it crashes
  // chrome during shutdown. Firefox also disables this plugin.
  // Please refer to http://code.google.com/p/chromium/issues/detail?id=3953
  // for more information.
  if (filename == kWanWangProtocolHandlerPlugin)
    return false;

  // We only work with newer versions of the Java plugin which use NPAPI only
  // and don't depend on XPCOM.
  if (filename == kJavaPlugin1 || filename == kJavaPlugin2) {
    std::vector<std::wstring> ver;
    SplitString(info.version, '.', &ver);
    int major, minor, update;
    if (ver.size() == 4 &&
        StringToInt(ver[0], &major) &&
        StringToInt(ver[1], &minor) &&
        StringToInt(ver[2], &update)) {
      if (major == 6 && minor == 0 && update < 120)
        return false;  // Java SE6 Update 12 or older.
    }
  }

  // Special WMP handling

  // If both the new and old WMP plugins exist, only load the new one.
  if (filename == kNewWMPPlugin) {
    if (dont_load_new_wmp_)
      return false;

    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) {
        plugins->erase(plugins->begin() + i);
        break;
      }
    }
  } else if (filename == kOldWMPPlugin) {
    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin)
        return false;
    }
  }

  return true;
}

} // namespace NPAPI
<commit_msg>Fix comment<commit_after>// Copyright (c) 2006-2008 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 <tchar.h>

#include "webkit/glue/plugins/plugin_list.h"

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const TCHAR kRegistryApps[] =
    _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
const TCHAR kRegistryFirefox[] = _T("firefox.exe");
const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
const TCHAR kRegistryPath[] = _T("Path");
const TCHAR kRegistryFirefoxInstalled[] =
    _T("SOFTWARE\\Mozilla\\Mozilla Firefox");
const TCHAR kRegistryJava[] =
    _T("Software\\JavaSoft\\Java Runtime Environment");
const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
const TCHAR kRegistryJavaHome[] = _T("JavaHome");

// The application path where we expect to find plugins.
void GetAppDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath app_path;
  if (!webkit_glue::GetApplicationDirectory(&app_path))
    return;

  app_path = app_path.AppendASCII("plugins");
  plugin_dirs->insert(app_path);
}

// The executable path where we expect to find plugins.
void GetExeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath exe_path;
  if (!webkit_glue::GetExeDirectory(&exe_path))
    return;

  exe_path = exe_path.AppendASCII("plugins");
  plugin_dirs->insert(exe_path);
}

// Gets the installed path for a registered app.
bool GetInstalledPath(const TCHAR* app, FilePath* out) {
  std::wstring reg_path(kRegistryApps);
  reg_path.append(L"\\");
  reg_path.append(app);

  RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
  std::wstring path;
  if (key.ReadValue(kRegistryPath, &path)) {
    *out = FilePath(path);
    return true;
  }

  return false;
}

// Search the registry at the given path and detect plugin directories.
void GetPluginsInRegistryDirectory(
    HKEY root_key,
    const std::wstring& registry_folder,
    std::set<FilePath>* plugin_dirs) {
  for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
       iter.Valid(); ++iter) {
    // Use the registry to gather plugin across the file system.
    std::wstring reg_path = registry_folder;
    reg_path.append(L"\\");
    reg_path.append(iter.Name());
    RegKey key(root_key, reg_path.c_str());

    std::wstring path;
    if (key.ReadValue(kRegistryPath, &path))
      plugin_dirs->insert(FilePath(path).DirName());
  }
}

// Enumerate through the registry key to find all installed FireFox paths.
// FireFox 3 beta and version 2 can coexist. See bug: 1025003
void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
  RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
  for (; it.Valid(); ++it) {
    std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
                             it.Name() + L"\\Main";
    RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
    std::wstring install_dir;
    if (!key.ReadValue(L"Install Directory", &install_dir))
      continue;
    out->push_back(FilePath(install_dir));
  }
}

// Get plugin directory locations from the Firefox install path.  This is kind
// of a kludge, but it helps us locate the flash player for users that
// already have it for firefox.  Not having to download yet-another-plugin
// is a good thing.
void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
  std::vector<FilePath> paths;
  GetFirefoxInstalledPaths(&paths);
  for (unsigned int i = 0; i < paths.size(); ++i) {
    plugin_dirs->insert(paths[i].Append(L"plugins"));
  }

  GetPluginsInRegistryDirectory(
      HKEY_CURRENT_USER, kRegistryMozillaPlugins, plugin_dirs);
  GetPluginsInRegistryDirectory(
      HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, plugin_dirs);

  FilePath firefox_app_data_plugin_path;
  if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
    firefox_app_data_plugin_path =
        firefox_app_data_plugin_path.AppendASCII("Mozilla")
                                    .AppendASCII("plugins");
    plugin_dirs->insert(firefox_app_data_plugin_path);
  }
}

// Hardcoded logic to detect Acrobat plugins locations.
void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
      !GetInstalledPath(kRegistryAcrobat, &path)) {
    return;
  }

  plugin_dirs->insert(path.Append(L"Browser"));
}

// Hardcoded logic to detect QuickTime plugin location.
void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryQuickTime, &path))
    plugin_dirs->insert(path.Append(L"plugins"));
}

// Hardcoded logic to detect Windows Media Player plugin location.
void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryWindowsMedia, &path))
    plugin_dirs->insert(path);

  // If the Windows Media Player Firefox plugin is installed before Firefox,
  // the plugin will get written under PFiles\Plugins on one the drives
  // (usually, but not always, the last letter).
  int size = GetLogicalDriveStrings(0, NULL);
  if (size) {
    scoped_array<wchar_t> strings(new wchar_t[size]);
    if (GetLogicalDriveStrings(size, strings.get())) {
      wchar_t* next_drive = strings.get();
      while (*next_drive) {
        if (GetDriveType(next_drive) == DRIVE_FIXED) {
          FilePath pfiles(next_drive);
          pfiles = pfiles.Append(L"PFiles\\Plugins");
          if (file_util::PathExists(pfiles))
            plugin_dirs->insert(pfiles);
        }
        next_drive = &next_drive[wcslen(next_drive) + 1];
      }
    }
  }
}

// Hardcoded logic to detect Java plugin location.
void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
  // Load the new NPAPI Java plugin
  // 1. Open the main JRE key under HKLM
  RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);

  // 2. Read the current Java version
  std::wstring java_version;
  if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
    java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);

  if (!java_version.empty()) {
    java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);

    // 3. Install path of the JRE binaries is specified in "JavaHome"
    //    value under the Java version key.
    std::wstring java_plugin_directory;
    if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {

      // 4. The new plugin resides under the 'bin/new_plugin'
      //    subdirectory.
      DCHECK(!java_plugin_directory.empty());
      java_plugin_directory.append(L"\\bin\\new_plugin");

      // 5. We don't know the exact name of the DLL but it's in the form
      //    NP*.dll so just invoke LoadPlugins on this path.
      plugin_dirs->insert(FilePath(java_plugin_directory));
    }
  }
}

}

namespace NPAPI
{

void PluginList::PlatformInit() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // We use a set for uniqueness, which we require, over order, which we do not.
  std::set<FilePath> dirs;

  // Load from the application-specific area
  GetAppDirectory(&dirs);

  // Load from the executable area
  GetExeDirectory(&dirs);

  // Load Java
  GetJavaDirectory(&dirs);

  // Load firefox plugins too.  This is mainly to try to locate
  // a pre-installed Flash player.
  GetFirefoxDirectory(&dirs);

  // Firefox hard-codes the paths of some popular plugins to ensure that
  // the plugins are found.  We are going to copy this as well.
  GetAcrobatDirectory(&dirs);
  GetQuicktimeDirectory(&dirs);
  GetWindowsMediaDirectory(&dirs);

  for (std::set<FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
    plugin_dirs->push_back(*i);
}

void PluginList::LoadPluginsFromDir(const FilePath &path,
                                    std::vector<WebPluginInfo>* plugins) {
  WIN32_FIND_DATA find_file_data;
  HANDLE find_handle;

  std::wstring dir = path.value();
  // FindFirstFile requires that you specify a wildcard for directories.
  dir.append(L"\\NP*.DLL");

  find_handle = FindFirstFile(dir.c_str(), &find_file_data);
  if (find_handle == INVALID_HANDLE_VALUE)
    return;

  do {
    if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      FilePath filename = path.Append(find_file_data.cFileName);
      LoadPlugin(filename, plugins);
    }
  } while (FindNextFile(find_handle, &find_file_data) != 0);

  DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
  FindClose(find_handle);
}

// Compares Windows style version strings (i.e. 1,2,3,4).  Returns true if b's
// version is newer than a's, or false if it's equal or older.
bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
  std::vector<std::wstring> a_ver, b_ver;
  SplitString(a, ',', &a_ver);
  SplitString(b, ',', &b_ver);
  if (a_ver.size() != b_ver.size())
    return false;
  for (size_t i = 0; i < a_ver.size(); i++) {
    int cur_a = StringToInt(a_ver[i]);
    int cur_b = StringToInt(b_ver[i]);
    if (cur_a > cur_b)
      return false;
    if (cur_a < cur_b)
      return true;
  }
  return false;
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  // Version check

  for (size_t i = 0; i < plugins->size(); ++i) {
    if ((*plugins)[i].path.BaseName() == info.path.BaseName() &&
        !IsNewerVersion((*plugins)[i].version, info.version)) {
      return false;  // We already have a loaded plugin whose version is newer.
    }
  }

  // Troublemakers

  std::wstring filename = StringToLowerASCII(info.path.BaseName().value());
  // Depends on XPCOM.
  if (filename == kMozillaActiveXPlugin)
    return false;

  // Disable the Yahoo Application State plugin as it crashes the plugin
  // process on return from NPObjectStub::OnInvoke. Please refer to
  // http://b/issue?id=1372124 for more information.
  if (filename == kYahooApplicationStatePlugin)
    return false;

  // Disable the WangWang protocol handler plugin (npww.dll) as it crashes
  // chrome during shutdown. Firefox also disables this plugin.
  // Please refer to http://code.google.com/p/chromium/issues/detail?id=3953
  // for more information.
  if (filename == kWanWangProtocolHandlerPlugin)
    return false;

  // We only work with newer versions of the Java plugin which use NPAPI only
  // and don't depend on XPCOM.
  if (filename == kJavaPlugin1 || filename == kJavaPlugin2) {
    std::vector<std::wstring> ver;
    SplitString(info.version, '.', &ver);
    int major, minor, update;
    if (ver.size() == 4 &&
        StringToInt(ver[0], &major) &&
        StringToInt(ver[1], &minor) &&
        StringToInt(ver[2], &update)) {
      if (major == 6 && minor == 0 && update < 120)
        return false;  // Java SE6 Update 11 or older.
    }
  }

  // Special WMP handling

  // If both the new and old WMP plugins exist, only load the new one.
  if (filename == kNewWMPPlugin) {
    if (dont_load_new_wmp_)
      return false;

    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) {
        plugins->erase(plugins->begin() + i);
        break;
      }
    }
  } else if (filename == kOldWMPPlugin) {
    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin)
        return false;
    }
  }

  return true;
}

} // namespace NPAPI
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include <cstdio>

#if qPlatform_Windows
#include <Windows.h>
#include <wininet.h> // for error codes
#endif

#include "../IO/FileAccessException.h"

#include "Throw.h"
#include "TimeOutException.h"

#include "ErrNoException.h"

using namespace Stroika;
using namespace Stroika::Foundation;

using namespace Characters;
using namespace Execution;

using Debug::TraceContextBumper;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ***************************** SystemException **********************************
 ********************************************************************************
 */
Characters::String SystemException::mkMsg_ (error_code errCode)
{
    return Characters::String::FromNarrowSDKString (errCode.message ());
}

Characters::String SystemException::mkMsg_ (error_code errCode, const Characters::String& message)
{
    return message + L": "sv + mkMsg_ (errCode);
}

void SystemException::ThrowPOSIXErrNo (int errNo)
{
    Require (errNo != 0);
    // @todo see errno_ErrorException::Throw () for additional needed mappings
	switch (static_cast<errc> (errNo)) {
	case errc::not_enough_memory: {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
		DbgTrace ("SystemException::ThrowPOSIXErrNo (0x%x) - translating errc::not_enough_memory to bad_alloc", errNo);
#endif
		Throw (bad_alloc ());
	} break;
	case errc::timed_out: {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
		DbgTrace ("SystemException::ThrowPOSIXErrNo (0x%x) - translating errc::not_enough_memory to TimeOutException", errNo);
#endif
		Throw (TimeOutException::kThe);
	}
        default: {
            Throw (SystemException (errNo, generic_category ()));
        } break;
    }
}

void SystemException::ThrowSystemErrNo (int sysErr)
{
    Require (sysErr != 0);
    // @todo see Execution::Platform::Windows::Exception::Throw - many more translations needed and this one needs testing
    error_code ec{sysErr, system_category ()};
    if (ec == errc::not_enough_memory) {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("SystemException::ThrowSystemErrNo (0x%x) - translating errc::not_enough_memory to bad_alloc", sysErr);
#endif
        Throw (bad_alloc ());
    }
    if (ec == errc::timed_out) {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("SystemException::ThrowSystemErrNo (0x%x) - translating errc::timed_out to TimeOutException", sysErr);
#endif
        Throw (TimeOutException (ec));
    }
#if qPlatform_Windows && qDebug
    switch (sysErr) {
        // \note - I think the design of error_category is such that the windows system_category class should override equivilent to match multiple
        // error codes to a single error_condition. But I've yet to verify this actually works that way...
        // But got the idea from the first answer to https://stackoverflow.com/questions/32232295/use-cases-for-stderror-code
        case ERROR_NOT_ENOUGH_MEMORY: // errc::not_enough_memory
        case ERROR_OUTOFMEMORY:       // ""
        case WAIT_TIMEOUT:            // errc::timed_out
        case ERROR_INTERNET_TIMEOUT:  // ""
            AssertNotReached ();      // should have been caught above in if (ec == errc::... checks) - so thats not working - maybe need to add this switch or debug
            break;
    }
#endif
    Throw (SystemException (ec));
}
<commit_msg>cometic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include <cstdio>

#if qPlatform_Windows
#include <Windows.h>
#include <wininet.h> // for error codes
#endif

#include "../IO/FileAccessException.h"

#include "Throw.h"
#include "TimeOutException.h"

#include "ErrNoException.h"

using namespace Stroika;
using namespace Stroika::Foundation;

using namespace Characters;
using namespace Execution;

using Debug::TraceContextBumper;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

/*
 ********************************************************************************
 ***************************** SystemException **********************************
 ********************************************************************************
 */
Characters::String SystemException::mkMsg_ (error_code errCode)
{
    return Characters::String::FromNarrowSDKString (errCode.message ());
}

Characters::String SystemException::mkMsg_ (error_code errCode, const Characters::String& message)
{
    return message + L": "sv + mkMsg_ (errCode);
}

void SystemException::ThrowPOSIXErrNo (int errNo)
{
    Require (errNo != 0);
    // @todo see errno_ErrorException::Throw () for additional needed mappings
    switch (static_cast<errc> (errNo)) {
        case errc::not_enough_memory: {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace ("SystemException::ThrowPOSIXErrNo (0x%x) - translating errc::not_enough_memory to bad_alloc", errNo);
#endif
            Throw (bad_alloc ());
        } break;
        case errc::timed_out: {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace ("SystemException::ThrowPOSIXErrNo (0x%x) - translating errc::not_enough_memory to TimeOutException", errNo);
#endif
            Throw (TimeOutException::kThe);
        }
        default: {
            Throw (SystemException (errNo, generic_category ()));
        } break;
    }
}

void SystemException::ThrowSystemErrNo (int sysErr)
{
    Require (sysErr != 0);
    // @todo see Execution::Platform::Windows::Exception::Throw - many more translations needed and this one needs testing
    error_code ec{sysErr, system_category ()};
    if (ec == errc::not_enough_memory) {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("SystemException::ThrowSystemErrNo (0x%x) - translating errc::not_enough_memory to bad_alloc", sysErr);
#endif
        Throw (bad_alloc ());
    }
    if (ec == errc::timed_out) {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace ("SystemException::ThrowSystemErrNo (0x%x) - translating errc::timed_out to TimeOutException", sysErr);
#endif
        Throw (TimeOutException (ec));
    }
#if qPlatform_Windows && qDebug
    switch (sysErr) {
        // \note - I think the design of error_category is such that the windows system_category class should override equivilent to match multiple
        // error codes to a single error_condition. But I've yet to verify this actually works that way...
        // But got the idea from the first answer to https://stackoverflow.com/questions/32232295/use-cases-for-stderror-code
        case ERROR_NOT_ENOUGH_MEMORY: // errc::not_enough_memory
        case ERROR_OUTOFMEMORY:       // ""
        case WAIT_TIMEOUT:            // errc::timed_out
        case ERROR_INTERNET_TIMEOUT:  // ""
            AssertNotReached ();      // should have been caught above in if (ec == errc::... checks) - so thats not working - maybe need to add this switch or debug
            break;
    }
#endif
    Throw (SystemException (ec));
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmessageaccount.h"
#include "qmessageaccount_p.h"
#include "qmessagemanager.h"
#include "qmtmengine_symbian_p.h"
#ifdef FREESTYLEMAILUSED
#include "qfsengine_symbian_p.h"
#endif

QTM_BEGIN_NAMESPACE

QMessageAccount QMessageAccountPrivate::from(const QMessageAccountId &id, const QString &name, long int service1EntryId, long int service2EntryId, const QMessage::TypeFlags &types)
{
    QMessageAccount result;
    result.d_ptr->_id = id;
    result.d_ptr->_name = name;
    result.d_ptr->_service1EntryId = service1EntryId;
    result.d_ptr->_service2EntryId = service2EntryId;
    result.d_ptr->_types = types;
    return result;
}

QMessageAccount::QMessageAccount()
 : d_ptr(new QMessageAccountPrivate(this))
{
}

QMessageAccount::QMessageAccount(const QMessageAccountId &id)
 : d_ptr(new QMessageAccountPrivate(this))
{
    *this = QMessageManager().account(id);
}

QMessageAccount::QMessageAccount(const QMessageAccount &other)
 : d_ptr(new QMessageAccountPrivate(this))
{
    this->operator=(other);
}

QMessageAccount& QMessageAccount::operator=(const QMessageAccount& other)
{
    if (&other != this) {
        *d_ptr = *other.d_ptr;
    }

    return *this;
}

QMessageAccount::~QMessageAccount()
{
    delete d_ptr;
    d_ptr = 0;
}

QMessageAccountId QMessageAccount::id() const
{
    return d_ptr->_id;
}

QString QMessageAccount::name() const
{
    return d_ptr->_name;
}

QMessage::TypeFlags QMessageAccount::messageTypes() const
{
    return d_ptr->_types;
}

QMessageAccountId QMessageAccount::defaultAccount(QMessage::Type type)
{
#ifdef FREESTYLEMAILUSED
    if (type == QMessage::Email) {
        QMessageAccountId id = CFSEngine::instance()->defaultAccount(type);
        if (id.isValid())
            return id;
        else return CMTMEngine::instance()->defaultAccount(type);
    }
#endif // FREESTYLEMAILUSED
    return CMTMEngine::instance()->defaultAccount(type);
}

QTM_END_NAMESPACE
<commit_msg>default account handling fixed<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmessageaccount.h"
#include "qmessageaccount_p.h"
#include "qmessagemanager.h"
#include "qmtmengine_symbian_p.h"
#ifdef FREESTYLEMAILUSED
#include "qfsengine_symbian_p.h"
#endif
#ifdef FREESTYLENMAILUSED
#include "qfsnmengine_symbian_p.h"
#endif

QTM_BEGIN_NAMESPACE

QMessageAccount QMessageAccountPrivate::from(const QMessageAccountId &id, const QString &name, long int service1EntryId, long int service2EntryId, const QMessage::TypeFlags &types)
{
    QMessageAccount result;
    result.d_ptr->_id = id;
    result.d_ptr->_name = name;
    result.d_ptr->_service1EntryId = service1EntryId;
    result.d_ptr->_service2EntryId = service2EntryId;
    result.d_ptr->_types = types;
    return result;
}

QMessageAccount::QMessageAccount()
 : d_ptr(new QMessageAccountPrivate(this))
{
}

QMessageAccount::QMessageAccount(const QMessageAccountId &id)
 : d_ptr(new QMessageAccountPrivate(this))
{
    *this = QMessageManager().account(id);
}

QMessageAccount::QMessageAccount(const QMessageAccount &other)
 : d_ptr(new QMessageAccountPrivate(this))
{
    this->operator=(other);
}

QMessageAccount& QMessageAccount::operator=(const QMessageAccount& other)
{
    if (&other != this) {
        *d_ptr = *other.d_ptr;
    }

    return *this;
}

QMessageAccount::~QMessageAccount()
{
    delete d_ptr;
    d_ptr = 0;
}

QMessageAccountId QMessageAccount::id() const
{
    return d_ptr->_id;
}

QString QMessageAccount::name() const
{
    return d_ptr->_name;
}

QMessage::TypeFlags QMessageAccount::messageTypes() const
{
    return d_ptr->_types;
}

QMessageAccountId QMessageAccount::defaultAccount(QMessage::Type type)
{
#if defined(FREESTYLEMAILUSED) || defined(FREESTYLENMAILUSED)
    if (type == QMessage::Email) {
        QMessageAccountId id = CFSEngine::instance()->defaultAccount(type);
        if (id.isValid())
            return id;
        else return CMTMEngine::instance()->defaultAccount(type);
    }
#endif // FREESTYLEMAILUSED
    return CMTMEngine::instance()->defaultAccount(type);
}

QTM_END_NAMESPACE
<|endoftext|>


<commit_before>#include "tests.h"

#if defined(BOTAN_HAS_COMPRESSION)

#include <botan/compression.h>
#include <botan/hex.h>
#include <iostream>

namespace {

using namespace Botan;

// Returns # of bytes of compressed message
size_t run_compression(Compressor_Transform& c, Transform& d,
                       const secure_vector<byte>& msg)
   {
   secure_vector<byte> compressed = msg;

   c.start();
   c.finish(compressed);

   const size_t c_size = compressed.size();

   secure_vector<byte> decompressed = compressed;
   d.start();
   d.finish(decompressed);

   if(msg != decompressed)
      {
      std::cout << hex_encode(msg) << " compressed to " << hex_encode(compressed)
                << " but did not roundtrip - " << hex_encode(decompressed) << std::endl;
      }

   return c_size;
   }

}

size_t test_compression()
   {
   using namespace Botan;

   size_t fails = 0, tests = 0;

   for(auto&& algo : { "zlib", "deflate", "gzip", "bz2", "lzma" })
      {
      try
         {
         std::unique_ptr<Compressor_Transform> c1(make_compressor(algo, 1));
         std::unique_ptr<Compressor_Transform> c9(make_compressor(algo, 9));
         std::unique_ptr<Compressor_Transform> d(make_decompressor(algo));

         if(!c1 || !c9 || !d)
            continue;

         ++tests;

         const char* text_str =
            "'Twas brillig, and the slithy toves"
            "Did gyre and gimble in the wabe:"
            "All mimsy were the borogoves,"
            "And the mome raths outgrabe."

            "'Beware the Jabberwock, my son!"
            "The jaws that bite, the claws that catch!"
            "Beware the Jubjub bird, and shun"
            "The frumious Bandersnatch!'"

            "He took his vorpal sword in hand;"
            "Long time the manxome foe he sought—"
            "So rested he by the Tumtum tree"
            "And stood awhile in thought."

            "And, as in uffish thought he stood,"
            "The Jabberwock, with eyes of flame,"
            "Came whiffling through the tulgey wood,"
            "And burbled as it came!"

            "One, two! One, two! And through and through"
            "The vorpal blade went snicker-snack!"
            "He left it dead, and with its head"
            "He went galumphing back."

            "'And hast thou slain the Jabberwock?"
            "Come to my arms, my beamish boy!"
            "O frabjous day! Callooh! Callay!'"
            "He chortled in his joy."

            "’Twas brillig, and the slithy toves"
            "Did gyre and gimble in the wabe:"
            "All mimsy were the borogoves,"
            "And the mome raths outgrabe.";

         const size_t text_len = strlen(text_str);

         const secure_vector<byte> all_zeros(text_len, 0);
         const secure_vector<byte> random_binary = test_rng().random_vec(text_len);

         const byte* textb = reinterpret_cast<const byte*>(text_str);
         const secure_vector<byte> text(textb, textb + text_len);

         const size_t c1_z = run_compression(*c1, *d, all_zeros);
         const size_t c9_z = run_compression(*c9, *d, all_zeros);
         const size_t c1_r = run_compression(*c1, *d, random_binary);
         const size_t c9_r = run_compression(*c9, *d, random_binary);
         const size_t c1_t = run_compression(*c1, *d, text);
         const size_t c9_t = run_compression(*c9, *d, text);

#define BOTAN_TEST_GTE(x, y, msg) if(x < y) { ++fails; std::cout << "FAIL: " << x << " " << y << " " << msg << std::endl; }

         BOTAN_TEST_GTE(c1_z, c9_z, "Level 9 compresses at least as well as level 1");
         BOTAN_TEST_GTE(c1_t, c9_t, "Level 9 compresses at least as well as level 1");
         BOTAN_TEST_GTE(c1_r, c9_r, "Level 9 compresses at least as well as level 1");

         BOTAN_TEST_GTE(c1_t, c1_z/8, "Zeros compress much better than text");
         BOTAN_TEST_GTE(c1_r, c1_t/2, "Text compress better than random");
         }
      catch(std::exception& e)
         {
         std::cout << "Failure testing " << algo << " - " << e.what() << std::endl;
         ++fails;
         }
      }

   test_report("Compression", tests, fails);

   return fails;
   }

#else

SKIP_TEST(compression);

#endif // BOTAN_HAS_COMPRESSION
<commit_msg>Add test for compression of an empty buffer<commit_after>#include "tests.h"

#if defined(BOTAN_HAS_COMPRESSION)

#include <botan/compression.h>
#include <botan/hex.h>
#include <iostream>

namespace {

using namespace Botan;

// Returns # of bytes of compressed message
size_t run_compression(Compressor_Transform& c, Transform& d,
                       const secure_vector<byte>& msg)
   {
   secure_vector<byte> compressed = msg;

   c.start();
   c.finish(compressed);

   const size_t c_size = compressed.size();

   secure_vector<byte> decompressed = compressed;
   d.start();
   d.finish(decompressed);

   if(msg != decompressed)
      {
      std::cout << hex_encode(msg) << " compressed to " << hex_encode(compressed)
                << " but did not roundtrip - " << hex_encode(decompressed) << std::endl;
      }

   return c_size;
   }

}

size_t test_compression()
   {
   using namespace Botan;

   size_t fails = 0, tests = 0;

   for(auto&& algo : { "zlib", "deflate", "gzip", "bz2", "lzma" })
      {
      try
         {
         std::unique_ptr<Compressor_Transform> c1(make_compressor(algo, 1));
         std::unique_ptr<Compressor_Transform> c9(make_compressor(algo, 9));
         std::unique_ptr<Compressor_Transform> d(make_decompressor(algo));

         if(!c1 || !c9 || !d)
            continue;

         ++tests;

         const char* text_str =
            "'Twas brillig, and the slithy toves"
            "Did gyre and gimble in the wabe:"
            "All mimsy were the borogoves,"
            "And the mome raths outgrabe."

            "'Beware the Jabberwock, my son!"
            "The jaws that bite, the claws that catch!"
            "Beware the Jubjub bird, and shun"
            "The frumious Bandersnatch!'"

            "He took his vorpal sword in hand;"
            "Long time the manxome foe he sought—"
            "So rested he by the Tumtum tree"
            "And stood awhile in thought."

            "And, as in uffish thought he stood,"
            "The Jabberwock, with eyes of flame,"
            "Came whiffling through the tulgey wood,"
            "And burbled as it came!"

            "One, two! One, two! And through and through"
            "The vorpal blade went snicker-snack!"
            "He left it dead, and with its head"
            "He went galumphing back."

            "'And hast thou slain the Jabberwock?"
            "Come to my arms, my beamish boy!"
            "O frabjous day! Callooh! Callay!'"
            "He chortled in his joy."

            "’Twas brillig, and the slithy toves"
            "Did gyre and gimble in the wabe:"
            "All mimsy were the borogoves,"
            "And the mome raths outgrabe.";

         const size_t text_len = strlen(text_str);

         const secure_vector<byte> empty;
         const secure_vector<byte> all_zeros(text_len, 0);
         const secure_vector<byte> random_binary = test_rng().random_vec(text_len);

         const byte* textb = reinterpret_cast<const byte*>(text_str);
         const secure_vector<byte> text(textb, textb + text_len);

         const size_t c1_e = run_compression(*c1, *d, empty);
         const size_t c9_e = run_compression(*c9, *d, empty);
         const size_t c1_z = run_compression(*c1, *d, all_zeros);
         const size_t c9_z = run_compression(*c9, *d, all_zeros);
         const size_t c1_r = run_compression(*c1, *d, random_binary);
         const size_t c9_r = run_compression(*c9, *d, random_binary);
         const size_t c1_t = run_compression(*c1, *d, text);
         const size_t c9_t = run_compression(*c9, *d, text);

#define BOTAN_TEST_GTE(x, y, msg) if(x < y) { ++fails; std::cout << "FAIL: " << x << " " << y << " " << msg << std::endl; }

         BOTAN_TEST_GTE(c1_e, 1, "Empty input compresses to non-empty output");
         BOTAN_TEST_GTE(c9_e, 1, "Empty input compresses to non-empty output");

         BOTAN_TEST_GTE(c1_e, c9_e, "Level 9 compresses at least as well as level 1");
         BOTAN_TEST_GTE(c1_z, c9_z, "Level 9 compresses at least as well as level 1");
         BOTAN_TEST_GTE(c1_t, c9_t, "Level 9 compresses at least as well as level 1");
         BOTAN_TEST_GTE(c1_r, c9_r, "Level 9 compresses at least as well as level 1");

         BOTAN_TEST_GTE(c1_t, c1_z/8, "Zeros compress much better than text");
         BOTAN_TEST_GTE(c1_r, c1_t/2, "Text compress better than random");
         }
      catch(std::exception& e)
         {
         std::cout << "Failure testing " << algo << " - " << e.what() << std::endl;
         ++fails;
         }
      }

   test_report("Compression", tests, fails);

   return fails;
   }

#else

SKIP_TEST(compression);

#endif // BOTAN_HAS_COMPRESSION
<|endoftext|>


<commit_before>#include <map>
#include <assert.h>
#include <random>
#include <iostream>
#include <vector>

using namespace std;
class UndirGraph;
class Adj {
    protected:
        int vertex;
        int distance;
        friend class UndirGraph;
    public:
        Adj(int v, int d): vertex(v),distance(d) {};
};
class Edge {
    public:
        int a;
        int b;
        int distance;
        Edge(int _a, int _b, int d) : a(_a), b(_b), distance(d) {};
        bool operator < ( Edge const &b ) { return (distance < b.distance); }
        friend bool operator <( const Edge &a, const Edge &b ) {
                return (a.distance > b.distance );
        }
};

class UndirGraph {
    protected:
        vector<vector<Adj> > adjvv;
    public:
        UndirGraph( int numVertices) { adjvv.resize( numVertices ); };
        void addEdge( Edge e );
        UndirGraph( int numVertices, double averageEdgesPerVertex );
        bool isCyclicDfsTraverse(int vertex, map<int, int> &vertexColor);
        bool isCyclic();
        void printUndirGraph();
        UndirGraph getMST();
};
class UnionFind {
    protected:
        vector<int> idv;
    public:
        UnionFind( int n );
        bool unionIfNonCyclic( int a, int b );
        bool isConnected( int a, int b );
        int getRoot( int a);
};

UnionFind::UnionFind(int n) {
    int i;
    idv.resize( n );
    for(i=0; i<n; i++) {
        idv[i] = i;
    }
}

int
UnionFind::getRoot( int a ) {
    // For the root idv[a] will be a.
    // Keep going till you hit yourself.
    while ( idv[a] != a ) {
        a = idv[a];
    }
    return a;
}

bool
UnionFind::unionIfNonCyclic( int a, int b ) {
    int r1;
    int r2;

    // If the nodes are already connected, return.
    if( isConnected(a,b) ) {
        return false;
    }
    r1 = getRoot(a);
    r2 = getRoot(b);
    idv[r1] = r2;
    return true;
}

bool
UnionFind::isConnected(int a, int b) {
    return getRoot(a) == getRoot(b);
}

UndirGraph::UndirGraph( int numVertices, double averageEdgesPerVertex ) {
    map<pair<int,int>, bool> edges;
    srand(time(NULL));
    for( int i=0; i<numVertices; i++) {
        vector<Adj> adjv;
        adjvv.push_back(adjv);
    }
    for( int i=0; i<numVertices; i++) {
        for( int j=0; j<numVertices; j++) {
            if ( edges[pair<int,int>(i,j)] == true ) { continue; }
            if ( i != j ) {
                double d1 = rand()*1.0/RAND_MAX;
                if ( d1 < averageEdgesPerVertex ) {
                    int distance = rand() % 100;
                    Adj adj1(j, distance);
                    adjvv[i].push_back(adj1);
                    Adj adj2(i, distance);
                    adjvv[j].push_back(adj2);
                    edges[pair<int,int>(i,j)] = true;
                    edges[pair<int,int>(j,i)] = true;
                }
            }
        }
    }
}

void
UndirGraph::addEdge( Edge e ) {
    adjvv[e.a].push_back( Adj(e.b, e.distance) );
    adjvv[e.b].push_back( Adj(e.a, e.distance) );
}

void
UndirGraph::printUndirGraph() {
    for( int i=0; i < adjvv.size(); i++ ) {
        cout << "\tVertex : " << i << endl;
        for( auto it=adjvv[i].begin(); it != adjvv[i].end(); it++ ) {
            cout << "\t\t vertex:" << it->vertex << " distance:"
                    << it->distance << endl;
        }
    }
}

UndirGraph
UndirGraph::getMST() {
    UndirGraph mst( adjvv.size() );
    int i, mstEdges = 0;
    UnionFind mstUnionFind( adjvv.size() );
    vector<Edge> edges;
    bool toAdd;

    for( i=0; i<adjvv.size(); i++ ) {
        for( auto it = adjvv[i].begin(); it != adjvv[i].end(); it++) {
            Edge e(i, it->vertex, it->distance);
            edges.push_back(e);
        }
    }
    make_heap( edges.begin(), edges.end() );

    while ( ! edges.empty() ) {
        Edge nextEdge = edges.front();
        pop_heap( edges.begin(), edges.end() );
        edges.pop_back();

        toAdd = mstUnionFind.unionIfNonCyclic( nextEdge.a, nextEdge.b );
        if ( toAdd ) {
            mst.addEdge( nextEdge );
            mstEdges++;
            if ( mstEdges == adjvv.size() - 1 ) {
                // Found our MST
                break;
            }
        }
    }
    if( mstEdges < (adjvv.size() - 1) ) {
        cout << "could not form mst" << endl;
        return UndirGraph::UndirGraph(0);
    } else {
        return mst;
    }
}

// Run a DFS and add the edges to a min-heap.
// Get the smallest edge and add to new UndirGraph and
// try unionIfNonCyclic.
// When the number of edges reach the goal ("numberOfVertices-1"),
//      or the heap is over
//          stop.
// If the heap was over, no MST can be formed.
// If we reached the goal, we have an MST.
void
tryUndirGraph(int numVertices, double numEdgesPerVertex) {
    vector<Edge> edges;
    UndirGraph G(numVertices, numEdgesPerVertex);
    G.printUndirGraph();
    UndirGraph G2 = G.getMST();
    cout << "MST " << endl;
    G2.printUndirGraph();
    cout << "Done " << endl;

}

int main() {
    tryUndirGraph(8, 2.0/8);
}

<commit_msg>kruskal<commit_after>#include <map>
#include <assert.h>
#include <random>
#include <iostream>
#include <vector>

using namespace std;
class UndirGraph;
class Adj {
    protected:
        int vertex;
        int distance;
        friend class UndirGraph;
    public:
        Adj(int v, int d): vertex(v),distance(d) {};
};
class Edge {
    public:
        int a;
        int b;
        int distance;
        Edge(int _a, int _b, int d) : a(_a), b(_b), distance(d) {};
        bool operator < ( Edge const &b ) { return (distance < b.distance); }
        friend bool operator <( const Edge &a, const Edge &b ) {
                return (a.distance > b.distance );
        }
};

class UndirGraph {
    protected:
        vector<vector<Adj> > adjvv;
    public:
        UndirGraph( int numVertices) { adjvv.resize( numVertices ); };
        void addEdge( Edge e );
        UndirGraph( int numVertices, double averageEdgesPerVertex );
        bool isCyclicDfsTraverse(int vertex, map<int, int> &vertexColor);
        bool isCyclic();
        void printUndirGraph();
        UndirGraph getMST();
};
class UnionFind {
    protected:
        vector<int> idv;
    public:
        UnionFind( int n );
        bool addIfNonCyclic( int a, int b );
        bool isConnected( int a, int b );
        int getRoot( int a);
};

UnionFind::UnionFind(int n) {
    int i;
    idv.resize( n );
    for(i=0; i<n; i++) {
        idv[i] = i;
    }
}

int
UnionFind::getRoot( int a ) {
    // For the root idv[a] will be a.
    // Keep going till you hit yourself.
    while ( idv[a] != a ) {
        a = idv[a];
    }
    return a;
}

bool
UnionFind::addIfNonCyclic( int a, int b ) {
    int r1;
    int r2;

    // If the nodes are already connected, return.
    if( isConnected(a,b) ) {
        return false;
    }
    r1 = getRoot(a);
    r2 = getRoot(b);
    idv[r1] = r2;
    return true;
}

bool
UnionFind::isConnected(int a, int b) {
    return getRoot(a) == getRoot(b);
}

UndirGraph::UndirGraph( int numVertices, double averageEdgesPerVertex ) {
    map<pair<int,int>, bool> edges;
    srand(time(NULL));
    for( int i=0; i<numVertices; i++) {
        vector<Adj> adjv;
        adjvv.push_back(adjv);
    }
    for( int i=0; i<numVertices; i++) {
        for( int j=0; j<numVertices; j++) {
            if ( edges[pair<int,int>(i,j)] == true ) { continue; }
            if ( i != j ) {
                double d1 = rand()*1.0/RAND_MAX;
                if ( d1 < averageEdgesPerVertex ) {
                    int distance = rand() % 100;
                    Adj adj1(j, distance);
                    adjvv[i].push_back(adj1);
                    Adj adj2(i, distance);
                    adjvv[j].push_back(adj2);
                    edges[pair<int,int>(i,j)] = true;
                    edges[pair<int,int>(j,i)] = true;
                }
            }
        }
    }
}

void
UndirGraph::addEdge( Edge e ) {
    adjvv[e.a].push_back( Adj(e.b, e.distance) );
    adjvv[e.b].push_back( Adj(e.a, e.distance) );
}

void
UndirGraph::printUndirGraph() {
    for( int i=0; i < adjvv.size(); i++ ) {
        cout << "\tVertex : " << i << endl;
        for( auto it=adjvv[i].begin(); it != adjvv[i].end(); it++ ) {
            cout << "\t\t vertex:" << it->vertex << " distance:"
                    << it->distance << endl;
        }
    }
}

UndirGraph
UndirGraph::getMST() {
    UndirGraph mst( adjvv.size() );
    int i, mstEdges = 0;
    UnionFind mstUnionFind( adjvv.size() );
    vector<Edge> edges;
    bool toAdd;

    for( i=0; i<adjvv.size(); i++ ) {
        for( auto it = adjvv[i].begin(); it != adjvv[i].end(); it++) {
            Edge e(i, it->vertex, it->distance);
            edges.push_back(e);
        }
    }
    make_heap( edges.begin(), edges.end() );

    while ( ! edges.empty() ) {
        Edge nextEdge = edges.front();
        pop_heap( edges.begin(), edges.end() );
        edges.pop_back();

        toAdd = mstUnionFind.addIfNonCyclic( nextEdge.a, nextEdge.b );
        if ( toAdd ) {
            mst.addEdge( nextEdge );
            mstEdges++;
            if ( mstEdges == adjvv.size() - 1 ) {
                // Found our MST
                break;
            }
        }
    }
    if( mstEdges < (adjvv.size() - 1) ) {
        cout << "could not form mst" << endl;
        return UndirGraph::UndirGraph(0);
    } else {
        return mst;
    }
}

// Run a DFS and add the edges to a min-heap.
// Get the smallest edge and add to new UndirGraph and
// try addIfNonCyclic.
// When the number of edges reach the goal ("numberOfVertices-1"),
//      or the heap is over
//          stop.
// If the heap was over, no MST can be formed.
// If we reached the goal, we have an MST.
void
tryUndirGraph(int numVertices, double numEdgesPerVertex) {
    vector<Edge> edges;
    UndirGraph G(numVertices, numEdgesPerVertex);
    G.printUndirGraph();
    UndirGraph G2 = G.getMST();
    cout << "MST " << endl;
    G2.printUndirGraph();
    cout << "Done " << endl;

}

int main() {
    tryUndirGraph(8, 2.0/8);
}

<|endoftext|>


<commit_before>/*
 * Drum.cpp
 *
 *  Created on: 6 May 2015
 *      Author: jeremy
 */

#include "Module.h"

namespace DrumKit
{

	Module::Module()
	: soundParameters(sndParams),
	  directory("./")
	{

		return;
	}

	Module::Module(std::string dir)
	: soundParameters(sndParams),
	  directory(dir)
	{

		return;
	}

	Module::~Module()
	{

		for(size_t i = 0; i < sndParams.size(); i++)
			delete[] sndParams[i].data;

		sndParams.clear();

		return;
	}

	void Module::LoadKit(std::string file, Kit& kit)
	{

		const char* fileName 	= file.c_str();

		//xmlInitParser();

		xmlDoc* doc 			= xmlReadFile(fileName, NULL, 0);
		xmlNode* rootElement 	= xmlDocGetRootElement(doc);

		xmlNode* node 			= rootElement->children;

		xmlNode* kitName 		= node->next;
		kit.kitName				= std::string((char*) kitName->children->content);

		xmlNode* kitFolder 		= kitName->next->next;
		kit.kitFolder 			= std::string((char*) kitFolder->children->content);

		xmlNode* kitParams 		= kitFolder->next->next;
		xmlNode* drumName 		= kitParams->children->next;

		bool getSound = true;

		while(getSound)
		{

			size_t drumId = kit.drum.size();

			bool newSound = GetDrumParams(drumName, kit.drum);

			std::string drumFileName = kit.drum.front().soundFile;
			std::string fileSound = directory + "Kits/" + kit.kitFolder + "/" + drumFileName;

			// Sound id must match drumId (index in the kit.drum vector)
			AddSound(fileSound, drumId);

			drumId++;

			if(!newSound)
				getSound = false;

		}

		//xmlFreeDoc(doc);
		xmlFree(doc);
		//xmlCleanupParser();
	    //xmlMemoryDump();

		return;
	}

	/// PRIVATE

	void Module::AddSound(std::string filename, size_t soundId)
	{

		// Get file location
		std::string fileLocation(filename);

		// Open file
		std::ifstream soundFile(fileLocation);

		// Check file validity
		if(!soundFile.good())
			throw - 1;

		soundFile.seekg (0, std::ios::end);

		// Get file size in bytes
		int fileSize = soundFile.tellg();

		short* soundData = new short[fileSize];

		soundFile.seekg(0, std::ios::beg);

		int i = 0;
		while(soundFile.read((char*)&soundData[i], sizeof(short))) i++;

		SoundParams sndParameters;

		sndParameters.length 	= fileSize*sizeof(char)/sizeof(short);
		sndParameters.data 		= soundData;
		sndParameters.id 		= soundId;

		// Add sound to lib
		sndParams.push_back(sndParameters);

		// Close file
		soundFile.close();

		return;
	}

	bool Module::GetDrumParams(xmlNode* drumName, std::vector<Drum>& drums)
	{

		Drum drum;

		drum.id 			= drums.size();

		drum.drumName 		= std::string((char*) drumName->children->content);

		xmlNode* soundFile 	= drumName->next->next;
		drum.soundFile 		= std::string((char*) soundFile->children->content);

		xmlNode* threshold 	= soundFile->next->next;
		drum.threshold 		= (short) std::atoi((char*) threshold->children->content);

		xmlNode* scanTime	= threshold->next->next;
		drum.scanTime 		= (int) std::atoi((char*) scanTime->children->content);

		xmlNode* maskTime 	= scanTime->next->next;
		drum.maskTime 		= (int) std::atoi((char*) maskTime->children->content);

		xmlNode* curve 		= maskTime->next->next;
		std::string curveName = std::string((char*) curve->children->content);

		GetDrumCurve(curveName, drum.curve);

		drums.push_back(drum);

		if(curve->parent->next->next)
			*drumName = *curve->parent->next->next->children->next;
		else
			return false;

		return true;
	}

	DrumCurve Module::GetCurveType(std::string curveName)
	{
		// Create map
		std::map<std::string, DrumCurve> dic;

		// Add definitions to dic
		dic["exponential"] = DrumCurve::exponential;
		dic["linear"] = DrumCurve::linear;

		std::map< std::string, DrumCurve>::iterator i = dic.find(curveName);

		if(i != dic.end())
			return i->second;
		else
			return DrumCurve::linear; // Default value

	}

	void Module::GetDrumCurve(std::string curveName, std::vector<float>& curve)
	{

		DrumCurve drumCurve = GetCurveType(curveName);

		switch(drumCurve)
		{

		case DrumCurve::exponential: Curves::Exponential(curve);
			break;

		default: throw - 1;
		}

		return;
	}

}

<commit_msg>Changed default curve to linear.<commit_after>/*
 * Drum.cpp
 *
 *  Created on: 6 May 2015
 *      Author: jeremy
 */

#include "Module.h"

namespace DrumKit
{

	Module::Module()
	: soundParameters(sndParams),
	  directory("./")
	{

		return;
	}

	Module::Module(std::string dir)
	: soundParameters(sndParams),
	  directory(dir)
	{

		return;
	}

	Module::~Module()
	{

		for(size_t i = 0; i < sndParams.size(); i++)
			delete[] sndParams[i].data;

		sndParams.clear();

		return;
	}

	void Module::LoadKit(std::string file, Kit& kit)
	{

		const char* fileName 	= file.c_str();

		//xmlInitParser();

		xmlDoc* doc 			= xmlReadFile(fileName, NULL, 0);
		xmlNode* rootElement 	= xmlDocGetRootElement(doc);

		xmlNode* node 			= rootElement->children;

		xmlNode* kitName 		= node->next;
		kit.kitName				= std::string((char*) kitName->children->content);

		xmlNode* kitFolder 		= kitName->next->next;
		kit.kitFolder 			= std::string((char*) kitFolder->children->content);

		xmlNode* kitParams 		= kitFolder->next->next;
		xmlNode* drumName 		= kitParams->children->next;

		bool getSound = true;

		while(getSound)
		{

			size_t drumId = kit.drum.size();

			bool newSound = GetDrumParams(drumName, kit.drum);

			std::string drumFileName = kit.drum.front().soundFile;
			std::string fileSound = directory + "Kits/" + kit.kitFolder + "/" + drumFileName;

			// Sound id must match drumId (index in the kit.drum vector)
			AddSound(fileSound, drumId);

			drumId++;

			if(!newSound)
				getSound = false;

		}

		//xmlFreeDoc(doc);
		xmlFree(doc);
		//xmlCleanupParser();
	    //xmlMemoryDump();

		return;
	}

	/// PRIVATE

	void Module::AddSound(std::string filename, size_t soundId)
	{

		// Get file location
		std::string fileLocation(filename);

		// Open file
		std::ifstream soundFile(fileLocation);

		// Check file validity
		if(!soundFile.good())
			throw - 1;

		soundFile.seekg (0, std::ios::end);

		// Get file size in bytes
		int fileSize = soundFile.tellg();

		short* soundData = new short[fileSize];

		soundFile.seekg(0, std::ios::beg);

		int i = 0;
		while(soundFile.read((char*)&soundData[i], sizeof(short))) i++;

		SoundParams sndParameters;

		sndParameters.length 	= fileSize*sizeof(char)/sizeof(short);
		sndParameters.data 		= soundData;
		sndParameters.id 		= soundId;

		// Add sound to lib
		sndParams.push_back(sndParameters);

		// Close file
		soundFile.close();

		return;
	}

	bool Module::GetDrumParams(xmlNode* drumName, std::vector<Drum>& drums)
	{

		Drum drum;

		drum.id 			= drums.size();

		drum.drumName 		= std::string((char*) drumName->children->content);

		xmlNode* soundFile 	= drumName->next->next;
		drum.soundFile 		= std::string((char*) soundFile->children->content);

		xmlNode* threshold 	= soundFile->next->next;
		drum.threshold 		= (short) std::atoi((char*) threshold->children->content);

		xmlNode* scanTime	= threshold->next->next;
		drum.scanTime 		= (int) std::atoi((char*) scanTime->children->content);

		xmlNode* maskTime 	= scanTime->next->next;
		drum.maskTime 		= (int) std::atoi((char*) maskTime->children->content);

		xmlNode* curve 		= maskTime->next->next;
		std::string curveName = std::string((char*) curve->children->content);

		GetDrumCurve(curveName, drum.curve);

		drums.push_back(drum);

		if(curve->parent->next->next)
			*drumName = *curve->parent->next->next->children->next;
		else
			return false;

		return true;
	}

	DrumCurve Module::GetCurveType(std::string curveName)
	{
		// Create map
		std::map<std::string, DrumCurve> dic;

		// Add definitions to dic
		dic["exponential"] = DrumCurve::exponential;
		dic["linear"] = DrumCurve::linear;

		std::map< std::string, DrumCurve>::iterator i = dic.find(curveName);

		if(i != dic.end())
			return i->second;
		else
			return DrumCurve::linear; // Default value

	}

	void Module::GetDrumCurve(std::string curveName, std::vector<float>& curve)
	{

		DrumCurve drumCurve = GetCurveType(curveName);

		switch(drumCurve)
		{

		case DrumCurve::exponential:
				Curves::Exponential(curve);
			break;

		default:
				Curves::Linear(curve);
			break;
		}

		return;
	}

}

<|endoftext|>