<commit_before>//
// MIT License
//
// Copyright (c) 2017-2018 Thibault Martinez and Simon Ninon
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//

#include <algorithm>
#include <cstdlib>
#include <functional>

#include <iota/constants.hpp>
#include <iota/types/trinary.hpp>

namespace IOTA {

namespace Types {

static std::vector<std::vector<int8_t>> trytesTrits = {
  { 0, 0, 0 },  { 1, 0, 0 },  { -1, 1, 0 },   { 0, 1, 0 },   { 1, 1, 0 },   { -1, -1, 1 },
  { 0, -1, 1 }, { 1, -1, 1 }, { -1, 0, 1 },   { 0, 0, 1 },   { 1, 0, 1 },   { -1, 1, 1 },
  { 0, 1, 1 },  { 1, 1, 1 },  { -1, -1, -1 }, { 0, -1, -1 }, { 1, -1, -1 }, { -1, 0, -1 },
  { 0, 0, -1 }, { 1, 0, -1 }, { -1, 1, -1 },  { 0, 1, -1 },  { 1, 1, -1 },  { -1, -1, 0 },
  { 0, -1, 0 }, { 1, -1, 0 }, { -1, 0, 0 }
};

int8_t
tryteIndex(const char& tryte) {
  if (tryte == '9') {
    return 0;
  }
  if ('A' <= tryte && tryte <= 'Z') {
    return tryte - 'A' + 1;
  }
  return -1;
}

bool
isValidTryte(const char& tryte) {
  return tryteIndex(tryte) >= 0;
}

bool
isValidTrytes(const Trytes& trytes) {
  return std::find_if_not(trytes.begin(), trytes.end(), &isValidTryte) == trytes.end();
}

bool
isArrayOfHashes(const std::vector<Trytes>& hashes) {
  for (const auto& hash : hashes) {
    if (hash.length() != SeedLength && hash.length() != SeedLengthWithChecksum) {
      return false;
    }

    if (!isValidTrytes(hash)) {
      return false;
    }
  }

  return true;
}

bool
isValidAddress(const Trytes& s) {
  return (s.length() == AddressLength || s.length() == AddressLengthWithChecksum) &&
         isValidTrytes(s);
}

bool
isValidHash(const Trytes& s) {
  return s.length() == HashLength && isValidTrytes(s);
}

std::vector<int8_t>
tritsToBytes(const Trits& trits) {
  size_t i = trits.size();
  // strip leading zeroes;
  while (i && !trits[i - 1]) {
    i--;
  }
  if (i == 0) {
    return std::vector<int8_t>(ByteHashLength, 0);
  }
  std::vector<uint32_t> data(1, 0);
  int8_t                sign = trits[i - 1];
  for (; i > 0; --i) {
    // multiply by 3
    uint64_t sum = 0;
    for (size_t j = 0; j < data.size(); ++j) {
      sum += data[j] + (static_cast<uint64_t>(data[j]) << 1);
      data[j] = static_cast<uint32_t>(sum & 0xffffffff);
      sum >>= 32;
    }
    if (sum != 0) {
      data.push_back(static_cast<uint32_t>(sum & 0xffffffff));
    }
    switch (sign * trits[i - 1]) {
      case 1:
        // increment by 1
        for (size_t j = 0; j < data.size(); ++j) {
          data[j] = data[j] + 1;
          if (data[j]) {
            break;
          }
        }
        if (!data.back()) {
          data.push_back(1);
        }
        break;
      case -1:
        // decrement by 1
        uint8_t carry = 0;
        for (size_t j = 0; j < data.size(); ++j) {
          data[j] = data[j] + 0xffffffff + carry;
          carry   = data[j] != 0xffffffff;
        }
        if (!data.back()) {
          data.pop_back();
        }
        break;
    }
  }

  uint32_t msdw = data.back();
  size_t   j    = 32;
  for (; j > 0 && !(msdw & (0x1 << (j - 1))); --j)
    ;
  size_t nr_bytes = ((data.size() - 1) << 2) + ((j + 7) >> 3);

  // negate two's complement if sign is negative
  if (sign == -1) {
    size_t i = 0;
    for (; i < data.size(); ++i) {
      data[i] = ~data[i] + 1;
      if (data[i]) {
        ++i;
        break;
      }
    }
    for (; i < data.size(); ++i) {
      data[i] = ~data[i];
    }
  }

  // read out the bytes
  std::vector<int8_t> bytes(nr_bytes);
  uint32_t            dw = 0;
  for (size_t i = 0; i < nr_bytes; ++i) {
    if (!(i & 0x3)) {
      dw = data[i >> 2];
    }
    bytes[nr_bytes - i - 1] = static_cast<int8_t>(dw & 0xff);
    dw >>= 8;
  }

  std::vector<int8_t> res(48, sign == 1 ? 0 : -1);
  std::copy(bytes.begin(), bytes.end(), res.begin() + ByteHashLength - nr_bytes);

  return res;
}

Trits
bytesToTrits(const std::vector<int8_t>& bytes) {
  int8_t                sign     = bytes.empty() || bytes[0] >= 0 ? 1 : -1;
  size_t                nr_bytes = bytes.size();
  size_t                j        = (nr_bytes + 3) >> 2;
  std::vector<uint32_t> div(j, 0);
  uint32_t              dw = sign == 1 ? 0 : (0xffffffff << 8);
  for (size_t i = 0; i < nr_bytes; ++i) {
    dw |= static_cast<uint8_t>(bytes[i]);
    if (!((nr_bytes - i - 1) & 0x3)) {
      div[(nr_bytes - i - 1) >> 2] = dw;
      dw                           = 0;
    }
    dw <<= 8;
  }

  // negate two's complement if sign is negative
  if (sign == -1) {
    size_t i = 0;
    for (; i < div.size(); ++i) {
      div[i] = ~div[i] + 1;
      if (div[i]) {
        ++i;
        break;
      }
    }
    for (; i < div.size(); ++i) {
      div[i] = ~div[i];
    }
  }

  std::vector<int8_t> trits;

  // strip leading zeros
  while (j && !div[j - 1]) {
    --j;
  }

  while (j) {
    // divide by 3
    uint64_t rem = 0;
    for (size_t k = j; k > 0; --k) {
      rem <<= 32;
      rem += div[k - 1];
      div[k - 1] = static_cast<uint32_t>(rem / 3);
      rem %= 3;
    }

    if (!div[j - 1]) {
      j--;
    }

    if (rem > 1) {
      // increment by 1
      for (size_t k = 0; k < j; ++k) {
        div[k] = div[k] + 1;
        if (div[k]) {
          break;
        }
      }
      if (!j || !div[j - 1]) {
        div[j] = 1;
        j++;
      }
      rem -= 3;
    }

    trits.push_back(sign * static_cast<int8_t>(rem));
  }

  trits.resize(TritHashLength, 0);
  return trits;
}

Trits
trytesToTrits(const Trytes& trytes) {
  Trits trits;
  for (std::size_t i = 0; i < trytes.size(); i++) {
    std::size_t index = tryteIndex(trytes[i]);
    trits.push_back(trytesTrits[index][0]);
    trits.push_back(trytesTrits[index][1]);
    trits.push_back(trytesTrits[index][2]);
  }
  return trits;
}

Trytes
tritsToTrytes(const Trits& trits) {
  return tritsToTrytes(trits, trits.size());
}

Trytes
tritsToTrytes(const Trits& trits, std::size_t length) {
  Trytes trytes;
  for (std::size_t i = 0; i < length; i += 3) {
    int8_t idx = trits[i] + trits[i + 1] * 3 + trits[i + 2] * 9;
    if (idx < 0) {
      idx += TryteAlphabetLength;
    }
    trytes += TryteAlphabet[idx];
  }
  return trytes;
}

Types::Trits
intToTrits(const int64_t& value) {
  Types::Trits trits;
  uint64_t     absoluteValue = std::abs(value);

  while (absoluteValue > 0) {
    int8_t remainder = absoluteValue % 3;
    absoluteValue    = absoluteValue / 3;

    if (remainder > 1) {
      remainder = -1;
      absoluteValue++;
    }

    trits.push_back(remainder);
  }

  if (value < 0) {
    std::transform(std::begin(trits), std::end(trits), std::begin(trits), std::negate<int>());
  }

  return trits;
}

Types::Trits
intToTrits(const int64_t& value, std::size_t length) {
  auto res = intToTrits(value);

  res.resize(length, 0);

  return res;
}

}  // namespace Types

}  // namespace IOTA
<commit_msg>Trytes to trits conversion optimization (#232)<commit_after>//
// MIT License
//
// Copyright (c) 2017-2018 Thibault Martinez and Simon Ninon
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//

#include <algorithm>
#include <array>
#include <cstdlib>
#include <functional>

#include <iota/constants.hpp>
#include <iota/types/trinary.hpp>

namespace IOTA {

namespace Types {

static constexpr std::array<std::array<int8_t, 3>, TryteAlphabetLength> trytesTrits{
  { { { 0, 0, 0 } },   { { 1, 0, 0 } },   { { -1, 1, 0 } },  { { 0, 1, 0 } },   { { 1, 1, 0 } },
    { { -1, -1, 1 } }, { { 0, -1, 1 } },  { { 1, -1, 1 } },  { { -1, 0, 1 } },  { { 0, 0, 1 } },
    { { 1, 0, 1 } },   { { -1, 1, 1 } },  { { 0, 1, 1 } },   { { 1, 1, 1 } },   { { -1, -1, -1 } },
    { { 0, -1, -1 } }, { { 1, -1, -1 } }, { { -1, 0, -1 } }, { { 0, 0, -1 } },  { { 1, 0, -1 } },
    { { -1, 1, -1 } }, { { 0, 1, -1 } },  { { 1, 1, -1 } },  { { -1, -1, 0 } }, { { 0, -1, 0 } },
    { { 1, -1, 0 } },  { { -1, 0, 0 } } }
};

int8_t
tryteIndex(const char& tryte) {
  if (tryte == '9') {
    return 0;
  }
  if ('A' <= tryte && tryte <= 'Z') {
    return tryte - 'A' + 1;
  }
  return -1;
}

bool
isValidTryte(const char& tryte) {
  return tryteIndex(tryte) >= 0;
}

bool
isValidTrytes(const Trytes& trytes) {
  return std::find_if_not(trytes.begin(), trytes.end(), &isValidTryte) == trytes.end();
}

bool
isArrayOfHashes(const std::vector<Trytes>& hashes) {
  for (const auto& hash : hashes) {
    if (hash.length() != SeedLength && hash.length() != SeedLengthWithChecksum) {
      return false;
    }

    if (!isValidTrytes(hash)) {
      return false;
    }
  }

  return true;
}

bool
isValidAddress(const Trytes& s) {
  return (s.length() == AddressLength || s.length() == AddressLengthWithChecksum) &&
         isValidTrytes(s);
}

bool
isValidHash(const Trytes& s) {
  return s.length() == HashLength && isValidTrytes(s);
}

std::vector<int8_t>
tritsToBytes(const Trits& trits) {
  size_t i = trits.size();
  // strip leading zeroes;
  while (i && !trits[i - 1]) {
    i--;
  }
  if (i == 0) {
    return std::vector<int8_t>(ByteHashLength, 0);
  }
  std::vector<uint32_t> data(1, 0);
  int8_t                sign = trits[i - 1];
  for (; i > 0; --i) {
    // multiply by 3
    uint64_t sum = 0;
    for (size_t j = 0; j < data.size(); ++j) {
      sum += data[j] + (static_cast<uint64_t>(data[j]) << 1);
      data[j] = static_cast<uint32_t>(sum & 0xffffffff);
      sum >>= 32;
    }
    if (sum != 0) {
      data.push_back(static_cast<uint32_t>(sum & 0xffffffff));
    }
    switch (sign * trits[i - 1]) {
      case 1:
        // increment by 1
        for (size_t j = 0; j < data.size(); ++j) {
          data[j] = data[j] + 1;
          if (data[j]) {
            break;
          }
        }
        if (!data.back()) {
          data.push_back(1);
        }
        break;
      case -1:
        // decrement by 1
        uint8_t carry = 0;
        for (size_t j = 0; j < data.size(); ++j) {
          data[j] = data[j] + 0xffffffff + carry;
          carry   = data[j] != 0xffffffff;
        }
        if (!data.back()) {
          data.pop_back();
        }
        break;
    }
  }

  uint32_t msdw = data.back();
  size_t   j    = 32;
  for (; j > 0 && !(msdw & (0x1 << (j - 1))); --j)
    ;
  size_t nr_bytes = ((data.size() - 1) << 2) + ((j + 7) >> 3);

  // negate two's complement if sign is negative
  if (sign == -1) {
    size_t i = 0;
    for (; i < data.size(); ++i) {
      data[i] = ~data[i] + 1;
      if (data[i]) {
        ++i;
        break;
      }
    }
    for (; i < data.size(); ++i) {
      data[i] = ~data[i];
    }
  }

  // read out the bytes
  std::vector<int8_t> bytes(nr_bytes);
  uint32_t            dw = 0;
  for (size_t i = 0; i < nr_bytes; ++i) {
    if (!(i & 0x3)) {
      dw = data[i >> 2];
    }
    bytes[nr_bytes - i - 1] = static_cast<int8_t>(dw & 0xff);
    dw >>= 8;
  }

  std::vector<int8_t> res(48, sign == 1 ? 0 : -1);
  std::copy(bytes.begin(), bytes.end(), res.begin() + ByteHashLength - nr_bytes);

  return res;
}

Trits
bytesToTrits(const std::vector<int8_t>& bytes) {
  int8_t                sign     = bytes.empty() || bytes[0] >= 0 ? 1 : -1;
  size_t                nr_bytes = bytes.size();
  size_t                j        = (nr_bytes + 3) >> 2;
  std::vector<uint32_t> div(j, 0);
  uint32_t              dw = sign == 1 ? 0 : (0xffffffff << 8);
  for (size_t i = 0; i < nr_bytes; ++i) {
    dw |= static_cast<uint8_t>(bytes[i]);
    if (!((nr_bytes - i - 1) & 0x3)) {
      div[(nr_bytes - i - 1) >> 2] = dw;
      dw                           = 0;
    }
    dw <<= 8;
  }

  // negate two's complement if sign is negative
  if (sign == -1) {
    size_t i = 0;
    for (; i < div.size(); ++i) {
      div[i] = ~div[i] + 1;
      if (div[i]) {
        ++i;
        break;
      }
    }
    for (; i < div.size(); ++i) {
      div[i] = ~div[i];
    }
  }

  std::vector<int8_t> trits;

  // strip leading zeros
  while (j && !div[j - 1]) {
    --j;
  }

  while (j) {
    // divide by 3
    uint64_t rem = 0;
    for (size_t k = j; k > 0; --k) {
      rem <<= 32;
      rem += div[k - 1];
      div[k - 1] = static_cast<uint32_t>(rem / 3);
      rem %= 3;
    }

    if (!div[j - 1]) {
      j--;
    }

    if (rem > 1) {
      // increment by 1
      for (size_t k = 0; k < j; ++k) {
        div[k] = div[k] + 1;
        if (div[k]) {
          break;
        }
      }
      if (!j || !div[j - 1]) {
        div[j] = 1;
        j++;
      }
      rem -= 3;
    }

    trits.push_back(sign * static_cast<int8_t>(rem));
  }

  trits.resize(TritHashLength, 0);
  return trits;
}

Trits
trytesToTrits(const Trytes& trytes) {
  Trits trits;
  trits.reserve(trytes.size() * 3);
  for (std::size_t i = 0; i < trytes.size(); i++) {
    std::size_t index = tryteIndex(trytes[i]);
    trits.insert(std::end(trits), std::begin(trytesTrits[index]), std::end(trytesTrits[index]));
  }
  return trits;
}

Trytes
tritsToTrytes(const Trits& trits) {
  return tritsToTrytes(trits, trits.size());
}

Trytes
tritsToTrytes(const Trits& trits, std::size_t length) {
  Trytes trytes;
  for (std::size_t i = 0; i < length; i += 3) {
    int8_t idx = trits[i] + trits[i + 1] * 3 + trits[i + 2] * 9;
    if (idx < 0) {
      idx += TryteAlphabetLength;
    }
    trytes += TryteAlphabet[idx];
  }
  return trytes;
}

Types::Trits
intToTrits(const int64_t& value) {
  Types::Trits trits;
  uint64_t     absoluteValue = std::abs(value);

  while (absoluteValue > 0) {
    int8_t remainder = absoluteValue % 3;
    absoluteValue    = absoluteValue / 3;

    if (remainder > 1) {
      remainder = -1;
      absoluteValue++;
    }

    trits.push_back(remainder);
  }

  if (value < 0) {
    std::transform(std::begin(trits), std::end(trits), std::begin(trits), std::negate<int>());
  }

  return trits;
}

Types::Trits
intToTrits(const int64_t& value, std::size_t length) {
  auto res = intToTrits(value);

  res.resize(length, 0);

  return res;
}

}  // namespace Types

}  // namespace IOTA
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* libodfgen
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2004 William Lachance (wlach@interlog.com)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

/* "This product is not manufactured, approved, or supported by
 * Corel Corporation or Corel Corporation Limited."
 */
#ifndef _ODFDOCUMENTHANDLER_HXX_
#define _ODFDOCUMENTHANDLER_HXX_
#include <libwpd/libwpd.h>

enum OdfStreamType { ODF_FLAT_XML, ODF_CONTENT_XML, ODF_STYLES_XML, ODF_SETTINGS_XML, ODF_META_XML };

class OdfDocumentHandler
{
public:
	OdfDocumentHandler() {};
	virtual ~OdfDocumentHandler() {};

	virtual void startDocument() = 0;
	virtual void endDocument() = 0;
	virtual void startElement(const char *psName, const WPXPropertyList &xPropList) = 0;
	virtual void endElement(const char *psName) = 0;
	virtual void characters(const WPXString &sCharacters) = 0;
};
#endif

/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
<commit_msg>a ctor in abstract class does not make sense<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* libodfgen
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2004 William Lachance (wlach@interlog.com)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

/* "This product is not manufactured, approved, or supported by
 * Corel Corporation or Corel Corporation Limited."
 */
#ifndef _ODFDOCUMENTHANDLER_HXX_
#define _ODFDOCUMENTHANDLER_HXX_
#include <libwpd/libwpd.h>

enum OdfStreamType { ODF_FLAT_XML, ODF_CONTENT_XML, ODF_STYLES_XML, ODF_SETTINGS_XML, ODF_META_XML };

class OdfDocumentHandler
{
public:
	virtual ~OdfDocumentHandler() {};

	virtual void startDocument() = 0;
	virtual void endDocument() = 0;
	virtual void startElement(const char *psName, const WPXPropertyList &xPropList) = 0;
	virtual void endElement(const char *psName) = 0;
	virtual void characters(const WPXString &sCharacters) = 0;
};
#endif

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


<commit_before>/* Butterworth filter class, by John Gibson.
   Just a knock-off of clm and csound ones, which come right outta Dodge.
*/
#include "Butter.h"

#define SQRT2  1.4142135623730950488

enum {
   LOW_PASS,
   HIGH_PASS,
   BAND_PASS,
   BAND_REJECT
};

Butter :: Butter() : Filter()
{
   inputs = new MY_FLOAT [2];
   zeroCoeffs[0] = (MY_FLOAT) 0.0;
   zeroCoeffs[1] = (MY_FLOAT) 0.0;
   poleCoeffs[0] = (MY_FLOAT) 0.0;
   poleCoeffs[1] = (MY_FLOAT) 0.0;
   gain = (MY_FLOAT) 1.0;
   type = LOW_PASS;
   c = d = 0.0;
   this->clear();
}

Butter :: ~Butter()
{
   delete [] inputs;
}

void Butter :: clear()
{
   inputs[0] = (MY_FLOAT) 0.0;
   inputs[1] = (MY_FLOAT) 0.0;
   lastOutput = (MY_FLOAT) 0.0;
}

void Butter :: setLowPass(MY_FLOAT cutoff)
{
   c = 1.0 / tan((double)(cutoff * PI / SR));

   gain = (MY_FLOAT)(1.0 / (1.0 + SQRT_TWO * c + c * c));

   zeroCoeffs[0] = 2.0 * gain;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = 2.0 * (1.0 - c * c) * gain;
   poleCoeffs[1] = ((1.0 - SQRT_TWO * c) + c * c) * gain;

   type = LOW_PASS;
}

void Butter :: setHighPass(MY_FLOAT cutoff)
{
   c = tan((double)(cutoff * PI / SR));

   gain = (MY_FLOAT)(1.0 / (1.0 + SQRT_TWO * c + c * c));

   zeroCoeffs[0] = -2.0 * gain;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = 2.0 * (c * c - 1.0) * gain;
   poleCoeffs[1] = ((1.0 - SQRT_TWO * c) + c * c) * gain;

   type = HIGH_PASS;
}

void Butter :: setBandPassFreq(MY_FLOAT freq)
{
   assert(type == BAND_PASS);

   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   poleCoeffs[0] = -c * d * gain;
}

void Butter :: setBandPassBandwidth(MY_FLOAT bandwidth)
{
   assert(type == BAND_PASS);

   c = 1.0 / tan((double)(bandwidth * PI / SR));

   gain = 1.0 / (1.0 + c);

   zeroCoeffs[0] = 0.0;
   zeroCoeffs[1] = -gain;

   poleCoeffs[0] = -c * d * gain;
   poleCoeffs[1] = (c - 1.0) * gain;
}

void Butter :: setBandPass(MY_FLOAT freq, MY_FLOAT bandwidth)
{
   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   type = BAND_PASS;
   setBandPassBandwidth(bandwidth);
}

void Butter :: setBandRejectFreq(MY_FLOAT freq)
{
   assert(type == BAND_REJECT);

   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   zeroCoeffs[0] = -c * d;
   poleCoeffs[0] = zeroCoeffs[0];
}

void Butter :: setBandRejectBandwidth(MY_FLOAT bandwidth)
{
   assert(type == BAND_REJECT);

   c = tan((double)(bandwidth * PI / SR));

   gain = 1.0 / (1.0 + c);

   zeroCoeffs[0] = -d * c;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = zeroCoeffs[0];
   poleCoeffs[1] = (1.0 - c) * gain;
}

void Butter :: setBandReject(MY_FLOAT freq, MY_FLOAT bandwidth)
{
   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   type = BAND_REJECT;
   setBandRejectBandwidth(bandwidth);
}

// y0 = g x(n) + a1 x(n-1) + a2 x(n-2) + b1 y(n-1) + b2 y(n-2)
// Note: signs of b1 and b2 flipped compared to what you often see
// Note: This is the canonical form, needing only 2 history vals.

MY_FLOAT Butter :: tick(MY_FLOAT sample)
{
   MY_FLOAT temp;

   temp = sample - inputs[0] * poleCoeffs[0] - inputs[1] * poleCoeffs[1];

   lastOutput = temp * gain + inputs[0] * zeroCoeffs[0]
                            + inputs[1] * zeroCoeffs[1];
   inputs[1] = inputs[0];
   inputs[0] = temp;

   return lastOutput;
}

<commit_msg>Fix band reject design as per Dodge.<commit_after>/* Butterworth filter class, by John Gibson.
   Just a knock-off of clm and csound ones, which come right outta Dodge.
*/
#include "Butter.h"

#define SQRT2  1.4142135623730950488

enum {
   LOW_PASS,
   HIGH_PASS,
   BAND_PASS,
   BAND_REJECT
};

Butter :: Butter() : Filter()
{
   inputs = new MY_FLOAT [2];
   zeroCoeffs[0] = (MY_FLOAT) 0.0;
   zeroCoeffs[1] = (MY_FLOAT) 0.0;
   poleCoeffs[0] = (MY_FLOAT) 0.0;
   poleCoeffs[1] = (MY_FLOAT) 0.0;
   gain = (MY_FLOAT) 1.0;
   type = LOW_PASS;
   c = d = 0.0;
   this->clear();
}

Butter :: ~Butter()
{
   delete [] inputs;
}

void Butter :: clear()
{
   inputs[0] = (MY_FLOAT) 0.0;
   inputs[1] = (MY_FLOAT) 0.0;
   lastOutput = (MY_FLOAT) 0.0;
}

void Butter :: setLowPass(MY_FLOAT cutoff)
{
   c = 1.0 / tan((double)(cutoff * PI / SR));

   gain = (MY_FLOAT)(1.0 / (1.0 + SQRT_TWO * c + c * c));

   zeroCoeffs[0] = 2.0 * gain;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = 2.0 * (1.0 - c * c) * gain;
   poleCoeffs[1] = ((1.0 - SQRT_TWO * c) + c * c) * gain;

   type = LOW_PASS;
}

void Butter :: setHighPass(MY_FLOAT cutoff)
{
   c = tan((double)(cutoff * PI / SR));

   gain = (MY_FLOAT)(1.0 / (1.0 + SQRT_TWO * c + c * c));

   zeroCoeffs[0] = -2.0 * gain;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = 2.0 * (c * c - 1.0) * gain;
   poleCoeffs[1] = ((1.0 - SQRT_TWO * c) + c * c) * gain;

   type = HIGH_PASS;
}

void Butter :: setBandPassFreq(MY_FLOAT freq)
{
   assert(type == BAND_PASS);

   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   poleCoeffs[0] = -c * d * gain;
}

void Butter :: setBandPassBandwidth(MY_FLOAT bandwidth)
{
   assert(type == BAND_PASS);

   c = 1.0 / tan((double)(bandwidth * PI / SR));

   gain = 1.0 / (1.0 + c);

   zeroCoeffs[0] = 0.0;
   zeroCoeffs[1] = -gain;

   poleCoeffs[0] = -c * d * gain;
   poleCoeffs[1] = (c - 1.0) * gain;
}

void Butter :: setBandPass(MY_FLOAT freq, MY_FLOAT bandwidth)
{
   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   type = BAND_PASS;
   setBandPassBandwidth(bandwidth);
}

void Butter :: setBandRejectFreq(MY_FLOAT freq)
{
   assert(type == BAND_REJECT);

   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   zeroCoeffs[0] = -d * gain;
   poleCoeffs[0] = zeroCoeffs[0];
}

void Butter :: setBandRejectBandwidth(MY_FLOAT bandwidth)
{
   assert(type == BAND_REJECT);

   c = tan((double)(bandwidth * PI / SR));

   gain = 1.0 / (1.0 + c);

   zeroCoeffs[0] = -d * gain;
   zeroCoeffs[1] = gain;

   poleCoeffs[0] = zeroCoeffs[0];
   poleCoeffs[1] = (1.0 - c) * gain;
}

void Butter :: setBandReject(MY_FLOAT freq, MY_FLOAT bandwidth)
{
   d = 2.0 * cos((double)(TWO_PI * freq / SR));

   type = BAND_REJECT;
   setBandRejectBandwidth(bandwidth);
}

// y0 = g x(n) + a1 x(n-1) + a2 x(n-2) + b1 y(n-1) + b2 y(n-2)
// Note: signs of b1 and b2 flipped compared to what you often see
// Note: This is the canonical form, needing only 2 history vals.

MY_FLOAT Butter :: tick(MY_FLOAT sample)
{
   MY_FLOAT temp;

   temp = sample - inputs[0] * poleCoeffs[0] - inputs[1] * poleCoeffs[1];

   lastOutput = temp * gain + inputs[0] * zeroCoeffs[0]
                            + inputs[1] * zeroCoeffs[1];
   inputs[1] = inputs[0];
   inputs[0] = temp;

   return lastOutput;
}

<|endoftext|>


<commit_before>#pragma once

#include "exceptions.hpp"
#include "list.hpp"
#include "maybe.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>

namespace imu {

  using namespace std::experimental;

  template<typename T>
  inline const std::shared_ptr<T>& nil() {
    static const std::shared_ptr<T> value;
    return value;
  }

  template<typename S>
  inline bool is_empty(const std::shared_ptr<S>& s) {
    return !s || s->is_empty();
  }

  template<typename S>
  inline auto is_seq(const std::shared_ptr<S>& s)
    -> decltype(s->first(), s->rest(), bool()) {

    return (bool) s;
  }

  template<typename S>
  inline auto seq(const std::shared_ptr<S>& s)
    -> decltype(s->first(), s->rest(), typename S::p()) {

    return s;
  }

  template<typename T, typename S>
  inline maybe<T> first(const std::shared_ptr<S>& s) {
    return !is_empty(s) ?
      maybe<T>(s->template first<T>())
      :
      maybe<T>();
  }

  template<typename S>
  inline maybe<typename S::value_type>
  first(const std::shared_ptr<S>& s) {
    return !is_empty(s) ?
      maybe<typename S::value_type>(s->first())
      :
      maybe<typename S::value_type>();
  }

  template<typename T, typename S>
  inline auto ffirst(const std::shared_ptr<S>& s)
    -> decltype(first<T, S>(first<T, S>(s))) {
    return first<T, S>(first<T, S>(s));
  }

  template<typename S>
  inline auto ffirst(const std::shared_ptr<S>& s)
    -> decltype(first<S>(first<S>(s))) {
    return first<S>(first<S>(s));
  }

  namespace sfinae {

    template<typename S>
    inline auto rest_impl_seq(const std::shared_ptr<S>& s)
      -> decltype(s->rest()) {

      return s ? s->rest() : std::shared_ptr<S>();
    }

    template<typename S>
    inline auto rest_impl(const std::shared_ptr<S>& s, int)
      -> decltype(rest_impl_seq(s)) {

      return rest_impl_seq(s);
    }

    template<typename S>
    inline auto rest_impl(const std::shared_ptr<S>& s, long)
      -> decltype(rest_impl_seq(seq(s), 0)) {

      return rest_impl_seq(seq(s));
    }
  }

  template<typename S>
  inline auto rest(const std::shared_ptr<S>& s)
    -> decltype(sfinae::rest_impl(s, 0)) {

    return sfinae::rest_impl(s, 0);
  }

  template<typename S>
  inline std::shared_ptr<S> nthrest(uint64_t n, const std::shared_ptr<S>& s) {

    auto head = s;
    auto cnt  = n;

    while (!is_empty(head) && cnt-- > 0) {
      head = rest(head);
    }

    return head;
  }

  template<typename T, typename S>
  inline maybe<T> second(const std::shared_ptr<S>& s) {
    return first<T, S>(rest(s));
  }

  template<typename T, typename S>
  inline const T& last(const std::shared_ptr<S>& s) {

    auto head = s;
    auto next = rest(head);

    while (!is_empty(next)) {
      head = next;
      next = rest(next);
    }

    return *first<T, S>(head);
  }

  template<typename T>
  inline const T& identity(const T& x) {
    return x;
  }

  template<typename S>
  inline uint64_t count(const std::shared_ptr<S>& s) {
    return s ? s->count() : 0;
  }

  template<typename T, typename S>
  inline T nth(std::shared_ptr<S>& s, uint64_t idx) {
    return s->template nth<T>(idx);
  }

  template<typename F, typename T, typename S>
  inline T reduce(
    const F& f, const T& x, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<1>::decayed arg_t;

    auto head = seq(s);
    auto out  = x;

    while (auto x = first<arg_t>(head)) {
      out  = f(out, *x);
      head = rest(head);
    }

    return out;
  }

  template<typename F, typename S>
  inline ty::list::p map(
    const F& f, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    return reduce([=](const ty::list::p& s, const arg_t& x) {
        return conj(s, f(x));
      },
      list(),
      seq(s));
  }

  template<typename F, typename S>
  inline ty::list::p filter(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    return reduce([=](const ty::list::p& s, const arg_t& x) {
        return pred(x) ? conj(s, x) : s;
      },
      list(),
      seq(s));
  }

  template<typename T, typename S>
  inline std::shared_ptr<T> into(
    const std::shared_ptr<T>& to, const std::shared_ptr<S>& from) {

    typedef typename T::value_type value_type;

    return reduce([](const std::shared_ptr<T>& s, const value_type& x) {
        return conj(s, x);
      },
      to,
      from);
  }

  template<typename T>
  inline ty::list::p take(uint64_t n, const std::shared_ptr<T>& x) {
    auto s = seq(x);
    if (n > 0 && !is_empty(s)) {
        return conj(take(n-1, rest(s), first(s)));
    }
    return nil<ty::list>();
  }

  template<typename F, typename S>
  inline std::shared_ptr<S> take_while(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto f = first<arg_t>(s);
    if (f && pred(f)) {
      return conj(take_while(pred, rest(s), f));
    }

    return nil<S>();
  }

  template<typename S>
  inline std::shared_ptr<S> drop(uint64_t n, const std::shared_ptr<S>& s) {

    auto head = seq(s);
    auto m    = n;

    while (!is_empty(head) && m-- > 0) {
      head = rest(head);
    }

    return head;
  }

  template<typename F, typename S>
  inline std::shared_ptr<S> drop_while(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto head = seq(s);

    while (!is_empty(head) && pred(first<arg_t>(head))) {
      head = rest(head);
    }

    return head;
  }

  template<typename F, typename S>
  inline bool is_every(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto head = seq(s);

    while (!is_empty(head) && pred(*first<arg_t>(head))) {
      head = rest(head);
    }

    return is_empty(head);
  }

  template<typename T, typename F, typename S>
  inline maybe<T>
  some(const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    if (is_seq(s)) {

      auto head = s;

      while (auto fst = first<arg_t>(head)) {
        if (pred(*fst)) {
          break;
        }
        head = rest(head);
      }

      return first<T>(head);
    }

    return maybe<T>();
  }

  template<typename F, typename S>
  inline auto some(const F& pred, const std::shared_ptr<S>& s)
    -> decltype(some<value, F, S>(pred, s)) {

    return some<value>(pred, s);
  }
}
<commit_msg>Don't use experimental namespace anymore<commit_after>#pragma once

#include "exceptions.hpp"
#include "list.hpp"
#include "maybe.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>

namespace imu {

  template<typename T>
  inline const std::shared_ptr<T>& nil() {
    static const std::shared_ptr<T> value;
    return value;
  }

  template<typename S>
  inline bool is_empty(const std::shared_ptr<S>& s) {
    return !s || s->is_empty();
  }

  template<typename S>
  inline auto is_seq(const std::shared_ptr<S>& s)
    -> decltype(s->first(), s->rest(), bool()) {

    return (bool) s;
  }

  template<typename S>
  inline auto seq(const std::shared_ptr<S>& s)
    -> decltype(s->first(), s->rest(), typename S::p()) {

    return s;
  }

  template<typename T, typename S>
  inline maybe<T> first(const std::shared_ptr<S>& s) {
    return !is_empty(s) ?
      maybe<T>(s->template first<T>())
      :
      maybe<T>();
  }

  template<typename S>
  inline maybe<typename S::value_type>
  first(const std::shared_ptr<S>& s) {
    return !is_empty(s) ?
      maybe<typename S::value_type>(s->first())
      :
      maybe<typename S::value_type>();
  }

  template<typename T, typename S>
  inline auto ffirst(const std::shared_ptr<S>& s)
    -> decltype(first<T, S>(first<T, S>(s))) {
    return first<T, S>(first<T, S>(s));
  }

  template<typename S>
  inline auto ffirst(const std::shared_ptr<S>& s)
    -> decltype(first<S>(first<S>(s))) {
    return first<S>(first<S>(s));
  }

  namespace sfinae {

    template<typename S>
    inline auto rest_impl_seq(const std::shared_ptr<S>& s)
      -> decltype(s->rest()) {

      return s ? s->rest() : std::shared_ptr<S>();
    }

    template<typename S>
    inline auto rest_impl(const std::shared_ptr<S>& s, int)
      -> decltype(rest_impl_seq(s)) {

      return rest_impl_seq(s);
    }

    template<typename S>
    inline auto rest_impl(const std::shared_ptr<S>& s, long)
      -> decltype(rest_impl_seq(seq(s), 0)) {

      return rest_impl_seq(seq(s));
    }
  }

  template<typename S>
  inline auto rest(const std::shared_ptr<S>& s)
    -> decltype(sfinae::rest_impl(s, 0)) {

    return sfinae::rest_impl(s, 0);
  }

  template<typename S>
  inline std::shared_ptr<S> nthrest(uint64_t n, const std::shared_ptr<S>& s) {

    auto head = s;
    auto cnt  = n;

    while (!is_empty(head) && cnt-- > 0) {
      head = rest(head);
    }

    return head;
  }

  template<typename T, typename S>
  inline maybe<T> second(const std::shared_ptr<S>& s) {
    return first<T, S>(rest(s));
  }

  template<typename T, typename S>
  inline const T& last(const std::shared_ptr<S>& s) {

    auto head = s;
    auto next = rest(head);

    while (!is_empty(next)) {
      head = next;
      next = rest(next);
    }

    return *first<T, S>(head);
  }

  template<typename T>
  inline const T& identity(const T& x) {
    return x;
  }

  template<typename S>
  inline uint64_t count(const std::shared_ptr<S>& s) {
    return s ? s->count() : 0;
  }

  template<typename T, typename S>
  inline T nth(std::shared_ptr<S>& s, uint64_t idx) {
    return s->template nth<T>(idx);
  }

  template<typename F, typename T, typename S>
  inline T reduce(
    const F& f, const T& x, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<1>::decayed arg_t;

    auto head = seq(s);
    auto out  = x;

    while (auto x = first<arg_t>(head)) {
      out  = f(out, *x);
      head = rest(head);
    }

    return out;
  }

  template<typename F, typename S>
  inline ty::list::p map(
    const F& f, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    return reduce([=](const ty::list::p& s, const arg_t& x) {
        return conj(s, f(x));
      },
      list(),
      seq(s));
  }

  template<typename F, typename S>
  inline ty::list::p filter(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    return reduce([=](const ty::list::p& s, const arg_t& x) {
        return pred(x) ? conj(s, x) : s;
      },
      list(),
      seq(s));
  }

  template<typename T, typename S>
  inline std::shared_ptr<T> into(
    const std::shared_ptr<T>& to, const std::shared_ptr<S>& from) {

    typedef typename T::value_type value_type;

    return reduce([](const std::shared_ptr<T>& s, const value_type& x) {
        return conj(s, x);
      },
      to,
      from);
  }

  template<typename T>
  inline ty::list::p take(uint64_t n, const std::shared_ptr<T>& x) {
    auto s = seq(x);
    if (n > 0 && !is_empty(s)) {
        return conj(take(n-1, rest(s), first(s)));
    }
    return nil<ty::list>();
  }

  template<typename F, typename S>
  inline std::shared_ptr<S> take_while(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto f = first<arg_t>(s);
    if (f && pred(f)) {
      return conj(take_while(pred, rest(s), f));
    }

    return nil<S>();
  }

  template<typename S>
  inline std::shared_ptr<S> drop(uint64_t n, const std::shared_ptr<S>& s) {

    auto head = seq(s);
    auto m    = n;

    while (!is_empty(head) && m-- > 0) {
      head = rest(head);
    }

    return head;
  }

  template<typename F, typename S>
  inline std::shared_ptr<S> drop_while(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto head = seq(s);

    while (!is_empty(head) && pred(first<arg_t>(head))) {
      head = rest(head);
    }

    return head;
  }

  template<typename F, typename S>
  inline bool is_every(
    const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    auto head = seq(s);

    while (!is_empty(head) && pred(*first<arg_t>(head))) {
      head = rest(head);
    }

    return is_empty(head);
  }

  template<typename T, typename F, typename S>
  inline maybe<T>
  some(const F& pred, const std::shared_ptr<S>& s) {

    typedef type_traits::lambda_traits<F> signature_t;
    typedef typename signature_t::template arg<0>::decayed arg_t;

    if (is_seq(s)) {

      auto head = s;

      while (auto fst = first<arg_t>(head)) {
        if (pred(*fst)) {
          break;
        }
        head = rest(head);
      }

      return first<T>(head);
    }

    return maybe<T>();
  }

  template<typename F, typename S>
  inline auto some(const F& pred, const std::shared_ptr<S>& s)
    -> decltype(some<value, F, S>(pred, s)) {

    return some<value>(pred, s);
  }
}
<|endoftext|>


<commit_before>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_curvature_hpp
#define eli_geom_curve_curvature_hpp

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      template<typename curve__>
      void curvature(typename curve__::data_type &rho, const curve__ &c, const typename curve__::data_type &t)
      {
        // check to make sure have valid curve
        assert(c.degree()>0);

        // check to make sure given valid parametric value
        assert((t>=0) && (t<=1));

        typename curve__::point_type xp(c.fp(t)), xpp(c.fpp(t));

        if (xp.innerSize()==2)
        {
          typename curve__::data_type tmp1(std::abs(xp(0)*xpp(1)-xp(1)*xpp(0))), tmp2(xp.norm());

          rho=tmp1/(tmp2*tmp2*tmp2);
        }
        else
        {
          typename curve__::point_type tmp1;
          typename curve__::data_type tmp2(xp.norm());

          tmp1 << (xp(1)*xpp(2)-xp(2)*xpp(1)), (xp(2)*xpp(0)-xp(0)*xpp(2)), (xp(0)*xpp(1)-xp(1)*xpp(0));
          rho=tmp1.norm()/(tmp2*tmp2*tmp2);
        }
      }
    }
  }
}
#endif
<commit_msg>Remove restriction of 0<=t<=1. Fixed #6.<commit_after>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_curvature_hpp
#define eli_geom_curve_curvature_hpp

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      template<typename curve__>
      void curvature(typename curve__::data_type &rho, const curve__ &c, const typename curve__::data_type &t)
      {
        // check to make sure have valid curve
        assert(c.degree()>0);

        typename curve__::point_type xp(c.fp(t)), xpp(c.fpp(t));

        if (xp.innerSize()==2)
        {
          typename curve__::data_type tmp1(std::abs(xp(0)*xpp(1)-xp(1)*xpp(0))), tmp2(xp.norm());

          rho=tmp1/(tmp2*tmp2*tmp2);
        }
        else
        {
          typename curve__::point_type tmp1;
          typename curve__::data_type tmp2(xp.norm());

          tmp1 << (xp(1)*xpp(2)-xp(2)*xpp(1)), (xp(2)*xpp(0)-xp(0)*xpp(2)), (xp(0)*xpp(1)-xp(1)*xpp(0));
          rho=tmp1.norm()/(tmp2*tmp2*tmp2);
        }
      }
    }
  }
}
#endif
<|endoftext|>


