<commit_before>//===--- Stubs.cpp - Swift Language ABI Runtime Stubs ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Misc stubs for functions which should be defined in the core standard
// library, but are difficult or impossible to write in Swift at the
// moment.
//
//===----------------------------------------------------------------------===//

#if defined(__FreeBSD__)
#define _WITH_GETLINE
#endif

#include <sys/resource.h>
#include <sys/errno.h>
#include <unistd.h>
#include <climits>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <xlocale.h>
#include <limits>
#include "llvm/ADT/StringExtras.h"
#include "swift/Runtime/Debug.h"
#include "swift/Basic/Lazy.h"

static uint64_t uint64ToStringImpl(char *Buffer, uint64_t Value,
                                   int64_t Radix, bool Uppercase,
                                   bool Negative) {
  char *P = Buffer;
  uint64_t Y = Value;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !Uppercase);
      Y /= Radix32;
    }
  }

  if (Negative)
    *P++ = '-';
  std::reverse(Buffer, P);
  return size_t(P - Buffer);
}

extern "C" uint64_t swift_int64ToString(char *Buffer, size_t BufferLength,
                                        int64_t Value, int64_t Radix,
                                        bool Uppercase) {
  if ((Radix >= 10 && BufferLength < 32) || (Radix < 10 && BufferLength < 65))
    swift::crash("swift_int64ToString: insufficient buffer size");

  if (Radix == 0 || Radix > 36)
    swift::crash("swift_int64ToString: invalid radix for string conversion");

  bool Negative = Value < 0;

  // Compute an absolute value safely, without using unary negation on INT_MIN,
  // which is undefined behavior.
  uint64_t UnsignedValue = Value;
  if (Negative) {
    // Assumes two's complement representation.
    UnsignedValue = ~UnsignedValue + 1;
  }

  return uint64ToStringImpl(Buffer, UnsignedValue, Radix, Uppercase,
                            Negative);
}

extern "C" uint64_t swift_uint64ToString(char *Buffer, intptr_t BufferLength,
                                         uint64_t Value, int64_t Radix,
                                         bool Uppercase) {
  if ((Radix >= 10 && BufferLength < 32) || (Radix < 10 && BufferLength < 64))
    swift::crash("swift_int64ToString: insufficient buffer size");

  if (Radix == 0 || Radix > 36)
    swift::crash("swift_int64ToString: invalid radix for string conversion");

  return uint64ToStringImpl(Buffer, Value, Radix, Uppercase,
                            /*Negative=*/false);
}

#if defined(__APPLE__) || defined(__FreeBSD__)
static inline locale_t getCLocale() {
  // On these platforms convenience functions from xlocale.h interpret nullptr
  // as C locale.
  return nullptr;
}
#else
static locale_t makeCLocale() {
  locale_t CLocale = newlocale(LC_ALL_MASK, "C", nullptr);
  if (!CLocale) {
    swift::crash("makeCLocale: newlocale() returned a null pointer");
  }
  return CLocale;
}

static locale_t getCLocale() {
  return SWIFT_LAZY_CONSTANT(makeCLocale());
}
#endif

#if defined(__APPLE__)
#define swift_snprintf_l snprintf_l
#else
static int swift_snprintf_l(char *Str, size_t StrSize, locale_t Locale,
                            const char *Format, ...) {
  if (Locale == nullptr) {
    Locale = getCLocale();
  }
  locale_t OldLocale = uselocale(Locale);

  va_list Args;
  va_start(Args, Format);
  int Result = std::vsnprintf(Str, StrSize, Format, Args);
  va_end(Args);

  uselocale(OldLocale);

  return Result;
}
#endif

template <typename T>
static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength,
                                            T Value, const char *Format) {
  if (BufferLength < 32)
    swift::crash("swift_floatingPointToString: insufficient buffer size");

  const int Precision = std::numeric_limits<T>::digits10;

  // Pass a null locale to use the C locale.
  int i = swift_snprintf_l(Buffer, BufferLength, /*locale=*/nullptr, Format,
                           Precision, Value);

  if (i < 0)
    swift::crash(
        "swift_floatingPointToString: unexpected return value from sprintf");
  if (size_t(i) >= BufferLength)
    swift::crash("swift_floatingPointToString: insufficient buffer size");

  // Add ".0" to a float that (a) is not in scientific notation, (b) does not
  // already have a fractional part, (c) is not infinite, and (d) is not a NaN
  // value.
  if (strchr(Buffer, 'e') == nullptr && strchr(Buffer, '.') == nullptr &&
      strchr(Buffer, 'n') == nullptr) {
    Buffer[i++] = '.';
    Buffer[i++] = '0';
  }

  return i;
}

extern "C" uint64_t swift_float32ToString(char *Buffer, size_t BufferLength,
                                          float Value) {
  return swift_floatingPointToString<float>(Buffer, BufferLength, Value,
                                            "%0.*g");
}

extern "C" uint64_t swift_float64ToString(char *Buffer, size_t BufferLength,
                                          double Value) {
  return swift_floatingPointToString<double>(Buffer, BufferLength, Value,
                                             "%0.*g");
}

extern "C" uint64_t swift_float80ToString(char *Buffer, size_t BufferLength,
                                          long double Value) {
  return swift_floatingPointToString<long double>(Buffer, BufferLength, Value,
                                                  "%0.*Lg");
}

/// \param[out] LinePtr Replaced with the pointer to the malloc()-allocated
/// line.  Can be NULL if no characters were read.
///
/// \returns Size of character data returned in \c LinePtr, or -1
/// if an error occurred, or EOF was reached.
extern "C" ssize_t swift_stdlib_readLine_stdin(char **LinePtr) {
  size_t Capacity = 0;
  return getline(LinePtr, &Capacity, stdin);
}

extern "C" float _swift_fmodf(float lhs, float rhs) {
    return fmodf(lhs, rhs);
}

extern "C" double _swift_fmod(double lhs, double rhs) {
    return fmod(lhs, rhs);
}

extern "C" long double _swift_fmodl(long double lhs, long double rhs) {
    return fmodl(lhs, rhs);
}

// Although this builtin is provided by clang rt builtins,
// it isn't provided by libgcc, which is the default
// runtime library on Linux, even when compiling with clang.
// This implementation is copied here to avoid a new dependency
// on compiler-rt on Linux.
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4
#if (defined(__APPLE__) && defined(__arm64__)) || \
    (defined(__linux__) && defined(__x86_64__))

typedef int      ti_int __attribute__ ((mode (TI)));
extern "C"
ti_int
__muloti4(ti_int a, ti_int b, int* overflow)
{
    const int N = (int)(sizeof(ti_int) * CHAR_BIT);
    const ti_int MIN = (ti_int)1 << (N-1);
    const ti_int MAX = ~MIN;
    *overflow = 0;
    ti_int result = a * b;
    if (a == MIN)
    {
        if (b != 0 && b != 1)
	    *overflow = 1;
	return result;
    }
    if (b == MIN)
    {
        if (a != 0 && a != 1)
	    *overflow = 1;
        return result;
    }
    ti_int sa = a >> (N - 1);
    ti_int abs_a = (a ^ sa) - sa;
    ti_int sb = b >> (N - 1);
    ti_int abs_b = (b ^ sb) - sb;
    if (abs_a < 2 || abs_b < 2)
        return result;
    if (sa == sb)
    {
        if (abs_a > MAX / abs_b)
            *overflow = 1;
    }
    else
    {
        if (abs_a > MIN / -abs_b)
            *overflow = 1;
    }
    return result;
}

#endif

#if defined(__linux__) && defined(__arm__)
// Similar to above, but with mulodi4.  Perhaps this is
// something that shouldn't be done, and is a bandaid over
// some other lower-level architecture issue that I'm
// missing.  Perhaps relevant bug report:
// FIXME: https://llvm.org/bugs/show_bug.cgi?id=14469
typedef int      di_int __attribute__ ((mode (DI)));
extern "C"
di_int
__mulodi4(di_int a, di_int b, int* overflow)
{
    const int N = (int)(sizeof(di_int) * CHAR_BIT);
    const di_int MIN = (di_int)1 << (N-1);
    const di_int MAX = ~MIN;
    *overflow = 0;
    di_int result = a * b;
    if (a == MIN)
    {
        if (b != 0 && b != 1)
            *overflow = 1;
        return result;
    }
    if (b == MIN)
    {
        if (a != 0 && a != 1)
            *overflow = 1;
        return result;
    }
    di_int sa = a >> (N - 1);
    di_int abs_a = (a ^ sa) - sa;
    di_int sb = b >> (N - 1);
    di_int abs_b = (b ^ sb) - sb;
    if (abs_a < 2 || abs_b < 2)
        return result;
    if (sa == sb)
    {
        if (abs_a > MAX / abs_b)
            *overflow = 1;
    }
    else
    {
        if (abs_a > MIN / -abs_b)
            *overflow = 1;
    }
    return result;
}
#endif

