<commit_before>/*  libscratch - Multipurpose objective C++ library.

    Copyright (c) 2015 Angelo Geels <spansjh@gmail.com>

    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 "CMemoryStream.h"

SCRATCH_NAMESPACE_BEGIN;

CMemoryStream::CMemoryStream(void)
{
  strm_pubBuffer = NULL;
  strm_ulPosition = 0;
  strm_ulSize = 0;
  strm_ulUsed = 0;
  AllocateMoreMemory(1024);
}

CMemoryStream::CMemoryStream(const CMemoryStream &copy)
{
  strm_pubBuffer = NULL;
  strm_ulPosition = 0;
  strm_ulSize = 0;
  strm_ulUsed = 0;
  AllocateMoreMemory(copy.strm_ulSize);
  memcpy(strm_pubBuffer, copy.strm_pubBuffer, copy.strm_ulSize);
  strm_ulPosition = copy.strm_ulPosition;
  strm_ulUsed = copy.strm_ulUsed;
}

CMemoryStream::~CMemoryStream(void)
{
  delete[] strm_pubBuffer;
}

ULONG CMemoryStream::Size()
{
  return strm_ulUsed;
}

ULONG CMemoryStream::Location()
{
  return strm_ulPosition;
}

void CMemoryStream::Seek(ULONG ulPos, INDEX iOrigin)
{
  switch(iOrigin) {
  case SEEK_CUR: strm_ulPosition += ulPos; break;
  case SEEK_END: strm_ulPosition = Size() + ulPos; break;
  case SEEK_SET: strm_ulPosition = ulPos; break;
  }
}

BOOL CMemoryStream::AtEOF()
{
  return Size() - Location() > 0;
}

void CMemoryStream::Write(const void* p, ULONG iLen)
{
  // check if we need a larger buffer
  if(strm_ulPosition + iLen >= strm_ulSize) {
    AllocateMoreMemory(Max<INDEX>(iLen, 1024));
  }

  // copy over memory
  memcpy(strm_pubBuffer + strm_ulPosition, p, iLen);

  // increase position
  strm_ulPosition += iLen;

  // update used counter
  strm_ulUsed = Max<ULONG>(strm_ulPosition, strm_ulUsed);
}

int CMemoryStream::Read(void* pDest, ULONG iLen)
{
  ULONG ulStart = strm_ulPosition;

  // increase position
  strm_ulPosition += iLen;

  // check boundaries
  if(strm_ulPosition > Size()) {
    strm_ulPosition = Size();
  }

  ULONG ulRealLength = strm_ulPosition - ulStart;

  // copy data to destination
  memcpy(pDest, strm_pubBuffer + strm_ulPosition, ulRealLength);

  return ulRealLength;
}

void CMemoryStream::AllocateMoreMemory(INDEX ctBytes)
{
  ASSERT(ctBytes > 0);

  // create new buffer and remember old one
  UBYTE* pubNewBuffer = new UBYTE[strm_ulSize + ctBytes];
  UBYTE* pubOldBuffer = strm_pubBuffer;

  // if there's old memory to copy
  if(pubOldBuffer != NULL && strm_ulSize > 0) {
    memcpy(pubNewBuffer, pubOldBuffer, strm_ulSize);
  }

  // increase the size count
  strm_ulSize += ctBytes;

  // set the new buffer pointer
  strm_pubBuffer = pubNewBuffer;

  // delete old memory
  if(pubOldBuffer != NULL) {
    delete[] pubOldBuffer;
  }
}

SCRATCH_NAMESPACE_END;
<commit_msg>Fixed bug with recent commit for CMemoryStream::Read<commit_after>/*  libscratch - Multipurpose objective C++ library.

    Copyright (c) 2015 Angelo Geels <spansjh@gmail.com>

    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 "CMemoryStream.h"

SCRATCH_NAMESPACE_BEGIN;

CMemoryStream::CMemoryStream(void)
{
  strm_pubBuffer = NULL;
  strm_ulPosition = 0;
  strm_ulSize = 0;
  strm_ulUsed = 0;
  AllocateMoreMemory(1024);
}

CMemoryStream::CMemoryStream(const CMemoryStream &copy)
{
  strm_pubBuffer = NULL;
  strm_ulPosition = 0;
  strm_ulSize = 0;
  strm_ulUsed = 0;
  AllocateMoreMemory(copy.strm_ulSize);
  memcpy(strm_pubBuffer, copy.strm_pubBuffer, copy.strm_ulSize);
  strm_ulPosition = copy.strm_ulPosition;
  strm_ulUsed = copy.strm_ulUsed;
}

CMemoryStream::~CMemoryStream(void)
{
  delete[] strm_pubBuffer;
}

ULONG CMemoryStream::Size()
{
  return strm_ulUsed;
}

ULONG CMemoryStream::Location()
{
  return strm_ulPosition;
}

void CMemoryStream::Seek(ULONG ulPos, INDEX iOrigin)
{
  switch(iOrigin) {
  case SEEK_CUR: strm_ulPosition += ulPos; break;
  case SEEK_END: strm_ulPosition = Size() + ulPos; break;
  case SEEK_SET: strm_ulPosition = ulPos; break;
  }
}

BOOL CMemoryStream::AtEOF()
{
  return Size() - Location() > 0;
}

void CMemoryStream::Write(const void* p, ULONG iLen)
{
  // check if we need a larger buffer
  if(strm_ulPosition + iLen >= strm_ulSize) {
    AllocateMoreMemory(Max<INDEX>(iLen, 1024));
  }

  // copy over memory
  memcpy(strm_pubBuffer + strm_ulPosition, p, iLen);

  // increase position
  strm_ulPosition += iLen;

  // update used counter
  strm_ulUsed = Max<ULONG>(strm_ulPosition, strm_ulUsed);
}

int CMemoryStream::Read(void* pDest, ULONG iLen)
{
  ULONG ulStart = strm_ulPosition;

  // increase position
  strm_ulPosition += iLen;

  // check boundaries
  if(strm_ulPosition > Size()) {
    strm_ulPosition = Size();
  }

  ULONG ulRealLength = strm_ulPosition - ulStart;

  // copy data to destination
  memcpy(pDest, strm_pubBuffer + ulStart, ulRealLength);

  return ulRealLength;
}

void CMemoryStream::AllocateMoreMemory(INDEX ctBytes)
{
  ASSERT(ctBytes > 0);

  // create new buffer and remember old one
  UBYTE* pubNewBuffer = new UBYTE[strm_ulSize + ctBytes];
  UBYTE* pubOldBuffer = strm_pubBuffer;

  // if there's old memory to copy
  if(pubOldBuffer != NULL && strm_ulSize > 0) {
    memcpy(pubNewBuffer, pubOldBuffer, strm_ulSize);
  }

  // increase the size count
  strm_ulSize += ctBytes;

  // set the new buffer pointer
  strm_pubBuffer = pubNewBuffer;

  // delete old memory
  if(pubOldBuffer != NULL) {
    delete[] pubOldBuffer;
  }
}

SCRATCH_NAMESPACE_END;
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "tile.h"

using namespace graphic;

cTile::cTile()
	: cNode(common::GenerateId(), "tile", eNodeType::TERRAIN)
	, m_isDbgRender(false)
	, m_location(-1,-1)
	, m_isHilight(false)
{
}

cTile::~cTile()
{
	Clear();
}

//
// rect =  3D-axis
//
//  z (rect.top, bottom)
//  |
//  |
//  |
//  + ---------> x (rect.left, right)
//
//
//   rect.left, top (X-Z axis)
//   * ---------------------------------- * rect.right, top (X-Z axis)
//   |                                    |
//   |                                    |
//   |                 +                  |
//   |               center               |
//   |                                    |
//   * ---------------------------------- * rect.right, bottom (X-Z axis)
//   rect.left, bottom (X-Z axis)
//
//
bool cTile::Create(cRenderer &renderer
	, const int id
	, const Str64 &name
	, const int row  // tile row index from terrain
	, const int col  // tile column index from terrain
	, const sRectf &rect // (x-z axis)
	, const char *textureFileName //= g_defaultTexture
	, const float uvFactor //= 1.f,
	, const Vector2 &uv0 //= Vector2(0, 0)
	, const Vector2 &uv1 //= Vector2(1, 1)
)
{
	m_id = id;
	m_name = name;
	m_location = Vector2i(row, col);
	SetRenderFlag(eRenderFlag::SHADOW, true);

	const float cellSize = rect.Width() / 2.f;
	m_ground = new cGrid();
	m_ground->Create(renderer, 16, 16, cellSize/8.f
		, (eVertexType::POSITION | eVertexType::NORMAL | eVertexType::TEXTURE)
		, cColor::WHITE, textureFileName, uv0, uv1, uvFactor
		, true);
	m_ground->SetRenderFlag(eRenderFlag::SHADOW, true);
	m_ground->SetOpFlag(eOpFlag::COLLISION, false);
	m_ground->m_isLineDrawing = true;
	//m_ground->m_transform.pos.y = -3.f;
	if (!textureFileName)
		m_ground->m_mtrl.InitWhite();
	AddChild(m_ground);

	m_transform.pos = Vector3(rect.left + cellSize, 0, rect.top + cellSize);
	m_boundingBox.SetBoundingBox(Vector3(0, 10, 0), Vector3(cellSize, cellSize, cellSize), Quaternion());
	CalcBoundingSphere();
	m_boundingBox.SetBoundingBox( Vector3(0,10,0), Vector3(cellSize, 20000, cellSize), Quaternion());

	return true;
}

bool cTile::Update(cRenderer &renderer, const float deltaSeconds)
{
	if (m_name == "4-5")
	{
		int a = 0;
	}

	return __super::Update(renderer, deltaSeconds);
}

void cTile::PreRender(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
)
{
	RET(!(m_renderFlags & eRenderFlag::SHADOW));
	RET(!m_isEnable);
	RET(!IsVisible());

	const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
	for (auto &p : m_children)
	{
		if (p->m_renderFlags & eRenderFlag::SHADOW)
			p->Render(renderer, transform, eRenderFlag::SHADOW);
	}
}

bool cTile::Render(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
	, const int flags //= 1
)
{
	RETV(!m_isEnable, false);
	RETV(!IsVisible(), false);

	if ((flags & 0x1) && m_isDbgRender)
		DebugRender(renderer, tm);

	if (m_isHilight)
	{
		const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
		renderer.m_dbgBox.SetBox(m_boundingBox);
		renderer.m_dbgBox.Render(renderer, transform);
	}

	return __super::Render(renderer, tm, flags);
}

void cTile::DebugRender(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
)
{
	const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
	renderer.m_dbgBox.SetBox(m_boundingBox);
	renderer.m_dbgBox.Render(renderer, transform);
}

// return frustum center to tile length
float cTile::CullingTest(const cFrustum &frustum
	, const XMMATRIX &tm //= XMIdentity
	, const bool isModel //= true
)
{
	RETV(!m_isEnable, false);

	const XMMATRIX transform = m_transform.GetMatrixXM()*tm;
	cBoundingSphere bsphere = m_boundingSphere * transform;
	if (frustum.IsInSphere(bsphere))
	{
		SetRenderFlag(eRenderFlag::VISIBLE, true);

		if (isModel)
		{
			for (auto &p : m_children)
				p->CullingTest(frustum, transform, isModel);
		}
		else
		{
			for (auto &p : m_children)
				p->SetRenderFlag(eRenderFlag::VISIBLE, true);
		}
	}
	else
	{
		SetRenderFlag(eRenderFlag::VISIBLE, false);
	}

	return frustum.LengthRoughly(m_boundingBox.Center() * transform);
}

bool cTile::AddChild(cNode *node)
{
	return __super::AddChild(node);
}

bool cTile::RemoveChild(cNode *rmNode
	, const bool rmInstance //= true
)
{
	return __super::RemoveChild(rmNode, rmInstance);
}

cNode* cTile::FindNode(const int id)
{
	return __super::FindNode(id);
}

void cTile::UpdatePosition(const sRectf &rect)
{
	const float cellSize = rect.Width() / 2.f;
	m_transform.pos = Vector3(rect.left + cellSize, 0, rect.top + cellSize);
	m_boundingBox.SetBoundingBox(Vector3(0, 10, 0), Vector3(cellSize, 20, cellSize), Quaternion());
	CalcBoundingSphere();
}

void cTile::Clear()
{
}
<commit_msg>update Graphic11, terrain<commit_after>#include "stdafx.h"
#include "tile.h"

using namespace graphic;

cTile::cTile()
	: cNode(common::GenerateId(), "tile", eNodeType::TERRAIN)
	, m_isDbgRender(false)
	, m_location(-1,-1)
	, m_isHilight(false)
{
}

cTile::~cTile()
{
	Clear();
}

//
// rect =  3D-axis
//
//  z (rect.top, bottom)
//  |
//  |
//  |
//  + ---------> x (rect.left, right)
//
//
//   rect.left, top (X-Z axis)
//   * ---------------------------------- * rect.right, top (X-Z axis)
//   |                                    |
//   |                                    |
//   |                 +                  |
//   |               center               |
//   |                                    |
//   * ---------------------------------- * rect.right, bottom (X-Z axis)
//   rect.left, bottom (X-Z axis)
//
//
bool cTile::Create(cRenderer &renderer
	, const int id
	, const Str64 &name
	, const int row  // tile row index from terrain
	, const int col  // tile column index from terrain
	, const sRectf &rect // (x-z axis)
	, const char *textureFileName //= g_defaultTexture
	, const float uvFactor //= 1.f,
	, const Vector2 &uv0 //= Vector2(0, 0)
	, const Vector2 &uv1 //= Vector2(1, 1)
)
{
	m_id = id;
	m_name = name;
	m_location = Vector2i(row, col);
	SetRenderFlag(eRenderFlag::SHADOW, true);

	const float cellSize = rect.Width() / 2.f;
	m_ground = new cGrid();
	m_ground->Create(renderer, 16, 16, cellSize/8.f
		, (eVertexType::POSITION | eVertexType::NORMAL | eVertexType::TEXTURE)
		, cColor::WHITE, textureFileName, uv0, uv1, uvFactor
		, true);
	m_ground->SetRenderFlag(eRenderFlag::SHADOW, true);
	m_ground->SetOpFlag(eOpFlag::COLLISION, false);
	m_ground->m_isLineDrawing = true;
	//m_ground->m_transform.pos.y = -3.f;
	if (!textureFileName)
		m_ground->m_mtrl.InitWhite();
	AddChild(m_ground);

	m_transform.pos = Vector3(rect.left + cellSize, 0, rect.top + cellSize);
	m_boundingBox.SetBoundingBox(Vector3(0, 0, 0), Vector3(cellSize, cellSize, cellSize), Quaternion());
	CalcBoundingSphere();
	m_boundingBox.SetBoundingBox( Vector3(0,0,0), Vector3(cellSize, 20000, cellSize), Quaternion());

	return true;
}

bool cTile::Update(cRenderer &renderer, const float deltaSeconds)
{
	if (m_name == "4-5")
	{
		int a = 0;
	}

	return __super::Update(renderer, deltaSeconds);
}

void cTile::PreRender(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
)
{
	RET(!(m_renderFlags & eRenderFlag::SHADOW));
	RET(!m_isEnable);
	RET(!IsVisible());

	const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
	for (auto &p : m_children)
	{
		if (p->m_renderFlags & eRenderFlag::SHADOW)
			p->Render(renderer, transform, eRenderFlag::SHADOW);
	}
}

bool cTile::Render(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
	, const int flags //= 1
)
{
	RETV(!m_isEnable, false);
	RETV(!IsVisible(), false);

	if ((flags & 0x1) && m_isDbgRender)
		DebugRender(renderer, tm);

	if (m_isHilight)
	{
		const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
		renderer.m_dbgBox.SetBox(m_boundingBox);
		renderer.m_dbgBox.Render(renderer, transform);
	}

	return __super::Render(renderer, tm, flags);
}

void cTile::DebugRender(cRenderer &renderer
	, const XMMATRIX &tm //= XMIdentity
)
{
	const XMMATRIX transform = m_transform.GetMatrixXM() * tm;
	renderer.m_dbgBox.SetBox(m_boundingBox);
	renderer.m_dbgBox.Render(renderer, transform);
}

// return frustum center to tile length
float cTile::CullingTest(const cFrustum &frustum
	, const XMMATRIX &tm //= XMIdentity
	, const bool isModel //= true
)
{
	RETV(!m_isEnable, false);

	const XMMATRIX transform = m_transform.GetMatrixXM()*tm;
	cBoundingSphere bsphere = m_boundingSphere * transform;
	if (frustum.IsInSphere(bsphere))
	{
		SetRenderFlag(eRenderFlag::VISIBLE, true);

		if (isModel)
		{
			for (auto &p : m_children)
				p->CullingTest(frustum, transform, isModel);
		}
		else
		{
			for (auto &p : m_children)
				p->SetRenderFlag(eRenderFlag::VISIBLE, true);
		}
	}
	else
	{
		SetRenderFlag(eRenderFlag::VISIBLE, false);
	}

	return frustum.LengthRoughly(m_boundingBox.Center() * transform);
}

bool cTile::AddChild(cNode *node)
{
	return __super::AddChild(node);
}

bool cTile::RemoveChild(cNode *rmNode
	, const bool rmInstance //= true
)
{
	return __super::RemoveChild(rmNode, rmInstance);
}

cNode* cTile::FindNode(const int id)
{
	return __super::FindNode(id);
}

void cTile::UpdatePosition(const sRectf &rect)
{
	const float cellSize = rect.Width() / 2.f;
	m_transform.pos = Vector3(rect.left + cellSize, 0, rect.top + cellSize);
	m_boundingBox.SetBoundingBox(Vector3(0, 10, 0), Vector3(cellSize, 20, cellSize), Quaternion());
	CalcBoundingSphere();
}

void cTile::Clear()
{
}
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#include <ios>
#include <cstring>
#include <errno.h>
#include <iostream>

#include "cppa/exception.hpp"
#include "cppa/detail/ipv4_io_stream.hpp"

#ifdef CPPA_WINDOWS
#else
#   include <netdb.h>
#   include <unistd.h>
#   include <sys/types.h>
#   include <sys/socket.h>
#   include <netinet/in.h>
#   include <netinet/tcp.h>
#   include <fcntl.h>
#endif

namespace cppa { namespace detail {

namespace {

template<typename T>
void handle_syscall_result(T result, bool is_recv_result) {
    if (result < 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            char* cstr = strerror(errno);
            std::string errmsg = cstr;
            errmsg += " [errno = ";
            errmsg += std::to_string(errno);
            errmsg += "]";
std::cerr << errmsg << std::endl;
            throw std::ios_base::failure(std::move(errmsg));
        }
    }
    else if (result == 0 && is_recv_result) {
        throw std::ios_base::failure("cannot read from closed socket");
    }
}

int rd_flags(native_socket_type fd) {
    auto flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
        throw network_error("unable to read socket flags");
    }
    return flags;
}

void set_nonblocking(native_socket_type fd) {
    auto flags = rd_flags(fd);
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
        throw network_error("unable to set socket to nonblock");
    }
}

} // namespace <anonymous>

ipv4_io_stream::ipv4_io_stream(native_socket_type fd) : m_fd(fd) { }

native_socket_type ipv4_io_stream::read_file_handle() const {
    return m_fd;
}

native_socket_type ipv4_io_stream::write_file_handle() const {
    return m_fd;
}

void ipv4_io_stream::read(void* vbuf, size_t len) {
    auto buf = reinterpret_cast<char*>(vbuf);
    size_t rd = 0;
    while (rd < len) {
        auto recv_result = ::recv(m_fd, buf + rd, len - rd, 0);
        handle_syscall_result(recv_result, true);
        if (recv_result > 0) {
            rd += static_cast<size_t>(recv_result);
        }
        if (rd < len) {
            fd_set rdset;
            FD_ZERO(&rdset);
            FD_SET(m_fd, &rdset);
            if (select(m_fd + 1, &rdset, nullptr, nullptr, nullptr) < 0) {
                throw network_error("select() failed");
            }
        }
    }
}

size_t ipv4_io_stream::read_some(void* buf, size_t len) {
    auto recv_result = ::recv(m_fd, buf, len, 0);
    handle_syscall_result(recv_result, true);
    return (recv_result > 0) ? static_cast<size_t>(recv_result) : 0;
}

void ipv4_io_stream::write(const void* vbuf, size_t len) {
    auto buf = reinterpret_cast<const char*>(vbuf);
    size_t written = 0;
    while (written < len) {
        auto send_result = ::send(m_fd, buf + written, len - written, 0);
        handle_syscall_result(send_result, false);
        if (send_result > 0) {
            written += static_cast<size_t>(send_result);
        }
        if (written < len) {
            // block until socked is writable again
            fd_set wrset;
            FD_ZERO(&wrset);
            FD_SET(m_fd, &wrset);
            if (select(m_fd + 1, nullptr, &wrset, nullptr, nullptr) < 0) {
                throw network_error("select() failed");
            }
        }
    }
}

size_t ipv4_io_stream::write_some(const void* buf, size_t len) {
    auto send_result = ::send(m_fd, buf, len, 0);
    handle_syscall_result(send_result, false);
    return static_cast<size_t>(send_result);
}

util::io_stream_ptr ipv4_io_stream::from_native_socket(native_socket_type fd) {
    set_nonblocking(fd);
    return new ipv4_io_stream(fd);
}

util::io_stream_ptr ipv4_io_stream::connect_to(const char* host,
                                               std::uint16_t port) {
    native_socket_type sockfd;
    struct sockaddr_in serv_addr;
    struct hostent* server;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == invalid_socket) {
        throw network_error("socket creation failed");
    }
    server = gethostbyname(host);
    if (!server) {
        std::string errstr = "no such host: ";
        errstr += host;
        throw network_error(std::move(errstr));
    }
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
    serv_addr.sin_port = htons(port);
    if (connect(sockfd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
        throw network_error("could not connect to host");
    }
    int flags = 1;
    setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
    set_nonblocking(sockfd);
    return new ipv4_io_stream(sockfd);
}

} } // namespace cppa::detail
<commit_msg>removed debug output<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#include <ios>
#include <cstring>
#include <errno.h>
#include <iostream>

#include "cppa/exception.hpp"
#include "cppa/detail/ipv4_io_stream.hpp"

#ifdef CPPA_WINDOWS
#else
#   include <netdb.h>
#   include <unistd.h>
#   include <sys/types.h>
#   include <sys/socket.h>
#   include <netinet/in.h>
#   include <netinet/tcp.h>
#   include <fcntl.h>
#endif

namespace cppa { namespace detail {

namespace {

template<typename T>
void handle_syscall_result(T result, bool is_recv_result) {
    if (result < 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            char* cstr = strerror(errno);
            std::string errmsg = cstr;
            errmsg += " [errno = ";
            errmsg += std::to_string(errno);
            errmsg += "]";
            throw std::ios_base::failure(std::move(errmsg));
        }
    }
    else if (result == 0 && is_recv_result) {
        throw std::ios_base::failure("cannot read from closed socket");
    }
}

int rd_flags(native_socket_type fd) {
    auto flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
        throw network_error("unable to read socket flags");
    }
    return flags;
}

void set_nonblocking(native_socket_type fd) {
    auto flags = rd_flags(fd);
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
        throw network_error("unable to set socket to nonblock");
    }
}

} // namespace <anonymous>

ipv4_io_stream::ipv4_io_stream(native_socket_type fd) : m_fd(fd) { }

native_socket_type ipv4_io_stream::read_file_handle() const {
    return m_fd;
}

native_socket_type ipv4_io_stream::write_file_handle() const {
    return m_fd;
}

void ipv4_io_stream::read(void* vbuf, size_t len) {
    auto buf = reinterpret_cast<char*>(vbuf);
    size_t rd = 0;
    while (rd < len) {
        auto recv_result = ::recv(m_fd, buf + rd, len - rd, 0);
        handle_syscall_result(recv_result, true);
        if (recv_result > 0) {
            rd += static_cast<size_t>(recv_result);
        }
        if (rd < len) {
            fd_set rdset;
            FD_ZERO(&rdset);
            FD_SET(m_fd, &rdset);
            if (select(m_fd + 1, &rdset, nullptr, nullptr, nullptr) < 0) {
                throw network_error("select() failed");
            }
        }
    }
}

size_t ipv4_io_stream::read_some(void* buf, size_t len) {
    auto recv_result = ::recv(m_fd, buf, len, 0);
    handle_syscall_result(recv_result, true);
    return (recv_result > 0) ? static_cast<size_t>(recv_result) : 0;
}

void ipv4_io_stream::write(const void* vbuf, size_t len) {
    auto buf = reinterpret_cast<const char*>(vbuf);
    size_t written = 0;
    while (written < len) {
        auto send_result = ::send(m_fd, buf + written, len - written, 0);
        handle_syscall_result(send_result, false);
        if (send_result > 0) {
            written += static_cast<size_t>(send_result);
        }
        if (written < len) {
            // block until socked is writable again
            fd_set wrset;
            FD_ZERO(&wrset);
            FD_SET(m_fd, &wrset);
            if (select(m_fd + 1, nullptr, &wrset, nullptr, nullptr) < 0) {
                throw network_error("select() failed");
            }
        }
    }
}

size_t ipv4_io_stream::write_some(const void* buf, size_t len) {
    auto send_result = ::send(m_fd, buf, len, 0);
    handle_syscall_result(send_result, false);
    return static_cast<size_t>(send_result);
}

util::io_stream_ptr ipv4_io_stream::from_native_socket(native_socket_type fd) {
    set_nonblocking(fd);
    return new ipv4_io_stream(fd);
}

util::io_stream_ptr ipv4_io_stream::connect_to(const char* host,
                                               std::uint16_t port) {
    native_socket_type sockfd;
    struct sockaddr_in serv_addr;
    struct hostent* server;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == invalid_socket) {
        throw network_error("socket creation failed");
    }
    server = gethostbyname(host);
    if (!server) {
        std::string errstr = "no such host: ";
        errstr += host;
        throw network_error(std::move(errstr));
    }
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
    serv_addr.sin_port = htons(port);
    if (connect(sockfd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
        throw network_error("could not connect to host");
    }
    int flags = 1;
    setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
    set_nonblocking(sockfd);
    return new ipv4_io_stream(sockfd);
}

} } // namespace cppa::detail
<|endoftext|>


<commit_before>/*
    Copyright (C) 2012  Lasath Fernando <kde@lasath.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "message.h"
#include <KDebug>

Message::Message(const Tp::Message &original) :
      m_sentTime(original.sent()),
      m_token(original.messageToken()),
      m_messageType(original.messageType())
{
    setMainMessagePart(original.text());
}

#ifdef TELEPATHY_LOGGER_QT4_FOUND
Message::Message(const Tpl::TextEventPtr &original) :
    m_sentTime(original->timestamp()),
    m_token(original->messageToken()),
    m_messageType(original->messageType())
{
    setMainMessagePart(original->message());
}
#endif

QString Message::mainMessagePart() const
{
    return m_mainPart;
}

void Message::setMainMessagePart(const QString& message)
{
    m_mainPart = message;
}

void Message::appendMessagePart(const QString& part)
{
    m_parts << part;
}

void Message::appendScript(const QString& script)
{
    m_scripts << script;
}

QString Message::finalizedMessage() const
{
    QString msg = m_mainPart + QLatin1String("\n") +
        m_parts.join(QLatin1String("\n"));

//     kDebug() << msg;
    return msg;
}

QString Message::finalizedScript() const
{
    if (m_scripts.empty()) {
        return QString();
    }

    QString finalScript;

    Q_FOREACH(const QString &script, m_scripts) {
        if (!finalScript.contains(script)) {
            if (!finalScript.isEmpty()) {
                finalScript.append(QLatin1String("; "));
            }
            finalScript.append(script);
        }
    }
    if (!finalScript.isEmpty()) {
        finalScript.append(QLatin1String("; false;"));
    }

    kDebug() << finalScript;
    return finalScript;
}

QVariant Message::property(const char *name) const
{
    return m_properties[QLatin1String(name)];
}

void Message::setProperty(const char *name, const QVariant& value)
{
    m_properties[QLatin1String(name)] = value;
}

QDateTime Message::time() const
{
    return m_sentTime;
}

QString Message::token() const
{
    return m_token;
}

Tp::ChannelTextMessageType Message::type() const
{
    return m_messageType;
}

int Message::partsSize() const
{
    return m_parts.size();
}
<commit_msg>Execute the script after appending a message<commit_after>/*
    Copyright (C) 2012  Lasath Fernando <kde@lasath.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "message.h"
#include <KDebug>

Message::Message(const Tp::Message &original) :
      m_sentTime(original.sent()),
      m_token(original.messageToken()),
      m_messageType(original.messageType())
{
    setMainMessagePart(original.text());
}

#ifdef TELEPATHY_LOGGER_QT4_FOUND
Message::Message(const Tpl::TextEventPtr &original) :
    m_sentTime(original->timestamp()),
    m_token(original->messageToken()),
    m_messageType(original->messageType())
{
    setMainMessagePart(original->message());
}
#endif

QString Message::mainMessagePart() const
{
    return m_mainPart;
}

void Message::setMainMessagePart(const QString& message)
{
    m_mainPart = message;
}

void Message::appendMessagePart(const QString& part)
{
    m_parts << part;
}

void Message::appendScript(const QString& script)
{
    m_scripts << script;
}

QString Message::finalizedMessage() const
{
    QString msg = m_mainPart + QLatin1String("\n") +
        m_parts.join(QLatin1String("\n"));

//     kDebug() << msg;
    return msg;
}

QString Message::finalizedScript() const
{
    if (m_scripts.empty()) {
        return QString();
    }

    QString finalScript;

    Q_FOREACH(const QString &script, m_scripts) {
        if (!finalScript.contains(script)) {
            finalScript.append(script);
        }
    }
    if (!finalScript.isEmpty()) {
        finalScript.append(QLatin1String("false;"));
    }

//    kDebug() << finalScript;
    return finalScript;
}

QVariant Message::property(const char *name) const
{
    return m_properties[QLatin1String(name)];
}

void Message::setProperty(const char *name, const QVariant& value)
{
    m_properties[QLatin1String(name)] = value;
}

QDateTime Message::time() const
{
    return m_sentTime;
}

QString Message::token() const
{
    return m_token;
}

Tp::ChannelTextMessageType Message::type() const
{
    return m_messageType;
}

int Message::partsSize() const
{
    return m_parts.size();
}
<|endoftext|>


<commit_before>/*!
	@file NeoPixelStripGroup.cpp
  	@brief This code allows control of multiple LED strips as one
	@details This class supports jagged groups. This means that the strips can
		be different lengths, though if a strip doesn't have a pixel at an index
		that pixel will be skipped/ignored using the Adafruit_NeoPixel library.
*/

