<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: submission_put.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 00:07:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <memory>

#include "submission_put.hxx"
#include "serialization_app_xml.hxx"
#include "serialization_urlencoded.hxx"

#include <osl/file.hxx>
#include <unotools/processfactory.hxx>
#include <ucbhelper/content.hxx>

using namespace CSS::uno;
using namespace CSS::ucb;
using namespace CSS::task;
using namespace CSS::io;
using namespace rtl;
using namespace osl;
using namespace ucb;
using namespace std;

CSubmissionPut::CSubmissionPut(const rtl::OUString& aURL, const CSS::uno::Reference< CSS::xml::dom::XDocumentFragment >& aFragment)
    : CSubmission(aURL, aFragment)
    , m_aFactory(utl::getProcessServiceFactory())
{
}

CSubmission::SubmissionResult CSubmissionPut::submit(const CSS::uno::Reference< CSS::task::XInteractionHandler >& aInteractionHandler)
{
    // PUT always uses application/xml
    auto_ptr< CSerialization > apSerialization(new CSerializationAppXML());
    apSerialization->setSource(m_aFragment);
    apSerialization->serialize();

    // create a commandEnvironment and use the default interaction handler
    CCommandEnvironmentHelper *pHelper = new CCommandEnvironmentHelper;
    if( aInteractionHandler.is() )
        pHelper->m_aInteractionHandler = aInteractionHandler;
    else
        pHelper->m_aInteractionHandler = Reference< XInteractionHandler >(m_aFactory->createInstance(
            OUString::createFromAscii("com.sun.star.task.InteractionHandler")), UNO_QUERY);
    OSL_ENSURE(pHelper->m_aInteractionHandler.is(), "failed to create IntreractionHandler");

    CProgressHandlerHelper *pProgressHelper = new CProgressHandlerHelper;
    pHelper->m_aProgressHandler = Reference< XProgressHandler >(pProgressHelper);

    // UCB has ownership of environment...
    Reference< XCommandEnvironment > aEnvironment(pHelper);

    try {
        ucb::Content aContent(m_aURLObj.GetMainURL(INetURLObject::NO_DECODE), aEnvironment);

        // insert serialized data to content -> PUT
        Reference< XInputStream > aInStream = apSerialization->getInputStream();
        aContent.writeStream(aInStream, sal_True);
        //aContent.closeStream();

        // no content as a result of put...

    } catch (Exception& e)
    {
        // XXX
        OSL_ENSURE(sal_False, "Exception during UCB operatration.");
        return UNKNOWN_ERROR;
    }

    return SUCCESS;
}

<commit_msg>INTEGRATION: CWS sb59 (1.5.114); FILE MERGED 2006/08/29 16:11:02 sb 1.5.114.1: #i67487# Made code warning-free (wntmsci10).<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: submission_put.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 11:15:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <memory>

#include "submission_put.hxx"
#include "serialization_app_xml.hxx"
#include "serialization_urlencoded.hxx"

#include <osl/file.hxx>
#include <unotools/processfactory.hxx>
#include <ucbhelper/content.hxx>

using namespace CSS::uno;
using namespace CSS::ucb;
using namespace CSS::task;
using namespace CSS::io;
using namespace rtl;
using namespace osl;
using namespace ucb;
using namespace std;

CSubmissionPut::CSubmissionPut(const rtl::OUString& aURL, const CSS::uno::Reference< CSS::xml::dom::XDocumentFragment >& aFragment)
    : CSubmission(aURL, aFragment)
    , m_aFactory(utl::getProcessServiceFactory())
{
}

CSubmission::SubmissionResult CSubmissionPut::submit(const CSS::uno::Reference< CSS::task::XInteractionHandler >& aInteractionHandler)
{
    // PUT always uses application/xml
    auto_ptr< CSerialization > apSerialization(new CSerializationAppXML());
    apSerialization->setSource(m_aFragment);
    apSerialization->serialize();

    // create a commandEnvironment and use the default interaction handler
    CCommandEnvironmentHelper *pHelper = new CCommandEnvironmentHelper;
    if( aInteractionHandler.is() )
        pHelper->m_aInteractionHandler = aInteractionHandler;
    else
        pHelper->m_aInteractionHandler = Reference< XInteractionHandler >(m_aFactory->createInstance(
            OUString::createFromAscii("com.sun.star.task.InteractionHandler")), UNO_QUERY);
    OSL_ENSURE(pHelper->m_aInteractionHandler.is(), "failed to create IntreractionHandler");

    CProgressHandlerHelper *pProgressHelper = new CProgressHandlerHelper;
    pHelper->m_aProgressHandler = Reference< XProgressHandler >(pProgressHelper);

    // UCB has ownership of environment...
    Reference< XCommandEnvironment > aEnvironment(pHelper);

    try {
        ucb::Content aContent(m_aURLObj.GetMainURL(INetURLObject::NO_DECODE), aEnvironment);

        // insert serialized data to content -> PUT
        Reference< XInputStream > aInStream = apSerialization->getInputStream();
        aContent.writeStream(aInStream, sal_True);
        //aContent.closeStream();

        // no content as a result of put...

    } catch (Exception&)
    {
        // XXX
        OSL_ENSURE(sal_False, "Exception during UCB operatration.");
        return UNKNOWN_ERROR;
    }

    return SUCCESS;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
    { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH         Prefix PATH to all generated files.\n"
      "  -I PATH         Search for includes in the specified path.\n"
      "  -M              Print make rules for generated files.\n"
      "  --strict-json   Strict JSON: field names must be / will be quoted,\n"
      "                  no trailing commas in tables/vectors.\n"
      "  --defaults-json Output fields whose value is the default when\n"
      "                  writing JSON\n"
      "  --no-prefix     Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums  Use C++11 style scoped and strongly typed enums.\n"
      "                  also implies --no-prefix.\n"
      "  --gen-includes  (deprecated), this is the default behavior.\n"
      "                  If the original behavior is required (no include\n"
    "                  statements) use --no-includes.\n"
      "  --no-includes   Don\'t generate include statements for included\n"
      "                  schemas the generated file depends on (C++).\n"
      "  --gen-mutable   Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile   Generate single output file for C#\n"
      "  --raw-binary    Allow binaries without file_indentifier to be read.\n"
      "                  This may crash flatc given a mismatched schema.\n"
      "  --proto         Input is a .proto, translate to .fbs.\n"
      "  --schema        Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may depend on declarations in earlier files.\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
        any_generator = true;
      } else if(arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (!any_generator)
    Error("no options: specify at least one generator.", true);

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase);

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<commit_msg>Fix #2775: Add option to flatc to skip unknown fields in JSON<commit_after>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
    { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH         Prefix PATH to all generated files.\n"
      "  -I PATH         Search for includes in the specified path.\n"
      "  -M              Print make rules for generated files.\n"
      "  --strict-json   Strict JSON: field names must be / will be quoted,\n"
      "                  no trailing commas in tables/vectors.\n"
      "  --defaults-json Output fields whose value is the default when\n"
      "                  writing JSON\n"
      "  --unknown-json  Allow fields in JSON that are not defined in the\n"
      "                  schema. These fields will be discared when generating\n"
      "                  binaries.\n"
      "  --no-prefix     Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums  Use C++11 style scoped and strongly typed enums.\n"
      "                  also implies --no-prefix.\n"
      "  --gen-includes  (deprecated), this is the default behavior.\n"
      "                  If the original behavior is required (no include\n"
      "                  statements) use --no-includes.\n"
      "  --no-includes   Don\'t generate include statements for included\n"
      "                  schemas the generated file depends on (C++).\n"
      "  --gen-mutable   Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile   Generate single output file for C#\n"
      "  --raw-binary    Allow binaries without file_indentifier to be read.\n"
      "                  This may crash flatc given a mismatched schema.\n"
      "  --proto         Input is a .proto, translate to .fbs.\n"
      "  --schema        Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may depend on declarations in earlier files.\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
        any_generator = true;
      } else if(arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (!any_generator)
    Error("no options: specify at least one generator.", true);

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase);

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<|endoftext|>


<commit_before>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
namespace detail {

template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
                 T value) {
#ifdef FMT_FUZZ
  if (precision > 100000)
    throw std::runtime_error(
        "fuzz mode - avoid large allocation inside snprintf");
#endif
  // Suppress the warning about nonliteral format string.
  int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
  return precision < 0 ? snprintf_ptr(buf, size, format, value)
                       : snprintf_ptr(buf, size, format, precision, value);
}
}  // namespace detail

template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs,
                                detail::buffer<char>&) = detail::format_float;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
#endif

// Explicit instantiations for char.

template FMT_API std::string detail::grouping_impl<char>(locale_ref);
template FMT_API char detail::thousands_sep_impl(locale_ref);
template FMT_API char detail::decimal_point_impl(locale_ref);

template FMT_API void detail::buffer<char>::append(const char*, const char*);

template FMT_API void detail::vformat_to(
    detail::buffer<char>&, string_view,
    basic_format_args<FMT_BUFFER_CONTEXT(char)>, detail::locale_ref);

template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
                                            detail::buffer<char>&);
template FMT_API int detail::snprintf_float(long double, int,
                                            detail::float_specs,
                                            detail::buffer<char>&);
template FMT_API int detail::format_float(double, int, detail::float_specs,
                                          detail::buffer<char>&);
template FMT_API int detail::format_float(long double, int, detail::float_specs,
                                          detail::buffer<char>&);

// Explicit instantiations for wchar_t.

template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref);
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);

template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
                                                      const wchar_t*);
