<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  unsigned int nrDMs = 0;
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int nrPeriods = 0;
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  bool exclusive = false;
  bool * exclusionMapDM = 0;
  bool * exclusionMapP = 0;
  float percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    exclusive = args.getSwitch("-exclusive");
    if ( exclusive ) {
      nrDMs = args.getSwitchArgument< unsigned int >("-dms");
      nrPeriods = args.getSwitchArgument< unsigned int >("-periods");
    }
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< float >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " [-exclusive] -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    std::cerr << "\t -exclusive -dms ... -periods ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = static_cast< unsigned int >((percentile * snrList.size()) / 100.0);
  unsigned int counter = snrList.size() - 1;

  if ( exclusive ) {
    exclusionMapDM = new bool [nrDMs];
    std::memset(reinterpret_cast< void * >(exclusionMapDM, 0, nrDMs * sizeof(bool)));
    exclusionMapP = new bool [nrPeriods];
    std::memset(reinterpret_cast< void * >(exclusionMapP, 0, nrDMs * sizeof(bool)));
  }
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  if ( exclusive && (exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second]) ) {
    continue;
  } else if ( exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second] ) {
    exclusionMapDM[(*item).second.first] = true;
    exclusionMapP[(*item).second.second] = true;
  }
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  delete [] exclusionMapDM;
  delete [] exclusionMapP;
  outFile.close();

  return 0;
}

<commit_msg>Adding header file.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <utility>
#include <map>
#include <iomanip>
#include <cstring>

#include <ArgumentList.hpp>
#include <utils.hpp>

int main(int argc, char * argv[]) {
  // DMs
  unsigned int nrDMs = 0;
  float firstDM = 0.0f;
  float stepDM = 0.0f;
  // Periods
  unsigned int nrPeriods = 0;
  unsigned int firstPeriod = 0;
  unsigned int stepPeriod = 0;
  // Sampling
  unsigned int nrSamplesPerSecond = 0;
  // I/O
  std::string outFilename;
  std::ifstream searchFile;
  std::ofstream outFile;
  // Data
  bool exclusive = false;
  bool * exclusionMapDM = 0;
  bool * exclusionMapP = 0;
  float percentile = 0;
  std::multimap< float, std::pair< unsigned int, unsigned int > > snrList;

  isa::utils::ArgumentList args(argc, argv);
  try {
    exclusive = args.getSwitch("-exclusive");
    if ( exclusive ) {
      nrDMs = args.getSwitchArgument< unsigned int >("-dms");
      nrPeriods = args.getSwitchArgument< unsigned int >("-periods");
    }
    outFilename = args.getSwitchArgument< std::string >("-output");
    firstDM = args.getSwitchArgument< float >("-dm_first");
    stepDM = args.getSwitchArgument< float >("-dm_step");
    firstPeriod = args.getSwitchArgument< unsigned int >("-period_first");
    stepPeriod = args.getSwitchArgument< unsigned int >("-period_step");
    nrSamplesPerSecond = args.getSwitchArgument< unsigned int >("-samples");
    percentile = args.getSwitchArgument< float >("-percentile");
  } catch ( isa::utils::EmptyCommandLine & err ) {
    std::cerr << args.getName() << " [-exclusive] -output ... -dm_first ... -dm_step ... -period_first ... -period_step ... -samples ... -percentile ... input" << std::endl;
    std::cerr << "\t -exclusive -dms ... -periods ..." << std::endl;
    return 1;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    return 1;
  }

  // Read the SNR data
  try {
    while ( true ) {
      searchFile.open(args.getFirst< std::string >());

      while ( ! searchFile.eof() ) {
        std::string temp;
        unsigned int splitPoint = 0;
        unsigned int DM = 0;
        unsigned int period = 0;
        float snr = 0.0f;

        std::getline(searchFile, temp);
        if ( ! std::isdigit(temp[0]) ) {
          continue;
        }
        splitPoint = temp.find(" ");
        period = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        DM = isa::utils::castToType< std::string, unsigned int >(temp.substr(0, splitPoint));
        temp = temp.substr(splitPoint + 1);
        splitPoint = temp.find(" ");
        snr = isa::utils::castToType< std::string, float >(temp);

        snrList.insert(std::make_pair(snr, std::make_pair(DM, period)));
      }
      searchFile.close();
    }
  } catch ( isa::utils::EmptyCommandLine & err ) {
  }

  // Print the percentile
  unsigned int lowerLimit = static_cast< unsigned int >((percentile * snrList.size()) / 100.0);
  unsigned int counter = snrList.size() - 1;

  if ( exclusive ) {
    exclusionMapDM = new bool [nrDMs];
    std::memset(reinterpret_cast< void * >(exclusionMapDM, 0, nrDMs * sizeof(bool)));
    exclusionMapP = new bool [nrPeriods];
    std::memset(reinterpret_cast< void * >(exclusionMapP, 0, nrDMs * sizeof(bool)));
  }
  outFile.open(outFilename);
  outFile << std::fixed;
  outFile << "# DMIndex DM periodIndex period snr" << std::endl;
  for ( std::multimap< float, std::pair< unsigned int, unsigned int> >::const_reverse_iterator item = snrList.crend(); counter >= lowerLimit; counter-- ) {
  ++item;
  if ( exclusive && (exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second]) ) {
    continue;
  } else if ( exclusionMapDM[(*item).second.first] || exclusionMapP[(*item).second.second] ) {
    exclusionMapDM[(*item).second.first] = true;
    exclusionMapP[(*item).second.second] = true;
  }
  outFile << std::setprecision(2);
  outFile << (*item).second.first << " " << firstDM + ((*item).second.first * stepDM) << " ";
  outFile << std::setprecision(6);
  outFile << (*item).second.second << " " << (firstPeriod + ((*item).second.second * stepPeriod)) / static_cast< float >(nrSamplesPerSecond) << " ";
  outFile << (*item).first << std::endl;
  }
  delete [] exclusionMapDM;
  delete [] exclusionMapP;
  outFile.close();

  return 0;
}

<|endoftext|>


<commit_before><commit_msg>sw: remove SwEventListenerContainer in SwXTextCursor<commit_after><|endoftext|>


<commit_before><commit_msg>whops, index swap<commit_after><|endoftext|>


<commit_before>#pragma once

// `krbn::cf_utility::run_loop_thread` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "dispatcher.hpp"
#include "logger.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <boost/optional.hpp>
#include <mutex>
#include <string>
#include <thread>

namespace krbn {
class cf_utility final {
public:
  template <typename T>
  class deleter final {
  public:
    using pointer = T;
    void operator()(T _Nullable ref) {
      if (ref) {
        CFRelease(ref);
      }
    }
  };

  // ========================================
  // Converts
  // ========================================

  static boost::optional<std::string> to_string(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFStringGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfstring = static_cast<CFStringRef>(value);

    std::string string;
    if (auto p = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8)) {
      string = p;
    } else {
      auto length = CFStringGetLength(cfstring);
      auto max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
      char* buffer = new char[max_size];
      if (CFStringGetCString(cfstring, buffer, max_size, kCFStringEncodingUTF8)) {
        string = buffer;
      }
      delete[] buffer;
    }

    return string;
  }

  static CFStringRef _Nullable create_cfstring(const std::string& string) {
    return CFStringCreateWithCString(kCFAllocatorDefault,
                                     string.c_str(),
                                     kCFStringEncodingUTF8);
  }

  static boost::optional<int64_t> to_int64_t(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFNumberGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfnumber = static_cast<CFNumberRef>(value);

    int64_t result;
    if (CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &result)) {
      return result;
    }