#include "NeoPixelStripManager.hpp"

/*!
	@brief Add a new strip to the group
	@details Strips can be of different lengths but all must be of the same
		color type.
	@param[in] strip The NeoPixel strip to add to the group
*/
void NeoPixelStripGroup::addStrip(Adafruit_NeoPixel* strip) {
	if (longestStripLength == 0) {
		longestStrip = strips.size();
		longestStripLength = strip->numPixels();
	} else if (strip->numPixels() > longestStripLength) {
			longestStrip = strips.size();
			longestStripLength = strip->numPixels();
		}
	}

	this->strips.push_back(strip);
}

/*!
	@brief Get the number of strips
	@return The number of strips in the group
*/
int NeoPixelStripGroup::numStrips() const { return this->strips.size(); };

/*!
	@brief Show all of the member strips
*/
void NeoPixelStripGroup::show() {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].show();
	}
}

/*!
	@brief Set the pixel color
	@param[in] n Index of pixel
	@param[in] r Red component
	@param[in] g Blue component
	@param[in] b Green component
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].setPixelColor(n, r, g, b);
	}
}

/*!
	@brief Set the pixel color
	@details Validates RGBW support before executing.
	@param[in] n Index of pixel
	@param[in] r Red component
	@param[in] g Blue component
	@param[in] b Green component
	@param[in] w White component
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
	if (rgbw) {
		for (unsigned int i = 0; i < strips.size(); i++) {
			strips[i].setPixelColor(n, r, g, b, w);
		}
	}
}

/*!
	@brief Set the pixel color
	@param[in] n Index of pixel
	@param[in] c 32-bit color
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint32_t c) {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].setPixelColor(n, c);
	}
}

/*!
	@brief Get the pixel color at pixel n
	@details If strips are not of the same length, the function will attempt to
		find a strip with a pixel at that position, otherwise it will return 0.
	@param[in] The index of the pixel
	@return The pixel color
*/
uint32_t NeoPixelStripGroup::getPixelColor(uint16_t n) {
	if (n >= longestStripLength) {
		return 0;
	} else {
		return strips[longestStrip]->getPixelColor(n);
	}
}
<commit_msg>fixed typo<commit_after>/*!
	@file NeoPixelStripGroup.cpp
  	@brief This code allows control of multiple LED strips as one
	@details This class supports jagged groups. This means that the strips can
		be different lengths, though if a strip doesn't have a pixel at an index
		that pixel will be skipped/ignored using the Adafruit_NeoPixel library.
*/