<commit_before>#include "MainWindow.h"

#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    resize(1200, 900);
    view = new QQuickView();
    container = QWidget::createWindowContainer(view, this);
    view->setSource(QUrl("qrc:/main.qml"));

    setCentralWidget(container);
}

MainWindow::~MainWindow()
{
}

void MainWindow::resizeEvent(QResizeEvent *ev)
{
    QMainWindow::resizeEvent(ev);
}

<commit_msg>Main window maximized<commit_after>#include "MainWindow.h"

#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    showMaximized();
    view = new QQuickView();
    container = QWidget::createWindowContainer(view, this);
    view->setSource(QUrl("qrc:/main.qml"));

    setCentralWidget(container);
}

MainWindow::~MainWindow()
{
}

void MainWindow::resizeEvent(QResizeEvent *ev)
{
    QMainWindow::resizeEvent(ev);
}

<|endoftext|>


<commit_before>#include <QtGui/QApplication>
#include "depthviewwindow.h"

int main(int argc, char *argv[]){
    QApplication a(argc, argv);

    qDebug() << "DepthView version:" << qPrintable(version::getVersionString()) << "revision:" << qPrintable(version::svn_revision);

    a.setOrganizationName("DepthView");
    a.setApplicationName("DepthView");

    DepthViewWindow w;
    w.show();

    if (argc > 1){
        if(!w.loadImage(argv[1])){
            w.showLoadImageDialog();
        }
    }
    else{
        w.showLoadImageDialog();
    }

    return a.exec();
}
<commit_msg>made the starting directory user's home path. (so the open file dialog at the start will not be in the program directory)<commit_after>#include <QtGui/QApplication>
#include "depthviewwindow.h"