FMT_END_NAMESPACE
<commit_msg>Instantiate to_decimal to make gcc lto happy (#1955)<commit_after>// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
namespace detail {

template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
                 T value) {
#ifdef FMT_FUZZ
  if (precision > 100000)
    throw std::runtime_error(
        "fuzz mode - avoid large allocation inside snprintf");
#endif
  // Suppress the warning about nonliteral format string.
  int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
  return precision < 0 ? snprintf_ptr(buf, size, format, value)
                       : snprintf_ptr(buf, size, format, precision, value);
}

template dragonbox::decimal_fp<float> dragonbox::to_decimal(float x)
    FMT_NOEXCEPT;
template dragonbox::decimal_fp<double> dragonbox::to_decimal(double x)
    FMT_NOEXCEPT;
}  // namespace detail

template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs,
                                detail::buffer<char>&) = detail::format_float;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
#endif

// Explicit instantiations for char.

template FMT_API std::string detail::grouping_impl<char>(locale_ref);
template FMT_API char detail::thousands_sep_impl(locale_ref);
template FMT_API char detail::decimal_point_impl(locale_ref);

template FMT_API void detail::buffer<char>::append(const char*, const char*);

template FMT_API void detail::vformat_to(
    detail::buffer<char>&, string_view,
    basic_format_args<FMT_BUFFER_CONTEXT(char)>, detail::locale_ref);

template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
                                            detail::buffer<char>&);
template FMT_API int detail::snprintf_float(long double, int,
                                            detail::float_specs,
                                            detail::buffer<char>&);
template FMT_API int detail::format_float(double, int, detail::float_specs,
                                          detail::buffer<char>&);
template FMT_API int detail::format_float(long double, int, detail::float_specs,
                                          detail::buffer<char>&);

// Explicit instantiations for wchar_t.

template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref);
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);

template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
                                                      const wchar_t*);
FMT_END_NAMESPACE
<|endoftext|>


<commit_before>/*
 *  funcs.cpp
 *  StatusSpec project
 *
 *  Copyright (c) 2014 thesupremecommander
 *  BSD 2-Clause License
 *  http://opensource.org/licenses/BSD-2-Clause
 *
 */

#include "funcs.h"

void StatusSpecUnloader::ReadyToUnload(SourceHook::Plugin plug) {};

SourceHook::Impl::CSourceHookImpl g_SourceHook;
SourceHook::ISourceHook *g_SHPtr = &g_SourceHook;
int g_PLID = 0;

SH_DECL_MANUALHOOK5_void(C_TFPlayer_CalcView, OFFSET_CALCVIEW, 0, 0, Vector &, QAngle &, float &, float &, float &);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetFOV, OFFSET_GETFOV, 0, 0, float);
SH_DECL_MANUALHOOK3_void(C_TFPlayer_GetGlowEffectColor, OFFSET_GETGLOWEFFECTCOLOR, 0, 0, float *, float *, float *);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetHealth, OFFSET_GETHEALTH, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetMaxHealth, OFFSET_GETMAXHEALTH, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetObserverMode, OFFSET_GETOBSERVERMODE, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetObserverTarget, OFFSET_GETOBSERVERTARGET, 0, 0, C_BaseEntity *);
SH_DECL_HOOK1_void(IBaseClientDLL, FrameStageNotify, SH_NOATTRIB, 0, ClientFrameStage_t);
SH_DECL_HOOK1(IClientMode, DoPostScreenSpaceEffects, SH_NOATTRIB, 0, bool, const CViewSetup *);
SH_DECL_HOOK1(IGameEventManager2, FireEventClientSide, SH_NOATTRIB, 0, bool, IGameEvent *);
SH_DECL_HOOK4(IMaterialSystem, FindMaterial, SH_NOATTRIB, 0, IMaterial *, char const *, const char *, bool, const char *);
SH_DECL_HOOK3_void(IPanel, SendMessage, SH_NOATTRIB, 0, VPANEL, KeyValues *, VPANEL);
SH_DECL_HOOK3_void(IPanel, SetPos, SH_NOATTRIB, 0, VPANEL, int, int);
SH_DECL_HOOK2(IVEngineClient, GetPlayerInfo, SH_NOATTRIB, 0, bool, int, player_info_t *);

inline bool DataCompare(const BYTE* pData, const BYTE* bSig, const char* szMask)
{
	for (; *szMask; ++szMask, ++pData, ++bSig)
	{
		if (*szMask == 'x' && *pData != *bSig)
			return false;
	}

	return (*szMask) == NULL;
}

inline DWORD FindPattern(DWORD dwAddress, DWORD dwSize, BYTE* pbSig, const char* szMask)
{
	for (DWORD i = NULL; i < dwSize; i++)
	{
		if (DataCompare((BYTE*)(dwAddress + i), pbSig, szMask))
			return (DWORD)(dwAddress + i);
	}

	return 0;
}

inline GLPI_t GetGLPIFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)GETLOCALPLAYERINDEX_SIG, GETLOCALPLAYERINDEX_MASK);
	return (GLPI_t)(pointer);
#else
	return nullptr;
#endif
}

inline SMI_t GetSMIFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETMODELINDEX_SIG, SETMODELINDEX_MASK);
	return (SMI_t)(pointer);
#else
	return nullptr;
#endif
}

inline SMP_t GetSMPFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETMODELPOINTER_SIG, SETMODELPOINTER_MASK);
	return (SMP_t)(pointer);
#else
	return nullptr;
#endif
}

inline SPT_t GetSPTFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETPRIMARYTARGET_SIG, SETPRIMARYTARGET_MASK);
	return (SPT_t)(pointer);
#else
	return nullptr;
#endif
}

int Funcs::setModelLastHookRegistered = 0;
std::map<int, std::function<void(C_BaseEntity *, const model_t *&)>> Funcs::setModelHooks;

GLPI_t Funcs::getLocalPlayerIndexOriginal = nullptr;
SMI_t Funcs::setModelIndexOriginal = nullptr;
SMP_t Funcs::setModelPointerOriginal = nullptr;

bool Funcs::AddDetour(void *target, void *detour, void *&original) {
	MH_STATUS addHookResult = MH_CreateHook(target, detour, &original);

	if (addHookResult != MH_OK && addHookResult != MH_ERROR_ALREADY_CREATED) {
		return false;
	}

	MH_STATUS enableHookResult = MH_EnableHook(target);

	return (enableHookResult == MH_OK || enableHookResult == MH_ERROR_ENABLED);
}

bool Funcs::AddDetour_GetLocalPlayerIndex(GLPI_t detour) {
	void *original;

	if (AddDetour(GetGLPIFunc(), detour, original)) {
		getLocalPlayerIndexOriginal = reinterpret_cast<GLPI_t>(original);
		return true;
	}

	return false;
}

bool Funcs::AddDetour_C_BaseEntity_SetModelIndex(SMIH_t detour) {
	void *original;

	if (AddDetour(GetSMIFunc(), detour, original)) {
		setModelIndexOriginal = reinterpret_cast<SMI_t>(original);
		return true;
	}

	return false;
}

bool Funcs::AddDetour_C_BaseEntity_SetModelPointer(SMPH_t detour) {
	void *original;

	if (AddDetour(GetSMPFunc(), detour, original)) {
		setModelPointerOriginal = reinterpret_cast<SMP_t>(original);
		return true;
	}

	return false;
}

int Funcs::AddGlobalHook_C_TFPlayer_GetFOV(C_TFPlayer *instance, fastdelegate::FastDelegate0<float> hook, bool post) {
	return SH_ADD_MANUALHOOK(C_TFPlayer_GetFOV, instance, hook, post);
}

int Funcs::AddHook_C_BaseEntity_SetModel(std::function<void(C_BaseEntity *, const model_t *&)> hook) {
	setModelHooks[++setModelLastHookRegistered] = hook;

	if (setModelHooks.size() > 0) {
		AddDetour_C_BaseEntity_SetModelIndex(Detour_C_BaseEntity_SetModelIndex);
		AddDetour_C_BaseEntity_SetModelPointer(Detour_C_BaseEntity_SetModelPointer);
	}

	return setModelLastHookRegistered;
}

int Funcs::AddHook_IBaseClientDLL_FrameStageNotify(IBaseClientDLL *instance, fastdelegate::FastDelegate1<ClientFrameStage_t> hook, bool post) {
	return SH_ADD_HOOK(IBaseClientDLL, FrameStageNotify, instance, hook, post);
}

int Funcs::AddHook_IClientMode_DoPostScreenSpaceEffects(IClientMode *instance, fastdelegate::FastDelegate1<const CViewSetup *, bool> hook, bool post) {
	return SH_ADD_HOOK(IClientMode, DoPostScreenSpaceEffects, instance, hook, post);
}

int Funcs::AddHook_IGameEventManager2_FireEventClientSide(IGameEventManager2 *instance, fastdelegate::FastDelegate1<IGameEvent *, bool> hook, bool post) {
	return SH_ADD_HOOK(IGameEventManager2, FireEventClientSide, instance, hook, post);
}

int Funcs::AddHook_IMaterialSystem_FindMaterial(IMaterialSystem *instance, fastdelegate::FastDelegate4<char const *, const char *, bool, const char *, IMaterial *> hook, bool post) {
	return SH_ADD_HOOK(IMaterialSystem, FindMaterial, instance, hook, post);
}

int Funcs::AddHook_IPanel_SendMessage(vgui::IPanel *instance, fastdelegate::FastDelegate3<vgui::VPANEL, KeyValues *, vgui::VPANEL> hook, bool post) {
	return SH_ADD_HOOK(IPanel, SendMessage, instance, hook, post);
}

