<commit_before>#if _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN_PAUSE 0
#include <objbase.h>
#endif

#include <clocale>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <signal.h>
#include <regex>
#include <list>
#include "hecl/Database.hpp"
#include "hecl/Blender/Connection.hpp"
#include "logvisor/logvisor.hpp"

logvisor::Module LogModule("hecl::Driver");

#include "ToolBase.hpp"
#include "ToolInit.hpp"
#include "ToolSpec.hpp"
#include "ToolExtract.hpp"
#include "ToolCook.hpp"
#include "ToolPackage.hpp"
#include "ToolImage.hpp"
#include "ToolHelp.hpp"

/* Static reference to dataspec additions
 * (used by MSVC to definitively link DataSpecs) */
#include "DataSpecRegistry.hpp"

bool XTERM_COLOR = false;

/*
#define HECL_GIT 1234567
#define HECL_GIT_S "1234567"
#define HECL_BRANCH master
#define HECL_BRANCH_S "master"
*/

/* Main usage message */
static void printHelp(const hecl::SystemChar* pname) {
  if (XTERM_COLOR)
    fmt::print(fmt(_SYS_STR("" BOLD "HECL" NORMAL "")));
  else
    fmt::print(fmt(_SYS_STR("HECL")));
#if HECL_HAS_NOD
#define TOOL_LIST "extract|init|cook|package|image|help"
#else
#define TOOL_LIST "extract|init|cook|package|help"
#endif
#if HECL_GIT
  fmt::print(fmt(_SYS_STR(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: {} " TOOL_LIST "\n")), pname);
#elif HECL_VER
  fmt::print(fmt(_SYS_STR(" Version " HECL_VER_S "\nUsage: {} " TOOL_LIST "\n")), pname);
#else
  fmt::print(fmt(_SYS_STR("\nUsage: {} " TOOL_LIST "\n")), pname);
#endif
}

/* Regex patterns */
static const hecl::SystemRegex regOPEN(_SYS_STR("-o([^\"]*|\\S*)"), std::regex::ECMAScript | std::regex::optimize);

static ToolBase* ToolPtr = nullptr;

/* SIGINT will gracefully close blender connections and delete blends in progress */
static void SIGINTHandler(int sig) {
  if (ToolPtr)
    ToolPtr->cancel();
  hecl::blender::Connection::Shutdown();
  logvisor::KillProcessTree();
  exit(1);
}

static logvisor::Module AthenaLog("Athena");
static void AthenaExc(athena::error::Level level, const char* file, const char*, int line,
                      fmt::string_view fmt, fmt::format_args args) {
  AthenaLog.vreport(logvisor::Level(level), fmt, args);
}

static hecl::SystemChar cwdbuf[1024];
hecl::SystemString ExeDir;

static std::unique_ptr<hecl::Database::Project> FindProject(hecl::SystemStringView cwd) {
  const hecl::ProjectRootPath rootPath = hecl::SearchForProject(cwd);
  if (!rootPath) {
    return nullptr;
  }

  const size_t ErrorRef = logvisor::ErrorCount;
  auto newProj = std::make_unique<hecl::Database::Project>(rootPath);
  if (logvisor::ErrorCount > ErrorRef) {
#if WIN_PAUSE
    system("PAUSE");
#endif
    return nullptr;
  }

  return newProj;
}

#if _WIN32
int wmain(int argc, const wchar_t** argv)
#else
/* SIGWINCH should do nothing */
static void SIGWINCHHandler(int sig) {}
int main(int argc, const char** argv)
#endif
{
  if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) {
    fmt::print(fmt("{}\n"), HECL_DLPACKAGE);
    return 100;
  }

#if _WIN32
  CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
#else
  std::setlocale(LC_ALL, "en-US.UTF-8");
#endif

  /* Xterm check */
#if _WIN32
  const char* conemuANSI = getenv("ConEmuANSI");
  if (conemuANSI && !strcmp(conemuANSI, "ON"))
    XTERM_COLOR = true;
#else
  const char* term = getenv("TERM");
  if (term && !strncmp(term, "xterm", 5))
    XTERM_COLOR = true;
  signal(SIGWINCH, SIGWINCHHandler);
#endif
  signal(SIGINT, SIGINTHandler);

  logvisor::RegisterStandardExceptions();
  logvisor::RegisterConsoleLogger();
  atSetExceptionHandler(AthenaExc);

  /* Basic usage check */
  if (argc == 1) {
    printHelp(argv[0]);
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 0;
  } else if (argc == 0) {
    printHelp(_SYS_STR("hecl"));
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 0;
  }

  /* Prepare DataSpecs */
  HECLRegisterDataSpecs();

  /* Assemble common tool pass info */
  ToolPassInfo info;
  info.pname = argv[0];
  if (hecl::Getcwd(cwdbuf, 1024)) {
    info.cwd = cwdbuf;
    if (info.cwd.size() && info.cwd.back() != _SYS_STR('/') && info.cwd.back() != _SYS_STR('\\'))
#if _WIN32
      info.cwd += _SYS_STR('\\');
#else
      info.cwd += _SYS_STR('/');
#endif

    if (hecl::PathRelative(argv[0]))
      ExeDir = hecl::SystemString(cwdbuf) + _SYS_STR('/');
    hecl::SystemString Argv0(argv[0]);
    hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\"));
    if (lastIdx != hecl::SystemString::npos)
      ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx);
  }

  /* Concatenate args */
  std::vector<hecl::SystemString> args;
  args.reserve(argc - 2);
  for (int i = 2; i < argc; ++i)
    args.push_back(hecl::SystemString(argv[i]));

  if (!args.empty()) {
    /* Extract output argument */
    for (auto it = args.cbegin(); it != args.cend();) {
      const hecl::SystemString& arg = *it;
      hecl::SystemRegexMatch oMatch;
      if (std::regex_search(arg, oMatch, regOPEN)) {
        const hecl::SystemString& token = oMatch[1].str();
        if (token.size()) {
          if (info.output.empty())
            info.output = oMatch[1].str();
          it = args.erase(it);
        } else {
          it = args.erase(it);
          if (it == args.end())
            break;
          if (info.output.empty())
            info.output = *it;
          it = args.erase(it);
        }
        continue;
      }
      ++it;
    }

    /* Iterate flags */
    bool threadArg = false;
    for (auto it = args.cbegin(); it != args.cend();) {
      const hecl::SystemString& arg = *it;
      if (threadArg) {
        threadArg = false;
        hecl::CpuCountOverride = int(hecl::StrToUl(arg.c_str(), nullptr, 0));
        it = args.erase(it);
        continue;
      }
      if (arg.size() < 2 || arg[0] != _SYS_STR('-') || arg[1] == _SYS_STR('-')) {
        ++it;
        continue;
      }

      for (auto chit = arg.cbegin() + 1; chit != arg.cend(); ++chit) {
        if (*chit == _SYS_STR('v'))
          ++info.verbosityLevel;
        else if (*chit == _SYS_STR('f'))
          info.force = true;
        else if (*chit == _SYS_STR('y'))
          info.yes = true;
        else if (*chit == _SYS_STR('g'))
          info.gui = true;
        else if (*chit == _SYS_STR('j')) {
          ++chit;
          if (*chit)
            hecl::CpuCountOverride = int(hecl::StrToUl(&*chit, nullptr, 0));
          else
            threadArg = true;
          break;
        }
        else
          info.flags.push_back(*chit);
      }

      it = args.erase(it);
    }

    /* Gather remaining args */
    info.args.reserve(args.size());
    for (const hecl::SystemString& arg : args)
      info.args.push_back(arg);
  }

  /* Attempt to find hecl project */
  auto project = FindProject(info.cwd);
  if (project != nullptr) {
    info.project = project.get();
  }

  /* Construct selected tool */
  hecl::SystemString toolName(argv[1]);
  hecl::ToLower(toolName);
  std::unique_ptr<ToolBase> tool;

  size_t ErrorRef = logvisor::ErrorCount;
  if (toolName == _SYS_STR("init"))
    tool.reset(new ToolInit(info));
  else if (toolName == _SYS_STR("spec"))
    tool.reset(new ToolSpec(info));
  else if (toolName == _SYS_STR("extract"))
    tool.reset(new ToolExtract(info));
  else if (toolName == _SYS_STR("cook"))
    tool.reset(new ToolCook(info));
  else if (toolName == _SYS_STR("package") || toolName == _SYS_STR("pack"))
    tool.reset(new ToolPackage(info));
#if HECL_HAS_NOD
  else if (toolName == _SYS_STR("image"))
    tool.reset(new ToolImage(info));
#endif
  else if (toolName == _SYS_STR("help"))
    tool.reset(new ToolHelp(info));
  else {
    FILE* fp = hecl::Fopen(argv[1], _SYS_STR("rb"));
    if (!fp)
      LogModule.report(logvisor::Error, fmt(_SYS_STR("unrecognized tool '{}'")), toolName);
    else {
      /* Shortcut-case: implicit extract */
      fclose(fp);
      info.args.insert(info.args.begin(), argv[1]);
      tool.reset(new ToolExtract(info));
    }
  }

  if (logvisor::ErrorCount > ErrorRef) {
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 1;
  }

  if (info.verbosityLevel)
    LogModule.report(logvisor::Info, fmt(_SYS_STR("Constructed tool '{}' {}\n")), tool->toolName(), info.verbosityLevel);

  /* Run tool */
  ErrorRef = logvisor::ErrorCount;
  ToolPtr = tool.get();
  int retval = tool->run();
  ToolPtr = nullptr;
  if (logvisor::ErrorCount > ErrorRef) {
    hecl::blender::Connection::Shutdown();
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 1;
  }

  hecl::blender::Connection::Shutdown();
#if WIN_PAUSE
  system("PAUSE");
#endif
  return retval;
}
<commit_msg>driver/main: Factor out tool construction code to its own function<commit_after>#if _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN_PAUSE 0
#include <objbase.h>
#endif

#include <clocale>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <signal.h>
#include <regex>
#include <list>
#include "hecl/Database.hpp"
#include "hecl/Blender/Connection.hpp"
#include "logvisor/logvisor.hpp"

logvisor::Module LogModule("hecl::Driver");

#include "ToolBase.hpp"
#include "ToolInit.hpp"
#include "ToolSpec.hpp"
#include "ToolExtract.hpp"
#include "ToolCook.hpp"
#include "ToolPackage.hpp"
#include "ToolImage.hpp"
#include "ToolHelp.hpp"

/* Static reference to dataspec additions
 * (used by MSVC to definitively link DataSpecs) */
#include "DataSpecRegistry.hpp"

bool XTERM_COLOR = false;

/*
#define HECL_GIT 1234567
#define HECL_GIT_S "1234567"
#define HECL_BRANCH master
#define HECL_BRANCH_S "master"
*/

/* Main usage message */
static void printHelp(const hecl::SystemChar* pname) {
  if (XTERM_COLOR)
    fmt::print(fmt(_SYS_STR("" BOLD "HECL" NORMAL "")));
  else
    fmt::print(fmt(_SYS_STR("HECL")));
#if HECL_HAS_NOD
#define TOOL_LIST "extract|init|cook|package|image|help"
#else
#define TOOL_LIST "extract|init|cook|package|help"
#endif
#if HECL_GIT
  fmt::print(fmt(_SYS_STR(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: {} " TOOL_LIST "\n")), pname);
#elif HECL_VER
  fmt::print(fmt(_SYS_STR(" Version " HECL_VER_S "\nUsage: {} " TOOL_LIST "\n")), pname);
#else
  fmt::print(fmt(_SYS_STR("\nUsage: {} " TOOL_LIST "\n")), pname);
#endif
}

/* Regex patterns */
static const hecl::SystemRegex regOPEN(_SYS_STR("-o([^\"]*|\\S*)"), std::regex::ECMAScript | std::regex::optimize);

static ToolBase* ToolPtr = nullptr;

/* SIGINT will gracefully close blender connections and delete blends in progress */
static void SIGINTHandler(int sig) {
  if (ToolPtr)
    ToolPtr->cancel();
  hecl::blender::Connection::Shutdown();
  logvisor::KillProcessTree();
  exit(1);
}

static logvisor::Module AthenaLog("Athena");
static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, fmt::string_view fmt,
                      fmt::format_args args) {
  AthenaLog.vreport(logvisor::Level(level), fmt, args);
}

static hecl::SystemChar cwdbuf[1024];
hecl::SystemString ExeDir;

static std::unique_ptr<hecl::Database::Project> FindProject(hecl::SystemStringView cwd) {
  const hecl::ProjectRootPath rootPath = hecl::SearchForProject(cwd);
  if (!rootPath) {
    return nullptr;
  }

  const size_t ErrorRef = logvisor::ErrorCount;
  auto newProj = std::make_unique<hecl::Database::Project>(rootPath);
  if (logvisor::ErrorCount > ErrorRef) {
#if WIN_PAUSE
    system("PAUSE");
#endif
    return nullptr;
  }

  return newProj;
}

static std::unique_ptr<ToolBase> MakeSelectedTool(hecl::SystemString toolName, ToolPassInfo& info) {
  hecl::SystemString toolNameLower = toolName;
  hecl::ToLower(toolNameLower);

  if (toolNameLower == _SYS_STR("init")) {
    return std::make_unique<ToolInit>(info);
  }

  if (toolNameLower == _SYS_STR("spec")) {
    return std::make_unique<ToolSpec>(info);
  }

  if (toolNameLower == _SYS_STR("extract")) {
    return std::make_unique<ToolExtract>(info);
  }

  if (toolNameLower == _SYS_STR("cook")) {
    return std::make_unique<ToolCook>(info);
  }

  if (toolNameLower == _SYS_STR("package") || toolNameLower == _SYS_STR("pack")) {
    return std::make_unique<ToolPackage>(info);
  }

#if HECL_HAS_NOD
  if (toolNameLower == _SYS_STR("image")) {
    return std::make_unique<ToolImage>(info);
  }
#endif

  if (toolNameLower == _SYS_STR("help")) {
    return std::make_unique<ToolHelp>(info);
  }

  std::unique_ptr<FILE, decltype(&std::fclose)> fp{hecl::Fopen(toolName.c_str(), _SYS_STR("rb")), std::fclose};
  if (fp == nullptr) {
    LogModule.report(logvisor::Error, fmt(_SYS_STR("unrecognized tool '{}'")), toolNameLower);
    return nullptr;
  }
  fp.reset();

  /* Shortcut-case: implicit extract */
  info.args.insert(info.args.begin(), std::move(toolName));
  return std::make_unique<ToolExtract>(info);
}

#if _WIN32
int wmain(int argc, const wchar_t** argv)
#else
/* SIGWINCH should do nothing */
static void SIGWINCHHandler(int sig) {}
int main(int argc, const char** argv)
#endif
{
  if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) {
    fmt::print(fmt("{}\n"), HECL_DLPACKAGE);
    return 100;
  }

#if _WIN32
  CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
#else
  std::setlocale(LC_ALL, "en-US.UTF-8");
#endif

  /* Xterm check */
#if _WIN32
  const char* conemuANSI = getenv("ConEmuANSI");
  if (conemuANSI && !strcmp(conemuANSI, "ON"))
    XTERM_COLOR = true;
#else
  const char* term = getenv("TERM");
  if (term && !strncmp(term, "xterm", 5))
    XTERM_COLOR = true;
  signal(SIGWINCH, SIGWINCHHandler);
#endif
  signal(SIGINT, SIGINTHandler);

  logvisor::RegisterStandardExceptions();
  logvisor::RegisterConsoleLogger();
  atSetExceptionHandler(AthenaExc);

  /* Basic usage check */
  if (argc == 1) {
    printHelp(argv[0]);
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 0;
  } else if (argc == 0) {
    printHelp(_SYS_STR("hecl"));
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 0;
  }

  /* Prepare DataSpecs */
  HECLRegisterDataSpecs();

  /* Assemble common tool pass info */
  ToolPassInfo info;
  info.pname = argv[0];
  if (hecl::Getcwd(cwdbuf, 1024)) {
    info.cwd = cwdbuf;
    if (info.cwd.size() && info.cwd.back() != _SYS_STR('/') && info.cwd.back() != _SYS_STR('\\'))
#if _WIN32
      info.cwd += _SYS_STR('\\');
#else
      info.cwd += _SYS_STR('/');
#endif

    if (hecl::PathRelative(argv[0]))
      ExeDir = hecl::SystemString(cwdbuf) + _SYS_STR('/');
    hecl::SystemString Argv0(argv[0]);
    hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_SYS_STR("/\\"));
    if (lastIdx != hecl::SystemString::npos)
      ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx);
  }

  /* Concatenate args */
  std::vector<hecl::SystemString> args;
  args.reserve(argc - 2);
  for (int i = 2; i < argc; ++i)
    args.push_back(hecl::SystemString(argv[i]));

  if (!args.empty()) {
    /* Extract output argument */
    for (auto it = args.cbegin(); it != args.cend();) {
      const hecl::SystemString& arg = *it;
      hecl::SystemRegexMatch oMatch;
      if (std::regex_search(arg, oMatch, regOPEN)) {
        const hecl::SystemString& token = oMatch[1].str();
        if (token.size()) {
          if (info.output.empty())
            info.output = oMatch[1].str();
          it = args.erase(it);
        } else {
          it = args.erase(it);
          if (it == args.end())
            break;
          if (info.output.empty())
            info.output = *it;
          it = args.erase(it);
        }
        continue;
      }
      ++it;
    }

    /* Iterate flags */
    bool threadArg = false;
    for (auto it = args.cbegin(); it != args.cend();) {
      const hecl::SystemString& arg = *it;
      if (threadArg) {
        threadArg = false;
        hecl::CpuCountOverride = int(hecl::StrToUl(arg.c_str(), nullptr, 0));
        it = args.erase(it);
        continue;
      }
      if (arg.size() < 2 || arg[0] != _SYS_STR('-') || arg[1] == _SYS_STR('-')) {
        ++it;
        continue;
      }

      for (auto chit = arg.cbegin() + 1; chit != arg.cend(); ++chit) {
        if (*chit == _SYS_STR('v'))
          ++info.verbosityLevel;
        else if (*chit == _SYS_STR('f'))
          info.force = true;
        else if (*chit == _SYS_STR('y'))
          info.yes = true;
        else if (*chit == _SYS_STR('g'))
          info.gui = true;
        else if (*chit == _SYS_STR('j')) {
          ++chit;
          if (*chit)
            hecl::CpuCountOverride = int(hecl::StrToUl(&*chit, nullptr, 0));
          else
            threadArg = true;
          break;
        } else
          info.flags.push_back(*chit);
      }

      it = args.erase(it);
    }

    /* Gather remaining args */
    info.args.reserve(args.size());
    for (const hecl::SystemString& arg : args)
      info.args.push_back(arg);
  }

  /* Attempt to find hecl project */
  auto project = FindProject(info.cwd);
  if (project != nullptr) {
    info.project = project.get();
  }

  /* Construct selected tool */
  size_t ErrorRef = logvisor::ErrorCount;
  auto tool = MakeSelectedTool(argv[1], info);

  if (logvisor::ErrorCount > ErrorRef) {
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 1;
  }

  if (info.verbosityLevel) {
    LogModule.report(logvisor::Info, fmt(_SYS_STR("Constructed tool '{}' {}\n")), tool->toolName(),
                     info.verbosityLevel);
  }

  /* Run tool */
  ErrorRef = logvisor::ErrorCount;
  ToolPtr = tool.get();
  int retval = tool->run();
  ToolPtr = nullptr;
  if (logvisor::ErrorCount > ErrorRef) {
    hecl::blender::Connection::Shutdown();
#if WIN_PAUSE
    system("PAUSE");
#endif
    return 1;
  }

  hecl::blender::Connection::Shutdown();
#if WIN_PAUSE
  system("PAUSE");
#endif
  return retval;
}
<|endoftext|>


