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

// This file contains the default suppressions for ThreadSanitizer.
// You can also pass additional suppressions via TSAN_OPTIONS:
// TSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =
// False positives in libflashplayer.so and libglib.so. Since we don't
// instrument them, we cannot reason about the synchronization in them.
"race:libflashplayer.so\n"
"race:libglib*.so\n"

// Intentional race in ToolsSanityTest.DataRace in base_unittests.
"race:base/tools_sanity_unittest.cc\n"

// Data race on WatchdogCounter [test-only].
"race:base/threading/watchdog_unittest.cc\n"

// Races in libevent, http://crbug.com/23244.
"race:libevent/event.c\n"

// http://crbug.com/46840.
"race:base::HistogramSamples::IncreaseSum\n"
"race:base::Histogram::Add\n"
"race:base::HistogramSamples::Add\n"

// http://crbug.com/84094.
"race:sqlite3StatusSet\n"
"race:pcache1EnforceMaxPage\n"
"race:pcache1AllocPage\n"

// http://crbug.com/102327.
// Test-only race, won't fix.
"race:tracked_objects::ThreadData::ShutdownSingleThreadedCleanup\n"

// http://crbug.com/115540
"race:*GetCurrentThreadIdentifier\n"

// http://crbug.com/120808
"race:base/threading/watchdog.cc\n"

// http://crbug.com/157586
"race:third_party/libvpx/source/libvpx/vp8/decoder/threading.c\n"

// http://crbug.com/158718
"race:third_party/ffmpeg/libavcodec/pthread.c\n"
"race:third_party/ffmpeg/libavcodec/pthread_frame.c\n"
"race:third_party/ffmpeg/libavcodec/vp8.c\n"
"race:third_party/ffmpeg/libavutil/mem.c\n"
"race:*HashFrameForTesting\n"
"race:third_party/ffmpeg/libavcodec/h264pred.c\n"
"race:media::ReleaseData\n"

// http://crbug.com/158922
"race:third_party/libvpx/source/libvpx/vp8/encoder/*\n"
"race:third_party/libvpx/source/libvpx/vp9/encoder/*\n"

// http://crbug.com/189177
"race:thread_manager\n"
"race:v8::Locker::Initialize\n"

// http://crbug.com/239359
"race:media::TestInputCallback::OnData\n"

// http://crbug.com/244368
"race:skia::BeginPlatformPaint\n"

// http://crbug.com/244385
"race:unixTempFileDir\n"

// http://crbug.com/244755
"race:v8::internal::Zone::NewExpand\n"
"race:TooLateToEnableNow\n"
"race:adjust_segment_bytes_allocated\n"

// http://crbug.com/244774
"race:webrtc::RTPReceiver::ProcessBitrate\n"
"race:webrtc::RTPSender::ProcessBitrate\n"
"race:webrtc::VideoCodingModuleImpl::Decode\n"
"race:webrtc::RTPSender::SendOutgoingData\n"
"race:webrtc::VP8EncoderImpl::GetEncodedPartitions\n"
"race:webrtc::VP8EncoderImpl::Encode\n"
"race:webrtc::ViEEncoder::DeliverFrame\n"
"race:webrtc::vcm::VideoReceiver::Decode\n"
"race:webrtc::VCMReceiver::FrameForDecoding\n"
"race:*trace_event_unique_catstatic*\n"

// http://crbug.com/244856
"race:AutoPulseLock\n"

// http://crbug.com/246968
"race:webrtc::VideoCodingModuleImpl::RegisterPacketRequestCallback\n"

// http://crbug.com/246974
"race:content::GpuWatchdogThread::CheckArmed\n"

// http://crbug.com/257396
"race:base::trace_event::"
    "TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n"

// http://crbug.com/258479
"race:SamplingStateScope\n"
"race:g_trace_state\n"

// http://crbug.com/258499
"race:third_party/skia/include/core/SkRefCnt.h\n"

// http://crbug.com/268924
"race:base::g_power_monitor\n"
"race:base::PowerMonitor::PowerMonitor\n"
"race:base::PowerMonitor::AddObserver\n"
"race:base::PowerMonitor::RemoveObserver\n"
"race:base::PowerMonitor::IsOnBatteryPower\n"

// http://crbug.com/258935
"race:base::Thread::StopSoon\n"

// http://crbug.com/268941
"race:tracked_objects::ThreadData::tls_index_\n"

// http://crbug.com/272095
"race:base::g_top_manager\n"

// http://crbug.com/273047
"race:base::*::g_lazy_tls_ptr\n"
"race:IPC::SyncChannel::ReceivedSyncMsgQueue::lazy_tls_ptr_\n"

// http://crbug.com/280466
"race:content::WebRtcAudioCapturer::SetCapturerSource\n"

// http://crbug.com/285242
"race:media::PulseAudioOutputStream::SetVolume\n"

// http://crbug.com/296883
"race:net::URLFetcherCore::Stop\n"

// http://crbug.com/308590
"race:CustomThreadWatcher::~CustomThreadWatcher\n"

// http://crbug.com/310851
"race:net::ProxyResolverV8Tracing::Job::~Job\n"

// http://crbug.com/313726
"race:CallbackWasCalled\n"

// http://crbug.com/327330
"race:PrepareTextureMailbox\n"
"race:cc::LayerTreeHost::PaintLayerContents\n"

// http://crbug.com/328826
"race:gLCDOrder\n"
"race:gLCDOrientation\n"

// http://crbug.com/328868
"race:PR_Lock\n"

// http://crbug.com/329225
"race:blink::currentTimeFunction\n"

// http://crbug.com/329460
"race:extensions::InfoMap::AddExtension\n"

// http://crbug.com/333244
"race:content::"
    "VideoCaptureImplTest::MockVideoCaptureImpl::~MockVideoCaptureImpl\n"

// http://crbug.com/333871
"race:v8::internal::Interface::NewValue()::value_interface\n"
"race:v8::internal::IsMinusZero(double)::minus_zero\n"
"race:v8::internal::FastCloneShallowObjectStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedLoadStubCompiler::registers\n"
"race:v8::internal::KeyedStoreStubCompiler::registers()::registers\n"
"race:v8::internal::KeyedLoadFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedStoreFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::LoadStubCompiler::registers\n"
"race:v8::internal::StoreStubCompiler::registers\n"
"race:v8::internal::HValue::LoopWeight\n"

// http://crbug.com/334140
"race:CommandLine::HasSwitch\n"
"race:CommandLine::current_process_commandline_\n"
"race:CommandLine::GetSwitchValueASCII\n"

// http://crbug.com/338675
"race:blink::s_platform\n"
"race:content::"
    "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n"

// http://crbug.com/345240
"race:WTF::s_shutdown\n"

// http://crbug.com/345245
"race:jingle_glue::JingleThreadWrapper::~JingleThreadWrapper\n"
"race:webrtc::voe::Channel::UpdatePacketDelay\n"
"race:webrtc::voe::Channel::GetDelayEstimate\n"
"race:webrtc::VCMCodecDataBase::DeregisterReceiveCodec\n"
"race:webrtc::GainControlImpl::set_stream_analog_level\n"

// http://crbug.com/345618
"race:WebCore::AudioDestinationNode::render\n"

// http://crbug.com/345624
"race:media::DataSource::set_host\n"

// http://crbug.com/347534
"race:v8::internal::V8::TearDown\n"

// http://crbug.com/347538
"race:sctp_timer_start\n"

// http://crbug.com/347548
"race:cricket::WebRtcVideoMediaChannel::MaybeResetVieSendCodec\n"
"race:cricket::WebRtcVideoMediaChannel::SetSendCodec\n"

// http://crbug.com/347553
"race:blink::WebString::reset\n"

// http://crbug.com/348511
"race:webrtc::acm1::AudioCodingModuleImpl::PlayoutData10Ms\n"

// http://crbug.com/348982
"race:cricket::P2PTransportChannel::OnConnectionDestroyed\n"
"race:cricket::P2PTransportChannel::AddConnection\n"

// http://crbug.com/348984
"race:sctp_express_handle_sack\n"
"race:system_base_info\n"

// http://crbug.com/363999
"race:v8::internal::EnterDebugger::*EnterDebugger\n"

// https://code.google.com/p/v8/issues/detail?id=3143
"race:v8::internal::FLAG_track_double_fields\n"

// https://crbug.com/369257
// TODO(mtklein): annotate properly and remove suppressions.
"race:SandboxIPCHandler::HandleFontMatchRequest\n"
"race:SkFontConfigInterfaceDirect::matchFamilyName\n"
"race:SkFontConfigInterface::GetSingletonDirectInterface\n"
"race:FcStrStaticName\n"

// http://crbug.com/372807
"deadlock:net::X509Certificate::CreateCertificateListFromBytes\n"
"deadlock:net::X509Certificate::CreateFromBytes\n"
"deadlock:net::SSLClientSocketNSS::Core::DoHandshakeLoop\n"

// http://crbug.com/374135
"race:media::AlsaWrapper::PcmWritei\n"

// False positive in libc's tzset_internal, http://crbug.com/379738.
"race:tzset_internal\n"

// http://crbug.com/380554
"deadlock:g_type_add_interface_static\n"

// http:://crbug.com/386385
"race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"

// http://crbug.com/388730
"race:g_next_user_script_id\n"

// http://crbug.com/389098
"race:webrtc::RtpToNtpMs\n"
"race:webrtc::UpdateRtcpList\n"
"race:webrtc::RemoteNtpTimeEstimator::Estimate\n"
"race:webrtc::voe::TransmitMixer::EnableStereoChannelSwapping\n"

// http://crbug.com/397022
"deadlock:"
"base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"

// http://crbug.com/415472
"deadlock:base::trace_event::TraceLog::GetCategoryGroupEnabled\n"

// http://crbug.com/425057
"deadlock:webrtc::ViEChannelManagerScoped::ViEChannelManagerScoped\n"

// http://crbug.com/417193
// Suppressing both AudioContext.{cpp,h}.
"race:modules/webaudio/AudioContext\n"

// https://code.google.com/p/skia/issues/detail?id=3294
"race:SkBaseMutex::acquire\n"

// https://crbug.com/430533
"race:TileTaskGraphRunner::Run\n"

// https://crbug.com/448203
"race:blink::RemoteFrame::detach\n"

// https://crbug.com/454652
"race:net::NetworkChangeNotifier::SetTestNotificationsOnly\n"

// https://crbug.com/455638
"deadlock:dbus::Bus::ShutdownAndBlock\n"

// https://crbug.com/455665
"race:mojo::common::*::tick_clock\n"

// https://crbug.com/459429
"race:randomnessPid\n"

// https://crbug.com/454655
"race:content::BrowserTestBase::PostTaskToInProcessRendererAndWait\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<commit_msg>Suppress TSAN for cc::VideoLayerImpl::WillDraw<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the default suppressions for ThreadSanitizer.
// You can also pass additional suppressions via TSAN_OPTIONS:
// TSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =
// False positives in libflashplayer.so and libglib.so. Since we don't
// instrument them, we cannot reason about the synchronization in them.
"race:libflashplayer.so\n"
"race:libglib*.so\n"

// Intentional race in ToolsSanityTest.DataRace in base_unittests.
"race:base/tools_sanity_unittest.cc\n"

// Data race on WatchdogCounter [test-only].
"race:base/threading/watchdog_unittest.cc\n"

// Races in libevent, http://crbug.com/23244.
"race:libevent/event.c\n"

// http://crbug.com/46840.
"race:base::HistogramSamples::IncreaseSum\n"
"race:base::Histogram::Add\n"
"race:base::HistogramSamples::Add\n"

// http://crbug.com/84094.
"race:sqlite3StatusSet\n"
"race:pcache1EnforceMaxPage\n"
"race:pcache1AllocPage\n"

// http://crbug.com/102327.
// Test-only race, won't fix.
"race:tracked_objects::ThreadData::ShutdownSingleThreadedCleanup\n"