int main(int argc, char *argv[]){
    QApplication a(argc, argv);

    QDir::setCurrent(QDir::homePath());

    qDebug() << "DepthView version:" << qPrintable(version::getVersionString()) << "revision:" << qPrintable(version::svn_revision);

    a.setOrganizationName("DepthView");
    a.setApplicationName("DepthView");

    DepthViewWindow w;
    w.show();

    if (argc > 1){
        if(!w.loadImage(argv[1])){
            w.showLoadImageDialog();
        }
    }
    else{
        w.showLoadImageDialog();
    }

    return a.exec();
}
<|endoftext|>


<commit_before>#include "ExampleGame/Components/GameScripts/Units/Assassin.h"
#include "ExampleGame/Components/Grid/GameGrid.h"
#include "ExampleGame/Components/Grid/GridCell.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/Components/Grid/GridNavigator.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"

#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"

#define ATTACK_SPEED 10.0f
#define SWIPE_DIST_IN_PIXELS 50.0f
#define SWIPE_DURATION_IN_SECONDS 1.0f
#define DASH_DISTANCE_IN_UNITS 6

Assassin::Assassin() : PlayerUnit() {
	this->init();
}

Assassin::Assassin(Object* object_) : PlayerUnit(object_) {
	this->init();
}

Assassin::~Assassin() {
	this->destroy();
}