<commit_before><commit_msg>Clean up C-style casts from pointers to void<commit_after><|endoftext|>


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

#include "documentbuilder.hxx"
#include "node.hxx"
#include "document.hxx"

#include <rtl/alloc.h>
#include <rtl/memory.h>
#include <rtl/ustrbuf.hxx>

#include <cppuhelper/implbase1.hxx>

#include <libxml/xmlerror.h>

#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <ucbhelper/content.hxx>
#include <ucbhelper/commandenvironment.hxx>

#include <string.h>
#include <stdio.h>
#include <stdarg.h>

using ::rtl::OUStringBuffer;
using ::rtl::OString;
using ::com::sun::star::xml::sax::InputSource;
using namespace ucbhelper;
using namespace ::com::sun::star::ucb;
using ::com::sun::star::task::XInteractionHandler;

namespace DOM
{
    extern "C" {
        //char *strdup(const char *s);
        /*
        static char* strdupfunc(const char* s)
        {
            sal_Int32 len = 0;
            while (s[len] != '\0') len++;
            char *newStr = (char*)rtl_allocateMemory(len+1);
            if (newStr != NULL)
                rtl_copyMemory(newStr, s, len+1);
            return newStr;
        }
        */
    }

    class CDefaultEntityResolver : public cppu::WeakImplHelper1< XEntityResolver >
    {
    public:
        virtual InputSource SAL_CALL resolveEntity( const OUString& sPublicId, const OUString& sSystemId )
            throw (::com::sun::star::uno::RuntimeException)
        {
            InputSource is;
            is.sPublicId = sPublicId;
            is.sSystemId = sSystemId;
            is.sEncoding = OUString();

            try {
                Reference< XCommandEnvironment > aEnvironment(
                    new CommandEnvironment(Reference< XInteractionHandler >(),
                                           Reference< XProgressHandler >() ));
                Content aContent(sSystemId, aEnvironment);

                is.aInputStream = aContent.openStream();
            } catch (com::sun::star::uno::Exception) {
                OSL_ENSURE(sal_False, "exception in default entity resolver");
                is.aInputStream = Reference< XInputStream >();
            }
            return is;
        }

    };