// http://crbug.com/115540
"race:*GetCurrentThreadIdentifier\n"

// http://crbug.com/120808
"race:base/threading/watchdog.cc\n"

// http://crbug.com/157586
"race:third_party/libvpx/source/libvpx/vp8/decoder/threading.c\n"

// http://crbug.com/158718
"race:third_party/ffmpeg/libavcodec/pthread.c\n"
"race:third_party/ffmpeg/libavcodec/pthread_frame.c\n"
"race:third_party/ffmpeg/libavcodec/vp8.c\n"
"race:third_party/ffmpeg/libavutil/mem.c\n"
"race:*HashFrameForTesting\n"
"race:third_party/ffmpeg/libavcodec/h264pred.c\n"
"race:media::ReleaseData\n"

// http://crbug.com/158922
"race:third_party/libvpx/source/libvpx/vp8/encoder/*\n"
"race:third_party/libvpx/source/libvpx/vp9/encoder/*\n"

// http://crbug.com/189177
"race:thread_manager\n"
"race:v8::Locker::Initialize\n"

// http://crbug.com/239359
"race:media::TestInputCallback::OnData\n"

// http://crbug.com/244368
"race:skia::BeginPlatformPaint\n"

// http://crbug.com/244385
"race:unixTempFileDir\n"

// http://crbug.com/244755
"race:v8::internal::Zone::NewExpand\n"
"race:TooLateToEnableNow\n"
"race:adjust_segment_bytes_allocated\n"

// http://crbug.com/244774
"race:webrtc::RTPReceiver::ProcessBitrate\n"
"race:webrtc::RTPSender::ProcessBitrate\n"
"race:webrtc::VideoCodingModuleImpl::Decode\n"
"race:webrtc::RTPSender::SendOutgoingData\n"
"race:webrtc::VP8EncoderImpl::GetEncodedPartitions\n"
"race:webrtc::VP8EncoderImpl::Encode\n"
"race:webrtc::ViEEncoder::DeliverFrame\n"
"race:webrtc::vcm::VideoReceiver::Decode\n"
"race:webrtc::VCMReceiver::FrameForDecoding\n"
"race:*trace_event_unique_catstatic*\n"

// http://crbug.com/244856
"race:AutoPulseLock\n"

// http://crbug.com/246968
"race:webrtc::VideoCodingModuleImpl::RegisterPacketRequestCallback\n"

// http://crbug.com/246974
"race:content::GpuWatchdogThread::CheckArmed\n"

// http://crbug.com/257396
"race:base::trace_event::"
    "TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n"

// http://crbug.com/258479
"race:SamplingStateScope\n"
"race:g_trace_state\n"

// http://crbug.com/258499
"race:third_party/skia/include/core/SkRefCnt.h\n"

// http://crbug.com/268924
"race:base::g_power_monitor\n"
"race:base::PowerMonitor::PowerMonitor\n"
"race:base::PowerMonitor::AddObserver\n"
"race:base::PowerMonitor::RemoveObserver\n"
"race:base::PowerMonitor::IsOnBatteryPower\n"

// http://crbug.com/258935
"race:base::Thread::StopSoon\n"

// http://crbug.com/268941
"race:tracked_objects::ThreadData::tls_index_\n"

// http://crbug.com/272095
"race:base::g_top_manager\n"

// http://crbug.com/273047
"race:base::*::g_lazy_tls_ptr\n"
"race:IPC::SyncChannel::ReceivedSyncMsgQueue::lazy_tls_ptr_\n"

// http://crbug.com/280466
"race:content::WebRtcAudioCapturer::SetCapturerSource\n"

// http://crbug.com/285242
"race:media::PulseAudioOutputStream::SetVolume\n"

// http://crbug.com/296883
"race:net::URLFetcherCore::Stop\n"

// http://crbug.com/308590
"race:CustomThreadWatcher::~CustomThreadWatcher\n"

// http://crbug.com/310851
"race:net::ProxyResolverV8Tracing::Job::~Job\n"

// http://crbug.com/313726
"race:CallbackWasCalled\n"

// http://crbug.com/327330
"race:PrepareTextureMailbox\n"
"race:cc::LayerTreeHost::PaintLayerContents\n"

// http://crbug.com/476529
"deadlock:cc::VideoLayerImpl::WillDraw\n"

// http://crbug.com/328826
"race:gLCDOrder\n"
"race:gLCDOrientation\n"

// http://crbug.com/328868
"race:PR_Lock\n"

// http://crbug.com/329225
"race:blink::currentTimeFunction\n"

// http://crbug.com/329460
"race:extensions::InfoMap::AddExtension\n"

// http://crbug.com/333244
"race:content::"
    "VideoCaptureImplTest::MockVideoCaptureImpl::~MockVideoCaptureImpl\n"

// http://crbug.com/333871
"race:v8::internal::Interface::NewValue()::value_interface\n"
"race:v8::internal::IsMinusZero(double)::minus_zero\n"
"race:v8::internal::FastCloneShallowObjectStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedLoadStubCompiler::registers\n"
"race:v8::internal::KeyedStoreStubCompiler::registers()::registers\n"
"race:v8::internal::KeyedLoadFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedStoreFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::LoadStubCompiler::registers\n"
"race:v8::internal::StoreStubCompiler::registers\n"
"race:v8::internal::HValue::LoopWeight\n"

// http://crbug.com/334140
"race:CommandLine::HasSwitch\n"
"race:CommandLine::current_process_commandline_\n"
"race:CommandLine::GetSwitchValueASCII\n"

// http://crbug.com/338675
"race:blink::s_platform\n"
"race:content::"
    "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n"

// http://crbug.com/345240
"race:WTF::s_shutdown\n"

// http://crbug.com/345245
"race:jingle_glue::JingleThreadWrapper::~JingleThreadWrapper\n"
"race:webrtc::voe::Channel::UpdatePacketDelay\n"
"race:webrtc::voe::Channel::GetDelayEstimate\n"
"race:webrtc::VCMCodecDataBase::DeregisterReceiveCodec\n"
"race:webrtc::GainControlImpl::set_stream_analog_level\n"

// http://crbug.com/345618
"race:WebCore::AudioDestinationNode::render\n"

// http://crbug.com/345624
"race:media::DataSource::set_host\n"

// http://crbug.com/347534
"race:v8::internal::V8::TearDown\n"

// http://crbug.com/347538
"race:sctp_timer_start\n"

// http://crbug.com/347548
"race:cricket::WebRtcVideoMediaChannel::MaybeResetVieSendCodec\n"
"race:cricket::WebRtcVideoMediaChannel::SetSendCodec\n"

// http://crbug.com/347553
"race:blink::WebString::reset\n"

// http://crbug.com/348511
"race:webrtc::acm1::AudioCodingModuleImpl::PlayoutData10Ms\n"

// http://crbug.com/348982
"race:cricket::P2PTransportChannel::OnConnectionDestroyed\n"
"race:cricket::P2PTransportChannel::AddConnection\n"

// http://crbug.com/348984
"race:sctp_express_handle_sack\n"
"race:system_base_info\n"

// http://crbug.com/363999
"race:v8::internal::EnterDebugger::*EnterDebugger\n"

// https://code.google.com/p/v8/issues/detail?id=3143
"race:v8::internal::FLAG_track_double_fields\n"

// https://crbug.com/369257
// TODO(mtklein): annotate properly and remove suppressions.
"race:SandboxIPCHandler::HandleFontMatchRequest\n"
"race:SkFontConfigInterfaceDirect::matchFamilyName\n"
"race:SkFontConfigInterface::GetSingletonDirectInterface\n"
"race:FcStrStaticName\n"

// http://crbug.com/372807
"deadlock:net::X509Certificate::CreateCertificateListFromBytes\n"
"deadlock:net::X509Certificate::CreateFromBytes\n"
"deadlock:net::SSLClientSocketNSS::Core::DoHandshakeLoop\n"

// http://crbug.com/374135
"race:media::AlsaWrapper::PcmWritei\n"

// False positive in libc's tzset_internal, http://crbug.com/379738.
"race:tzset_internal\n"

// http://crbug.com/380554
"deadlock:g_type_add_interface_static\n"

// http:://crbug.com/386385
"race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"

// http://crbug.com/388730
"race:g_next_user_script_id\n"

// http://crbug.com/389098
"race:webrtc::RtpToNtpMs\n"
"race:webrtc::UpdateRtcpList\n"
"race:webrtc::RemoteNtpTimeEstimator::Estimate\n"
"race:webrtc::voe::TransmitMixer::EnableStereoChannelSwapping\n"

// http://crbug.com/397022
"deadlock:"
"base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"

// http://crbug.com/415472
"deadlock:base::trace_event::TraceLog::GetCategoryGroupEnabled\n"

// http://crbug.com/425057
"deadlock:webrtc::ViEChannelManagerScoped::ViEChannelManagerScoped\n"

// http://crbug.com/417193
// Suppressing both AudioContext.{cpp,h}.
"race:modules/webaudio/AudioContext\n"

// https://code.google.com/p/skia/issues/detail?id=3294
"race:SkBaseMutex::acquire\n"

// https://crbug.com/430533
"race:TileTaskGraphRunner::Run\n"

// https://crbug.com/448203
"race:blink::RemoteFrame::detach\n"

// https://crbug.com/454652
"race:net::NetworkChangeNotifier::SetTestNotificationsOnly\n"

// https://crbug.com/455638
"deadlock:dbus::Bus::ShutdownAndBlock\n"

// https://crbug.com/455665
"race:mojo::common::*::tick_clock\n"

// https://crbug.com/459429
"race:randomnessPid\n"

// https://crbug.com/454655
"race:content::BrowserTestBase::PostTaskToInProcessRendererAndWait\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<|endoftext|>


<commit_before>#include <algorithm>
#include <string>

#include <gtest/gtest.h>

#include "prefix_function.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct prefix_function_tester : public gt::Test
{
    static const int MAX_TEXT_SIZE = 100;

    // tested class:
    prefix_function<MAX_TEXT_SIZE> pf;
};

TEST_F(prefix_function_tester, tests_abcd)
{
    // given
    const std::string text = "abcd";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_aaaa)
{
    // given
    const std::string text = "aaaa";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(1, prefix_suffix_table[1]);
    EXPECT_EQ(2, prefix_suffix_table[2]);
    EXPECT_EQ(3, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_abcabcabc)
{
    // given
    const std::string text = "abcabcabc";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(1, prefix_suffix_table[3]);
    EXPECT_EQ(2, prefix_suffix_table[4]);
    EXPECT_EQ(3, prefix_suffix_table[5]);
    EXPECT_EQ(4, prefix_suffix_table[6]);
    EXPECT_EQ(5, prefix_suffix_table[7]);
    EXPECT_EQ(6, prefix_suffix_table[8]);
}

TEST_F(prefix_function_tester, tests_abcdabcaba)
{
    // given
    const std::string text = "abcdabcaba";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
    EXPECT_EQ(1, prefix_suffix_table[4]);
    EXPECT_EQ(2, prefix_suffix_table[5]);
    EXPECT_EQ(3, prefix_suffix_table[6]);
    EXPECT_EQ(1, prefix_suffix_table[7]);
    EXPECT_EQ(2, prefix_suffix_table[8]);
    EXPECT_EQ(1, prefix_suffix_table[9]);
}

TEST_F(prefix_function_tester, tests_pattern_searching_in_text)
{
    // given
    const std::string pattern = "abca";
    const std::string text = "abaabcdabcabdabcabcad";
    // pattern ends at:                 ^     ^  ^

    // when
    std::string s = pattern + "#" + text;
    pf.run(s.c_str(), s.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(3u, std::count(prefix_suffix_table, prefix_suffix_table + s.size(), pattern.size()));

    const int first_occurance = pattern.size() + 1 + 10;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[first_occurance]);

    const int second_occurance = pattern.size() + 1 + 16;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[second_occurance]);

    const int third_occurance = pattern.size() + 1 + 19;
    EXPECT_EQ(pattern.size(), prefix_suffix_table[third_occurance]);
}

} // namespace testing
} // namespace pk
<commit_msg>Comparison between signed and unsigned integers removed<commit_after>#include <algorithm>
#include <string>