void Assassin::init() {
	this->unitType = UnitType::UNIT_TYPE_ASSASSIN;
}

void Assassin::destroy() {
}

bool Assassin::isSpecialTouch(int touchId) {
	if(this->getTouchNearUnit()) {
		Touch touch = ENGINE->GetInput()->GetTouch(touchId);
		if(touch.timeDown <= SWIPE_DURATION_IN_SECONDS && glm::distance(touch.pos, this->touchStartPos) > SWIPE_DIST_IN_PIXELS) {
			this->swipeDirectionScreen = this->touchStartPos - touch.pos;
			this->targetedCell = nullptr;
			return true;
		}
	}
	return false;
}

void Assassin::onSpecialTouch(int touchId) {
	Touch touch = ENGINE->GetInput()->GetTouch(touchId);
	if(touch.phase == TouchPhase::Ended) {
		this->trySpecial(touchId);
	}
}

void Assassin::trySpecial(int /*touchId*/) {
	if(this->targetedCell != nullptr && this->targetedCell != this->gridNavRef->GetCurrentCell()) {
		this->startSpecial();
	} else {
		this->onSpecialEnd();
	}
}

void Assassin::startSpecial() {
	PlayerUnit::startSpecial();
	this->gridNavRef->SetMovementSpeed(ATTACK_SPEED);
	this->gridNavRef->SetDestination(this->targetedCell->x, this->targetedCell->z);
}