// We can't return Float80, but we can receive a pointer to one, so
// switch the return type and the out parameter on strtold.
template <typename T>
static const char *_swift_stdlib_strtoX_clocale_impl(
    const char * nptr, T* outResult, T huge,
    T (*posixImpl)(const char *, char **, locale_t)
) {
  char *EndPtr;
  errno = 0;
  const auto result = posixImpl(nptr, &EndPtr, getCLocale());
  *outResult = result;
  if (result == huge || result == -huge || result == 0.0 || result == -0.0) {
      if (errno == ERANGE)
          EndPtr = NULL;
  }
  return EndPtr;
}

extern "C" const char *_swift_stdlib_strtold_clocale(
  const char * nptr, void *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, static_cast<long double*>(outResult), HUGE_VALL, strtold_l);
}

extern "C" const char *_swift_stdlib_strtod_clocale(
    const char * nptr, double *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, outResult, HUGE_VAL, strtod_l);
}

extern "C" const char *_swift_stdlib_strtof_clocale(
    const char * nptr, float *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, outResult, HUGE_VALF, strtof_l);
}

extern "C" void _swift_stdlib_flockfile_stdout() {
  flockfile(stdout);
}

extern "C" void _swift_stdlib_funlockfile_stdout() {
  funlockfile(stdout);
}

extern "C" int _swift_stdlib_putc_stderr(int C) {
  return putc(C, stderr);
}

extern "C" size_t _swift_stdlib_getHardwareConcurrency() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}
<commit_msg>Fix precision of float to string to max significant decimals<commit_after>//===--- Stubs.cpp - Swift Language ABI Runtime Stubs ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Misc stubs for functions which should be defined in the core standard
// library, but are difficult or impossible to write in Swift at the
// moment.
//
//===----------------------------------------------------------------------===//

#if defined(__FreeBSD__)
#define _WITH_GETLINE
#endif

#include <sys/resource.h>
#include <sys/errno.h>
#include <unistd.h>
#include <climits>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <xlocale.h>
#include <limits>
#include "llvm/ADT/StringExtras.h"
#include "swift/Runtime/Debug.h"
#include "swift/Basic/Lazy.h"

static uint64_t uint64ToStringImpl(char *Buffer, uint64_t Value,
                                   int64_t Radix, bool Uppercase,
                                   bool Negative) {
  char *P = Buffer;
  uint64_t Y = Value;

  if (Y == 0) {
    *P++ = '0';
  } else if (Radix == 10) {
    while (Y) {
      *P++ = '0' + char(Y % 10);
      Y /= 10;
    }
  } else {
    unsigned Radix32 = Radix;
    while (Y) {
      *P++ = llvm::hexdigit(Y % Radix32, !Uppercase);
      Y /= Radix32;
    }
  }

  if (Negative)
    *P++ = '-';
  std::reverse(Buffer, P);
  return size_t(P - Buffer);
}

extern "C" uint64_t swift_int64ToString(char *Buffer, size_t BufferLength,
                                        int64_t Value, int64_t Radix,
                                        bool Uppercase) {
  if ((Radix >= 10 && BufferLength < 32) || (Radix < 10 && BufferLength < 65))
    swift::crash("swift_int64ToString: insufficient buffer size");

  if (Radix == 0 || Radix > 36)
    swift::crash("swift_int64ToString: invalid radix for string conversion");

  bool Negative = Value < 0;

  // Compute an absolute value safely, without using unary negation on INT_MIN,
  // which is undefined behavior.
  uint64_t UnsignedValue = Value;
  if (Negative) {
    // Assumes two's complement representation.
    UnsignedValue = ~UnsignedValue + 1;
  }

  return uint64ToStringImpl(Buffer, UnsignedValue, Radix, Uppercase,
                            Negative);
}

extern "C" uint64_t swift_uint64ToString(char *Buffer, intptr_t BufferLength,
                                         uint64_t Value, int64_t Radix,
                                         bool Uppercase) {
  if ((Radix >= 10 && BufferLength < 32) || (Radix < 10 && BufferLength < 64))
    swift::crash("swift_int64ToString: insufficient buffer size");

  if (Radix == 0 || Radix > 36)
    swift::crash("swift_int64ToString: invalid radix for string conversion");

  return uint64ToStringImpl(Buffer, Value, Radix, Uppercase,
                            /*Negative=*/false);
}

#if defined(__APPLE__) || defined(__FreeBSD__)
static inline locale_t getCLocale() {
  // On these platforms convenience functions from xlocale.h interpret nullptr
  // as C locale.
  return nullptr;
}
#else
static locale_t makeCLocale() {
  locale_t CLocale = newlocale(LC_ALL_MASK, "C", nullptr);
  if (!CLocale) {
    swift::crash("makeCLocale: newlocale() returned a null pointer");
  }
  return CLocale;
}

static locale_t getCLocale() {
  return SWIFT_LAZY_CONSTANT(makeCLocale());
}
#endif

#if defined(__APPLE__)
#define swift_snprintf_l snprintf_l
#else
static int swift_snprintf_l(char *Str, size_t StrSize, locale_t Locale,
                            const char *Format, ...) {
  if (Locale == nullptr) {
    Locale = getCLocale();
  }
  locale_t OldLocale = uselocale(Locale);

  va_list Args;
  va_start(Args, Format);
  int Result = std::vsnprintf(Str, StrSize, Format, Args);
  va_end(Args);

  uselocale(OldLocale);

  return Result;
}
#endif

template <typename T>
static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength,
                                            T Value, const char *Format) {
  if (BufferLength < 32)
    swift::crash("swift_floatingPointToString: insufficient buffer size");

  const int Precision = std::numeric_limits<T>::max_digits10;

  // Pass a null locale to use the C locale.
  int i = swift_snprintf_l(Buffer, BufferLength, /*locale=*/nullptr, Format,
                           Precision, Value);

  if (i < 0)
    swift::crash(
        "swift_floatingPointToString: unexpected return value from sprintf");
  if (size_t(i) >= BufferLength)
    swift::crash("swift_floatingPointToString: insufficient buffer size");

  // Add ".0" to a float that (a) is not in scientific notation, (b) does not
  // already have a fractional part, (c) is not infinite, and (d) is not a NaN
  // value.
  if (strchr(Buffer, 'e') == nullptr && strchr(Buffer, '.') == nullptr &&
      strchr(Buffer, 'n') == nullptr) {
    Buffer[i++] = '.';
    Buffer[i++] = '0';
  }

  return i;
}

extern "C" uint64_t swift_float32ToString(char *Buffer, size_t BufferLength,
                                          float Value) {
  return swift_floatingPointToString<float>(Buffer, BufferLength, Value,
                                            "%0.*g");
}

extern "C" uint64_t swift_float64ToString(char *Buffer, size_t BufferLength,
                                          double Value) {
  return swift_floatingPointToString<double>(Buffer, BufferLength, Value,
                                             "%0.*g");
}

extern "C" uint64_t swift_float80ToString(char *Buffer, size_t BufferLength,
                                          long double Value) {
  return swift_floatingPointToString<long double>(Buffer, BufferLength, Value,
                                                  "%0.*Lg");
}

/// \param[out] LinePtr Replaced with the pointer to the malloc()-allocated
/// line.  Can be NULL if no characters were read.
///
/// \returns Size of character data returned in \c LinePtr, or -1
/// if an error occurred, or EOF was reached.
extern "C" ssize_t swift_stdlib_readLine_stdin(char **LinePtr) {
  size_t Capacity = 0;
  return getline(LinePtr, &Capacity, stdin);
}

extern "C" float _swift_fmodf(float lhs, float rhs) {
    return fmodf(lhs, rhs);
}

extern "C" double _swift_fmod(double lhs, double rhs) {
    return fmod(lhs, rhs);
}

extern "C" long double _swift_fmodl(long double lhs, long double rhs) {
    return fmodl(lhs, rhs);
}

// Although this builtin is provided by clang rt builtins,
// it isn't provided by libgcc, which is the default
// runtime library on Linux, even when compiling with clang.
// This implementation is copied here to avoid a new dependency
// on compiler-rt on Linux.
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4
#if (defined(__APPLE__) && defined(__arm64__)) || \
    (defined(__linux__) && defined(__x86_64__))

typedef int      ti_int __attribute__ ((mode (TI)));
extern "C"
ti_int
__muloti4(ti_int a, ti_int b, int* overflow)
{
    const int N = (int)(sizeof(ti_int) * CHAR_BIT);
    const ti_int MIN = (ti_int)1 << (N-1);
    const ti_int MAX = ~MIN;
    *overflow = 0;
    ti_int result = a * b;
    if (a == MIN)
    {
        if (b != 0 && b != 1)
	    *overflow = 1;
	return result;
    }
    if (b == MIN)
    {
        if (a != 0 && a != 1)
	    *overflow = 1;
        return result;
    }
    ti_int sa = a >> (N - 1);
    ti_int abs_a = (a ^ sa) - sa;
    ti_int sb = b >> (N - 1);
    ti_int abs_b = (b ^ sb) - sb;
    if (abs_a < 2 || abs_b < 2)
        return result;
    if (sa == sb)
    {
        if (abs_a > MAX / abs_b)
            *overflow = 1;
    }
    else
    {
        if (abs_a > MIN / -abs_b)
            *overflow = 1;
    }
    return result;
}

#endif