    return boost::none;
  }

  // ========================================
  // CFArray, CFMutableArray
  // ========================================

  static CFArrayRef _Nonnull create_empty_cfarray(void) {
    return CFArrayCreate(nullptr, nullptr, 0, &kCFTypeArrayCallBacks);
  }

  static CFMutableArrayRef _Nonnull create_cfmutablearray(CFIndex capacity = 0) {
    return CFArrayCreateMutable(nullptr, capacity, &kCFTypeArrayCallBacks);
  }

  template <typename T>
  static T _Nullable get_value(CFArrayRef _Nonnull array, CFIndex index) {
    if (array && index < CFArrayGetCount(array)) {
      return static_cast<T>(const_cast<void*>(CFArrayGetValueAtIndex(array, index)));
    }
    return nullptr;
  }

  template <typename T>
  static bool exists(CFArrayRef _Nonnull array, T _Nonnull value) {
    if (array) {
      CFRange range = {0, CFArrayGetCount(array)};
      if (CFArrayContainsValue(array, range, value)) {
        return true;
      }
    }
    return false;
  }

  // ========================================
  // CFDictionary, CFMutableDictionary
  // ========================================

  static CFMutableDictionaryRef _Nonnull create_cfmutabledictionary(CFIndex capacity = 0) {
    return CFDictionaryCreateMutable(nullptr,
                                     capacity,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
  }

  // ========================================
  // CFRunLoop
  // ========================================

  /**
   * Create a thread and then run CFRunLoop on the thread.
   */
  class run_loop_thread final {
  public:
    run_loop_thread(void) : run_loop_(nullptr) {
      running_wait_ = pqrs::dispatcher::make_wait();

      thread_ = std::thread([this] {
        run_loop_ = CFRunLoopGetCurrent();
        CFRetain(run_loop_);

        // Append empty source to prevent immediately quitting of `CFRunLoopRun`.

        auto context = CFRunLoopSourceContext();
        context.perform = perform;
        auto source = CFRunLoopSourceCreate(kCFAllocatorDefault,
                                            0,
                                            &context);

        CFRunLoopAddSource(run_loop_,
                           source,
                           kCFRunLoopCommonModes);

        // Run

        CFRunLoopPerformBlock(run_loop_,
                              kCFRunLoopCommonModes,
                              ^{
                                running_wait_->notify();
                              });

        CFRunLoopRun();

        // Remove source

        CFRunLoopRemoveSource(run_loop_,
                              source,
                              kCFRunLoopCommonModes);

        CFRelease(source);
      });
    }

    ~run_loop_thread(void) {
      if (thread_.joinable()) {
        logger::get_logger().error("Call `cf_utility::run_loop_thread::terminate` before destroy `cf_utility::run_loop_thread`");
        terminate();
      }

      if (run_loop_) {
        CFRelease(run_loop_);
      }
    }

    void terminate(void) {
      enqueue(^{
        CFRunLoopStop(run_loop_);
      });

      if (thread_.joinable()) {
        thread_.join();
      }
    }

    CFRunLoopRef _Nonnull get_run_loop(void) const {
      // We wait until running to avoid a segmentation fault which is described in `enqueue`.

      wait_until_running();

      return run_loop_;
    }

    void wake(void) const {
      // Do not touch run_loop_ until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we touch `run_loop_` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopWakeUp(run_loop_);
    }

    void enqueue_and_wait(const std::function<void(void)>& function) const {
      auto wait = pqrs::dispatcher::make_wait();

      enqueue(^{
        function();

        wait->notify();
      });

      wait->wait_notice();
    }

  private:
    void enqueue(void (^_Nonnull block)(void)) const {
      // Do not call `CFRunLoopPerformBlock` until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we call `CFRunLoopPerformBlock` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopPerformBlock(run_loop_,
                            kCFRunLoopCommonModes,
                            block);

      CFRunLoopWakeUp(run_loop_);
    }

    void wait_until_running(void) const {
      running_wait_->wait_notice();
    }

    static void perform(void* _Nullable info) {
    }

    std::thread thread_;

    CFRunLoopRef _Nullable run_loop_;
    std::shared_ptr<pqrs::dispatcher::wait> running_wait_;
  };
};
} // namespace krbn
<commit_msg>add cf_utility::set_cfmutabledictionary_value<commit_after>#pragma once

// `krbn::cf_utility::run_loop_thread` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "dispatcher.hpp"
#include "logger.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <boost/optional.hpp>
#include <mutex>
#include <string>
#include <thread>

namespace krbn {
class cf_utility final {
public:
  template <typename T>
  class deleter final {
  public:
    using pointer = T;
    void operator()(T _Nullable ref) {
      if (ref) {
        CFRelease(ref);
      }
    }
  };

  // ========================================
  // Converts
  // ========================================

  static boost::optional<std::string> to_string(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFStringGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfstring = static_cast<CFStringRef>(value);

    std::string string;
    if (auto p = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8)) {
      string = p;
    } else {
      auto length = CFStringGetLength(cfstring);
      auto max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
      char* buffer = new char[max_size];
      if (CFStringGetCString(cfstring, buffer, max_size, kCFStringEncodingUTF8)) {
        string = buffer;
      }
      delete[] buffer;
    }

    return string;
  }

  static CFStringRef _Nullable create_cfstring(const std::string& string) {
    return CFStringCreateWithCString(kCFAllocatorDefault,
                                     string.c_str(),
                                     kCFStringEncodingUTF8);
  }

  static boost::optional<int64_t> to_int64_t(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFNumberGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfnumber = static_cast<CFNumberRef>(value);

    int64_t result;
    if (CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &result)) {
      return result;
    }

    return boost::none;
  }

  // ========================================
  // CFArray, CFMutableArray
  // ========================================

  static CFArrayRef _Nonnull create_empty_cfarray(void) {
    return CFArrayCreate(nullptr, nullptr, 0, &kCFTypeArrayCallBacks);
  }

  static CFMutableArrayRef _Nonnull create_cfmutablearray(CFIndex capacity = 0) {
    return CFArrayCreateMutable(nullptr, capacity, &kCFTypeArrayCallBacks);
  }

  template <typename T>
  static T _Nullable get_value(CFArrayRef _Nonnull array, CFIndex index) {
    if (array && index < CFArrayGetCount(array)) {
      return static_cast<T>(const_cast<void*>(CFArrayGetValueAtIndex(array, index)));
    }
    return nullptr;
  }

  template <typename T>
  static bool exists(CFArrayRef _Nonnull array, T _Nonnull value) {
    if (array) {
      CFRange range = {0, CFArrayGetCount(array)};
      if (CFArrayContainsValue(array, range, value)) {
        return true;
      }
    }
    return false;
  }

  // ========================================
  // CFDictionary, CFMutableDictionary
  // ========================================

  static CFMutableDictionaryRef _Nonnull create_cfmutabledictionary(CFIndex capacity = 0) {
    return CFDictionaryCreateMutable(nullptr,
                                     capacity,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
  }

  static void set_cfmutabledictionary_value(CFMutableDictionaryRef _Nonnull dictionary,
                                            CFStringRef _Nonnull key,
                                            int64_t value) {
    if (auto number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)) {
      CFDictionarySetValue(dictionary, key, number);
      CFRelease(number);
    }
  }

  // ========================================
  // CFRunLoop
  // ========================================

  /**
   * Create a thread and then run CFRunLoop on the thread.
   */
  class run_loop_thread final {
  public:
    run_loop_thread(void) : run_loop_(nullptr) {
      running_wait_ = pqrs::dispatcher::make_wait();

      thread_ = std::thread([this] {
        run_loop_ = CFRunLoopGetCurrent();
        CFRetain(run_loop_);

        // Append empty source to prevent immediately quitting of `CFRunLoopRun`.

        auto context = CFRunLoopSourceContext();
        context.perform = perform;
        auto source = CFRunLoopSourceCreate(kCFAllocatorDefault,
                                            0,
                                            &context);

        CFRunLoopAddSource(run_loop_,
                           source,
                           kCFRunLoopCommonModes);

        // Run

        CFRunLoopPerformBlock(run_loop_,
                              kCFRunLoopCommonModes,
                              ^{
                                running_wait_->notify();
                              });

        CFRunLoopRun();

        // Remove source

        CFRunLoopRemoveSource(run_loop_,
                              source,
                              kCFRunLoopCommonModes);

        CFRelease(source);
      });
    }

    ~run_loop_thread(void) {
      if (thread_.joinable()) {
        logger::get_logger().error("Call `cf_utility::run_loop_thread::terminate` before destroy `cf_utility::run_loop_thread`");
        terminate();
      }

      if (run_loop_) {
        CFRelease(run_loop_);
      }
    }

    void terminate(void) {
      enqueue(^{
        CFRunLoopStop(run_loop_);
      });

      if (thread_.joinable()) {
        thread_.join();
      }
    }

    CFRunLoopRef _Nonnull get_run_loop(void) const {
      // We wait until running to avoid a segmentation fault which is described in `enqueue`.

      wait_until_running();

      return run_loop_;
    }

    void wake(void) const {
      // Do not touch run_loop_ until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we touch `run_loop_` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopWakeUp(run_loop_);
    }

    void enqueue_and_wait(const std::function<void(void)>& function) const {
      auto wait = pqrs::dispatcher::make_wait();

      enqueue(^{
        function();

        wait->notify();
      });

      wait->wait_notice();
    }

  private:
    void enqueue(void (^_Nonnull block)(void)) const {
      // Do not call `CFRunLoopPerformBlock` until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we call `CFRunLoopPerformBlock` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopPerformBlock(run_loop_,
                            kCFRunLoopCommonModes,
                            block);

      CFRunLoopWakeUp(run_loop_);
    }

    void wait_until_running(void) const {
      running_wait_->wait_notice();
    }

    static void perform(void* _Nullable info) {
    }

    std::thread thread_;

    CFRunLoopRef _Nullable run_loop_;
    std::shared_ptr<pqrs::dispatcher::wait> running_wait_;
  };
};
} // namespace krbn
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrtasc.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: ihi $ $Date: 2007-07-12 10:44:33 $
 *
 *  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_sw.hxx"

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _OSL_ENDIAN_H_
#include <osl/endian.h>
#endif

#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif

#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _MDIEXP_HXX
#include <mdiexp.hxx>           // ...Percent()
#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
#ifndef _FMTCNTNT_HXX //autogen
#include <fmtcntnt.hxx>
#endif
#ifndef _FRMFMT_HXX //autogen
#include <frmfmt.hxx>
#endif
#ifndef _WRTASC_HXX
#include <wrtasc.hxx>
#endif

#ifndef _STATSTR_HRC
#include <statstr.hrc>          // ResId fuer Statusleiste
#endif

//-----------------------------------------------------------------