int Funcs::AddHook_IPanel_SetPos(vgui::IPanel *instance, fastdelegate::FastDelegate3<vgui::VPANEL, int, int> hook, bool post) {
	return SH_ADD_HOOK(IPanel, SetPos, instance, hook, post);
}

int Funcs::AddHook_IVEngineClient_GetPlayerInfo(IVEngineClient *instance, fastdelegate::FastDelegate2<int, player_info_t *, bool> hook, bool post) {
	return SH_ADD_HOOK(IVEngineClient, GetPlayerInfo, instance, hook, post);
}

int Funcs::CallFunc_GetLocalPlayerIndex() {
	if (getLocalPlayerIndexOriginal) {
		return getLocalPlayerIndexOriginal();
	}
	else {
		return GetGLPIFunc()();
	}
}

void Funcs::CallFunc_C_BaseEntity_SetModelIndex(C_BaseEntity *instance, int index) {
	if (setModelIndexOriginal) {
		setModelIndexOriginal(instance, index);
	}
	else {
		GetSMIFunc()(instance, index);
	}
}

void Funcs::CallFunc_C_BaseEntity_SetModelPointer(C_BaseEntity *instance, const model_t *pModel) {
	if (setModelPointerOriginal) {
		setModelPointerOriginal(instance, pModel);
	}
	else {
		GetSMPFunc()(instance, pModel);
	}
}

void Funcs::CallFunc_C_HLTVCamera_SetPrimaryTarget(C_HLTVCamera *instance, int nEntity) {
	GetSPTFunc()(instance, nEntity);
}

float Funcs::CallFunc_C_TFPlayer_GetFOV(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetFOV)();
}

void Funcs::CallFunc_C_TFPlayer_GetGlowEffectColor(C_TFPlayer *instance, float *r, float *g, float *b) {
	SH_MCALL(instance, C_TFPlayer_GetGlowEffectColor)(r, g, b);
}

int Funcs::CallFunc_C_TFPlayer_GetHealth(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetHealth)();
}

int Funcs::CallFunc_C_TFPlayer_GetMaxHealth(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetMaxHealth)();
}

int Funcs::CallFunc_C_TFPlayer_GetObserverMode(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetObserverMode)();
}

C_BaseEntity *Funcs::CallFunc_C_TFPlayer_GetObserverTarget(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetObserverTarget)();
}

bool Funcs::CallFunc_IVEngineClient_GetPlayerInfo(IVEngineClient *instance, int ent_num, player_info_t *pinfo) {
	return SH_CALL(instance, &IVEngineClient::GetPlayerInfo)(ent_num, pinfo);
}

void Funcs::Detour_C_BaseEntity_SetModelIndex(C_BaseEntity *instance, void *, int index) {
	const model_t *model = Interfaces::pModelInfoClient->GetModel(index);

	for (auto iterator = setModelHooks.begin(); iterator != setModelHooks.end(); ++iterator) {
		iterator->second(instance, model);
	}

	int newIndex = Interfaces::pModelInfoClient->GetModelIndex(Interfaces::pModelInfoClient->GetModelName(model));

	Funcs::CallFunc_C_BaseEntity_SetModelIndex(instance, newIndex);
}

void Funcs::Detour_C_BaseEntity_SetModelPointer(C_BaseEntity *instance, void *, const model_t *pModel) {
	for (auto iterator = setModelHooks.begin(); iterator != setModelHooks.end(); ++iterator) {
		iterator->second(instance, pModel);
	}

	Funcs::CallFunc_C_BaseEntity_SetModelPointer(instance, pModel);
}

bool Funcs::RemoveDetour_GetLocalPlayerIndex() {
	if (RemoveDetour(GetGLPIFunc())) {
		getLocalPlayerIndexOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour_C_BaseEntity_SetModelIndex() {
	if (RemoveDetour(GetSMIFunc())) {
		setModelIndexOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour_C_BaseEntity_SetModelPointer() {
	if (RemoveDetour(GetSMPFunc())) {
		setModelPointerOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour(void *target) {
	MH_STATUS disableHookResult = MH_DisableHook(target);

	if (disableHookResult != MH_OK && disableHookResult != MH_ERROR_DISABLED) {
		return false;
	}

	MH_STATUS removeHookResult = MH_RemoveHook(target);

	return (removeHookResult == MH_OK || removeHookResult == MH_ERROR_NOT_CREATED);
}

bool Funcs::RemoveHook(int hookID) {
	return SH_REMOVE_HOOK_ID(hookID);
}

void Funcs::RemoveHook_C_BaseEntity_SetModel(int hookID) {
	setModelHooks.erase(hookID);

	if (setModelHooks.size() == 0) {
		RemoveDetour_C_BaseEntity_SetModelIndex();
		RemoveDetour_C_BaseEntity_SetModelPointer();
	}
}

bool Funcs::Load() {
	MH_STATUS minHookResult = MH_Initialize();

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_ALREADY_INITIALIZED);
}

bool Funcs::Unload() {
	g_SourceHook.UnloadPlugin(g_PLID, new StatusSpecUnloader());
	MH_STATUS minHookResult = MH_Uninitialize();

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_NOT_INITIALIZED);
}

bool Funcs::Pause() {
	g_SourceHook.PausePlugin(g_PLID);
	MH_STATUS minHookResult = MH_DisableHook(MH_ALL_HOOKS);

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_DISABLED);
}

bool Funcs::Unpause() {
	g_SourceHook.UnpausePlugin(g_PLID);
	MH_STATUS minHookResult = MH_EnableHook(MH_ALL_HOOKS);

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_ENABLED);
}<commit_msg>Fix detours reporting they're created if they already exist.<commit_after>/*
 *  funcs.cpp
 *  StatusSpec project
 *
 *  Copyright (c) 2014 thesupremecommander
 *  BSD 2-Clause License
 *  http://opensource.org/licenses/BSD-2-Clause
 *
 */

#include "funcs.h"

void StatusSpecUnloader::ReadyToUnload(SourceHook::Plugin plug) {};

SourceHook::Impl::CSourceHookImpl g_SourceHook;
SourceHook::ISourceHook *g_SHPtr = &g_SourceHook;
int g_PLID = 0;

SH_DECL_MANUALHOOK5_void(C_TFPlayer_CalcView, OFFSET_CALCVIEW, 0, 0, Vector &, QAngle &, float &, float &, float &);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetFOV, OFFSET_GETFOV, 0, 0, float);
SH_DECL_MANUALHOOK3_void(C_TFPlayer_GetGlowEffectColor, OFFSET_GETGLOWEFFECTCOLOR, 0, 0, float *, float *, float *);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetHealth, OFFSET_GETHEALTH, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetMaxHealth, OFFSET_GETMAXHEALTH, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetObserverMode, OFFSET_GETOBSERVERMODE, 0, 0, int);
SH_DECL_MANUALHOOK0(C_TFPlayer_GetObserverTarget, OFFSET_GETOBSERVERTARGET, 0, 0, C_BaseEntity *);
SH_DECL_HOOK1_void(IBaseClientDLL, FrameStageNotify, SH_NOATTRIB, 0, ClientFrameStage_t);
SH_DECL_HOOK1(IClientMode, DoPostScreenSpaceEffects, SH_NOATTRIB, 0, bool, const CViewSetup *);
SH_DECL_HOOK1(IGameEventManager2, FireEventClientSide, SH_NOATTRIB, 0, bool, IGameEvent *);
SH_DECL_HOOK4(IMaterialSystem, FindMaterial, SH_NOATTRIB, 0, IMaterial *, char const *, const char *, bool, const char *);
SH_DECL_HOOK3_void(IPanel, SendMessage, SH_NOATTRIB, 0, VPANEL, KeyValues *, VPANEL);
SH_DECL_HOOK3_void(IPanel, SetPos, SH_NOATTRIB, 0, VPANEL, int, int);
SH_DECL_HOOK2(IVEngineClient, GetPlayerInfo, SH_NOATTRIB, 0, bool, int, player_info_t *);

inline bool DataCompare(const BYTE* pData, const BYTE* bSig, const char* szMask)
{
	for (; *szMask; ++szMask, ++pData, ++bSig)
	{
		if (*szMask == 'x' && *pData != *bSig)
			return false;
	}

	return (*szMask) == NULL;
}

inline DWORD FindPattern(DWORD dwAddress, DWORD dwSize, BYTE* pbSig, const char* szMask)
{
	for (DWORD i = NULL; i < dwSize; i++)
	{
		if (DataCompare((BYTE*)(dwAddress + i), pbSig, szMask))
			return (DWORD)(dwAddress + i);
	}

	return 0;
}

inline GLPI_t GetGLPIFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)GETLOCALPLAYERINDEX_SIG, GETLOCALPLAYERINDEX_MASK);
	return (GLPI_t)(pointer);
#else
	return nullptr;
#endif
}

inline SMI_t GetSMIFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETMODELINDEX_SIG, SETMODELINDEX_MASK);
	return (SMI_t)(pointer);
#else
	return nullptr;
#endif
}

inline SMP_t GetSMPFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETMODELPOINTER_SIG, SETMODELPOINTER_MASK);
	return (SMP_t)(pointer);
#else
	return nullptr;
#endif
}