#if defined(__linux__) && defined(__arm__)
// Similar to above, but with mulodi4.  Perhaps this is
// something that shouldn't be done, and is a bandaid over
// some other lower-level architecture issue that I'm
// missing.  Perhaps relevant bug report:
// FIXME: https://llvm.org/bugs/show_bug.cgi?id=14469
typedef int      di_int __attribute__ ((mode (DI)));
extern "C"
di_int
__mulodi4(di_int a, di_int b, int* overflow)
{
    const int N = (int)(sizeof(di_int) * CHAR_BIT);
    const di_int MIN = (di_int)1 << (N-1);
    const di_int MAX = ~MIN;
    *overflow = 0;
    di_int result = a * b;
    if (a == MIN)
    {
        if (b != 0 && b != 1)
            *overflow = 1;
        return result;
    }
    if (b == MIN)
    {
        if (a != 0 && a != 1)
            *overflow = 1;
        return result;
    }
    di_int sa = a >> (N - 1);
    di_int abs_a = (a ^ sa) - sa;
    di_int sb = b >> (N - 1);
    di_int abs_b = (b ^ sb) - sb;
    if (abs_a < 2 || abs_b < 2)
        return result;
    if (sa == sb)
    {
        if (abs_a > MAX / abs_b)
            *overflow = 1;
    }
    else
    {
        if (abs_a > MIN / -abs_b)
            *overflow = 1;
    }
    return result;
}
#endif

// We can't return Float80, but we can receive a pointer to one, so
// switch the return type and the out parameter on strtold.
template <typename T>
static const char *_swift_stdlib_strtoX_clocale_impl(
    const char * nptr, T* outResult, T huge,
    T (*posixImpl)(const char *, char **, locale_t)
) {
  char *EndPtr;
  errno = 0;
  const auto result = posixImpl(nptr, &EndPtr, getCLocale());
  *outResult = result;
  if (result == huge || result == -huge || result == 0.0 || result == -0.0) {
      if (errno == ERANGE)
          EndPtr = NULL;
  }
  return EndPtr;
}

extern "C" const char *_swift_stdlib_strtold_clocale(
  const char * nptr, void *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, static_cast<long double*>(outResult), HUGE_VALL, strtold_l);
}

extern "C" const char *_swift_stdlib_strtod_clocale(
    const char * nptr, double *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, outResult, HUGE_VAL, strtod_l);
}

extern "C" const char *_swift_stdlib_strtof_clocale(
    const char * nptr, float *outResult) {
  return _swift_stdlib_strtoX_clocale_impl(
    nptr, outResult, HUGE_VALF, strtof_l);
}

extern "C" void _swift_stdlib_flockfile_stdout() {
  flockfile(stdout);
}

extern "C" void _swift_stdlib_funlockfile_stdout() {
  funlockfile(stdout);
}

extern "C" int _swift_stdlib_putc_stderr(int C) {
  return putc(C, stderr);
}

extern "C" size_t _swift_stdlib_getHardwareConcurrency() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, 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.

*/

#include "libtorrent/peer_id.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/thread.hpp"
#include <cstring>
#include <boost/bind.hpp>
#include <iostream>

using namespace libtorrent;
using namespace libtorrent::detail; // for write_* and read_*

struct peer_conn
{
	peer_conn(io_service& ios, int num_pieces, int blocks_pp, tcp::endpoint const& ep
		, char const* ih)
		: s(ios)
		, read_pos(0)
		, state(handshaking)
		// don't request anything from the last piece
		// to keep things simple
		, pieces(num_pieces - 1)
		, block(0)
		, blocks_per_piece(blocks_pp)
		, info_hash(ih)
		, outstanding_requests(0)
	{
		// build a list of all pieces and request them all!
		for (int i = 0; i < int(pieces.size()); ++i)
			pieces[i] = i;
		std::random_shuffle(pieces.begin(), pieces.end());

		s.async_connect(ep, boost::bind(&peer_conn::on_connect, this, _1));
	}

	stream_socket s;
	char buffer[17*1024];
	int read_pos;

	enum state_t
	{
		handshaking,
		sending_request,
		receiving_message
	};
	int state;
	std::vector<int> pieces;
	int block;
	int blocks_per_piece;
	char const* info_hash;
	int outstanding_requests;

	void on_connect(error_code const& ec)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR CONNECT: %s\n", ec.message().c_str());
			return;
		}

		char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
			"                    " // space for info-hash
			"aaaaaaaaaaaaaaaaaaaa" // peer-id
			"\0\0\0\x01\x02"; // interested
		char* h = (char*)malloc(sizeof(handshake));
		memcpy(h, handshake, sizeof(handshake));
		std::memcpy(h + 28, info_hash, 20);
		std::generate(h + 48, h + 68, &rand);
		boost::asio::async_write(s, libtorrent::asio::buffer(h, sizeof(handshake) - 1)
			, boost::bind(&peer_conn::on_handshake, this, h, _1, _2));
	}

	void on_handshake(char* h, error_code const& ec, size_t bytes_transferred)
	{
		free(h);
		if (ec)
		{
			fprintf(stderr, "ERROR SEND HANDSHAKE: %s\n", ec.message().c_str());
			return;
		}

		// read handshake
		boost::asio::async_read(s, libtorrent::asio::buffer(buffer, 68)
			, boost::bind(&peer_conn::on_handshake2, this, _1, _2));
	}

	void on_handshake2(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR READ HANDSHAKE: %s\n", ec.message().c_str());
			return;
		}

		work();
	}

	void write_request()
	{
		if (pieces.empty()) return;

		int piece = pieces.back();

		char msg[] = "\0\0\0\xd\x06"
			"    " // piece
			"    " // offset
			"    "; // length
		char* m = (char*)malloc(sizeof(msg));
		memcpy(m, msg, sizeof(msg));
		char* ptr = m + 5;
		write_uint32(piece, ptr);
		write_uint32(block * 16 * 1024, ptr);
		write_uint32(16 * 1024, ptr);
		error_code ec;
		boost::asio::async_write(s, libtorrent::asio::buffer(m, sizeof(msg) - 1)
			, boost::bind(&peer_conn::on_req_sent, this, m, _1, _2));

		++block;
		if (block == blocks_per_piece)
		{
			block = 0;
			pieces.pop_back();
		}
	}

	void on_req_sent(char* m, error_code const& ec, size_t bytes_transferred)
	{
		free(m);
		if (ec)
		{
			fprintf(stderr, "ERROR SEND REQUEST: %s\n", ec.message().c_str());
			return;
		}

		++outstanding_requests;

		work();
	}

	void work()
	{
		if (pieces.empty() && outstanding_requests == 0)
		{
			fprintf(stderr, "COMPLETED DOWNLOAD\n");
			return;
		}

		// send requests
		if (outstanding_requests < 20 && !pieces.empty())
		{
			write_request();
			return;
		}

		// read message
		boost::asio::async_read(s, asio::buffer(buffer, 4)
			, boost::bind(&peer_conn::on_msg_length, this, _1, _2));
	}

	void on_msg_length(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE PREFIX: %s\n", ec.message().c_str());
			return;
		}
		char* ptr = buffer;
		unsigned int length = read_uint32(ptr);
		if (length > sizeof(buffer))
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE PREFIX: packet too big\n");
			return;
		}
		boost::asio::async_read(s, asio::buffer(buffer, length)
			, boost::bind(&peer_conn::on_message, this, _1, _2));
	}

	void on_message(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE: %s\n", ec.message().c_str());
			return;
		}
		char* ptr = buffer;
		int msg = read_uint8(ptr);
		if (msg == 7) --outstanding_requests;

		work();
	}
};

int main(int argc, char* argv[])
{
	if (argc < 5)
	{
		fprintf(stderr, "usage: connection_tester number-of-connections destination-ip destination-port torrent-file\n");
		return 1;
	}
	int num_connections = atoi(argv[1]);
	error_code ec;
	address_v4 addr = address_v4::from_string(argv[2], ec);
	if (ec)
	{
		fprintf(stderr, "ERROR RESOLVING %s: %s\n", argv[2], ec.message().c_str());
		return 1;
	}
	int port = atoi(argv[3]);
	tcp::endpoint ep(addr, port);
	torrent_info ti(argv[4], ec);
	if (ec)
	{
		fprintf(stderr, "ERROR LOADING .TORRENT: %s\n", ec.message().c_str());
		return 1;
	}
	std::list<peer_conn*> conns;
	io_service ios;
	for (int i = 0; i < num_connections; ++i)
	{
		conns.push_back(new peer_conn(ios, ti.num_pieces(), ti.piece_length() / 16 / 1024
			, ep, (char const*)&ti.info_hash()[0]));
		libtorrent::sleep(1);
		ios.poll_one(ec);
		if (ec)
		{
			fprintf(stderr, "ERROR: %s\n", ec.message().c_str());
			break;
		}
	}

	ios.run(ec);
	if (ec) fprintf(stderr, "ERROR: %s\n", ec.message().c_str());

	return 0;
}

<commit_msg>extend connection test to support uploading as well<commit_after>/*

Copyright (c) 2008, 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.

*/

#include "libtorrent/peer_id.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/thread.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/hasher.hpp"
#include <cstring>
#include <boost/bind.hpp>
#include <iostream>
#include <boost/array.hpp>