SwASCWriter::SwASCWriter( const String& rFltNm )
{
    SwAsciiOptions aNewOpts;

    switch( 5 <= rFltNm.Len() ? rFltNm.GetChar( 4 ) : 0 )
    {
    case 'D':
#if !defined(PM2)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );
                aNewOpts.SetParaFlags( LINEEND_CRLF );
#endif
                if( 5 < rFltNm.Len() )
                    switch( rFltNm.Copy( 5 ).ToInt32() )
                    {
                    case 437: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_437 );  break;
                    case 850: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );  break;
                    case 860: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_860 );  break;
                    case 861: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_861 );  break;
                    case 863: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_863 );  break;
                    case 865: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_865 );  break;
                    }
                break;

    case 'A':
#if !defined(WIN) && !defined(WNT)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
                aNewOpts.SetParaFlags( LINEEND_CRLF );
#endif
                break;

    case 'M':
                aNewOpts.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN );
                aNewOpts.SetParaFlags( LINEEND_CR );
                break;

    case 'X':
#if !defined(UNX)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
                aNewOpts.SetParaFlags( LINEEND_LF );
#endif
                break;

    default:
        if( rFltNm.Copy( 4 ).EqualsAscii( "_DLG" ))
        {
            // use the options
            aNewOpts = GetAsciiOptions();
        }
    }
    SetAsciiOptions( aNewOpts );
}

SwASCWriter::~SwASCWriter() {}

ULONG SwASCWriter::WriteStream()
{
    sal_Char cLineEnd[ 3 ];
    sal_Char* pCEnd = cLineEnd;
    if( bASCII_ParaAsCR )           // falls vorgegeben ist.
        *pCEnd++ = '\015';
    else if( bASCII_ParaAsBlanc )
        *pCEnd++ = ' ';
    else
        switch( GetAsciiOptions().GetParaFlags() )
        {
        case LINEEND_CR:    *pCEnd++ = '\015'; break;
        case LINEEND_LF:    *pCEnd++ = '\012'; break;
        case LINEEND_CRLF:  *pCEnd++ = '\015', *pCEnd++ = '\012'; break;
        }
    *pCEnd = 0;

    sLineEnd.AssignAscii( cLineEnd );

    long nMaxNode = pDoc->GetNodes().Count();

    if( bShowProgress )
        ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );

    SwPaM* pPam = pOrigPam;

    BOOL bWriteSttTag = bUCS2_WithStartChar &&
        (RTL_TEXTENCODING_UCS2 == GetAsciiOptions().GetCharSet() ||
        RTL_TEXTENCODING_UTF8 == GetAsciiOptions().GetCharSet());

    rtl_TextEncoding eOld = Strm().GetStreamCharSet();
    Strm().SetStreamCharSet( GetAsciiOptions().GetCharSet() );

    // gebe alle Bereich des Pams in das ASC-File aus.
    do {
        BOOL bTstFly = TRUE;
        while( pCurPam->GetPoint()->nNode.GetIndex() < pCurPam->GetMark()->nNode.GetIndex() ||
              (pCurPam->GetPoint()->nNode.GetIndex() == pCurPam->GetMark()->nNode.GetIndex() &&
               pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
        {
            SwTxtNode* pNd = pCurPam->GetPoint()->nNode.GetNode().GetTxtNode();
            if( pNd )
            {
                // sollten nur Rahmen vorhanden sein?
                // (Moeglich, wenn Rahmen-Selektion ins Clipboard
                // gestellt wurde)
                if( bTstFly && bWriteAll &&
                    // keine Laenge
                    !pNd->GetTxt().Len() &&
                    // Rahmen vorhanden
                    pDoc->GetSpzFrmFmts()->Count() &&
                    // nur ein Node im Array
                    pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 ==
                    pDoc->GetNodes().GetEndOfContent().GetIndex() &&
                    // und genau der ist selektiert
                    pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 ==
                    pCurPam->GetPoint()->nNode.GetIndex() )
                {
                    // dann den Inhalt vom Rahmen ausgeben.
                    // dieser steht immer an Position 0 !!
                    SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[ 0 ];
                    const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
                    if( pIdx )
                    {
                        delete pCurPam;
                        pCurPam = NewSwPaM( *pDoc, pIdx->GetIndex(),
                                    pIdx->GetNode().EndOfSectionIndex() );
                        pCurPam->Exchange();
                        continue;       // while-Schleife neu aufsetzen !!
                    }
                }
                else
                {
                    if (bWriteSttTag)
                    {
                        switch(GetAsciiOptions().GetCharSet())
                        {
                            case RTL_TEXTENCODING_UTF8:
                                Strm() << BYTE(0xEF) << BYTE(0xBB) <<
                                    BYTE(0xBF);
                                break;
                            case RTL_TEXTENCODING_UCS2:
                                //Strm().StartWritingUnicodeText();
                                Strm().SetEndianSwap(FALSE);
#ifdef OSL_LITENDIAN
                                Strm() << BYTE(0xFF) << BYTE(0xFE);
#else
                                Strm() << BYTE(0xFE) << BYTE(0xFF);
#endif
                                break;

                        }
                        bWriteSttTag = FALSE;
                    }
                    Out( aASCNodeFnTab, *pNd, *this );
                }
                bTstFly = FALSE;        // eimal Testen reicht
            }

            if( !pCurPam->Move( fnMoveForward, fnGoNode ) )
                break;

            if( bShowProgress )
                ::SetProgressState( pCurPam->GetPoint()->nNode.GetIndex(),
                                    pDoc->GetDocShell() );   // Wie weit ?

        }
    } while( CopyNextPam( &pPam ) );        // bis alle Pam bearbeitet

    Strm().SetStreamCharSet( eOld );

    if( bShowProgress )
        ::EndProgress( pDoc->GetDocShell() );

    return 0;
}

void GetASCWriter( const String& rFltNm, const String& rBaseURL, WriterRef& xRet )
{
  xRet = new SwASCWriter( rFltNm );
}

<commit_msg>INTEGRATION: CWS swwarnings (1.10.222); FILE MERGED 2007/08/20 15:43:27 tl 1.10.222.2: RESYNC: (1.10-1.11); FILE MERGED 2007/03/15 15:52:03 tl 1.10.222.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrtasc.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 09:44:25 $
 *
 *  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_sw.hxx"

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _OSL_ENDIAN_H_
#include <osl/endian.h>
#endif

#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif

#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _MDIEXP_HXX
#include <mdiexp.hxx>           // ...Percent()
#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
#ifndef _FMTCNTNT_HXX //autogen
#include <fmtcntnt.hxx>
#endif
#ifndef _FRMFMT_HXX //autogen
#include <frmfmt.hxx>
#endif
#ifndef _WRTASC_HXX
#include <wrtasc.hxx>
#endif

#ifndef _STATSTR_HRC
#include <statstr.hrc>          // ResId fuer Statusleiste
#endif

//-----------------------------------------------------------------

SwASCWriter::SwASCWriter( const String& rFltNm )
{
    SwAsciiOptions aNewOpts;

    switch( 5 <= rFltNm.Len() ? rFltNm.GetChar( 4 ) : 0 )
    {
    case 'D':
#if !defined(PM2)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );
                aNewOpts.SetParaFlags( LINEEND_CRLF );
#endif
                if( 5 < rFltNm.Len() )
                    switch( rFltNm.Copy( 5 ).ToInt32() )
                    {
                    case 437: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_437 );  break;
                    case 850: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_850 );  break;
                    case 860: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_860 );  break;
                    case 861: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_861 );  break;
                    case 863: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_863 );  break;
                    case 865: aNewOpts.SetCharSet( RTL_TEXTENCODING_IBM_865 );  break;
                    }
                break;

    case 'A':
#if !defined(WIN) && !defined(WNT)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
                aNewOpts.SetParaFlags( LINEEND_CRLF );
#endif
                break;

    case 'M':
                aNewOpts.SetCharSet( RTL_TEXTENCODING_APPLE_ROMAN );
                aNewOpts.SetParaFlags( LINEEND_CR );
                break;

    case 'X':
#if !defined(UNX)
                aNewOpts.SetCharSet( RTL_TEXTENCODING_MS_1252 );
                aNewOpts.SetParaFlags( LINEEND_LF );
#endif
                break;

    default:
        if( rFltNm.Copy( 4 ).EqualsAscii( "_DLG" ))
        {
            // use the options
            aNewOpts = GetAsciiOptions();
        }
    }
    SetAsciiOptions( aNewOpts );
}

SwASCWriter::~SwASCWriter() {}