inline SPT_t GetSPTFunc() {
#if defined _WIN32
	static DWORD pointer = NULL;
	if (!pointer)
		pointer = FindPattern((DWORD)GetHandleOfModule(_T("client")), CLIENT_MODULE_SIZE, (PBYTE)SETPRIMARYTARGET_SIG, SETPRIMARYTARGET_MASK);
	return (SPT_t)(pointer);
#else
	return nullptr;
#endif
}

int Funcs::setModelLastHookRegistered = 0;
std::map<int, std::function<void(C_BaseEntity *, const model_t *&)>> Funcs::setModelHooks;

GLPI_t Funcs::getLocalPlayerIndexOriginal = nullptr;
SMI_t Funcs::setModelIndexOriginal = nullptr;
SMP_t Funcs::setModelPointerOriginal = nullptr;

bool Funcs::AddDetour(void *target, void *detour, void *&original) {
	MH_STATUS addHookResult = MH_CreateHook(target, detour, &original);

	if (addHookResult != MH_OK) {
		return false;
	}

	MH_STATUS enableHookResult = MH_EnableHook(target);

	return (enableHookResult == MH_OK);
}

bool Funcs::AddDetour_GetLocalPlayerIndex(GLPI_t detour) {
	void *original;

	if (AddDetour(GetGLPIFunc(), detour, original)) {
		getLocalPlayerIndexOriginal = reinterpret_cast<GLPI_t>(original);
		return true;
	}

	return false;
}

bool Funcs::AddDetour_C_BaseEntity_SetModelIndex(SMIH_t detour) {
	void *original;

	if (AddDetour(GetSMIFunc(), detour, original)) {
		setModelIndexOriginal = reinterpret_cast<SMI_t>(original);
		return true;
	}

	return false;
}

bool Funcs::AddDetour_C_BaseEntity_SetModelPointer(SMPH_t detour) {
	void *original;

	if (AddDetour(GetSMPFunc(), detour, original)) {
		setModelPointerOriginal = reinterpret_cast<SMP_t>(original);
		return true;
	}

	return false;
}

int Funcs::AddGlobalHook_C_TFPlayer_GetFOV(C_TFPlayer *instance, fastdelegate::FastDelegate0<float> hook, bool post) {
	return SH_ADD_MANUALHOOK(C_TFPlayer_GetFOV, instance, hook, post);
}

int Funcs::AddHook_C_BaseEntity_SetModel(std::function<void(C_BaseEntity *, const model_t *&)> hook) {
	setModelHooks[++setModelLastHookRegistered] = hook;

	if (setModelHooks.size() > 0) {
		AddDetour_C_BaseEntity_SetModelIndex(Detour_C_BaseEntity_SetModelIndex);
		AddDetour_C_BaseEntity_SetModelPointer(Detour_C_BaseEntity_SetModelPointer);
	}

	return setModelLastHookRegistered;
}

int Funcs::AddHook_IBaseClientDLL_FrameStageNotify(IBaseClientDLL *instance, fastdelegate::FastDelegate1<ClientFrameStage_t> hook, bool post) {
	return SH_ADD_HOOK(IBaseClientDLL, FrameStageNotify, instance, hook, post);
}

int Funcs::AddHook_IClientMode_DoPostScreenSpaceEffects(IClientMode *instance, fastdelegate::FastDelegate1<const CViewSetup *, bool> hook, bool post) {
	return SH_ADD_HOOK(IClientMode, DoPostScreenSpaceEffects, instance, hook, post);
}

int Funcs::AddHook_IGameEventManager2_FireEventClientSide(IGameEventManager2 *instance, fastdelegate::FastDelegate1<IGameEvent *, bool> hook, bool post) {
	return SH_ADD_HOOK(IGameEventManager2, FireEventClientSide, instance, hook, post);
}

int Funcs::AddHook_IMaterialSystem_FindMaterial(IMaterialSystem *instance, fastdelegate::FastDelegate4<char const *, const char *, bool, const char *, IMaterial *> hook, bool post) {
	return SH_ADD_HOOK(IMaterialSystem, FindMaterial, instance, hook, post);
}

int Funcs::AddHook_IPanel_SendMessage(vgui::IPanel *instance, fastdelegate::FastDelegate3<vgui::VPANEL, KeyValues *, vgui::VPANEL> hook, bool post) {
	return SH_ADD_HOOK(IPanel, SendMessage, instance, hook, post);
}

int Funcs::AddHook_IPanel_SetPos(vgui::IPanel *instance, fastdelegate::FastDelegate3<vgui::VPANEL, int, int> hook, bool post) {
	return SH_ADD_HOOK(IPanel, SetPos, instance, hook, post);
}

int Funcs::AddHook_IVEngineClient_GetPlayerInfo(IVEngineClient *instance, fastdelegate::FastDelegate2<int, player_info_t *, bool> hook, bool post) {
	return SH_ADD_HOOK(IVEngineClient, GetPlayerInfo, instance, hook, post);
}

int Funcs::CallFunc_GetLocalPlayerIndex() {
	if (getLocalPlayerIndexOriginal) {
		return getLocalPlayerIndexOriginal();
	}
	else {
		return GetGLPIFunc()();
	}
}

void Funcs::CallFunc_C_BaseEntity_SetModelIndex(C_BaseEntity *instance, int index) {
	if (setModelIndexOriginal) {
		setModelIndexOriginal(instance, index);
	}
	else {
		GetSMIFunc()(instance, index);
	}
}

void Funcs::CallFunc_C_BaseEntity_SetModelPointer(C_BaseEntity *instance, const model_t *pModel) {
	if (setModelPointerOriginal) {
		setModelPointerOriginal(instance, pModel);
	}
	else {
		GetSMPFunc()(instance, pModel);
	}
}

void Funcs::CallFunc_C_HLTVCamera_SetPrimaryTarget(C_HLTVCamera *instance, int nEntity) {
	GetSPTFunc()(instance, nEntity);
}

float Funcs::CallFunc_C_TFPlayer_GetFOV(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetFOV)();
}

void Funcs::CallFunc_C_TFPlayer_GetGlowEffectColor(C_TFPlayer *instance, float *r, float *g, float *b) {
	SH_MCALL(instance, C_TFPlayer_GetGlowEffectColor)(r, g, b);
}

int Funcs::CallFunc_C_TFPlayer_GetHealth(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetHealth)();
}

int Funcs::CallFunc_C_TFPlayer_GetMaxHealth(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetMaxHealth)();
}

int Funcs::CallFunc_C_TFPlayer_GetObserverMode(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetObserverMode)();
}

C_BaseEntity *Funcs::CallFunc_C_TFPlayer_GetObserverTarget(C_TFPlayer *instance) {
	return SH_MCALL(instance, C_TFPlayer_GetObserverTarget)();
}

bool Funcs::CallFunc_IVEngineClient_GetPlayerInfo(IVEngineClient *instance, int ent_num, player_info_t *pinfo) {
	return SH_CALL(instance, &IVEngineClient::GetPlayerInfo)(ent_num, pinfo);
}

void Funcs::Detour_C_BaseEntity_SetModelIndex(C_BaseEntity *instance, void *, int index) {
	const model_t *model = Interfaces::pModelInfoClient->GetModel(index);

	for (auto iterator = setModelHooks.begin(); iterator != setModelHooks.end(); ++iterator) {
		iterator->second(instance, model);
	}

	int newIndex = Interfaces::pModelInfoClient->GetModelIndex(Interfaces::pModelInfoClient->GetModelName(model));

	Funcs::CallFunc_C_BaseEntity_SetModelIndex(instance, newIndex);
}

void Funcs::Detour_C_BaseEntity_SetModelPointer(C_BaseEntity *instance, void *, const model_t *pModel) {
	for (auto iterator = setModelHooks.begin(); iterator != setModelHooks.end(); ++iterator) {
		iterator->second(instance, pModel);
	}

	Funcs::CallFunc_C_BaseEntity_SetModelPointer(instance, pModel);
}