using namespace libtorrent;
using namespace libtorrent::detail; // for write_* and read_*

void generate_block(boost::uint32_t* buffer, int piece, int start, int length)
{
	boost::uint32_t fill = (piece << 16) | (start / 0x4000);
	for (int i = 0; i < length / 4; ++i)
	{
		buffer[i] = fill;
	}
}

struct peer_conn
{
	peer_conn(io_service& ios, int num_pieces, int blocks_pp, tcp::endpoint const& ep
		, char const* ih, bool seed_)
		: s(ios)
		, read_pos(0)
		, state(handshaking)
		// don't request anything from the last piece
		// to keep things simple
		, pieces(num_pieces - 1)
		, block(0)
		, blocks_per_piece(blocks_pp)
		, info_hash(ih)
		, outstanding_requests(0)
		, seed(seed_)
	{
		if (!seed_)
		{
			// build a list of all pieces and request them all!
			for (int i = 0; i < int(pieces.size()); ++i)
				pieces[i] = i;
			std::random_shuffle(pieces.begin(), pieces.end());
		}

		s.async_connect(ep, boost::bind(&peer_conn::on_connect, this, _1));
	}

	stream_socket s;
	boost::uint32_t write_buffer[17*1024/4];
	boost::uint32_t buffer[17*1024/4];
	int read_pos;

	enum state_t
	{
		handshaking,
		sending_request,
		receiving_message
	};
	int state;
	std::vector<int> pieces;
	int block;
	int blocks_per_piece;
	char const* info_hash;
	int outstanding_requests;
	// if this is true, this connection is a seed
	bool seed;

	void on_connect(error_code const& ec)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR CONNECT: %s\n", ec.message().c_str());
			return;
		}

		char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
			"                    " // space for info-hash
			"aaaaaaaaaaaaaaaaaaaa" // peer-id
			"\0\0\0\x01\x02"; // interested
		char* h = (char*)malloc(sizeof(handshake));
		memcpy(h, handshake, sizeof(handshake));
		std::memcpy(h + 28, info_hash, 20);
		std::generate(h + 48, h + 68, &rand);
		// for seeds, don't send the interested message
		boost::asio::async_write(s, libtorrent::asio::buffer(h, (sizeof(handshake) - 1) - (seed ? 5 : 0))
			, boost::bind(&peer_conn::on_handshake, this, h, _1, _2));
	}

	void on_handshake(char* h, error_code const& ec, size_t bytes_transferred)
	{
		free(h);
		if (ec)
		{
			fprintf(stderr, "ERROR SEND HANDSHAKE: %s\n", ec.message().c_str());
			return;
		}

		// read handshake
		boost::asio::async_read(s, libtorrent::asio::buffer((char*)buffer, 68)
			, boost::bind(&peer_conn::on_handshake2, this, _1, _2));
	}

	void on_handshake2(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR READ HANDSHAKE: %s\n", ec.message().c_str());
			return;
		}

		if (seed)
		{
			write_have_all();
		}
		else
		{
			work_download();
		}
	}

	void write_have_all()
	{
		// have_all and unchoke
		static char msg[] = "\0\0\0\x01\x0e\0\0\0\x01\x01";
		error_code ec;
		boost::asio::async_write(s, libtorrent::asio::buffer(msg, sizeof(msg) - 1)
			, boost::bind(&peer_conn::on_have_all_sent, this, _1, _2));

	}

	void on_have_all_sent(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR SEND HAVE ALL: %s\n", ec.message().c_str());
			return;
		}

		// read message
		boost::asio::async_read(s, asio::buffer((char*)buffer, 4)
			, boost::bind(&peer_conn::on_msg_length, this, _1, _2));
	}

	void write_request()
	{
		if (pieces.empty()) return;

		int piece = pieces.back();

		char msg[] = "\0\0\0\xd\x06"
			"    " // piece
			"    " // offset
			"    "; // length
		char* m = (char*)malloc(sizeof(msg));
		memcpy(m, msg, sizeof(msg));
		char* ptr = m + 5;
		write_uint32(piece, ptr);
		write_uint32(block * 16 * 1024, ptr);
		write_uint32(16 * 1024, ptr);
		error_code ec;
		boost::asio::async_write(s, libtorrent::asio::buffer(m, sizeof(msg) - 1)
			, boost::bind(&peer_conn::on_req_sent, this, m, _1, _2));

		++block;
		if (block == blocks_per_piece)
		{
			block = 0;
			pieces.pop_back();
		}
	}

	void on_req_sent(char* m, error_code const& ec, size_t bytes_transferred)
	{
		free(m);
		if (ec)
		{
			fprintf(stderr, "ERROR SEND REQUEST: %s\n", ec.message().c_str());
			return;
		}

		++outstanding_requests;

		work_download();
	}

	void work_download()
	{
		if (pieces.empty() && outstanding_requests == 0)
		{
			fprintf(stderr, "COMPLETED DOWNLOAD\n");
			return;
		}

		// send requests
		if (outstanding_requests < 20 && !pieces.empty())
		{
			write_request();
			return;
		}

		// read message
		boost::asio::async_read(s, asio::buffer((char*)buffer, 4)
			, boost::bind(&peer_conn::on_msg_length, this, _1, _2));
	}

	void on_msg_length(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE PREFIX: %s\n", ec.message().c_str());
			return;
		}
		char* ptr = (char*)buffer;
		unsigned int length = read_uint32(ptr);
		if (length > sizeof(buffer))
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE PREFIX: packet too big\n");
			return;
		}
		boost::asio::async_read(s, asio::buffer((char*)buffer, length)
			, boost::bind(&peer_conn::on_message, this, _1, _2));
	}

	void on_message(error_code const& ec, size_t bytes_transferred)
	{
		if (ec)
		{
			fprintf(stderr, "ERROR RECEIVE MESSAGE: %s\n", ec.message().c_str());
			return;
		}
		char* ptr = (char*)buffer;
		int msg = read_uint8(ptr);

		if (seed)
		{
			if (msg == 6 && bytes_transferred == 13)
			{
				int piece = detail::read_int32(ptr);
				int start = detail::read_int32(ptr);
				int length = detail::read_int32(ptr);
				write_piece(piece, start, length);
			}
			else
			{
				// read another message
				boost::asio::async_read(s, asio::buffer(buffer, 4)
					, boost::bind(&peer_conn::on_msg_length, this, _1, _2));
			}
		}
		else
		{
			if (msg == 7) --outstanding_requests;
			work_download();
		}
	}

	void write_piece(int piece, int start, int length)
	{
		generate_block(write_buffer, piece, start, length);
		static char msg[] = "    \x07"
			"    " // piece
			"    "; // start
		char* ptr = msg;
		write_uint32(9 + length, ptr);
		assert(length == 0x4000);
		assert(*ptr == 7);
		++ptr; // skip message id
		write_uint32(piece, ptr);
		write_uint32(start, ptr);
		boost::array<libtorrent::asio::const_buffer, 2> vec;
		vec[0] = libtorrent::asio::buffer(msg, sizeof(msg)-1);
		vec[1] = libtorrent::asio::buffer(write_buffer, length);
		boost::asio::async_write(s, vec, boost::bind(&peer_conn::on_have_all_sent, this, _1, _2));
	}
};

void print_usage()
{
	fprintf(stderr, "usage: connection_tester command ...\n\n"
		"command is one of:\n"
		"  gen-torrent         generate a test torrent\n"
		"  upload              start an uploader test\n"
		"  download            start a downloader test\n\n"
		"examples:\n\n"
		"connection_tester gen-torrent torrent-name\n"
		"connection_tester upload number-of-connections destination-ip destination-port torrent-file\n"
		"connection_tester download number-of-connections destination-ip destination-port torrent-file\n");
	exit(1);
}

void generate_torrent(std::vector<char>& buf)
{
	file_storage fs;
	// 1 MiB piece size
	const int piece_size = 1024 * 1024;
	// 50 GiB should be enough to not fit in physical RAM
	const int num_pieces = 1 * 1024;
	const size_type total_size = size_type(piece_size) * num_pieces;
	fs.add_file("stress_test_file", total_size);
	libtorrent::create_torrent t(fs, piece_size);

	boost::uint32_t piece[0x4000 / 4];
	for (int i = 0; i < num_pieces; ++i)
	{
		hasher ph;
		for (int j = 0; j < piece_size; j += 0x4000)
		{
			generate_block(piece, i, j, 0x4000);
			ph.update((char*)piece, 0x4000);
		}
		t.set_hash(i, ph.final());
	}

	std::back_insert_iterator<std::vector<char> > out(buf);

	bencode(out, t.generate());
}