#include <gtest/gtest.h>

#include "prefix_function.hpp"

namespace gt = testing;

namespace pk
{
namespace testing
{

struct prefix_function_tester : public gt::Test
{
    static const int MAX_TEXT_SIZE = 100;

    // tested class:
    prefix_function<MAX_TEXT_SIZE> pf;
};

TEST_F(prefix_function_tester, tests_abcd)
{
    // given
    const std::string text = "abcd";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_aaaa)
{
    // given
    const std::string text = "aaaa";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(1, prefix_suffix_table[1]);
    EXPECT_EQ(2, prefix_suffix_table[2]);
    EXPECT_EQ(3, prefix_suffix_table[3]);
}

TEST_F(prefix_function_tester, tests_abcabcabc)
{
    // given
    const std::string text = "abcabcabc";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(1, prefix_suffix_table[3]);
    EXPECT_EQ(2, prefix_suffix_table[4]);
    EXPECT_EQ(3, prefix_suffix_table[5]);
    EXPECT_EQ(4, prefix_suffix_table[6]);
    EXPECT_EQ(5, prefix_suffix_table[7]);
    EXPECT_EQ(6, prefix_suffix_table[8]);
}

TEST_F(prefix_function_tester, tests_abcdabcaba)
{
    // given
    const std::string text = "abcdabcaba";

    // when
    pf.run(text.c_str(), text.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(0, prefix_suffix_table[0]);
    EXPECT_EQ(0, prefix_suffix_table[1]);
    EXPECT_EQ(0, prefix_suffix_table[2]);
    EXPECT_EQ(0, prefix_suffix_table[3]);
    EXPECT_EQ(1, prefix_suffix_table[4]);
    EXPECT_EQ(2, prefix_suffix_table[5]);
    EXPECT_EQ(3, prefix_suffix_table[6]);
    EXPECT_EQ(1, prefix_suffix_table[7]);
    EXPECT_EQ(2, prefix_suffix_table[8]);
    EXPECT_EQ(1, prefix_suffix_table[9]);
}

TEST_F(prefix_function_tester, tests_pattern_searching_in_text)
{
    // given
    const std::string pattern = "abca";
    const std::string text = "abaabcdabcabdabcabcad";
    // pattern ends at:                 ^     ^  ^

    // when
    std::string s = pattern + "#" + text;
    pf.run(s.c_str(), s.size());

    // then
    const int* prefix_suffix_table = pf.get_prefix_suffix_table();

    EXPECT_EQ(3u, std::count(prefix_suffix_table, prefix_suffix_table + s.size(), pattern.size()));

    const int first_occurance = pattern.size() + 1 + 10;
    EXPECT_EQ(4, prefix_suffix_table[first_occurance]);

    const int second_occurance = pattern.size() + 1 + 16;
    EXPECT_EQ(4, prefix_suffix_table[second_occurance]);

    const int third_occurance = pattern.size() + 1 + 19;
    EXPECT_EQ(4, prefix_suffix_table[third_occurance]);
}

} // namespace testing
} // namespace pk
<|endoftext|>


<commit_before>#include "tests/Base.hh"

#include "topology/MaximalCliques.hh"

#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include <algorithm>
#include <vector>

using namespace aleph::topology;
using namespace aleph;

template <class Data, class Vertex> void triangles()
{
  ALEPH_TEST_BEGIN( "Triangles [connected & unconnected]" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  // 2---1
  // |  /|
  // | / |
  // |/  |
  // 0---3
  //
  // Expected cliques: {0,1,2}, {0,3,1}
  std::vector<Simplex> trianglesConnected
    = {
        {0,1}, {0,2}, {0,3}, {1,2}, {1,3},
        {0,1,2}, {0,1,3}
    };

  // 2---1   5
  // |  /   /|
  // | /   / |
  // |/   /  |
  // 0---3---4
  //
  // Expected cliques: {0,3}, {0,1,2}, {3,4,5}
  std::vector<Simplex> trianglesDisconnected
    = {
        {0,1}, {0,2}, {0,3}, {1,2}, {3,4}, {3,5}, {4,5},
        {0,1,2}, {3,4,5}
    };

  SimplicialComplex K1( trianglesConnected.begin()   , trianglesConnected.end() );
  SimplicialComplex K2( trianglesDisconnected.begin(), trianglesDisconnected.end() );

  auto C11 = maximalCliquesBronKerbosch( K1 );
  auto C12 = maximalCliquesKoch( K1 );
  auto C21 = maximalCliquesBronKerbosch( K2 );
  auto C22 = maximalCliquesKoch( K2 );

  ALEPH_ASSERT_THROW( C11.empty() == false );
  ALEPH_ASSERT_THROW( C12.empty() == false );
  ALEPH_ASSERT_THROW( C21.empty() == false );
  ALEPH_ASSERT_THROW( C22.empty() == false );

  ALEPH_ASSERT_EQUAL( C11.size(), C12.size() );
  ALEPH_ASSERT_EQUAL( C21.size(), C22.size() );

  ALEPH_TEST_END();
}

int main()
{
  triangles<double, unsigned>();
  triangles<float,  unsigned>();
}
<commit_msg>Extended test case for maximal clique enumeration<commit_after>#include "tests/Base.hh"

#include "topology/MaximalCliques.hh"

#include "topology/Simplex.hh"
#include "topology/SimplicialComplex.hh"

#include <algorithm>
#include <vector>

using namespace aleph::topology;
using namespace aleph;

template <class Data, class Vertex> void triangles()
{
  ALEPH_TEST_BEGIN( "Triangles [connected & unconnected]" );

  using Simplex           = Simplex<Data, Vertex>;
  using SimplicialComplex = SimplicialComplex<Simplex>;

  // 2---1
  // |  /|
  // | / |
  // |/  |
  // 0---3
  //
  // Expected cliques: {0,1,2}, {0,3,1}
  std::vector<Simplex> trianglesConnected
    = {
        {0,1}, {0,2}, {0,3}, {1,2}, {1,3},
        {0,1,2}, {0,1,3}
    };

  // 2---1   5
  // |  /   /|
  // | /   / |
  // |/   /  |
  // 0---3---4
  //
  // Expected cliques: {0,3}, {0,1,2}, {3,4,5}
  std::vector<Simplex> trianglesDisconnected
    = {
        {0,1}, {0,2}, {0,3}, {1,2}, {3,4}, {3,5}, {4,5},
        {0,1,2}, {3,4,5}
    };

  SimplicialComplex K1( trianglesConnected.begin()   , trianglesConnected.end() );
  SimplicialComplex K2( trianglesDisconnected.begin(), trianglesDisconnected.end() );

  auto C11 = maximalCliquesBronKerbosch( K1 );
  auto C12 = maximalCliquesKoch( K1 );
  auto C21 = maximalCliquesBronKerbosch( K2 );
  auto C22 = maximalCliquesKoch( K2 );

  ALEPH_ASSERT_THROW( C11.empty() == false );
  ALEPH_ASSERT_THROW( C12.empty() == false );
  ALEPH_ASSERT_THROW( C21.empty() == false );
  ALEPH_ASSERT_THROW( C22.empty() == false );

  ALEPH_ASSERT_EQUAL( C11.size(), C12.size() );
  ALEPH_ASSERT_EQUAL( C21.size(), C22.size() );

  ALEPH_ASSERT_EQUAL( C11.size(), 2 );
  ALEPH_ASSERT_EQUAL( C21.size(), 3 );

  ALEPH_ASSERT_THROW( C11 == C12 );
  ALEPH_ASSERT_THROW( C21 == C22 );

  ALEPH_ASSERT_THROW( std::find( C11.begin(), C11.end(), std::set<Vertex>( {0,1,2} ) ) != C11.end() );
  ALEPH_ASSERT_THROW( std::find( C11.begin(), C11.end(), std::set<Vertex>( {0,1,3} ) ) != C11.end() );

  ALEPH_ASSERT_THROW( std::find( C21.begin(), C21.end(), std::set<Vertex>( {0,3  } ) ) != C21.end() );
  ALEPH_ASSERT_THROW( std::find( C21.begin(), C21.end(), std::set<Vertex>( {0,1,2} ) ) != C21.end() );
  ALEPH_ASSERT_THROW( std::find( C21.begin(), C21.end(), std::set<Vertex>( {3,4,5} ) ) != C21.end() );

  ALEPH_TEST_END();
}

int main()
{
  triangles<double, unsigned>();
  triangles<float,  unsigned>();
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "OsmDatabase.h"
#include "MarbleDebug.h"
#include "MarbleMath.h"
#include "MarbleLocale.h"
#include "DatabaseQuery.h"

#include <QtCore/QFile>
#include <QtCore/QDataStream>
#include <QtCore/QStringList>
#include <QtCore/QRegExp>
#include <QtCore/QVariant>
#include <QtCore/QTime>

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

namespace Marble {

OsmDatabase::OsmDatabase()
{
    m_database = QSqlDatabase::addDatabase( "QSQLITE" );
}

void OsmDatabase::addFile( const QString &fileName )
{
    m_databases << fileName;
}

QList<OsmPlacemark> OsmDatabase::find( MarbleModel* model, const QString &searchTerm )
{
    if ( m_databases.isEmpty() ) {
        return QList<OsmPlacemark>();
    }

    DatabaseQuery userQuery( model, searchTerm );

    QList<OsmPlacemark> result;
    QTime timer;
    timer.start();
    foreach( const QString &databaseFile, m_databases ) {
        m_database.setDatabaseName( databaseFile );
        if ( !m_database.open() ) {
            mDebug() << "Failed to connect to database " << databaseFile;
        }

        QString regionRestriction;
        if ( !userQuery.region().isEmpty() ) {
            // Nested set model to support region hierarchies, see http://en.wikipedia.org/wiki/Nested_set_model
            QSqlQuery regionsQuery( "SELECT lft, rgt FROM regions WHERE name LIKE '%" + userQuery.region() + "%';" );
            if ( regionsQuery.lastError().isValid() ) {
                mDebug() << "Error when executing query" << regionsQuery.executedQuery();
                mDebug() << "Sql reports" << regionsQuery.lastError();
            }
            regionRestriction = " AND (";
            bool first = true;
            while ( regionsQuery.next() ) {
                if ( first ) {
                    first = false;
                } else {
                    regionRestriction += " OR ";
                }
                regionRestriction += " (regions.lft >= " + regionsQuery.value( 0 ).toString();
                regionRestriction += " AND regions.lft <= " + regionsQuery.value( 1 ).toString() + ")";
            }
            regionRestriction += ")";

            if ( first ) {
                return QList<OsmPlacemark>();
            }
        }

        QString queryString;

        queryString = " SELECT regions.name,"
                " places.name, places.number,"
                " places.category, places.lon, places.lat"
                " FROM regions, places";

        if ( userQuery.queryType() == DatabaseQuery::CategorySearch ) {
            queryString += " WHERE regions.id = places.region AND places.category = %1";
            queryString = queryString.arg( (qint32) userQuery.category() );
            if ( userQuery.resultFormat() == DatabaseQuery::DistanceFormat && userQuery.region().isEmpty() ) {
                queryString += " ORDER BY ((places.lat-%1)*(places.lat-%1)+(places.lon-%2)*(places.lon-%2))";
                GeoDataCoordinates position = userQuery.position();
                queryString = queryString.arg( position.latitude( GeoDataCoordinates::Degree ), 0, 'f', 8 )
                        .arg( position.longitude( GeoDataCoordinates::Degree ), 0, 'f', 8 );
            } else {
                queryString += regionRestriction;
            }
        } else if ( userQuery.queryType() == DatabaseQuery::BroadSearch ) {
            queryString += " WHERE regions.id = places.region"
                    " AND places.name " + wildcardQuery( searchTerm );
        } else {
            queryString += " WHERE regions.id = places.region"
                    "   AND places.name " + wildcardQuery( userQuery.street() );
            if ( !userQuery.houseNumber().isEmpty() ) {
                queryString += " AND places.number " + wildcardQuery( userQuery.houseNumber() );
            } else {
                queryString += "AND places.number IS NULL";
            }
            queryString += regionRestriction;
        }

        queryString += " LIMIT 50;";

        /** @todo: sort/filter results from several databases */

        QSqlQuery query;
        query.setForwardOnly( true );
        if ( !query.exec( queryString ) ) {
            mDebug() << "Failed to execute query" << query.lastError();
            return result;
        }

        while ( query.next() ) {
            OsmPlacemark placemark;
            if ( userQuery.resultFormat() == DatabaseQuery::DistanceFormat ) {
                GeoDataCoordinates coordinates( query.value(4).toFloat(), query.value(5).toFloat(), 0.0, GeoDataCoordinates::Degree );
                placemark.setAdditionalInformation( formatDistance( coordinates, userQuery.position() ) );
            } else {
                placemark.setAdditionalInformation( query.value( 0 ).toString() );
            }
            placemark.setName( query.value(1).toString() );
            placemark.setHouseNumber( query.value(2).toString() );
            placemark.setCategory( (OsmPlacemark::OsmCategory) query.value(3).toInt() );
            placemark.setLongitude( query.value(4).toFloat() );
            placemark.setLatitude( query.value(5).toFloat() );
            result.push_back( placemark );
        }

        // mDebug() << "Query string: " << queryString;
    }

    mDebug() << "Offline OSM search query took " << timer.elapsed() << " ms.";
    return result;
}

QString OsmDatabase::formatDistance( const GeoDataCoordinates &a, const GeoDataCoordinates &b ) const
{
    qreal distance = EARTH_RADIUS * distanceSphere( a, b);

    int precision = 0;
    QString distanceUnit = "m";

    if ( MarbleGlobal::getInstance()->locale()->distanceUnit() == Marble::MilesFeet ) {
        precision = 1;
        distanceUnit = "mi";
        distance *= METER2KM;
        distance *= KM2MI;
    } else {
        if ( distance >= 1000 ) {
            distance /= 1000;
            distanceUnit = "km";
            precision = 1;
        } else if ( distance >= 200 ) {
            distance = 50 * qRound( distance / 50 );
        } else if ( distance >= 100 ) {
            distance = 25 * qRound( distance / 25 );
        } else {
            distance = 10 * qRound( distance / 10 );
        }
    }

    QString const fuzzyDistance = QString( "%1 %2" ).arg( distance, 0, 'f', precision ).arg( distanceUnit );

    int direction = 180 + bearing( a, b ) * RAD2DEG;

    QString heading = QObject::tr( "north" );
    if ( direction > 337 ) {
        heading = QObject::tr( "north" );
    } else if ( direction > 292 ) {
        heading = QObject::tr( "north-west" );
    } else if ( direction > 247 ) {
        heading = QObject::tr( "west" );
    } else if ( direction > 202 ) {
        heading = QObject::tr( "south-west" );
    } else if ( direction > 157 ) {
        heading = QObject::tr( "south" );
    } else if ( direction > 112 ) {
        heading = QObject::tr( "south-east" );
    } else if ( direction > 67 ) {
        heading = QObject::tr( "east" );
    } else if ( direction > 22 ) {
        heading = QObject::tr( "north-east" );
    }

    return fuzzyDistance + " " + heading;
}

qreal OsmDatabase::bearing( const GeoDataCoordinates &a, const GeoDataCoordinates &b ) const
{
    qreal delta = b.longitude() - a.longitude();
    qreal lat1 = a.latitude();
    qreal lat2 = b.latitude();
    return fmod( atan2( sin ( delta ) * cos ( lat2 ),
                       cos( lat1 ) * sin( lat2 ) - sin( lat1 ) * cos( lat2 ) * cos ( delta ) ), 2 * M_PI );
}

QString OsmDatabase::wildcardQuery( const QString &term ) const
{
    QString result = term;
    if ( term.contains( '*' ) ) {
        return " LIKE '" + result.replace( '*', '%' ) + "'";
    } else {
        return " = '" + result + "'";
    }
}

}
<commit_msg>Fix region restriction for multiple databases.<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "OsmDatabase.h"
#include "MarbleDebug.h"
#include "MarbleMath.h"
#include "MarbleLocale.h"
#include "DatabaseQuery.h"

#include <QtCore/QFile>
#include <QtCore/QDataStream>
#include <QtCore/QStringList>
#include <QtCore/QRegExp>
#include <QtCore/QVariant>
#include <QtCore/QTime>

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

namespace Marble {

OsmDatabase::OsmDatabase()
{
    m_database = QSqlDatabase::addDatabase( "QSQLITE" );
}

void OsmDatabase::addFile( const QString &fileName )
{
    m_databases << fileName;
}

QList<OsmPlacemark> OsmDatabase::find( MarbleModel* model, const QString &searchTerm )
{
    if ( m_databases.isEmpty() ) {
        return QList<OsmPlacemark>();
    }

    DatabaseQuery userQuery( model, searchTerm );

    QList<OsmPlacemark> result;
    QTime timer;
    timer.start();
    foreach( const QString &databaseFile, m_databases ) {
        m_database.setDatabaseName( databaseFile );
        if ( !m_database.open() ) {
            mDebug() << "Failed to connect to database " << databaseFile;
        }

        QString regionRestriction;
        if ( !userQuery.region().isEmpty() ) {
            // Nested set model to support region hierarchies, see http://en.wikipedia.org/wiki/Nested_set_model
            QSqlQuery regionsQuery( "SELECT lft, rgt FROM regions WHERE name LIKE '%" + userQuery.region() + "%';" );
            if ( regionsQuery.lastError().isValid() ) {
                mDebug() << "Error when executing query" << regionsQuery.executedQuery();
                mDebug() << "Sql reports" << regionsQuery.lastError();
            }
            regionRestriction = " AND (";
            bool first = true;
            while ( regionsQuery.next() ) {
                if ( first ) {
                    first = false;
                } else {
                    regionRestriction += " OR ";
                }
                regionRestriction += " (regions.lft >= " + regionsQuery.value( 0 ).toString();
                regionRestriction += " AND regions.lft <= " + regionsQuery.value( 1 ).toString() + ")";
            }
            regionRestriction += ")";

            if ( first ) {
                continue;
            }
        }

        QString queryString;

        queryString = " SELECT regions.name,"
                " places.name, places.number,"
                " places.category, places.lon, places.lat"
                " FROM regions, places";

        if ( userQuery.queryType() == DatabaseQuery::CategorySearch ) {
            queryString += " WHERE regions.id = places.region AND places.category = %1";
            queryString = queryString.arg( (qint32) userQuery.category() );
            if ( userQuery.resultFormat() == DatabaseQuery::DistanceFormat && userQuery.region().isEmpty() ) {
                queryString += " ORDER BY ((places.lat-%1)*(places.lat-%1)+(places.lon-%2)*(places.lon-%2))";
                GeoDataCoordinates position = userQuery.position();
                queryString = queryString.arg( position.latitude( GeoDataCoordinates::Degree ), 0, 'f', 8 )
                        .arg( position.longitude( GeoDataCoordinates::Degree ), 0, 'f', 8 );
            } else {
                queryString += regionRestriction;
            }
        } else if ( userQuery.queryType() == DatabaseQuery::BroadSearch ) {
            queryString += " WHERE regions.id = places.region"
                    " AND places.name " + wildcardQuery( searchTerm );
        } else {
            queryString += " WHERE regions.id = places.region"
                    "   AND places.name " + wildcardQuery( userQuery.street() );
            if ( !userQuery.houseNumber().isEmpty() ) {
                queryString += " AND places.number " + wildcardQuery( userQuery.houseNumber() );
            } else {
                queryString += "AND places.number IS NULL";
            }
            queryString += regionRestriction;
        }

        queryString += " LIMIT 50;";

        /** @todo: sort/filter results from several databases */

        QSqlQuery query;
        query.setForwardOnly( true );
        if ( !query.exec( queryString ) ) {
            mDebug() << "Failed to execute query" << query.lastError();
            return result;
        }

        while ( query.next() ) {
            OsmPlacemark placemark;
            if ( userQuery.resultFormat() == DatabaseQuery::DistanceFormat ) {
                GeoDataCoordinates coordinates( query.value(4).toFloat(), query.value(5).toFloat(), 0.0, GeoDataCoordinates::Degree );
                placemark.setAdditionalInformation( formatDistance( coordinates, userQuery.position() ) );
            } else {
                placemark.setAdditionalInformation( query.value( 0 ).toString() );
            }
            placemark.setName( query.value(1).toString() );
            placemark.setHouseNumber( query.value(2).toString() );
            placemark.setCategory( (OsmPlacemark::OsmCategory) query.value(3).toInt() );
            placemark.setLongitude( query.value(4).toFloat() );
            placemark.setLatitude( query.value(5).toFloat() );
            result.push_back( placemark );
        }

        // mDebug() << "Query string: " << queryString;
    }

    mDebug() << "Offline OSM search query took " << timer.elapsed() << " ms.";
    return result;
}

QString OsmDatabase::formatDistance( const GeoDataCoordinates &a, const GeoDataCoordinates &b ) const
{
    qreal distance = EARTH_RADIUS * distanceSphere( a, b);

    int precision = 0;
    QString distanceUnit = "m";

    if ( MarbleGlobal::getInstance()->locale()->distanceUnit() == Marble::MilesFeet ) {
        precision = 1;
        distanceUnit = "mi";
        distance *= METER2KM;
        distance *= KM2MI;
    } else {
        if ( distance >= 1000 ) {
            distance /= 1000;
            distanceUnit = "km";
            precision = 1;
        } else if ( distance >= 200 ) {
            distance = 50 * qRound( distance / 50 );
        } else if ( distance >= 100 ) {
            distance = 25 * qRound( distance / 25 );
        } else {
            distance = 10 * qRound( distance / 10 );
        }
    }

    QString const fuzzyDistance = QString( "%1 %2" ).arg( distance, 0, 'f', precision ).arg( distanceUnit );

    int direction = 180 + bearing( a, b ) * RAD2DEG;

    QString heading = QObject::tr( "north" );
    if ( direction > 337 ) {
        heading = QObject::tr( "north" );
    } else if ( direction > 292 ) {
        heading = QObject::tr( "north-west" );
    } else if ( direction > 247 ) {
        heading = QObject::tr( "west" );
    } else if ( direction > 202 ) {
        heading = QObject::tr( "south-west" );
    } else if ( direction > 157 ) {
        heading = QObject::tr( "south" );
    } else if ( direction > 112 ) {
        heading = QObject::tr( "south-east" );
    } else if ( direction > 67 ) {
        heading = QObject::tr( "east" );
    } else if ( direction > 22 ) {
        heading = QObject::tr( "north-east" );
    }

    return fuzzyDistance + " " + heading;
}

qreal OsmDatabase::bearing( const GeoDataCoordinates &a, const GeoDataCoordinates &b ) const
{
    qreal delta = b.longitude() - a.longitude();
    qreal lat1 = a.latitude();
    qreal lat2 = b.latitude();
    return fmod( atan2( sin ( delta ) * cos ( lat2 ),
                       cos( lat1 ) * sin( lat2 ) - sin( lat1 ) * cos( lat2 ) * cos ( delta ) ), 2 * M_PI );
}

QString OsmDatabase::wildcardQuery( const QString &term ) const
{
    QString result = term;
    if ( term.contains( '*' ) ) {
        return " LIKE '" + result.replace( '*', '%' ) + "'";
    } else {
        return " = '" + result + "'";
    }
}

}
<|endoftext|>


<commit_before>/*
 * Moon++ Scripts for Ascent MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2007-2008 Moon++ Team <http://www.moonplusplus.info/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Setup.h"

// Event of Hallowen control
//#define EVENT_HALLOWEEN		// Decomment this for enable the event on Innkeepers

#define SPELL_TRICK_OR_TREATED  24755
#define SPELL_TREAT             24715
// -------------------------

class InnkeeperGossip : public Arcemu::Gossip::Script
{
	public:
		void OnHello(Object* pObject, Player* Plr);
		void OnSelectOption(Object* pObject, Player* Plr, uint32 Id, const char* Code);
		void Destroy() { delete this; }
};

void InnkeeperGossip::OnHello(Object* pObject, Player* Plr)
{
	Creature* pCreature = (pObject->IsCreature()) ? (TO_CREATURE(pObject)) : NULL;
	if(pCreature == NULL)
		return;
	uint32 TextID = 820;
	uint32 Text = objmgr.GetGossipTextForNpc(pCreature->GetEntry());
	if(Text != 0)
	{
		GossipText* text = NpcTextStorage.LookupEntry(Text);
		if(text != 0)
			TextID = Text;
	}
	Arcemu::Gossip::Menu menu(pCreature->GetGUID(), TextID, 0);

#ifdef	EVENT_HALLOWEEN
	if(!Plr->HasAura(SPELL_TRICK_OR_TREATED))
		menu.AddItem(Arcemu::Gossip::ICON_CHAT, "Trick or Treat!", 4);
#endif

	if(pCreature->isVendor())
		menu.AddItem(Arcemu::Gossip::ICON_VENDOR, "I would like to browse your goods.", 1);

	menu.AddItem(Arcemu::Gossip::ICON_CHAT, "Make this inn your home.", 2);
	menu.AddItem(Arcemu::Gossip::ICON_CHAT, "What can I do at an inn?", 3);

	sQuestMgr.FillQuestMenu(pCreature, Plr, menu);

	menu.Send(Plr);
}

//#define SendQuickMenu(textid) objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), textid, Plr); \
//    Menu->SendTo(Plr);

void InnkeeperGossip::OnSelectOption(Object* pObject, Player* Plr, uint32 Id, const char* Code)
{
	Creature* pCreature = (pObject->IsCreature()) ? (TO_CREATURE(pObject)) : NULL;
	if(pCreature == NULL)
		return;

	switch(Id)
	{
		case 1:     // VENDOR
			Plr->GetSession()->SendInventoryList(pCreature);
			break;
		case 2:     // BINDER
			Plr->GetSession()->SendInnkeeperBind(pCreature);
			break;
		case 3:     // WHAT CAN I DO ?
			// Prepare second menu
			Arcemu::Gossip::Menu::SendQuickMenu(pCreature->GetGUID(), 1853, Plr, 2, Arcemu::Gossip::ICON_CHAT, "Make this inn your home.");
			break;
		case 4:     // EVENT OF HALLOWEEN
			if(!Plr->HasAura(SPELL_TRICK_OR_TREATED))
			{
				pCreature->CastSpell(Plr, SPELL_TRICK_OR_TREATED, true);

				// either trick or treat, 50% chance
				if(rand() % 2)
				{
					Plr->CastSpell(Plr, SPELL_TREAT, true);
				}
				else
				{
					int32 trickspell = 0;
					switch(rand() % 9)
					{
						case 0:
							trickspell = 24753;                     // cannot cast, random 30sec
							break;
						case 1:
							trickspell = 24713;                     // lepper gnome costume
							break;
						case 2:
							if(Plr->getGender() == 0)
							{
								trickspell = 24735;                 // male ghost costume
							}
							else
							{
								trickspell = 24736;                 // female ghostcostume
							}
							break;
						case 3:
							if(Plr->getGender() == 0)
							{
								trickspell = 24711;                 // male ninja costume
							}
							else
							{
								trickspell = 24710;                 // female ninja costume
							}
							break;
						case 4:
							if(Plr->getGender() == 0)
							{
								trickspell = 24708;                 // male pirate costume
							}
							else
							{
								trickspell = 24709;                 // female pirate costume
							}
							break;
						case 5:
							trickspell = 24723;                     // skeleton costume
							break;
					}
					pCreature->CastSpell(Plr, trickspell, true);
				}
			}
			Arcemu::Gossip::Menu::Complete(Plr);
			break;
	}
}

void SetupInnkeepers(ScriptMgr* mgr)
{
	Arcemu::Gossip::Script* gs = new InnkeeperGossip();
	/* Innkeeper List */
	mgr->register_creature_gossip(15174, gs);     //Calandrath
	mgr->register_creature_gossip(18251, gs);     //Caregiver Abidaar
	mgr->register_creature_gossip(16739, gs);     //Caregiver Breel
	mgr->register_creature_gossip(16553, gs);     //Caregiver Chellan
	mgr->register_creature_gossip(18914, gs);     //Caregiver Isel
	mgr->register_creature_gossip(18906, gs);     //Caregiver Ophera Windfury
	mgr->register_creature_gossip(17553, gs);     //Caregiver Topher Loaal
	mgr->register_creature_gossip(21746, gs);     //Caretaker Aluuro
	mgr->register_creature_gossip(19352, gs);     //Dreg Cloudsweeper
	mgr->register_creature_gossip(19531, gs);     //Eyonix
	mgr->register_creature_gossip(21110, gs);     //Fizit "Doc" Clocktock
	mgr->register_creature_gossip(16602, gs);     //Floyd Pinkus
	mgr->register_creature_gossip(19470, gs);     //Gholah
	mgr->register_creature_gossip(23143, gs);     //Horus
	mgr->register_creature_gossip(11116, gs);     //Innkeeper Abeqwa
	mgr->register_creature_gossip(9501, gs);      //Innkeeper Adegwa
	mgr->register_creature_gossip(22922, gs);     //Innkeeper Aelerya
	mgr->register_creature_gossip(6740, gs);      //Innkeeper Allison
	mgr->register_creature_gossip(2352, gs);      //Innkeeper Anderson
	mgr->register_creature_gossip(6739, gs);      //Innkeeper Bates
	mgr->register_creature_gossip(18905, gs);     //Innkeeper Bazil Olof'tazun
	mgr->register_creature_gossip(1247, gs);      //Innkeeper Belm
	mgr->register_creature_gossip(19296, gs);     //Innkeeper Biribi
	mgr->register_creature_gossip(3934, gs);      //Innkeeper Boorand Plainswind
	mgr->register_creature_gossip(6727, gs);      //Innkeeper Brianna
	mgr->register_creature_gossip(7714, gs);      //Innkeeper Byula
	mgr->register_creature_gossip(18907, gs);     //Innkeeper Coryth Stoktron
	mgr->register_creature_gossip(19319, gs);     //Innkeeper Darg Bloodclaw
	mgr->register_creature_gossip(15433, gs);     //Innkeeper Delaniel
	mgr->register_creature_gossip(16458, gs);     //Innkeeper Faralia
	mgr->register_creature_gossip(295, gs);       //Innkeeper Farley
	mgr->register_creature_gossip(5111, gs);      //Innkeeper Firebrew
	mgr->register_creature_gossip(7733, gs);      //Innkeeper Fizzgrimble
	mgr->register_creature_gossip(7737, gs);      //Innkeeper Greul
	mgr->register_creature_gossip(18957, gs);     //Innkeeper Grilka
	mgr->register_creature_gossip(6928, gs);      //Innkeeper Grosk
	mgr->register_creature_gossip(6929, gs);      //Innkeeper Gryshka
	mgr->register_creature_gossip(19232, gs);     //Innkeeper Haelthol
	mgr->register_creature_gossip(6734, gs);      //Innkeeper Hearthstove
	mgr->register_creature_gossip(8931, gs);      //Innkeeper Heather
	mgr->register_creature_gossip(1464, gs);      //Innkeeper Helbrek
	mgr->register_creature_gossip(6272, gs);      //Innkeeper Janene
	mgr->register_creature_gossip(7731, gs);      //Innkeeper Jayka
	mgr->register_creature_gossip(17630, gs);     //Innkeeper Jovia
	mgr->register_creature_gossip(16542, gs);     //Innkeeper Kalarin
	mgr->register_creature_gossip(6930, gs);      //Innkeeper Karakul
	mgr->register_creature_gossip(6747, gs);      //Innkeeper Kauth
	mgr->register_creature_gossip(12196, gs);     //Innkeeper Kaylisk
	mgr->register_creature_gossip(6736, gs);      //Innkeeper Keldamyr
	mgr->register_creature_gossip(18908, gs);     //Innkeeper Kerp
	mgr->register_creature_gossip(6738, gs);      //Innkeeper Kimlya
	mgr->register_creature_gossip(11103, gs);     //Innkeeper Lyshaerya
	mgr->register_creature_gossip(6741, gs);      //Innkeeper Norman
	mgr->register_creature_gossip(6746, gs);      //Innkeeper Pala
	mgr->register_creature_gossip(19571, gs);     //Innkeeper Remi Dodoso
	mgr->register_creature_gossip(5688, gs);      //Innkeeper Renee
	mgr->register_creature_gossip(6735, gs);      //Innkeeper Saelienne
	mgr->register_creature_gossip(19495, gs);     //Innkeeper Shaunessy
	mgr->register_creature_gossip(6737, gs);      //Innkeeper Shaussiy
	mgr->register_creature_gossip(2388, gs);      //Innkeeper Shay
	mgr->register_creature_gossip(9356, gs);      //Innkeeper Shul'kar
	mgr->register_creature_gossip(7736, gs);      //Innkeeper Shyria
	mgr->register_creature_gossip(11106, gs);     //Innkeeper Sikewa
	mgr->register_creature_gossip(6807, gs);      //Innkeeper Skindle
	mgr->register_creature_gossip(5814, gs);      //Innkeeper Thulbek
	mgr->register_creature_gossip(7744, gs);      //Innkeeper Thulfram
	mgr->register_creature_gossip(6790, gs);      //Innkeeper Trelayne
	mgr->register_creature_gossip(16618, gs);     //Innkeeper Velandra
	mgr->register_creature_gossip(11118, gs);     //Innkeeper Vizzie
	mgr->register_creature_gossip(6791, gs);      //Innkeeper Wiley
	mgr->register_creature_gossip(16256, gs);     //Jessica Chambers
	mgr->register_creature_gossip(14731, gs);     //Lard
	mgr->register_creature_gossip(15397, gs);     //Marniel Amberlight
	mgr->register_creature_gossip(18913, gs);     //Matron Tikkit
	mgr->register_creature_gossip(21088, gs);     //Matron Varah
	mgr->register_creature_gossip(6778, gs);      //Melika Isenstrider
	mgr->register_creature_gossip(18245, gs);     //Merajit
	mgr->register_creature_gossip(19046, gs);     //Minalei
	mgr->register_creature_gossip(21744, gs);     //Roldemar
	mgr->register_creature_gossip(16826, gs);     //Sid Limbardi
	mgr->register_creature_gossip(6806, gs);      //Tannok Frosthammer
	mgr->register_creature_gossip(25036, gs);     //Caregiver Inaara

	//cleanup:
	//added 36 new Innkeeper's ,81 working innkeeper's now :P
	//removed Innkeeper Monica(she dos not have gossip option she is from Old Hillsbrad Foothills)
}
<commit_msg>FIXED: Localization support for some world strings in Innkeeper gossips.<commit_after>/*
 * Moon++ Scripts for Ascent MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2007-2008 Moon++ Team <http://www.moonplusplus.info/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Setup.h"

// Event of Hallowen control
//#define EVENT_HALLOWEEN		// Decomment this for enable the event on Innkeepers

#define SPELL_TRICK_OR_TREATED  24755
#define SPELL_TREAT             24715
// -------------------------

class InnkeeperGossip : public Arcemu::Gossip::Script
{
	public:
		void OnHello(Object* pObject, Player* Plr);
		void OnSelectOption(Object* pObject, Player* Plr, uint32 Id, const char* Code);
		void Destroy() { delete this; }
};

void InnkeeperGossip::OnHello(Object* pObject, Player* Plr)
{
	Creature* pCreature = (pObject->IsCreature()) ? (TO_CREATURE(pObject)) : NULL;
	if(pCreature == NULL)
		return;
	uint32 TextID = 820;
	uint32 Text = objmgr.GetGossipTextForNpc(pCreature->GetEntry());
	if(Text != 0)
	{
		GossipText* text = NpcTextStorage.LookupEntry(Text);
		if(text != 0)
			TextID = Text;
	}
	Arcemu::Gossip::Menu menu(pCreature->GetGUID(), TextID, 0);

#ifdef	EVENT_HALLOWEEN
	if(!Plr->HasAura(SPELL_TRICK_OR_TREATED))
		menu.AddItem(Arcemu::Gossip::ICON_CHAT, "Trick or Treat!", 4);
#endif

	if(pCreature->isVendor())
		menu.AddItem(Arcemu::Gossip::ICON_VENDOR, Plr->GetSession()->LocalizedWorldSrv(Arcemu::Gossip::VENDOR), 1);

	menu.AddItem(Arcemu::Gossip::ICON_CHAT, Plr->GetSession()->LocalizedWorldSrv(Arcemu::Gossip::INNKEEPER), 2);
	menu.AddItem(Arcemu::Gossip::ICON_CHAT, "What can I do at an inn?", 3);

	sQuestMgr.FillQuestMenu(pCreature, Plr, menu);

	menu.Send(Plr);
}

//#define SendQuickMenu(textid) objmgr.CreateGossipMenuForPlayer(&Menu, pCreature->GetGUID(), textid, Plr); \
//    Menu->SendTo(Plr);

void InnkeeperGossip::OnSelectOption(Object* pObject, Player* Plr, uint32 Id, const char* Code)
{
	Creature* pCreature = (pObject->IsCreature()) ? (TO_CREATURE(pObject)) : NULL;
	if(pCreature == NULL)
		return;

	switch(Id)
	{
		case 1:     // VENDOR
			Plr->GetSession()->SendInventoryList(pCreature);
			break;
		case 2:     // BINDER
			Plr->GetSession()->SendInnkeeperBind(pCreature);
			break;
		case 3:     // WHAT CAN I DO ?
			// Prepare second menu
			Arcemu::Gossip::Menu::SendQuickMenu(pCreature->GetGUID(), 1853, Plr, 2, Arcemu::Gossip::ICON_CHAT, Plr->GetSession()->LocalizedWorldSrv(Arcemu::Gossip::INNKEEPER));
			break;
		case 4:     // EVENT OF HALLOWEEN
			if(!Plr->HasAura(SPELL_TRICK_OR_TREATED))
			{
				pCreature->CastSpell(Plr, SPELL_TRICK_OR_TREATED, true);

				// either trick or treat, 50% chance
				if(rand() % 2)
				{
					Plr->CastSpell(Plr, SPELL_TREAT, true);
				}
				else
				{
					int32 trickspell = 0;
					switch(rand() % 9)
					{
						case 0:
							trickspell = 24753;                     // cannot cast, random 30sec
							break;
						case 1:
							trickspell = 24713;                     // lepper gnome costume
							break;
						case 2:
							if(Plr->getGender() == 0)
							{
								trickspell = 24735;                 // male ghost costume
							}
							else
							{
								trickspell = 24736;                 // female ghostcostume
							}
							break;
						case 3:
							if(Plr->getGender() == 0)
							{
								trickspell = 24711;                 // male ninja costume
							}
							else
							{
								trickspell = 24710;                 // female ninja costume
							}
							break;
						case 4:
							if(Plr->getGender() == 0)
							{
								trickspell = 24708;                 // male pirate costume
							}
							else
							{
								trickspell = 24709;                 // female pirate costume
							}
							break;
						case 5:
							trickspell = 24723;                     // skeleton costume
							break;
					}
					pCreature->CastSpell(Plr, trickspell, true);
				}
			}
			Arcemu::Gossip::Menu::Complete(Plr);
			break;
	}
}

void SetupInnkeepers(ScriptMgr* mgr)
{
	Arcemu::Gossip::Script* gs = new InnkeeperGossip();
	/* Innkeeper List */
	mgr->register_creature_gossip(15174, gs);     //Calandrath
	mgr->register_creature_gossip(18251, gs);     //Caregiver Abidaar
	mgr->register_creature_gossip(16739, gs);     //Caregiver Breel
	mgr->register_creature_gossip(16553, gs);     //Caregiver Chellan
	mgr->register_creature_gossip(18914, gs);     //Caregiver Isel
	mgr->register_creature_gossip(18906, gs);     //Caregiver Ophera Windfury
	mgr->register_creature_gossip(17553, gs);     //Caregiver Topher Loaal
	mgr->register_creature_gossip(21746, gs);     //Caretaker Aluuro
	mgr->register_creature_gossip(19352, gs);     //Dreg Cloudsweeper
	mgr->register_creature_gossip(19531, gs);     //Eyonix
	mgr->register_creature_gossip(21110, gs);     //Fizit "Doc" Clocktock
	mgr->register_creature_gossip(16602, gs);     //Floyd Pinkus
	mgr->register_creature_gossip(19470, gs);     //Gholah
	mgr->register_creature_gossip(23143, gs);     //Horus
	mgr->register_creature_gossip(11116, gs);     //Innkeeper Abeqwa
	mgr->register_creature_gossip(9501, gs);      //Innkeeper Adegwa
	mgr->register_creature_gossip(22922, gs);     //Innkeeper Aelerya
	mgr->register_creature_gossip(6740, gs);      //Innkeeper Allison
	mgr->register_creature_gossip(2352, gs);      //Innkeeper Anderson
	mgr->register_creature_gossip(6739, gs);      //Innkeeper Bates
	mgr->register_creature_gossip(18905, gs);     //Innkeeper Bazil Olof'tazun
	mgr->register_creature_gossip(1247, gs);      //Innkeeper Belm
	mgr->register_creature_gossip(19296, gs);     //Innkeeper Biribi
	mgr->register_creature_gossip(3934, gs);      //Innkeeper Boorand Plainswind
	mgr->register_creature_gossip(6727, gs);      //Innkeeper Brianna
	mgr->register_creature_gossip(7714, gs);      //Innkeeper Byula
	mgr->register_creature_gossip(18907, gs);     //Innkeeper Coryth Stoktron
	mgr->register_creature_gossip(19319, gs);     //Innkeeper Darg Bloodclaw
	mgr->register_creature_gossip(15433, gs);     //Innkeeper Delaniel
	mgr->register_creature_gossip(16458, gs);     //Innkeeper Faralia
	mgr->register_creature_gossip(295, gs);       //Innkeeper Farley
	mgr->register_creature_gossip(5111, gs);      //Innkeeper Firebrew
	mgr->register_creature_gossip(7733, gs);      //Innkeeper Fizzgrimble
	mgr->register_creature_gossip(7737, gs);      //Innkeeper Greul
	mgr->register_creature_gossip(18957, gs);     //Innkeeper Grilka
	mgr->register_creature_gossip(6928, gs);      //Innkeeper Grosk
	mgr->register_creature_gossip(6929, gs);      //Innkeeper Gryshka
	mgr->register_creature_gossip(19232, gs);     //Innkeeper Haelthol
	mgr->register_creature_gossip(6734, gs);      //Innkeeper Hearthstove
	mgr->register_creature_gossip(8931, gs);      //Innkeeper Heather
	mgr->register_creature_gossip(1464, gs);      //Innkeeper Helbrek
	mgr->register_creature_gossip(6272, gs);      //Innkeeper Janene
	mgr->register_creature_gossip(7731, gs);      //Innkeeper Jayka
	mgr->register_creature_gossip(17630, gs);     //Innkeeper Jovia
	mgr->register_creature_gossip(16542, gs);     //Innkeeper Kalarin
	mgr->register_creature_gossip(6930, gs);      //Innkeeper Karakul
	mgr->register_creature_gossip(6747, gs);      //Innkeeper Kauth
	mgr->register_creature_gossip(12196, gs);     //Innkeeper Kaylisk
	mgr->register_creature_gossip(6736, gs);      //Innkeeper Keldamyr
	mgr->register_creature_gossip(18908, gs);     //Innkeeper Kerp
	mgr->register_creature_gossip(6738, gs);      //Innkeeper Kimlya
	mgr->register_creature_gossip(11103, gs);     //Innkeeper Lyshaerya
	mgr->register_creature_gossip(6741, gs);      //Innkeeper Norman
	mgr->register_creature_gossip(6746, gs);      //Innkeeper Pala
	mgr->register_creature_gossip(19571, gs);     //Innkeeper Remi Dodoso
	mgr->register_creature_gossip(5688, gs);      //Innkeeper Renee
	mgr->register_creature_gossip(6735, gs);      //Innkeeper Saelienne
	mgr->register_creature_gossip(19495, gs);     //Innkeeper Shaunessy
	mgr->register_creature_gossip(6737, gs);      //Innkeeper Shaussiy
	mgr->register_creature_gossip(2388, gs);      //Innkeeper Shay
	mgr->register_creature_gossip(9356, gs);      //Innkeeper Shul'kar
	mgr->register_creature_gossip(7736, gs);      //Innkeeper Shyria
	mgr->register_creature_gossip(11106, gs);     //Innkeeper Sikewa
	mgr->register_creature_gossip(6807, gs);      //Innkeeper Skindle
	mgr->register_creature_gossip(5814, gs);      //Innkeeper Thulbek
	mgr->register_creature_gossip(7744, gs);      //Innkeeper Thulfram
	mgr->register_creature_gossip(6790, gs);      //Innkeeper Trelayne
	mgr->register_creature_gossip(16618, gs);     //Innkeeper Velandra
	mgr->register_creature_gossip(11118, gs);     //Innkeeper Vizzie
	mgr->register_creature_gossip(6791, gs);      //Innkeeper Wiley
	mgr->register_creature_gossip(16256, gs);     //Jessica Chambers
	mgr->register_creature_gossip(14731, gs);     //Lard
	mgr->register_creature_gossip(15397, gs);     //Marniel Amberlight
	mgr->register_creature_gossip(18913, gs);     //Matron Tikkit
	mgr->register_creature_gossip(21088, gs);     //Matron Varah
	mgr->register_creature_gossip(6778, gs);      //Melika Isenstrider
	mgr->register_creature_gossip(18245, gs);     //Merajit
	mgr->register_creature_gossip(19046, gs);     //Minalei
	mgr->register_creature_gossip(21744, gs);     //Roldemar
	mgr->register_creature_gossip(16826, gs);     //Sid Limbardi
	mgr->register_creature_gossip(6806, gs);      //Tannok Frosthammer
	mgr->register_creature_gossip(25036, gs);     //Caregiver Inaara

	//cleanup:
	//added 36 new Innkeeper's ,81 working innkeeper's now :P
	//removed Innkeeper Monica(she dos not have gossip option she is from Old Hillsbrad Foothills)
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <stan/optimization/bfgs_linesearch.hpp>
#include <stan/math/matrix/Eigen.hpp>

TEST(OptimizationBfgsLinesearch, CubicInterp) {
  using stan::optimization::CubicInterp;
  static const unsigned int nVals = 5;
  static const double xVals[5] = { -2.0, -1.0, 0.0, 1.0, 2.0 };
  double xMin;

  for (unsigned int i = 0; i < nVals; i++) {
    const double &x0 = xVals[i];
    const double f0 = x0*x0*x0/3.0 - x0;
    const double df0 = x0*x0 - 1.0;
    for (unsigned int j = 0; j < nVals; j++) {
      if (i == j)
        continue;

      const double &x1 = xVals[j];
      const double f1 = x1*x1*x1/3.0 - x1;
      const double df1 = x1*x1 - 1.0;

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-3.0,2.0);
      EXPECT_NEAR(-3.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-3.0,0.0);
      EXPECT_NEAR(-3.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-1.0,2.0);
      EXPECT_NEAR(1.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,0.0,2.0);
      EXPECT_NEAR(1.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,0.5,1.5);
      EXPECT_NEAR(1.0,xMin,1e-8);
    }
  }
}

TEST(OptimizationBfgsLinesearch, CubicInterp_6arg) {
  FAIL()
    << "add tests for the 6 argument version of CubicInterp()";
}

class linesearch_testfunc {
public:
  double operator()(const Eigen::Matrix<double,Eigen::Dynamic,1> &x) {
    return x.dot(x) - 1.0;
  }
  int operator()(const Eigen::Matrix<double,Eigen::Dynamic,1> &x,
                 double &f, Eigen::Matrix<double,Eigen::Dynamic,1> &g) {
    f = x.dot(x) - 1.0;
    g = 2.0*x;
    return 0;
  }
};

TEST(OptimizationBfgsLinesearch, WolfLSZoom) {
  FAIL()
    << "add tests for WolfLSZoom()";
}

TEST(OptimizationBfgsLinesearch, wolfeLineSearch) {
  using stan::optimization::WolfeLineSearch;

  static const double c1 = 1e-4;
  static const double c2 = 0.9;
  static const double minAlpha = 1e-16;

  linesearch_testfunc func1;
  Eigen::Matrix<double,-1,1> x0,x1;
  double f0,f1;
  Eigen::Matrix<double,-1,1> p, gradx0,gradx1;
  double alpha;
  int ret;

  x0.setOnes(5,1);
  func1(x0,f0,gradx0);

  p = -gradx0;

  alpha = 2.0;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));

  alpha = 10.0;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));

  alpha = 0.25;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.25,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));
}
<commit_msg>added bfgs_linesearch tests<commit_after>#include <gtest/gtest.h>
#include <stan/optimization/bfgs_linesearch.hpp>
#include <stan/math/matrix/Eigen.hpp>