#include "NeoPixelStripGroup.hpp"

/*!
	@brief Add a new strip to the group
	@details Strips can be of different lengths but all must be of the same
		color type.
	@param[in] strip The NeoPixel strip to add to the group
*/
void NeoPixelStripGroup::addStrip(Adafruit_NeoPixel* strip) {
	if (longestStripLength == 0) {
		longestStrip = strips.size();
		longestStripLength = strip->numPixels();
	} else if (strip->numPixels() > longestStripLength) {
			longestStrip = strips.size();
			longestStripLength = strip->numPixels();
		}
	}

	this->strips.push_back(strip);
}

/*!
	@brief Get the number of strips
	@return The number of strips in the group
*/
int NeoPixelStripGroup::numStrips() const { return this->strips.size(); };

/*!
	@brief Show all of the member strips
*/
void NeoPixelStripGroup::show() {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].show();
	}
}

/*!
	@brief Set the pixel color
	@param[in] n Index of pixel
	@param[in] r Red component
	@param[in] g Blue component
	@param[in] b Green component
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].setPixelColor(n, r, g, b);
	}
}

/*!
	@brief Set the pixel color
	@details Validates RGBW support before executing.
	@param[in] n Index of pixel
	@param[in] r Red component
	@param[in] g Blue component
	@param[in] b Green component
	@param[in] w White component
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
	if (rgbw) {
		for (unsigned int i = 0; i < strips.size(); i++) {
			strips[i].setPixelColor(n, r, g, b, w);
		}
	}
}

/*!
	@brief Set the pixel color
	@param[in] n Index of pixel
	@param[in] c 32-bit color
*/
void NeoPixelStripGroup::setPixelColor(uint16_t n, uint32_t c) {
	for (unsigned int i = 0; i < strips.size(); i++) {
		strips[i].setPixelColor(n, c);
	}
}