    CDocumentBuilder::CDocumentBuilder(const Reference< XMultiServiceFactory >& xFactory)
        : m_aFactory(xFactory)
        , m_aEntityResolver(Reference< XEntityResolver > (new CDefaultEntityResolver()))
    {
        // init libxml. libxml will protect itself against multiple
        // initializations so there is no problem here if this gets
        // called multiple times.
        xmlInitParser();
    }

    Reference< XInterface > CDocumentBuilder::_getInstance(const Reference< XMultiServiceFactory >& rSMgr)
    {
        // XXX
        return static_cast< XDocumentBuilder* >(new CDocumentBuilder(rSMgr));
    }

    const char* CDocumentBuilder::aImplementationName = "com.sun.star.comp.xml.dom.DocumentBuilder";
    const char* CDocumentBuilder::aSupportedServiceNames[] = {
        "com.sun.star.xml.dom.DocumentBuilder",
        NULL
    };

    OUString CDocumentBuilder::_getImplementationName()
    {
        return OUString::createFromAscii(aImplementationName);
    }
    Sequence<OUString> CDocumentBuilder::_getSupportedServiceNames()
    {
        Sequence<OUString> aSequence;
        for (int i=0; aSupportedServiceNames[i]!=NULL; i++) {
            aSequence.realloc(i+1);
            aSequence[i]=(OUString::createFromAscii(aSupportedServiceNames[i]));
        }
        return aSequence;
    }

    Sequence< OUString > SAL_CALL CDocumentBuilder::getSupportedServiceNames()
        throw (RuntimeException)
    {
        return CDocumentBuilder::_getSupportedServiceNames();
    }

    OUString SAL_CALL CDocumentBuilder::getImplementationName()
        throw (RuntimeException)
    {
        return CDocumentBuilder::_getImplementationName();
    }

    sal_Bool SAL_CALL CDocumentBuilder::supportsService(const OUString& aServiceName)
        throw (RuntimeException)
    {
        Sequence< OUString > supported = CDocumentBuilder::_getSupportedServiceNames();
        for (sal_Int32 i=0; i<supported.getLength(); i++)
        {
            if (supported[i] == aServiceName) return sal_True;
        }
        return sal_False;
    }

    Reference< XDOMImplementation > SAL_CALL CDocumentBuilder::getDOMImplementation()
        throw (RuntimeException)
    {

        return Reference< XDOMImplementation >();
    }

    sal_Bool SAL_CALL CDocumentBuilder::isNamespaceAware()
        throw (RuntimeException)
    {
        return sal_True;
    }