TEST(OptimizationBfgsLinesearch, CubicInterp) {
  using stan::optimization::CubicInterp;
  static const unsigned int nVals = 5;
  static const double xVals[5] = { -2.0, -1.0, 0.0, 1.0, 2.0 };
  double xMin;

  for (unsigned int i = 0; i < nVals; i++) {
    const double &x0 = xVals[i];
    const double f0 = x0*x0*x0/3.0 - x0;
    const double df0 = x0*x0 - 1.0;
    for (unsigned int j = 0; j < nVals; j++) {
      if (i == j)
        continue;

      const double &x1 = xVals[j];
      const double f1 = x1*x1*x1/3.0 - x1;
      const double df1 = x1*x1 - 1.0;

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-3.0,2.0);
      EXPECT_NEAR(-3.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-3.0,0.0);
      EXPECT_NEAR(-3.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,-1.0,2.0);
      EXPECT_NEAR(1.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,0.0,2.0);
      EXPECT_NEAR(1.0,xMin,1e-8);

      xMin = CubicInterp(x0,f0,df0,x1,f1,df1,0.5,1.5);
      EXPECT_NEAR(1.0,xMin,1e-8);
    }
  }
}

TEST(OptimizationBfgsLinesearch, CubicInterp_6arg) {
  using stan::optimization::CubicInterp;
  static const unsigned int nVals = 5;
  static const double xVals[5] = { -2.0, -1.0, 0.0, 1.0, 2.0 };
  double x;

  for (unsigned int i = 0; i < nVals; i++) {
    const double &x0 = xVals[i];
    const double f0 = x0*x0*x0/3.0 - x0;
    const double df0 = x0*x0 - 1.0;
    for (unsigned int j = 0; j < nVals; j++) {
      if (i == j)
        continue;

      const double &x1 = xVals[j];
      const double f1 = x1*x1*x1/3.0 - x1;
      const double df1 = x1*x1 - 1.0;

      x = CubicInterp(df0,x1-x0,f1-f0,df1,-3.0-x0,2.0-x0);
      EXPECT_NEAR(-3.0,x0+x,1e-8);

      x = CubicInterp(df0,x1-x0,f1-f0,df1,-3.0-x0,0.0-x0);
      EXPECT_NEAR(-3.0,x0+x,1e-8);

      x = CubicInterp(df0,x1-x0,f1-f0,df1,-1.0-x0,2.0-x0);
      EXPECT_NEAR(1.0,x0+x,1e-8);

      x = CubicInterp(df0,x1-x0,f1-f0,df1,0.0-x0,2.0-x0);
      EXPECT_NEAR(1.0,x0+x,1e-8);

      x = CubicInterp(df0,x1-x0,f1-f0,df1,0.5-x0,1.5-x0);
      EXPECT_NEAR(1.0,x0+x,1e-8);
    }
  }
}