ULONG SwASCWriter::WriteStream()
{
    sal_Char cLineEnd[ 3 ];
    sal_Char* pCEnd = cLineEnd;
    if( bASCII_ParaAsCR )           // falls vorgegeben ist.
        *pCEnd++ = '\015';
    else if( bASCII_ParaAsBlanc )
        *pCEnd++ = ' ';
    else
        switch( GetAsciiOptions().GetParaFlags() )
        {
        case LINEEND_CR:    *pCEnd++ = '\015'; break;
        case LINEEND_LF:    *pCEnd++ = '\012'; break;
        case LINEEND_CRLF:  *pCEnd++ = '\015', *pCEnd++ = '\012'; break;
        }
    *pCEnd = 0;

    sLineEnd.AssignAscii( cLineEnd );

    long nMaxNode = pDoc->GetNodes().Count();

    if( bShowProgress )
        ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );

    SwPaM* pPam = pOrigPam;

    BOOL bWriteSttTag = bUCS2_WithStartChar &&
        (RTL_TEXTENCODING_UCS2 == GetAsciiOptions().GetCharSet() ||
        RTL_TEXTENCODING_UTF8 == GetAsciiOptions().GetCharSet());

    rtl_TextEncoding eOld = Strm().GetStreamCharSet();
    Strm().SetStreamCharSet( GetAsciiOptions().GetCharSet() );

    // gebe alle Bereich des Pams in das ASC-File aus.
    do {
        BOOL bTstFly = TRUE;
        while( pCurPam->GetPoint()->nNode.GetIndex() < pCurPam->GetMark()->nNode.GetIndex() ||
              (pCurPam->GetPoint()->nNode.GetIndex() == pCurPam->GetMark()->nNode.GetIndex() &&
               pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
        {
            SwTxtNode* pNd = pCurPam->GetPoint()->nNode.GetNode().GetTxtNode();
            if( pNd )
            {
                // sollten nur Rahmen vorhanden sein?
                // (Moeglich, wenn Rahmen-Selektion ins Clipboard
                // gestellt wurde)
                if( bTstFly && bWriteAll &&
                    // keine Laenge
                    !pNd->GetTxt().Len() &&
                    // Rahmen vorhanden
                    pDoc->GetSpzFrmFmts()->Count() &&
                    // nur ein Node im Array
                    pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 ==
                    pDoc->GetNodes().GetEndOfContent().GetIndex() &&
                    // und genau der ist selektiert
                    pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 ==
                    pCurPam->GetPoint()->nNode.GetIndex() )
                {
                    // dann den Inhalt vom Rahmen ausgeben.
                    // dieser steht immer an Position 0 !!
                    SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[ 0 ];
                    const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
                    if( pIdx )
                    {
                        delete pCurPam;
                        pCurPam = NewSwPaM( *pDoc, pIdx->GetIndex(),
                                    pIdx->GetNode().EndOfSectionIndex() );
                        pCurPam->Exchange();
                        continue;       // while-Schleife neu aufsetzen !!
                    }
                }
                else
                {
                    if (bWriteSttTag)
                    {
                        switch(GetAsciiOptions().GetCharSet())
                        {
                            case RTL_TEXTENCODING_UTF8:
                                Strm() << BYTE(0xEF) << BYTE(0xBB) <<
                                    BYTE(0xBF);
                                break;
                            case RTL_TEXTENCODING_UCS2:
                                //Strm().StartWritingUnicodeText();
                                Strm().SetEndianSwap(FALSE);
#ifdef OSL_LITENDIAN
                                Strm() << BYTE(0xFF) << BYTE(0xFE);
#else
                                Strm() << BYTE(0xFE) << BYTE(0xFF);
#endif
                                break;

                        }
                        bWriteSttTag = FALSE;
                    }
                    Out( aASCNodeFnTab, *pNd, *this );
                }
                bTstFly = FALSE;        // eimal Testen reicht
            }

            if( !pCurPam->Move( fnMoveForward, fnGoNode ) )
                break;

            if( bShowProgress )
                ::SetProgressState( pCurPam->GetPoint()->nNode.GetIndex(),
                                    pDoc->GetDocShell() );   // Wie weit ?

        }
    } while( CopyNextPam( &pPam ) );        // bis alle Pam bearbeitet

    Strm().SetStreamCharSet( eOld );

    if( bShowProgress )
        ::EndProgress( pDoc->GetDocShell() );

    return 0;
}

void GetASCWriter( const String& rFltNm, const String& /*rBaseURL*/, WriterRef& xRet )
{
  xRet = new SwASCWriter( rFltNm );
}

<|endoftext|>


<commit_before>#pragma once

// `krbn::cf_utility::run_loop_thread` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "logger.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <boost/optional.hpp>
#include <mutex>
#include <string>
#include <thread>

namespace krbn {
class cf_utility final {
public:
  template <typename T>
  class deleter final {
  public:
    using pointer = T;
    void operator()(T _Nullable ref) {
      if (ref) {
        CFRelease(ref);
      }
    }
  };

  // ========================================
  // Converts
  // ========================================

  static boost::optional<std::string> to_string(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFStringGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfstring = static_cast<CFStringRef>(value);

    std::string string;
    if (auto p = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8)) {
      string = p;
    } else {
      auto length = CFStringGetLength(cfstring);
      auto max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
      char* buffer = new char[max_size];
      if (CFStringGetCString(cfstring, buffer, max_size, kCFStringEncodingUTF8)) {
        string = buffer;
      }
      delete[] buffer;
    }

    return string;
  }

  static CFStringRef _Nullable create_cfstring(const std::string& string) {
    return CFStringCreateWithCString(kCFAllocatorDefault,
                                     string.c_str(),
                                     kCFStringEncodingUTF8);
  }

  static boost::optional<int64_t> to_int64_t(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFNumberGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfnumber = static_cast<CFNumberRef>(value);

    int64_t result;
    if (CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &result)) {
      return result;
    }

    return boost::none;
  }

  // ========================================
  // CFArray, CFMutableArray
  // ========================================

  static CFArrayRef _Nonnull create_empty_cfarray(void) {
    return CFArrayCreate(nullptr, nullptr, 0, &kCFTypeArrayCallBacks);
  }

  static CFMutableArrayRef _Nonnull create_cfmutablearray(CFIndex capacity = 0) {
    return CFArrayCreateMutable(nullptr, capacity, &kCFTypeArrayCallBacks);
  }

  template <typename T>
  static T _Nullable get_value(CFArrayRef _Nonnull array, CFIndex index) {
    if (array && index < CFArrayGetCount(array)) {
      return static_cast<T>(const_cast<void*>(CFArrayGetValueAtIndex(array, index)));
    }
    return nullptr;
  }

  template <typename T>
  static bool exists(CFArrayRef _Nonnull array, T _Nonnull value) {
    if (array) {
      CFRange range = {0, CFArrayGetCount(array)};
      if (CFArrayContainsValue(array, range, value)) {
        return true;
      }
    }
    return false;
  }

  // ========================================
  // CFDictionary, CFMutableDictionary
  // ========================================

  static CFMutableDictionaryRef _Nonnull create_cfmutabledictionary(CFIndex capacity = 0) {
    return CFDictionaryCreateMutable(nullptr,
                                     capacity,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
  }

  // ========================================
  // CFRunLoop
  // ========================================

  /**
   * Create a thread and then run CFRunLoop on the thread.
   */
  class run_loop_thread final {
  public:
    run_loop_thread(void) : run_loop_(nullptr),
                            running_(false) {
      thread_ = std::thread([this] {
        run_loop_ = CFRunLoopGetCurrent();
        CFRetain(run_loop_);

        // Append empty source to prevent immediately quitting of `CFRunLoopRun`.

        auto context = CFRunLoopSourceContext();
        context.perform = perform;
        auto source = CFRunLoopSourceCreate(kCFAllocatorDefault,
                                            0,
                                            &context);

        CFRunLoopAddSource(run_loop_,
                           source,
                           kCFRunLoopDefaultMode);

        // Run

        CFRunLoopPerformBlock(run_loop_,
                              kCFRunLoopDefaultMode,
                              ^{
                                {
                                  std::lock_guard<std::mutex> lock(running_mutex_);

                                  running_ = true;
                                }
                                running_cv_.notify_one();
                              });

        CFRunLoopRun();

        // Remove source

        CFRunLoopRemoveSource(run_loop_,
                              source,
                              kCFRunLoopDefaultMode);

        CFRelease(source);
      });
    }

    ~run_loop_thread(void) {
      if (thread_.joinable()) {
        logger::get_logger().error("Call `cf_utility::run_loop_thread::terminate` before destroy `cf_utility::run_loop_thread`");
        terminate();
      }

      if (run_loop_) {
        CFRelease(run_loop_);
      }
    }

    void terminate(void) {
      enqueue(^{
        CFRunLoopStop(run_loop_);
      });

      if (thread_.joinable()) {
        thread_.join();
      }
    }

    CFRunLoopRef _Nonnull get_run_loop(void) const {
      // We wait until running to avoid a segmentation fault which is described in `enqueue`.

      wait_until_running();

      return run_loop_;
    }

    void enqueue(void (^_Nonnull block)(void)) const {
      // Do not call `CFRunLoopPerformBlock` until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we call `CFRunLoopPerformBlock` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopPerformBlock(run_loop_,
                            kCFRunLoopDefaultMode,
                            block);

      CFRunLoopWakeUp(run_loop_);
    }

  private:
    void wait_until_running(void) const {
      std::unique_lock<std::mutex> lock(running_mutex_);

      running_cv_.wait(lock, [this] {
        return running_;
      });
    }

    static void perform(void* _Nullable info) {
    }

    std::thread thread_;

    CFRunLoopRef _Nullable run_loop_;

    bool running_;
    mutable std::mutex running_mutex_;
    mutable std::condition_variable running_cv_;
  };
};
} // namespace krbn
<commit_msg>add run_loop_thread::wake<commit_after>#pragma once

// `krbn::cf_utility::run_loop_thread` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "logger.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <boost/optional.hpp>
#include <mutex>
#include <string>
#include <thread>

namespace krbn {
class cf_utility final {
public:
  template <typename T>
  class deleter final {
  public:
    using pointer = T;
    void operator()(T _Nullable ref) {
      if (ref) {
        CFRelease(ref);
      }
    }
  };

  // ========================================
  // Converts
  // ========================================