void Assassin::onSpecialEnd() {
	PlayerUnit::onSpecialEnd();
	this->gridNavRef->SetMovementSpeed(MOVE_SPEED);

}

void Assassin::touchedCellChanged() {
	if(this->inputState == InputState::INPUT_STATE_NAV) {
		PlayerUnit::touchedCellChanged();
	} else {
		std::list<GridCell*> touchedCells;
		SINGLETONS->GetGridManager()->GetGrid()->TouchedCells(this->gridNavRef->GetCurrentCell(), this->GetCurrentTouchedCell(), touchedCells);
		int elevation = SINGLETONS->GetGridManager()->GetGrid()->GetElevationFromWorldY(this->gridNavRef->GetCurrentCell()->center.y);

		for( GridCell* c : touchedCells) {
			if(SINGLETONS->GetGridManager()->GetGrid()->IsCellPassableAtElevation(c->x, c->z, elevation)) {
				this->targetedCell = c;
			} else {
				break;
			}
		}
		/*if(this->gridNavRef->CanReachDestination(this->GetCurrentTouchedCell(), DASH_DISTANCE_IN_UNITS) && SINGLETONS->GetGridManager()->GetGrid()->HasLineOfSight(this->gridNavRef->GetCurrentCell(), this->GetCurrentTouchedCell())) {//this->gridNavRef->CanReachDestination(touchedCell)) {
			this->targetedCell = this->GetCurrentTouchedCell();
		} else {
			this->targetedCell = this->gridNavRef->GetCurrentCell();
		}*/
		this->GetTouchIndicator()->GetTransform()->SetPosition(this->targetedCell->center);
		this->GetTouchIndicator()->GetTransform()->Translate(0.01f, YAXIS);
	}

}

<commit_msg>assassin takes into account his range in the dash<commit_after>#include "ExampleGame/Components/GameScripts/Units/Assassin.h"
#include "ExampleGame/Components/Grid/GameGrid.h"
#include "ExampleGame/Components/Grid/GridCell.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/Components/Grid/GridNavigator.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"

#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"

#define ATTACK_SPEED 10.0f
#define SWIPE_DIST_IN_PIXELS 50.0f
#define SWIPE_DURATION_IN_SECONDS 1.0f
#define DASH_DISTANCE_IN_UNITS 6

Assassin::Assassin() : PlayerUnit() {
	this->init();
}

Assassin::Assassin(Object* object_) : PlayerUnit(object_) {
	this->init();
}

Assassin::~Assassin() {
	this->destroy();
}

void Assassin::init() {
	this->unitType = UnitType::UNIT_TYPE_ASSASSIN;
}

void Assassin::destroy() {
}

bool Assassin::isSpecialTouch(int touchId) {
	if(this->getTouchNearUnit()) {
		Touch touch = ENGINE->GetInput()->GetTouch(touchId);
		if(touch.timeDown <= SWIPE_DURATION_IN_SECONDS && glm::distance(touch.pos, this->touchStartPos) > SWIPE_DIST_IN_PIXELS) {
			this->swipeDirectionScreen = this->touchStartPos - touch.pos;
			this->targetedCell = nullptr;
			return true;
		}
	}
	return false;
}

void Assassin::onSpecialTouch(int touchId) {
	Touch touch = ENGINE->GetInput()->GetTouch(touchId);
	if(touch.phase == TouchPhase::Ended) {
		this->trySpecial(touchId);
	}
}

void Assassin::trySpecial(int /*touchId*/) {
	if(this->targetedCell != nullptr && this->targetedCell != this->gridNavRef->GetCurrentCell()) {
		this->startSpecial();
	} else {
		this->onSpecialEnd();
	}
}

void Assassin::startSpecial() {
	PlayerUnit::startSpecial();
	this->gridNavRef->SetMovementSpeed(ATTACK_SPEED);
	this->gridNavRef->SetDestination(this->targetedCell->x, this->targetedCell->z);
}

void Assassin::onSpecialEnd() {
	PlayerUnit::onSpecialEnd();
	this->gridNavRef->SetMovementSpeed(MOVE_SPEED);

}

