<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
//  TEST    Foundation::IO::Network::Transfer
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    <iostream>
#include    <random>

#include    "Stroika/Foundation/Cryptography/Encoding/Algorithm/Base64.h"
#include    "Stroika/Foundation/DataExchange/JSON/Reader.h"
#include    "Stroika/Foundation/Debug/Trace.h"
#include    "Stroika/Foundation/Execution/RequiredComponentMissingException.h"
#include    "Stroika/Foundation/IO/Network/Transfer/Client.h"
#if     qHasFeature_LibCurl
#include    "Stroika/Foundation/IO/Network/Transfer/Client_libcurl.h"
#endif
#if     qHasFeature_WinHTTP
#include    "Stroika/Foundation/IO/Network/Transfer/Client_WinHTTP.h"
#endif

#include    "../TestHarness/TestHarness.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;
using   namespace   Stroika::Foundation::IO::Network::Transfer;

namespace {
    namespace Test_1_SimpleConnnectionTests_ {
        namespace Private_ {
            void    Test_1_SimpleFetch_Google_C_ (Connection c)
            {
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
            }
            void    Test_2_SimpleFetch_SSL_Google_C_ (Connection c)
            {
                try {
                    c.SetURL (URL::Parse (L"https://www.google.com"));
                    Response    r   =   c.GET ();
                    VerifyTestResult (r.GetSucceeded ());
                    VerifyTestResult (r.GetData ().size () > 1);
                }
#if     qHasFeature_LibCurl
                catch (const LibCurlException& lce) {
#if     !qHasFeature_OpenSSL
                    if (lce.GetCode () == 1/*CURLE_UNSUPPORTED_PROTOCOL*/) {
                        DbgTrace ("Warning - ignored exception doing LibCurl/ssl - for now probably just no SSL support with libcurl");
                        return;
                    }
#endif
                    throw;
                }
#else
                catch (...) {
                    throw;
                }
#endif
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                Test_1_SimpleFetch_Google_C_ (factory ());
                Test_2_SimpleFetch_SSL_Google_C_ (factory ());
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_1_SimpleConnnectionTests_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test_2_SimpleFetch_httpbin_ {
        namespace Private_ {
            void    T1_httpbin_SimpleGET_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T1_httpbin_SimpleGET_");
                c.SetURL (URL::Parse (L"http://httpbin.org/get"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    VerifyTestResult (vv.ContainsKey (L"args"));
                    VerifyTestResult (vv[L"url"] == L"http://httpbin.org/get");
                }
            }
            void    T2_httpbin_SimplePOST_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T2_httpbin_SimplePOST_");
                using   Memory::BLOB;

                static   mt19937 sRNG_;

                c.SetURL (URL::Parse (L"http://httpbin.org/post"));
                BLOB    roundTripTestData = [] () {
                    Memory::SmallStackBuffer<Byte> buf (1024);
                    for (size_t i = 0; i < buf.GetSize (); ++i) {
                        buf[i] = static_cast<Byte> (uniform_int_distribution<unsigned short>()(sRNG_));
                    }
                    return BLOB (buf.begin (), buf.end ());
                } ();
                Response    r   =   c.POST (roundTripTestData, DataExchange::PredefinedInternetMediaType::OctetStream_CT ());
                VerifyTestResult (r.GetSucceeded ());
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    DbgTrace ("POST parsed response:");
                    for (auto i : vv) {
                        DbgTrace (L"%s : %s", i.fKey.c_str (), i.fValue.As<String> ().c_str ());
                    }
                    String  dataValueString = vv.Lookup (L"data").Value ().As<String> ();
                    {
                        size_t i = dataValueString.Find (',');
                        if (i != -1) {
                            dataValueString = dataValueString.SubString (i + 1);
                        }
                    }
                    BLOB    resultBLOB = Cryptography::Encoding::Algorithm::DecodeBase64 (dataValueString.AsUTF8 ());
                    VerifyTestResult (resultBLOB == roundTripTestData);
                }
            }
            void    T3_httpbin_SimplePUT_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T3_httpbin_SimplePUT_");
                using   Memory::BLOB;

                static   mt19937 sRNG_;

                c.SetURL (URL::Parse (L"http://httpbin.org/put"));
                BLOB    roundTripTestData = [] () {
                    Memory::SmallStackBuffer<Byte> buf (1024);
                    for (size_t i = 0; i < buf.GetSize (); ++i) {
                        buf[i] = static_cast<Byte> (uniform_int_distribution<unsigned short>()(sRNG_));
                    }
                    return BLOB (buf.begin (), buf.end ());
                } ();
                Response    r   =   c.PUT (roundTripTestData, DataExchange::PredefinedInternetMediaType::OctetStream_CT ());
                VerifyTestResult (r.GetSucceeded ());
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    DbgTrace ("PUT parsed response:");
                    for (auto i : vv) {
                        DbgTrace (L"%s : %s", i.fKey.c_str (), i.fValue.As<String> ().c_str ());
                    }
                    String  dataValueString = vv.Lookup (L"data").Value ().As<String> ();
                    {
                        size_t i = dataValueString.Find (',');
                        if (i != -1) {
                            dataValueString = dataValueString.SubString (i + 1);
                        }
                    }
                    BLOB    resultBLOB = Cryptography::Encoding::Algorithm::DecodeBase64 (dataValueString.AsUTF8 ());
                    VerifyTestResult (resultBLOB == roundTripTestData);
                }
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                {
                    T1_httpbin_SimpleGET_ (factory ());
                    T2_httpbin_SimplePOST_ (factory ());
                }
                {
                    // Connection re-use
                    Connection conn = factory ();
                    T1_httpbin_SimpleGET_ (conn);
                    T2_httpbin_SimplePOST_ (conn);
                    T3_httpbin_SimplePUT_ (conn);
                }
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_2_SimpleFetch_httpbin_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test3_TextStreamResponse_ {
        namespace Private_ {
            void    Test_1_SimpleFetch_Google_C_ (Connection c)
            {
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                for (auto i : r.GetHeaders ()) {
                    DbgTrace (L"%s=%s", i.fKey.c_str (), i.fValue.c_str ());
                }
                InternetMediaType contentType = r.GetContentType ();
                String responseText = r.GetDataTextInputStream ().ReadAll ();
                DbgTrace (L"responseText = %s", responseText.c_str ());
                VerifyTestResult (responseText.Contains (L"google"));
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                Test_1_SimpleFetch_Google_C_ (factory ());
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test3_TextStreamResponse_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test_4_RefDocsTests_ {
        namespace Private_ {
            void    T1_get_ ()
            {
                Connection  c   =   IO::Network::Transfer::CreateConnection ();
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
            }

        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_4_RefDocsTests_");
            try {
                Private_::T1_get_ ();
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
        }
    }
}

namespace {
    namespace Test_5_SSLCertCheckTests_ {
        namespace Private_ {
            void    T1_get_ (Connection::Options o)
            {
                Connection  c   =   IO::Network::Transfer::CreateConnection (o);
                try {
                    c.SetURL (URL::Parse (L"https://testssl-valid.disig.sk/index.en.html"));
                    Response    r   =   c.GET ();
                    VerifyTestResult (r.GetSucceeded ());
                    VerifyTestResult (r.GetData ().size () > 1);
                }
#if     qHasFeature_LibCurl
                catch (const LibCurlException& lce) {
#if     !qHasFeature_OpenSSL
                    if (lce.GetCode () == 1/*CURLE_UNSUPPORTED_PROTOCOL*/) {
                        DbgTrace ("Warning - ignored exception doing LibCurl/ssl - for now probably just no SSL support with libcurl");
                        return;
                    }
#endif
                    throw;
                }
#else
                catch (...) {
                    throw;
                }
#endif
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_5_SSLCertCheckTests_");
            Connection::Options o;
            try {
                o.fFailConnectionIfSSLCertificateInvalid = true;
                Private_::T1_get_ (o);
                VerifyTestResult (false);
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
            catch (...) {
                // Good - this should fail
            }
            try {
                o.fFailConnectionIfSSLCertificateInvalid = false;
                Private_::T1_get_ (o);
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
            catch (...) {
                VerifyTestResult (false);
            }
        }
    }
}

namespace   {
    void    DoRegressionTests_ ()
    {
        Test_1_SimpleConnnectionTests_::DoTests_ ();
        Test_2_SimpleFetch_httpbin_::DoTests_ ();
        Test3_TextStreamResponse_::DoTests_ ();
        Test_4_RefDocsTests_::DoTests_ ();
        Test_5_SSLCertCheckTests_::DoTests_ ();
    }
}

int main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}
<commit_msg>another workaround for too complicated ssl tests with curl/no openssl<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
//  TEST    Foundation::IO::Network::Transfer
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    <iostream>
#include    <random>

#include    "Stroika/Foundation/Cryptography/Encoding/Algorithm/Base64.h"
#include    "Stroika/Foundation/DataExchange/JSON/Reader.h"
#include    "Stroika/Foundation/Debug/Trace.h"
#include    "Stroika/Foundation/Execution/RequiredComponentMissingException.h"
#include    "Stroika/Foundation/IO/Network/Transfer/Client.h"
#if     qHasFeature_LibCurl
#include    "Stroika/Foundation/IO/Network/Transfer/Client_libcurl.h"
#endif
#if     qHasFeature_WinHTTP
#include    "Stroika/Foundation/IO/Network/Transfer/Client_WinHTTP.h"
#endif

#include    "../TestHarness/TestHarness.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::Network;
using   namespace   Stroika::Foundation::IO::Network::Transfer;

namespace {
    namespace Test_1_SimpleConnnectionTests_ {
        namespace Private_ {
            void    Test_1_SimpleFetch_Google_C_ (Connection c)
            {
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
            }
            void    Test_2_SimpleFetch_SSL_Google_C_ (Connection c)
            {
                try {
                    c.SetURL (URL::Parse (L"https://www.google.com"));
                    Response    r   =   c.GET ();
                    VerifyTestResult (r.GetSucceeded ());
                    VerifyTestResult (r.GetData ().size () > 1);
                }
#if     qHasFeature_LibCurl
                catch (const LibCurlException& lce) {
#if     !qHasFeature_OpenSSL
                    if (lce.GetCode () == 1/*CURLE_UNSUPPORTED_PROTOCOL*/) {
                        DbgTrace ("Warning - ignored exception doing LibCurl/ssl - for now probably just no SSL support with libcurl");
                        return;
                    }
#endif
                    throw;
                }
#else
                catch (...) {
                    throw;
                }
#endif
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                Test_1_SimpleFetch_Google_C_ (factory ());
                Test_2_SimpleFetch_SSL_Google_C_ (factory ());
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_1_SimpleConnnectionTests_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test_2_SimpleFetch_httpbin_ {
        namespace Private_ {
            void    T1_httpbin_SimpleGET_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T1_httpbin_SimpleGET_");
                c.SetURL (URL::Parse (L"http://httpbin.org/get"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    VerifyTestResult (vv.ContainsKey (L"args"));
                    VerifyTestResult (vv[L"url"] == L"http://httpbin.org/get");
                }
            }
            void    T2_httpbin_SimplePOST_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T2_httpbin_SimplePOST_");
                using   Memory::BLOB;

                static   mt19937 sRNG_;

                c.SetURL (URL::Parse (L"http://httpbin.org/post"));
                BLOB    roundTripTestData = [] () {
                    Memory::SmallStackBuffer<Byte> buf (1024);
                    for (size_t i = 0; i < buf.GetSize (); ++i) {
                        buf[i] = static_cast<Byte> (uniform_int_distribution<unsigned short>()(sRNG_));
                    }
                    return BLOB (buf.begin (), buf.end ());
                } ();
                Response    r   =   c.POST (roundTripTestData, DataExchange::PredefinedInternetMediaType::OctetStream_CT ());
                VerifyTestResult (r.GetSucceeded ());
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    DbgTrace ("POST parsed response:");
                    for (auto i : vv) {
                        DbgTrace (L"%s : %s", i.fKey.c_str (), i.fValue.As<String> ().c_str ());
                    }
                    String  dataValueString = vv.Lookup (L"data").Value ().As<String> ();
                    {
                        size_t i = dataValueString.Find (',');
                        if (i != -1) {
                            dataValueString = dataValueString.SubString (i + 1);
                        }
                    }
                    BLOB    resultBLOB = Cryptography::Encoding::Algorithm::DecodeBase64 (dataValueString.AsUTF8 ());
                    VerifyTestResult (resultBLOB == roundTripTestData);
                }
            }
            void    T3_httpbin_SimplePUT_ (Connection c)
            {
                Debug::TraceContextBumper ctx ("T3_httpbin_SimplePUT_");
                using   Memory::BLOB;

                static   mt19937 sRNG_;

                c.SetURL (URL::Parse (L"http://httpbin.org/put"));
                BLOB    roundTripTestData = [] () {
                    Memory::SmallStackBuffer<Byte> buf (1024);
                    for (size_t i = 0; i < buf.GetSize (); ++i) {
                        buf[i] = static_cast<Byte> (uniform_int_distribution<unsigned short>()(sRNG_));
                    }
                    return BLOB (buf.begin (), buf.end ());
                } ();
                Response    r   =   c.PUT (roundTripTestData, DataExchange::PredefinedInternetMediaType::OctetStream_CT ());
                VerifyTestResult (r.GetSucceeded ());
                {
                    VariantValue v = JSON::Reader ().Read (r.GetDataBinaryInputStream ());
                    Mapping<String, VariantValue> vv = v.As<Mapping<String, VariantValue>> ();
                    DbgTrace ("PUT parsed response:");
                    for (auto i : vv) {
                        DbgTrace (L"%s : %s", i.fKey.c_str (), i.fValue.As<String> ().c_str ());
                    }
                    String  dataValueString = vv.Lookup (L"data").Value ().As<String> ();
                    {
                        size_t i = dataValueString.Find (',');
                        if (i != -1) {
                            dataValueString = dataValueString.SubString (i + 1);
                        }
                    }
                    BLOB    resultBLOB = Cryptography::Encoding::Algorithm::DecodeBase64 (dataValueString.AsUTF8 ());
                    VerifyTestResult (resultBLOB == roundTripTestData);
                }
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                {
                    T1_httpbin_SimpleGET_ (factory ());
                    T2_httpbin_SimplePOST_ (factory ());
                }
                {
                    // Connection re-use
                    Connection conn = factory ();
                    T1_httpbin_SimpleGET_ (conn);
                    T2_httpbin_SimplePOST_ (conn);
                    T3_httpbin_SimplePUT_ (conn);
                }
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_2_SimpleFetch_httpbin_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test3_TextStreamResponse_ {
        namespace Private_ {
            void    Test_1_SimpleFetch_Google_C_ (Connection c)
            {
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                for (auto i : r.GetHeaders ()) {
                    DbgTrace (L"%s=%s", i.fKey.c_str (), i.fValue.c_str ());
                }
                InternetMediaType contentType = r.GetContentType ();
                String responseText = r.GetDataTextInputStream ().ReadAll ();
                DbgTrace (L"responseText = %s", responseText.c_str ());
                VerifyTestResult (responseText.Contains (L"google"));
            }
            void    DoRegressionTests_ForConnectionFactory_ (Connection (*factory) ())
            {
                Test_1_SimpleFetch_Google_C_ (factory ());
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test3_TextStreamResponse_");
            using namespace Private_;
            try {
                DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return CreateConnection (); });
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }

#if     qHasFeature_LibCurl
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_LibCurl (); });
#endif
#if     qHasFeature_WinHTTP
            DoRegressionTests_ForConnectionFactory_ ([]() -> Connection { return Connection_WinHTTP (); });
#endif
        }
    }
}

namespace {
    namespace Test_4_RefDocsTests_ {
        namespace Private_ {
            void    T1_get_ ()
            {
                Connection  c   =   IO::Network::Transfer::CreateConnection ();
                c.SetURL (URL::Parse (L"http://www.google.com"));
                Response    r   =   c.GET ();
                VerifyTestResult (r.GetSucceeded ());
                VerifyTestResult (r.GetData ().size () > 1);
            }

        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_4_RefDocsTests_");
            try {
                Private_::T1_get_ ();
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
        }
    }
}

namespace {
    namespace Test_5_SSLCertCheckTests_ {
        namespace Private_ {
            void    T1_get_ (Connection::Options o)
            {
                Connection  c   =   IO::Network::Transfer::CreateConnection (o);
                try {
                    c.SetURL (URL::Parse (L"https://testssl-valid.disig.sk/index.en.html"));
                    Response    r   =   c.GET ();
                    VerifyTestResult (r.GetSucceeded ());
                    VerifyTestResult (r.GetData ().size () > 1);
                }
#if     qHasFeature_LibCurl
                catch (const LibCurlException& lce) {
#if     !qHasFeature_OpenSSL
                    if (lce.GetCode () == 1/*CURLE_UNSUPPORTED_PROTOCOL*/) {
                        DbgTrace ("Warning - ignored exception doing LibCurl/ssl - for now probably just no SSL support with libcurl");
                        return;
                    }
#endif
                    throw;
                }
#else
                catch (...) {
                    throw;
                }
#endif
            }
        }
        void    DoTests_ ()
        {
            Debug::TraceContextBumper ctx ("{}::Test_5_SSLCertCheckTests_");
            Connection::Options o;
            try {
                o.fFailConnectionIfSSLCertificateInvalid = true;
                Private_::T1_get_ (o);
#if     qHasFeature_LibCurl && !qHasFeature_OpenSSL
                // ingore this case, since we allow the failed connect above...
#else
                VerifyTestResult (false);
#endif
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
            catch (...) {
                // Good - this should fail
            }
            try {
                o.fFailConnectionIfSSLCertificateInvalid = false;
                Private_::T1_get_ (o);
            }
            catch (const Execution::RequiredComponentMissingException&) {
#if     !qHasFeature_LibCurl && !qHasFeature_WinHTTP
                // OK to ignore. We don't wnat to call this failing a test, because there is nothing to fix.
                // This is more like the absence of a feature beacuse of the missing component.
#else
                Execution::ReThrow ();
#endif
            }
            catch (...) {
                VerifyTestResult (false);
            }
        }
    }
}

namespace   {
    void    DoRegressionTests_ ()
    {
        Test_1_SimpleConnnectionTests_::DoTests_ ();
        Test_2_SimpleFetch_httpbin_::DoTests_ ();
        Test3_TextStreamResponse_::DoTests_ ();
        Test_4_RefDocsTests_::DoTests_ ();
        Test_5_SSLCertCheckTests_::DoTests_ ();
    }
}

int main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "TrackingWorker.hpp"

#include <boost/chrono/duration.hpp>
#include <ros/console.h>
#include "../matlab/profiling.hpp"

TrackingWorker::TrackingWorker(IPositionReceiver *receiver)
{
	assert(receiver != 0);

	this->receiver = receiver;
	stop = false;

	thread = new boost::thread(boost::bind(&TrackingWorker::run, this));
}

TrackingWorker::~TrackingWorker()
{
	stop = true;
	thread->join();
}

void TrackingWorker::run()
{
	ROS_INFO("Started tracking thread");

	bool receivedFirstPosition = false;

	while (!stop) {
		CameraData data = dequeue();

		if (data.valid) {
			// ROS_DEBUG("Got valid data");
			receivedFirstPosition = true;

			long int startTime = getNanoTime();
			Vector position = tracker.updatePosition(data.cameraVector, data.camNo, data.quadcopterId);
			double duration = getNanoTime() - startTime;
			duration /= 1e6;

			std::vector<Vector> positions;
			std::vector<int> ids;
			std::vector<int> updates;
			positions.push_back(position);
			ids.push_back(data.quadcopterId);
			updates.push_back(1);

			if (position.isValid()) {
				receiver->updatePositions(positions, ids, updates);
			} else {
				// ROS_DEBUG("Not enough information to get position of quadcopter %d", data.quadcopterId);
			}

			ROS_DEBUG("Updating position of quadcopter %d took %.3f ms", data.quadcopterId, duration);
		} else if (receivedFirstPosition) {
			ROS_WARN("Position update buffer is empty!");
		}
	}

	ROS_INFO("Stopped tracking thread");
}

void TrackingWorker::updatePosition(Vector cameraVector, int camNo, int quadcopterId)
{
	CameraData data;
	data.cameraVector = cameraVector;
	data.camNo = camNo;
	data.quadcopterId = quadcopterId;
	data.valid = true;

	updatePosition(data);
}

void TrackingWorker::updatePosition(CameraData data)
{
	// ROS_DEBUG("updatePosition: called");

	enqueue(data);

	// ROS_DEBUG("updatePosition: Inserted CameraData for camera %d and quadcopter %d", data.camNo, data.quadcopterId);
}

void TrackingWorker::enqueue(CameraData data)
{
	// ROS_DEBUG("enqueue: Inserting CameraData");

	{
		boost::mutex::scoped_lock lock(positionsMutex);
		// ROS_DEBUG("enqueue: Got positions lock");
		positions.push(data);

		if (positions.size() > 25) {
			ROS_WARN("Position update buffer is running full (%ld entries). Seems like the position updating can't keep up!", positions.size());
		}
	}

	// ROS_DEBUG("enqueue: Released positions lock");
	// ROS_DEBUG("enqueue: Notifying about new CameraData");

	positionsEmpty.notify_one();

	// ROS_DEBUG("enqueue: Finished insertion process");
}

CameraData TrackingWorker::dequeue()
{
	// ROS_DEBUG("dequeue: Getting positions lock");

	{
		boost::mutex::scoped_lock lock(positionsMutex);

		// ROS_DEBUG("dequeue: Got positions lock");

		if (!dataAvailable()) {
			positionsEmpty.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(100));
		}

		if (dataAvailable()) {
			CameraData data = positions.back();
			positions.pop();

			// ROS_DEBUG("dequeue: Released positions lock");
			return data;
		} else {
			CameraData data;
			data.valid = false;

			// ROS_DEBUG("dequeue: Released positions lock");
			return data;
		}
	}
}

bool TrackingWorker::dataAvailable()
{
	return positions.size() > 0;
}

bool TrackingWorker::calibrate(ChessboardData *chessboard, int camNo)
{
	return tracker.calibrate(chessboard, camNo);
}<commit_msg>Fixed taking the correct datum out of the queue<commit_after>#include "TrackingWorker.hpp"

#include <boost/chrono/duration.hpp>
#include <ros/console.h>
#include "../matlab/profiling.hpp"

TrackingWorker::TrackingWorker(IPositionReceiver *receiver)
{
	assert(receiver != 0);

	this->receiver = receiver;
	stop = false;

	thread = new boost::thread(boost::bind(&TrackingWorker::run, this));
}

TrackingWorker::~TrackingWorker()
{
	stop = true;
	thread->join();
}

void TrackingWorker::run()
{
	ROS_INFO("Started tracking thread");

	bool receivedFirstPosition = false;

	while (!stop) {
		CameraData data = dequeue();

		if (data.valid) {
			// ROS_DEBUG("Got valid data");
			receivedFirstPosition = true;

			long int startTime = getNanoTime();
			Vector position = tracker.updatePosition(data.cameraVector, data.camNo, data.quadcopterId);
			double duration = getNanoTime() - startTime;
			duration /= 1e6;

			std::vector<Vector> positions;
			std::vector<int> ids;
			std::vector<int> updates;
			positions.push_back(position);
			ids.push_back(data.quadcopterId);
			updates.push_back(1);

			if (position.isValid()) {
				receiver->updatePositions(positions, ids, updates);
			} else {
				// ROS_DEBUG("Not enough information to get position of quadcopter %d", data.quadcopterId);
			}

			ROS_DEBUG("Updating position of quadcopter %d took %.3f ms", data.quadcopterId, duration);
		} else if (receivedFirstPosition) {
			ROS_WARN("Position update buffer is empty!");
		}
	}

	ROS_INFO("Stopped tracking thread");
}

void TrackingWorker::updatePosition(Vector cameraVector, int camNo, int quadcopterId)
{
	CameraData data;
	data.cameraVector = cameraVector;
	data.camNo = camNo;
	data.quadcopterId = quadcopterId;
	data.valid = true;

	updatePosition(data);
}

void TrackingWorker::updatePosition(CameraData data)
{
	// ROS_DEBUG("updatePosition: called");

	enqueue(data);

	// ROS_DEBUG("updatePosition: Inserted CameraData for camera %d and quadcopter %d", data.camNo, data.quadcopterId);
}

void TrackingWorker::enqueue(CameraData data)
{
	// ROS_DEBUG("enqueue: Inserting CameraData");

	{
		boost::mutex::scoped_lock lock(positionsMutex);
		// ROS_DEBUG("enqueue: Got positions lock");
		positions.push(data);

		if (positions.size() > 25) {
			ROS_WARN("Position update buffer is running full (%ld entries). Seems like the position updating can't keep up! Dropping 15 entries.", positions.size());

			for (int i = 0; i < 15; i++) {
				positions.pop();
			}
		}
	}

	// ROS_DEBUG("enqueue: Released positions lock");
	// ROS_DEBUG("enqueue: Notifying about new CameraData");

	positionsEmpty.notify_one();

	// ROS_DEBUG("enqueue: Finished insertion process");
}

CameraData TrackingWorker::dequeue()
{
	// ROS_DEBUG("dequeue: Getting positions lock");

	{
		boost::mutex::scoped_lock lock(positionsMutex);

		// ROS_DEBUG("dequeue: Got positions lock");

		if (!dataAvailable()) {
			positionsEmpty.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(100));
		}

		if (dataAvailable()) {
			CameraData data = positions.front();
			positions.pop();

			// ROS_DEBUG("dequeue: Released positions lock");
			return data;
		} else {
			CameraData data;
			data.valid = false;

			// ROS_DEBUG("dequeue: Released positions lock");
			return data;
		}
	}
}

bool TrackingWorker::dataAvailable()
{
	return positions.size() > 0;
}

bool TrackingWorker::calibrate(ChessboardData *chessboard, int camNo)
{
	return tracker.calibrate(chessboard, camNo);
}<|endoftext|>


<commit_before>/*
 * texture.cpp
 *
 *  Created on: 18 kwi 2016
 *      Author: Michal
 */

#include "texture.h"
#include "window.h"
#include <iostream>

Texture::Texture(int x, int y, int width, int height, char* path) {
	this->x = x;
	this->y = y;
	this->width = width;
	this->height = height;
	string(path).copy(this->path,256,0);
}

Texture::~Texture() {
	// TODO Auto-generated destructor stub
}

void Texture::loadTexture(){
	this->id = Window::loadGLTexture(path);
}
<commit_msg>Small bugfix.<commit_after>/*
 * texture.cpp
 *
 *  Created on: 18 kwi 2016
 *      Author: Michal
 */

#include "texture.h"
#include "window.h"
#include <iostream>

Texture::Texture(int x, int y, int width, int height, char* path) {
	this->x = x;
	this->y = y;
	this->width = width;
	this->height = height;
	string(path).copy(this->path,256,0);
	this->path[strlen(path)]='\0';
}

Texture::~Texture() {
	// TODO Auto-generated destructor stub
}

void Texture::loadTexture(){
	this->id = Window::loadGLTexture(path);
}
<|endoftext|>


<commit_before>
#include "NNApplication.h"
#include "NNInputSystem.h"
#include "NNAudioSystem.h"
#include "NNResourceManager.h"

NNApplication* NNApplication::m_pInstance = nullptr;

NNApplication::NNApplication()
	: m_Hwnd(nullptr), m_hInstance(nullptr),
	  m_ScreenHeight(0), m_ScreenWidth(0),
	  m_Fps(0.f), m_ElapsedTime(0.f), m_DeltaTime(0.f),
	  m_PrevTime(0), m_NowTime(0),
	  m_Renderer(nullptr), m_pSceneDirector(nullptr),
	  m_RendererStatus(UNKNOWN)
{

}
NNApplication::~NNApplication()
{

}

NNApplication* NNApplication::GetInstance()
{
	if ( m_pInstance == nullptr )
	{
		m_pInstance = new NNApplication();
	}

	return m_pInstance;
}
void NNApplication::ReleaseInstance()
{
	if ( m_pInstance != nullptr )
	{
		delete m_pInstance;
		m_pInstance = nullptr;
	}
}

bool NNApplication::Init( wchar_t* const title, int width, int height, RendererStatus renderStatus )
{
	m_hInstance = GetModuleHandle(0);

	m_Title = title;
	m_ScreenWidth = width;
	m_ScreenHeight = height;
	m_RendererStatus = renderStatus;

	_CreateWindow( m_Title, m_ScreenWidth, m_ScreenHeight );
	_CreateRenderer( renderStatus );

	m_pSceneDirector = NNSceneDirector::GetInstance();

	m_Renderer->Init();
	m_pSceneDirector->Init();

	return true;
}

bool NNApplication::Release()
{
	SafeDelete( m_Renderer );
	m_pSceneDirector->Release();

	NNSceneDirector::ReleaseInstance();
	NNResourceManager::ReleaseInstance();
	NNInputSystem::ReleaseInstance();
	NNAudioSystem::ReleaseInstance();
	ReleaseInstance();

	return true;
}

bool NNApplication::Run()
{
	MSG msg;
	ZeroMemory( &msg, sizeof(msg) );

	while (true)
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
			{
				return true;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			m_NowTime = timeGetTime();
			if ( m_PrevTime == 0.f )
			{
				m_PrevTime = m_NowTime;
			}
			m_DeltaTime = static_cast<float>(m_NowTime - m_PrevTime) / 60.f;
			m_PrevTime = m_NowTime;
			m_Fps = 1.f / m_DeltaTime;

			m_ElapsedTime += m_DeltaTime;

			NNInputSystem::GetInstance()->UpdateKeyState();

			m_pSceneDirector->UpdateScene( m_DeltaTime );

			m_Renderer->Begin();
			m_Renderer->Clear();
			m_pSceneDirector->RenderScene();
			m_Renderer->End();

			if ( NNInputSystem::GetInstance()->GetKeyState( VK_ESCAPE ) == KEY_DOWN )
			{
				PostQuitMessage(0);
			}
		}
	}

	return true;
}

bool NNApplication::_CreateWindow( wchar_t* title, int width, int height )
{
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = NULL;
	wcex.cbWndExtra = NULL;
	wcex.hInstance = m_hInstance;
	wcex.hIcon = NULL;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"NNApplication";
	wcex.hIconSm = NULL;
	wcex.hIcon = NULL;

	RegisterClassEx( &wcex );

	DWORD style = WS_OVERLAPPEDWINDOW;

	m_Hwnd = CreateWindow( L"NNApplication", title, style, CW_USEDEFAULT, CW_USEDEFAULT,
		width, height, NULL, NULL, m_hInstance, NULL);

	ShowWindow( m_Hwnd, SW_SHOWNORMAL );

	return true;
}
bool NNApplication::_CreateRenderer( RendererStatus renderStatus )
{
	switch( renderStatus )
	{
	case D2D:
		m_Renderer = new NND2DRenderer();
		break;
	default:
		return false;
	}

	return true;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	switch( message )
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint( hWnd, &ps );
		EndPaint( hWnd, &ps );
	}

	return(DefWindowProc(hWnd,message,wParam,lParam));
}

<commit_msg>commit test<commit_after>
#include "NNApplication.h"
#include "NNInputSystem.h"
#include "NNAudioSystem.h"
#include "NNResourceManager.h"

NNApplication* NNApplication::m_pInstance = nullptr;

NNApplication::NNApplication()
	: m_Hwnd(nullptr), m_hInstance(nullptr),
	  m_ScreenHeight(0), m_ScreenWidth(0),
	  m_Fps(0.f), m_ElapsedTime(0.f), m_DeltaTime(0.f),
	  m_PrevTime(0), m_NowTime(0),
	  m_Renderer(nullptr), m_pSceneDirector(nullptr),
	  m_RendererStatus(UNKNOWN)
{

}
NNApplication::~NNApplication()
{

}

NNApplication* NNApplication::GetInstance()
{
	if ( m_pInstance == nullptr )
	{
		m_pInstance = new NNApplication();
	}

	return m_pInstance;
}
void NNApplication::ReleaseInstance()
{
	if ( m_pInstance != nullptr )
	{
		delete m_pInstance;
		m_pInstance = nullptr;
	}
}

bool NNApplication::Init( wchar_t* const title, int width, int height, RendererStatus renderStatus )
{
	m_hInstance = GetModuleHandle(0);

	m_Title = title;
	m_ScreenWidth = width;
	m_ScreenHeight = height;
	m_RendererStatus = renderStatus;

	_CreateWindow( m_Title, m_ScreenWidth, m_ScreenHeight );
	_CreateRenderer( renderStatus );

	m_pSceneDirector = NNSceneDirector::GetInstance();

	m_Renderer->Init();
	m_pSceneDirector->Init();

	return true;
}

bool NNApplication::Release()
{
	SafeDelete( m_Renderer );
	m_pSceneDirector->Release();

	NNSceneDirector::ReleaseInstance();
	NNResourceManager::ReleaseInstance();
	NNInputSystem::ReleaseInstance();
	NNAudioSystem::ReleaseInstance();
	ReleaseInstance();

	return true;
}

bool NNApplication::Run()
{
	MSG msg;
	ZeroMemory( &msg, sizeof(msg) );

	while (true)
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
			{
				return true;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			m_NowTime = timeGetTime();
			if ( m_PrevTime == 0.f )
			{
				m_PrevTime = m_NowTime;
			}
			m_DeltaTime = static_cast<float>(m_NowTime - m_PrevTime) / 60.f;
			m_PrevTime = m_NowTime;
			m_Fps = 1.f / m_DeltaTime;

			m_ElapsedTime += m_DeltaTime;

			NNInputSystem::GetInstance()->UpdateKeyState();

			m_pSceneDirector->UpdateScene( m_DeltaTime );

			m_Renderer->Begin();
			m_Renderer->Clear();
			m_pSceneDirector->RenderScene();
			m_Renderer->End();

			if ( NNInputSystem::GetInstance()->GetKeyState( VK_ESCAPE ) == KEY_DOWN )
			{
				PostQuitMessage(0);
			}
		}
	}

	return true;
}

bool NNApplication::_CreateWindow( wchar_t* title, int width, int height )
{
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = NULL;
	wcex.cbWndExtra = NULL;
	wcex.hInstance = m_hInstance;
	wcex.hIcon = NULL;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"NNApplication";
	wcex.hIconSm = NULL;
	wcex.hIcon = NULL;

	RegisterClassEx( &wcex );

	DWORD style = WS_OVERLAPPEDWINDOW;

	m_Hwnd = CreateWindow( L"NNApplication", title, style, CW_USEDEFAULT, CW_USEDEFAULT,
		width, height, NULL, NULL, m_hInstance, NULL);

	ShowWindow( m_Hwnd, SW_SHOWNORMAL );

	return true;
}
bool NNApplication::_CreateRenderer( RendererStatus renderStatus )
{
	switch( renderStatus )
	{
	case D2D:
		m_Renderer = new NND2DRenderer();
		break;
	default:
		return false;
	}

	return true;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	switch( message )
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint( hWnd, &ps );
		EndPaint( hWnd, &ps );
	}

	return(DefWindowProc(hWnd,message,wParam,lParam));
}
//commit test
<|endoftext|>


<commit_before>#include "visitor_impl.hpp"

#include "function.hpp"

namespace ex {

void printer_visitor::visit(ex::expr & e) {
    return_("general_expression");
}

void printer_visitor::visit(ex::function<ex::base::variable> & c) {
    return_(c.value);
}

void printer_visitor::visit(ex::function<ex::base::constant> & c) {
    return_(std::to_string(c.value));
}

void printer_visitor::visit(ex::function<ex::base::sin> & c) {
    return_( "sin(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::cos> & c) {
    return_( "cos(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::tan> & c) {
    return_( "tan(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::log> & c) {
    return_( "log(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::add> & c) {
    return_( "(" + recurse(c, 0) + "+" + recurse(c, 1) + "_" );
}

void printer_visitor::visit(ex::function<ex::base::sub> & c) {
    return_( "(" + recurse(c, 0) + "-" + recurse(c, 1) + "_" );
}

void printer_visitor::visit(ex::function<ex::base::mul> & c) {
    return_( "(" + recurse(c, 0) + "*" + recurse(c, 1) + "_" );
}

void printer_visitor::visit(ex::function<ex::base::div> & c) {
    return_( "(" + recurse(c, 0) + "/" + recurse(c, 1) + "_" );
}

void printer_visitor::visit(ex::function<ex::base::pow> & c) {
    return_( "(" + recurse(c, 0) + "/" + recurse(c, 1) + "_" );
}

eval_visitor::eval_visitor(const globals::valuation_type & v_)
  : v(v_) { }

eval_visitor::eval_visitor(const eval_visitor & e)
  : v(e.v) { }

void eval_visitor::visit(expr & e) {
    return_( 0 );
}

void eval_visitor::visit(function<base::variable> & c) {
    return_( v(c.value) );
}

void eval_visitor::visit(function<base::constant> & c) {
    return_( c.value );
}

void eval_visitor::visit(function<base::sin> & c) {
    return_( std::sin(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::cos> & c) {
    return_( std::cos(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::tan> & c) {
    return_( std::tan(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::log> & c) {
    return_( std::log(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::add> & c) {
    return_( recurse(c, 0) + recurse(c, 1) );
}

void eval_visitor::visit(function<base::sub> & c) {
    return_( recurse(c, 0) - recurse(c, 1) );
}

void eval_visitor::visit(function<base::mul> & c) {
    return_( recurse(c, 0) * recurse(c, 1) );
}

void eval_visitor::visit(function<base::div> & c) {
    return_( recurse(c, 0) / recurse(c, 1) );
}

void eval_visitor::visit(function<base::pow> & c) {
    return_( std::pow(recurse(c, 0), recurse(c, 1)) );
}

void is_constant_visitor::visit(ex::expr & e) {
    for (std::size_t i = 0; i < e.arity(); ++i)
        e[i]->accept(*gen_);
}

void is_constant_visitor::visit(function<base::variable> &) {
    result = false;
}

}

<commit_msg>fixed bug when printing _ instead of )<commit_after>#include "visitor_impl.hpp"

#include "function.hpp"

namespace ex {

void printer_visitor::visit(ex::expr & e) {
    return_("general_expression");
}

void printer_visitor::visit(ex::function<ex::base::variable> & c) {
    return_(c.value);
}

void printer_visitor::visit(ex::function<ex::base::constant> & c) {
    return_(std::to_string(c.value));
}

void printer_visitor::visit(ex::function<ex::base::sin> & c) {
    return_( "sin(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::cos> & c) {
    return_( "cos(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::tan> & c) {
    return_( "tan(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::log> & c) {
    return_( "log(" + recurse(c, 0) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::add> & c) {
    return_( "(" + recurse(c, 0) + "+" + recurse(c, 1) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::sub> & c) {
    return_( "(" + recurse(c, 0) + "-" + recurse(c, 1) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::mul> & c) {
    return_( "(" + recurse(c, 0) + "*" + recurse(c, 1) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::div> & c) {
    return_( "(" + recurse(c, 0) + "/" + recurse(c, 1) + ")" );
}

void printer_visitor::visit(ex::function<ex::base::pow> & c) {
    return_( "(" + recurse(c, 0) + "/" + recurse(c, 1) + ")" );
}

eval_visitor::eval_visitor(const globals::valuation_type & v_)
  : v(v_) { }

eval_visitor::eval_visitor(const eval_visitor & e)
  : v(e.v) { }

void eval_visitor::visit(expr & e) {
    return_( 0 );
}

void eval_visitor::visit(function<base::variable> & c) {
    return_( v(c.value) );
}

void eval_visitor::visit(function<base::constant> & c) {
    return_( c.value );
}

void eval_visitor::visit(function<base::sin> & c) {
    return_( std::sin(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::cos> & c) {
    return_( std::cos(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::tan> & c) {
    return_( std::tan(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::log> & c) {
    return_( std::log(recurse(c, 0)) );
}

void eval_visitor::visit(function<base::add> & c) {
    return_( recurse(c, 0) + recurse(c, 1) );
}

void eval_visitor::visit(function<base::sub> & c) {
    return_( recurse(c, 0) - recurse(c, 1) );
}

void eval_visitor::visit(function<base::mul> & c) {
    return_( recurse(c, 0) * recurse(c, 1) );
}

void eval_visitor::visit(function<base::div> & c) {
    return_( recurse(c, 0) / recurse(c, 1) );
}

void eval_visitor::visit(function<base::pow> & c) {
    return_( std::pow(recurse(c, 0), recurse(c, 1)) );
}

void is_constant_visitor::visit(ex::expr & e) {
    for (std::size_t i = 0; i < e.arity(); ++i)
        e[i]->accept(*gen_);
}

void is_constant_visitor::visit(function<base::variable> &) {
    result = false;
}

}

<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2009 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/Plate/Amqp.h>

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

#include <stdint.h>
#include <amqp.h>
#include <amqp_framing.h>

#include <unistd.h>
#include <assert.h>

#include <vw/Core/Exception.h>
#include <vw/Core/Log.h>

#include <sstream>

#include <boost/shared_array.hpp>

using namespace vw;
using namespace vw::platefile;

// --------------------- Error Handling --------------------------

void die_on_error(int x, char const *context) {
  if (x < 0) {
    std::ostringstream msg;
    msg << "AMQP Error: " << context << " -- " << strerror(-x);
    vw::vw_throw(vw::LogicErr() << msg.str());
  }
}

void die_on_amqp_error(amqp_rpc_reply_t x, char const *context) {
  std::ostringstream msg;

  switch (x.reply_type) {
  case AMQP_RESPONSE_NORMAL:
    return;

  case AMQP_RESPONSE_NONE:
    vw_out(0) << "AMQP Error: " << context << " -- missing RPC reply type.";
    exit(1);

  case AMQP_RESPONSE_LIBRARY_EXCEPTION:
    vw_out(0) << "AMQP Error: " << context << " -- "
              << (x.library_errno ? strerror(x.library_errno) : "(end-of-stream)");
    exit(1);

  case AMQP_RESPONSE_SERVER_EXCEPTION:
    switch (x.reply.id) {
    case AMQP_CONNECTION_CLOSE_METHOD: {
      amqp_connection_close_t *m = (amqp_connection_close_t *) x.reply.decoded;
      vw_out(0) << "AMQP Error: " << context << " -- "
                << "server connection error " << m->reply_code << ", message: "
                << (char *) m->reply_text.bytes;
      exit(1);
    }
    case AMQP_CHANNEL_CLOSE_METHOD: {
      amqp_channel_close_t *m = (amqp_channel_close_t *) x.reply.decoded;
      vw_out(0)  << "AMQP Error: " << context << " -- "
                 << "server channel error " << m->reply_code << ", message: "
                 << (char *) m->reply_text.bytes;
      exit(1);
    }
    default:
      vw_out(0) << "AMQP Error: " << context << " -- "
                << "unknown server error, method id " << x.reply.id;
      exit(1);
    }
    break;
  }
  vw_out(0) << "AMQP Error: unknown response type.";
  exit(1);
}

// --------------------- AmqpConnection State Structure -------------------------

struct vw::platefile::AmqpConnectionState {
  int sockfd;
  amqp_connection_state_t conn;

  // -- Workaround --
  //
  // These are standins fro AMQP_EMPTY_BYTES and AMQP_EMPTY_TABLE from
  // amqp.h. Those don't seem to work properly in C++, so we sub in
  // these, which do the same thing, instead.
  amqp_table_t empty_table;
  amqp_bytes_t empty_bytes;

  AmqpConnectionState() {
    empty_table.num_entries=0;
    empty_table.entries = NULL;

    empty_bytes.len = 0;
    empty_bytes.bytes = NULL;
  }
};

// --------------------- AmqpConnection Implementation --------------------------

// ------------------------------------------------------
// Constructor / destructor
// ------------------------------------------------------

AmqpConnection::AmqpConnection(std::string const& hostname, int port) {

  m_state = boost::shared_ptr<AmqpConnectionState>(new AmqpConnectionState());

  // Open a socket and establish an amqp connection
  die_on_error(m_state->sockfd = amqp_open_socket(hostname.c_str(), port), "Opening socket");
  m_state->conn = amqp_new_connection();
  amqp_set_sockfd(m_state->conn, m_state->sockfd);

  // Login to the Amqp Server
  die_on_amqp_error(amqp_login(m_state->conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
                               "guest", "guest"), "Logging in");
  amqp_channel_open(m_state->conn, 1);
  die_on_amqp_error(amqp_rpc_reply, "Opening channel");
}

AmqpConnection::~AmqpConnection() {
  vw_out(InfoMessage, "platefile::amqp") << "Closing AMQP connection.\n";
  die_on_amqp_error(amqp_channel_close(m_state->conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
  die_on_amqp_error(amqp_connection_close(m_state->conn, AMQP_REPLY_SUCCESS), "Closing connection");
  amqp_destroy_connection(m_state->conn);
  die_on_error(close(m_state->sockfd), "Closing socket");
}

// ------------------------------------------------------
// Methods for modifying exchanges, queues, and bindings.
// ------------------------------------------------------

void AmqpConnection::queue_declare(std::string const& queue_name, bool durable,
                                   bool exclusive, bool auto_delete) {
  amqp_queue_declare_ok_t *r = amqp_queue_declare(m_state->conn, 1,
                                                  amqp_cstring_bytes(queue_name.c_str()),
                                                  0, 0, 0, 1,
                                                  m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Declaring queue");
}

void AmqpConnection::exchange_declare(std::string const& exchange_name,
                                      std::string const& exchange_type,
                                      bool durable, bool auto_delete) {
  amqp_exchange_declare(m_state->conn, 1,
                        amqp_cstring_bytes(exchange_name.c_str()),
                        amqp_cstring_bytes(exchange_type.c_str()),
			0, durable, auto_delete, m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Declaring exchange");
}

void AmqpConnection::queue_bind(std::string const& queue, std::string const& exchange,
                                std::string const& routing_key) {
  amqp_queue_bind(m_state->conn, 1,
                  amqp_cstring_bytes(queue.c_str()),
                  amqp_cstring_bytes(exchange.c_str()),
                  amqp_cstring_bytes(routing_key.c_str()),
		  m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Binding queue");
}

void AmqpConnection::queue_unbind(std::string const& queue, std::string const& exchange,
                                  std::string const& routing_key) {
  amqp_queue_unbind(m_state->conn, 1,
                    amqp_cstring_bytes(queue.c_str()),
                    amqp_cstring_bytes(exchange.c_str()),
                    amqp_cstring_bytes(routing_key.c_str()),
                    m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Unbinding queue");
}

// ------------------------------------------------------
// Methods for sending and receiving data
// ------------------------------------------------------

void AmqpConnection::basic_publish(boost::shared_array<uint8> const& message,
                                   int32 size,
                                   std::string const& exchange,
                                   std::string const& routing_key) const {

  // The delivery mode flag (below) can be used to select for
  // persistent delivery mode, which virtually gurantees that the
  // message will get through, even if the AMQP server crashes.
  // However, this comes at a performance penalty, so it is disabled
  // here for now.
  //
  // amqp_basic_properties_t props;
  // props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
  // props.content_type = amqp_cstring_bytes("text/plain");
  // props.delivery_mode = 2; // persistent delivery mode
  amqp_bytes_t raw_data;
  raw_data.len = size;
  raw_data.bytes = (void*)(message.get());

  die_on_error(amqp_basic_publish(m_state->conn,
                                  1,
                                  amqp_cstring_bytes(exchange.c_str()),
                                  amqp_cstring_bytes(routing_key.c_str()),
                                  0,
                                  0,
                                  NULL,
                                  raw_data ),
               "Publishing");
}

boost::shared_array<uint8> AmqpConnection::basic_consume(std::string const& queue,
                                                         std::string &routing_key,
                                                         bool no_ack) const {

  amqp_basic_consume(m_state->conn,
                     1,  // channel
                     amqp_cstring_bytes(queue.c_str()),
                     m_state->empty_bytes,
                     0,  // no_local
                     no_ack,
                     0); // exclusive
  die_on_amqp_error(amqp_rpc_reply, "Consuming");

  {
    amqp_frame_t frame;
    int result;

    amqp_basic_deliver_t *d;
    amqp_basic_properties_t *p;
    size_t body_target;
    size_t body_received;

    boost::shared_array<uint8> payload;

    amqp_maybe_release_buffers(m_state->conn);
    result = amqp_simple_wait_frame(m_state->conn, &frame);
    //    printf("Result %d\n", result);
    if (result <= 0)
      vw_throw(IOErr() << "AMQP error: unknown result code.");

    //    printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel);
    if (frame.frame_type != AMQP_FRAME_METHOD)
      vw_throw(IOErr() << "AMQP error: unknown frame type.");

    //    printf("Method %s\n", amqp_method_name(frame.payload.method.id));
    if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
      vw_throw(IOErr() << "AMQP error: unknown payload method.");

    d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
    //    printf("Delivery %u, exchange %.*s routingkey %.*s\n",
           // (unsigned) d->delivery_tag,
           // (int) d->exchange.len, (char *) d->exchange.bytes,
           // (int) d->routing_key.len, (char *) d->routing_key.bytes);

    // copy the routing key to pass out to the caller
    boost::shared_array<char> rk_bytes(new char[d->routing_key.len + 1]);
    strncpy(rk_bytes.get(), (char*)(d->routing_key.bytes), d->routing_key.len);
    rk_bytes[d->routing_key.len] = '\0';
    routing_key = rk_bytes.get();

    result = amqp_simple_wait_frame(m_state->conn, &frame);
    if (result <= 0)
      vw_throw(IOErr() << "AMQP error: unknown result waiting for frame.");

    if (frame.frame_type != AMQP_FRAME_HEADER) {
      vw_out(ErrorMessage, "platefile::amqp") << "Expected AMQP header!";
      abort();
    }
    p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
    if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
      // printf("Content-type: %.*s\n",
      //        (int) p->content_type.len, (char *) p->content_type.bytes);
    }
    // printf("----\n");

    body_target = frame.payload.properties.body_size;
    body_received = 0;
    payload = boost::shared_array<uint8>( new uint8[body_target] );

    while (body_received < body_target) {
      result = amqp_simple_wait_frame(m_state->conn, &frame);
      if (result <= 0)
        vw_throw(IOErr() << "AMQP error: unknown result waiting for frame.");

      if (frame.frame_type != AMQP_FRAME_BODY) {
        vw_out(ErrorMessage, "platefile::amqp") << "Expected AMQP message body!";
        abort();
      }

      // Copy the bytes out of the payload...
      memcpy(((char*)(payload.get()) + body_received),
             (const char*)(frame.payload.body_fragment.bytes),
             frame.payload.body_fragment.len);

      // ... and update the number of bytes we have received
      body_received += frame.payload.body_fragment.len;
      VW_ASSERT(body_received <= body_target, IOErr() << "AMQP packet body size exceeded header\'s body target.");
    }

    // Check to make sure that we have received the right number of bytes.
    if (body_received != body_target) {
      vw_throw(IOErr() << "AMQP packet body size does not match header\'s body target.");
    }

    if (!no_ack)
      amqp_basic_ack(m_state->conn, 1, d->delivery_tag, 0);

    vw_out(VerboseDebugMessage, "platefile::amqp") << "Message payload: \""
                                                   << payload.get() << "\"\n";

    return payload;
  }

}
<commit_msg>fix breakage in api update to 0.9.1<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2009 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/Plate/Amqp.h>

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

#include <stdint.h>
#include <amqp.h>
#include <amqp_framing.h>

#include <unistd.h>
#include <assert.h>

#include <vw/Core/Exception.h>
#include <vw/Core/Log.h>

#include <sstream>

#include <boost/shared_array.hpp>

using namespace vw;
using namespace vw::platefile;

// --------------------- Error Handling --------------------------

void die_on_error(int x, char const *context) {
  if (x < 0) {
    std::ostringstream msg;
    msg << "AMQP Error: " << context << " -- " << strerror(-x);
    vw::vw_throw(vw::LogicErr() << msg.str());
  }
}

void die_on_amqp_error(amqp_rpc_reply_t x, char const *context) {
  std::ostringstream msg;

  switch (x.reply_type) {
  case AMQP_RESPONSE_NORMAL:
    return;

  case AMQP_RESPONSE_NONE:
    vw_out(0) << "AMQP Error: " << context << " -- missing RPC reply type.";
    exit(1);

  case AMQP_RESPONSE_LIBRARY_EXCEPTION:
    vw_out(0) << "AMQP Error: " << context << " -- "
              << (x.library_errno ? strerror(x.library_errno) : "(end-of-stream)");
    exit(1);

  case AMQP_RESPONSE_SERVER_EXCEPTION:
    switch (x.reply.id) {
    case AMQP_CONNECTION_CLOSE_METHOD: {
      amqp_connection_close_t *m = (amqp_connection_close_t *) x.reply.decoded;
      vw_out(0) << "AMQP Error: " << context << " -- "
                << "server connection error " << m->reply_code << ", message: "
                << (char *) m->reply_text.bytes;
      exit(1);
    }
    case AMQP_CHANNEL_CLOSE_METHOD: {
      amqp_channel_close_t *m = (amqp_channel_close_t *) x.reply.decoded;
      vw_out(0)  << "AMQP Error: " << context << " -- "
                 << "server channel error " << m->reply_code << ", message: "
                 << (char *) m->reply_text.bytes;
      exit(1);
    }
    default:
      vw_out(0) << "AMQP Error: " << context << " -- "
                << "unknown server error, method id " << x.reply.id;
      exit(1);
    }
    break;
  }
  vw_out(0) << "AMQP Error: unknown response type.";
  exit(1);
}

// --------------------- AmqpConnection State Structure -------------------------

struct vw::platefile::AmqpConnectionState {
  int sockfd;
  amqp_connection_state_t conn;

  // -- Workaround --
  //
  // These are standins fro AMQP_EMPTY_BYTES and AMQP_EMPTY_TABLE from
  // amqp.h. Those don't seem to work properly in C++, so we sub in
  // these, which do the same thing, instead.
  amqp_table_t empty_table;
  amqp_bytes_t empty_bytes;

  AmqpConnectionState() {
    empty_table.num_entries=0;
    empty_table.entries = NULL;

    empty_bytes.len = 0;
    empty_bytes.bytes = NULL;
  }
};

// --------------------- AmqpConnection Implementation --------------------------

// ------------------------------------------------------
// Constructor / destructor
// ------------------------------------------------------

AmqpConnection::AmqpConnection(std::string const& hostname, int port) {

  m_state = boost::shared_ptr<AmqpConnectionState>(new AmqpConnectionState());

  // Open a socket and establish an amqp connection
  die_on_error(m_state->sockfd = amqp_open_socket(hostname.c_str(), port), "Opening socket");
  m_state->conn = amqp_new_connection();
  amqp_set_sockfd(m_state->conn, m_state->sockfd);

  // Login to the Amqp Server
  die_on_amqp_error(amqp_login(m_state->conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
                               "guest", "guest"), "Logging in");
  amqp_channel_open(m_state->conn, 1);
  die_on_amqp_error(amqp_rpc_reply, "Opening channel");
}

AmqpConnection::~AmqpConnection() {
  vw_out(InfoMessage, "platefile::amqp") << "Closing AMQP connection.\n";
  die_on_amqp_error(amqp_channel_close(m_state->conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
  die_on_amqp_error(amqp_connection_close(m_state->conn, AMQP_REPLY_SUCCESS), "Closing connection");
  amqp_destroy_connection(m_state->conn);
  die_on_error(close(m_state->sockfd), "Closing socket");
}

// ------------------------------------------------------
// Methods for modifying exchanges, queues, and bindings.
// ------------------------------------------------------

void AmqpConnection::queue_declare(std::string const& queue_name, bool durable,
                                   bool exclusive, bool auto_delete) {
  amqp_queue_declare_ok_t *r = amqp_queue_declare(m_state->conn, 1,
                                                  amqp_cstring_bytes(queue_name.c_str()),
                                                  0, 0, 0, 1,
                                                  m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Declaring queue");
}

void AmqpConnection::exchange_declare(std::string const& exchange_name,
                                      std::string const& exchange_type,
                                      bool durable, bool auto_delete) {
  amqp_exchange_declare(m_state->conn, 1,
                        amqp_cstring_bytes(exchange_name.c_str()),
                        amqp_cstring_bytes(exchange_type.c_str()),
			0, durable, auto_delete, m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Declaring exchange");
}

void AmqpConnection::queue_bind(std::string const& queue, std::string const& exchange,
                                std::string const& routing_key) {
  amqp_queue_bind(m_state->conn, 1,
                  amqp_cstring_bytes(queue.c_str()),
                  amqp_cstring_bytes(exchange.c_str()),
                  amqp_cstring_bytes(routing_key.c_str()),
		  m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Binding queue");
}

void AmqpConnection::queue_unbind(std::string const& queue, std::string const& exchange,
                                  std::string const& routing_key) {
  amqp_queue_unbind(m_state->conn, 1,
                    amqp_cstring_bytes(queue.c_str()),
                    amqp_cstring_bytes(exchange.c_str()),
                    amqp_cstring_bytes(routing_key.c_str()),
                    m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Unbinding queue");
}

// ------------------------------------------------------
// Methods for sending and receiving data
// ------------------------------------------------------

void AmqpConnection::basic_publish(boost::shared_array<uint8> const& message,
                                   int32 size,
                                   std::string const& exchange,
                                   std::string const& routing_key) const {

  // The delivery mode flag (below) can be used to select for
  // persistent delivery mode, which virtually gurantees that the
  // message will get through, even if the AMQP server crashes.
  // However, this comes at a performance penalty, so it is disabled
  // here for now.
  //
  // amqp_basic_properties_t props;
  // props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
  // props.content_type = amqp_cstring_bytes("text/plain");
  // props.delivery_mode = 2; // persistent delivery mode
  amqp_bytes_t raw_data;
  raw_data.len = size;
  raw_data.bytes = (void*)(message.get());

  die_on_error(amqp_basic_publish(m_state->conn,
                                  1,
                                  amqp_cstring_bytes(exchange.c_str()),
                                  amqp_cstring_bytes(routing_key.c_str()),
                                  0,
                                  0,
                                  NULL,
                                  raw_data ),
               "Publishing");
}

boost::shared_array<uint8> AmqpConnection::basic_consume(std::string const& queue,
                                                         std::string &routing_key,
                                                         bool no_ack) const {

  amqp_basic_consume(m_state->conn,
                     1,  // channel
                     amqp_cstring_bytes(queue.c_str()),
                     m_state->empty_bytes,
                     0,  // no_local
                     no_ack,
                     0,  // exclusive
                     m_state->empty_table);
  die_on_amqp_error(amqp_rpc_reply, "Consuming");

  {
    amqp_frame_t frame;
    int result;

    amqp_basic_deliver_t *d;
    amqp_basic_properties_t *p;
    size_t body_target;
    size_t body_received;

    boost::shared_array<uint8> payload;

    amqp_maybe_release_buffers(m_state->conn);
    result = amqp_simple_wait_frame(m_state->conn, &frame);
    //    printf("Result %d\n", result);
    if (result <= 0)
      vw_throw(IOErr() << "AMQP error: unknown result code.");

    //    printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel);
    if (frame.frame_type != AMQP_FRAME_METHOD)
      vw_throw(IOErr() << "AMQP error: unknown frame type.");

    //    printf("Method %s\n", amqp_method_name(frame.payload.method.id));
    if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
      vw_throw(IOErr() << "AMQP error: unknown payload method.");

    d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
    //    printf("Delivery %u, exchange %.*s routingkey %.*s\n",
           // (unsigned) d->delivery_tag,
           // (int) d->exchange.len, (char *) d->exchange.bytes,
           // (int) d->routing_key.len, (char *) d->routing_key.bytes);

    // copy the routing key to pass out to the caller
    boost::shared_array<char> rk_bytes(new char[d->routing_key.len + 1]);
    strncpy(rk_bytes.get(), (char*)(d->routing_key.bytes), d->routing_key.len);
    rk_bytes[d->routing_key.len] = '\0';
    routing_key = rk_bytes.get();

    result = amqp_simple_wait_frame(m_state->conn, &frame);
    if (result <= 0)
      vw_throw(IOErr() << "AMQP error: unknown result waiting for frame.");

    if (frame.frame_type != AMQP_FRAME_HEADER) {
      vw_out(ErrorMessage, "platefile::amqp") << "Expected AMQP header!";
      abort();
    }
    p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
    if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
      // printf("Content-type: %.*s\n",
      //        (int) p->content_type.len, (char *) p->content_type.bytes);
    }
    // printf("----\n");

    body_target = frame.payload.properties.body_size;
    body_received = 0;
    payload = boost::shared_array<uint8>( new uint8[body_target] );

    while (body_received < body_target) {
      result = amqp_simple_wait_frame(m_state->conn, &frame);
      if (result <= 0)
        vw_throw(IOErr() << "AMQP error: unknown result waiting for frame.");

      if (frame.frame_type != AMQP_FRAME_BODY) {
        vw_out(ErrorMessage, "platefile::amqp") << "Expected AMQP message body!";
        abort();
      }

      // Copy the bytes out of the payload...
      memcpy(((char*)(payload.get()) + body_received),
             (const char*)(frame.payload.body_fragment.bytes),
             frame.payload.body_fragment.len);

      // ... and update the number of bytes we have received
      body_received += frame.payload.body_fragment.len;
      VW_ASSERT(body_received <= body_target, IOErr() << "AMQP packet body size exceeded header\'s body target.");
    }

    // Check to make sure that we have received the right number of bytes.
    if (body_received != body_target) {
      vw_throw(IOErr() << "AMQP packet body size does not match header\'s body target.");
    }

    if (!no_ack)
      amqp_basic_ack(m_state->conn, 1, d->delivery_tag, 0);

    vw_out(VerboseDebugMessage, "platefile::amqp") << "Message payload: \""
                                                   << payload.get() << "\"\n";

    return payload;
  }

}
<|endoftext|>


<commit_before>#include "LoadResTask.h"
#include "ResourceAPI.h"

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

namespace dtex
{

/************************************************************************/
/* class LoadResTask                                                    */
/************************************************************************/

LoadResTask::LoadResTask(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
	: mt::Task(TASK_TYPE)
	, m_on_finish(finish_cb)
	, m_ud(ud)
{
	memset(m_res_path, 0, sizeof(m_res_path));

	m_data = NULL;
	m_size = 0;
}

LoadResTask::~LoadResTask()
{
	free(m_data);
}

static inline void
on_load(const void* data, size_t size, void* ud)
{
	LoadResTask* task = static_cast<LoadResTask*>(ud);
	task->OnLoad(data, size);
}

void LoadResTask::Run()
{
	LoadResTaskMgr::Instance()->AddResult(this);

	ResourceAPI::LoadFile(m_res_path, false, on_load, this);
}

void LoadResTask::Flush()
{
	if (m_data && m_size != 0) {
		m_on_finish(m_data, m_size, m_ud);
	}
}

void LoadResTask::OnLoad(const void* data, size_t size)
{
	if (m_data) {
		free(m_data); m_data = NULL;
	}
	m_size = size;
	m_data = malloc(m_size);
	if (m_data) {
		memcpy(m_data, data, m_size);
	} else {
		m_size = 0;
	}
}

void LoadResTask::Init(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
{
	assert(!m_data);
	memset(m_res_path, 0, sizeof(m_res_path));
	m_on_finish = finish_cb;
	m_ud = ud;
}

void LoadResTask::Release()
{
	free(m_data); m_data = NULL;
	m_size = 0;
}

/************************************************************************/
/* class LoadResTaskMgr                                                 */
/************************************************************************/

SINGLETON_DEFINITION(LoadResTaskMgr)

LoadResTaskMgr::LoadResTaskMgr()
	: m_count(0)
{
}

LoadResTask* LoadResTaskMgr::Fetch(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
{
	mt::Task* t = m_freelist.Front();
	LoadResTask* tt = static_cast<LoadResTask*>(t);
	if (!tt) {
		tt = new LoadResTask(finish_cb, ud);
	} else {
		m_freelist.Pop();
		tt->Init(finish_cb, ud);
	}
	return tt;
}

void LoadResTaskMgr::AddResult(LoadResTask* task)
{
	m_result.Push(task);
}

void LoadResTaskMgr::Flush()
{
	while (mt::Task* t = m_result.TryPop())
	{
		LoadResTask* tt = static_cast<LoadResTask*>(t);
		tt->Flush();
		m_freelist.Push(t);
	}
}

}<commit_msg>[FIXED] task's release<commit_after>#include "LoadResTask.h"
#include "ResourceAPI.h"

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

namespace dtex
{

/************************************************************************/
/* class LoadResTask                                                    */
/************************************************************************/

LoadResTask::LoadResTask(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
	: mt::Task(TASK_TYPE)
	, m_on_finish(finish_cb)
	, m_ud(ud)
{
	memset(m_res_path, 0, sizeof(m_res_path));

	m_data = NULL;
	m_size = 0;
}

LoadResTask::~LoadResTask()
{
	free(m_data);
}

static inline void
on_load(const void* data, size_t size, void* ud)
{
	LoadResTask* task = static_cast<LoadResTask*>(ud);
	task->OnLoad(data, size);
}

void LoadResTask::Run()
{
	LoadResTaskMgr::Instance()->AddResult(this);

	ResourceAPI::LoadFile(m_res_path, false, on_load, this);
}

void LoadResTask::Flush()
{
	if (m_data && m_size != 0) {
		m_on_finish(m_data, m_size, m_ud);
	}
}

void LoadResTask::OnLoad(const void* data, size_t size)
{
	if (m_data) {
		free(m_data); m_data = NULL;
	}
	m_size = size;
	m_data = malloc(m_size);
	if (m_data) {
		memcpy(m_data, data, m_size);
	} else {
		m_size = 0;
	}
}

void LoadResTask::Init(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
{
	assert(!m_data);
	memset(m_res_path, 0, sizeof(m_res_path));
	m_on_finish = finish_cb;
	m_ud = ud;
}

void LoadResTask::Release()
{
	free(m_data); m_data = NULL;
	m_size = 0;
}

/************************************************************************/
/* class LoadResTaskMgr                                                 */
/************************************************************************/

SINGLETON_DEFINITION(LoadResTaskMgr)

LoadResTaskMgr::LoadResTaskMgr()
	: m_count(0)
{
}

LoadResTask* LoadResTaskMgr::Fetch(void (*finish_cb)(const void* data, size_t size, void* ud), void* ud)
{
	mt::Task* t = m_freelist.Front();
	LoadResTask* tt = static_cast<LoadResTask*>(t);
	if (!tt) {
		tt = new LoadResTask(finish_cb, ud);
	} else {
		m_freelist.Pop();
		tt->Init(finish_cb, ud);
	}
	return tt;
}

void LoadResTaskMgr::AddResult(LoadResTask* task)
{
	m_result.Push(task);
}

void LoadResTaskMgr::Flush()
{
	while (mt::Task* t = m_result.TryPop())
	{
		LoadResTask* tt = static_cast<LoadResTask*>(t);
		tt->Flush();
		tt->Release();
		m_freelist.Push(t);
	}
}

}<|endoftext|>


<commit_before>
#include "journal/player.hpp"

#include <list>
#include <string>
#include <thread>
#include <vector>

#include "benchmark/benchmark.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "journal/method.hpp"
#include "journal/profiles.hpp"
#include "journal/recorder.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {
namespace journal {

// The benchmark is only run if --gtest_filter=PlayerTest.Benchmarks
void BM_PlayForReal(benchmark::State& state) {  // NOLINT(runtime/references)
  while (state.KeepRunning()) {
    Player player(
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20160626-143407)");
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0)
          << count << " journal entries replayed";
    }
  }
}

BENCHMARK(BM_PlayForReal);

class PlayerTest : public ::testing::Test {
 protected:
  PlayerTest()
      : test_info_(testing::UnitTest::GetInstance()->current_test_info()),
        test_case_name_(test_info_->test_case_name()),
        test_name_(test_info_->name()),
        plugin_(interface::principia__NewPlugin("0 s", "0 s", 0)) {}

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method_in,
                        serialization::Method const& method_out_return,
                        Player& player) {
    return player.RunIfAppropriate<Profile>(method_in, method_out_return);
  }

  ::testing::TestInfo const* const test_info_;
  std::string const test_case_name_;
  std::string const test_name_;
  std::unique_ptr<ksp_plugin::Plugin> plugin_;
};

TEST_F(PlayerTest, PlayTiny) {
  // Do the recording in a separate thread to make sure that it activates using
  // a different static variable than the one in the plugin dynamic library.
  std::thread recorder([this]() {
    Recorder* const r(new Recorder(test_name_ + ".journal.hex"));
    Recorder::Activate(r);

    {
      Method<NewPlugin> m({"1 s", "2 s", 3});
      m.Return(plugin_.get());
    }
    {
      const ksp_plugin::Plugin* plugin = plugin_.get();
      Method<DeletePlugin> m({&plugin}, {&plugin});
      m.Return();
    }
    Recorder::Deactivate();
  });
  recorder.join();

  Player player(test_name_ + ".journal.hex");

  // Replay the journal.
  int count = 0;
  while (player.Play()) {
    ++count;
  }
  EXPECT_EQ(2, count);
}

// This test (a.k.a. benchmark) is only run if the --gtest_filter flag names it
// explicitly.
TEST_F(PlayerTest, Benchmarks) {
  if (testing::FLAGS_gtest_filter == test_case_name_ + "." + test_name_) {
    benchmark::RunSpecifiedBenchmarks();
  }
}

#if 1
// This test is only run if the --gtest_filter flag names it explicitly.
TEST_F(PlayerTest, Debug) {
  if (testing::FLAGS_gtest_filter == test_case_name_ + "." + test_name_) {
    // An example of how journaling may be used for debugging.  You must set
    // |path| and fill the |method_in| and |method_out_return| protocol buffers.
    std::string path =
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20170322-175914)";
    Player player(path);
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0) << count
                                            << " journal entries replayed";
    }
    LOG(ERROR) << count << " journal entries in total";
    LOG(ERROR) << "Last successful method in:\n"
               << player.last_method_in().DebugString();
    LOG(ERROR) << "Last successful method out/return: \n"
               << player.last_method_out_return().DebugString();

#if 0
    serialization::Method method_in;
    auto* extension = method_in.MutableExtension(
        serialization::ReportCollision::extension);
    auto* in = extension->mutable_in();
    in->set_plugin(355375312);
    in->set_vessel1_guid("14b05bd3-9707-4d49-a6be-a7de481f3e0a");
    in->set_vessel2_guid("3e6fcb7e-4761-48ed-829f-0adb035f457e");
    serialization::Method method_out_return;
    method_out_return.MutableExtension(
        serialization::ReportCollision::extension);
    LOG(ERROR) << "Running unpaired method:\n" << method_in.DebugString();
    CHECK(RunIfAppropriate<ReportCollision>(method_in,
                                            method_out_return,
                                            player));
#endif
  }
}
#endif

}  // namespace journal
}  // namespace principia
<commit_msg>No if.<commit_after>
#include "journal/player.hpp"

#include <list>
#include <string>
#include <thread>
#include <vector>

#include "benchmark/benchmark.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "journal/method.hpp"
#include "journal/profiles.hpp"
#include "journal/recorder.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {
namespace journal {

// The benchmark is only run if --gtest_filter=PlayerTest.Benchmarks
void BM_PlayForReal(benchmark::State& state) {  // NOLINT(runtime/references)
  while (state.KeepRunning()) {
    Player player(
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20160626-143407)");
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0)
          << count << " journal entries replayed";
    }
  }
}

BENCHMARK(BM_PlayForReal);

class PlayerTest : public ::testing::Test {
 protected:
  PlayerTest()
      : test_info_(testing::UnitTest::GetInstance()->current_test_info()),
        test_case_name_(test_info_->test_case_name()),
        test_name_(test_info_->name()),
        plugin_(interface::principia__NewPlugin("0 s", "0 s", 0)) {}

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method_in,
                        serialization::Method const& method_out_return,
                        Player& player) {
    return player.RunIfAppropriate<Profile>(method_in, method_out_return);
  }

  ::testing::TestInfo const* const test_info_;
  std::string const test_case_name_;
  std::string const test_name_;
  std::unique_ptr<ksp_plugin::Plugin> plugin_;
};

TEST_F(PlayerTest, PlayTiny) {
  // Do the recording in a separate thread to make sure that it activates using
  // a different static variable than the one in the plugin dynamic library.
  std::thread recorder([this]() {
    Recorder* const r(new Recorder(test_name_ + ".journal.hex"));
    Recorder::Activate(r);

    {
      Method<NewPlugin> m({"1 s", "2 s", 3});
      m.Return(plugin_.get());
    }
    {
      const ksp_plugin::Plugin* plugin = plugin_.get();
      Method<DeletePlugin> m({&plugin}, {&plugin});
      m.Return();
    }
    Recorder::Deactivate();
  });
  recorder.join();

  Player player(test_name_ + ".journal.hex");

  // Replay the journal.
  int count = 0;
  while (player.Play()) {
    ++count;
  }
  EXPECT_EQ(2, count);
}

// This test (a.k.a. benchmark) is only run if the --gtest_filter flag names it
// explicitly.
TEST_F(PlayerTest, Benchmarks) {
  if (testing::FLAGS_gtest_filter == test_case_name_ + "." + test_name_) {
    benchmark::RunSpecifiedBenchmarks();
  }
}

// This test is only run if the --gtest_filter flag names it explicitly.
TEST_F(PlayerTest, Debug) {
  if (testing::FLAGS_gtest_filter == test_case_name_ + "." + test_name_) {
    // An example of how journaling may be used for debugging.  You must set
    // |path| and fill the |method_in| and |method_out_return| protocol buffers.
    std::string path =
        R"(P:\Public Mockingbird\Principia\Journals\JOURNAL.20170322-175914)";
    Player player(path);
    int count = 0;
    while (player.Play()) {
      ++count;
      LOG_IF(ERROR, (count % 100'000) == 0) << count
                                            << " journal entries replayed";
    }
    LOG(ERROR) << count << " journal entries in total";
    LOG(ERROR) << "Last successful method in:\n"
               << player.last_method_in().DebugString();
    LOG(ERROR) << "Last successful method out/return: \n"
               << player.last_method_out_return().DebugString();

#if 0
    serialization::Method method_in;
    auto* extension = method_in.MutableExtension(
        serialization::ReportCollision::extension);
    auto* in = extension->mutable_in();
    in->set_plugin(355375312);
    in->set_vessel1_guid("14b05bd3-9707-4d49-a6be-a7de481f3e0a");
    in->set_vessel2_guid("3e6fcb7e-4761-48ed-829f-0adb035f457e");
    serialization::Method method_out_return;
    method_out_return.MutableExtension(
        serialization::ReportCollision::extension);
    LOG(ERROR) << "Running unpaired method:\n" << method_in.DebugString();
    CHECK(RunIfAppropriate<ReportCollision>(method_in,
                                            method_out_return,
                                            player));
#endif
  }
}

}  // namespace journal
}  // namespace principia
<|endoftext|>