    sal_Bool SAL_CALL CDocumentBuilder::isValidating()
        throw (RuntimeException)
    {
        return sal_False;
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::newDocument()
        throw (RuntimeException)
    {
        // create a new document
        xmlDocPtr pDocument = xmlNewDoc((const xmlChar*)"1.0");
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDocument)));
    }

    static OUString make_error_message(xmlParserCtxtPtr ctxt)
    {
        OUStringBuffer buf;
        buf.appendAscii(ctxt->lastError.message);
        buf.appendAscii("Line: ");
        buf.append(static_cast<sal_Int32>(ctxt->lastError.line));
        buf.appendAscii("\nColumn: ");
        buf.append(static_cast<sal_Int32>(ctxt->lastError.int2));
        OUString msg = buf.makeStringAndClear();
        return msg;
    }

    // -- callbacks and context struct for parsing from stream
    // -- c-linkage, so the callbacks can be used by libxml
    extern "C" {

    // context struct passed to IO functions
    typedef struct context {
        CDocumentBuilder *pBuilder;
        Reference< XInputStream > rInputStream;
        bool close;
        bool freeOnClose;
    } context_t;

    static int xmlIO_read_func( void *context, char *buffer, int len)
    {
        // get the context...
        context_t *pctx = static_cast<context_t*>(context);
        if (!pctx->rInputStream.is())
            return -1;
        try {
            // try to read the requested number of bytes
            Sequence< sal_Int8 > chunk(len);
            int nread = pctx->rInputStream->readBytes(chunk, len);

            // copy bytes to the provided buffer
            rtl_copyMemory(buffer, chunk.getConstArray(), nread);
            return nread;
        } catch (com::sun::star::uno::Exception& ex) {
            (void) ex;
            OSL_ENSURE(sal_False, OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
            return -1;
        }
    }

    static int xmlIO_close_func(void* context)
    {
        // get the context...
        context_t *pctx = static_cast<context_t*>(context);
        if (!pctx->rInputStream.is())
            return 0;
        try
        {
            if (pctx->close)
                pctx->rInputStream->closeInput();
            if (pctx->freeOnClose)
                delete pctx;
            return 0;
        } catch (com::sun::star::uno::Exception& ex) {
            (void) ex;
            OSL_ENSURE(sal_False, OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
            return -1;
        }
    }

    static xmlParserInputPtr resolve_func(void *ctx,
                                const xmlChar *publicId,
                                const xmlChar *systemId)
    {
        // get the CDocumentBuilder object
        xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx;
        CDocumentBuilder *builder = static_cast< CDocumentBuilder* >(ctxt->_private);
        Reference< XEntityResolver > resolver = builder->getEntityResolver();
        OUString sysid;
        if (systemId != 0)
            sysid = OUString((sal_Char*)systemId, strlen((char*)systemId), RTL_TEXTENCODING_UTF8);
        OUString pubid;
        if (publicId != 0)
            pubid = OUString((sal_Char*)publicId, strlen((char*)publicId), RTL_TEXTENCODING_UTF8);

        // resolve the entity
        InputSource src = resolver->resolveEntity(pubid, sysid);

        // create IO context on heap because this call will no longer be on the stack
        // when IO is actually performed through the callbacks. The close function must
        // free the memory which is indicated by the freeOnClose field in the context struct
        context_t *c = new context_t;
        c->pBuilder = builder;
        c->rInputStream = src.aInputStream;
        c->close = true;
        c->freeOnClose = true;

        // set up the inputBuffer and inputPtr for libxml
        xmlParserInputBufferPtr pBuffer =
            xmlParserInputBufferCreateIO(xmlIO_read_func, xmlIO_close_func, c, XML_CHAR_ENCODING_NONE);
        xmlParserInputPtr pInput =
                    xmlNewIOInputStream(ctxt, pBuffer, XML_CHAR_ENCODING_NONE);
        return pInput;
    }

    static xmlParserInputPtr external_entity_loader(const char *URL, const char * /*ID*/, xmlParserCtxtPtr ctxt)
    {
        // just call our resolver function using the URL as systemId
        return resolve_func(ctxt, 0, (const xmlChar*)URL);
    }

    // default warning handler triggers assertion
    static void warning_func(void * ctx, const char * /*msg*/, ...)
    {
        OUStringBuffer buf(OUString(RTL_CONSTASCII_USTRINGPARAM("libxml2 warning\n")));
        buf.append(make_error_message(static_cast< xmlParserCtxtPtr >(ctx)));
        OString msg = OUStringToOString(buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, msg.getStr());
    }

    // default error handler triggers assertion
    static void error_func(void * ctx, const char * /*msg*/, ...)
    {
        OUStringBuffer buf(OUString(RTL_CONSTASCII_USTRINGPARAM("libxml2 error\n")));
        buf.append(make_error_message(static_cast< xmlParserCtxtPtr >(ctx)));
        OString msg = OUStringToOString(buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, msg.getStr());
    }

    } // extern "C"

    void throwEx(xmlParserCtxtPtr ctxt) {
        OUString msg = make_error_message(ctxt);
        xmlFreeParserCtxt(ctxt);
        com::sun::star::xml::sax::SAXParseException saxex;
        saxex.Message = msg;
        saxex.LineNumber = static_cast<sal_Int32>(ctxt->lastError.line);
        saxex.ColumnNumber = static_cast<sal_Int32>(ctxt->lastError.int2);
        throw saxex;
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parse(const Reference< XInputStream >& is)
        throw (RuntimeException, SAXParseException, IOException)
    {

        // encoding...
        /*
        xmlChar *encstr = (xmlChar*) OUStringToOString(src.sEncoding, RTL_TEXTENCODING_UTF8).getStr();
        xmlCharEncoding enc = xmlParseCharEncoding(encstr);
        */

        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();

        // register error functions to prevent errors being printed
        // on the console
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;
        ctxt->sax->resolveEntity = resolve_func;

        // IO context struct
        context_t c;
        c.pBuilder = this;
        c.rInputStream = is;
        // we did not open the stream, thus we do not close it.
        c.close = false;
        c.freeOnClose = false;
        xmlDocPtr pDoc = xmlCtxtReadIO(ctxt, xmlIO_read_func, xmlIO_close_func, &c,
                     0, 0, 0);

        if (pDoc == 0) {
            throwEx(ctxt);
        }
        xmlFreeParserCtxt(ctxt);
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDoc)));
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parseSource(const InputSource& is)
        throw (RuntimeException, SAXParseException, IOException)
    {
        // if there is an encoding specified in the input source, use it
        xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
        if (is.sEncoding.getLength() > 0) {
            OString oEncstr = OUStringToOString(is.sEncoding, RTL_TEXTENCODING_UTF8);
            char *encstr = (char*) oEncstr.getStr();
            enc = xmlParseCharEncoding(encstr);
        }

        // set up parser context
        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
        // register error functions to prevent errors being printed
        // on the console
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;

        // setup entity resolver binding(s)
        ctxt->sax->resolveEntity = resolve_func;
        xmlSetExternalEntityLoader(external_entity_loader);

        // if an input stream is provided, use it

        // use the systemID

        return Reference< XDocument >();
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parseURI(const OUString& sUri)
        throw (RuntimeException, SAXParseException, IOException)
    {
        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;
        ctxt->sax->resolveEntity = resolve_func;
        // xmlSetExternalEntityLoader(external_entity_loader);
        OString oUri = OUStringToOString(sUri, RTL_TEXTENCODING_UTF8);
        char *uri = (char*) oUri.getStr();
        xmlDocPtr pDoc = xmlCtxtReadFile(ctxt, uri, 0, 0);
        if (pDoc == 0) {
            throwEx(ctxt);
        }
        xmlFreeParserCtxt(ctxt);
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDoc)));
    }

    void SAL_CALL CDocumentBuilder::setEntityResolver(const Reference< XEntityResolver >& er)
        throw (RuntimeException)
    {
        m_aEntityResolver = er;
    }

    Reference< XEntityResolver > SAL_CALL CDocumentBuilder::getEntityResolver()
        throw (RuntimeException)
    {
        return m_aEntityResolver;
    }

    void SAL_CALL CDocumentBuilder::setErrorHandler(const Reference< XErrorHandler >& eh)
        throw (RuntimeException)
    {
        m_aErrorHandler = eh;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>free ctxt *after* taking lastError details<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "documentbuilder.hxx"
#include "node.hxx"
#include "document.hxx"

#include <rtl/alloc.h>
#include <rtl/memory.h>
#include <rtl/ustrbuf.hxx>

#include <cppuhelper/implbase1.hxx>

#include <libxml/xmlerror.h>

#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <ucbhelper/content.hxx>
#include <ucbhelper/commandenvironment.hxx>

#include <string.h>
#include <stdio.h>
#include <stdarg.h>

using ::rtl::OUStringBuffer;
using ::rtl::OString;
using ::com::sun::star::xml::sax::InputSource;
using namespace ucbhelper;
using namespace ::com::sun::star::ucb;
using ::com::sun::star::task::XInteractionHandler;

namespace DOM
{
    extern "C" {
        //char *strdup(const char *s);
        /*
        static char* strdupfunc(const char* s)
        {
            sal_Int32 len = 0;
            while (s[len] != '\0') len++;
            char *newStr = (char*)rtl_allocateMemory(len+1);
            if (newStr != NULL)
                rtl_copyMemory(newStr, s, len+1);
            return newStr;
        }
        */
    }

    class CDefaultEntityResolver : public cppu::WeakImplHelper1< XEntityResolver >
    {
    public:
        virtual InputSource SAL_CALL resolveEntity( const OUString& sPublicId, const OUString& sSystemId )
            throw (::com::sun::star::uno::RuntimeException)
        {
            InputSource is;
            is.sPublicId = sPublicId;
            is.sSystemId = sSystemId;
            is.sEncoding = OUString();

            try {
                Reference< XCommandEnvironment > aEnvironment(
                    new CommandEnvironment(Reference< XInteractionHandler >(),
                                           Reference< XProgressHandler >() ));
                Content aContent(sSystemId, aEnvironment);

                is.aInputStream = aContent.openStream();
            } catch (com::sun::star::uno::Exception) {
                OSL_ENSURE(sal_False, "exception in default entity resolver");
                is.aInputStream = Reference< XInputStream >();
            }
            return is;
        }

    };

    CDocumentBuilder::CDocumentBuilder(const Reference< XMultiServiceFactory >& xFactory)
        : m_aFactory(xFactory)
        , m_aEntityResolver(Reference< XEntityResolver > (new CDefaultEntityResolver()))
    {
        // init libxml. libxml will protect itself against multiple
        // initializations so there is no problem here if this gets
        // called multiple times.
        xmlInitParser();
    }

    Reference< XInterface > CDocumentBuilder::_getInstance(const Reference< XMultiServiceFactory >& rSMgr)
    {
        // XXX
        return static_cast< XDocumentBuilder* >(new CDocumentBuilder(rSMgr));
    }

    const char* CDocumentBuilder::aImplementationName = "com.sun.star.comp.xml.dom.DocumentBuilder";
    const char* CDocumentBuilder::aSupportedServiceNames[] = {
        "com.sun.star.xml.dom.DocumentBuilder",
        NULL
    };

    OUString CDocumentBuilder::_getImplementationName()
    {
        return OUString::createFromAscii(aImplementationName);
    }
    Sequence<OUString> CDocumentBuilder::_getSupportedServiceNames()
    {
        Sequence<OUString> aSequence;
        for (int i=0; aSupportedServiceNames[i]!=NULL; i++) {
            aSequence.realloc(i+1);
            aSequence[i]=(OUString::createFromAscii(aSupportedServiceNames[i]));
        }
        return aSequence;
    }

    Sequence< OUString > SAL_CALL CDocumentBuilder::getSupportedServiceNames()
        throw (RuntimeException)
    {
        return CDocumentBuilder::_getSupportedServiceNames();
    }

    OUString SAL_CALL CDocumentBuilder::getImplementationName()
        throw (RuntimeException)
    {
        return CDocumentBuilder::_getImplementationName();
    }

    sal_Bool SAL_CALL CDocumentBuilder::supportsService(const OUString& aServiceName)
        throw (RuntimeException)
    {
        Sequence< OUString > supported = CDocumentBuilder::_getSupportedServiceNames();
        for (sal_Int32 i=0; i<supported.getLength(); i++)
        {
            if (supported[i] == aServiceName) return sal_True;
        }
        return sal_False;
    }

    Reference< XDOMImplementation > SAL_CALL CDocumentBuilder::getDOMImplementation()
        throw (RuntimeException)
    {

        return Reference< XDOMImplementation >();
    }

    sal_Bool SAL_CALL CDocumentBuilder::isNamespaceAware()
        throw (RuntimeException)
    {
        return sal_True;
    }

    sal_Bool SAL_CALL CDocumentBuilder::isValidating()
        throw (RuntimeException)
    {
        return sal_False;
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::newDocument()
        throw (RuntimeException)
    {
        // create a new document
        xmlDocPtr pDocument = xmlNewDoc((const xmlChar*)"1.0");
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDocument)));
    }

    static OUString make_error_message(xmlParserCtxtPtr ctxt)
    {
        OUStringBuffer buf;
        buf.appendAscii(ctxt->lastError.message);
        buf.appendAscii("Line: ");
        buf.append(static_cast<sal_Int32>(ctxt->lastError.line));
        buf.appendAscii("\nColumn: ");
        buf.append(static_cast<sal_Int32>(ctxt->lastError.int2));
        OUString msg = buf.makeStringAndClear();
        return msg;
    }

    // -- callbacks and context struct for parsing from stream
    // -- c-linkage, so the callbacks can be used by libxml
    extern "C" {

    // context struct passed to IO functions
    typedef struct context {
        CDocumentBuilder *pBuilder;
        Reference< XInputStream > rInputStream;
        bool close;
        bool freeOnClose;
    } context_t;

    static int xmlIO_read_func( void *context, char *buffer, int len)
    {
        // get the context...
        context_t *pctx = static_cast<context_t*>(context);
        if (!pctx->rInputStream.is())
            return -1;
        try {
            // try to read the requested number of bytes
            Sequence< sal_Int8 > chunk(len);
            int nread = pctx->rInputStream->readBytes(chunk, len);

            // copy bytes to the provided buffer
            rtl_copyMemory(buffer, chunk.getConstArray(), nread);
            return nread;
        } catch (com::sun::star::uno::Exception& ex) {
            (void) ex;
            OSL_ENSURE(sal_False, OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
            return -1;
        }
    }

    static int xmlIO_close_func(void* context)
    {
        // get the context...
        context_t *pctx = static_cast<context_t*>(context);
        if (!pctx->rInputStream.is())
            return 0;
        try
        {
            if (pctx->close)
                pctx->rInputStream->closeInput();
            if (pctx->freeOnClose)
                delete pctx;
            return 0;
        } catch (com::sun::star::uno::Exception& ex) {
            (void) ex;
            OSL_ENSURE(sal_False, OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
            return -1;
        }
    }

    static xmlParserInputPtr resolve_func(void *ctx,
                                const xmlChar *publicId,
                                const xmlChar *systemId)
    {
        // get the CDocumentBuilder object
        xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx;
        CDocumentBuilder *builder = static_cast< CDocumentBuilder* >(ctxt->_private);
        Reference< XEntityResolver > resolver = builder->getEntityResolver();
        OUString sysid;
        if (systemId != 0)
            sysid = OUString((sal_Char*)systemId, strlen((char*)systemId), RTL_TEXTENCODING_UTF8);
        OUString pubid;
        if (publicId != 0)
            pubid = OUString((sal_Char*)publicId, strlen((char*)publicId), RTL_TEXTENCODING_UTF8);

        // resolve the entity
        InputSource src = resolver->resolveEntity(pubid, sysid);

        // create IO context on heap because this call will no longer be on the stack
        // when IO is actually performed through the callbacks. The close function must
        // free the memory which is indicated by the freeOnClose field in the context struct
        context_t *c = new context_t;
        c->pBuilder = builder;
        c->rInputStream = src.aInputStream;
        c->close = true;
        c->freeOnClose = true;

        // set up the inputBuffer and inputPtr for libxml
        xmlParserInputBufferPtr pBuffer =
            xmlParserInputBufferCreateIO(xmlIO_read_func, xmlIO_close_func, c, XML_CHAR_ENCODING_NONE);
        xmlParserInputPtr pInput =
                    xmlNewIOInputStream(ctxt, pBuffer, XML_CHAR_ENCODING_NONE);
        return pInput;
    }

    static xmlParserInputPtr external_entity_loader(const char *URL, const char * /*ID*/, xmlParserCtxtPtr ctxt)
    {
        // just call our resolver function using the URL as systemId
        return resolve_func(ctxt, 0, (const xmlChar*)URL);
    }

    // default warning handler triggers assertion
    static void warning_func(void * ctx, const char * /*msg*/, ...)
    {
        OUStringBuffer buf(OUString(RTL_CONSTASCII_USTRINGPARAM("libxml2 warning\n")));
        buf.append(make_error_message(static_cast< xmlParserCtxtPtr >(ctx)));
        OString msg = OUStringToOString(buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, msg.getStr());
    }

    // default error handler triggers assertion
    static void error_func(void * ctx, const char * /*msg*/, ...)
    {
        OUStringBuffer buf(OUString(RTL_CONSTASCII_USTRINGPARAM("libxml2 error\n")));
        buf.append(make_error_message(static_cast< xmlParserCtxtPtr >(ctx)));
        OString msg = OUStringToOString(buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, msg.getStr());
    }

    } // extern "C"

    void throwEx(xmlParserCtxtPtr ctxt)
    {
        com::sun::star::xml::sax::SAXParseException saxex;
        saxex.Message = make_error_message(ctxt);
        saxex.LineNumber = static_cast<sal_Int32>(ctxt->lastError.line);
        saxex.ColumnNumber = static_cast<sal_Int32>(ctxt->lastError.int2);
        xmlFreeParserCtxt(ctxt);
        throw saxex;
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parse(const Reference< XInputStream >& is)
        throw (RuntimeException, SAXParseException, IOException)
    {

        // encoding...
        /*
        xmlChar *encstr = (xmlChar*) OUStringToOString(src.sEncoding, RTL_TEXTENCODING_UTF8).getStr();
        xmlCharEncoding enc = xmlParseCharEncoding(encstr);
        */

        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();

        // register error functions to prevent errors being printed
        // on the console
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;
        ctxt->sax->resolveEntity = resolve_func;

        // IO context struct
        context_t c;
        c.pBuilder = this;
        c.rInputStream = is;
        // we did not open the stream, thus we do not close it.
        c.close = false;
        c.freeOnClose = false;
        xmlDocPtr pDoc = xmlCtxtReadIO(ctxt, xmlIO_read_func, xmlIO_close_func, &c,
                     0, 0, 0);

        if (pDoc == 0) {
            throwEx(ctxt);
        }
        xmlFreeParserCtxt(ctxt);
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDoc)));
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parseSource(const InputSource& is)
        throw (RuntimeException, SAXParseException, IOException)
    {
        // if there is an encoding specified in the input source, use it
        xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
        if (is.sEncoding.getLength() > 0) {
            OString oEncstr = OUStringToOString(is.sEncoding, RTL_TEXTENCODING_UTF8);
            char *encstr = (char*) oEncstr.getStr();
            enc = xmlParseCharEncoding(encstr);
        }

        // set up parser context
        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
        // register error functions to prevent errors being printed
        // on the console
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;

        // setup entity resolver binding(s)
        ctxt->sax->resolveEntity = resolve_func;
        xmlSetExternalEntityLoader(external_entity_loader);

        // if an input stream is provided, use it

        // use the systemID

        return Reference< XDocument >();
    }

    Reference< XDocument > SAL_CALL CDocumentBuilder::parseURI(const OUString& sUri)
        throw (RuntimeException, SAXParseException, IOException)
    {
        xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
        ctxt->_private = this;
        ctxt->sax->error = error_func;
        ctxt->sax->warning = warning_func;
        ctxt->sax->resolveEntity = resolve_func;
        // xmlSetExternalEntityLoader(external_entity_loader);
        OString oUri = OUStringToOString(sUri, RTL_TEXTENCODING_UTF8);
        char *uri = (char*) oUri.getStr();
        xmlDocPtr pDoc = xmlCtxtReadFile(ctxt, uri, 0, 0);
        if (pDoc == 0) {
            throwEx(ctxt);
        }
        xmlFreeParserCtxt(ctxt);
        return Reference< XDocument >(static_cast< CDocument* >(CNode::get((xmlNodePtr)pDoc)));
    }

    void SAL_CALL CDocumentBuilder::setEntityResolver(const Reference< XEntityResolver >& er)
        throw (RuntimeException)
    {
        m_aEntityResolver = er;
    }

    Reference< XEntityResolver > SAL_CALL CDocumentBuilder::getEntityResolver()
        throw (RuntimeException)
    {
        return m_aEntityResolver;
    }

    void SAL_CALL CDocumentBuilder::setErrorHandler(const Reference< XErrorHandler >& eh)
        throw (RuntimeException)
    {
        m_aErrorHandler = eh;
    }
}

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