/*!
	@brief Get the pixel color at pixel n
	@details If strips are not of the same length, the function will attempt to
		find a strip with a pixel at that position, otherwise it will return 0.
	@param[in] The index of the pixel
	@return The pixel color
*/
uint32_t NeoPixelStripGroup::getPixelColor(uint16_t n) {
	if (n >= longestStripLength) {
		return 0;
	} else {
		return strips[longestStrip]->getPixelColor(n);
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 AUV-IITK
#include <ros/ros.h>
#include <std_msgs/Float32.h>
#include <std_msgs/Float64.h>
#include <std_msgs/Int32.h>
#include <std_msgs/String.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Float64MultiArray.h>
#include <actionlib/server/simple_action_server.h>
#include <actionlib/client/simple_action_client.h>
#include <task_commons/buoyAction.h>
#include <motion_commons/ForwardAction.h>
#include <motion_commons/TurnAction.h>
#include <motion_commons/SidewardAction.h>
#include <motion_commons/UpwardAction.h>
#include <motion_commons/ForwardActionFeedback.h>
#include <motion_commons/TurnActionFeedback.h>
#include <motion_commons/SidewardActionFeedback.h>
#include <motion_commons/UpwardActionFeedback.h>
#include <motion_commons/UpwardActionResult.h>
#include <motion_commons/SidewardActionResult.h>
#include <string>

typedef actionlib::SimpleActionServer<task_commons::buoyAction> Server;
typedef actionlib::SimpleActionClient<motion_commons::ForwardAction> ClientForward;
typedef actionlib::SimpleActionClient<motion_commons::SidewardAction> ClientSideward;
typedef actionlib::SimpleActionClient<motion_commons::UpwardAction> ClientUpward;
typedef actionlib::SimpleActionClient<motion_commons::TurnAction> ClientTurn;

class TaskBuoyInnerClass
{
private:
  ros::NodeHandle nh_;
  Server buoy_server_;
  std::string action_name_;
  std_msgs::Float64 data_X_;
  std_msgs::Float64 data_Y_;
  std_msgs::Float64 data_distance_;
  task_commons::buoyFeedback feedback_;
  task_commons::buoyResult result_;
  ros::Subscriber sub_ip_;
  ros::Subscriber yaw_sub_;
  ros::Publisher switch_buoy_detection;
  ros::Publisher yaw_pub_;
  ros::Publisher present_distance_;
  ros::Publisher present_X_;
  ros::Publisher present_Y_;
  ClientForward ForwardClient_;
  ClientSideward SidewardClient_;
  ClientUpward UpwardClient_;
  ClientTurn TurnClient_;
  motion_commons::ForwardGoal forwardgoal;
  motion_commons::SidewardGoal sidewardgoal;
  motion_commons::UpwardGoal upwardgoal;
  motion_commons::TurnGoal turngoal;
  bool successBuoy, heightCenter, sideCenter, IP_stopped, heightGoal;
  float present_depth;

public:
  TaskBuoyInnerClass(std::string name, std::string node, std::string node1, std::string node2, std::string node3)
    : buoy_server_(nh_, name, boost::bind(&TaskBuoyInnerClass::analysisCB, this, _1), false)
    , action_name_(name)
    , ForwardClient_(node)
    , SidewardClient_(node1)
    , UpwardClient_(node2)
    , TurnClient_(node3)
  {
    ROS_INFO("%s inside constructor", action_name_.c_str());
    buoy_server_.registerPreemptCallback(boost::bind(&TaskBuoyInnerClass::preemptCB, this));

    switch_buoy_detection = nh_.advertise<std_msgs::Bool>("buoy_detection_switch", 1000);
    present_X_ = nh_.advertise<std_msgs::Float64>("/varun/motion/y_distance", 1000);
    present_Y_ = nh_.advertise<std_msgs::Float64>("/varun/motion/z_distance", 1000);
    present_distance_ = nh_.advertise<std_msgs::Float64>("/varun/motion/x_distance", 1000);
    yaw_pub_ = nh_.advertise<std_msgs::Float64>("/varun/motion/yaw", 1000);
    sub_ip_ =
        nh_.subscribe<std_msgs::Float64MultiArray>("/varun/ip/buoy", 1000, &TaskBuoyInnerClass::buoyNavigation, this);
    yaw_sub_ = nh_.subscribe<std_msgs::Float64>("/varun/sensors/imu/yaw", 1000, &TaskBuoyInnerClass::yawCB, this);
    buoy_server_.start();
  }

  ~TaskBuoyInnerClass(void)
  {
  }

  void yawCB(std_msgs::Float64 imu_data)
  {
    yaw_pub_.publish(imu_data);
  }

  void buoyNavigation(std_msgs::Float64MultiArray array)
  {
    data_X_.data = array.data[1];
    data_Y_.data = array.data[2];
    data_distance_.data = array.data[3];

    if (data_distance_.data > 0)
    {
      present_distance_.publish(data_distance_);
      present_X_.publish(data_X_);
      present_Y_.publish(data_Y_);
    }

    // if distance is -1 to -4 then buoy is out of frame and the motion library will assume the last data.
    else if (data_distance_.data == -5)
    {
      IP_stopped = true;
      stopBuoyDetection();
      ROS_INFO("%s Bot is in front of buoy, IP stopped.", action_name_.c_str());
    }
  }

  void preemptCB(void)
  {
    // Not actually preempting the goal because Prakhar did it in analysisCB
    ROS_INFO("Called when preempted from the client");
  }

  void spinThreadUpwardCamera()
  {
    ClientUpward &tempUpward = UpwardClient_;
    tempUpward.waitForResult();
    heightCenter = (*(tempUpward.getResult())).Result;
    if (heightCenter)
    {
      ROS_INFO("%s Bot is at height center", action_name_.c_str());
    }
    else
    {
      ROS_INFO("%s Bot is not at height center, something went wrong", action_name_.c_str());
    }
  }

  void spinThreadSidewardCamera()
  {
    ClientSideward &tempSideward = SidewardClient_;
    tempSideward.waitForResult();
    sideCenter = (*(tempSideward.getResult())).Result;
    if (sideCenter)
    {
      ROS_INFO("%s Bot is at side center", action_name_.c_str());
    }
    else
    {
      ROS_INFO("%s Bot is not at side center, something went wrong", action_name_.c_str());
    }
  }

  void analysisCB(const task_commons::buoyGoalConstPtr goal)
  {
    ROS_INFO("Inside analysisCB");
    heightCenter = false;
    sideCenter = false;
    successBuoy = false;
    IP_stopped = false;
    heightGoal = false;
    ros::Rate looprate(12);
    if (!buoy_server_.isActive())
      return;

    ROS_INFO("%s Waiting for Forward server to start.", action_name_.c_str());
    ForwardClient_.waitForServer();
    SidewardClient_.waitForServer();
    UpwardClient_.waitForServer();
    TurnClient_.waitForServer();

    TaskBuoyInnerClass::startBuoyDetection();

    sidewardgoal.Goal = 0;
    sidewardgoal.loop = 10;
    SidewardClient_.sendGoal(sidewardgoal);
    boost::thread spin_thread_sideward_camera(&TaskBuoyInnerClass::spinThreadSidewardCamera, this);

    // Stabilization of yaw
    turngoal.AngleToTurn = 0;
    turngoal.loop = 100000;
    TurnClient_.sendGoal(turngoal);

    upwardgoal.Goal = 0;
    upwardgoal.loop = 10;
    UpwardClient_.sendGoal(upwardgoal);
    boost::thread spin_thread_upward_camera(&TaskBuoyInnerClass::spinThreadUpwardCamera, this);
    ROS_INFO("%s: finding buoy", action_name_.c_str());

    while (goal->order)
    {
      if (buoy_server_.isPreemptRequested() || !ros::ok())
      {
        ROS_INFO("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        buoy_server_.setPreempted();
        successBuoy = false;
        break;
      }
      looprate.sleep();
      if (heightCenter && sideCenter)
      {
        break;
      }
      // publish the feedback
      feedback_.x_coord = data_X_.data;
      feedback_.y_coord = data_Y_.data;
      feedback_.distance = data_distance_.data;
      buoy_server_.publishFeedback(feedback_);
      ros::spinOnce();
    }

    ROS_INFO("%s: Bot is in center of buoy", action_name_.c_str());
    forwardgoal.Goal = 0;
    forwardgoal.loop = 10;
    ForwardClient_.sendGoal(forwardgoal);
    ROS_INFO("%s: Bot is moving forward to hit the buoy", action_name_.c_str());

    while (goal->order)
    {
      if (buoy_server_.isPreemptRequested() || !ros::ok())
      {
        ROS_INFO("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        buoy_server_.setPreempted();
        successBuoy = false;
        break;
      }
      looprate.sleep();

      if (IP_stopped)
      {
        successBuoy = true;
        ROS_INFO("%s: Waiting for hitting the buoy...", action_name_.c_str());
        // sleep(1);
        break;
      }

      feedback_.x_coord = data_X_.data;
      feedback_.y_coord = data_Y_.data;
      feedback_.distance = data_distance_.data;
      buoy_server_.publishFeedback(feedback_);
      ros::spinOnce();
    }

    ForwardClient_.cancelGoal();  // stop motion here

    result_.MotionCompleted = successBuoy;
    ROS_INFO("%s: Succeeded", action_name_.c_str());
    // set the action state to succeeded
    buoy_server_.setSucceeded(result_);
  }

  void startBuoyDetection()
  {
    std_msgs::Bool msg;
    msg.data = false;
    switch_buoy_detection.publish(msg);
  }

  void stopBuoyDetection()
  {
    std_msgs::Bool msg;
    msg.data = true;
    switch_buoy_detection.publish(msg);
  }
};

int main(int argc, char **argv)
{
  ros::init(argc, argv, "buoy_server");
  ROS_INFO("Waiting for Goal");
  TaskBuoyInnerClass taskBuoyObject(ros::this_node::getName(), "forward", "sideward", "upward", "turningXY");
  ros::spin();
  return 0;
}
<commit_msg>upward and sideward centralization seperated<commit_after>// Copyright 2016 AUV-IITK
#include <ros/ros.h>
#include <std_msgs/Float32.h>
#include <std_msgs/Float64.h>
#include <std_msgs/Int32.h>
#include <std_msgs/String.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Float64MultiArray.h>
#include <actionlib/server/simple_action_server.h>
#include <actionlib/client/simple_action_client.h>
#include <task_commons/buoyAction.h>
#include <motion_commons/ForwardAction.h>
#include <motion_commons/TurnAction.h>
#include <motion_commons/SidewardAction.h>
#include <motion_commons/UpwardAction.h>
#include <motion_commons/ForwardActionFeedback.h>
#include <motion_commons/TurnActionFeedback.h>
#include <motion_commons/SidewardActionFeedback.h>
#include <motion_commons/UpwardActionFeedback.h>
#include <motion_commons/UpwardActionResult.h>
#include <motion_commons/SidewardActionResult.h>
#include <string>

typedef actionlib::SimpleActionServer<task_commons::buoyAction> Server;
typedef actionlib::SimpleActionClient<motion_commons::ForwardAction> ClientForward;
typedef actionlib::SimpleActionClient<motion_commons::SidewardAction> ClientSideward;
typedef actionlib::SimpleActionClient<motion_commons::UpwardAction> ClientUpward;
typedef actionlib::SimpleActionClient<motion_commons::TurnAction> ClientTurn;

class TaskBuoyInnerClass
{
private:
  ros::NodeHandle nh_;
  Server buoy_server_;
  std::string action_name_;
  std_msgs::Float64 data_X_;
  std_msgs::Float64 data_distance_;
  std_msgs::Int32 min_pwm_data;
  task_commons::buoyFeedback feedback_;
  task_commons::buoyResult result_;
  ros::Subscriber sub_ip_;
  ros::Subscriber depth_sub_;
  ros::Subscriber yaw_sub_;
  ros::Publisher switch_buoy_detection;
  ros::Publisher yaw_pub_;
  ros::Publisher upward_pwm;
  ros::Publisher present_distance_;
  ros::Publisher present_X_;
  ros::Publisher present_Y_;
  ClientForward ForwardClient_;
  ClientSideward SidewardClient_;
  ClientUpward UpwardClient_;
  ClientTurn TurnClient_;
  motion_commons::ForwardGoal forwardgoal;
  motion_commons::SidewardGoal sidewardgoal;
  motion_commons::UpwardGoal upwardgoal;
  motion_commons::TurnGoal turngoal;
  bool successBuoy, sideCenter, IP_stopped, heightGoal;
  float present_depth, present_Y_coord;
  int min_pwm;

public:
  TaskBuoyInnerClass(std::string name, std::string node, std::string node1, std::string node2, std::string node3)
    : buoy_server_(nh_, name, boost::bind(&TaskBuoyInnerClass::analysisCB, this, _1), false)
    , action_name_(name)
    , ForwardClient_(node)
    , SidewardClient_(node1)
    , UpwardClient_(node2)
    , TurnClient_(node3)
  {
    ROS_INFO("%s inside constructor", action_name_.c_str());
    buoy_server_.registerPreemptCallback(boost::bind(&TaskBuoyInnerClass::preemptCB, this));

    switch_buoy_detection = nh_.advertise<std_msgs::Bool>("buoy_detection_switch", 1000);
    present_X_ = nh_.advertise<std_msgs::Float64>("/varun/motion/y_distance", 1000);
    present_Y_ = nh_.advertise<std_msgs::Float64>("/varun/motion/z_distance", 1000);
    present_distance_ = nh_.advertise<std_msgs::Float64>("/varun/motion/x_distance", 1000);
    yaw_pub_ = nh_.advertise<std_msgs::Float64>("/varun/motion/yaw", 1000);
    upward_pwm = nh_.advertise<std_msgs::Int32>("/pwm/upward", 1000);
    sub_ip_ =
        nh_.subscribe<std_msgs::Float64MultiArray>("/varun/ip/buoy", 1000, &TaskBuoyInnerClass::buoyNavigation, this);
    yaw_sub_ = nh_.subscribe<std_msgs::Float64>("/varun/sensors/imu/yaw", 1000, &TaskBuoyInnerClass::yawCB, this);
    depth_sub_ = nh_.subscribe<std_msgs::Float64>("/varun/sensors/pressure_sensor/depth",
        1000, &TaskBuoyInnerClass::depthCB, this);
    buoy_server_.start();
  }

  ~TaskBuoyInnerClass(void)
  {
  }

  void yawCB(std_msgs::Float64 imu_data)
  {
    yaw_pub_.publish(imu_data);
  }

  void depthCB(std_msgs::Float64 depth_data)
  {
    present_depth = depth_data.data;
  }

  void buoyNavigation(std_msgs::Float64MultiArray array)
  {
    data_X_.data = array.data[1];
    present_Y_coord = array.data[2];
    data_distance_.data = array.data[3];

    if (data_distance_.data > 0)
    {
      present_distance_.publish(data_distance_);
      present_X_.publish(data_X_);
    }

    // if distance is -1 to -4 then buoy is out of frame and the motion library will assume the last data.
    else if (data_distance_.data == -5 && sideCenter)
    {
      IP_stopped = true;
      stopBuoyDetection();
      ROS_INFO("%s Bot is in front of buoy, IP stopped.", action_name_.c_str());
    }
  }

  void preemptCB(void)
  {
    // Not actually preempting the goal because Prakhar did it in analysisCB
    successBuoy = false;
    ROS_INFO("Called when preempted from the client");
  }

  void spinThreadSidewardCamera()
  {
    ClientSideward &tempSideward = SidewardClient_;
    tempSideward.waitForResult();
    sideCenter = (*(tempSideward.getResult())).Result;
    if (sideCenter)
    {
      ROS_INFO("%s Bot is at side center", action_name_.c_str());
    }
    else
    {
      ROS_INFO("%s Bot is not at side center, something went wrong", action_name_.c_str());
      successBuoy = false;
    }
  }

  void analysisCB(const task_commons::buoyGoalConstPtr goal)
  {
    ROS_INFO("Inside analysisCB");
    sideCenter = false;
    successBuoy = true;
    IP_stopped = false;
    heightGoal = false;
    min_pwm = 4;
    ros::Rate looprate(12);
    if (!buoy_server_.isActive())
      return;

    ROS_INFO("%s Waiting for Forward server to start.", action_name_.c_str());
    ForwardClient_.waitForServer();
    SidewardClient_.waitForServer();
    UpwardClient_.waitForServer();
    TurnClient_.waitForServer();

    TaskBuoyInnerClass::startBuoyDetection();

    // Stabilization of yaw
    turngoal.AngleToTurn = 0;
    turngoal.loop = 100000;
    TurnClient_.sendGoal(turngoal);

    if (present_depth < 0.0)
    {
      min_pwm_data.data = -min_pwm;
      upward_pwm.publish(min_pwm_data);
    }
    else
    {
      min_pwm_data.data = min_pwm;
      upward_pwm.publish(min_pwm_data);
    }

    while (present_Y_coord > 5.0 || present_Y_coord < -5.0)
    {
      if (buoy_server_.isPreemptRequested() || !ros::ok())
      {
        ROS_INFO("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        buoy_server_.setPreempted();
        successBuoy = false;
        break;
      }

      if (present_Y_coord < 5.0 && present_Y_coord > -5.0)
      {
        upwardgoal.Goal = present_depth;
        break;
      }

      feedback_.x_coord = data_X_.data;
      feedback_.y_coord = present_Y_coord;
      feedback_.distance = data_distance_.data;
      buoy_server_.publishFeedback(feedback_);
      ros::spinOnce();
    }

    upwardgoal.loop = 100000;
    UpwardClient_.sendGoal(upwardgoal);
    ROS_INFO("%s: upward Stabilization is on", action_name_.c_str());

    sidewardgoal.Goal = 0;
    sidewardgoal.loop = 10;
    SidewardClient_.sendGoal(sidewardgoal);
    boost::thread spin_thread_sideward_camera(&TaskBuoyInnerClass::spinThreadSidewardCamera, this);

    while (goal->order && successBuoy)
    {
      if (buoy_server_.isPreemptRequested() || !ros::ok())
      {
        ROS_INFO("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        buoy_server_.setPreempted();
        successBuoy = false;
        break;
      }
      looprate.sleep();
      if (sideCenter)
      {
        break;
      }
      // publish the feedback
      feedback_.x_coord = data_X_.data;
      feedback_.y_coord = present_Y_coord;
      feedback_.distance = data_distance_.data;
      buoy_server_.publishFeedback(feedback_);
      ros::spinOnce();
    }

    ROS_INFO("%s: Bot is in center of buoy", action_name_.c_str());
    forwardgoal.Goal = 0;
    forwardgoal.loop = 10;
    ForwardClient_.sendGoal(forwardgoal);
    ROS_INFO("%s: Bot is moving forward to hit the buoy", action_name_.c_str());

    while (goal->order && successBuoy)
    {
      if (buoy_server_.isPreemptRequested() || !ros::ok())
      {
        ROS_INFO("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        buoy_server_.setPreempted();
        successBuoy = false;
        break;
      }
      looprate.sleep();

      if (IP_stopped)
      {
        ROS_INFO("%s: Waiting for hitting the buoy...", action_name_.c_str());
        // sleep(1);
        break;
      }

      feedback_.x_coord = data_X_.data;
      feedback_.y_coord = present_Y_coord;
      feedback_.distance = data_distance_.data;
      buoy_server_.publishFeedback(feedback_);
      ros::spinOnce();
    }

    ForwardClient_.cancelGoal();  // stop motion here

    result_.MotionCompleted = successBuoy;
    ROS_INFO("%s: Succeeded", action_name_.c_str());
    // set the action state to succeeded
    buoy_server_.setSucceeded(result_);
  }

  void startBuoyDetection()
  {
    std_msgs::Bool msg;
    msg.data = false;
    switch_buoy_detection.publish(msg);
  }

  void stopBuoyDetection()
  {
    std_msgs::Bool msg;
    msg.data = true;
    switch_buoy_detection.publish(msg);
  }
};

int main(int argc, char **argv)
{
  ros::init(argc, argv, "buoy_server");
  ROS_INFO("Waiting for Goal");
  TaskBuoyInnerClass taskBuoyObject(ros::this_node::getName(), "forward", "sideward", "upward", "turningXY");
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>#include <tclap/CmdLine.h>
#include <iostream>
#include <cstdint>
#include "balance.h"

int main(int argc, const char **argv) {
    TCLAP::CmdLine cmd("Broker balance module", ' ', "1.0.0", true);
    TCLAP::ValueArg<std::string> common_broker_url("u", "url", "Broker url", false, "tcp://127.0.0.110000",
                                                   "zmq bind");
    TCLAP::ValueArg<std::string> proxy_backend("b", "backend", "Backend binding for proxy", false,
                                               "tcp://127.0.0.1:10001",
                                               "zmq bind");
    TCLAP::ValueArg<std::string> common_name("n", "name", "Balancing service name", true, "unknown", "name");
    TCLAP::SwitchArg common_is_verbose("v", "verbose", "Show much more output", false);
    cmd.add(common_broker_url);
    cmd.add(common_name);
    cmd.add(common_is_verbose);
    cmd.add(proxy_backend);
    cmd.parse(argc, argv);
    start_balance_proxy(common_broker_url.getValue(), proxy_backend.getValue(), common_name.getValue());
}<commit_msg>Typo fix<commit_after>#include <tclap/CmdLine.h>
#include <iostream>
#include <cstdint>
#include "balance.h"

int main(int argc, const char **argv) {
    TCLAP::CmdLine cmd("Broker balance module", ' ', "1.0.0", true);
    TCLAP::ValueArg<std::string> common_broker_url("u", "url", "Broker url", false, "tcp://127.0.0.10000",
                                                   "zmq bind");
    TCLAP::ValueArg<std::string> proxy_backend("b", "backend", "Backend binding for proxy", false,
                                               "tcp://127.0.0.1:10001",
                                               "zmq bind");
    TCLAP::ValueArg<std::string> common_name("n", "name", "Balancing service name", true, "unknown", "name");
    TCLAP::SwitchArg common_is_verbose("v", "verbose", "Show much more output", false);
    cmd.add(common_broker_url);
    cmd.add(common_name);
    cmd.add(common_is_verbose);
    cmd.add(proxy_backend);
    cmd.parse(argc, argv);
    start_balance_proxy(common_broker_url.getValue(), proxy_backend.getValue(), common_name.getValue());
}<|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Piston.h"
#include "ChunkDef.h"
#include "Pickup.h"
#include "Item.h"
#include "Root.h"
#include "ClientHandle.h"
#include "World.h"
#include "BlockID.h"
#include "Server.h"
#include "Blocks/BlockHandler.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

//Athar from http://www.cplusplus.com/forum/unices/60161/ helped with the sleep code.

extern bool g_BlockPistonBreakable[];

#define AddDir( x, y, z, dir, amount ) \
	switch (dir) \
	{ \
		case 0: (y)-=(amount); break; \
		case 1: (y)+=(amount); break; \
		case 2: (z)-=(amount); break; \
		case 3: (z)+=(amount); break; \
		case 4: (x)-=(amount); break; \
		case 5: (x)+=(amount); break; \
	}

cPiston::cPiston(cWorld * a_World)
	: m_World(a_World)
{

}

unsigned short cPiston::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, char pistonmeta)
{
	unsigned short ret;
	pistonmeta &= 7;
	if (pistonmeta >= 6)
	{
		// Just in case, it shouldn't happen but if it would, it'd case inf loop
		LOGD("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n");
		return 9001;
	}
	BLOCKTYPE currBlock;
	for (ret = 0; ret < 24; ret++)  // push up to 24 blocks
	{
		AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1)
		currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ );
		if ((currBlock == E_BLOCK_BEDROCK) || (currBlock == E_BLOCK_OBSIDIAN) || (currBlock == E_BLOCK_PISTON_EXTENSION))
		{
			return 9001;
		}
		if (g_BlockPistonBreakable[currBlock])
		{
			return ret;
		}
	}
	return 9001;
}

void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
{
	BLOCKTYPE pistonBlock;
	NIBBLETYPE pistonMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
	char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8;
	if ( (pistonMeta & 0x8) != 0x0 )
	{
		// Piston already extended, bail out
		return;
	}

	unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta);
	if (dist > 9000) return; // too many blocks

	AddDir(pistx, pisty, pistz, pistonMeta & 7, dist + 1)
	BLOCKTYPE currBlock;
	NIBBLETYPE currMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currMeta);
	if (currBlock != E_BLOCK_AIR)
	{
		cBlockHandler * Handler = BlockHandler(currBlock);
		if (Handler->DoesDropOnUnsuitable())
		{
			Handler->DropBlock(m_World, NULL, pistx, pisty, pistz);
		}
	}
	int oldx = pistx, oldy = pisty, oldz = pistz;
	NIBBLETYPE currBlockMeta;
	for (int i = dist + 1; i > 0; i--)
	{
		AddDir(pistx, pisty, pistz, pistonMeta & 7, -1)
		m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currBlockMeta);
		m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta);
		oldx = pistx;
		oldy = pisty;
		oldz = pistz;
	}
	m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, E_BLOCK_PISTON);
	m_World->BroadcastSoundEffect("tile.piston.out", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
	m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 );

	int extx = pistx;
	int exty = pisty;
	int extz = pistz;

	AddDir(extx, exty, extz, pistonMeta & 7, 1)

	#ifdef _WIN32
	Sleep(100);
	#else
	usleep(static_cast<useconds_t>(100)*1000);
	#endif

	m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta & 7);
}