int main(int argc, char* argv[])
{
	if (argc <= 1) print_usage();

	bool upload_test = false;
	bool download_test = false;

	if (strcmp(argv[1], "gen-torrent") == 0)
	{
		if (argc != 3) print_usage();

		std::vector<char> tmp;
		generate_torrent(tmp);

		FILE* output = stdout;
		if (strcmp("-", argv[2]) != 0)
			output = fopen(argv[2], "wb+");
		fwrite(&tmp[0], 1, tmp.size(), output);
		if (output != stdout)
			fclose(output);

		return 0;
	}
	else if (strcmp(argv[1], "upload") == 0)
	{
		if (argc != 6) print_usage();
		upload_test = true;
	}
	else if (strcmp(argv[1], "download") == 0)
	{
		if (argc != 6) print_usage();
		download_test = true;
	}

	if (!download_test && !upload_test) print_usage();

	int num_connections = atoi(argv[2]);
	error_code ec;
	address_v4 addr = address_v4::from_string(argv[3], ec);
	if (ec)
	{
		fprintf(stderr, "ERROR RESOLVING %s: %s\n", argv[3], ec.message().c_str());
		return 1;
	}
	int port = atoi(argv[4]);
	tcp::endpoint ep(addr, port);

	torrent_info ti(argv[5], ec);
	if (ec)
	{
		fprintf(stderr, "ERROR LOADING .TORRENT: %s\n", ec.message().c_str());
		return 1;
	}

	std::list<peer_conn*> conns;
	io_service ios;
	for (int i = 0; i < num_connections; ++i)
	{
		conns.push_back(new peer_conn(ios, ti.num_pieces(), ti.piece_length() / 16 / 1024
			, ep, (char const*)&ti.info_hash()[0], upload_test));
		libtorrent::sleep(1);
		ios.poll_one(ec);
		if (ec)
		{
			fprintf(stderr, "ERROR: %s\n", ec.message().c_str());
			break;
		}
	}

	ios.run(ec);
	if (ec) fprintf(stderr, "ERROR: %s\n", ec.message().c_str());

	return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sdrpagewindow.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 16:11:32 $
 *
 *  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 _SDRPAGEWINDOW_HXX
#define _SDRPAGEWINDOW_HXX

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_XWINDOWLISTENER_HPP_
#include <com/sun/star/awt/XWindowListener.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODECHANGELISTENER_HPP_
#include <com/sun/star/util/XModeChangeListener.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE4_HXX_
#include <cppuhelper/implbase4.hxx>
#endif

#ifndef _SVDTYPES_HXX
#include <svx/svdtypes.hxx> // fuer SdrLayerID
#endif

#ifndef _SVARRAY_HXX
#include <svtools/svarray.hxx>
#endif

#ifndef _CONTNR_HXX
#include <tools/contnr.hxx>
#endif

#ifndef _SDRPAGEWINDOW_HXX
#include <svx/sdrpagewindow.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

#include <vector>

////////////////////////////////////////////////////////////////////////////////////////////////////
// predeclarations

class Region;
class SdrPaintInfoRec;
class SdrUnoObj;
class SdrPageView;

// #110094#
namespace sdr
{
    namespace contact
    {
        class ObjectContact;
        class ViewObjectContactRedirector;
    } // end of namespace contact

    namespace overlay
    {
        class OverlayManager;
    } // end of namespace overlay
} // end of namespace sdr

class SdrUnoControlList;
class SdrPaintWindow;
class Rectangle;
class Link;

////////////////////////////////////////////////////////////////////////////////////////////////////

class SVX_DLLPUBLIC SdrPageWindow
{
    // #110094# ObjectContact section
    sdr::contact::ObjectContact*                        mpObjectContact;

    // the SdrPageView this window belongs to
    SdrPageView&                                        mrPageView;

    // the PaintWindow to paint on. Here is access to OutDev etc.
    // #i72752# change to pointer to allow patcing it in DrawLayer() if necessary
    SdrPaintWindow*                                     mpPaintWindow;
    SdrPaintWindow*                                     mpOriginalPaintWindow;

    // UNO stuff for xControls
    void*                                               mpDummy;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > mxControlContainer;

    // #110094# ObjectContact section
    sdr::contact::ObjectContact* CreateViewSpecificObjectContact();

    // support method for creating PageInfoRecs for painting
    SdrPaintInfoRec* ImpCreateNewPageInfoRec(const Rectangle& rDirtyRect,
        sal_uInt16 nPaintMode, const SdrLayerID* pId) const;

public:
    SdrPageWindow(SdrPageView& rNewPageView, SdrPaintWindow& rPaintWindow);
    ~SdrPageWindow();

    // data read accesses
    SdrPageView& GetPageView() const { return mrPageView; }
    SdrPaintWindow& GetPaintWindow() const { return *mpPaintWindow; }
    const SdrPaintWindow* GetOriginalPaintWindow() const { return mpOriginalPaintWindow; }
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > GetControlContainer( bool _bCreateIfNecessary = true ) const;

    // OVERLAYMANAGER
    ::sdr::overlay::OverlayManager* GetOverlayManager() const;

    // #i72752# allow patcing SdrPaintWindow from SdrPageView::DrawLayer if needed
    void patchPaintWindow(SdrPaintWindow& rPaintWindow);
    void unpatchPaintWindow();

    // the repaint method. For migration from pPaintProc, use one more parameter
    void PrepareRedraw(const Region& rReg);
    void RedrawAll(sal_uInt16 nPaintMode, ::sdr::contact::ViewObjectContactRedirector* pRedirector) const;
    void RedrawLayer(sal_uInt16 nPaintMode, const SdrLayerID* pId, ::sdr::contact::ViewObjectContactRedirector* pRedirector) const;

    // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
    void Invalidate(const Rectangle& rRectangle);

    // #110094# ObjectContact section
    sdr::contact::ObjectContact& GetObjectContact() const;
    /// determines whether there already exists an ObjectContact
    bool                         HasObjectContact() const;

    // #i26631#
    void ResetObjectContact();

    /** sets all elements in the view which support a design and a alive mode into the given mode
    */
    void    SetDesignMode( bool _bDesignMode ) const;
};

// typedefs for a list of SdrPageWindow
typedef ::std::vector< SdrPageWindow* > SdrPageWindowVector;

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //_SDRPAGEWINDOW_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.2.466); FILE MERGED 2008/04/01 15:49:36 thb 1.2.466.3: #i85898# Stripping all external header guards 2008/04/01 12:46:49 thb 1.2.466.2: #i85898# Stripping all external header guards 2008/03/31 14:18:15 rt 1.2.466.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sdrpagewindow.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SDRPAGEWINDOW_HXX
#define _SDRPAGEWINDOW_HXX

#include <tools/debug.hxx>
#include <com/sun/star/awt/XWindowListener.hpp>
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/util/XModeChangeListener.hpp>
#include <cppuhelper/implbase4.hxx>
#include <svx/svdtypes.hxx> // fuer SdrLayerID
#include <svtools/svarray.hxx>
#include <tools/contnr.hxx>
#include <svx/sdrpagewindow.hxx>
#include "svx/svxdllapi.h"

#include <vector>

////////////////////////////////////////////////////////////////////////////////////////////////////
// predeclarations

class Region;
class SdrPaintInfoRec;
class SdrUnoObj;
class SdrPageView;

// #110094#
namespace sdr
{
    namespace contact
    {
        class ObjectContact;
        class ViewObjectContactRedirector;
    } // end of namespace contact

    namespace overlay
    {
        class OverlayManager;
    } // end of namespace overlay
} // end of namespace sdr

class SdrUnoControlList;
class SdrPaintWindow;
class Rectangle;
class Link;

////////////////////////////////////////////////////////////////////////////////////////////////////

class SVX_DLLPUBLIC SdrPageWindow
{
    // #110094# ObjectContact section
    sdr::contact::ObjectContact*                        mpObjectContact;

    // the SdrPageView this window belongs to
    SdrPageView&                                        mrPageView;

    // the PaintWindow to paint on. Here is access to OutDev etc.
    // #i72752# change to pointer to allow patcing it in DrawLayer() if necessary
    SdrPaintWindow*                                     mpPaintWindow;
    SdrPaintWindow*                                     mpOriginalPaintWindow;

    // UNO stuff for xControls
    void*                                               mpDummy;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > mxControlContainer;

    // #110094# ObjectContact section
    sdr::contact::ObjectContact* CreateViewSpecificObjectContact();

    // support method for creating PageInfoRecs for painting
    SdrPaintInfoRec* ImpCreateNewPageInfoRec(const Rectangle& rDirtyRect,
        sal_uInt16 nPaintMode, const SdrLayerID* pId) const;

public:
    SdrPageWindow(SdrPageView& rNewPageView, SdrPaintWindow& rPaintWindow);
    ~SdrPageWindow();

    // data read accesses
    SdrPageView& GetPageView() const { return mrPageView; }
    SdrPaintWindow& GetPaintWindow() const { return *mpPaintWindow; }
    const SdrPaintWindow* GetOriginalPaintWindow() const { return mpOriginalPaintWindow; }
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > GetControlContainer( bool _bCreateIfNecessary = true ) const;

    // OVERLAYMANAGER
    ::sdr::overlay::OverlayManager* GetOverlayManager() const;

    // #i72752# allow patcing SdrPaintWindow from SdrPageView::DrawLayer if needed
    void patchPaintWindow(SdrPaintWindow& rPaintWindow);
    void unpatchPaintWindow();

    // the repaint method. For migration from pPaintProc, use one more parameter
    void PrepareRedraw(const Region& rReg);
    void RedrawAll(sal_uInt16 nPaintMode, ::sdr::contact::ViewObjectContactRedirector* pRedirector) const;
    void RedrawLayer(sal_uInt16 nPaintMode, const SdrLayerID* pId, ::sdr::contact::ViewObjectContactRedirector* pRedirector) const;

    // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
    void Invalidate(const Rectangle& rRectangle);

    // #110094# ObjectContact section
    sdr::contact::ObjectContact& GetObjectContact() const;
    /// determines whether there already exists an ObjectContact
    bool                         HasObjectContact() const;

    // #i26631#
    void ResetObjectContact();

    /** sets all elements in the view which support a design and a alive mode into the given mode
    */
    void    SetDesignMode( bool _bDesignMode ) const;
};

// typedefs for a list of SdrPageWindow
typedef ::std::vector< SdrPageWindow* > SdrPageWindowVector;

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //_SDRPAGEWINDOW_HXX
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile$
 *
 *  $Revision$
 *
 *  last change: $Author$ $Date$
 *
 *  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 _SVXSWFRAMEVALIDATION_HXX
#define _SVXSWFRAMEVALIDATION_HXX
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#include <limits.h>

/* -----------------03.03.2004 16:31-----------------
    struct to determine min/max values for fly frame positioning in Writer
 --------------------------------------------------*/
struct SvxSwFrameValidation
{
    sal_Int16           nAnchorType; //com::sun::star::text::TextContentAnchorType
    sal_Int16           nHoriOrient; //com::sun::star::text::HoriOrientation
    sal_Int16           nVertOrient; //com::sun::star::text::VertOrientation
    sal_Int16           nHRelOrient; //com::sun::star::text::RelOrientation
    sal_Int16           nVRelOrient; //com::sun::star::text::RelOrientation
    bool                bAutoHeight;
    bool                bAutoWidth;
    bool                bMirror;
    bool                bFollowTextFlow;

    sal_Int32 nHPos;
    sal_Int32 nMaxHPos;
    sal_Int32 nMinHPos;

    sal_Int32 nVPos;
    sal_Int32 nMaxVPos;
    sal_Int32 nMinVPos;

    sal_Int32 nWidth;
    sal_Int32 nMinWidth;
    sal_Int32 nMaxWidth;

    sal_Int32 nHeight;
    sal_Int32 nMinHeight;
    sal_Int32 nMaxHeight;

    Size    aPercentSize;   // Size fuer 100%-Wert

    SvxSwFrameValidation() :
        bAutoHeight(false),
        bAutoWidth(false),
        bMirror(false),
        bFollowTextFlow( false ),
        nHPos(0),
        nMaxHPos(LONG_MAX),
        nMinHPos(0),
        nVPos(0),
        nMaxVPos(LONG_MAX),
        nMinVPos(0),
        nWidth( 283 * 4 ), //2.0 cm
        nMinWidth(0),
        nMaxWidth(LONG_MAX),
        nHeight( 283 ), //0.5 cm
        nMaxHeight(LONG_MAX)
    {
    }
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.1256); FILE MERGED 2008/04/01 15:49:23 thb 1.3.1256.2: #i85898# Stripping all external header guards 2008/03/31 14:18:00 rt 1.3.1256.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile$
 * $Revision$
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SVXSWFRAMEVALIDATION_HXX
#define _SVXSWFRAMEVALIDATION_HXX
#include <sal/types.h>
#include <tools/gen.hxx>
#include <limits.h>

/* -----------------03.03.2004 16:31-----------------
    struct to determine min/max values for fly frame positioning in Writer
 --------------------------------------------------*/
struct SvxSwFrameValidation
{
    sal_Int16           nAnchorType; //com::sun::star::text::TextContentAnchorType
    sal_Int16           nHoriOrient; //com::sun::star::text::HoriOrientation
    sal_Int16           nVertOrient; //com::sun::star::text::VertOrientation
    sal_Int16           nHRelOrient; //com::sun::star::text::RelOrientation
    sal_Int16           nVRelOrient; //com::sun::star::text::RelOrientation
    bool                bAutoHeight;
    bool                bAutoWidth;
    bool                bMirror;
    bool                bFollowTextFlow;

    sal_Int32 nHPos;
    sal_Int32 nMaxHPos;
    sal_Int32 nMinHPos;

    sal_Int32 nVPos;
    sal_Int32 nMaxVPos;
    sal_Int32 nMinVPos;

    sal_Int32 nWidth;
    sal_Int32 nMinWidth;
    sal_Int32 nMaxWidth;

    sal_Int32 nHeight;
    sal_Int32 nMinHeight;
    sal_Int32 nMaxHeight;

    Size    aPercentSize;   // Size fuer 100%-Wert

    SvxSwFrameValidation() :
        bAutoHeight(false),
        bAutoWidth(false),
        bMirror(false),
        bFollowTextFlow( false ),
        nHPos(0),
        nMaxHPos(LONG_MAX),
        nMinHPos(0),
        nVPos(0),
        nMaxVPos(LONG_MAX),
        nMinVPos(0),
        nWidth( 283 * 4 ), //2.0 cm
        nMinWidth(0),
        nMaxWidth(LONG_MAX),
        nHeight( 283 ), //0.5 cm
        nMaxHeight(LONG_MAX)
    {
    }
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: anchoreddrawobject.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2004-09-09 10:54:27 $
 *
 *  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 _ANCHOREDDRAWOBJECT_HXX
#define _ANCHOREDDRAWOBJECT_HXX

#ifndef _ANCHOREDOBJECT_HXX
#include <anchoredobject.hxx>
#endif
#ifndef _GEN_HXX
#include <tools/gen.hxx>
#endif

/** class for the positioning of drawing objects

    OD 2004-03-25 #i26791#

    @author OD
*/
class SwAnchoredDrawObject : public SwAnchoredObject
{
    private:
        // boolean, indicating that the object position has been invalidated
        // and that a positioning has to be performed.
        bool mbValidPos;

        // rectangle, keeping the last object rectangle after the postioning
        Rectangle maLastObjRect;

        // boolean, indicating that anchored drawing object hasn't been attached
        // to a anchor frame yet. Once, it is attached to a anchor frame the
        // boolean changes its state.
        bool mbNotYetAttachedToAnchorFrame;

        // --> OD 2004-08-09 #i28749# - boolean, indicating that anchored
        // drawing object hasn't been positioned yet. Once, it's positioned the
        // boolean changes its state.
        bool mbNotYetPositioned;

        /** method for the intrinsic positioning of a at-paragraph|at-character
            anchored drawing object

            OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>

            @author OD
        */
        void _MakeObjPosAnchoredAtPara();

        /** method for the intrinsic positioning of a at-page|at-frame anchored
            drawing object

            OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>

            @author OD
        */
        void _MakeObjPosAnchoredAtLayout();
        /** method to convert positioning attributes from horizontal
            left-to-right layout to the layout direction of its anchor frame

            OD 2004-08-09 #i28749#
            The positioning attributes are converted by the current object geometry.
            Conversion has to be done for drawing objects (not anchored
            as-character) imported from OpenOffice.org file format only once
            and directly before the first positioning.

            @author OD
        */
        void _ConvertPositioningAttr();

        /** method to set internal anchor position of <SdrObject> instance
            of the drawing object

            For drawing objects the internal anchor position of the <SdrObject>
            instance has to be set.
            Note: This adjustment is not be done for as-character anchored
            drawing object - the positioning code takes care of this.
            OD 2004-07-29 #i31698# - API for drawing objects in Writer has
            been adjusted. Thus, this method will only set the internal anchor
            position of the <SdrObject> instance to the anchor position given
            by its anchor frame.

            @author OD
        */
        void _SetDrawObjAnchor();

        /** method to invalidate the given page frame

            OD 2004-07-02 #i28701#

            @author OD
        */
        void _InvalidatePage( SwPageFrm* _pPageFrm );

    protected:
        virtual void ObjectAttachedToAnchorFrame();

        /** method to assure that anchored object is registered at the correct
            page frame

            OD 2004-07-02 #i28701#

            @author OD
        */
        virtual void RegisterAtCorrectPage();

    public:
        TYPEINFO();

        SwAnchoredDrawObject();
        virtual ~SwAnchoredDrawObject();

        // declaration of pure virtual methods of base class <SwAnchoredObject>
        virtual void MakeObjPos();
        virtual void InvalidateObjPos();

        // accessors to the format
        virtual SwFrmFmt& GetFrmFmt();
        virtual const SwFrmFmt& GetFrmFmt() const;

        // accessors to the object area and its position
        virtual const SwRect GetObjRect() const;
        virtual void SetObjTop( const SwTwips _nTop);
        virtual void SetObjLeft( const SwTwips _nLeft);
        const Rectangle& GetLastObjRect() const;
        Rectangle& LastObjRect();

        /** adjust positioning and alignment attributes for new anchor frame

            OD 2004-04-21
            Set horizontal and vertical position/alignment to manual position
            relative to anchor frame area using the anchor position of the
            new anchor frame and the current absolute drawing object position.
            Note: For correct Undo/Redo method should only be called inside a
            Undo-/Redo-action.
            OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>

            @author OD

            @param <_pNewAnchorFrm>
            input parameter - new anchor frame for the anchored object.

            @param <_pNewObjRect>
            optional input parameter - proposed new object rectangle. If not
            provided the current object rectangle is taken.
        */
        void AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
                                    const SwRect* _pNewObjRect = 0L );

        /** anchored drawing object not yet attached to a anchor frame

            OD 2004-08-04 #i31698#

            @author OD
        */
        inline bool NotYetAttachedToAnchorFrm() const
        {
            return mbNotYetAttachedToAnchorFrame;
        }

        /** method to notify background of drawing object

            OD 2004-06-30 #i28701#

            @author OD
        */
        virtual void NotifyBackground( SwPageFrm* _pPageFrm,
                                       const SwRect& _rRect,
                                       PrepareHint _eHint );
};

#endif
<commit_msg>INTEGRATION: CWS dbwizard1 (1.4.18); FILE MERGED 2004/10/20 10:52:17 od 1.4.18.3: #i35798# class <SwAnchoredDrawObject>          - replace method <_ConvertPositioningAttr()> by <_SetPositioningAttr()> 2004/10/11 14:32:24 tv 1.4.18.2: RESYNC: (1.4-1.5); FILE MERGED 2004/10/01 12:34:51 od 1.4.18.1: #i34748# class <SwAnchoredDrawObject> - change handling of the last object          rectangle in order to consider, if already a last object rectangle          exists.<commit_after>/*************************************************************************
 *
 *  $RCSfile: anchoreddrawobject.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-10-27 12:29:49 $
 *
 *  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 _ANCHOREDDRAWOBJECT_HXX
#define _ANCHOREDDRAWOBJECT_HXX

#ifndef _ANCHOREDOBJECT_HXX
#include <anchoredobject.hxx>
#endif
#ifndef _GEN_HXX
#include <tools/gen.hxx>
#endif

/** class for the positioning of drawing objects

    OD 2004-03-25 #i26791#

    @author OD
*/
class SwAnchoredDrawObject : public SwAnchoredObject
{
    private:
        // boolean, indicating that the object position has been invalidated
        // and that a positioning has to be performed.
        bool mbValidPos;

        // rectangle, keeping the last object rectangle after the postioning
        // --> OD 2004-09-29 #i34748# - change <maLastObjRect> to a pointer
        Rectangle* mpLastObjRect;

        // boolean, indicating that anchored drawing object hasn't been attached
        // to a anchor frame yet. Once, it is attached to a anchor frame the
        // boolean changes its state.
        bool mbNotYetAttachedToAnchorFrame;

        // --> OD 2004-08-09 #i28749# - boolean, indicating that anchored
        // drawing object hasn't been positioned yet. Once, it's positioned the
        // boolean changes its state.
        bool mbNotYetPositioned;

        /** method for the intrinsic positioning of a at-paragraph|at-character
            anchored drawing object

            OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>

            @author OD
        */
        void _MakeObjPosAnchoredAtPara();

        /** method for the intrinsic positioning of a at-page|at-frame anchored
            drawing object

            OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>

            @author OD
        */
        void _MakeObjPosAnchoredAtLayout();

            /** method to set positioning attributes (not for as-character anchored)

            OD 2004-10-20 #i35798#
            During load the positioning attributes aren't set.
            Thus, the positioning attributes are set by the current object geometry.
            This method is also used for the conversion for drawing objects
            (not anchored as-character) imported from OpenOffice.org file format
            once and directly before the first positioning.

            @author OD
        */
        void _SetPositioningAttr();

        /** method to set internal anchor position of <SdrObject> instance
            of the drawing object

            For drawing objects the internal anchor position of the <SdrObject>
            instance has to be set.
            Note: This adjustment is not be done for as-character anchored
            drawing object - the positioning code takes care of this.
            OD 2004-07-29 #i31698# - API for drawing objects in Writer has
            been adjusted. Thus, this method will only set the internal anchor
            position of the <SdrObject> instance to the anchor position given
            by its anchor frame.

            @author OD
        */
        void _SetDrawObjAnchor();

        /** method to invalidate the given page frame

            OD 2004-07-02 #i28701#

            @author OD
        */
        void _InvalidatePage( SwPageFrm* _pPageFrm );

    protected:
        virtual void ObjectAttachedToAnchorFrame();

        /** method to assure that anchored object is registered at the correct
            page frame

            OD 2004-07-02 #i28701#

            @author OD
        */
        virtual void RegisterAtCorrectPage();

    public:
        TYPEINFO();

        SwAnchoredDrawObject();
        virtual ~SwAnchoredDrawObject();

        // declaration of pure virtual methods of base class <SwAnchoredObject>
        virtual void MakeObjPos();
        virtual void InvalidateObjPos();

        // accessors to the format
        virtual SwFrmFmt& GetFrmFmt();
        virtual const SwFrmFmt& GetFrmFmt() const;

        // accessors to the object area and its position
        virtual const SwRect GetObjRect() const;
        virtual void SetObjTop( const SwTwips _nTop);
        virtual void SetObjLeft( const SwTwips _nLeft);
        // --> OD 2004-09-29 #i34748# - change return type to a pointer.
        // Return value can be NULL.
        const Rectangle* GetLastObjRect() const;
        // <--
        // --> OD 2004-09-29 #i34748# - change method
        void SetLastObjRect( const Rectangle& _rNewObjRect );
        // <--

        /** adjust positioning and alignment attributes for new anchor frame

            OD 2004-04-21
            Set horizontal and vertical position/alignment to manual position
            relative to anchor frame area using the anchor position of the
            new anchor frame and the current absolute drawing object position.
            Note: For correct Undo/Redo method should only be called inside a
            Undo-/Redo-action.
            OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>

            @author OD

            @param <_pNewAnchorFrm>
            input parameter - new anchor frame for the anchored object.

            @param <_pNewObjRect>
            optional input parameter - proposed new object rectangle. If not
            provided the current object rectangle is taken.
        */
        void AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
                                    const SwRect* _pNewObjRect = 0L );

        /** anchored drawing object not yet attached to a anchor frame

            OD 2004-08-04 #i31698#

            @author OD
        */
        inline bool NotYetAttachedToAnchorFrm() const
        {
            return mbNotYetAttachedToAnchorFrame;
        }

        /** method to notify background of drawing object

            OD 2004-06-30 #i28701#

            @author OD
        */
        virtual void NotifyBackground( SwPageFrm* _pPageFrm,
                                       const SwRect& _rRect,
                                       PrepareHint _eHint );
};