  static boost::optional<std::string> to_string(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFStringGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfstring = static_cast<CFStringRef>(value);

    std::string string;
    if (auto p = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8)) {
      string = p;
    } else {
      auto length = CFStringGetLength(cfstring);
      auto max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
      char* buffer = new char[max_size];
      if (CFStringGetCString(cfstring, buffer, max_size, kCFStringEncodingUTF8)) {
        string = buffer;
      }
      delete[] buffer;
    }

    return string;
  }

  static CFStringRef _Nullable create_cfstring(const std::string& string) {
    return CFStringCreateWithCString(kCFAllocatorDefault,
                                     string.c_str(),
                                     kCFStringEncodingUTF8);
  }

  static boost::optional<int64_t> to_int64_t(CFTypeRef _Nullable value) {
    if (!value) {
      return boost::none;
    }

    if (CFNumberGetTypeID() != CFGetTypeID(value)) {
      return boost::none;
    }

    auto cfnumber = static_cast<CFNumberRef>(value);

    int64_t result;
    if (CFNumberGetValue(cfnumber, kCFNumberSInt64Type, &result)) {
      return result;
    }

    return boost::none;
  }

  // ========================================
  // CFArray, CFMutableArray
  // ========================================

  static CFArrayRef _Nonnull create_empty_cfarray(void) {
    return CFArrayCreate(nullptr, nullptr, 0, &kCFTypeArrayCallBacks);
  }

  static CFMutableArrayRef _Nonnull create_cfmutablearray(CFIndex capacity = 0) {
    return CFArrayCreateMutable(nullptr, capacity, &kCFTypeArrayCallBacks);
  }

  template <typename T>
  static T _Nullable get_value(CFArrayRef _Nonnull array, CFIndex index) {
    if (array && index < CFArrayGetCount(array)) {
      return static_cast<T>(const_cast<void*>(CFArrayGetValueAtIndex(array, index)));
    }
    return nullptr;
  }

  template <typename T>
  static bool exists(CFArrayRef _Nonnull array, T _Nonnull value) {
    if (array) {
      CFRange range = {0, CFArrayGetCount(array)};
      if (CFArrayContainsValue(array, range, value)) {
        return true;
      }
    }
    return false;
  }

  // ========================================
  // CFDictionary, CFMutableDictionary
  // ========================================

  static CFMutableDictionaryRef _Nonnull create_cfmutabledictionary(CFIndex capacity = 0) {
    return CFDictionaryCreateMutable(nullptr,
                                     capacity,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
  }

  // ========================================
  // CFRunLoop
  // ========================================

  /**
   * Create a thread and then run CFRunLoop on the thread.
   */
  class run_loop_thread final {
  public:
    run_loop_thread(void) : run_loop_(nullptr),
                            running_(false) {
      thread_ = std::thread([this] {
        run_loop_ = CFRunLoopGetCurrent();
        CFRetain(run_loop_);

        // Append empty source to prevent immediately quitting of `CFRunLoopRun`.

        auto context = CFRunLoopSourceContext();
        context.perform = perform;
        auto source = CFRunLoopSourceCreate(kCFAllocatorDefault,
                                            0,
                                            &context);

        CFRunLoopAddSource(run_loop_,
                           source,
                           kCFRunLoopDefaultMode);

        // Run

        CFRunLoopPerformBlock(run_loop_,
                              kCFRunLoopDefaultMode,
                              ^{
                                {
                                  std::lock_guard<std::mutex> lock(running_mutex_);

                                  running_ = true;
                                }
                                running_cv_.notify_one();
                              });

        CFRunLoopRun();

        // Remove source

        CFRunLoopRemoveSource(run_loop_,
                              source,
                              kCFRunLoopDefaultMode);

        CFRelease(source);
      });
    }

    ~run_loop_thread(void) {
      if (thread_.joinable()) {
        logger::get_logger().error("Call `cf_utility::run_loop_thread::terminate` before destroy `cf_utility::run_loop_thread`");
        terminate();
      }

      if (run_loop_) {
        CFRelease(run_loop_);
      }
    }

    void terminate(void) {
      enqueue(^{
        CFRunLoopStop(run_loop_);
      });

      if (thread_.joinable()) {
        thread_.join();
      }
    }

    CFRunLoopRef _Nonnull get_run_loop(void) const {
      // We wait until running to avoid a segmentation fault which is described in `enqueue`.

      wait_until_running();

      return run_loop_;
    }

    void enqueue(void (^_Nonnull block)(void)) const {
      // Do not call `CFRunLoopPerformBlock` until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we call `CFRunLoopPerformBlock` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopPerformBlock(run_loop_,
                            kCFRunLoopDefaultMode,
                            block);

      CFRunLoopWakeUp(run_loop_);
    }

    void wake(void) const {
      // Do not touch run_loop_ until `CFRunLoopRun` is called.
      // A segmentation fault occurs if we touch `run_loop_` while `CFRunLoopRun' is processing.

      wait_until_running();

      CFRunLoopWakeUp(run_loop_);
    }

  private:
    void wait_until_running(void) const {
      std::unique_lock<std::mutex> lock(running_mutex_);

      running_cv_.wait(lock, [this] {
        return running_;
      });
    }

    static void perform(void* _Nullable info) {
    }

    std::thread thread_;

    CFRunLoopRef _Nullable run_loop_;

    bool running_;
    mutable std::mutex running_mutex_;
    mutable std::condition_variable running_cv_;
  };
};
} // namespace krbn
<|endoftext|>


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

#ifndef _SHELLIO_HXX
#include <shellio.hxx>
#endif
#ifndef _WRT_FN_HXX
#include <wrt_fn.hxx>
#endif

extern SwNodeFnTab aASCNodeFnTab;

// der ASC-Writer

class SwASCWriter : public Writer
{
    String sLineEnd;

    virtual ULONG WriteStream();

public:
    SwASCWriter( const String& rFilterName );
    virtual ~SwASCWriter();

    const String& GetLineEnd() const      { return sLineEnd; }
};

#endif  //  _WRTASC_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.1.1.1462); FILE MERGED 2005/09/05 13:41:53 rt 1.1.1.1.1462.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrtasc.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:34:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _WRTASC_HXX
#define _WRTASC_HXX

#ifndef _SHELLIO_HXX
#include <shellio.hxx>
#endif
#ifndef _WRT_FN_HXX
#include <wrt_fn.hxx>
#endif

extern SwNodeFnTab aASCNodeFnTab;

// der ASC-Writer

class SwASCWriter : public Writer
{
    String sLineEnd;

    virtual ULONG WriteStream();

public:
    SwASCWriter( const String& rFilterName );
    virtual ~SwASCWriter();

    const String& GetLineEnd() const      { return sLineEnd; }
};

#endif  //  _WRTASC_HXX
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2013 Communi authors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "usermodel.h"
#include "session.h"
#include <ircmessage.h>
#include <ircsender.h>
#include <irc.h>

UserModel::UserModel(QObject* parent) : QAbstractListModel(parent)
{
    d.session = qobject_cast<Session*>(parent);
}

UserModel::~UserModel()
{
}

Session* UserModel::session() const
{
    return d.session;
}

void UserModel::setSession(Session* session)
{
    d.session = session;
    clearUsers();
}

QString UserModel::channel() const
{
    return d.channel;
}

void UserModel::setChannel(const QString& channel)
{
    d.channel = channel.toLower();
}

QStringList UserModel::users() const
{
    return d.names;
}

bool UserModel::hasUser(const QString& user) const
{
    return d.names.contains(user, Qt::CaseInsensitive);
}

void UserModel::addUser(const QString& user)
{
    addUsers(QStringList() << user);
}

void UserModel::addUsers(const QStringList& users)
{
    QStringList unique;
    QSet<QString> nameSet = d.names.toSet();
    foreach (const QString& user, users) {
        QString name = d.session->unprefixedUser(user);
        if (!nameSet.contains(name))
            unique += user;
    }

    if (!unique.isEmpty()) {
        beginInsertRows(QModelIndex(), rowCount(), rowCount() + unique.count() - 1);
        foreach (const QString& user, unique) {
            QString name = d.session->unprefixedUser(user);
            d.names += name;
            d.prefixes.insert(name, d.session->userPrefix(user));
        }
        endInsertRows();
    }
}

void UserModel::removeUser(const QString& user)
{
    QString name = d.session->unprefixedUser(user);
    int idx = d.names.indexOf(name);
    if (idx != -1) {
        beginRemoveRows(QModelIndex(), idx, idx);
        d.names.removeAt(idx);
        d.prefixes.remove(name);
        endRemoveRows();
    }
}

void UserModel::clearUsers()
{
    if (!d.names.isEmpty()) {
        beginResetModel();
        d.names.clear();
        endResetModel();
    }
}

void UserModel::renameUser(const QString& from, const QString& to)
{
    int idx = d.names.indexOf(from);
    if (idx != -1) {
        d.names[idx] = to;
        d.prefixes[to] = d.prefixes.take(from);
        emit dataChanged(index(idx, 0), index(idx, 0));
    }
}