void cPiston::RetractPiston( int pistx, int pisty, int pistz )
{
	BLOCKTYPE pistonBlock;
	NIBBLETYPE pistonMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
	if (pistonMeta <= 6)
	{
		// Already retracted, bail out
		return;
	}
	m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), E_BLOCK_PISTON);
	m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
	m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));

	AddDir(pistx, pisty, pistz, pistonMeta & 7, 1)
	if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION)
	{
		LOGD("%s: Piston without an extension?", __FUNCTION__);
		return;
	}

	if (pistonBlock == E_BLOCK_STICKY_PISTON)
	{
		int tempx = pistx, tempy = pisty, tempz = pistz;
		AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 )
		BLOCKTYPE tempblock;
		NIBBLETYPE tempmeta;
		m_World->GetBlockTypeMeta(tempx, tempy, tempz, tempblock, tempmeta);
		if (
			(tempblock == E_BLOCK_OBSIDIAN) ||
			(tempblock == E_BLOCK_BEDROCK) ||
			(tempblock == E_BLOCK_PISTON_EXTENSION)
		)
		{
			// These cannot be moved by the sticky piston, bail out
			return;
		}
		#ifdef _WIN32
		Sleep(100);
		#else
		usleep(static_cast<useconds_t>(100)*1000);
		#endif

		m_World->SetBlock(pistx, pisty, pistz, tempblock, tempmeta);
		m_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0);
	}
	else
	{
		#ifdef _WIN32
		Sleep(100);
		#else
		usleep(static_cast<useconds_t>(100)*1000);
		#endif

		m_World->SetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0);
	}
}