#endif
<|endoftext|>


<commit_before>/******************************************************************************
 * Evatar_AutoFocus.cpp
 *
 * Author: Bryan D. Maione
 *
 * This application uses the Mantis camera API and OpenCV to Autofocus Mcams.
 *
 *****************************************************************************/
 /*  gcc -std=c++11 -o Evetar_AutoFocus Evetar_AutoFocus.cpp -lMantisAPI -lpthread -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lm -lstdc++
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#include "mantis/MantisAPI.h"

using namespace cv;
using namespace std;

void newMCamCallback(MICRO_CAMERA mcam, void* data)
{
    static int mcamCounter = 0;
    MICRO_CAMERA* mcamList = (MICRO_CAMERA*) data;
    mcamList[mcamCounter++] = mcam;
}

/**
 * \brief Function to handle recieving microcamera frames that just
 *        prints the mcam ID and timestamp of the received frame
 **/
void mcamFrameCallback(FRAME frame, void* data)
{
           ; //do nothing
}

/**
 * \ Main Function that steps the focus motors and computes a focus metric
 **/

int main()
{
    char ip[24] = "10.0.0.152";
    int port = 9999;
    mCamConnect(ip, port);
    initMCamFrameReceiver( 11001, 1 );

    /* get cameras from API */
    int numMCams = getNumberOfMCams();
    printf("API reported that there are %d microcameras available\n", numMCams);
    MICRO_CAMERA mcamList[numMCams];

    /* create new microcamera callback struct */
    NEW_MICRO_CAMERA_CALLBACK mcamCB;
    mcamCB.f = newMCamCallback;
    mcamCB.data = mcamList;

    /* call setNewMCamCallback; this function sets a callback that is
     * triggered each time a new microcamera is discovered by the API,
     * and also calls the callback function for each microcamera that
     * has already been discovered at the time of setting the callback */
    setNewMCamCallback(mcamCB);

    /* Next we set a callback function to receive the stream of frames
     * from the desired microcamera */
    MICRO_CAMERA_FRAME_CALLBACK frameCB;
    frameCB.f = mcamFrameCallback;
    frameCB.data = NULL;
    setMCamFrameCallback(frameCB);
    //MICRO_CAMERA myMCam = mcamList[0];

    /* now if we check our list, we should see a populated list
     * of MICRO_CAMERA objects */
    for( int i = 0; i < numMCams; i++ ){
        printf("Found mcam with ID %u\n", mcamList[i].mcamID);
        // Star the stream for each Mcam in the list
        if( !startMCamStream(mcamList[i], 11001+i) ){
        printf("Failed to start streaming mcam %u\n", mcamList[i].mcamID);
        exit(0);
        }
    }

    /* We only want to stream HD frame */
    for( int i = 0; i < numMCams; i++ ){
    setMCamStreamFilter(mcamList[i], 11001+i, ATL_SCALE_MODE_HD);
    }

    /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }
    sleep(1);
    int step = 100; //Doing a focus sweep with 100 step increments
    int numiter = 2300/step;
    double metric[numMCams] = {0};
    double metricprev[numMCams] = {0};
    double localbestmetric[numMCams] = {0};
    double globalbestmetric[numMCams] = {0};
    int globalbestpos[numMCams] = {0};

    /* Start the focus sweep for each micro camera connected to this tegra*/
    for ( int i = 0; i <= numiter-1; i++ ){
        cout << "Current Position: "+to_string(i*step) << "\n";

        /* Step each motor 100 steps */
        for (int j = 0; j < numMCams; j++){
            setMCamFocusFar(mcamList[j], step);
        }

        sleep(2);

        for (int j = 0; j < numMCams; j++){
            int edgeThresh = 1;
            int imgsize = 1920*1080;
        /*Ideally we want to get rid of this section and replace the saving and loading with a MantisAPI to OpenCV mat construction*/
            /**************************************/
            FRAME frame = grabMCamFrame(11001+j, 1.0 );
            if (!saveMCamFrame(frame, "focustmp")){
                printf("Unable to save frame\n");
                }
            /**************************************/
        /* The constructor should look something like this, I just couldn't get it to compile*/
        //loaded(1080, 1920,  CV_8UC1, frame.m_image,  size_t step = AUTO_STEP);

            Mat loaded,edge;
            loaded = imread("focustmp.jpeg",1);
            Canny(loaded, edge, edgeThresh, edgeThresh*100, 3);
            metric[j] = cv::sum( edge )[0]/imgsize;
            //imshow("Frame",loaded);
            //waitKey(1000);
            cout << "Current metric value: "+to_string(metric[j]) << "\n";
            /* If the metric increased update the best value and position */
            if ( metric[j] > metricprev[j]){
            cout << "metric value increased" << "\n";
            localbestmetric[j] = metric[j];
            /* If the current metric is the best we've seen yet, update as current best*/
                if ( localbestmetric[j] > globalbestmetric[j] ){
                cout << "Global best updated" << "\n";
                globalbestmetric[j] = localbestmetric[j];
                globalbestpos[j] = i+1;
                }
            }
            metricprev[j] = metric[j];
        }
    }
     /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }
    sleep(4);

    //For some reason have to send this command a second time -- Possible error state on motor
   /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }

    sleep(3);
    /* Bring each Mcam to best focus position*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusFar(mcamList[i], globalbestpos[i]*step);
    }
    sleep(3);
    for( int i = 0; i < numMCams; i++ ){
    closeMCamFrameReceiver( 11001+i );
    }
    mCamDisconnect(ip, port);

    cout << "Best Focus metric of: " + std::to_string(globalbestmetric[0]) + " at position: " + std::to_string(globalbestpos[0]) << "\n";
    exit(1);
}

<commit_msg>Updated code to pass image buffer directly to openCV.<commit_after>/******************************************************************************
 * Evatar_AutoFocus.cpp
 *
 * Author: Bryan D. Maione
 *
 * This application uses the Mantis camera API and OpenCV to Autofocus Mcams.
 *
 *****************************************************************************/
 /*  gcc -std=c++11 -o Evetar_AutoFocus Evetar_AutoFocus.cpp -lMantisAPI -lpthread -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lm -lstdc++
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#include "opencv2/core/mat.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#include "mantis/MantisAPI.h"

using namespace cv;
using namespace std;

void newMCamCallback(MICRO_CAMERA mcam, void* data)
{
    static int mcamCounter = 0;
    MICRO_CAMERA* mcamList = (MICRO_CAMERA*) data;
    mcamList[mcamCounter++] = mcam;
}

/**
 * \brief Function to handle recieving microcamera frames that just
 *        prints the mcam ID and timestamp of the received frame
 **/