void Assassin::touchedCellChanged() {
	if(this->inputState == InputState::INPUT_STATE_NAV) {
		PlayerUnit::touchedCellChanged();
	} else {
		std::list<GridCell*> touchedCells;
		SINGLETONS->GetGridManager()->GetGrid()->TouchedCells(this->gridNavRef->GetCurrentCell(), this->GetCurrentTouchedCell(), touchedCells);
		int elevation = SINGLETONS->GetGridManager()->GetGrid()->GetElevationFromWorldY(this->gridNavRef->GetCurrentCell()->center.y);
		int cellIndex = 0;
		for( GridCell* c : touchedCells) {
			if(cellIndex <= DASH_DISTANCE_IN_UNITS && SINGLETONS->GetGridManager()->GetGrid()->IsCellPassableAtElevation(c->x, c->z, elevation)) {
				this->targetedCell = c;
			} else {
				break;
			}
			cellIndex++;
		}
		this->GetTouchIndicator()->GetTransform()->SetPosition(this->targetedCell->center);
		this->GetTouchIndicator()->GetTransform()->Translate(0.01f, YAXIS);
	}

}

<|endoftext|>


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

#include "base/threading/platform_thread.h"

#include <errno.h>
#include <sched.h>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
#include "base/threading/thread_local.h"
#include "base/threading/thread_restrictions.h"
#include "base/tracked_objects.h"

#if defined(OS_MACOSX)
#include <mach/mach.h>
#include <sys/resource.h>
#include <algorithm>
#endif

#if defined(OS_LINUX)
#include <dlfcn.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#endif

#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
#endif

namespace base {

#if defined(OS_MACOSX)
void InitThreading();
#endif

namespace {

#if !defined(OS_MACOSX)
// Mac name code is in in platform_thread_mac.mm.
LazyInstance<ThreadLocalPointer<char>,
             LeakyLazyInstanceTraits<ThreadLocalPointer<char> > >
    current_thread_name = LAZY_INSTANCE_INITIALIZER;
#endif

struct ThreadParams {
  PlatformThread::Delegate* delegate;
  bool joinable;
};

void* ThreadFunc(void* params) {
  ThreadParams* thread_params = static_cast<ThreadParams*>(params);
  PlatformThread::Delegate* delegate = thread_params->delegate;
  if (!thread_params->joinable)
    base::ThreadRestrictions::SetSingletonAllowed(false);
  delete thread_params;
  delegate->ThreadMain();
#if defined(OS_ANDROID)
  base::android::DetachFromVM();
#endif
  return NULL;
}

bool CreateThread(size_t stack_size, bool joinable,
                  PlatformThread::Delegate* delegate,
                  PlatformThreadHandle* thread_handle) {
#if defined(OS_MACOSX)
  base::InitThreading();
#endif  // OS_MACOSX

  bool success = false;
  pthread_attr_t attributes;
  pthread_attr_init(&attributes);

  // Pthreads are joinable by default, so only specify the detached attribute if
  // the thread should be non-joinable.
  if (!joinable) {
    pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
  }

#if defined(OS_MACOSX)
  // The Mac OS X default for a pthread stack size is 512kB.
  // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
  // DEFAULT_STACK_SIZE for this purpose.
  //
  // 512kB isn't quite generous enough for some deeply recursive threads that
  // otherwise request the default stack size by specifying 0. Here, adopt
  // glibc's behavior as on Linux, which is to use the current stack size
  // limit (ulimit -s) as the default stack size. See
  // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
  // avoid setting the limit below the Mac OS X default or the minimum usable
  // stack size, these values are also considered. If any of these values
  // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
  // stack_size is left at 0 to get the system default.
  //
  // Mac OS X normally only applies ulimit -s to the main thread stack. On
  // contemporary OS X and Linux systems alike, this value is generally 8MB
  // or in that neighborhood.
  if (stack_size == 0) {
    size_t default_stack_size;
    struct rlimit stack_rlimit;
    if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
        getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
        stack_rlimit.rlim_cur != RLIM_INFINITY) {
      stack_size = std::max(std::max(default_stack_size,
                                     static_cast<size_t>(PTHREAD_STACK_MIN)),
                            static_cast<size_t>(stack_rlimit.rlim_cur));
    }
  }
#endif  // OS_MACOSX

  if (stack_size > 0)
    pthread_attr_setstacksize(&attributes, stack_size);

  ThreadParams* params = new ThreadParams;
  params->delegate = delegate;
  params->joinable = joinable;
  success = !pthread_create(thread_handle, &attributes, ThreadFunc, params);

  pthread_attr_destroy(&attributes);
  if (!success)
    delete params;
  return success;
}

}  // namespace

// static
PlatformThreadId PlatformThread::CurrentId() {
  // Pthreads doesn't have the concept of a thread ID, so we have to reach down
  // into the kernel.
#if defined(OS_MACOSX)
  return mach_thread_self();
#elif defined(OS_LINUX)
  return syscall(__NR_gettid);
#elif defined(OS_ANDROID)
  return gettid();
#elif defined(OS_NACL) || defined(OS_SOLARIS)
  return pthread_self();
#elif defined(OS_POSIX)
  return reinterpret_cast<int64>(pthread_self());
#endif
}

// static
void PlatformThread::YieldCurrentThread() {
  sched_yield();
}

// static
void PlatformThread::Sleep(int duration_ms) {
  struct timespec sleep_time, remaining;

  // Contains the portion of duration_ms >= 1 sec.
  sleep_time.tv_sec = duration_ms / 1000;
  duration_ms -= sleep_time.tv_sec * 1000;

  // Contains the portion of duration_ms < 1 sec.
  sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.

  while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
    sleep_time = remaining;
}

// Linux SetName is currently disabled, as we need to distinguish between
// helper threads (where it's ok to make this call) and the main thread
// (where making this call renames our process, causing tools like killall
// to stop working).
#if 0 && defined(OS_LINUX)
// static
void PlatformThread::SetName(const char* name) {
  // have to cast away const because ThreadLocalPointer does not support const
  // void*
  current_thread_name.Pointer()->Set(const_cast<char*>(name));
  tracked_objects::ThreadData::InitializeThreadContext(name);

  // http://0pointer.de/blog/projects/name-your-threads.html

  // glibc recently added support for pthread_setname_np, but it's not
  // commonly available yet.  So test for it at runtime.
  int (*dynamic_pthread_setname_np)(pthread_t, const char*);
  *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
      dlsym(RTLD_DEFAULT, "pthread_setname_np");

  if (dynamic_pthread_setname_np) {
    // This limit comes from glibc, which gets it from the kernel
    // (TASK_COMM_LEN).
    const int kMaxNameLength = 15;
    std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
    int err = dynamic_pthread_setname_np(pthread_self(),
                                         shortened_name.c_str());
    if (err < 0)
      DLOG(ERROR) << "pthread_setname_np: " << safe_strerror(err);
  } else {
    // Implementing this function without glibc is simple enough.  (We
    // don't do the name length clipping as above because it will be
    // truncated by the callee (see TASK_COMM_LEN above).)
    int err = prctl(PR_SET_NAME, name);
    if (err < 0)
      DPLOG(ERROR) << "prctl(PR_SET_NAME)";
  }
}
#elif defined(OS_MACOSX)
// Mac is implemented in platform_thread_mac.mm.
#else
// static
void PlatformThread::SetName(const char* name) {
  // have to cast away const because ThreadLocalPointer does not support const
  // void*
  current_thread_name.Pointer()->Set(const_cast<char*>(name));
  tracked_objects::ThreadData::InitializeThreadContext(name);

  // (This should be relatively simple to implement for the BSDs; I
  // just don't have one handy to test the code on.)
}
#endif  // defined(OS_LINUX)

#if !defined(OS_MACOSX)
// Mac is implemented in platform_thread_mac.mm.
// static
const char* PlatformThread::GetName() {
  return current_thread_name.Pointer()->Get();
}
#endif

// static
bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
                            PlatformThreadHandle* thread_handle) {
  return CreateThread(stack_size, true /* joinable thread */,
                      delegate, thread_handle);
}

// static
bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
  PlatformThreadHandle unused;

  bool result = CreateThread(stack_size, false /* non-joinable thread */,
                             delegate, &unused);
  return result;
}

// static
void PlatformThread::Join(PlatformThreadHandle thread_handle) {
  // Joining another thread may block the current thread for a long time, since
  // the thread referred to by |thread_handle| may still be running long-lived /
  // blocking tasks.
  base::ThreadRestrictions::AssertIOAllowed();
  pthread_join(thread_handle, NULL);
}

#if !defined(OS_MACOSX)
// Mac OS X uses lower-level mach APIs

// static
void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) {
  // TODO(crogers): implement
  NOTIMPLEMENTED();
}
#endif

}  // namespace base
<commit_msg>Enable setting thread names on Linux<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/platform_thread.h"

#include <errno.h>
#include <sched.h>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
#include "base/threading/thread_local.h"
#include "base/threading/thread_restrictions.h"
#include "base/tracked_objects.h"

#if defined(OS_MACOSX)
#include <mach/mach.h>
#include <sys/resource.h>
#include <algorithm>
#endif

#if defined(OS_LINUX)
#include <dlfcn.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#endif

#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
#endif

namespace base {

#if defined(OS_MACOSX)
void InitThreading();
#endif

namespace {

#if !defined(OS_MACOSX)
// Mac name code is in in platform_thread_mac.mm.
LazyInstance<ThreadLocalPointer<char>,
             LeakyLazyInstanceTraits<ThreadLocalPointer<char> > >
    current_thread_name = LAZY_INSTANCE_INITIALIZER;
#endif

struct ThreadParams {
  PlatformThread::Delegate* delegate;
  bool joinable;
};

void* ThreadFunc(void* params) {
  ThreadParams* thread_params = static_cast<ThreadParams*>(params);
  PlatformThread::Delegate* delegate = thread_params->delegate;
  if (!thread_params->joinable)
    base::ThreadRestrictions::SetSingletonAllowed(false);
  delete thread_params;
  delegate->ThreadMain();
#if defined(OS_ANDROID)
  base::android::DetachFromVM();
#endif
  return NULL;
}

bool CreateThread(size_t stack_size, bool joinable,
                  PlatformThread::Delegate* delegate,
                  PlatformThreadHandle* thread_handle) {
#if defined(OS_MACOSX)
  base::InitThreading();
#endif  // OS_MACOSX

  bool success = false;
  pthread_attr_t attributes;
  pthread_attr_init(&attributes);

  // Pthreads are joinable by default, so only specify the detached attribute if
  // the thread should be non-joinable.
  if (!joinable) {
    pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
  }

#if defined(OS_MACOSX)
  // The Mac OS X default for a pthread stack size is 512kB.
  // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
  // DEFAULT_STACK_SIZE for this purpose.
  //
  // 512kB isn't quite generous enough for some deeply recursive threads that
  // otherwise request the default stack size by specifying 0. Here, adopt
  // glibc's behavior as on Linux, which is to use the current stack size
  // limit (ulimit -s) as the default stack size. See
  // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
  // avoid setting the limit below the Mac OS X default or the minimum usable
  // stack size, these values are also considered. If any of these values
  // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
  // stack_size is left at 0 to get the system default.
  //
  // Mac OS X normally only applies ulimit -s to the main thread stack. On
  // contemporary OS X and Linux systems alike, this value is generally 8MB
  // or in that neighborhood.
  if (stack_size == 0) {
    size_t default_stack_size;
    struct rlimit stack_rlimit;
    if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
        getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
        stack_rlimit.rlim_cur != RLIM_INFINITY) {
      stack_size = std::max(std::max(default_stack_size,
                                     static_cast<size_t>(PTHREAD_STACK_MIN)),
                            static_cast<size_t>(stack_rlimit.rlim_cur));
    }
  }
#endif  // OS_MACOSX