<commit_msg>Partially fixed tonibm19's mess.<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Piston.h"
#include "ChunkDef.h"
#include "Pickup.h"
#include "Item.h"
#include "Root.h"
#include "ClientHandle.h"
#include "World.h"
#include "BlockID.h"
#include "Server.h"
#include "Blocks/BlockHandler.h"

extern bool g_BlockPistonBreakable[];

#define AddDir( x, y, z, dir, amount ) \
	switch (dir) \
	{ \
		case 0: (y)-=(amount); break; \
		case 1: (y)+=(amount); break; \
		case 2: (z)-=(amount); break; \
		case 3: (z)+=(amount); break; \
		case 4: (x)-=(amount); break; \
		case 5: (x)+=(amount); break; \
	}

cPiston::cPiston(cWorld * a_World)
	: m_World(a_World)
{

}

unsigned short cPiston::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, char pistonmeta)
{
	unsigned short ret;
	pistonmeta &= 7;
	if (pistonmeta >= 6)
	{
		// Just in case, it shouldn't happen but if it would, it'd case inf loop
		LOGD("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n");
		return 9001;
	}
	BLOCKTYPE currBlock;
	for (ret = 0; ret < 24; ret++)  // push up to 24 blocks
	{
		AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1)
		currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ );
		if ((currBlock == E_BLOCK_BEDROCK) || (currBlock == E_BLOCK_OBSIDIAN) || (currBlock == E_BLOCK_PISTON_EXTENSION))
		{
			return 9001;
		}
		if (g_BlockPistonBreakable[currBlock])
		{
			return ret;
		}
	}
	return 9001;
}

void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
{
	BLOCKTYPE pistonBlock;
	NIBBLETYPE pistonMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
	char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8;
	if ( (pistonMeta & 0x8) != 0x0 )
	{
		// Piston already extended, bail out
		return;
	}

	unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta);
	if (dist > 9000) return; // too many blocks

	AddDir(pistx, pisty, pistz, pistonMeta & 7, dist + 1)
	BLOCKTYPE currBlock;
	NIBBLETYPE currMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currMeta);
	if (currBlock != E_BLOCK_AIR)
	{
		cBlockHandler * Handler = BlockHandler(currBlock);
		if (Handler->DoesDropOnUnsuitable())
		{
			Handler->DropBlock(m_World, NULL, pistx, pisty, pistz);
		}
	}
	int oldx = pistx, oldy = pisty, oldz = pistz;
	NIBBLETYPE currBlockMeta;
	for (int i = dist + 1; i > 0; i--)
	{
		AddDir(pistx, pisty, pistz, pistonMeta & 7, -1)
		m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currBlockMeta);
		m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta);
		oldx = pistx;
		oldy = pisty;
		oldz = pistz;
	}
	m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, E_BLOCK_PISTON);
	m_World->BroadcastSoundEffect("tile.piston.out", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
	m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 );

	int extx = pistx;
	int exty = pisty;
	int extz = pistz;

	AddDir(extx, exty, extz, pistonMeta & 7, 1)

	// TODO: This code needs replacing
	// Sleeping here will play the piston animation on the client; however, it will block the entire server
	// for the 100 ms, effectively dropping 2 game ticks per piston. This is very bad
		// This needs to be handled using delayed scheduled tasks instead
	cSleep::MilliSleep(100);

	m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta & 7);
}