void UserModel::setUserMode(const QString& user, const QString& mode)
{
    int idx = d.names.indexOf(user);
    if (idx != -1) {
        bool add = true;
        IrcSessionInfo info(d.session);
        QString updated = d.prefixes.value(user);
        for (int i = 0; i < mode.size(); ++i) {
            QChar c = mode.at(i);
            QString p = info.modeToPrefix(c);
            switch (c.unicode()) {
                case '+':
                    add = true;
                    break;
                case '-':
                    add = false;
                    break;
                default:
                    if (add) {
                        if (!updated.contains(p))
                            updated += p;
                    } else {
                        updated.remove(p);
                    }
                    break;
            }
        }
        d.prefixes[user] = updated;
        emit dataChanged(index(idx, 0), index(idx, 0));
    }
}

int UserModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid())
        return 0;

    return d.names.count();
}

QVariant UserModel::data(const QModelIndex& index, int role) const
{
    if (index.row() < 0 || index.row() >= d.names.count())
        return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
        QString name = d.names.at(index.row());
        if (role == Qt::DisplayRole)
            return d.prefixes.value(name).left(1) + name;
        if (role == Qt::UserRole)
            return d.prefixes.value(name);
        return name;
    }

    return QVariant();
}

void UserModel::processMessage(IrcMessage* message)
{
    if (!d.session) {
        qWarning() << "UserModel::processMessage(): session is null!";
        return;
    }

    if (message->type() == IrcMessage::Nick) {
        QString nick = message->sender().name().toLower();
        renameUser(nick, static_cast<IrcNickMessage*>(message)->nick());
    } else if (message->type() == IrcMessage::Join) {
        if (message->flags() & IrcMessage::Own)
            clearUsers();
        else
            addUser(message->sender().name());
    } else if (message->type() == IrcMessage::Part) {
        if (message->flags() & IrcMessage::Own)
            clearUsers();
        else
            removeUser(message->sender().name());
    } else if (message->type() == IrcMessage::Kick) {
        removeUser(static_cast<IrcKickMessage*>(message)->user());
    } else if (message->type() == IrcMessage::Quit) {
        removeUser(message->sender().name());
    } else if (message->type() == IrcMessage::Mode) {
        IrcModeMessage* modeMsg = static_cast<IrcModeMessage*>(message);
        if (modeMsg->sender().name() != modeMsg->target() && !modeMsg->argument().isEmpty())
            setUserMode(modeMsg->argument(), modeMsg->mode());
    } else if (message->type() == IrcMessage::Numeric) {
        if (static_cast<IrcNumericMessage*>(message)->code() == Irc::RPL_NAMREPLY) {
            int count = message->parameters().count();
            if (!d.channel.isNull() && d.channel == message->parameters().value(count - 2).toLower()) {
                QString names = message->parameters().value(count - 1);
                addUsers(names.split(" ", QString::SkipEmptyParts));
            }
        }
    }
}
<commit_msg>Fix #5: UserModel goes sometimes out of sync<commit_after>/*
* Copyright (C) 2008-2013 Communi authors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "usermodel.h"
#include "session.h"
#include <ircmessage.h>
#include <ircsender.h>
#include <irc.h>

UserModel::UserModel(QObject* parent) : QAbstractListModel(parent)
{
    d.session = qobject_cast<Session*>(parent);
}

UserModel::~UserModel()
{
}

Session* UserModel::session() const
{
    return d.session;
}

void UserModel::setSession(Session* session)
{
    d.session = session;
    clearUsers();
}

QString UserModel::channel() const
{
    return d.channel;
}

void UserModel::setChannel(const QString& channel)
{
    d.channel = channel.toLower();
}

QStringList UserModel::users() const
{
    return d.names;
}

bool UserModel::hasUser(const QString& user) const
{
    return d.names.contains(user, Qt::CaseInsensitive);
}

void UserModel::addUser(const QString& user)
{
    addUsers(QStringList() << user);
}

void UserModel::addUsers(const QStringList& users)
{
    QStringList unique;
    QSet<QString> nameSet = d.names.toSet();
    foreach (const QString& user, users) {
        QString name = d.session->unprefixedUser(user);
        if (!nameSet.contains(name))
            unique += user;
    }

    if (!unique.isEmpty()) {
        beginInsertRows(QModelIndex(), rowCount(), rowCount() + unique.count() - 1);
        foreach (const QString& user, unique) {
            QString name = d.session->unprefixedUser(user);
            d.names += name;
            d.prefixes.insert(name, d.session->userPrefix(user));
        }
        endInsertRows();
    }
}

void UserModel::removeUser(const QString& user)
{
    QString name = d.session->unprefixedUser(user);
    int idx = d.names.indexOf(name);
    if (idx != -1) {
        beginRemoveRows(QModelIndex(), idx, idx);
        d.names.removeAt(idx);
        d.prefixes.remove(name);
        endRemoveRows();
    }
}

void UserModel::clearUsers()
{
    if (!d.names.isEmpty()) {
        beginResetModel();
        d.names.clear();
        endResetModel();
    }
}

void UserModel::renameUser(const QString& from, const QString& to)
{
    int idx = d.names.indexOf(from);
    if (idx != -1) {
        d.names[idx] = to;
        d.prefixes[to] = d.prefixes.take(from);
        emit dataChanged(index(idx, 0), index(idx, 0));
    }
}

void UserModel::setUserMode(const QString& user, const QString& mode)
{
    int idx = d.names.indexOf(user);
    if (idx != -1) {
        bool add = true;
        IrcSessionInfo info(d.session);
        QString updated = d.prefixes.value(user);
        for (int i = 0; i < mode.size(); ++i) {
            QChar c = mode.at(i);
            QString p = info.modeToPrefix(c);
            switch (c.unicode()) {
                case '+':
                    add = true;
                    break;
                case '-':
                    add = false;
                    break;
                default:
                    if (add) {
                        if (!updated.contains(p))
                            updated += p;
                    } else {
                        updated.remove(p);
                    }
                    break;
            }
        }
        d.prefixes[user] = updated;
        emit dataChanged(index(idx, 0), index(idx, 0));
    }
}

int UserModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid())
        return 0;

    return d.names.count();
}

QVariant UserModel::data(const QModelIndex& index, int role) const
{
    if (index.row() < 0 || index.row() >= d.names.count())
        return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
        QString name = d.names.at(index.row());
        if (role == Qt::DisplayRole)
            return d.prefixes.value(name).left(1) + name;
        if (role == Qt::UserRole)
            return d.prefixes.value(name);
        return name;
    }

    return QVariant();
}

void UserModel::processMessage(IrcMessage* message)
{
    if (!d.session) {
        qWarning() << "UserModel::processMessage(): session is null!";
        return;
    }

    if (message->type() == IrcMessage::Nick) {
        QString from = message->sender().name();
        QString to = static_cast<IrcNickMessage*>(message)->nick();
        renameUser(from, to);
    } else if (message->type() == IrcMessage::Join) {
        if (message->flags() & IrcMessage::Own)
            clearUsers();
        else
            addUser(message->sender().name());
    } else if (message->type() == IrcMessage::Part) {
        if (message->flags() & IrcMessage::Own)
            clearUsers();
        else
            removeUser(message->sender().name());
    } else if (message->type() == IrcMessage::Kick) {
        removeUser(static_cast<IrcKickMessage*>(message)->user());
    } else if (message->type() == IrcMessage::Quit) {
        removeUser(message->sender().name());
    } else if (message->type() == IrcMessage::Mode) {
        IrcModeMessage* modeMsg = static_cast<IrcModeMessage*>(message);
        if (modeMsg->sender().name() != modeMsg->target() && !modeMsg->argument().isEmpty())
            setUserMode(modeMsg->argument(), modeMsg->mode());
    } else if (message->type() == IrcMessage::Numeric) {
        if (static_cast<IrcNumericMessage*>(message)->code() == Irc::RPL_NAMREPLY) {
            int count = message->parameters().count();
            if (!d.channel.isNull() && d.channel == message->parameters().value(count - 2).toLower()) {
                QString names = message->parameters().value(count - 1);
                addUsers(names.split(" ", QString::SkipEmptyParts));
            }
        }
    }
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 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
    Library General Public License for more details.

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

*/

#include "volumeslider.h"
#include "volumeslider_p.h"
#include "audiooutput.h"
#include "phonondefs_p.h"
#include "phononnamespace_p.h"
#include "factory.h"

namespace Phonon
{

VolumeSlider::VolumeSlider(QWidget *parent)
    : QWidget(parent),
    k_ptr(new VolumeSliderPrivate(this))
{
    K_D(VolumeSlider);
    setToolTip(tr("Volume: %1%").arg(100));
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%").arg(100));

    connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_sliderChanged(int)));
    connect(&d->muteButton, SIGNAL(clicked()), SLOT(_k_buttonClicked()));
}

VolumeSlider::VolumeSlider(AudioOutput *output, QWidget *parent)
    : QWidget(parent),
    k_ptr(new VolumeSliderPrivate(this))
{
    K_D(VolumeSlider);
    setToolTip(tr("Volume: %1%").arg(100));
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%").arg(100));

    connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_sliderChanged(int)));
    connect(&d->muteButton, SIGNAL(clicked()), SLOT(_k_buttonClicked()));

    if (output) {
        d->output = output;
        d->slider.setValue(qRound(100 * output->volume()));
        d->slider.setEnabled(true);
        d->muteButton.setEnabled(true);
        connect(output, SIGNAL(volumeChanged(qreal)), SLOT(_k_volumeChanged(qreal)));
        connect(output, SIGNAL(mutedChanged(bool)), SLOT(_k_mutedChanged(bool)));
    }
}