class linesearch_testfunc {
public:
  double operator()(const Eigen::Matrix<double,Eigen::Dynamic,1> &x) {
    return x.dot(x) - 1.0;
  }
  int operator()(const Eigen::Matrix<double,Eigen::Dynamic,1> &x,
                 double &f, Eigen::Matrix<double,Eigen::Dynamic,1> &g) {
    f = x.dot(x) - 1.0;
    g = 2.0*x;
    return 0;
  }
};

TEST(OptimizationBfgsLinesearch, WolfLSZoom) {
  using stan::optimization::WolfLSZoom;

  static const double c1 = 1e-4;
  static const double c2 = 0.9;
  static const double minAlpha = 1e-16;

  linesearch_testfunc func1;
  Eigen::Matrix<double,-1,1> x0,x1;
  double f0,f1;
  Eigen::Matrix<double,-1,1> p, gradx0,gradx1;
  double alpha;
  int ret;

  x0.setOnes(5,1);
  p = -gradx0;

  func1(x0,f0,gradx0);

  p = -gradx0;

  double dfp = gradx0.dot(p);
  alpha = 2.0;
  x1 = x0 + alpha*p;
  func1(x1,f1,gradx1);

  double dfp2 = gradx1.dot(p);

  ret = WolfLSZoom(alpha, x1, f1, gradx1,
                   func1, x0, f0, dfp,
                   c1*dfp, c2*dfp, p,
                   minAlpha, f0, dfp,
                   alpha, f1, dfp2, 1e-16);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));

  alpha = 10.0;
  x1 = x0 + alpha*p;
  func1(x1,f1,gradx1);

  dfp2 = gradx1.dot(p);

  ret = WolfLSZoom(alpha, x1, f1, gradx1,
                   func1, x0, f0, dfp,
                   c1*dfp, c2*dfp, p,
                   minAlpha, f0, dfp,
                   alpha, f1, dfp2, 1e-16);

  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));
}