  if (stack_size > 0)
    pthread_attr_setstacksize(&attributes, stack_size);

  ThreadParams* params = new ThreadParams;
  params->delegate = delegate;
  params->joinable = joinable;
  success = !pthread_create(thread_handle, &attributes, ThreadFunc, params);

  pthread_attr_destroy(&attributes);
  if (!success)
    delete params;
  return success;
}

}  // namespace

// static
PlatformThreadId PlatformThread::CurrentId() {
  // Pthreads doesn't have the concept of a thread ID, so we have to reach down
  // into the kernel.
#if defined(OS_MACOSX)
  return mach_thread_self();
#elif defined(OS_LINUX)
  return syscall(__NR_gettid);
#elif defined(OS_ANDROID)
  return gettid();
#elif defined(OS_NACL) || defined(OS_SOLARIS)
  return pthread_self();
#elif defined(OS_POSIX)
  return reinterpret_cast<int64>(pthread_self());
#endif
}

// static
void PlatformThread::YieldCurrentThread() {
  sched_yield();
}

// static
void PlatformThread::Sleep(int duration_ms) {
  struct timespec sleep_time, remaining;

  // Contains the portion of duration_ms >= 1 sec.
  sleep_time.tv_sec = duration_ms / 1000;
  duration_ms -= sleep_time.tv_sec * 1000;

  // Contains the portion of duration_ms < 1 sec.
  sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.

  while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
    sleep_time = remaining;
}

#if defined(OS_LINUX)
// static
void PlatformThread::SetName(const char* name) {
  // have to cast away const because ThreadLocalPointer does not support const
  // void*
  current_thread_name.Pointer()->Set(const_cast<char*>(name));
  tracked_objects::ThreadData::InitializeThreadContext(name);

  // On linux we can get the thread names to show up in the debugger by setting
  // the process name for the LWP.  We don't want to do this for the main
  // thread because that would rename the process, causing tools like killall
  // to stop working.
  if (PlatformThread::CurrentId() == getpid())
    return;

  // http://0pointer.de/blog/projects/name-your-threads.html

  // glibc recently added support for pthread_setname_np, but it's not
  // commonly available yet.  So test for it at runtime.
  int (*dynamic_pthread_setname_np)(pthread_t, const char*);
  *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
      dlsym(RTLD_DEFAULT, "pthread_setname_np");

  if (dynamic_pthread_setname_np) {
    // This limit comes from glibc, which gets it from the kernel
    // (TASK_COMM_LEN).
    const int kMaxNameLength = 15;
    std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
    int err = dynamic_pthread_setname_np(pthread_self(),
                                         shortened_name.c_str());
    if (err < 0)
      DLOG(ERROR) << "pthread_setname_np: " << safe_strerror(err);
  } else {
    // Implementing this function without glibc is simple enough.  (We
    // don't do the name length clipping as above because it will be
    // truncated by the callee (see TASK_COMM_LEN above).)
    int err = prctl(PR_SET_NAME, name);
    if (err < 0)
      DPLOG(ERROR) << "prctl(PR_SET_NAME)";
  }
}
#elif defined(OS_MACOSX)
// Mac is implemented in platform_thread_mac.mm.
#else
// static
void PlatformThread::SetName(const char* name) {
  // have to cast away const because ThreadLocalPointer does not support const
  // void*
  current_thread_name.Pointer()->Set(const_cast<char*>(name));
  tracked_objects::ThreadData::InitializeThreadContext(name);

  // (This should be relatively simple to implement for the BSDs; I
  // just don't have one handy to test the code on.)
}
#endif  // defined(OS_LINUX)

#if !defined(OS_MACOSX)
// Mac is implemented in platform_thread_mac.mm.
// static
const char* PlatformThread::GetName() {
  return current_thread_name.Pointer()->Get();
}
#endif

// static
bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
                            PlatformThreadHandle* thread_handle) {
  return CreateThread(stack_size, true /* joinable thread */,
                      delegate, thread_handle);
}

// static
bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
  PlatformThreadHandle unused;

  bool result = CreateThread(stack_size, false /* non-joinable thread */,
                             delegate, &unused);
  return result;
}

// static
void PlatformThread::Join(PlatformThreadHandle thread_handle) {
  // Joining another thread may block the current thread for a long time, since
  // the thread referred to by |thread_handle| may still be running long-lived /
  // blocking tasks.
  base::ThreadRestrictions::AssertIOAllowed();
  pthread_join(thread_handle, NULL);
}

#if !defined(OS_MACOSX)
// Mac OS X uses lower-level mach APIs

// static
void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) {
  // TODO(crogers): implement
  NOTIMPLEMENTED();
}
#endif

}  // namespace base
<|endoftext|>