VolumeSlider::~VolumeSlider()
{
    delete k_ptr;
}

bool VolumeSlider::isMuteVisible() const
{
    return k_ptr->muteButton.isVisible();
}

void VolumeSlider::setMuteVisible(bool visible)
{
    k_ptr->muteButton.setVisible(visible);
}

QSize VolumeSlider::iconSize() const
{
    return k_ptr->muteButton.iconSize();
}

void VolumeSlider::setIconSize(const QSize &iconSize)
{
    pDebug() << Q_FUNC_INFO << iconSize;
    k_ptr->muteButton.setIconSize(iconSize);
}

qreal VolumeSlider::maximumVolume() const
{
    return k_ptr->slider.maximum() * 0.01;
}

void VolumeSlider::setMaximumVolume(qreal volume)
{
    int max = static_cast<int>(volume * 100);
    k_ptr->slider.setMaximum(max);
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%")
            .arg(max));
}

Qt::Orientation VolumeSlider::orientation() const
{
    return k_ptr->slider.orientation();
}

void VolumeSlider::setOrientation(Qt::Orientation o)
{
    K_D(VolumeSlider);
    Qt::Alignment align = (o == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter);
    d->layout.setAlignment(&d->muteButton, align);
    d->layout.setAlignment(&d->slider, align);
    d->layout.setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
    d->slider.setOrientation(o);
}

AudioOutput *VolumeSlider::audioOutput() const
{
    K_D(const VolumeSlider);
    return d->output;
}