<commit_before>/**
 * CMathNode class.
 * The class CMathNode is describes a node of the equation tree.
 *
 * Created for Copasi by Stefan Hoops 2003
 */

#include <sstream>

#include "copasi.h"
#include "CMathNode.h"
#include "CMathSymbol.h"

CMathNode::CMathNode(CMathNode * pParent):
    CCopasiNode< std::string >(pParent),
    mData()
{}

CMathNode::CMathNode(const CMathNode &src):
    CCopasiNode< std::string >(src),
    mData(src.mData)
{}

CMathNode::CMathNode(const std::string & data, CMathNode * pParent):
    CCopasiNode< std::string >(pParent),
    mData(data)
{}

CMathNode::~CMathNode() {}

std::string CMathNode::getData() const
  {
    CMathNode * pC = (CMathNode *) getChild();
    if (pC) return pC->getData();
    else return "@@@";
  }

bool CMathNode::setData(const std::string & data)
{
  mData = data;
  return true;
}

const std::string CMathNodeOperation::Operations("+-*/%^");

CMathNodeOperation::CMathNodeOperation(CMathNode * pParent):
    CMathNode(pParent)
{}

CMathNodeOperation::CMathNodeOperation(const std::string & operation, CMathNode * pParent):
    CMathNode(operation, pParent)
{assert (Operations.find(operation) != std::string::npos);}

CMathNodeOperation::CMathNodeOperation(const CMathNodeOperation & src):
    CMathNode(src)
{}

CMathNodeOperation::~CMathNodeOperation() {}

std::string CMathNodeOperation::getData() const
  {
    std::stringstream text;
    const CMathNode * pChild = (CMathNode *) getChild();

    if (pChild)
      {
        text << pChild->getData();

        std::string tmp;
        if (pChild->getSibling())
          tmp = ((CMathNode *) pChild->getSibling())->getData();
        else
          tmp = "@@@";

        if (mData == "+" && tmp[0] == '-')
          {
            tmp = tmp.substr(1);
            text << " - ";
          }
        else if (mData == "-" && tmp[0] == '-')
          {
            tmp = tmp.substr(1);
            text << " + ";
          }
        else
          text << " " << mData << " ";

        if (text.str().substr(text.str().length() - 4) == "1 * ")
          text.seekp(-4, std::ios::cur);

        text << tmp;
      }
    else
      text << "@@@" << mData << "@@@";

    return text.str();
  }

CMathNodeDerivative::CMathNodeDerivative(const std::string & operation,
    CMathNode * pParent):
    CMathNodeOperation(pParent)
{mData = operation;}

CMathNodeDerivative::CMathNodeDerivative(const CMathNodeDerivative &src):
    CMathNodeOperation(src)
{}

CMathNodeDerivative::~CMathNodeDerivative() {}

std::string CMathNodeDerivative::getData() const
  {
    std::stringstream text;
    CMathNode * pChild = (CMathNode *) getChild();

    text << "(" << mData << " ";

    if (pChild)
      {
        text << pChild->getData() << ")(";

        if (pChild->getSibling())
          text << ((CMathNode *) pChild->getSibling())->getData();
        else
          text << "@@@";

        text << ")";
      }
    else
      text << "@@@)(@@@)";

    return text.str();
  }

CMathNodeNumber::CMathNodeNumber(const C_FLOAT64 & number,
                                 CMathNode * pParent):
    CMathNode(pParent)
{setData(number);}

CMathNodeNumber::CMathNodeNumber(const CMathNodeNumber &src):
    CMathNode(src)
{}

CMathNodeNumber::~CMathNodeNumber() {}

std::string CMathNodeNumber::getData() const {return mData;}

bool CMathNodeNumber::setData(const C_FLOAT64 & number)
{
  std::stringstream text;
  text << number;
  mData = text.str();

  return true;
}

CMathNodeSymbol::CMathNodeSymbol(const CMathSymbol * pSymbol,
                                 CMathNode * pParent):
    CMathNode(pParent),
    mpSymbol(pSymbol)
{setData(pSymbol);}

CMathNodeSymbol::CMathNodeSymbol(const CMathNodeSymbol & src):
    CMathNode(src),
    mpSymbol(src.mpSymbol)
{}

CMathNodeSymbol::~CMathNodeSymbol() {}

std::string CMathNodeSymbol::getData() const {return mData;}

bool CMathNodeSymbol::setData(const CMathSymbol * pSymbol)
{
  mpSymbol = pSymbol;

  if (mpSymbol)
    mData = mpSymbol->getName();
  else
    mData = "@@@";

  return true;
}

CMathNodeFunction::CMathNodeFunction(const CMathSymbol * pSymbol,
                                     CMathNode * pParent):
    CMathNodeSymbol(pSymbol, pParent)
{}

CMathNodeFunction::CMathNodeFunction(const CMathNodeFunction & src):
    CMathNodeSymbol(src)
{}

CMathNodeFunction::~CMathNodeFunction() {}

std::string CMathNodeFunction::getData() const
  {
    std::stringstream text;

    text << "<emp>" << mData << "</emp>";

    CMathNode * pChild = (CMathNode *) getChild();

    if (pChild) text << pChild->getData();

    return text.str();
  }

CMathNodeList::CMathNodeList(CMathNode * pParent):
    CMathNode(pParent)
{}

CMathNodeList::CMathNodeList(const CMathNodeList & src):
    CMathNode(src)
{}

CMathNodeList::~CMathNodeList() {}

std::string CMathNodeList::getData() const
  {
    std::stringstream text;

    CMathNode * pChild = (CMathNode *) getChild();

    text << "(";

    while (pChild)
      {
        text << pChild->getData();
        pChild = (CMathNode *) pChild->getSibling();

        if (pChild) text << ", ";
      }

    text << ")";

    return text.str();
  }
<commit_msg>Replaced std::ios with std::ios_base where appropriate.<commit_after>/**
 * CMathNode class.
 * The class CMathNode is describes a node of the equation tree.
 *
 * Created for Copasi by Stefan Hoops 2003
 */

#include <sstream>

#include "copasi.h"
#include "CMathNode.h"
#include "CMathSymbol.h"

CMathNode::CMathNode(CMathNode * pParent):
    CCopasiNode< std::string >(pParent),
    mData()
{}

CMathNode::CMathNode(const CMathNode &src):
    CCopasiNode< std::string >(src),
    mData(src.mData)
{}

CMathNode::CMathNode(const std::string & data, CMathNode * pParent):
    CCopasiNode< std::string >(pParent),
    mData(data)
{}

CMathNode::~CMathNode() {}

std::string CMathNode::getData() const
  {
    CMathNode * pC = (CMathNode *) getChild();
    if (pC) return pC->getData();
    else return "@@@";
  }

bool CMathNode::setData(const std::string & data)
{
  mData = data;
  return true;
}