TEST(OptimizationBfgsLinesearch, wolfeLineSearch) {
  using stan::optimization::WolfeLineSearch;

  static const double c1 = 1e-4;
  static const double c2 = 0.9;
  static const double minAlpha = 1e-16;

  linesearch_testfunc func1;
  Eigen::Matrix<double,-1,1> x0,x1;
  double f0,f1;
  Eigen::Matrix<double,-1,1> p, gradx0,gradx1;
  double alpha;
  int ret;

  x0.setOnes(5,1);
  func1(x0,f0,gradx0);

  p = -gradx0;

  alpha = 2.0;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));

  alpha = 10.0;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.5,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));

  alpha = 0.25;
  ret = WolfeLineSearch(func1, alpha,
                        x1, f1, gradx1,
                        p, x0, f0, gradx0,
                        c1, c2, minAlpha);
  EXPECT_EQ(0,ret);
  EXPECT_NEAR(0.25,alpha,1e-8);
  EXPECT_NEAR(0,(x1 - (x0 + alpha*p)).norm(),1e-8);
  EXPECT_EQ(f1,func1(x1));
  EXPECT_LE(f1,f0 + c1*alpha*p.dot(gradx0));
  EXPECT_LE(std::fabs(p.dot(gradx1)),c2*std::fabs(p.dot(gradx0)));
}
<|endoftext|>