void VolumeSlider::setAudioOutput(AudioOutput *output)
{
    K_D(VolumeSlider);
    if (d->output) {
        disconnect(d->output, 0, this, 0);
    }
    d->output = output;
    if (output) {
        d->slider.setValue(qRound(100 * output->volume()));
        d->slider.setEnabled(true);
        d->muteButton.setEnabled(true);

        d->_k_volumeChanged(output->volume());
        d->_k_mutedChanged(output->isMuted());

        connect(output, SIGNAL(volumeChanged(qreal)), SLOT(_k_volumeChanged(qreal)));
        connect(output, SIGNAL(mutedChanged(bool)), SLOT(_k_mutedChanged(bool)));
    } else {
        d->slider.setValue(100);
        d->slider.setEnabled(false);
        d->muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_buttonClicked()
{
    if (output) {
        output->setMuted(!output->isMuted());
    } else {
        slider.setEnabled(false);
        muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_mutedChanged(bool muted)
{
    Q_Q(VolumeSlider);
    if (muted) {
        q->setToolTip(VolumeSlider::tr("Muted"));
        muteButton.setIcon(mutedIcon);
    } else {
        q->setToolTip(VolumeSlider::tr("Volume: %1%").arg(static_cast<int>(output->volume() * 100.0)));
        muteButton.setIcon(volumeIcon);
    }
}

void VolumeSliderPrivate::_k_sliderChanged(int value)
{
    Q_Q(VolumeSlider);

    if (output) {
        if (!output->isMuted()) {
           q->setToolTip(VolumeSlider::tr("Volume: %1%").arg(value));
        }

        ignoreVolumeChange = true;
        output->setVolume((static_cast<qreal>(value)) * 0.01);
        ignoreVolumeChange = false;
    } else {
        slider.setEnabled(false);
        muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_volumeChanged(qreal value)
{
    if (!ignoreVolumeChange) {
        slider.setValue(qRound(100 * value));
    }
}

bool VolumeSlider::hasTracking() const
{
    return k_ptr->slider.hasTracking();
}

void VolumeSlider::setTracking(bool tracking)
{
    k_ptr->slider.setTracking(tracking);
}

int VolumeSlider::pageStep() const
{
    return k_ptr->slider.pageStep();
}

void VolumeSlider::setPageStep(int milliseconds)
{
    k_ptr->slider.setPageStep(milliseconds);
}

int VolumeSlider::singleStep() const
{
    return k_ptr->slider.singleStep();
}

void VolumeSlider::setSingleStep(int milliseconds)
{
    k_ptr->slider.setSingleStep(milliseconds);
}

} // namespace Phonon

#include "moc_volumeslider.cpp"

// vim: sw=4 et
<commit_msg>make the internal slider take focus if VolumeSlider is supposed to take focus<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 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
    Library General Public License for more details.

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

*/

#include "volumeslider.h"
#include "volumeslider_p.h"
#include "audiooutput.h"
#include "phonondefs_p.h"
#include "phononnamespace_p.h"
#include "factory.h"

namespace Phonon
{

VolumeSlider::VolumeSlider(QWidget *parent)
    : QWidget(parent),
    k_ptr(new VolumeSliderPrivate(this))
{
    K_D(VolumeSlider);
    setToolTip(tr("Volume: %1%").arg(100));
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%").arg(100));

    connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_sliderChanged(int)));
    connect(&d->muteButton, SIGNAL(clicked()), SLOT(_k_buttonClicked()));

    setFocusProxy(&d->slider);
}

VolumeSlider::VolumeSlider(AudioOutput *output, QWidget *parent)
    : QWidget(parent),
    k_ptr(new VolumeSliderPrivate(this))
{
    K_D(VolumeSlider);
    setToolTip(tr("Volume: %1%").arg(100));
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%").arg(100));

    connect(&d->slider, SIGNAL(valueChanged(int)), SLOT(_k_sliderChanged(int)));
    connect(&d->muteButton, SIGNAL(clicked()), SLOT(_k_buttonClicked()));

    if (output) {
        d->output = output;
        d->slider.setValue(qRound(100 * output->volume()));
        d->slider.setEnabled(true);
        d->muteButton.setEnabled(true);
        connect(output, SIGNAL(volumeChanged(qreal)), SLOT(_k_volumeChanged(qreal)));
        connect(output, SIGNAL(mutedChanged(bool)), SLOT(_k_mutedChanged(bool)));
    }

    setFocusProxy(&d->slider);
}

VolumeSlider::~VolumeSlider()
{
    delete k_ptr;
}

bool VolumeSlider::isMuteVisible() const
{
    return k_ptr->muteButton.isVisible();
}

void VolumeSlider::setMuteVisible(bool visible)
{
    k_ptr->muteButton.setVisible(visible);
}

QSize VolumeSlider::iconSize() const
{
    return k_ptr->muteButton.iconSize();
}

void VolumeSlider::setIconSize(const QSize &iconSize)
{
    pDebug() << Q_FUNC_INFO << iconSize;
    k_ptr->muteButton.setIconSize(iconSize);
}

qreal VolumeSlider::maximumVolume() const
{
    return k_ptr->slider.maximum() * 0.01;
}

void VolumeSlider::setMaximumVolume(qreal volume)
{
    int max = static_cast<int>(volume * 100);
    k_ptr->slider.setMaximum(max);
    setWhatsThis(tr("Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%")
            .arg(max));
}

Qt::Orientation VolumeSlider::orientation() const
{
    return k_ptr->slider.orientation();
}

void VolumeSlider::setOrientation(Qt::Orientation o)
{
    K_D(VolumeSlider);
    Qt::Alignment align = (o == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter);
    d->layout.setAlignment(&d->muteButton, align);
    d->layout.setAlignment(&d->slider, align);
    d->layout.setDirection(o == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
    d->slider.setOrientation(o);
}

AudioOutput *VolumeSlider::audioOutput() const
{
    K_D(const VolumeSlider);
    return d->output;
}

void VolumeSlider::setAudioOutput(AudioOutput *output)
{
    K_D(VolumeSlider);
    if (d->output) {
        disconnect(d->output, 0, this, 0);
    }
    d->output = output;
    if (output) {
        d->slider.setValue(qRound(100 * output->volume()));
        d->slider.setEnabled(true);
        d->muteButton.setEnabled(true);

        d->_k_volumeChanged(output->volume());
        d->_k_mutedChanged(output->isMuted());

        connect(output, SIGNAL(volumeChanged(qreal)), SLOT(_k_volumeChanged(qreal)));
        connect(output, SIGNAL(mutedChanged(bool)), SLOT(_k_mutedChanged(bool)));
    } else {
        d->slider.setValue(100);
        d->slider.setEnabled(false);
        d->muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_buttonClicked()
{
    if (output) {
        output->setMuted(!output->isMuted());
    } else {
        slider.setEnabled(false);
        muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_mutedChanged(bool muted)
{
    Q_Q(VolumeSlider);
    if (muted) {
        q->setToolTip(VolumeSlider::tr("Muted"));
        muteButton.setIcon(mutedIcon);
    } else {
        q->setToolTip(VolumeSlider::tr("Volume: %1%").arg(static_cast<int>(output->volume() * 100.0)));
        muteButton.setIcon(volumeIcon);
    }
}

void VolumeSliderPrivate::_k_sliderChanged(int value)
{
    Q_Q(VolumeSlider);

    if (output) {
        if (!output->isMuted()) {
           q->setToolTip(VolumeSlider::tr("Volume: %1%").arg(value));
        }

        ignoreVolumeChange = true;
        output->setVolume((static_cast<qreal>(value)) * 0.01);
        ignoreVolumeChange = false;
    } else {
        slider.setEnabled(false);
        muteButton.setEnabled(false);
    }
}

void VolumeSliderPrivate::_k_volumeChanged(qreal value)
{
    if (!ignoreVolumeChange) {
        slider.setValue(qRound(100 * value));
    }
}

bool VolumeSlider::hasTracking() const
{
    return k_ptr->slider.hasTracking();
}

void VolumeSlider::setTracking(bool tracking)
{
    k_ptr->slider.setTracking(tracking);
}

int VolumeSlider::pageStep() const
{
    return k_ptr->slider.pageStep();
}

void VolumeSlider::setPageStep(int milliseconds)
{
    k_ptr->slider.setPageStep(milliseconds);
}

int VolumeSlider::singleStep() const
{
    return k_ptr->slider.singleStep();
}

void VolumeSlider::setSingleStep(int milliseconds)
{
    k_ptr->slider.setSingleStep(milliseconds);
}

} // namespace Phonon

#include "moc_volumeslider.cpp"

// vim: sw=4 et
<|endoftext|>


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

#include <exotica/PlanningProblem.h>
#include <exotica/PlanningProblemInitializer.h>
#include <exotica/Setup.h>

namespace exotica
{
PlanningProblem::PlanningProblem() : Flags(KIN_FK), N(0)
{
}

std::string PlanningProblem::print(std::string prepend)
{
    std::string ret = Object::print(prepend);
    ret += "\n" + prepend + "  Task definitions:";
    for (auto& it : TaskMaps)
        ret += "\n" + it.second->print(prepend + "    ");
    return ret;
}

Eigen::VectorXd PlanningProblem::applyStartState()
{
    scene_->setModelState(startState);
    return scene_->getControlledState();
}

void PlanningProblem::preupdate()
{
    for (auto& it : TaskMaps) it.second->preupdate();
}

void PlanningProblem::setStartState(Eigen::VectorXdRefConst x)
{
    if (x.rows() == startState.rows())
    {
        startState = x;
    }
    else if (x.rows() == scene_->getSolver().getNumControlledJoints())
    {
        std::vector<std::string> jointNames = scene_->getJointNames();
        std::vector<std::string> modelNames = scene_->getModelJointNames();
        for (int i = 0; i < jointNames.size(); i++)
        {
            for (int j = 0; j < modelNames.size(); j++)
            {
                if (jointNames[i] == modelNames[j]) startState[j] = x(i);
            }
        }
    }
    else
    {
        throw_named("Wrong start state vector size, expected " << startState.rows() << " got " << x.rows());
    }
}

Eigen::VectorXd PlanningProblem::getStartState()
{
    return startState;
}

void PlanningProblem::InstantiateBase(const Initializer& init_)
{
    Object::InstatiateObject(init_);
    PlanningProblemInitializer init(init_);

    TaskMaps.clear();
    Tasks.clear();

    // Create the scene
    scene_.reset(new Scene());
    scene_->InstantiateInternal(SceneInitializer(init.PlanningScene));
    startState = Eigen::VectorXd::Zero(scene_->getModelJointNames().size());
    N = scene_->getSolver().getNumControlledJoints();

    if (init.StartState.rows() > 0)
    {
        setStartState(init.StartState);
    }

    KinematicsRequest Request;
    Request.Flags = Flags;

    // Create the maps
    int id = 0;
    for (const Initializer& MapInitializer : init.Maps)
    {
        TaskMap_ptr NewMap = Setup::createMap(MapInitializer);
        NewMap->assignScene(scene_);
        NewMap->ns_ = ns_ + "/" + NewMap->getObjectName();
        if (TaskMaps.find(NewMap->getObjectName()) != TaskMaps.end())
        {
            throw_named("Map '" + NewMap->getObjectName() + "' already exists!");
        }
        std::vector<KinematicFrameRequest> frames = NewMap->GetFrames();

        NewMap->Kinematics = KinematicSolution(id, frames.size());
        id += frames.size();

        Request.Frames.insert(Request.Frames.end(), frames.begin(), frames.end());
        TaskMaps[NewMap->getObjectName()] = NewMap;
        Tasks.push_back(NewMap);
    }

    std::shared_ptr<KinematicResponse> Response = scene_->RequestKinematics(Request);
    id = 0;
    int idJ = 0;
    for (int i = 0; i < Tasks.size(); i++)
    {
        Tasks[i]->Kinematics.Create(Response);
        Tasks[i]->Id = i;
        Tasks[i]->Start = id;
        Tasks[i]->Length = Tasks[i]->taskSpaceDim();
        Tasks[i]->StartJ = idJ;
        Tasks[i]->LengthJ = Tasks[i]->taskSpaceJacobianDim();
        id += Tasks[i]->Length;
        idJ += Tasks[i]->LengthJ;
    }

    if (init.Maps.size() == 0)
    {
        HIGHLIGHT("No maps were defined!");
    }
}

TaskMap_map& PlanningProblem::getTaskMaps()
{
    return TaskMaps;
}

TaskMap_vec& PlanningProblem::getTasks()
{
    return Tasks;
}

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

#include <exotica/PlanningProblem.h>
#include <exotica/PlanningProblemInitializer.h>
#include <exotica/Setup.h>

namespace exotica
{
PlanningProblem::PlanningProblem() : Flags(KIN_FK), N(0)
{
}

std::string PlanningProblem::print(std::string prepend)
{
    std::string ret = Object::print(prepend);
    ret += "\n" + prepend + "  Task definitions:";
    for (auto& it : TaskMaps)
        ret += "\n" + it.second->print(prepend + "    ");
    return ret;
}

Eigen::VectorXd PlanningProblem::applyStartState()
{
    scene_->setModelState(startState);
    return scene_->getControlledState();
}

void PlanningProblem::preupdate()
{
    for (auto& it : TaskMaps) it.second->preupdate();
}

void PlanningProblem::setStartState(Eigen::VectorXdRefConst x)
{
    if (x.rows() == scene_->getSolver().getNumModelJoints())
    {
        startState = x;
    }
    else if (x.rows() == scene_->getSolver().getNumControlledJoints())
    {
        std::vector<std::string> jointNames = scene_->getJointNames();
        std::vector<std::string> modelNames = scene_->getModelJointNames();
        for (int i = 0; i < jointNames.size(); i++)
        {
            for (int j = 0; j < modelNames.size(); j++)
            {
                if (jointNames[i] == modelNames[j]) startState[j] = x(i);
            }
        }
    }
    else
    {
        throw_named("Wrong start state vector size, expected " << scene_->getSolver().getNumModelJoints() << ", got " << x.rows());
    }
}

Eigen::VectorXd PlanningProblem::getStartState()
{
    return startState;
}

void PlanningProblem::InstantiateBase(const Initializer& init_)
{
    Object::InstatiateObject(init_);
    PlanningProblemInitializer init(init_);

    TaskMaps.clear();
    Tasks.clear();

    // Create the scene
    scene_.reset(new Scene());
    scene_->InstantiateInternal(SceneInitializer(init.PlanningScene));
    startState = Eigen::VectorXd::Zero(scene_->getModelJointNames().size());
    N = scene_->getSolver().getNumControlledJoints();

    if (init.StartState.rows() > 0)
    {
        setStartState(init.StartState);
    }

    KinematicsRequest Request;
    Request.Flags = Flags;

    // Create the maps
    int id = 0;
    for (const Initializer& MapInitializer : init.Maps)
    {
        TaskMap_ptr NewMap = Setup::createMap(MapInitializer);
        NewMap->assignScene(scene_);
        NewMap->ns_ = ns_ + "/" + NewMap->getObjectName();
        if (TaskMaps.find(NewMap->getObjectName()) != TaskMaps.end())
        {
            throw_named("Map '" + NewMap->getObjectName() + "' already exists!");
        }
        std::vector<KinematicFrameRequest> frames = NewMap->GetFrames();

        NewMap->Kinematics = KinematicSolution(id, frames.size());
        id += frames.size();

        Request.Frames.insert(Request.Frames.end(), frames.begin(), frames.end());
        TaskMaps[NewMap->getObjectName()] = NewMap;
        Tasks.push_back(NewMap);
    }

    std::shared_ptr<KinematicResponse> Response = scene_->RequestKinematics(Request);
    id = 0;
    int idJ = 0;
    for (int i = 0; i < Tasks.size(); i++)
    {
        Tasks[i]->Kinematics.Create(Response);
        Tasks[i]->Id = i;
        Tasks[i]->Start = id;
        Tasks[i]->Length = Tasks[i]->taskSpaceDim();
        Tasks[i]->StartJ = idJ;
        Tasks[i]->LengthJ = Tasks[i]->taskSpaceJacobianDim();
        id += Tasks[i]->Length;
        idJ += Tasks[i]->LengthJ;
    }

    if (init.Maps.size() == 0)
    {
        HIGHLIGHT("No maps were defined!");
    }
}

TaskMap_map& PlanningProblem::getTaskMaps()
{
    return TaskMaps;
}

TaskMap_vec& PlanningProblem::getTasks()
{
    return Tasks;
}

Scene_ptr PlanningProblem::getScene()
{
    return scene_;
}
}
<|endoftext|>


<commit_before><commit_msg>clang scan-build: Dead initialization<commit_after><|endoftext|>


<commit_before><commit_msg>Add ground-truth option to cso-lut (#2398)<commit_after><|endoftext|>