const std::string CMathNodeOperation::Operations("+-*/%^");

CMathNodeOperation::CMathNodeOperation(CMathNode * pParent):
    CMathNode(pParent)
{}

CMathNodeOperation::CMathNodeOperation(const std::string & operation, CMathNode * pParent):
    CMathNode(operation, pParent)
{assert (Operations.find(operation) != std::string::npos);}

CMathNodeOperation::CMathNodeOperation(const CMathNodeOperation & src):
    CMathNode(src)
{}

CMathNodeOperation::~CMathNodeOperation() {}

std::string CMathNodeOperation::getData() const
  {
    std::stringstream text;
    const CMathNode * pChild = (CMathNode *) getChild();

    if (pChild)
      {
        text << pChild->getData();

        std::string tmp;
        if (pChild->getSibling())
          tmp = ((CMathNode *) pChild->getSibling())->getData();
        else
          tmp = "@@@";

        if (mData == "+" && tmp[0] == '-')
          {
            tmp = tmp.substr(1);
            text << " - ";
          }
        else if (mData == "-" && tmp[0] == '-')
          {
            tmp = tmp.substr(1);
            text << " + ";
          }
        else
          text << " " << mData << " ";

        if (text.str().substr(text.str().length() - 4) == "1 * ")
          text.seekp(-4, std::ios_base::cur);

        text << tmp;
      }
    else
      text << "@@@" << mData << "@@@";

    return text.str();
  }

CMathNodeDerivative::CMathNodeDerivative(const std::string & operation,
    CMathNode * pParent):
    CMathNodeOperation(pParent)
{mData = operation;}

CMathNodeDerivative::CMathNodeDerivative(const CMathNodeDerivative &src):
    CMathNodeOperation(src)
{}

CMathNodeDerivative::~CMathNodeDerivative() {}

std::string CMathNodeDerivative::getData() const
  {
    std::stringstream text;
    CMathNode * pChild = (CMathNode *) getChild();

    text << "(" << mData << " ";

    if (pChild)
      {
        text << pChild->getData() << ")(";

        if (pChild->getSibling())
          text << ((CMathNode *) pChild->getSibling())->getData();
        else
          text << "@@@";

        text << ")";
      }
    else
      text << "@@@)(@@@)";

    return text.str();
  }

CMathNodeNumber::CMathNodeNumber(const C_FLOAT64 & number,
                                 CMathNode * pParent):
    CMathNode(pParent)
{setData(number);}

CMathNodeNumber::CMathNodeNumber(const CMathNodeNumber &src):
    CMathNode(src)
{}

CMathNodeNumber::~CMathNodeNumber() {}

std::string CMathNodeNumber::getData() const {return mData;}

bool CMathNodeNumber::setData(const C_FLOAT64 & number)
{
  std::stringstream text;
  text << number;
  mData = text.str();

  return true;
}

CMathNodeSymbol::CMathNodeSymbol(const CMathSymbol * pSymbol,
                                 CMathNode * pParent):
    CMathNode(pParent),
    mpSymbol(pSymbol)
{setData(pSymbol);}

CMathNodeSymbol::CMathNodeSymbol(const CMathNodeSymbol & src):
    CMathNode(src),
    mpSymbol(src.mpSymbol)
{}

CMathNodeSymbol::~CMathNodeSymbol() {}

std::string CMathNodeSymbol::getData() const {return mData;}

bool CMathNodeSymbol::setData(const CMathSymbol * pSymbol)
{
  mpSymbol = pSymbol;

  if (mpSymbol)
    mData = mpSymbol->getName();
  else
    mData = "@@@";

  return true;
}

CMathNodeFunction::CMathNodeFunction(const CMathSymbol * pSymbol,
                                     CMathNode * pParent):
    CMathNodeSymbol(pSymbol, pParent)
{}

CMathNodeFunction::CMathNodeFunction(const CMathNodeFunction & src):
    CMathNodeSymbol(src)
{}

CMathNodeFunction::~CMathNodeFunction() {}

std::string CMathNodeFunction::getData() const
  {
    std::stringstream text;

    text << "<emp>" << mData << "</emp>";

    CMathNode * pChild = (CMathNode *) getChild();

    if (pChild) text << pChild->getData();

    return text.str();
  }

CMathNodeList::CMathNodeList(CMathNode * pParent):
    CMathNode(pParent)
{}

CMathNodeList::CMathNodeList(const CMathNodeList & src):
    CMathNode(src)
{}

CMathNodeList::~CMathNodeList() {}

std::string CMathNodeList::getData() const
  {
    std::stringstream text;

    CMathNode * pChild = (CMathNode *) getChild();

    text << "(";

    while (pChild)
      {
        text << pChild->getData();
        pChild = (CMathNode *) pChild->getSibling();

        if (pChild) text << ", ";
      }

    text << ")";

    return text.str();
  }
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "hash_map.hpp"
#include "hash_map_equal.hpp"
#include <vespa/vespalib/util/array_equal.hpp>

namespace vespalib {
}

VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, vespalib::string);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, int);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned int);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned long);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned long long);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, double);
VESPALIB_HASH_MAP_INSTANTIATE(int64_t, int32_t);
VESPALIB_HASH_MAP_INSTANTIATE(int64_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(int32_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, int32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint64_t);
VESPALIB_HASH_MAP_INSTANTIATE(double, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(float, uint32_t);
<commit_msg>Instatiate map externally.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "hash_map.hpp"
#include "hash_map_equal.hpp"
#include <vespa/vespalib/util/array_equal.hpp>

namespace vespalib {
}

VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, vespalib::string);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, int);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned int);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned long);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, unsigned long long);
VESPALIB_HASH_MAP_INSTANTIATE(vespalib::string, double);
VESPALIB_HASH_MAP_INSTANTIATE(int64_t, int32_t);
VESPALIB_HASH_MAP_INSTANTIATE(int64_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(int32_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, int32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint32_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, uint64_t);
VESPALIB_HASH_MAP_INSTANTIATE(uint64_t, bool);
VESPALIB_HASH_MAP_INSTANTIATE(double, uint32_t);
VESPALIB_HASH_MAP_INSTANTIATE(float, uint32_t);
<|endoftext|>


<commit_before>// Copyright 2015 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 "components/autofill/core/browser/wallet/real_pan_wallet_client.h"

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/autofill/core/browser/credit_card.h"
#include "google_apis/gaia/identity_provider.h"
#include "net/base/escape.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"

namespace autofill {
namespace wallet {

namespace {

const char kUnmaskCardRequestFormat[] =
    "requestContentType=application/json; charset=utf-8&request=%s"
    "&s7e_13_cvc=%s";

const char kUnmaskCardRequestUrl[] =
    "https://sandbox.google.com/payments/apis-secure/creditcardservice"
    "/getrealpan?s7e_suffix=chromewallet";

const char kTokenServiceConsumerId[] = "real_pan_wallet_client";
const char kWalletOAuth2Scope[] =
    "https://www.googleapis.com/auth/wallet.chrome";

}  // namespace

RealPanWalletClient::RealPanWalletClient(
    net::URLRequestContextGetter* context_getter,
    Delegate* delegate)
    : OAuth2TokenService::Consumer(kTokenServiceConsumerId),
      context_getter_(context_getter),
      delegate_(delegate),
      weak_ptr_factory_(this) {
  DCHECK(delegate);
}

RealPanWalletClient::~RealPanWalletClient() {
}

void RealPanWalletClient::Prepare() {
  if (access_token_.empty())
    StartTokenFetch();
}

void RealPanWalletClient::UnmaskCard(
    const CreditCard& card,
    const CardUnmaskDelegate::UnmaskResponse& response) {
  DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type());

  request_.reset(net::URLFetcher::Create(
      0, GURL(kUnmaskCardRequestUrl), net::URLFetcher::POST, this));
  request_->SetRequestContext(context_getter_.get());

  base::DictionaryValue request_dict;
  request_dict.SetString("encrypted_cvc", "__param:s7e_13_cvc");
  request_dict.SetString("credit_card_id", card.server_id());
  request_dict.SetString("risk_data_base64", response.risk_data);
  request_dict.Set("context", make_scoped_ptr(new base::DictionaryValue()));

  int value = 0;
  if (base::StringToInt(response.exp_month, &value))
    request_dict.SetInteger("expiration_month", value);
  if (base::StringToInt(response.exp_year, &value))
    request_dict.SetInteger("expiration_year", value);

  std::string json_request;
  base::JSONWriter::Write(&request_dict, &json_request);
  std::string post_body =
      base::StringPrintf(kUnmaskCardRequestFormat,
                         net::EscapeUrlEncodedData(json_request, true).c_str(),
                         net::EscapeUrlEncodedData(
                             base::UTF16ToASCII(response.cvc), true).c_str());
  request_->SetUploadData("application/x-www-form-urlencoded", post_body);
  request_->AddExtraRequestHeader(
      net::HttpRequestHeaders::kAcceptEncoding + std::string(": chunked;q=0"));

  if (access_token_.empty())
    StartTokenFetch();
  else
    SetOAuth2TokenAndStartRequest();
}

void RealPanWalletClient::CancelRequest() {
  request_.reset();
}

void RealPanWalletClient::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK_EQ(source, request_.get());

  // |request_|, which is aliased to |source|, might continue to be used in this
  // |method, but should be freed once control leaves the method.
  scoped_ptr<net::URLFetcher> scoped_request(request_.Pass());
  scoped_ptr<base::DictionaryValue> response_dict;
  int response_code = source->GetResponseCode();
  std::string data;
  source->GetResponseAsString(&data);

  // TODO(estade): OAuth2 may fail due to an expired access token, in which case
  // we should invalidate the token and try again. How is that failure reported?

  switch (response_code) {
    // Valid response.
    case net::HTTP_OK: {
      scoped_ptr<base::Value> message_value(base::JSONReader::Read(data));
      if (message_value.get() &&
          message_value->IsType(base::Value::TYPE_DICTIONARY)) {
        response_dict.reset(
            static_cast<base::DictionaryValue*>(message_value.release()));
      }
      break;
    }

    // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying.
    case net::HTTP_BAD_REQUEST: {
      break;
    }

    // Response contains an error to show the user.
    case net::HTTP_FORBIDDEN:
    case net::HTTP_INTERNAL_SERVER_ERROR: {
      break;
    }

    // Handle anything else as a generic error.
    default:
      break;
  }

  std::string real_pan;
  if (response_dict)
    response_dict->GetString("pan", &real_pan);

  if (real_pan.empty()) {
    NOTIMPLEMENTED() << "Unhandled error: " << response_code
                     << " with data: " << data;
  }

  delegate_->OnDidGetRealPan(real_pan);
}

void RealPanWalletClient::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const std::string& access_token,
    const base::Time& expiration_time) {
  DCHECK_EQ(request, access_token_request_.get());
  access_token_ = access_token;
  if (request_)
    SetOAuth2TokenAndStartRequest();

  access_token_request_.reset();
}