void cPiston::RetractPiston( int pistx, int pisty, int pistz )
{
	BLOCKTYPE pistonBlock;
	NIBBLETYPE pistonMeta;
	m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
	if (pistonMeta <= 6)
	{
		// Already retracted, bail out
		return;
	}
	m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), E_BLOCK_PISTON);
	m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
	m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));

	AddDir(pistx, pisty, pistz, pistonMeta & 7, 1)
	if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION)
	{
		LOGD("%s: Piston without an extension?", __FUNCTION__);
		return;
	}

	if (pistonBlock == E_BLOCK_STICKY_PISTON)
	{
		int tempx = pistx, tempy = pisty, tempz = pistz;
		AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 )
		BLOCKTYPE tempblock;
		NIBBLETYPE tempmeta;
		m_World->GetBlockTypeMeta(tempx, tempy, tempz, tempblock, tempmeta);
		if (
			(tempblock == E_BLOCK_OBSIDIAN) ||
			(tempblock == E_BLOCK_BEDROCK) ||
			(tempblock == E_BLOCK_PISTON_EXTENSION)
		)
		{
			// These cannot be moved by the sticky piston, bail out
			return;
		}

		// TODO: This code needs replacing
		// Sleeping here will play the piston animation on the client; however, it will block the entire server
		// for the 100 ms, effectively dropping 2 game ticks per piston. This is very bad
		// This needs to be handled using delayed scheduled tasks instead
		cSleep::MilliSleep(100);

		m_World->SetBlock(pistx, pisty, pistz, tempblock, tempmeta);
		m_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0);
	}
	else
	{
		// TODO: This code needs replacing
		// Sleeping here will play the piston animation on the client; however, it will block the entire server
		// for the 100 ms, effectively dropping 2 game ticks per piston. This is very bad
		// This needs to be handled using delayed scheduled tasks instead
		cSleep::MilliSleep(100);

		m_World->SetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0);
	}
}

<|endoftext|>


<commit_before>//---------------------------------------------------------- -*- Mode: C++ -*-
// $Id$
//
// Created 2013/06/09
// Author: Mike Ovsiannikov
//
// Copyright 2013 Quantcast Corp.
//
// This file is part of Kosmos File System (KFS).
//
// Licensed under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// Kerberos 5 service / client authentication test.
//
//----------------------------------------------------------------------------

#include "KrbService.h"
#include "KrbClient.h"

#include "qcdio/QCThread.h"

#include <string.h>
#include <stdlib.h>

#include <time.h>
#include <iostream>
#include <vector>
#include <string>

namespace
{
using KFS::KrbClient;
using KFS::KrbService;

using std::cerr;
using std::cout;
using std::ostream;
using std::string;

class QfsKrbTest
{
public:
    QfsKrbTest()
        : mClient(),
          mService(),
          mServiceClock(0),
          mClientClock()
        {}
    int Init(
        int         inArgsCount,
        char**      inArgsPtr,
        const char* inInMemoryKeyTabNamePtr)
    {
        const bool theDetectReplayFlag = inArgsCount >= 5 &&
            strchr(inArgsPtr[4], 'R');
        const char* theErrMsgPtr = mClient.Init(inArgsPtr[1], inArgsPtr[2]);
        if (theErrMsgPtr) {
            cerr <<
                "client: init error: " << theErrMsgPtr << "\n";
            return 1;
        }
        if ((theErrMsgPtr = mService.Init(
                inArgsPtr[1],
                inArgsPtr[2],
                inArgsCount <= 3 ? 0 : inArgsPtr[3],
                inInMemoryKeyTabNamePtr,
                theDetectReplayFlag))) {
            cerr <<
                "service init error: " << theErrMsgPtr << "\n";
            return 1;
        }
        return 0;
    }
    int Run(
        int    inArgsCount,
        char** inArgsPtr)
    {
        if (inArgsCount < 3 || 6 < inArgsCount) {
            cerr <<
                "Usage: " << (inArgsCount >= 1 ? inArgsPtr[0] : "") <<
                " <service host> <service name> [<keytab name>]"
                " [-d|-p|-r<num>] [<num>]\n"
            ;
            return 1;
        }
        const int theCnt = inArgsCount >= 6 ? atoi(inArgsPtr[5]) : 1;
        int       theRet = 0;
        for (int i = 0; i < theCnt; i++) {
            const int theErr = RunSelf(inArgsCount, inArgsPtr);
            if (theErr && ! theRet) {
                theRet = theErr;
            }
        }
        if (inArgsCount >= 5 && strchr(inArgsPtr[4], 'p')) {
            cerr << (void*)this << "\n" <<
                "client  cpu: " <<  (double)mClientClock / CLOCKS_PER_SEC <<
                    " ops/sec: " << (mClientClock != 0 ?
                        (double)theCnt * CLOCKS_PER_SEC /  mClientClock
                        : 0.0) <<
                "\n"
                "service cpu: " << (double)mServiceClock / CLOCKS_PER_SEC <<
                    " ops/sec: " << (mServiceClock != 0 ?
                        (double)theCnt * CLOCKS_PER_SEC /  mServiceClock
                        : 0.0) <<
            "\n";
        }
        return theRet;
    }
private:
    KrbClient  mClient;
    KrbService mService;
    clock_t    mServiceClock;
    clock_t    mClientClock;

    int RunSelf(
        int    inArgsCount,
        char** inArgsPtr)
    {
        const int theReplayCnt =
            (inArgsCount >= 5 && strncmp(inArgsPtr[4], "-r", 2) == 0) ?
            atoi(inArgsPtr[4] + 2) : 1;
        const bool theDebugFlag = inArgsCount >= 5 &&
            strchr(inArgsPtr[4], 'd');
        const char* theDataPtr   = 0;
        int         theDataLen   = 0;
        clock_t     theStart     = clock();
        const char* theCliKeyPtr = 0;
        int         theCliKeyLen = 0;
        const char* theErrMsgPtr;
        if ((theErrMsgPtr = mClient.Request(theDataPtr, theDataLen,
                theCliKeyPtr, theCliKeyLen))) {
            cerr <<
                "client: request create error: " << theErrMsgPtr << "\n";
            return 1;
        }
        mClientClock += clock() - theStart;
        if (theDebugFlag) {
            cout <<
                "client:"
                " request:"
                " length: " << theDataLen <<
                " key:"
                " length: " << theCliKeyLen <<
                " data: "
            ;
            ShowAsHexString(theCliKeyPtr, theCliKeyLen, cout) << "\n";
        }
        const char* theSrvKeyPtr  = 0;
        int         theSrvKeyLen  = 0;
        const char* theReqDataPtr = theDataPtr;
        int         theReqDataLen = theDataLen;
        theStart = clock();
        for (int i = 0; i < theReplayCnt; i++) {
            if ((theErrMsgPtr = mService.Request(
                    theReqDataPtr, theReqDataLen))) {
                cerr <<
                    "service: request process error: " << theErrMsgPtr << "\n";
                return 1;
            }
            if (theDebugFlag) {
                cout << "service: request: processed\n";
            }
            theDataPtr   = 0;
            theDataLen   = 0;
            theSrvKeyPtr = 0;
            theSrvKeyLen = 0;
            const char* thePrincipalPtr = 0;
            if ((theErrMsgPtr = mService.Reply(
                    KrbService::kPrincipalUnparseShort,
                    theDataPtr,
                    theDataLen,
                    theSrvKeyPtr,
                    theSrvKeyLen,
                    thePrincipalPtr))) {
                cerr <<
                    "service: reply create error: " << theErrMsgPtr << "\n";
                return 1;
            }
            if (theDebugFlag) {
                cout <<
                    "service:"
                    " reply:"
                    " length: " << theDataLen <<
                    " principal: " << thePrincipalPtr <<
                    " key:"
                    " length: " << theSrvKeyLen <<
                    " data: "
                ;
                ShowAsHexString(theSrvKeyPtr, theSrvKeyLen, cout) << "\n";
            }
        }
        const clock_t theEnd = clock();
        mServiceClock += theEnd - theStart;
        theStart = theEnd;
        if ((theErrMsgPtr = mClient.Reply(theDataPtr, theDataLen))) {
            cerr <<
                "client: reply: process error: " << theErrMsgPtr << "\n";
            return 1;
        }
        mClientClock += clock() - theStart;
        if (theDebugFlag) {
            cout <<
                "client:"
                " reply: processed"
            "\n";
        }
        if (theCliKeyLen != theSrvKeyLen ||
                memcmp(theCliKeyPtr, theSrvKeyPtr, theCliKeyLen) != 0) {
            cerr << (void*)this << " " <<
                "service / client key mismatch:" <<
                " key length:"
                " service: " << theSrvKeyLen <<
                " client: "  << theCliKeyLen <<
            "\n";
            return 1;
        }
        return 0;
    }

    ostream& ShowAsHexString(
        const char* inDataPtr,
        int         inLength,
        ostream&    inOutStream)
    {
        const char* const kHexSyms = "0123456789ABCDEF";
        for (const char* thePtr = inDataPtr,
                * const theEndPtr = inDataPtr + inLength;
                thePtr < theEndPtr;
                ++thePtr) {
            inOutStream <<
                kHexSyms[(*thePtr >> 4) & 0xF] <<
                kHexSyms[*thePtr & 0xF];
        }
        return inOutStream;
    }
private:
    QfsKrbTest(
        const QfsKrbTest& inTest);
    QfsKrbTest& operator=(
        const QfsKrbTest& inTest);
};

class KrbTestThread : public QCThread, private QfsKrbTest
{
public:
    KrbTestThread()
        : mArgsCount(0),
          mArgsPtr(0),
          mStatus(0)
        {}
    ~KrbTestThread()
        {}
    void Start(
        int         inArgsCount,
        char**      inArgsPtr,
        const char* inInMemoryKeyTabNamePtr)
    {
        mArgsCount = inArgsCount;
        mArgsPtr   = inArgsPtr;
        mStatus    = Init(mArgsCount, mArgsPtr, inInMemoryKeyTabNamePtr);
        QCThread::Start();
    }
    virtual void Run()
    {
        if (mStatus) {
            return;
        }
        mStatus = QfsKrbTest::Run(mArgsCount, mArgsPtr);
    }
    int Stop()
    {
        QCThread::Join();
        return mStatus;
    }
private:
    int    mArgsCount;
    char** mArgsPtr;
    int    mStatus;
};

}

    int