<commit_before>/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * 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
 * imitations under the License.
 */

/*
 * XSEC
 *
 * XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
 *                         HTTP wrapper for testing the client code.
 *
 *
 * $Id$
 *
 */

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

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>

#include <xsec/utils/XSECSOAPRequestorSimple.hpp>
#include <xsec/framework/XSECError.hpp>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Platform specific constructor
// --------------------------------------------------------------------------------

XSECSOAPRequestorSimple::XSECSOAPRequestorSimple(const XMLCh * uri) : m_uri(uri) {

}

// --------------------------------------------------------------------------------
//           Interface
// --------------------------------------------------------------------------------

DOMDocument * XSECSOAPRequestorSimple::doRequest(DOMDocument * request) {

	char * content = wrapAndSerialise(request);

	// First we need to serialise

    char                fBuffer[4000];
    char *              fBufferEnd;
    char *              fBufferPos;

    //
    // Pull all of the parts of the URL out of th m_uri object, and transcode them
    //   and transcode them back to ASCII.
    //
    const XMLCh*        hostName = m_uri.getHost();
    char*               hostNameAsCharStar = XMLString::transcode(hostName);
    ArrayJanitor<char>  janBuf1(hostNameAsCharStar);

    const XMLCh*        path = m_uri.getPath();
    char*               pathAsCharStar = XMLString::transcode(path);
    ArrayJanitor<char>  janBuf2(pathAsCharStar);

    const XMLCh*        fragment = m_uri.getFragment();
    char*               fragmentAsCharStar = 0;
    if (fragment)
        fragmentAsCharStar = XMLString::transcode(fragment);
    ArrayJanitor<char>  janBuf3(fragmentAsCharStar);

    const XMLCh*        query = m_uri.getQueryString();
    char*               queryAsCharStar = 0;
    if (query)
        queryAsCharStar = XMLString::transcode(query);
    ArrayJanitor<char>  janBuf4(queryAsCharStar);

    unsigned short      portNumber = (unsigned short) m_uri.getPort();

	// If no number is set, go with port 80
	if (portNumber == USHRT_MAX)
		portNumber = 80;

    //
    // Set up a socket.
    //
    struct hostent*     hostEntPtr = 0;
    struct sockaddr_in  sa;

    if ((hostEntPtr = gethostbyname(hostNameAsCharStar)) == NULL)
    {
        unsigned long  numAddress = inet_addr(hostNameAsCharStar);
        if (numAddress == 0)
        {
            ThrowXML(NetAccessorException,
                     XMLExcepts::NetAcc_TargetResolution);
        }
        if ((hostEntPtr =
                gethostbyaddr((char *) &numAddress,
                              sizeof(unsigned long), AF_INET)) == NULL)
        {
            ThrowXML(NetAccessorException,
                     XMLExcepts::NetAcc_TargetResolution);
        }
    }

    memcpy((void *) &sa.sin_addr,
           (const void *) hostEntPtr->h_addr, hostEntPtr->h_length);
    sa.sin_family = hostEntPtr->h_addrtype;
    sa.sin_port = htons(portNumber);

    int s = socket(hostEntPtr->h_addrtype, SOCK_STREAM, 0);
    if (s < 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error creating socket");

    }

    if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error connecting to end server");
    }

    // The port is open and ready to go.
    // Build up the http GET command to send to the server.
    // To do:  We should really support http 1.1.  This implementation
    //         is weak.

    memset(fBuffer, 0, sizeof(fBuffer));

    strcpy(fBuffer, "POST ");
    strcat(fBuffer, pathAsCharStar);

    if (queryAsCharStar != 0)
    {
        // Tack on a ? before the fragment
        strcat(fBuffer,"?");
        strcat(fBuffer, queryAsCharStar);
    }

    if (fragmentAsCharStar != 0)
    {
        strcat(fBuffer, fragmentAsCharStar);
    }
    strcat(fBuffer, " HTTP/1.0\r\n");

	strcat(fBuffer, "Content-Type: text/xml; charset=utf-8\r\n");

    strcat(fBuffer, "Host: ");
    strcat(fBuffer, hostNameAsCharStar);
    if (portNumber != 80)
    {
        int i = strlen(fBuffer);
		sprintf(fBuffer+i, ":%d", portNumber);
    }
	strcat(fBuffer, "\r\n");

	strcat(fBuffer, "Content-Length: ");
    int i = (int) strlen(fBuffer);
	sprintf(fBuffer+i, "%d", strlen(content));
	strcat(fBuffer, "\r\n");
	strcat(fBuffer, "SOAPAction: \"\"\r\n");