void RealPanWalletClient::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  DCHECK_EQ(request, access_token_request_.get());
  if (request_) {
    request_.reset();
    delegate_->OnDidGetRealPan(std::string());
  }
  // TODO(estade): what do we do in the failure case?
  NOTIMPLEMENTED() << "Unhandled OAuth2 error: " << error.ToString();

  access_token_request_.reset();
}

void RealPanWalletClient::StartTokenFetch() {
  // Don't cancel outstanding requests.
  if (access_token_request_)
    return;

  // However, do clear old tokens.
  access_token_.clear();

  OAuth2TokenService::ScopeSet wallet_scopes;
  wallet_scopes.insert(kWalletOAuth2Scope);
  IdentityProvider* identity = delegate_->GetIdentityProvider();
  access_token_request_ = identity->GetTokenService()->StartRequest(
      identity->GetActiveAccountId(), wallet_scopes, this);
}

void RealPanWalletClient::SetOAuth2TokenAndStartRequest() {
  request_->AddExtraRequestHeader(net::HttpRequestHeaders::kAuthorization +
      std::string(": Bearer ") + access_token_);

  request_->Start();
}

}  // namespace wallet
}  // namespace autofill
<commit_msg>Selectively connect to production Wallet servers for Autofill.<commit_after>// Copyright 2015 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 "components/autofill/core/browser/wallet/real_pan_wallet_client.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "google_apis/gaia/identity_provider.h"
#include "net/base/escape.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"

namespace autofill {
namespace wallet {

namespace {

const char kUnmaskCardRequestFormat[] =
    "requestContentType=application/json; charset=utf-8&request=%s"
    "&s7e_13_cvc=%s";

const char kUnmaskCardRequestHost[] = "https://wallet.google.com";
const char kUnmaskCardRequestHostSandbox[] = "https://sandbox.google.com";
const char kUnmaskCardRequestPath[] =
    "payments/apis-secure/creditcardservice/getrealpan?s7e_suffix=chromewallet";

const char kTokenServiceConsumerId[] = "real_pan_wallet_client";
const char kWalletOAuth2Scope[] =
    "https://www.googleapis.com/auth/wallet.chrome";

// This is mostly copied from wallet_service_url.cc, which is currently in
// content/, hence inaccessible from here.
bool IsWalletProductionEnabled() {
  // If the command line flag exists, it takes precedence.
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  std::string sandbox_enabled(
      command_line->GetSwitchValueASCII(switches::kWalletServiceUseSandbox));
  if (!sandbox_enabled.empty())
    return sandbox_enabled != "1";

#if defined(ENABLE_PROD_WALLET_SERVICE)
  return true;
#else
  return false;
#endif
}

GURL GetUnmaskCardRequestUrl() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch("sync-url")) {
    if (IsWalletProductionEnabled()) {
      LOG(ERROR) << "You are using production Wallet but you specified a "
                    "--sync-url. You likely want to disable the sync sandbox "
                    "or switch to sandbox Wallet. Both are controlled in "
                    "about:flags.";
    }
  } else if (!IsWalletProductionEnabled()) {
    LOG(ERROR) << "You are using sandbox Wallet but you didn't specify a "
                  "--sync-url. You likely want to enable the sync sandbox "
                  "or switch to production Wallet. Both are controlled in "
                  "about:flags.";
  }

  GURL base(IsWalletProductionEnabled() ? kUnmaskCardRequestHost
                                        : kUnmaskCardRequestHostSandbox);
  return base.Resolve(kUnmaskCardRequestPath);
}

}  // namespace

RealPanWalletClient::RealPanWalletClient(
    net::URLRequestContextGetter* context_getter,
    Delegate* delegate)
    : OAuth2TokenService::Consumer(kTokenServiceConsumerId),
      context_getter_(context_getter),
      delegate_(delegate),
      weak_ptr_factory_(this) {
  DCHECK(delegate);
}

RealPanWalletClient::~RealPanWalletClient() {
}

void RealPanWalletClient::Prepare() {
  if (access_token_.empty())
    StartTokenFetch();
}

void RealPanWalletClient::UnmaskCard(
    const CreditCard& card,
    const CardUnmaskDelegate::UnmaskResponse& response) {
  DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type());

  request_.reset(net::URLFetcher::Create(
      0, GetUnmaskCardRequestUrl(), net::URLFetcher::POST, this));
  request_->SetRequestContext(context_getter_.get());

  base::DictionaryValue request_dict;
  request_dict.SetString("encrypted_cvc", "__param:s7e_13_cvc");
  request_dict.SetString("credit_card_id", card.server_id());
  request_dict.SetString("risk_data_base64", response.risk_data);
  request_dict.Set("context", make_scoped_ptr(new base::DictionaryValue()));

  int value = 0;
  if (base::StringToInt(response.exp_month, &value))
    request_dict.SetInteger("expiration_month", value);
  if (base::StringToInt(response.exp_year, &value))
    request_dict.SetInteger("expiration_year", value);

  std::string json_request;
  base::JSONWriter::Write(&request_dict, &json_request);
  std::string post_body =
      base::StringPrintf(kUnmaskCardRequestFormat,
                         net::EscapeUrlEncodedData(json_request, true).c_str(),
                         net::EscapeUrlEncodedData(
                             base::UTF16ToASCII(response.cvc), true).c_str());
  request_->SetUploadData("application/x-www-form-urlencoded", post_body);
  request_->AddExtraRequestHeader(
      net::HttpRequestHeaders::kAcceptEncoding + std::string(": chunked;q=0"));

  if (access_token_.empty())
    StartTokenFetch();
  else
    SetOAuth2TokenAndStartRequest();
}

void RealPanWalletClient::CancelRequest() {
  request_.reset();
}

void RealPanWalletClient::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK_EQ(source, request_.get());

  // |request_|, which is aliased to |source|, might continue to be used in this
  // |method, but should be freed once control leaves the method.
  scoped_ptr<net::URLFetcher> scoped_request(request_.Pass());
  scoped_ptr<base::DictionaryValue> response_dict;
  int response_code = source->GetResponseCode();
  std::string data;
  source->GetResponseAsString(&data);

  // TODO(estade): OAuth2 may fail due to an expired access token, in which case
  // we should invalidate the token and try again. How is that failure reported?

  switch (response_code) {
    // Valid response.
    case net::HTTP_OK: {
      scoped_ptr<base::Value> message_value(base::JSONReader::Read(data));
      if (message_value.get() &&
          message_value->IsType(base::Value::TYPE_DICTIONARY)) {
        response_dict.reset(
            static_cast<base::DictionaryValue*>(message_value.release()));
      }
      break;
    }

    // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying.
    case net::HTTP_BAD_REQUEST: {
      break;
    }

    // Response contains an error to show the user.
    case net::HTTP_FORBIDDEN:
    case net::HTTP_INTERNAL_SERVER_ERROR: {
      break;
    }

    // Handle anything else as a generic error.
    default:
      break;
  }

  std::string real_pan;
  if (response_dict)
    response_dict->GetString("pan", &real_pan);

  if (real_pan.empty()) {
    NOTIMPLEMENTED() << "Unhandled error: " << response_code
                     << " with data: " << data;
  }

  delegate_->OnDidGetRealPan(real_pan);
}

void RealPanWalletClient::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const std::string& access_token,
    const base::Time& expiration_time) {
  DCHECK_EQ(request, access_token_request_.get());
  access_token_ = access_token;
  if (request_)
    SetOAuth2TokenAndStartRequest();

  access_token_request_.reset();
}

void RealPanWalletClient::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  DCHECK_EQ(request, access_token_request_.get());
  if (request_) {
    request_.reset();
    delegate_->OnDidGetRealPan(std::string());
  }
  // TODO(estade): what do we do in the failure case?
  NOTIMPLEMENTED() << "Unhandled OAuth2 error: " << error.ToString();

  access_token_request_.reset();
}

void RealPanWalletClient::StartTokenFetch() {
  // Don't cancel outstanding requests.
  if (access_token_request_)
    return;

  // However, do clear old tokens.
  access_token_.clear();

  OAuth2TokenService::ScopeSet wallet_scopes;
  wallet_scopes.insert(kWalletOAuth2Scope);
  IdentityProvider* identity = delegate_->GetIdentityProvider();
  access_token_request_ = identity->GetTokenService()->StartRequest(
      identity->GetActiveAccountId(), wallet_scopes, this);
}

void RealPanWalletClient::SetOAuth2TokenAndStartRequest() {
  request_->AddExtraRequestHeader(net::HttpRequestHeaders::kAuthorization +
      std::string(": Bearer ") + access_token_);

  request_->Start();
}

}  // namespace wallet
}  // namespace autofill
<|endoftext|>


<commit_before>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

#ifdef TARGET_OPENGLES
	shader.load("shadersES2/shader");
#else
	if(ofIsGLProgrammableRenderer()){
		shader.load("shadersGL3/shader");
	}else{
		shader.load("shadersGL2/shader");
	}
#endif

	img.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);
	U.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);
	//U.clone(img);
	V.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);

	for (int i = 0;  i < DEPTH; i++) {
		fp[i].allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);

		for (int y = 0; y < fp[i].getHeight(); y++) {
			for (int x = 0; x < fp[i].getWidth(); x++) {
				int j = y * fp[i].getWidth() + x;
				fp[i][j] = 0.0;
			}
		}

	}

    plane.set(IMG_H, IMG_W, IMG_W / 10, IMG_H / 10);
	//plane.mapTexCoordsFromTexture(img.getTextureReference());
	plane.mapTexCoordsFromTexture(U.getTextureReference());
	toggle = 0;
	ofSetFrameRate(30);
}