main(
    int    inArgsCount,
    char** inArgsPtr)
{
    const char* thePtr       = 0;
    int         theThreadCnt = 0;
    string      theInMemoryKeyTabName("_qfs_keytab");
    if (inArgsCount >= 5 && (thePtr = strchr(inArgsPtr[4], 't')) &&
            (theThreadCnt = atoi(thePtr + 1)) > 1) {
        KrbTestThread* const theThreadsPtr = new KrbTestThread[theThreadCnt];
        for (int i = 0; i < theThreadCnt; i++) {
            theThreadsPtr[i].Start(inArgsCount, inArgsPtr,
                theInMemoryKeyTabName.c_str());
             // The key tab names should be unique, each tread.must have its
             // own.
            theInMemoryKeyTabName += "X";
        }
        int theRet = 0;
        for (int i = 0; i < theThreadCnt; i++) {
            const int theErr = theThreadsPtr[i].Stop();
            if (theErr) {
                theRet = theErr;
            }
        }
        delete [] theThreadsPtr;
        return theRet;
    } else {
        QfsKrbTest theTest;
        const int  theStatus = theTest.Init(inArgsCount, inArgsPtr,
            theInMemoryKeyTabName.c_str());
        return (theStatus ? theStatus : theTest.Run(inArgsCount, inArgsPtr));
    }
}
<commit_msg>Qfs kerberos lib: unit test: invoke init multiple times to detect possible memory leaks, and ensure that in memory keytab is properly created.<commit_after>//---------------------------------------------------------- -*- Mode: C++ -*-
// $Id$
//
// Created 2013/06/09
// Author: Mike Ovsiannikov
//
// Copyright 2013 Quantcast Corp.
//
// This file is part of Kosmos File System (KFS).
//
// Licensed under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// Kerberos 5 service / client authentication test.
//
//----------------------------------------------------------------------------

#include "KrbService.h"
#include "KrbClient.h"

#include "qcdio/QCThread.h"

#include <string.h>
#include <stdlib.h>

#include <time.h>
#include <iostream>
#include <vector>
#include <string>

namespace
{
using KFS::KrbClient;
using KFS::KrbService;

using std::cerr;
using std::cout;
using std::ostream;
using std::string;

class QfsKrbTest
{
public:
    QfsKrbTest()
        : mClient(),
          mService(),
          mServiceClock(0),
          mClientClock()
        {}
    int Init(
        int         inArgsCount,
        char**      inArgsPtr,
        const char* inInMemoryKeyTabNamePtr)
    {
        const bool theDetectReplayFlag = inArgsCount >= 5 &&
            strchr(inArgsPtr[4], 'R');
        const char* theErrMsgPtr = mClient.Init(inArgsPtr[1], inArgsPtr[2]);
        if (theErrMsgPtr) {
            cerr <<
                "client: init error: " << theErrMsgPtr << "\n";
            return 1;
        }
        if ((theErrMsgPtr = mService.Init(
                inArgsPtr[1],
                inArgsPtr[2],
                inArgsCount <= 3 ? 0 : inArgsPtr[3],
                inInMemoryKeyTabNamePtr,
                theDetectReplayFlag))) {
            cerr <<
                "service init error: " << theErrMsgPtr << "\n";
            return 1;
        }
        return 0;
    }
    int Run(
        int    inArgsCount,
        char** inArgsPtr)
    {
        if (inArgsCount < 3 || 6 < inArgsCount) {
            cerr <<
                "Usage: " << (inArgsCount >= 1 ? inArgsPtr[0] : "") <<
                " <service host> <service name> [<keytab name>]"
                " [-d|-p|-r<num>] [<num>]\n"
            ;
            return 1;
        }
        const int theCnt = inArgsCount >= 6 ? atoi(inArgsPtr[5]) : 1;
        int       theRet = 0;
        for (int i = 0; i < theCnt; i++) {
            const int theErr = RunSelf(inArgsCount, inArgsPtr);
            if (theErr && ! theRet) {
                theRet = theErr;
            }
        }
        if (inArgsCount >= 5 && strchr(inArgsPtr[4], 'p')) {
            cerr << (void*)this << "\n" <<
                "client  cpu: " <<  (double)mClientClock / CLOCKS_PER_SEC <<
                    " ops/sec: " << (mClientClock != 0 ?
                        (double)theCnt * CLOCKS_PER_SEC /  mClientClock
                        : 0.0) <<
                "\n"
                "service cpu: " << (double)mServiceClock / CLOCKS_PER_SEC <<
                    " ops/sec: " << (mServiceClock != 0 ?
                        (double)theCnt * CLOCKS_PER_SEC /  mServiceClock
                        : 0.0) <<
            "\n";
        }
        return theRet;
    }
private:
    KrbClient  mClient;
    KrbService mService;
    clock_t    mServiceClock;
    clock_t    mClientClock;

    int RunSelf(
        int    inArgsCount,
        char** inArgsPtr)
    {
        const int theReplayCnt =
            (inArgsCount >= 5 && strncmp(inArgsPtr[4], "-r", 2) == 0) ?
            atoi(inArgsPtr[4] + 2) : 1;
        const bool theDebugFlag = inArgsCount >= 5 &&
            strchr(inArgsPtr[4], 'd');
        const char* theDataPtr   = 0;
        int         theDataLen   = 0;
        clock_t     theStart     = clock();
        const char* theCliKeyPtr = 0;
        int         theCliKeyLen = 0;
        const char* theErrMsgPtr;
        if ((theErrMsgPtr = mClient.Request(theDataPtr, theDataLen,
                theCliKeyPtr, theCliKeyLen))) {
            cerr <<
                "client: request create error: " << theErrMsgPtr << "\n";
            return 1;
        }
        mClientClock += clock() - theStart;
        if (theDebugFlag) {
            cout <<
                "client:"
                " request:"
                " length: " << theDataLen <<
                " key:"
                " length: " << theCliKeyLen <<
                " data: "
            ;
            ShowAsHexString(theCliKeyPtr, theCliKeyLen, cout) << "\n";
        }
        const char* theSrvKeyPtr  = 0;
        int         theSrvKeyLen  = 0;
        const char* theReqDataPtr = theDataPtr;
        int         theReqDataLen = theDataLen;
        theStart = clock();
        for (int i = 0; i < theReplayCnt; i++) {
            if ((theErrMsgPtr = mService.Request(
                    theReqDataPtr, theReqDataLen))) {
                cerr <<
                    "service: request process error: " << theErrMsgPtr << "\n";
                return 1;
            }
            if (theDebugFlag) {
                cout << "service: request: processed\n";
            }
            theDataPtr   = 0;
            theDataLen   = 0;
            theSrvKeyPtr = 0;
            theSrvKeyLen = 0;
            const char* thePrincipalPtr = 0;
            if ((theErrMsgPtr = mService.Reply(
                    KrbService::kPrincipalUnparseShort,
                    theDataPtr,
                    theDataLen,
                    theSrvKeyPtr,
                    theSrvKeyLen,
                    thePrincipalPtr))) {
                cerr <<
                    "service: reply create error: " << theErrMsgPtr << "\n";
                return 1;
            }
            if (theDebugFlag) {
                cout <<
                    "service:"
                    " reply:"
                    " length: " << theDataLen <<
                    " principal: " << thePrincipalPtr <<
                    " key:"
                    " length: " << theSrvKeyLen <<
                    " data: "
                ;
                ShowAsHexString(theSrvKeyPtr, theSrvKeyLen, cout) << "\n";
            }
        }
        const clock_t theEnd = clock();
        mServiceClock += theEnd - theStart;
        theStart = theEnd;
        if ((theErrMsgPtr = mClient.Reply(theDataPtr, theDataLen))) {
            cerr <<
                "client: reply: process error: " << theErrMsgPtr << "\n";
            return 1;
        }
        mClientClock += clock() - theStart;
        if (theDebugFlag) {
            cout <<
                "client:"
                " reply: processed"
            "\n";
        }
        if (theCliKeyLen != theSrvKeyLen ||
                memcmp(theCliKeyPtr, theSrvKeyPtr, theCliKeyLen) != 0) {
            cerr << (void*)this << " " <<
                "service / client key mismatch:" <<
                " key length:"
                " service: " << theSrvKeyLen <<
                " client: "  << theCliKeyLen <<
            "\n";
            return 1;
        }
        return 0;
    }

    ostream& ShowAsHexString(
        const char* inDataPtr,
        int         inLength,
        ostream&    inOutStream)
    {
        const char* const kHexSyms = "0123456789ABCDEF";
        for (const char* thePtr = inDataPtr,
                * const theEndPtr = inDataPtr + inLength;
                thePtr < theEndPtr;
                ++thePtr) {
            inOutStream <<
                kHexSyms[(*thePtr >> 4) & 0xF] <<
                kHexSyms[*thePtr & 0xF];
        }
        return inOutStream;
    }
private:
    QfsKrbTest(
        const QfsKrbTest& inTest);
    QfsKrbTest& operator=(
        const QfsKrbTest& inTest);
};

class KrbTestThread : public QCThread, private QfsKrbTest
{
public:
    KrbTestThread()
        : mArgsCount(0),
          mArgsPtr(0),
          mStatus(0)
        {}
    ~KrbTestThread()
        {}
    void Start(
        int         inArgsCount,
        char**      inArgsPtr,
        const char* inInMemoryKeyTabNamePtr)
    {
        mArgsCount = inArgsCount;
        mArgsPtr   = inArgsPtr;
        mStatus    = Init(mArgsCount, mArgsPtr, inInMemoryKeyTabNamePtr);
        // Test that the init works and doesn't leak memory.
        for (int i = 0; i < 5 && ! mStatus; i++) {
            mStatus = Init(mArgsCount, mArgsPtr, inInMemoryKeyTabNamePtr);
        }
        QCThread::Start();
    }
    virtual void Run()
    {
        if (mStatus) {
            return;
        }
        mStatus = QfsKrbTest::Run(mArgsCount, mArgsPtr);
    }
    int Stop()
    {
        QCThread::Join();
        return mStatus;
    }
private:
    int    mArgsCount;
    char** mArgsPtr;
    int    mStatus;
};

}

    int
main(
    int    inArgsCount,
    char** inArgsPtr)
{
    const char* thePtr       = 0;
    int         theThreadCnt = 0;
    string      theInMemoryKeyTabName("_qfs_keytab");
    if (inArgsCount >= 5 && (thePtr = strchr(inArgsPtr[4], 't')) &&
            (theThreadCnt = atoi(thePtr + 1)) > 1) {
        KrbTestThread* const theThreadsPtr = new KrbTestThread[theThreadCnt];
        for (int i = 0; i < theThreadCnt; i++) {
            theThreadsPtr[i].Start(inArgsCount, inArgsPtr,
                theInMemoryKeyTabName.c_str());
             // The key tab names should be unique, each tread.must have its
             // own.
            theInMemoryKeyTabName += "X";
        }
        int theRet = 0;
        for (int i = 0; i < theThreadCnt; i++) {
            const int theErr = theThreadsPtr[i].Stop();
            if (theErr) {
                theRet = theErr;
            }
        }
        delete [] theThreadsPtr;
        return theRet;
    } else {
        QfsKrbTest theTest;
        int        theStatus = theTest.Init(inArgsCount, inArgsPtr,
            theInMemoryKeyTabName.c_str());
        // Test that the init works and doesn't leak memory.
        for (int i = 0; i < 5 && ! theStatus; i++) {
            theStatus = theTest.Init(inArgsCount, inArgsPtr,
                theInMemoryKeyTabName.c_str());
        }
        return (theStatus ? theStatus : theTest.Run(inArgsCount, inArgsPtr));
    }
}
<|endoftext|>


<commit_before><commit_msg>`print_hexdump`: align ASCII dump of the last incomplete line.<commit_after><|endoftext|>