bool Funcs::RemoveDetour_GetLocalPlayerIndex() {
	if (RemoveDetour(GetGLPIFunc())) {
		getLocalPlayerIndexOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour_C_BaseEntity_SetModelIndex() {
	if (RemoveDetour(GetSMIFunc())) {
		setModelIndexOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour_C_BaseEntity_SetModelPointer() {
	if (RemoveDetour(GetSMPFunc())) {
		setModelPointerOriginal = nullptr;
		return true;
	}

	return false;
}

bool Funcs::RemoveDetour(void *target) {
	MH_STATUS disableHookResult = MH_DisableHook(target);

	if (disableHookResult != MH_OK) {
		return false;
	}

	MH_STATUS removeHookResult = MH_RemoveHook(target);

	return (removeHookResult == MH_OK);
}

bool Funcs::RemoveHook(int hookID) {
	return SH_REMOVE_HOOK_ID(hookID);
}

void Funcs::RemoveHook_C_BaseEntity_SetModel(int hookID) {
	setModelHooks.erase(hookID);

	if (setModelHooks.size() == 0) {
		RemoveDetour_C_BaseEntity_SetModelIndex();
		RemoveDetour_C_BaseEntity_SetModelPointer();
	}
}

bool Funcs::Load() {
	MH_STATUS minHookResult = MH_Initialize();

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_ALREADY_INITIALIZED);
}

bool Funcs::Unload() {
	g_SourceHook.UnloadPlugin(g_PLID, new StatusSpecUnloader());
	MH_STATUS minHookResult = MH_Uninitialize();

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_NOT_INITIALIZED);
}

bool Funcs::Pause() {
	g_SourceHook.PausePlugin(g_PLID);
	MH_STATUS minHookResult = MH_DisableHook(MH_ALL_HOOKS);

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_DISABLED);
}

bool Funcs::Unpause() {
	g_SourceHook.UnpausePlugin(g_PLID);
	MH_STATUS minHookResult = MH_EnableHook(MH_ALL_HOOKS);

	return (minHookResult == MH_OK || minHookResult == MH_ERROR_ENABLED);
}<|endoftext|>


<commit_before>#include "Arduino_I2C_ESC.h"
#include <Wire.h>

namespace {
  uint8_t _buffer[9];
}

Arduino_I2C_ESC::Arduino_I2C_ESC(uint8_t address, uint8_t poleCount) {
	_address = address;
  _poleCount = poleCount;
}

// Read the incoming data buffer from an ESC
void Arduino_I2C_ESC::readBuffer(uint8_t address, uint8_t buffer[]) {
  Wire.beginTransmission(address);
  Wire.write(0x02); // Data start register
  Wire.endTransmission();

  Wire.requestFrom(address,uint8_t(9));
  uint8_t i = 0;
  while(Wire.available()) {
    buffer[i] = Wire.read();
    i++;
  }
}

// Send motor speed command to ESC
void Arduino_I2C_ESC::set(int16_t throttle) {
  Wire.beginTransmission(_address);
  Wire.write(0x00);
  Wire.write(throttle>>8);
  Wire.write(throttle);
  Wire.endTransmission();
}

// Send motor speed command to ESC
void Arduino_I2C_ESC::setPWM(int16_t pwm) {
  int16_t throttle = map(pwm,1100,1900,-32767,32767);
  Wire.beginTransmission(_address);
  Wire.write(0x00);
  Wire.write(throttle>>8);
  Wire.write(throttle);
  Wire.endTransmission();
}

void Arduino_I2C_ESC::update() {
  _buffer[8] = 0x00; // Reset last byte so we can check for alive

  readBuffer(_address,_buffer);

  _rpm = (_buffer[0] << 8) | _buffer[1];
  _voltage_raw = (_buffer[2] << 8) | _buffer[3];
  _temp_raw = (_buffer[4] << 8) | _buffer[5];
  _current_raw = (_buffer[6] << 8) | _buffer[7];
  _identifier = _buffer[8];

  _rpm = float(_rpm)/((uint16_t(millis())-_rpmTimer)/1000.0f)*60/float(_poleCount);
  _rpmTimer = millis();
}

bool Arduino_I2C_ESC::isAlive() {
  return (_identifier == 0xab);
}

float Arduino_I2C_ESC::voltage() {
	return float(_voltage_raw)/65536.0f*5.0f*6.45f;
}

float Arduino_I2C_ESC::current() {
  return (float(_current_raw)-32767)/65535.0f*5.0f*14.706f;
}

float Arduino_I2C_ESC::temperature() {
  // This code was taken from an Adafruit
	float resistance = SERIESRESISTOR/(65535/float(_temp_raw)-1);

	float steinhart;
	steinhart = resistance / THERMISTORNOMINAL;  // (R/Ro)
	steinhart = log(steinhart);                  // ln(R/Ro)
	steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
	steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
	steinhart = 1.0 / steinhart;                 // Invert
	steinhart -= 273.15;                         // convert to C

	return steinhart;
}

int16_t Arduino_I2C_ESC::rpm() {
  return _rpm;
}
<commit_msg>Modified setPWM convenience function.<commit_after>#include "Arduino_I2C_ESC.h"
#include <Wire.h>

namespace {
  uint8_t _buffer[9];
}

Arduino_I2C_ESC::Arduino_I2C_ESC(uint8_t address, uint8_t poleCount) {
	_address = address;
  _poleCount = poleCount;
}

// Read the incoming data buffer from an ESC
void Arduino_I2C_ESC::readBuffer(uint8_t address, uint8_t buffer[]) {
  Wire.beginTransmission(address);
  Wire.write(0x02); // Data start register
  Wire.endTransmission();

  Wire.requestFrom(address,uint8_t(9));
  uint8_t i = 0;
  while(Wire.available()) {
    buffer[i] = Wire.read();
    i++;
  }
}

// Send motor speed command to ESC
void Arduino_I2C_ESC::set(int16_t throttle) {
  Wire.beginTransmission(_address);
  Wire.write(0x00);
  Wire.write(throttle>>8);
  Wire.write(throttle);
  Wire.endTransmission();
}

// Send motor speed command to ESC
void Arduino_I2C_ESC::setPWM(int16_t pwm) {
  set(map(pwm,1100,1900,-32767,32767));
}

void Arduino_I2C_ESC::update() {
  _buffer[8] = 0x00; // Reset last byte so we can check for alive

  readBuffer(_address,_buffer);

  _rpm = (_buffer[0] << 8) | _buffer[1];
  _voltage_raw = (_buffer[2] << 8) | _buffer[3];
  _temp_raw = (_buffer[4] << 8) | _buffer[5];
  _current_raw = (_buffer[6] << 8) | _buffer[7];
  _identifier = _buffer[8];

  _rpm = float(_rpm)/((uint16_t(millis())-_rpmTimer)/1000.0f)*60/float(_poleCount);
  _rpmTimer = millis();
}

bool Arduino_I2C_ESC::isAlive() {
  return (_identifier == 0xab);
}

float Arduino_I2C_ESC::voltage() {
	return float(_voltage_raw)/65536.0f*5.0f*6.45f;
}

float Arduino_I2C_ESC::current() {
  return (float(_current_raw)-32767)/65535.0f*5.0f*14.706f;
}

float Arduino_I2C_ESC::temperature() {
  // This code was taken from an Adafruit
	float resistance = SERIESRESISTOR/(65535/float(_temp_raw)-1);

	float steinhart;
	steinhart = resistance / THERMISTORNOMINAL;  // (R/Ro)
	steinhart = log(steinhart);                  // ln(R/Ro)
	steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
	steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
	steinhart = 1.0 / steinhart;                 // Invert
	steinhart -= 273.15;                         // convert to C

	return steinhart;
}

int16_t Arduino_I2C_ESC::rpm() {
  return _rpm;
}
<|endoftext|>


<commit_before>#include "itkMultiThreader.h"
#include "itkAnalyzeImageIO.h"
#include "itkMetaDataObject.h"
#include "itkImage.h"
#include "itkSpatialOrientation.h"
#include "itkOrientImageFilter.h"
#include "itkIOCommon.h"
#include <vnl/vnl_sample.h>

typedef itk::Image<unsigned int,3> ImageType;

ImageType::Pointer CreateRandomImage()
{
  const ImageType::SizeType imageSize = {{4,4,4}};
  const ImageType::IndexType imageIndex = {{0,0,0}};
  ImageType::RegionType region;
  region.SetSize(imageSize);
  region.SetIndex(imageIndex);
  ImageType::Pointer img = ImageType::New();
  img->SetLargestPossibleRegion(region);
  img->SetBufferedRegion(region);
  img->SetRequestedRegion(region);
  img->Allocate();
  itk::ImageRegionIterator<ImageType> ri(img,region);
  while(!ri.IsAtEnd())
    {
    ri.Set( (unsigned int) vnl_sample_uniform(0, 32767) );
    ++ri;
    }
  return img;
}

static void PrintImg(ImageType::Pointer img)
{
  //  std::cerr << img << std::endl;
  // std::cerr << std::endl << "-------------------" << std::endl;
  ImageType::IndexType Index;
  for(Index[2] = 0;Index[2] < 4; Index[2]++)
    {
    for(Index[1] = 0; Index[1] < 4; Index[1]++)
      {
      for(Index[0] = 0; Index[0] < 4; Index[0]++)
        {
        std::cerr << img->GetPixel(Index) << " ";
        }
      std::cerr << std::endl;
      }
    std::cerr << std::endl;
    }
}

int itkOrientImageFilterTest(int,char *[])
{
  itk::MultiThreader::SetGlobalMaximumNumberOfThreads(1);
  ImageType::Pointer randimage = CreateRandomImage();
  std::cerr << "Original" << std::endl;
  PrintImg(randimage);

  // act like we're in RIP.
  itk::EncapsulateMetaData<itk::SpatialOrientation::ValidCoordinateOrientationFlags>
    (randimage->GetMetaDataDictionary(),
     itk::ITK_CoordinateOrientation,
     itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);

  itk::OrientImageFilter<ImageType,ImageType>::Pointer orienter =
    itk::OrientImageFilter<ImageType,ImageType>::New();

  orienter->SetGivenCoordinateOrientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);
  orienter->SetInput(randimage);

  // try permuting axes
  orienter->SetDesiredCoordinateOrientation
    (itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRP);
  orienter->Update();
  ImageType::Pointer IRP  = orienter->GetOutput();
  std::cerr << "IRP" << std::endl;
  PrintImg(IRP);

  ImageType::RegionType::SizeType originalSize =
    randimage->GetLargestPossibleRegion().GetSize();
  ImageType::RegionType::SizeType transformedSize =
    IRP->GetLargestPossibleRegion().GetSize();
  ImageType::IndexType originalIndex, transformedIndex;

  for(originalIndex[2] = transformedIndex[2] = 0;
      originalIndex[2] < originalSize[2]; originalIndex[2]++,transformedIndex[2]++)
    {
    for(originalIndex[1] = transformedIndex[0] = 0;
        originalIndex[1] < originalSize[1]; originalIndex[1]++,transformedIndex[0]++)
      {
      for(originalIndex[0] = transformedIndex[1] = 0;
          originalIndex[0] < originalSize[0]; originalIndex[0]++,transformedIndex[1]++)
        {
        ImageType::PixelType orig = randimage->GetPixel(originalIndex);
        ImageType::PixelType xfrm = IRP->GetPixel(transformedIndex);
        if(orig != xfrm)
          return -1;
        }
      }
    }

  // go to LIP, to check flipping an axis.
  orienter = itk::OrientImageFilter<ImageType,ImageType>::New();
  orienter->SetInput(randimage);
  orienter->SetGivenCoordinateOrientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);
  orienter->SetDesiredCoordinateOrientation
    (itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIP);
  orienter->Update();
  ImageType::Pointer LIP  = orienter->GetOutput();
  std::cerr << "LIP" << std::endl;
  PrintImg(LIP);
  transformedSize = LIP->GetLargestPossibleRegion().GetSize();

  for(originalIndex[2] = transformedIndex[2] = 0;
      originalIndex[2] < originalSize[2]; originalIndex[2]++,transformedIndex[2]++)
    {
    for(originalIndex[1] = transformedIndex[1] = 0;
        originalIndex[1] < originalSize[1]; originalIndex[1]++,transformedIndex[1]++)
      {
      for(originalIndex[0] = 0,
            transformedIndex[0] = transformedSize[0] - 1;
          originalIndex[0] < originalSize[0]; originalIndex[0]++,transformedIndex[0]--)
        {
        ImageType::PixelType orig = randimage->GetPixel(originalIndex);
        ImageType::PixelType xfrm = LIP->GetPixel(transformedIndex);
        if(orig != xfrm)
          return -1;
        }
      }
    }

  return 0;
}
<commit_msg>ERR: Fixed signed/unsigned warnings.<commit_after>#include "itkMultiThreader.h"
#include "itkAnalyzeImageIO.h"
#include "itkMetaDataObject.h"
#include "itkImage.h"
#include "itkSpatialOrientation.h"
#include "itkOrientImageFilter.h"
#include "itkIOCommon.h"
#include <vnl/vnl_sample.h>