void ofApp::updateWave() {

	// toggle between U and V indices

	unsigned char * Ipix = img.getPixels();
	unsigned char * Upix = U.getPixels();

	int w = img.getWidth();
	int h = img.getHeight();

	toggle = (toggle + 1) % DEPTH;

	float * vnew  = fp[(toggle + 2) % DEPTH].getData();
	float * vold  = fp[(toggle + 1) % DEPTH].getData();
	float * vvold = fp[(toggle + 0) % DEPTH].getData();

	for (int y = 1; y< h-1; y++) {
		for (int x = 1; x < w - 1; x++) {
			int i = y * w + x;
			//vfp[i] = 1- (float)Ipix[i] / 255.0;
			float v = 0.3*(vold[x - 1 + y*w] + vold[x + 1 + y*w] + vold[x + (y - 1)*w] + vold[x + (y + 1)*w] - 4 * vold[i]);
			v += 2 * vold[i];
			if (Ipix[i] > 0) {
				vnew[i] = (float)Ipix[i] / 255.0;
			}
			else {
				vnew[i] = 0.98*v - vvold[i];
			}
		}
	}

	for (int y = 0; y<h; y++) {
		for (int x = 0; x<w; x++) {
			int i = y * w + x;
			Upix[i] = 128 + (unsigned char)(127 * vnew[i]);

		}
	}

	//for x in range(1, self.NX - 1) :
	//	for y in range(1, self.NY - 1) :
	//		n = 0.1*(self.vals[old][x - 1][y] + self.vals[old][x + 1][y] + \
	//			self.vals[old][x][y - 1] + self.vals[old][x][y + 1] - \
	//			4 * self.vals[old][x][y])
	//		n += 2 * self.vals[old][x][y]

	//		#this is actual t - 2 term
	//		n -= self.vals[self.vold][x][y];

	//# bound to + / -1 *
	//	if n >= self.max:
	//n = self.max
	//	elif n <= 0 :
	//	n = 0.0
	//	self.vals[self.new][x][y] = n * self.damp;

}

//--------------------------------------------------------------
void ofApp::update() {
	float noiseScale = ofMap(mouseX, 0, ofGetWidth(), 0, 0.1);
    float noiseVel = ofGetElapsedTimef();

    unsigned char * pixels = img.getPixels();
    int w = img.getWidth();
    int h = img.getHeight();
    /*
	for(int y=0; y<h; y++) {
        for(int x=0; x<w; x++) {
            int i = y * w + x;
            float noiseVelue = ofNoise(x * noiseScale, y * noiseScale, noiseVel);
            pixels[i] = 255 * noiseVelue;
        }
    }*/
	for (int y = 0; y<h; y++) {
		for (int x = 0; x<w; x++) {
			int i = y * w + x;
			float d = sqrt((x - mouseX/10)*(x-mouseX/10) + (y-mouseY/10)*(y-mouseY/10));
			if ((d < 10) && ofGetMousePressed()) {
				pixels[i] = 255 - 2.5*d*d;
			}
			else {
				pixels[i] = 0;
					}
		}
	}
	updateWave();
	img.update();
	U.update();
}

//--------------------------------------------------------------
void ofApp::draw(){

    // bind our texture. in our shader this will now be tex0 by default
    // so we can just go ahead and access it there.
	//img.getTextureReference().bind();
	U.getTextureReference().bind();

    shader.begin();

    ofPushMatrix();

    // translate plane into center screen.
    float tx = ofGetWidth() / 2;
    float ty = ofGetHeight() / 2;
    ofTranslate(tx, ty);

    // the mouse/touch Y position changes the rotation of the plane.
    float percentY = mouseY / (float)ofGetHeight();
    float rotation = ofMap(percentY, 0, 1, -60, 60, true) + 60;
    ofRotate(rotation, 1, 0, 0);

    plane.drawWireframe();

    ofPopMatrix();

    shader.end();

	ofSetColor(ofColor::white);
	img.draw(0, 0);
	ofSetColor(ofColor::white);
	U.draw(img.getWidth(), 0);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<commit_msg>checkpoint<commit_after>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

#ifdef TARGET_OPENGLES
	shader.load("shadersES2/shader");
#else
	if(ofIsGLProgrammableRenderer()){
		shader.load("shadersGL3/shader");
	}else{
		shader.load("shadersGL2/shader");
	}
#endif

	img.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);
	U.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);
	//U.clone(img);
	V.allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);

	for (int i = 0;  i < DEPTH; i++) {
		fp[i].allocate(IMG_W / 10, IMG_H / 10, OF_IMAGE_GRAYSCALE);

		for (int y = 0; y < fp[i].getHeight(); y++) {
			for (int x = 0; x < fp[i].getWidth(); x++) {
				int j = y * fp[i].getWidth() + x;
				fp[i][j] = 0.0;
			}
		}

	}

    plane.set(IMG_H, IMG_W, IMG_W / 10, IMG_H / 10);
	//plane.mapTexCoordsFromTexture(img.getTextureReference());
	plane.mapTexCoordsFromTexture(U.getTextureReference());
	toggle = 0;
	ofSetFrameRate(30);
}

void ofApp::updateWave() {

	// toggle between U and V indices

	unsigned char * Ipix = img.getPixels();
	unsigned char * Upix = U.getPixels();

	int w = img.getWidth();
	int h = img.getHeight();

	// kind of like tripple-buffering: we need times t+1, t, and t-1
	// so rotate through the stack of three floating point images...
	toggle = (toggle + 1) % DEPTH;

	float * vnew  = fp[(toggle + 2) % DEPTH].getData();
	float * vold  = fp[(toggle + 1) % DEPTH].getData();
	float * vvold = fp[(toggle + 0) % DEPTH].getData();

	for (int y = 1; y< h-1; y++) {
		for (int x = 1; x < w - 1; x++) {
			int i = y * w + x;
			//vfp[i] = 1- (float)Ipix[i] / 255.0;
			// for this pixel, first compute Laplacian
			float v = 0.3*(vold[x - 1 + y*w] + vold[x + 1 + y*w] + vold[x + (y - 1)*w] + vold[x + (y + 1)*w] - 4 * vold[i]);
		   // then add 2*v(t)
			v += 2 * vold[i];
			if (Ipix[i] > 0) {
				// forcing function
				vnew[i] = (float)Ipix[i] / 255.0;
			}
			else {
				//finally subtract v(t-1) with damping function
				vnew[i] = 0.98*(v - vvold[i]);
			}
		}
	}

	for (int y = 0; y<h; y++) {
		for (int x = 0; x<w; x++) {
			int i = y * w + x;
			Upix[i] = 128 + (unsigned char)(127 * vnew[i]);

		}
	}

	//for x in range(1, self.NX - 1) :
	//	for y in range(1, self.NY - 1) :
	//		n = 0.1*(self.vals[old][x - 1][y] + self.vals[old][x + 1][y] + \
	//			self.vals[old][x][y - 1] + self.vals[old][x][y + 1] - \
	//			4 * self.vals[old][x][y])
	//		n += 2 * self.vals[old][x][y]

	//		#this is actual t - 2 term
	//		n -= self.vals[self.vold][x][y];

	//# bound to + / -1 *
	//	if n >= self.max:
	//n = self.max
	//	elif n <= 0 :
	//	n = 0.0
	//	self.vals[self.new][x][y] = n * self.damp;

}

//--------------------------------------------------------------
void ofApp::update() {
	float noiseScale = ofMap(mouseX, 0, ofGetWidth(), 0, 0.1);
    float noiseVel = ofGetElapsedTimef();

    unsigned char * pixels = img.getPixels();
    int w = img.getWidth();
    int h = img.getHeight();
    /*
	for(int y=0; y<h; y++) {
        for(int x=0; x<w; x++) {
            int i = y * w + x;
            float noiseVelue = ofNoise(x * noiseScale, y * noiseScale, noiseVel);
            pixels[i] = 255 * noiseVelue;
        }
    }*/
	for (int y = 0; y<h; y++) {
		for (int x = 0; x<w; x++) {
			int i = y * w + x;
			float d = sqrt((x - mouseX/10)*(x-mouseX/10) + (y-mouseY/10)*(y-mouseY/10));
			if ((d < 10) && ofGetMousePressed()) {
				pixels[i] = 255 - 2.5*d*d;
			}
			else {
				pixels[i] = 0;
					}
		}
	}
	updateWave();
	img.update();
	U.update();
}

//--------------------------------------------------------------
void ofApp::draw(){

    // bind our texture. in our shader this will now be tex0 by default
    // so we can just go ahead and access it there.
	//img.getTextureReference().bind();
	U.getTextureReference().bind();

    shader.begin();

    ofPushMatrix();

    // translate plane into center screen.
    float tx = ofGetWidth() / 2;
    float ty = ofGetHeight() / 2;
    ofTranslate(tx, ty);

    // the mouse/touch Y position changes the rotation of the plane.
    float percentY = mouseY / (float)ofGetHeight();
    float rotation = ofMap(percentY, 0, 1, -60, 60, true) + 60;
    ofRotate(rotation, 1, 0, 0);

    plane.drawWireframe();

    ofPopMatrix();

    shader.end();

	ofSetColor(ofColor::white);
	img.draw(0, 0);
	ofSetColor(ofColor::white);
	U.draw(img.getWidth(), 0);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}<|endoftext|>


<commit_before>#include <RGBColor.h>

RGBColor RGBColor::black(glm::vec3(0.f, 0.f, 0.f));
RGBColor RGBColor::red(glm::vec3(1.f, 0.f, 0.f));

RGBColor::RGBColor()
    : color(glm::vec3(0.f, 0.f, 0.f))
{
}

RGBColor::RGBColor(const glm::vec3& color)
    : color(color)
{
}

glm::vec3 RGBColor::GetRGBComponents() const
{
    return this->color;
}

uint32_t RGBColor::GetRGBAIntPacked() const
{
    uint32_t col = 0xFF;
    col = col | ((uint32_t)(color.x * 0xFF) << 24);
    col = col | ((uint32_t)(color.y * 0xFF) << 16);
    col = col | ((uint32_t)(color.z * 0xFF) << 8);
    return col;
}<commit_msg>Correct for color order inside PNG<commit_after>#include <RGBColor.h>

RGBColor RGBColor::black(glm::vec3(0.f, 0.f, 0.f));
RGBColor RGBColor::red(glm::vec3(1.f, 0.f, 0.f));

RGBColor::RGBColor()
    : color(glm::vec3(0.f, 0.f, 0.f))
{
}

RGBColor::RGBColor(const glm::vec3& color)
    : color(color)
{
}

glm::vec3 RGBColor::GetRGBComponents() const
{
    return this->color;
}

uint32_t RGBColor::GetRGBAIntPacked() const
{
    uint32_t col = 0;
    col = col | ((uint32_t)(color.x * 0xFF));
    col = col | ((uint32_t)(color.y * 0xFF) << 8);
    col = col | ((uint32_t)(color.z * 0xFF) << 16);
    col = col | (0xFF << 24);
    return col;
}
<|endoftext|>