<commit_before>/*

Copyright (c) 2006, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef NODE_HPP
#define NODE_HPP

#include <algorithm>
#include <map>
#include <set>

#include <libtorrent/kademlia/routing_table.hpp>
#include <libtorrent/kademlia/rpc_manager.hpp>
#include <libtorrent/kademlia/node_id.hpp>
#include <libtorrent/kademlia/msg.hpp>
#include <libtorrent/kademlia/find_data.hpp>

#include <libtorrent/io.hpp>
#include <libtorrent/session_settings.hpp>
#include <libtorrent/assert.hpp>
#include <libtorrent/thread.hpp>

#include <boost/cstdint.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/ref.hpp>
#include <boost/optional.hpp>

#include "libtorrent/socket.hpp"

namespace libtorrent {

	namespace aux { struct session_impl; }
	struct session_status;

}

namespace libtorrent { namespace dht
{

#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_DECLARE_LOG(node);
#endif

class traversal_algorithm;

struct key_desc_t
{
	char const* name;
	int type;
	int size;
	int flags;

	enum { optional = 1};
};

bool TORRENT_EXPORT verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry const* ret[]
	, int size , char* error, int error_size);

// this is the entry for every peer
// the timestamp is there to make it possible
// to remove stale peers
struct peer_entry
{
	tcp::endpoint addr;
	ptime added;
};

// this is a group. It contains a set of group members
struct torrent_entry
{
	std::set<peer_entry> peers;
};

// this is the entry for a torrent that has been published
// in the DHT.
struct search_torrent_entry
{
	// the tags of the torrent. The key of
	// this entry is the sha-1 hash of one of
	// these tags. The counter is the number of
	// times a tag has been included in a publish
	// call. The counters are periodically
	// decremented by a factor, so that the
	// popularity ratio between the tags is
	// maintained. The decrement is rounded down.
	std::map<std::string, int> tags;

	// this is the sum of all values in the tags
	// map. It is only an optimization to avoid
	// recalculating it constantly
	int total_tag_points;

	// the name of the torrent
	std::map<std::string, int> name;
	int total_name_points;

	// increase the popularity counters for this torrent
	void publish(std::string const& name, char const* in_tags[], int num_tags);

	// return a score of how well this torrent matches
	// the given set of tags. Each word in the string
	// (separated by a space) is considered a tag.
	// tags with 2 letters or fewer are ignored
	int match(char const* tags[], int num_tags) const;

	// this is called once every hour, and will
	// decrement the popularity counters of the
	// tags. Returns true if this entry should
	// be deleted
	bool tick();

	void get_name(std::string& t) const;
	void get_tags(std::string& t) const;
};

inline bool operator<(peer_entry const& lhs, peer_entry const& rhs)
{
	return lhs.addr.address() == rhs.addr.address()
		? lhs.addr.port() < rhs.addr.port()
		: lhs.addr.address() < rhs.addr.address();
}

struct null_type {};

class announce_observer : public observer
{
public:
	announce_observer(boost::intrusive_ptr<traversal_algorithm> const& algo)
		: observer(algo)
	{}

	void reply(msg const&) { m_done = true; }
};

struct count_peers
{
	int& count;
	count_peers(int& c): count(c) {}
	void operator()(std::pair<libtorrent::dht::node_id
		, libtorrent::dht::torrent_entry> const& t)
	{
		count += t.second.peers.size();
	}
};

class node_impl : boost::noncopyable
{
typedef std::map<node_id, torrent_entry> table_t;
typedef std::map<std::pair<node_id, sha1_hash>, search_torrent_entry> search_table_t;
public:
	node_impl(libtorrent::aux::session_impl& ses
		, bool (*f)(void*, entry const&, udp::endpoint const&, int)
		, dht_settings const& settings, boost::optional<node_id> nid
		, void* userdata);

	virtual ~node_impl() {}

	void refresh(node_id const& id, find_data::nodes_callback const& f);
	void bootstrap(std::vector<udp::endpoint> const& nodes
		, find_data::nodes_callback const& f);
	void add_router_node(udp::endpoint router);

	void unreachable(udp::endpoint const& ep);
	void incoming(msg const& m);

	int num_torrents() const { return m_map.size(); }
	int num_peers() const
	{
		int ret = 0;
		std::for_each(m_map.begin(), m_map.end(), count_peers(ret));
		return ret;
	}

	void refresh();
	void refresh_bucket(int bucket);
	int bucket_size(int bucket);

	typedef routing_table::iterator iterator;

	iterator begin() const { return m_table.begin(); }
	iterator end() const { return m_table.end(); }

	node_id const& nid() const { return m_id; }

	boost::tuple<int, int> size() const{ return m_table.size(); }
	size_type num_global_nodes() const
	{ return m_table.num_global_nodes(); }

	int data_size() const { return int(m_map.size()); }

#ifdef TORRENT_DHT_VERBOSE_LOGGING
	void print_state(std::ostream& os) const
	{ m_table.print_state(os); }
#endif

	void announce(sha1_hash const& info_hash, int listen_port
		, boost::function<void(std::vector<tcp::endpoint> const&)> f);

	bool verify_token(std::string const& token, char const* info_hash
		, udp::endpoint const& addr);

	std::string generate_token(udp::endpoint const& addr, char const* info_hash);

	// the returned time is the delay until connection_timeout()
	// should be called again the next time
	time_duration connection_timeout();
	time_duration refresh_timeout();

	// generates a new secret number used to generate write tokens
	void new_write_key();

	// pings the given node, and adds it to
	// the routing table if it respons and if the
	// bucket is not full.
	void add_node(udp::endpoint node);

	void replacement_cache(bucket_t& nodes) const
	{ m_table.replacement_cache(nodes); }

	int branch_factor() const { return m_settings.search_branching; }

	void add_traversal_algorithm(traversal_algorithm* a)
	{
		mutex_t::scoped_lock l(m_mutex);
		m_running_requests.insert(a);
	}

	void remove_traversal_algorithm(traversal_algorithm* a)
	{
		mutex_t::scoped_lock l(m_mutex);
		m_running_requests.erase(a);
	}

	void status(libtorrent::session_status& s);

protected:
	// is called when a find data request is received. Should
	// return false if the data is not stored on this node. If
	// the data is stored, it should be serialized into 'data'.
	bool lookup_peers(sha1_hash const& info_hash, entry& reply) const;
	bool lookup_torrents(sha1_hash const& target, entry& reply
		, char* tags) const;

	dht_settings const& m_settings;

	// the maximum number of peers to send in a get_peers
	// reply. Ordinary trackers usually limit this to 50.
	// 50 => 6 * 50 = 250 bytes + packet overhead
	int m_max_peers_reply;

private:
	typedef libtorrent::mutex mutex_t;
	mutex_t m_mutex;

	// this list must be destructed after the rpc manager
	// since it might have references to it
	std::set<traversal_algorithm*> m_running_requests;

	void incoming_request(msg const& h, entry& e);

	node_id m_id;

public:
	routing_table m_table;
	rpc_manager m_rpc;

private:
	table_t m_map;
	search_table_t m_search_map;

	ptime m_last_tracker_tick;

	// secret random numbers used to create write tokens
	int m_secret[2];

	libtorrent::aux::session_impl& m_ses;
	bool (*m_send)(void*, entry const&, udp::endpoint const&, int);
	void* m_userdata;
};

} } // namespace libtorrent::dht

#endif // NODE_HPP

<commit_msg>dht fix<commit_after>/*

Copyright (c) 2006, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef NODE_HPP
#define NODE_HPP

#include <algorithm>
#include <map>
#include <set>

#include <libtorrent/kademlia/routing_table.hpp>
#include <libtorrent/kademlia/rpc_manager.hpp>
#include <libtorrent/kademlia/node_id.hpp>
#include <libtorrent/kademlia/msg.hpp>
#include <libtorrent/kademlia/find_data.hpp>

#include <libtorrent/io.hpp>
#include <libtorrent/session_settings.hpp>
#include <libtorrent/assert.hpp>
#include <libtorrent/thread.hpp>

#include <boost/cstdint.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/ref.hpp>
#include <boost/optional.hpp>

#include "libtorrent/socket.hpp"

namespace libtorrent {

	namespace aux { struct session_impl; }
	struct session_status;

}

namespace libtorrent { namespace dht
{

#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_DECLARE_LOG(node);
#endif

class traversal_algorithm;

struct key_desc_t
{
	char const* name;
	int type;
	int size;
	int flags;

	enum { optional = 1};
};

bool TORRENT_EXPORT verify_message(lazy_entry const* msg, key_desc_t const desc[], lazy_entry const* ret[]
	, int size , char* error, int error_size);

// this is the entry for every peer
// the timestamp is there to make it possible
// to remove stale peers
struct peer_entry
{
	tcp::endpoint addr;
	ptime added;
};

// this is a group. It contains a set of group members
struct torrent_entry
{
	std::set<peer_entry> peers;
};

// this is the entry for a torrent that has been published
// in the DHT.
struct search_torrent_entry
{
	search_torrent_entry(): total_tag_points(0), total_name_points(0) {}

	// the tags of the torrent. The key of
	// this entry is the sha-1 hash of one of
	// these tags. The counter is the number of
	// times a tag has been included in a publish
	// call. The counters are periodically
	// decremented by a factor, so that the
	// popularity ratio between the tags is
	// maintained. The decrement is rounded down.
	std::map<std::string, int> tags;

	// this is the sum of all values in the tags
	// map. It is only an optimization to avoid
	// recalculating it constantly
	int total_tag_points;

	// the name of the torrent
	std::map<std::string, int> name;
	int total_name_points;

	// increase the popularity counters for this torrent
	void publish(std::string const& name, char const* in_tags[], int num_tags);

	// return a score of how well this torrent matches
	// the given set of tags. Each word in the string
	// (separated by a space) is considered a tag.
	// tags with 2 letters or fewer are ignored
	int match(char const* tags[], int num_tags) const;

	// this is called once every hour, and will
	// decrement the popularity counters of the
	// tags. Returns true if this entry should
	// be deleted
	bool tick();

	void get_name(std::string& t) const;
	void get_tags(std::string& t) const;
};

inline bool operator<(peer_entry const& lhs, peer_entry const& rhs)
{
	return lhs.addr.address() == rhs.addr.address()
		? lhs.addr.port() < rhs.addr.port()
		: lhs.addr.address() < rhs.addr.address();
}

struct null_type {};

class announce_observer : public observer
{
public:
	announce_observer(boost::intrusive_ptr<traversal_algorithm> const& algo)
		: observer(algo)
	{}

	void reply(msg const&) { m_done = true; }
};

struct count_peers
{
	int& count;
	count_peers(int& c): count(c) {}
	void operator()(std::pair<libtorrent::dht::node_id
		, libtorrent::dht::torrent_entry> const& t)
	{
		count += t.second.peers.size();
	}
};

class node_impl : boost::noncopyable
{
typedef std::map<node_id, torrent_entry> table_t;
typedef std::map<std::pair<node_id, sha1_hash>, search_torrent_entry> search_table_t;
public:
	node_impl(libtorrent::aux::session_impl& ses
		, bool (*f)(void*, entry const&, udp::endpoint const&, int)
		, dht_settings const& settings, boost::optional<node_id> nid
		, void* userdata);

	virtual ~node_impl() {}

	void refresh(node_id const& id, find_data::nodes_callback const& f);
	void bootstrap(std::vector<udp::endpoint> const& nodes
		, find_data::nodes_callback const& f);
	void add_router_node(udp::endpoint router);

	void unreachable(udp::endpoint const& ep);
	void incoming(msg const& m);

	int num_torrents() const { return m_map.size(); }
	int num_peers() const
	{
		int ret = 0;
		std::for_each(m_map.begin(), m_map.end(), count_peers(ret));
		return ret;
	}

	void refresh();
	void refresh_bucket(int bucket);
	int bucket_size(int bucket);

	typedef routing_table::iterator iterator;

	iterator begin() const { return m_table.begin(); }
	iterator end() const { return m_table.end(); }

	node_id const& nid() const { return m_id; }

	boost::tuple<int, int> size() const{ return m_table.size(); }
	size_type num_global_nodes() const
	{ return m_table.num_global_nodes(); }

	int data_size() const { return int(m_map.size()); }

#ifdef TORRENT_DHT_VERBOSE_LOGGING
	void print_state(std::ostream& os) const
	{ m_table.print_state(os); }
#endif

	void announce(sha1_hash const& info_hash, int listen_port
		, boost::function<void(std::vector<tcp::endpoint> const&)> f);

	bool verify_token(std::string const& token, char const* info_hash
		, udp::endpoint const& addr);

	std::string generate_token(udp::endpoint const& addr, char const* info_hash);

	// the returned time is the delay until connection_timeout()
	// should be called again the next time
	time_duration connection_timeout();
	time_duration refresh_timeout();

	// generates a new secret number used to generate write tokens
	void new_write_key();

	// pings the given node, and adds it to
	// the routing table if it respons and if the
	// bucket is not full.
	void add_node(udp::endpoint node);

	void replacement_cache(bucket_t& nodes) const
	{ m_table.replacement_cache(nodes); }

	int branch_factor() const { return m_settings.search_branching; }

	void add_traversal_algorithm(traversal_algorithm* a)
	{
		mutex_t::scoped_lock l(m_mutex);
		m_running_requests.insert(a);
	}

	void remove_traversal_algorithm(traversal_algorithm* a)
	{
		mutex_t::scoped_lock l(m_mutex);
		m_running_requests.erase(a);
	}

	void status(libtorrent::session_status& s);

protected:
	// is called when a find data request is received. Should
	// return false if the data is not stored on this node. If
	// the data is stored, it should be serialized into 'data'.
	bool lookup_peers(sha1_hash const& info_hash, entry& reply) const;
	bool lookup_torrents(sha1_hash const& target, entry& reply
		, char* tags) const;

	dht_settings const& m_settings;

	// the maximum number of peers to send in a get_peers
	// reply. Ordinary trackers usually limit this to 50.
	// 50 => 6 * 50 = 250 bytes + packet overhead
	int m_max_peers_reply;

private:
	typedef libtorrent::mutex mutex_t;
	mutex_t m_mutex;

	// this list must be destructed after the rpc manager
	// since it might have references to it
	std::set<traversal_algorithm*> m_running_requests;

	void incoming_request(msg const& h, entry& e);

	node_id m_id;

public:
	routing_table m_table;
	rpc_manager m_rpc;

private:
	table_t m_map;
	search_table_t m_search_map;

	ptime m_last_tracker_tick;

	// secret random numbers used to create write tokens
	int m_secret[2];

	libtorrent::aux::session_impl& m_ses;
	bool (*m_send)(void*, entry const&, udp::endpoint const&, int);
	void* m_userdata;
};

} } // namespace libtorrent::dht

#endif // NODE_HPP

<|endoftext|>