typedef itk::Image<unsigned int,3> ImageType;

ImageType::Pointer CreateRandomImage()
{
  const ImageType::SizeType imageSize = {{4,4,4}};
  const ImageType::IndexType imageIndex = {{0,0,0}};
  ImageType::RegionType region;
  region.SetSize(imageSize);
  region.SetIndex(imageIndex);
  ImageType::Pointer img = ImageType::New();
  img->SetLargestPossibleRegion(region);
  img->SetBufferedRegion(region);
  img->SetRequestedRegion(region);
  img->Allocate();
  itk::ImageRegionIterator<ImageType> ri(img,region);
  while(!ri.IsAtEnd())
    {
    ri.Set( (unsigned int) vnl_sample_uniform(0, 32767) );
    ++ri;
    }
  return img;
}

static void PrintImg(ImageType::Pointer img)
{
  //  std::cerr << img << std::endl;
  // std::cerr << std::endl << "-------------------" << std::endl;
  ImageType::IndexType Index;
  for(Index[2] = 0;Index[2] < 4; Index[2]++)
    {
    for(Index[1] = 0; Index[1] < 4; Index[1]++)
      {
      for(Index[0] = 0; Index[0] < 4; Index[0]++)
        {
        std::cerr << img->GetPixel(Index) << " ";
        }
      std::cerr << std::endl;
      }
    std::cerr << std::endl;
    }
}

int itkOrientImageFilterTest(int,char *[])
{
  itk::MultiThreader::SetGlobalMaximumNumberOfThreads(1);
  ImageType::Pointer randimage = CreateRandomImage();
  std::cerr << "Original" << std::endl;
  PrintImg(randimage);

  // act like we're in RIP.
  itk::EncapsulateMetaData<itk::SpatialOrientation::ValidCoordinateOrientationFlags>
    (randimage->GetMetaDataDictionary(),
     itk::ITK_CoordinateOrientation,
     itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);

  itk::OrientImageFilter<ImageType,ImageType>::Pointer orienter =
    itk::OrientImageFilter<ImageType,ImageType>::New();

  orienter->SetGivenCoordinateOrientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);
  orienter->SetInput(randimage);

  // try permuting axes
  orienter->SetDesiredCoordinateOrientation
    (itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRP);
  orienter->Update();
  ImageType::Pointer IRP  = orienter->GetOutput();
  std::cerr << "IRP" << std::endl;
  PrintImg(IRP);

  ImageType::RegionType::SizeType originalSize =
    randimage->GetLargestPossibleRegion().GetSize();
  ImageType::RegionType::SizeType transformedSize =
    IRP->GetLargestPossibleRegion().GetSize();
  ImageType::IndexType originalIndex, transformedIndex;

  for(originalIndex[2] = transformedIndex[2] = 0;
      originalIndex[2] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[2]); originalIndex[2]++,transformedIndex[2]++)
    {
    for(originalIndex[1] = transformedIndex[0] = 0;
        originalIndex[1] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[1]); originalIndex[1]++,transformedIndex[0]++)
      {
      for(originalIndex[0] = transformedIndex[1] = 0;
          originalIndex[0] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[0]); originalIndex[0]++,transformedIndex[1]++)
        {
        ImageType::PixelType orig = randimage->GetPixel(originalIndex);
        ImageType::PixelType xfrm = IRP->GetPixel(transformedIndex);
        if(orig != xfrm)
          return -1;
        }
      }
    }

  // go to LIP, to check flipping an axis.
  orienter = itk::OrientImageFilter<ImageType,ImageType>::New();
  orienter->SetInput(randimage);
  orienter->SetGivenCoordinateOrientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP);
  orienter->SetDesiredCoordinateOrientation
    (itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIP);
  orienter->Update();
  ImageType::Pointer LIP  = orienter->GetOutput();
  std::cerr << "LIP" << std::endl;
  PrintImg(LIP);
  transformedSize = LIP->GetLargestPossibleRegion().GetSize();

  for(originalIndex[2] = transformedIndex[2] = 0;
      originalIndex[2] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[2]); originalIndex[2]++,transformedIndex[2]++)
    {
    for(originalIndex[1] = transformedIndex[1] = 0;
        originalIndex[1] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[1]); originalIndex[1]++,transformedIndex[1]++)
      {
      for(originalIndex[0] = 0,
            transformedIndex[0] = transformedSize[0] - 1;
          originalIndex[0] < static_cast<ImageType::IndexType::IndexValueType>(originalSize[0]); originalIndex[0]++,transformedIndex[0]--)
        {
        ImageType::PixelType orig = randimage->GetPixel(originalIndex);
        ImageType::PixelType xfrm = LIP->GetPixel(transformedIndex);
        if(orig != xfrm)
          return -1;
        }
      }
    }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Multi-carrier radio interface
 *
 * Copyright (C) 2016 Ettus Research LLC
 *
 * Author: Tom Tsou <tom.tsou@ettus.com>
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * See the COPYING file in the main directory for details.
 */

#include <radioInterface.h>
#include <Logger.h>

#include "Resampler.h"

extern "C" {
#include "convert.h"
}

/* Resampling parameters for 64 MHz clocking */
#define RESAMP_INRATE			65
#define RESAMP_OUTRATE			(96 / 2)

/* Universal resampling parameters */
#define NUMCHUNKS				24

#define MCHANS					4

RadioInterfaceMulti::RadioInterfaceMulti(RadioDevice *radio, size_t tx_sps,
					 size_t rx_sps, size_t chans)
	: RadioInterface(radio, tx_sps, rx_sps, chans),
	  outerSendBuffer(NULL), outerRecvBuffer(NULL),
	  dnsampler(NULL), upsampler(NULL), channelizer(NULL), synthesis(NULL)
{
}

RadioInterfaceMulti::~RadioInterfaceMulti()
{
	close();
}

void RadioInterfaceMulti::close()
{
	delete outerSendBuffer;
	delete outerRecvBuffer;
	delete dnsampler;
	delete upsampler;
	delete channelizer;
	delete synthesis;

	outerSendBuffer = NULL;
	outerRecvBuffer = NULL;
	dnsampler = NULL;
	upsampler = NULL;
	channelizer = NULL;
	synthesis = NULL;

	mReceiveFIFO.resize(0);
	powerScaling.resize(0);
	history.resize(0);
	active.resize(0);

	RadioInterface::close();
}

static int getLogicalChan(size_t pchan, size_t chans)
{
	switch (chans) {
	case 1:
		if (pchan == 0)
			return 0;
		else
			return -1;
		break;
	case 2:
		if (pchan == 0)
			return 0;
		if (pchan == 3)
			return 1;
		else
			return -1;
		break;
	case 3:
		if (pchan == 1)
			return 0;
		if (pchan == 0)
			return 1;
		if (pchan == 3)
			return 2;
		else
			return -1;
		break;
	default:
		break;
	};

	return -1;
}

static int getFreqShift(size_t chans)
{
	switch (chans) {
	case 1:
		return 0;
	case 2:
		return 0;
	case 3:
		return 1;
	default:
		break;
	};

	return -1;
}