void mcamFrameCallback(FRAME frame, void* data)
{
           ; //do nothing
}

//double calculateFocusMetric(uint8_t* img){
    /* Casting from image buffer goes here */
   // Mat edge;
   // Canny(img, edge, edgeThresh, edgeThresh*100, 3);
    //metric = cv::sum( edge )[0]/imgsize;
   // return metric;
//}

/**
 * \ Main Function that steps the focus motors and computes a focus metric
 **/

int main()
{
    char ip[24] = "10.0.0.152";
    int port = 9999;
    mCamConnect(ip, port);
    initMCamFrameReceiver( 13001, 1 );

    /* get cameras from API */
    int numMCams = getNumberOfMCams();
    printf("API reported that there are %d microcameras available\n", numMCams);
    MICRO_CAMERA mcamList[numMCams];

    /* create new microcamera callback struct */
    NEW_MICRO_CAMERA_CALLBACK mcamCB;
    mcamCB.f = newMCamCallback;
    mcamCB.data = mcamList;

    /* call setNewMCamCallback; this function sets a callback that is
     * triggered each time a new microcamera is discovered by the API,
     * and also calls the callback function for each microcamera that
     * has already been discovered at the time of setting the callback */
    setNewMCamCallback(mcamCB);

    /* Next we set a callback function to receive the stream of frames
     * from the desired microcamera */
    MICRO_CAMERA_FRAME_CALLBACK frameCB;
    frameCB.f = mcamFrameCallback;
    frameCB.data = NULL;
    setMCamFrameCallback(frameCB);
    //MICRO_CAMERA myMCam = mcamList[0];

    /* now if we check our list, we should see a populated list
     * of MICRO_CAMERA objects */
    for( int i = 0; i < numMCams; i++ ){
        printf("Found mcam with ID %u\n", mcamList[i].mcamID);
        // Star the stream for each Mcam in the list
        if( !startMCamStream(mcamList[i], 13001+i) ){
        printf("Failed to start streaming mcam %u\n", mcamList[i].mcamID);
        exit(0);
        }
    }

    /* We only want to stream HD frame */
    for( int i = 0; i < numMCams; i++ ){
    setMCamStreamFilter(mcamList[i], 13001+i, ATL_SCALE_MODE_HD);
    }

    /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }
    sleep(1);
    int step = 100; //Doing a focus sweep with 100 step increments
    int numiter = 2300/step;
    double metric[numMCams] = {0};
    double metricprev[numMCams] = {0};
    double localbestmetric[numMCams] = {0};
    double globalbestmetric[numMCams] = {0};
    int globalbestpos[numMCams] = {0};

    /* Start the focus sweep for each micro camera connected to this tegra*/
    for ( int i = 0; i <= numiter-1; i++ ){
        cout << "Current Position: "+to_string(i*step) << "\n";

        /* Step each motor 100 steps */
        for (int j = 0; j < numMCams; j++){
            setMCamFocusFar(mcamList[j], step);
        }

        sleep(1);

        for (int j = 0; j < numMCams; j++){
            int edgeThresh = 1;
            int imgsize = 1920*1080;
        /*Ideally we want to get rid of this section and replace the saving and loading with a MantisAPI to OpenCV mat construction*/
            /**************************************/
            FRAME frame = grabMCamFrame(13001+j, 1.0 );
            //if (!saveMCamFrame(frame, "focustmp")){
                //printf("Unable to save frame\n");
                //}
            /**************************************/
        /* The constructor should look something like this, I just couldn't get it to compile*/
            size_t step=CV_AUTO_STEP;
            Mat rawdata = Mat(1, frame.m_metadata.m_size ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
            Mat loaded = imdecode(rawdata,1);
            if (loaded.data==NULL){
                cerr << "Failed to decode data" <<"\n";
            }

            //imshow("Frame",loaded);
            //waitKey(1000);
            Mat edge;
            //loaded = imread("focustmp.jpeg",1);
            Canny(loaded, edge, edgeThresh, edgeThresh*100, 3);
            metric[j] = cv::sum( edge )[0]/imgsize;

            cout << "Current metric value: "+to_string(metric[j]) << "\n";
            /* If the metric increased update the best value and position */
            if ( metric[j] > metricprev[j]){
            cout << "metric value increased" << "\n";
            localbestmetric[j] = metric[j];
            /* If the current metric is the best we've seen yet, update as current best*/
                if ( localbestmetric[j] > globalbestmetric[j] ){
                cout << "Global best updated" << "\n";
                globalbestmetric[j] = localbestmetric[j];
                globalbestpos[j] = i+1;
                }
            }
            metricprev[j] = metric[j];
        }
    }/*End Coarse focus sweep*/

     /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }
    sleep(3);

    //For some reason have to send this command a second time -- Possible error state on motor
   /* Bring each Mcam to near focus*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusNear(mcamList[i], 0); // I currently have a modified moveFocusmotors.py that will go to "home" when given 0 for num steps
    }

    sleep(3);
    /* Bring each Mcam to best focus position*/
    for( int i = 0; i < numMCams; i++ ){
    setMCamFocusFar(mcamList[i], globalbestpos[i]*step);
    }
    sleep(4);
    for( int i = 0; i < numMCams; i++ ){
    closeMCamFrameReceiver( 13001+i );
    }
    mCamDisconnect(ip, port);

    cout << "Best Focus metric of: " + std::to_string(globalbestmetric[0]) + " at position: " + std::to_string(globalbestpos[0]) << "\n";
    exit(1);
    destroyAllWindows();
}

<|endoftext|>