/*	strcat(fBuffer, "Connection: Close\r\n");
	strcat(fBuffer, "Cache-Control: no-cache\r\n");*/
    strcat(fBuffer, "\r\n");

	// Now the content
	strcat(fBuffer, content);

    // Send the http request
    int lent = strlen(fBuffer);
    int  aLent = 0;
    if ((aLent = write(s, (void *) fBuffer, lent)) != lent)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error writing to socket");
    }

    //
    // get the response, check the http header for errors from the server.
    //
    aLent = read(s, (void *)fBuffer, sizeof(fBuffer)-1);
	/***/
	fBuffer[aLent] = '\0';
	printf(fBuffer);
	/***/
    if (aLent <= 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    fBufferEnd = fBuffer+aLent;
    *fBufferEnd = 0;

    // Find the break between the returned http header and any data.
    //  (Delimited by a blank line)
    // Hang on to any data for use by the first read from this BinHTTPURLInputStream.
    //
    fBufferPos = strstr(fBuffer, "\r\n\r\n");
    if (fBufferPos != 0)
    {
        fBufferPos += 4;
        *(fBufferPos-2) = 0;
    }
    else
    {
        fBufferPos = strstr(fBuffer, "\n\n");
        if (fBufferPos != 0)
        {
            fBufferPos += 2;
            *(fBufferPos-1) = 0;
        }
        else
            fBufferPos = fBufferEnd;
    }

    // Make sure the header includes an HTTP 200 OK response.
    //
    char *p = strstr(fBuffer, "HTTP");
    if (p == 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    p = strchr(p, ' ');
    if (p == 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    int httpResponse = atoi(p);

	if (httpResponse == 302 || httpResponse == 301) {
		//Once grows, should use a switch
		char redirectBuf[256];
		int q;

		// Find the "Location:" string
		p = strstr(p, "Location:");
		if (p == 0)
        {
			throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
		}
		p = strchr(p, ' ');
		if (p == 0)
		{
			throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
		}

		// Now read
		p++;
		for (q=0; q < 255 && p[q] != '\r' && p[q] !='\n'; ++q)
			redirectBuf[q] = p[q];

		redirectBuf[q] = '\0';

		// Try to find this location
		m_uri = XMLUri(XMLString::transcode(redirectBuf));

		return doRequest(request);

	}

    else if (httpResponse != 200)
    {
        // Most likely a 404 Not Found error.
        //   Should recognize and handle the forwarding responses.
        //
		throw XSECException(XSECException::HTTPURIInputStreamError,
						"Unknown HTTP Response");
    }
	/*
	while (aLent != 0) {
		aLent = read(s, (void *)fBuffer, sizeof(fBuffer)-1);

		fBuffer[aLent] = '\0';
		printf(fBuffer);

	}
*/
	/* Now find out how long the return is */

	p = strstr(fBuffer, "Content-Length:");
	if (p == NULL) {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Content-Length required in SOAP HTTP Response");
	}

	p = strchr(p, ' ');
	p++;

	int responseLength = atoi(p);

	char * responseBuffer;
	XSECnew(responseBuffer, char[responseLength]);
	ArrayJanitor<char> j_responseBuffer(responseBuffer);

	lent = fBufferEnd - fBufferPos;
	memcpy(responseBuffer, fBufferPos, lent);
	while (lent < responseLength) {
	    aLent = read(s, &responseBuffer[lent], responseLength - lent);
		lent += aLent;
	}

    return parseAndUnwrap(responseBuffer, responseLength);

}

<commit_msg>Cleaned up Unix simple SOAP client<commit_after>/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * 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
 * imitations under the License.
 */

/*
 * XSEC
 *
 * XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
 *                         HTTP wrapper for testing the client code.
 *
 *
 * $Id$
 *
 */

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

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>

#include <xsec/utils/XSECSOAPRequestorSimple.hpp>
#include <xsec/framework/XSECError.hpp>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Platform specific constructor
// --------------------------------------------------------------------------------

XSECSOAPRequestorSimple::XSECSOAPRequestorSimple(const XMLCh * uri) : m_uri(uri) {

}

// --------------------------------------------------------------------------------
//           Interface
// --------------------------------------------------------------------------------

DOMDocument * XSECSOAPRequestorSimple::doRequest(DOMDocument * request) {

	char * content = wrapAndSerialise(request);

	// First we need to serialise

    char                fBuffer[4000];
    char *              fBufferEnd;
    char *              fBufferPos;

    //
    // Pull all of the parts of the URL out of th m_uri object, and transcode them
    //   and transcode them back to ASCII.
    //
    const XMLCh*        hostName = m_uri.getHost();
    char*               hostNameAsCharStar = XMLString::transcode(hostName);
    ArrayJanitor<char>  janBuf1(hostNameAsCharStar);

    const XMLCh*        path = m_uri.getPath();
    char*               pathAsCharStar = XMLString::transcode(path);
    ArrayJanitor<char>  janBuf2(pathAsCharStar);

    const XMLCh*        fragment = m_uri.getFragment();
    char*               fragmentAsCharStar = 0;
    if (fragment)
        fragmentAsCharStar = XMLString::transcode(fragment);
    ArrayJanitor<char>  janBuf3(fragmentAsCharStar);

    const XMLCh*        query = m_uri.getQueryString();
    char*               queryAsCharStar = 0;
    if (query)
        queryAsCharStar = XMLString::transcode(query);
    ArrayJanitor<char>  janBuf4(queryAsCharStar);

    unsigned short      portNumber = (unsigned short) m_uri.getPort();

	// If no number is set, go with port 80
	if (portNumber == USHRT_MAX)
		portNumber = 80;

    //
    // Set up a socket.
    //
    struct hostent*     hostEntPtr = 0;
    struct sockaddr_in  sa;

    if ((hostEntPtr = gethostbyname(hostNameAsCharStar)) == NULL)
    {
        unsigned long  numAddress = inet_addr(hostNameAsCharStar);
        if (numAddress == 0)
        {
            ThrowXML(NetAccessorException,
                     XMLExcepts::NetAcc_TargetResolution);
        }
        if ((hostEntPtr =
                gethostbyaddr((char *) &numAddress,
                              sizeof(unsigned long), AF_INET)) == NULL)
        {
            ThrowXML(NetAccessorException,
                     XMLExcepts::NetAcc_TargetResolution);
        }
    }

    memcpy((void *) &sa.sin_addr,
           (const void *) hostEntPtr->h_addr, hostEntPtr->h_length);
    sa.sin_family = hostEntPtr->h_addrtype;
    sa.sin_port = htons(portNumber);

    int s = socket(hostEntPtr->h_addrtype, SOCK_STREAM, 0);
    if (s < 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error creating socket");

    }

    if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error connecting to end server");
    }

    // The port is open and ready to go.
    // Build up the http GET command to send to the server.
    // To do:  We should really support http 1.1.  This implementation
    //         is weak.

    memset(fBuffer, 0, sizeof(fBuffer));

    strcpy(fBuffer, "POST ");
    strcat(fBuffer, pathAsCharStar);

    if (queryAsCharStar != 0)
    {
        // Tack on a ? before the fragment
        strcat(fBuffer,"?");
        strcat(fBuffer, queryAsCharStar);
    }

    if (fragmentAsCharStar != 0)
    {
        strcat(fBuffer, fragmentAsCharStar);
    }
    strcat(fBuffer, " HTTP/1.0\r\n");

	strcat(fBuffer, "Content-Type: text/xml; charset=utf-8\r\n");

    strcat(fBuffer, "Host: ");
    strcat(fBuffer, hostNameAsCharStar);
    if (portNumber != 80)
    {
        int i = strlen(fBuffer);
		sprintf(fBuffer+i, ":%d", portNumber);
    }
	strcat(fBuffer, "\r\n");

	strcat(fBuffer, "Content-Length: ");
    int i = (int) strlen(fBuffer);
	sprintf(fBuffer+i, "%d", strlen(content));
	strcat(fBuffer, "\r\n");
	strcat(fBuffer, "SOAPAction: \"\"\r\n");

/*	strcat(fBuffer, "Connection: Close\r\n");
	strcat(fBuffer, "Cache-Control: no-cache\r\n");*/
    strcat(fBuffer, "\r\n");

	// Now the content
	strcat(fBuffer, content);

    // Send the http request
    int lent = strlen(fBuffer);
    int  aLent = 0;
    if ((aLent = write(s, (void *) fBuffer, lent)) != lent)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error writing to socket");
    }

    //
    // get the response, check the http header for errors from the server.
    //
    aLent = read(s, (void *)fBuffer, sizeof(fBuffer)-1);
	/*
	fBuffer[aLent] = '\0';
	printf(fBuffer);
	*/
    if (aLent <= 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    fBufferEnd = fBuffer+aLent;
    *fBufferEnd = 0;

    // Find the break between the returned http header and any data.
    //  (Delimited by a blank line)
    // Hang on to any data for use by the first read from this BinHTTPURLInputStream.
    //
    fBufferPos = strstr(fBuffer, "\r\n\r\n");
    if (fBufferPos != 0)
    {
        fBufferPos += 4;
        *(fBufferPos-2) = 0;
    }
    else
    {
        fBufferPos = strstr(fBuffer, "\n\n");
        if (fBufferPos != 0)
        {
            fBufferPos += 2;
            *(fBufferPos-1) = 0;
        }
        else
            fBufferPos = fBufferEnd;
    }

    // Make sure the header includes an HTTP 200 OK response.
    //
    char *p = strstr(fBuffer, "HTTP");
    if (p == 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    p = strchr(p, ' ');
    if (p == 0)
    {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
    }

    int httpResponse = atoi(p);

	if (httpResponse == 302 || httpResponse == 301) {
		//Once grows, should use a switch
		char redirectBuf[256];
		int q;

		// Find the "Location:" string
		p = strstr(p, "Location:");
		if (p == 0)
        {
			throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
		}
		p = strchr(p, ' ');
		if (p == 0)
		{
			throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error reported reading socket");
		}

		// Now read
		p++;
		for (q=0; q < 255 && p[q] != '\r' && p[q] !='\n'; ++q)
			redirectBuf[q] = p[q];

		redirectBuf[q] = '\0';

		// Try to find this location
		m_uri = XMLUri(XMLString::transcode(redirectBuf));

		return doRequest(request);

	}

    else if (httpResponse != 200)
    {
        // Most likely a 404 Not Found error.
        //   Should recognize and handle the forwarding responses.
        //
		throw XSECException(XSECException::HTTPURIInputStreamError,
						"Unknown HTTP Response");
    }

	/* Now find out how long the return is */

	p = strstr(fBuffer, "Content-Length:");
	if (p == NULL) {
        throw XSECException(XSECException::HTTPURIInputStreamError,
							"Content-Length required in SOAP HTTP Response");
	}

	p = strchr(p, ' ');
	p++;

	int responseLength = atoi(p);

	char * responseBuffer;
	XSECnew(responseBuffer, char[responseLength]);
	ArrayJanitor<char> j_responseBuffer(responseBuffer);

	lent = fBufferEnd - fBufferPos;
	memcpy(responseBuffer, fBufferPos, lent);
	while (lent < responseLength) {
	    aLent = read(s, &responseBuffer[lent], responseLength - lent);
		lent += aLent;
	}

    return parseAndUnwrap(responseBuffer, responseLength);

}

<|endoftext|>