/* Initialize I/O specific objects */
bool RadioInterfaceMulti::init(int type)
{
	float cutoff = 1.0f;
	size_t inchunk = 0, outchunk = 0;

	if (mChans > MCHANS - 1) {
		LOG(ALERT) << "Invalid channel configuration " << mChans;
		return false;
	}

	close();

	sendBuffer.resize(mChans);
	recvBuffer.resize(mChans);
	convertSendBuffer.resize(1);
	convertRecvBuffer.resize(1);

	mReceiveFIFO.resize(mChans);
	powerScaling.resize(mChans);
	history.resize(mChans);
	active.resize(MCHANS, false);

	inchunk = RESAMP_INRATE * 4;
	outchunk = RESAMP_OUTRATE * 4;

	if (inchunk  * NUMCHUNKS < 625 * 2) {
		LOG(ALERT) << "Invalid inner chunk size " << inchunk;
		return false;
	}

	dnsampler = new Resampler(RESAMP_INRATE, RESAMP_OUTRATE);
	if (!dnsampler->init(1.0)) {
		LOG(ALERT) << "Rx resampler failed to initialize";
		return false;
	}

	upsampler = new Resampler(RESAMP_OUTRATE, RESAMP_INRATE);
	if (!upsampler->init(cutoff)) {
		LOG(ALERT) << "Tx resampler failed to initialize";
		return false;
	}

	channelizer = new Channelizer(MCHANS, outchunk);
	if (!channelizer->init()) {
		LOG(ALERT) << "Rx channelizer failed to initialize";
		return false;
	}

	synthesis = new Synthesis(MCHANS, outchunk);
	if (!synthesis->init()) {
		LOG(ALERT) << "Tx synthesis filter failed to initialize";
		return false;
	}

	/*
	 * Allocate high and low rate buffers. The high rate receive
	 * buffer and low rate transmit vectors feed into the resampler
	 * and requires headroom equivalent to the filter length. Low
	 * rate buffers are allocated in the main radio interface code.
	 */
	for (size_t i = 0; i < mChans; i++) {
		sendBuffer[i] = new RadioBuffer(NUMCHUNKS, inchunk,
					        upsampler->len(), true);
		recvBuffer[i] = new RadioBuffer(NUMCHUNKS, inchunk,
		                                0, false);
		history[i] = new signalVector(dnsampler->len());

		synthesis->resetBuffer(i);
	}

	outerSendBuffer = new signalVector(synthesis->outputLen());
	outerRecvBuffer = new signalVector(channelizer->inputLen());

	convertSendBuffer[0] = new short[2 * synthesis->outputLen()];
	convertRecvBuffer[0] = new short[2 * channelizer->inputLen()];

	/* Configure channels */
	switch (mChans) {
	case 1:
		active[0] = true;
		break;
	case 2:
		active[0] = true;
		active[3] = true;
		break;
	case 3:
		active[0] = true;
		active[1] = true;
		active[3] = true;
		break;
	default:
		LOG(ALERT) << "Unsupported channel combination";
		return false;
	}

	return true;
}

/* Receive a timestamped chunk from the device */
int RadioInterfaceMulti::pullBuffer()
{
	bool local_underrun;
	size_t num;
	float *buf;
	unsigned int i;

	if (recvBuffer[0]->getFreeSegments() <= 0)
		return -1;

	/* Outer buffer access size is fixed */
	num = mDevice->readSamples(convertRecvBuffer,
				  outerRecvBuffer->size(),
				  &overrun,
				  readTimestamp,
				  &local_underrun);
	if (num != channelizer->inputLen()) {
		LOG(ALERT) << "Receive error " << num << ", " << channelizer->inputLen();
		return -1;
	}

	convert_short_float((float *) outerRecvBuffer->begin(),
			    convertRecvBuffer[0], 2 * outerRecvBuffer->size());

	underrun |= local_underrun;
	readTimestamp += num;

	channelizer->rotate((float *) outerRecvBuffer->begin(),
			    outerRecvBuffer->size());

	for (size_t pchan = 0; pchan < MCHANS; pchan++) {
		if (!active[pchan])
			continue;

		int lchan = getLogicalChan(pchan, mChans);
		if (lchan < 0) {
			LOG(ALERT) << "Invalid logical channel " << pchan;
			continue;
		}

		/*
		 * Update history by writing into the head portion of the
		 * channelizer output buffer. For this to work, filter length of
		 * the polyphase channelizer partition filter should be equal to
		 * or larger than the resampling filter.
		 */
		buf = channelizer->outputBuffer(pchan);
		size_t cLen = channelizer->outputLen();
		size_t hLen = dnsampler->len();

		float *fdst = &buf[2 * -hLen];
		complex *src = history[lchan]->begin();
		for (i = 0; i < hLen; i++) {
			fdst[0] = src->real();
			fdst[1] = src->imag();
			src++;
			fdst += 2;
		}
		complex *dst = history[lchan]->begin();
		float *fsrc = &buf[2 * (cLen - hLen)];
		for (i = 0; i < hLen; i++) {
			*dst = complex(fdst[0], fdst[1]);
			fsrc += 2;
			dst++;
		}

		float *wr_segment = recvBuffer[lchan]->getWriteSegment();

		/* Write to the end of the inner receive buffer */
		if (!dnsampler->rotate(channelizer->outputBuffer(pchan),
				       channelizer->outputLen(),
				       wr_segment,
				       recvBuffer[lchan]->getSegmentLen())) {
			LOG(ALERT) << "Sample rate upsampling error";
		}
	}
	return 0;
}

/* Send a timestamped chunk to the device */
bool RadioInterfaceMulti::pushBuffer()
{
	bool local_underrun;
	if (sendBuffer[0]->getAvailSegments() <= 0)
		return false;

	for (size_t pchan = 0; pchan < MCHANS; pchan++) {
		if (!active[pchan]) {
			synthesis->resetBuffer(pchan);
			continue;
		}

		int lchan = getLogicalChan(pchan, mChans);
		if (lchan < 0) {
			LOG(ALERT) << "Invalid logical channel " << pchan;
			continue;
		}

		if (!upsampler->rotate(sendBuffer[lchan]->getReadSegment(),
				       sendBuffer[lchan]->getSegmentLen(),
				       synthesis->inputBuffer(pchan),
				       synthesis->inputLen())) {
			LOG(ALERT) << "Sample rate downsampling error";
		}
	}

	synthesis->rotate((float *) outerSendBuffer->begin(),
			  outerSendBuffer->size());

	convert_float_short(convertSendBuffer[0],
			    (float *) outerSendBuffer->begin(),
			    1.0 / (float) mChans, 2 * outerSendBuffer->size());

	size_t num = mDevice->writeSamples(convertSendBuffer,
					  outerSendBuffer->size(),
					  &local_underrun,
					  writeTimestamp);
	if (num != outerSendBuffer->size()) {
		LOG(ALERT) << "Transmit error " << num;
	}

	underrun |= local_underrun;
	writeTimestamp += num;

	return true;
}

/* Frequency comparison limit */
#define FREQ_DELTA_LIMIT		10.0

static bool fltcmp(double a, double b)
{
	return fabs(a - b) < FREQ_DELTA_LIMIT ? true : false;
}

bool RadioInterfaceMulti::tuneTx(double freq, size_t chan)
{
  if (chan >= mChans)
    return false;

  double shift = (double) getFreqShift(mChans);

  if (!chan)
    return mDevice->setTxFreq(freq + shift * MCBTS_SPACING);

  double center = mDevice->getTxFreq();
  if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) {
    LOG(NOTICE) << "Channel " << chan << " RF frequency offset is "
                << freq / 1e6 << " MHz";
  }

  return true;
}

bool RadioInterfaceMulti::tuneRx(double freq, size_t chan)
{
  if (chan >= mChans)
    return false;

  double shift = (double) getFreqShift(mChans);

  if (!chan)
    return mDevice->setRxFreq(freq + shift * MCBTS_SPACING);

  double center = mDevice->getRxFreq();
  if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) {
    LOG(NOTICE) << "Channel " << chan << " RF frequency offset is "
                << freq / 1e6 << " MHz";
  }

  return true;
}

double RadioInterfaceMulti::setRxGain(double db, size_t chan)
{
  if (chan == 0)
    return mDevice->setRxGain(db);
  else
    return mDevice->getRxGain();
}

double RadioInterfaceMulti::setTxGain(double dB, size_t chan)
{
	if (chan == 0)
		return mDevice->setTxGain(dB);
	else
		return mDevice->getTxGain();

}
<commit_msg>Transceiver: Fixed copying of history into and from channelizer buffer.<commit_after>/*
 * Multi-carrier radio interface
 *
 * Copyright (C) 2016 Ettus Research LLC
 *
 * Author: Tom Tsou <tom.tsou@ettus.com>
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * See the COPYING file in the main directory for details.
 */

#include <radioInterface.h>
#include <Logger.h>

#include "Resampler.h"

extern "C" {
#include "convert.h"
}

/* Resampling parameters for 64 MHz clocking */
#define RESAMP_INRATE			65
#define RESAMP_OUTRATE			(96 / 2)

/* Universal resampling parameters */
#define NUMCHUNKS				24

#define MCHANS					4

RadioInterfaceMulti::RadioInterfaceMulti(RadioDevice *radio, size_t tx_sps,
					 size_t rx_sps, size_t chans)
	: RadioInterface(radio, tx_sps, rx_sps, chans),
	  outerSendBuffer(NULL), outerRecvBuffer(NULL),
	  dnsampler(NULL), upsampler(NULL), channelizer(NULL), synthesis(NULL)
{
}

RadioInterfaceMulti::~RadioInterfaceMulti()
{
	close();
}

void RadioInterfaceMulti::close()
{
	delete outerSendBuffer;
	delete outerRecvBuffer;
	delete dnsampler;
	delete upsampler;
	delete channelizer;
	delete synthesis;

	outerSendBuffer = NULL;
	outerRecvBuffer = NULL;
	dnsampler = NULL;
	upsampler = NULL;
	channelizer = NULL;
	synthesis = NULL;

	mReceiveFIFO.resize(0);
	powerScaling.resize(0);
	history.resize(0);
	active.resize(0);

	RadioInterface::close();
}

static int getLogicalChan(size_t pchan, size_t chans)
{
	switch (chans) {
	case 1:
		if (pchan == 0)
			return 0;
		else
			return -1;
		break;
	case 2:
		if (pchan == 0)
			return 0;
		if (pchan == 3)
			return 1;
		else
			return -1;
		break;
	case 3:
		if (pchan == 1)
			return 0;
		if (pchan == 0)
			return 1;
		if (pchan == 3)
			return 2;
		else
			return -1;
		break;
	default:
		break;
	};

	return -1;
}

static int getFreqShift(size_t chans)
{
	switch (chans) {
	case 1:
		return 0;
	case 2:
		return 0;
	case 3:
		return 1;
	default:
		break;
	};

	return -1;
}

/* Initialize I/O specific objects */
bool RadioInterfaceMulti::init(int type)
{
	float cutoff = 1.0f;
	size_t inchunk = 0, outchunk = 0;

	if (mChans > MCHANS - 1) {
		LOG(ALERT) << "Invalid channel configuration " << mChans;
		return false;
	}

	close();

	sendBuffer.resize(mChans);
	recvBuffer.resize(mChans);
	convertSendBuffer.resize(1);
	convertRecvBuffer.resize(1);

	mReceiveFIFO.resize(mChans);
	powerScaling.resize(mChans);
	history.resize(mChans);
	active.resize(MCHANS, false);

	inchunk = RESAMP_INRATE * 4;
	outchunk = RESAMP_OUTRATE * 4;

	if (inchunk  * NUMCHUNKS < 625 * 2) {
		LOG(ALERT) << "Invalid inner chunk size " << inchunk;
		return false;
	}

	dnsampler = new Resampler(RESAMP_INRATE, RESAMP_OUTRATE);
	if (!dnsampler->init(1.0)) {
		LOG(ALERT) << "Rx resampler failed to initialize";
		return false;
	}

	upsampler = new Resampler(RESAMP_OUTRATE, RESAMP_INRATE);
	if (!upsampler->init(cutoff)) {
		LOG(ALERT) << "Tx resampler failed to initialize";
		return false;
	}

	channelizer = new Channelizer(MCHANS, outchunk);
	if (!channelizer->init()) {
		LOG(ALERT) << "Rx channelizer failed to initialize";
		return false;
	}

	synthesis = new Synthesis(MCHANS, outchunk);
	if (!synthesis->init()) {
		LOG(ALERT) << "Tx synthesis filter failed to initialize";
		return false;
	}

	/*
	 * Allocate high and low rate buffers. The high rate receive
	 * buffer and low rate transmit vectors feed into the resampler
	 * and requires headroom equivalent to the filter length. Low
	 * rate buffers are allocated in the main radio interface code.
	 */
	for (size_t i = 0; i < mChans; i++) {
		sendBuffer[i] = new RadioBuffer(NUMCHUNKS, inchunk,
					        upsampler->len(), true);
		recvBuffer[i] = new RadioBuffer(NUMCHUNKS, inchunk,
		                                0, false);
		history[i] = new signalVector(dnsampler->len());

		synthesis->resetBuffer(i);
	}

	outerSendBuffer = new signalVector(synthesis->outputLen());
	outerRecvBuffer = new signalVector(channelizer->inputLen());

	convertSendBuffer[0] = new short[2 * synthesis->outputLen()];
	convertRecvBuffer[0] = new short[2 * channelizer->inputLen()];

	/* Configure channels */
	switch (mChans) {
	case 1:
		active[0] = true;
		break;
	case 2:
		active[0] = true;
		active[3] = true;
		break;
	case 3:
		active[0] = true;
		active[1] = true;
		active[3] = true;
		break;
	default:
		LOG(ALERT) << "Unsupported channel combination";
		return false;
	}

	return true;
}

/* Receive a timestamped chunk from the device */
int RadioInterfaceMulti::pullBuffer()
{
	bool local_underrun;
	size_t num;
	float *buf;
	unsigned int i;

	if (recvBuffer[0]->getFreeSegments() <= 0)
		return -1;

	/* Outer buffer access size is fixed */
	num = mDevice->readSamples(convertRecvBuffer,
				  outerRecvBuffer->size(),
				  &overrun,
				  readTimestamp,
				  &local_underrun);
	if (num != channelizer->inputLen()) {
		LOG(ALERT) << "Receive error " << num << ", " << channelizer->inputLen();
		return -1;
	}

	convert_short_float((float *) outerRecvBuffer->begin(),
			    convertRecvBuffer[0], 2 * outerRecvBuffer->size());

	underrun |= local_underrun;
	readTimestamp += num;

	channelizer->rotate((float *) outerRecvBuffer->begin(),
			    outerRecvBuffer->size());

	for (size_t pchan = 0; pchan < MCHANS; pchan++) {
		if (!active[pchan])
			continue;

		int lchan = getLogicalChan(pchan, mChans);
		if (lchan < 0) {
			LOG(ALERT) << "Invalid logical channel " << pchan;
			continue;
		}

		/*
		 * Update history by writing into the head portion of the
		 * channelizer output buffer. For this to work, filter length of
		 * the polyphase channelizer partition filter should be equal to
		 * or larger than the resampling filter.
		 */
		buf = channelizer->outputBuffer(pchan);
		size_t cLen = channelizer->outputLen();
		size_t hLen = dnsampler->len();

		float *fdst = &buf[2 * -hLen];
		complex *src = history[lchan]->begin();
		for (i = 0; i < hLen; i++) {
			fdst[0] = src->real();
			fdst[1] = src->imag();
			src++;
			fdst += 2;
		}
		complex *dst = history[lchan]->begin();
		float *fsrc = &buf[2 * (cLen - hLen)];
		for (i = 0; i < hLen; i++) {
			*dst = complex(fsrc[0], fsrc[1]);
			fsrc += 2;
			dst++;
		}

		float *wr_segment = recvBuffer[lchan]->getWriteSegment();

		/* Write to the end of the inner receive buffer */
		if (!dnsampler->rotate(channelizer->outputBuffer(pchan),
				       channelizer->outputLen(),
				       wr_segment,
				       recvBuffer[lchan]->getSegmentLen())) {
			LOG(ALERT) << "Sample rate upsampling error";
		}
	}
	return 0;
}

/* Send a timestamped chunk to the device */
bool RadioInterfaceMulti::pushBuffer()
{
	bool local_underrun;
	if (sendBuffer[0]->getAvailSegments() <= 0)
		return false;

	for (size_t pchan = 0; pchan < MCHANS; pchan++) {
		if (!active[pchan]) {
			synthesis->resetBuffer(pchan);
			continue;
		}

		int lchan = getLogicalChan(pchan, mChans);
		if (lchan < 0) {
			LOG(ALERT) << "Invalid logical channel " << pchan;
			continue;
		}

		if (!upsampler->rotate(sendBuffer[lchan]->getReadSegment(),
				       sendBuffer[lchan]->getSegmentLen(),
				       synthesis->inputBuffer(pchan),
				       synthesis->inputLen())) {
			LOG(ALERT) << "Sample rate downsampling error";
		}
	}

	synthesis->rotate((float *) outerSendBuffer->begin(),
			  outerSendBuffer->size());

	convert_float_short(convertSendBuffer[0],
			    (float *) outerSendBuffer->begin(),
			    1.0 / (float) mChans, 2 * outerSendBuffer->size());

	size_t num = mDevice->writeSamples(convertSendBuffer,
					  outerSendBuffer->size(),
					  &local_underrun,
					  writeTimestamp);
	if (num != outerSendBuffer->size()) {
		LOG(ALERT) << "Transmit error " << num;
	}

	underrun |= local_underrun;
	writeTimestamp += num;

	return true;
}

/* Frequency comparison limit */
#define FREQ_DELTA_LIMIT		10.0

static bool fltcmp(double a, double b)
{
	return fabs(a - b) < FREQ_DELTA_LIMIT ? true : false;
}

bool RadioInterfaceMulti::tuneTx(double freq, size_t chan)
{
  if (chan >= mChans)
    return false;

  double shift = (double) getFreqShift(mChans);

  if (!chan)
    return mDevice->setTxFreq(freq + shift * MCBTS_SPACING);

  double center = mDevice->getTxFreq();
  if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) {
    LOG(NOTICE) << "Channel " << chan << " RF frequency offset is "
                << freq / 1e6 << " MHz";
  }

  return true;
}

bool RadioInterfaceMulti::tuneRx(double freq, size_t chan)
{
  if (chan >= mChans)
    return false;

  double shift = (double) getFreqShift(mChans);

  if (!chan)
    return mDevice->setRxFreq(freq + shift * MCBTS_SPACING);

  double center = mDevice->getRxFreq();
  if (!fltcmp(freq, center + (double) (chan - shift) * MCBTS_SPACING)) {
    LOG(NOTICE) << "Channel " << chan << " RF frequency offset is "
                << freq / 1e6 << " MHz";
  }

  return true;
}

double RadioInterfaceMulti::setRxGain(double db, size_t chan)
{
  if (chan == 0)
    return mDevice->setRxGain(db);
  else
    return mDevice->getRxGain();
}

double RadioInterfaceMulti::setTxGain(double dB, size_t chan)
{
	if (chan == 0)
		return mDevice->setTxGain(dB);
	else
		return mDevice->getTxGain();

}
<|endoftext|>