<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/storage/persistence/filestorage/service_layer_host_info_reporter.h>
#include <tests/common/hostreporter/util.h>
#include <tests/common/testnodestateupdater.h>
#include <vespa/vespalib/data/slime/slime.h>
#include <vespa/vespalib/io/fileutil.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/gtest/gtest.h>
#include <iostream>

namespace storage {

namespace {

double
get_usage_element(const vespalib::Slime& root, const vespalib::string& label)
{
    return root.get()["content-node"]["resource-usage"][label]["usage"].asDouble();
}

}

struct ServiceLayerHostInfoReporterTest : ::testing::Test {

    TestNodeStateUpdater         _state_manager;
    ServiceLayerHostInfoReporter _reporter;

    ServiceLayerHostInfoReporterTest();
    ~ServiceLayerHostInfoReporterTest();

    void notify(double disk_usage, double memory_usage)
    {
        auto& listener = static_cast<spi::IResourceUsageListener&>(_reporter);
        listener.update_resource_usage(spi::ResourceUsage(disk_usage, memory_usage));
    }

    size_t requested_almost_immediate_replies() { return _state_manager.requested_almost_immediate_node_state_replies(); }
    std::vector<double> get_old_usage() {
        auto &old_resource_usage = _reporter.get_old_resource_usage();
        return std::vector<double>{ old_resource_usage.get_disk_usage(), old_resource_usage.get_memory_usage() };
    }
    std::vector<double> get_usage() {
        auto &resource_usage = _reporter.get_usage();
        return std::vector<double>{ resource_usage.get_disk_usage(), resource_usage.get_memory_usage() };
    }
    std::vector<double> get_slime_usage() {
        vespalib::Slime root;
        util::reporterToSlime(_reporter, root);
        return std::vector<double>{ get_usage_element(root, "disk"), get_usage_element(root, "memory") };
    }
};

ServiceLayerHostInfoReporterTest::ServiceLayerHostInfoReporterTest()
    : _state_manager(lib::NodeType::STORAGE),
      _reporter(_state_manager)
{
}

ServiceLayerHostInfoReporterTest::~ServiceLayerHostInfoReporterTest() = default;

TEST_F(ServiceLayerHostInfoReporterTest, request_almost_immediate_node_state_as_needed)
{
    EXPECT_EQ(0, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.0, 0.0 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.0, 0.0 }), get_usage());
    notify(0.5, 0.4);
    EXPECT_EQ(1, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.5, 0.4 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.5, 0.4 }), get_usage());
    notify(0.501, 0.401);
    EXPECT_EQ(1, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.5, 0.4 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.501, 0.401 }), get_usage());
    notify(0.8, 0.4);
    EXPECT_EQ(2, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.8, 0.4 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.8, 0.4 }), get_usage());
    notify(0.8, 0.7);
    EXPECT_EQ(3, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.8, 0.7 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.8, 0.7 }), get_usage());
    notify(0.799, 0.699);
    EXPECT_EQ(3, requested_almost_immediate_replies());
    EXPECT_EQ((std::vector<double>{ 0.8, 0.7 }), get_old_usage());
    EXPECT_EQ((std::vector<double>{ 0.799, 0.699 }), get_usage());
}

TEST_F(ServiceLayerHostInfoReporterTest, json_report_generated)
{
    EXPECT_EQ((std::vector<double>{ 0.0, 0.0 }), get_slime_usage());
    notify(0.5, 0.4);
    EXPECT_EQ((std::vector<double>{ 0.5, 0.4 }), get_slime_usage());
}

}
<commit_msg>Simplify test.<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/storage/persistence/filestorage/service_layer_host_info_reporter.h>
#include <tests/common/hostreporter/util.h>
#include <tests/common/testnodestateupdater.h>
#include <vespa/vespalib/data/slime/slime.h>
#include <vespa/vespalib/io/fileutil.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/gtest/gtest.h>
#include <iostream>

namespace storage {

using spi::ResourceUsage;

namespace {

double
get_usage_element(const vespalib::Slime& root, const vespalib::string& label)
{
    return root.get()["content-node"]["resource-usage"][label]["usage"].asDouble();
}

}

struct ServiceLayerHostInfoReporterTest : ::testing::Test {

    TestNodeStateUpdater         _state_manager;
    ServiceLayerHostInfoReporter _reporter;

    ServiceLayerHostInfoReporterTest();
    ~ServiceLayerHostInfoReporterTest();

    void notify(double disk_usage, double memory_usage) {
        auto& listener = static_cast<spi::IResourceUsageListener&>(_reporter);
        listener.update_resource_usage(ResourceUsage(disk_usage, memory_usage));
    }

    size_t requested_almost_immediate_replies() { return _state_manager.requested_almost_immediate_node_state_replies(); }
    ResourceUsage get_old_usage() { return _reporter.get_old_resource_usage(); }
    ResourceUsage get_usage() { return _reporter.get_usage(); }
    ResourceUsage get_slime_usage() {
        vespalib::Slime root;
        util::reporterToSlime(_reporter, root);
        return ResourceUsage(get_usage_element(root, "disk"), get_usage_element(root, "memory"));
    }
};

ServiceLayerHostInfoReporterTest::ServiceLayerHostInfoReporterTest()
    : _state_manager(lib::NodeType::STORAGE),
      _reporter(_state_manager)
{
}

ServiceLayerHostInfoReporterTest::~ServiceLayerHostInfoReporterTest() = default;

TEST_F(ServiceLayerHostInfoReporterTest, request_almost_immediate_node_state_as_needed)
{
    EXPECT_EQ(0, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.0, 0.0), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.0, 0.0), get_usage());
    notify(0.5, 0.4);
    EXPECT_EQ(1, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.5, 0.4), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.5, 0.4), get_usage());
    notify(0.501, 0.401);
    EXPECT_EQ(1, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.5, 0.4), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.501, 0.401), get_usage());
    notify(0.8, 0.4);
    EXPECT_EQ(2, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.8, 0.4), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.8, 0.4), get_usage());
    notify(0.8, 0.7);
    EXPECT_EQ(3, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.8, 0.7), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.8, 0.7), get_usage());
    notify(0.799, 0.699);
    EXPECT_EQ(3, requested_almost_immediate_replies());
    EXPECT_EQ(ResourceUsage(0.8, 0.7), get_old_usage());
    EXPECT_EQ(ResourceUsage(0.799, 0.699), get_usage());
}

TEST_F(ServiceLayerHostInfoReporterTest, json_report_generated)
{
    EXPECT_EQ(ResourceUsage(0.0, 0.0), get_slime_usage());
    notify(0.5, 0.4);
    EXPECT_EQ(ResourceUsage(0.5, 0.4), get_slime_usage());
}

}
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "win_dev_wifi_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::DisposeNative___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeInit___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeConnect___WindowsDevicesWiFiWiFiConnectionStatus__STRING__STRING__WindowsDevicesWiFiWiFiReconnectionKind,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeDisconnect___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeScanAsync___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::GetNativeScanReport___SZARRAY_U1,
    NULL,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeFindWirelessAdapters___STATIC__SZARRAY_U1,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_Windows_Devices_Wifi =
{
    "Windows.Devices.Wifi",
    0x5AC050C9,
    method_lookup,
    { 1, 0, 0, 0 }
};
<commit_msg>Update Windows.Devices.WiFi version to 1.0.2-preview-004 (#966)<commit_after>//
// Copyright (c) 2017 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "win_dev_wifi_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::DisposeNative___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeInit___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeConnect___WindowsDevicesWiFiWiFiConnectionStatus__STRING__STRING__WindowsDevicesWiFiWiFiReconnectionKind,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeDisconnect___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeScanAsync___VOID,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::GetNativeScanReport___SZARRAY_U1,
    NULL,
    Library_win_dev_wifi_native_Windows_Devices_WiFi_WiFiAdapter::NativeFindWirelessAdapters___STATIC__SZARRAY_U1,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_Windows_Devices_Wifi =
{
    "Windows.Devices.Wifi",
    0x5AC050C9,
    method_lookup,
    { 1, 0, 2, 4 }
};
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGLSLShaderProgram.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2003 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

#include "vtkGLSLShaderProgram.h"

#include "vtkActor.h"
#include "vtkCollectionIterator.h"
#include "vtkGLSLShaderDeviceAdapter.h"
#include "vtkGLSLShader.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkTexture.h"
#include "vtkXMLDataElement.h"
#include "vtkWindow.h"

#include <vector>
#include <string>
// GL/glu.h is needed for the error reporting, this should be removed
// after the initial development phase.
//#include <GL/glu.h>
#include <vtkgl.h>

#if 1
#define printOpenGLError() printOglError(__FILE__, __LINE__)
static int printOglError(char *vtkNotUsed(file), int vtkNotUsed(line))
  {
  // Returns 1 if an OpenGL error occurred, 0 otherwise.
  //
  GLenum glErr;
  int    retCode = 0;

  glErr = glGetError();
  while (glErr != GL_NO_ERROR)
    {
    //printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
    cout << "Error in GLSLShaderProgram" << endl;
    retCode = 1;
    glErr = glGetError();
    }
  return retCode;
  }
#endif

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkGLSLShaderProgram);

//-----------------------------------------------------------------------------
vtkGLSLShaderProgram::vtkGLSLShaderProgram()
  : Program(0),
    Info(NULL)
{
  vtkGLSLShaderDeviceAdapter* adapter = vtkGLSLShaderDeviceAdapter::New();
  this->SetShaderDeviceAdapter(adapter);
  adapter->Delete();
}

//-----------------------------------------------------------------------------
vtkGLSLShaderProgram::~vtkGLSLShaderProgram()
{
  this->SetShaderDeviceAdapter(0);
}

//-----------------------------------------------------------------------------
vtkShader* vtkGLSLShaderProgram::NewShader()
{
  return vtkGLSLShader::New();
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::ReleaseGraphicsResources(vtkWindow* w)
{
  if (w && w->GetMapped() && this->IsProgram())
    {
    vtkgl::DeleteProgram(this->Program);
    }
  this->Program = 0;
  this->Superclass::ReleaseGraphicsResources(w);
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::Link()
{
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsProgram()
{
  return this->Program &&
    vtkgl::IsProgram( static_cast<GLuint>(this->Program) ) == GL_TRUE;
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsLinked()
{
  if(!this->IsProgram())
    {
    return false;
    }
  GLint value = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::LINK_STATUS, &value);
  return value==1;
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::GetProgramInfo()
{
  if (!this->Program)
    {
    return;
    }

  std::string infoString;
  if(this->IsProgram())
    {
    infoString += "GLSL Program. \n";
    }
  else
    {
    this->SetInfo("Not a GLSL Program. \n");
    return;
    }

  // is this Program linked?
  infoString += "Linked Status: ";
  char linkedStr[256];
  sprintf( linkedStr, "%d", this->IsLinked() );
  infoString += linkedStr;
  infoString += "\n";

  // how many objects are attached?
  GLint numObjects = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::ATTACHED_SHADERS, &numObjects);

  char numStr[256];
  sprintf( numStr, "%d", static_cast<int>(numObjects) );
  infoString += "Number of attached objects: ";
  infoString += numStr;
  infoString += "\n";

  // Anything in the info log?
  GLint maxLength = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::INFO_LOG_LENGTH, &maxLength);

  vtkgl::GLchar* info = new vtkgl::GLchar[maxLength];

  GLsizei charsWritten;
  vtkgl::GetProgramInfoLog( static_cast<GLuint>(this->Program), maxLength,
                            &charsWritten, info );
  if( info )
    {
    infoString += static_cast<char*>(info);
    infoString += "\n";
    }

  if( infoString.empty() )
    {
    this->SetInfo( "No Program Info." );
    }
  else
    {
    this->SetInfo( infoString.c_str() );
    }
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::GetInfoLog()
{
  // Anything in the info log?
  int infologLength = 0;
  int charsWritten  = 0;
  vtkgl::GLchar *infoLog = NULL;

  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::INFO_LOG_LENGTH,
                      reinterpret_cast<GLint*>(&infologLength));

  if(infologLength > 0)
    {
    infoLog = new vtkgl::GLchar[infologLength];
    if(infoLog == NULL)
      {
      printf("ERROR: Could not allocate InfoLog buffer\n");
      return;
      }
    vtkgl::GetProgramInfoLog(static_cast<GLuint>(this->Program),
                             infologLength,
                             reinterpret_cast<GLsizei*>(&charsWritten),
                             infoLog);
    this->SetInfo( infoLog );
    delete [] infoLog;
    }
  else
    {
    this->SetInfo( "No Log Info." );
    }
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsAttached(vtkGLSLShader* glslshader)
{
  unsigned int handle = glslshader->GetHandle();
  int attached = 0;
  // find out what's attached
  GLint numObjects = 0;
  GLint writtenObjects = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::ATTACHED_SHADERS, &numObjects);

  std::vector<GLuint> attachedObjects(numObjects);
  if( numObjects > 0 )
    {
    vtkgl::GetAttachedShaders(static_cast<GLuint>(this->Program), numObjects,
                              &writtenObjects, &attachedObjects[0]);
    }

  std::vector<GLuint>::iterator it = attachedObjects.begin();
  std::vector<GLuint>::iterator itEnd = attachedObjects.end();
  while( it != itEnd )
    {
    if( static_cast<GLuint>(handle) == *it )
      {
      attached = 1;
      }
    it++;
    }
  return attached;
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::LoadExtensions( vtkRenderWindow* renWin )
{
  if(this->GetGLExtensionsLoaded())
    {
    return;
    }

  // Load extensions using vtkOpenGLExtensionManager
  vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New();
  // How can I get access to the vtkRenderWindow from here?
  extensions->SetRenderWindow( renWin );
  if(extensions->ExtensionSupported("GL_VERSION_2_0")
     && extensions->ExtensionSupported("GL_VERSION_1_3") )
    {
    extensions->LoadExtension("GL_VERSION_2_0");
    extensions->LoadExtension("GL_VERSION_1_3");
    this->SetGLExtensionsLoaded(1);
    }
  else if (extensions->ExtensionSupported("GL_VERSION_1_3")
           && extensions->ExtensionSupported("GL_ARB_shading_language_100")
           && extensions->ExtensionSupported("GL_ARB_shader_objects")
           && extensions->ExtensionSupported("GL_ARB_vertex_shader")
           && extensions->ExtensionSupported("GL_ARB_fragment_shader") )
    {
    // Support older drivers that implement GLSL but not all of OpenGL 2.0.
    extensions->LoadExtension("GL_VERSION_1_3");
    extensions->LoadCorePromotedExtension("GL_ARB_shading_language_100");
    extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
    extensions->LoadCorePromotedExtension("GL_ARB_vertex_shader");
    extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
    this->SetGLExtensionsLoaded(1);
    }
  else
    {
    vtkErrorMacro( "Required extension (GL_VERSION_2_0) is not supported." )
    this->SetGLExtensionsLoaded(0);
    }
  extensions->Delete();
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::Render(vtkActor *actor, vtkRenderer *renderer)
{
  this->LoadExtensions( renderer->GetRenderWindow() );
  if (!this->GetGLExtensionsLoaded())
    {
    return;
    }

  // Get a gl identifier for the shader program if we don't already have one.
  if(!this->IsProgram())
    {
    this->Program = static_cast<unsigned int>(vtkgl::CreateProgram());
    }

  if(!this->IsProgram())
    {
    vtkErrorMacro( "Not able to create a GLSL Program!!!" << endl );
    return;
    }

  vtkCollectionIterator* iter = this->ShaderCollectionIterator;
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
    iter->GoToNextItem())
    {
    vtkGLSLShader* shader = vtkGLSLShader::SafeDownCast(
      iter->GetCurrentObject());

    if (!shader)
      {
      vtkErrorMacro("GLSL Shader program cannot contain a non-GLSL shader.");
      continue;
      }

    if (shader->Compile())
      {
      if (!this->IsAttached(shader))
        {
        vtkgl::AttachShader(static_cast<GLuint>(this->Program),
                            shader->GetHandle());
        }
      }
    }

  if( !this->IsLinked() )
    {
    // if either a vertex or a fragment program is attached (or both)
    // link the program.
    GLint numObjects = 0;
    vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                        vtkgl::ATTACHED_SHADERS, &numObjects);
    if (numObjects>0)
      {
      vtkgl::LinkProgram(static_cast<GLuint>(this->Program));
      if (!this->IsLinked())
        {
        this->GetInfoLog();
        vtkErrorMacro(<< "Failed to link GLSL program:\n"
                      << this->Info);
        }
      }
    }

  if( this->IsLinked() )
    {
    // check to see if this is the active program
    vtkgl::UseProgram(static_cast<GLuint>(this->Program));
    }

  // handle attributes and uniform variables
  // uniform variables
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
    iter->GoToNextItem())
    {
    vtkGLSLShader* shader = vtkGLSLShader::SafeDownCast(
      iter->GetCurrentObject());
    if (!shader)
      {
      // no need to flag error...already marked.
      continue;
      }
    shader->SetProgram(this->Program);
    shader->PassShaderVariables(actor, renderer);
    }
}
//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::PostRender(vtkActor*, vtkRenderer*)
{
  if (!this->GetGLExtensionsLoaded())
    {
    return;
    }

  if (this->IsProgram())
    {
    // this unloads the shader program.
    vtkgl::UseProgram(0);
    }
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

<commit_msg>Silence warning by toggling an "#if 1"<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGLSLShaderProgram.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2003 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

#include "vtkGLSLShaderProgram.h"

#include "vtkActor.h"
#include "vtkCollectionIterator.h"
#include "vtkGLSLShaderDeviceAdapter.h"
#include "vtkGLSLShader.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkTexture.h"
#include "vtkXMLDataElement.h"
#include "vtkWindow.h"

#include <vector>
#include <string>
// GL/glu.h is needed for the error reporting, this should be removed
// after the initial development phase.
//#include <GL/glu.h>
#include <vtkgl.h>

#if 0
#define printOpenGLError() printOglError(__FILE__, __LINE__)
static int printOglError(char *vtkNotUsed(file), int vtkNotUsed(line))
  {
  // Returns 1 if an OpenGL error occurred, 0 otherwise.
  //
  GLenum glErr;
  int    retCode = 0;

  glErr = glGetError();
  while (glErr != GL_NO_ERROR)
    {
    //printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
    cout << "Error in GLSLShaderProgram" << endl;
    retCode = 1;
    glErr = glGetError();
    }
  return retCode;
  }
#endif

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkGLSLShaderProgram);

//-----------------------------------------------------------------------------
vtkGLSLShaderProgram::vtkGLSLShaderProgram()
  : Program(0),
    Info(NULL)
{
  vtkGLSLShaderDeviceAdapter* adapter = vtkGLSLShaderDeviceAdapter::New();
  this->SetShaderDeviceAdapter(adapter);
  adapter->Delete();
}

//-----------------------------------------------------------------------------
vtkGLSLShaderProgram::~vtkGLSLShaderProgram()
{
  this->SetShaderDeviceAdapter(0);
}

//-----------------------------------------------------------------------------
vtkShader* vtkGLSLShaderProgram::NewShader()
{
  return vtkGLSLShader::New();
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::ReleaseGraphicsResources(vtkWindow* w)
{
  if (w && w->GetMapped() && this->IsProgram())
    {
    vtkgl::DeleteProgram(this->Program);
    }
  this->Program = 0;
  this->Superclass::ReleaseGraphicsResources(w);
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::Link()
{
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsProgram()
{
  return this->Program &&
    vtkgl::IsProgram( static_cast<GLuint>(this->Program) ) == GL_TRUE;
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsLinked()
{
  if(!this->IsProgram())
    {
    return false;
    }
  GLint value = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::LINK_STATUS, &value);
  return value==1;
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::GetProgramInfo()
{
  if (!this->Program)
    {
    return;
    }

  std::string infoString;
  if(this->IsProgram())
    {
    infoString += "GLSL Program. \n";
    }
  else
    {
    this->SetInfo("Not a GLSL Program. \n");
    return;
    }

  // is this Program linked?
  infoString += "Linked Status: ";
  char linkedStr[256];
  sprintf( linkedStr, "%d", this->IsLinked() );
  infoString += linkedStr;
  infoString += "\n";

  // how many objects are attached?
  GLint numObjects = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::ATTACHED_SHADERS, &numObjects);

  char numStr[256];
  sprintf( numStr, "%d", static_cast<int>(numObjects) );
  infoString += "Number of attached objects: ";
  infoString += numStr;
  infoString += "\n";

  // Anything in the info log?
  GLint maxLength = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::INFO_LOG_LENGTH, &maxLength);

  vtkgl::GLchar* info = new vtkgl::GLchar[maxLength];

  GLsizei charsWritten;
  vtkgl::GetProgramInfoLog( static_cast<GLuint>(this->Program), maxLength,
                            &charsWritten, info );
  if( info )
    {
    infoString += static_cast<char*>(info);
    infoString += "\n";
    }

  if( infoString.empty() )
    {
    this->SetInfo( "No Program Info." );
    }
  else
    {
    this->SetInfo( infoString.c_str() );
    }
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::GetInfoLog()
{
  // Anything in the info log?
  int infologLength = 0;
  int charsWritten  = 0;
  vtkgl::GLchar *infoLog = NULL;

  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::INFO_LOG_LENGTH,
                      reinterpret_cast<GLint*>(&infologLength));

  if(infologLength > 0)
    {
    infoLog = new vtkgl::GLchar[infologLength];
    if(infoLog == NULL)
      {
      printf("ERROR: Could not allocate InfoLog buffer\n");
      return;
      }
    vtkgl::GetProgramInfoLog(static_cast<GLuint>(this->Program),
                             infologLength,
                             reinterpret_cast<GLsizei*>(&charsWritten),
                             infoLog);
    this->SetInfo( infoLog );
    delete [] infoLog;
    }
  else
    {
    this->SetInfo( "No Log Info." );
    }
}

//-----------------------------------------------------------------------------
int vtkGLSLShaderProgram::IsAttached(vtkGLSLShader* glslshader)
{
  unsigned int handle = glslshader->GetHandle();
  int attached = 0;
  // find out what's attached
  GLint numObjects = 0;
  GLint writtenObjects = 0;
  vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                      vtkgl::ATTACHED_SHADERS, &numObjects);

  std::vector<GLuint> attachedObjects(numObjects);
  if( numObjects > 0 )
    {
    vtkgl::GetAttachedShaders(static_cast<GLuint>(this->Program), numObjects,
                              &writtenObjects, &attachedObjects[0]);
    }

  std::vector<GLuint>::iterator it = attachedObjects.begin();
  std::vector<GLuint>::iterator itEnd = attachedObjects.end();
  while( it != itEnd )
    {
    if( static_cast<GLuint>(handle) == *it )
      {
      attached = 1;
      }
    it++;
    }
  return attached;
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::LoadExtensions( vtkRenderWindow* renWin )
{
  if(this->GetGLExtensionsLoaded())
    {
    return;
    }

  // Load extensions using vtkOpenGLExtensionManager
  vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New();
  // How can I get access to the vtkRenderWindow from here?
  extensions->SetRenderWindow( renWin );
  if(extensions->ExtensionSupported("GL_VERSION_2_0")
     && extensions->ExtensionSupported("GL_VERSION_1_3") )
    {
    extensions->LoadExtension("GL_VERSION_2_0");
    extensions->LoadExtension("GL_VERSION_1_3");
    this->SetGLExtensionsLoaded(1);
    }
  else if (extensions->ExtensionSupported("GL_VERSION_1_3")
           && extensions->ExtensionSupported("GL_ARB_shading_language_100")
           && extensions->ExtensionSupported("GL_ARB_shader_objects")
           && extensions->ExtensionSupported("GL_ARB_vertex_shader")
           && extensions->ExtensionSupported("GL_ARB_fragment_shader") )
    {
    // Support older drivers that implement GLSL but not all of OpenGL 2.0.
    extensions->LoadExtension("GL_VERSION_1_3");
    extensions->LoadCorePromotedExtension("GL_ARB_shading_language_100");
    extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
    extensions->LoadCorePromotedExtension("GL_ARB_vertex_shader");
    extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
    this->SetGLExtensionsLoaded(1);
    }
  else
    {
    vtkErrorMacro( "Required extension (GL_VERSION_2_0) is not supported." )
    this->SetGLExtensionsLoaded(0);
    }
  extensions->Delete();
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::Render(vtkActor *actor, vtkRenderer *renderer)
{
  this->LoadExtensions( renderer->GetRenderWindow() );
  if (!this->GetGLExtensionsLoaded())
    {
    return;
    }

  // Get a gl identifier for the shader program if we don't already have one.
  if(!this->IsProgram())
    {
    this->Program = static_cast<unsigned int>(vtkgl::CreateProgram());
    }

  if(!this->IsProgram())
    {
    vtkErrorMacro( "Not able to create a GLSL Program!!!" << endl );
    return;
    }

  vtkCollectionIterator* iter = this->ShaderCollectionIterator;
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
    iter->GoToNextItem())
    {
    vtkGLSLShader* shader = vtkGLSLShader::SafeDownCast(
      iter->GetCurrentObject());

    if (!shader)
      {
      vtkErrorMacro("GLSL Shader program cannot contain a non-GLSL shader.");
      continue;
      }

    if (shader->Compile())
      {
      if (!this->IsAttached(shader))
        {
        vtkgl::AttachShader(static_cast<GLuint>(this->Program),
                            shader->GetHandle());
        }
      }
    }

  if( !this->IsLinked() )
    {
    // if either a vertex or a fragment program is attached (or both)
    // link the program.
    GLint numObjects = 0;
    vtkgl::GetProgramiv(static_cast<GLuint>(this->Program),
                        vtkgl::ATTACHED_SHADERS, &numObjects);
    if (numObjects>0)
      {
      vtkgl::LinkProgram(static_cast<GLuint>(this->Program));
      if (!this->IsLinked())
        {
        this->GetInfoLog();
        vtkErrorMacro(<< "Failed to link GLSL program:\n"
                      << this->Info);
        }
      }
    }

  if( this->IsLinked() )
    {
    // check to see if this is the active program
    vtkgl::UseProgram(static_cast<GLuint>(this->Program));
    }

  // handle attributes and uniform variables
  // uniform variables
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
    iter->GoToNextItem())
    {
    vtkGLSLShader* shader = vtkGLSLShader::SafeDownCast(
      iter->GetCurrentObject());
    if (!shader)
      {
      // no need to flag error...already marked.
      continue;
      }
    shader->SetProgram(this->Program);
    shader->PassShaderVariables(actor, renderer);
    }
}
//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::PostRender(vtkActor*, vtkRenderer*)
{
  if (!this->GetGLExtensionsLoaded())
    {
    return;
    }

  if (this->IsProgram())
    {
    // this unloads the shader program.
    vtkgl::UseProgram(0);
    }
}

//-----------------------------------------------------------------------------
void vtkGLSLShaderProgram::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

<|endoftext|>


<commit_before>#include "uci.h"
#include "board.h"
#include "defs.h"
#include "move.h"
#include "movegen.h"
#include "search.h"
#include "version.h"
#include <iostream>
#include <thread>
#include <sstream>

void Uci::_uciNewGame(){
  _board.setToStartPos();
}

void Uci::_setPosition(std::istringstream& is) {
  std::string token;
  is >> token;

  if (token == "startpos") {
    _board.setToStartPos();
  } else {
    std::string fen;

    while (is >> token && token != "moves") {
      fen += token + " ";
    }

    _board.setToFen(fen);
  }

  while (is >> token) {
    if (token == "moves") {
      continue;
    }

    MoveGen movegen(_board);
    for (auto move : movegen.getMoves()) {
      if (move.getNotation() == token) {
        _board.doMove(move);
        break;
      }
    }
  }
}

void Uci::_pickBestMove(Search::Limits limits) {
  _search->iterDeep();
}

void Uci::_go(std::istringstream& is) {
  std::string token;
  Search::Limits limits;

  while (is >> token) {
    if (token == "depth") is >> limits.depth;
    if (token == "infinite") limits.infinite = true;
    else if (token == "nodes") is >> limits.nodes;
    else if (token == "wtime") is >> limits.time[WHITE];
    else if (token == "btime") is >> limits.time[BLACK];
    else if (token == "winc") is >> limits.increment[WHITE];
    else if (token == "binc") is >> limits.increment[BLACK];
    else if (token == "movestogo") is >> limits.movesToGo;
  }

  _search = std::shared_ptr<Search>(new Search(_board, limits));

  std::thread searchThread(&Uci::_pickBestMove, this, limits);
  searchThread.detach();
}

unsigned long long Uci::_perft(const Board& board, int depth) {
  if (depth == 0) {
    return 1;
  }

  MoveGen movegen(board);

  unsigned long long nodes = 0;
  for (auto move : movegen.getLegalMoves()) {
    Board movedBoard = board;
    movedBoard.doMove(move);

    nodes += _perft(movedBoard, depth-1);
  }

  return nodes;
}

void Uci::_perftDivide(int depth) {
  unsigned long long total = 0;

  MoveGen movegen(_board);

  std::cout << std::endl;
  auto start = std::chrono::steady_clock::now();
  for (auto move : movegen.getLegalMoves()) {
    Board movedBoard = _board;
    movedBoard.doMove(move);

    unsigned long long perftRes = _perft(movedBoard, depth-1);
    total += perftRes;

    std::cout << move.getNotation() << ": " << perftRes << std::endl;
  }
  auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end-start;

  std::cout << std::endl << "==========================" << std::endl;
  std::cout << "Total time (ms) : " << static_cast<int>(elapsed.count() * 1000) << std::endl;
  std::cout << "Nodes searched  : " << total << std::endl;
  std::cout << "Nodes / second  : " << static_cast<int>(total / elapsed.count()) << std::endl;
}

void Uci::start() {
  std::cout << "Shallow Blue " << VER_MAJ << "." << VER_MIN << "." << VER_PATCH;
  std::cout << " by Rhys Rustad-Elliott";
  std::cout << " (built " << __DATE__ << " " << __TIME__ << ")" << std::endl;

  #ifdef __DEBUG__
    std::cout << "***DEBUG BUILD (This will be slow)***" << std::endl;
  #endif

  _board.setToStartPos();

  std::string line;
  std::string token;

  while(std::getline(std::cin, line)) {
    std::istringstream is(line);
    is >> token;

    if (token == "uci") {
      std::cout << "id name Shallow Blue" << VER_MAJ << "." << VER_MIN << "." << VER_PATCH << std::endl;
      std::cout << "id author Rhys Rustad-Elliott" << std::endl;
      std::cout << "uciok" << std::endl;
    } else if (token == "ucinewgame") {
      _uciNewGame();
    } else if (token == "isready") {
      std::cout << "readyok" << std::endl;
    } else if (token == "stop") {
      if (_search) _search->stop();
    } else if (token == "go") {
      _go(is);
    } else if (token == "quit") {
      if (_search) _search->stop();
      return;
    } else if (token == "position") {
      _setPosition(is);
    }

    // Non UCI commands
    else if (token == "printboard") {
      std::cout << std::endl << _board.getStringRep() << std::endl;
    } else if (token == "printmoves") {
      std::cout << std::endl << "Legal moves:" << std::endl;
      for (auto move : MoveGen(_board).getLegalMoves()) {
        std::cout << move.getNotation() << std::endl;
      }
    } else if (token == "perft") {
      int depth;
      is >> depth;
      _perftDivide(depth);
    }

    else {
      std::cout << "what?" << std::endl;
    }
  }
}
<commit_msg>Add missing space in uci output<commit_after>#include "uci.h"
#include "board.h"
#include "defs.h"
#include "move.h"
#include "movegen.h"
#include "search.h"
#include "version.h"
#include <iostream>
#include <thread>
#include <sstream>

void Uci::_uciNewGame(){
  _board.setToStartPos();
}

void Uci::_setPosition(std::istringstream& is) {
  std::string token;
  is >> token;

  if (token == "startpos") {
    _board.setToStartPos();
  } else {
    std::string fen;

    while (is >> token && token != "moves") {
      fen += token + " ";
    }

    _board.setToFen(fen);
  }

  while (is >> token) {
    if (token == "moves") {
      continue;
    }

    MoveGen movegen(_board);
    for (auto move : movegen.getMoves()) {
      if (move.getNotation() == token) {
        _board.doMove(move);
        break;
      }
    }
  }
}

void Uci::_pickBestMove(Search::Limits limits) {
  _search->iterDeep();
}

void Uci::_go(std::istringstream& is) {
  std::string token;
  Search::Limits limits;

  while (is >> token) {
    if (token == "depth") is >> limits.depth;
    if (token == "infinite") limits.infinite = true;
    else if (token == "nodes") is >> limits.nodes;
    else if (token == "wtime") is >> limits.time[WHITE];
    else if (token == "btime") is >> limits.time[BLACK];
    else if (token == "winc") is >> limits.increment[WHITE];
    else if (token == "binc") is >> limits.increment[BLACK];
    else if (token == "movestogo") is >> limits.movesToGo;
  }

  _search = std::shared_ptr<Search>(new Search(_board, limits));

  std::thread searchThread(&Uci::_pickBestMove, this, limits);
  searchThread.detach();
}

unsigned long long Uci::_perft(const Board& board, int depth) {
  if (depth == 0) {
    return 1;
  }

  MoveGen movegen(board);

  unsigned long long nodes = 0;
  for (auto move : movegen.getLegalMoves()) {
    Board movedBoard = board;
    movedBoard.doMove(move);

    nodes += _perft(movedBoard, depth-1);
  }

  return nodes;
}

void Uci::_perftDivide(int depth) {
  unsigned long long total = 0;

  MoveGen movegen(_board);

  std::cout << std::endl;
  auto start = std::chrono::steady_clock::now();
  for (auto move : movegen.getLegalMoves()) {
    Board movedBoard = _board;
    movedBoard.doMove(move);

    unsigned long long perftRes = _perft(movedBoard, depth-1);
    total += perftRes;

    std::cout << move.getNotation() << ": " << perftRes << std::endl;
  }
  auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end-start;

  std::cout << std::endl << "==========================" << std::endl;
  std::cout << "Total time (ms) : " << static_cast<int>(elapsed.count() * 1000) << std::endl;
  std::cout << "Nodes searched  : " << total << std::endl;
  std::cout << "Nodes / second  : " << static_cast<int>(total / elapsed.count()) << std::endl;
}

void Uci::start() {
  std::cout << "Shallow Blue " << VER_MAJ << "." << VER_MIN << "." << VER_PATCH;
  std::cout << " by Rhys Rustad-Elliott";
  std::cout << " (built " << __DATE__ << " " << __TIME__ << ")" << std::endl;

  #ifdef __DEBUG__
    std::cout << "***DEBUG BUILD (This will be slow)***" << std::endl;
  #endif

  _board.setToStartPos();

  std::string line;
  std::string token;

  while(std::getline(std::cin, line)) {
    std::istringstream is(line);
    is >> token;

    if (token == "uci") {
      std::cout << "id name Shallow Blue " << VER_MAJ << "." << VER_MIN << "." << VER_PATCH << std::endl;
      std::cout << "id author Rhys Rustad-Elliott" << std::endl;
      std::cout << "uciok" << std::endl;
    } else if (token == "ucinewgame") {
      _uciNewGame();
    } else if (token == "isready") {
      std::cout << "readyok" << std::endl;
    } else if (token == "stop") {
      if (_search) _search->stop();
    } else if (token == "go") {
      _go(is);
    } else if (token == "quit") {
      if (_search) _search->stop();
      return;
    } else if (token == "position") {
      _setPosition(is);
    }

    // Non UCI commands
    else if (token == "printboard") {
      std::cout << std::endl << _board.getStringRep() << std::endl;
    } else if (token == "printmoves") {
      std::cout << std::endl << "Legal moves:" << std::endl;
      for (auto move : MoveGen(_board).getLegalMoves()) {
        std::cout << move.getNotation() << std::endl;
      }
    } else if (token == "perft") {
      int depth;
      is >> depth;
      _perftDivide(depth);
    }

    else {
      std::cout << "what?" << std::endl;
    }
  }
}
<|endoftext|>


<commit_before>/*   This file is part of fus.
 *
 *   fus is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   fus 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 Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with fus.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "auth_private.h"
#include "core/errors.h"
#include "daemon_base.h"
#include <openssl/rand.h>
#include "protocol/auth.h"

// =================================================================================

void fus::auth_client_init(fus::auth_client_t* client)
{
    crypt_stream_init((crypt_stream_t*)client);
    client->m_flags = 0;
    client->m_loginSalt = 0;
}

// =================================================================================

static void auth_pingpong(fus::auth_client_t* client, ssize_t nread, fus::protocol::auth_pingRequest* msg)
{
    // Message reply is a bitwise copy, so we'll just throw the request back.
    size_t bufsz = fus::net_struct_calcsz(fus::protocol::auth_pingReply::net_struct) + msg->get_payloadsz();
    fus::crypt_stream_write((fus::crypt_stream_t*)client, msg, bufsz);
}

static void auth_registerClient(fus::auth_client_t* client, ssize_t nread, fus::protocol::auth_clientRegisterRequest* msg)
{
    // If a client tries to register more than once, they are obviously being nefarious.
    if (client->m_flags & e_clientRegistered)
        fus::crypt_stream_close((fus::crypt_stream_t*)client);

    RAND_bytes((unsigned char*)(&client->m_loginSalt), sizeof(client->m_loginSalt));
    client->m_flags |= e_clientRegistered;

    fus::protocol::auth_msg<fus::protocol::auth_clientRegisterReply> reply;
    reply.m_header.set_type(fus::protocol::auth2client::e_clientRegisterReply);
    reply.m_contents.set_loginSalt(client->m_loginSalt);
    fus::crypt_stream_write((fus::crypt_stream_t*)client, reply, sizeof(reply));
}

// =================================================================================

static void auth_msg_pump(fus::auth_client_t* client, ssize_t nread, fus::protocol::msg_std_header* msg)
{
    switch (msg->get_type()) {
    case fus::protocol::client2auth::e_pingRequest:
        auth_read<fus::protocol::auth_pingRequest>(client, auth_pingpong);
        break;
    case fus::protocol::client2auth::e_clientRegisterRequest:
        auth_read<fus::protocol::auth_clientRegisterRequest>(client, auth_registerClient);
        break;
    default:
        /// fixme
        fus::crypt_stream_close((fus::crypt_stream_t*)client);
    }
}

void fus::auth_client_read(fus::auth_client_t* client)
{
    auth_read<protocol::msg_std_header>(client, auth_msg_pump);
}
<commit_msg>Fix incorrect auth pong<commit_after>/*   This file is part of fus.
 *
 *   fus is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   fus 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 Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with fus.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "auth_private.h"
#include "core/errors.h"
#include "daemon_base.h"
#include <openssl/rand.h>
#include "protocol/auth.h"

// =================================================================================

void fus::auth_client_init(fus::auth_client_t* client)
{
    crypt_stream_init((crypt_stream_t*)client);
    client->m_flags = 0;
    client->m_loginSalt = 0;
}

// =================================================================================

static void auth_pingpong(fus::auth_client_t* client, ssize_t nread, fus::protocol::auth_pingRequest* msg)
{
    fus::protocol::msg_std_header header;
    header.set_type(fus::protocol::auth2client::e_pingReply);
    fus::crypt_stream_write((fus::crypt_stream_t*)client, &header, sizeof(header));

    // Message reply is a bitwise copy, so we'll just throw the request back.
    fus::crypt_stream_write((fus::crypt_stream_t*)client, msg, nread);
}

static void auth_registerClient(fus::auth_client_t* client, ssize_t nread, fus::protocol::auth_clientRegisterRequest* msg)
{
    // If a client tries to register more than once, they are obviously being nefarious.
    if (client->m_flags & e_clientRegistered)
        fus::crypt_stream_close((fus::crypt_stream_t*)client);

    RAND_bytes((unsigned char*)(&client->m_loginSalt), sizeof(client->m_loginSalt));
    client->m_flags |= e_clientRegistered;

    fus::protocol::auth_msg<fus::protocol::auth_clientRegisterReply> reply;
    reply.m_header.set_type(fus::protocol::auth2client::e_clientRegisterReply);
    reply.m_contents.set_loginSalt(client->m_loginSalt);
    fus::crypt_stream_write((fus::crypt_stream_t*)client, reply, sizeof(reply));
}

// =================================================================================

static void auth_msg_pump(fus::auth_client_t* client, ssize_t nread, fus::protocol::msg_std_header* msg)
{
    switch (msg->get_type()) {
    case fus::protocol::client2auth::e_pingRequest:
        auth_read<fus::protocol::auth_pingRequest>(client, auth_pingpong);
        break;
    case fus::protocol::client2auth::e_clientRegisterRequest:
        auth_read<fus::protocol::auth_clientRegisterRequest>(client, auth_registerClient);
        break;
    default:
        /// fixme
        fus::crypt_stream_close((fus::crypt_stream_t*)client);
    }
}

void fus::auth_client_read(fus::auth_client_t* client)
{
    auth_read<protocol::msg_std_header>(client, auth_msg_pump);
}
<|endoftext|>


<commit_before>
#include "vm.hpp"

#define JUMP(pos) loc = codes + pos
#define SKIP ++loc; if( Compiler::hasOperand(*loc) ) ++loc
#define RUN loc = codes + length + 1
#define LOC loc - codes
#define LLOC loc - sloc
#define RLOC sloc - codes
#define CODE (*loc)
#define OP (*(1 + loc))
#define HADOP ++loc;

#define _EPUSH(v) stack[stackSize++] = v
#define _EPOP stack[--stackSize]
#define _ETOP stack[stackSize - 1]
#define _ETOP1 stack[stackSize - 2]

#define _DPUSH(v) dataStack[dataStackSize++] = v
#define _DPOP dataStack[--dataStackSize]
#define _DTOP dataStack[dataStackSize - 1]
#define _DSEARCH(v) this->search(dataStackSize, v)
#define _DSEARCHNR(v) this->searchnr(dataStackSize, v)

#ifdef DEBUG
#define DBGHEAD printf("%03ld: %03ld: %-8s\t", LOC, LLOC, Compiler::opcodeName(*loc))
#define DBG(...) printf(__VA_ARGS__)
#define DBGFOOT printf("\n");
#else
#define DBGHEAD
#define DBG(...)
#define DBGFOOT
#endif

namespace mustache {

std::string * VM::execute(uint8_t * codes, size_t length, Data * data)
{
  std::string * output = new std::string;
  execute(codes, length, data, output);
  return output;
}

void VM::execute(std::vector<uint8_t> * codes, Data * data, std::string * output)
{
#ifdef HAVE_CXX11
  execute(codes->data(), codes->size(), data, output);
#else
  uint8_t * codes_buf = NULL;
  size_t codes_length = 0;
  Compiler::vectorToBuffer(codes, &codes_buf, &codes_length);
  execute(codes_buf, codes_length, data, output);
  free(codes_buf);
#endif
}

void VM::execute(uint8_t * codes, size_t length, Data * data, std::string * output)
{
  register uint8_t * loc = codes;
  register uint8_t * end = codes + length;
  register uint8_t * sloc = loc;
  register uint32_t * symbols = NULL;
  register uint32_t * stack = this->stack;
  register uint32_t stackSize = 0;
  register Data ** dataStack = this->dataStack;
  register uint32_t dataStackSize = 0;

  // Clear the output buffer
  outputBuffer.clear();

  // Push the initial data onto the data stack
  _DPUSH(data);

  // Read the symbol table
  {
    uint32_t nSymbols = _UNPACK4A(loc, 0);
    uint32_t i;
    loc += 4;
    symbols = (uint32_t *) malloc(sizeof(uint32_t) * nSymbols);
    for( i = 0; i < nSymbols; i++ ) {
      symbols[i] = _UNPACK4A(loc, 0);
      DBG("Symbol %d @ %u\n", i, symbols[i]);
      loc += 4;
    }
  }

  // Jump to main
  sloc = loc = codes + symbols[0] + 2;

  // First thing to put on stack is code past the end of length so that the VM
  // will terminate when returning from main
  _EPUSH(LOC);
  _EPUSH(length + 1);

  for( ; loc < end; loc++ ) {
    DBGHEAD;
    switch( CODE ) {
      /** Basic operations -------------------------------------------------- */
      case opcodes::PRINTL:
        DBG("Jump: %u", OP);
        outputBuffer.append((const char *) (codes + OP));
        HADOP;
        break;
      case opcodes::PRINTSYM:
        DBG("Symbol: %u, Jump: %u", OP, symbols[OP]);
        outputBuffer.append((const char *) (codes + symbols[OP] + 2)); // Need 2 to skip symbol name and type marker
        HADOP;
        break;
      case opcodes::CALL:
        DBG("Push: %ld, Jump: %u", LOC, OP);
        _EPUSH(RLOC);
        _EPUSH(LOC + _COPERANDSIZE);
        JUMP(OP - 1);  // Need -1 so increment on loop will cancel out
        // Don't need HADOP because JUMP
        sloc = loc + 1;
        break;
      case opcodes::CALLSYM:
        DBG("Symbol: %d, Push: %ld, Jump: %u", OP, LOC, symbols[OP]);
        _EPUSH(RLOC);
        _EPUSH(LOC + _COPERANDSIZE);
        JUMP(symbols[OP] + 2 - 1);  // Need -1 so increment on loop will cancel out
        // Don't need HADOP because JUMP
        sloc = loc + 1;
        break;
      case opcodes::RETURN:
        DBG("Jump: %lu", _ETOP);
        JUMP(_EPOP);
        sloc = codes + _EPOP;
        break;
      case opcodes::JUMP:
        DBG("Jump: %u", OP);
        JUMP(OP - 1); // -1 to cancel out the next loop increment
        // Don't need HADOP because JUMP
        break;
      case opcodes::JUMPL:
        DBG("Jump: %u", (RLOC) + OP);
        JUMP((RLOC) + OP - 1); // -1 to cancel out the next loop increment
        // Don't need HADOP because JUMP
        break;
      case opcodes::PUSH:
        DBG("Push: %u", *(1 + loc));
        _EPUSH(OP);
        HADOP;
        break;
      case opcodes::POP:
        DBG("Top: %lu", _ETOP);
        _EPOP;
        break;
      case opcodes::INCR:
        DBG("%lu+1", _ETOP);
        _ETOP++;
        break;
      case opcodes::IF_GE:
        DBG("%ld >= %ld", _ETOP, _ETOP1);
        if( _ETOP >= _ETOP1 ) {
          DBG(", GE");
        } else {
          DBG(", !GE");
          SKIP;
        }
        break;

      /** Data operations --------------------------------------------------- */
//      case opcodes::DPUSH:
//        DBG("Top %p", (Data *) _ETOP);
//        _DPUSH((Data *) _ETOP);
//        break;
      case opcodes::DPOP:
        DBG("DTop: %p", (Data *) _DTOP);
        _DPOP;
        break;
      case opcodes::DLOOKUP: {
        DBG("Symbol: %u", OP);
        const char * cstr = (const char *) (codes + OP);
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCH(&lookupstr));
        _DPUSH(_DSEARCH(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPSYM: {
        DBG("Symbol: %u, Jump: %d", OP, symbols[OP]);
        const char * cstr = (const char *) (codes + symbols[OP] + 2); // Need 2 to skip symbol name and type
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCH(&lookupstr));
        _DPUSH(_DSEARCH(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPNR: {
        DBG("Symbol: %u", *(1 + loc));
        char * cstr = (/*unsigned*/ char *) (codes + OP);
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCHNR(&lookupstr));
        _DPUSH(_DSEARCHNR(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPNRSYM: {
        DBG("Symbol: %u, Jump: %d", OP, symbols[OP]);
        const char * cstr = (const char *) (codes + symbols[OP] + 2); // Need 2 to skip symbol name and type
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCHNR(&lookupstr));
        _DPUSH(_DSEARCHNR(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPA: {
        DBG("Index: %lu, DPush: %p", _ETOP, _DTOP->array + _ETOP);
        _DPUSH(_DTOP->array + _ETOP);
        break;
      }
      case opcodes::DARRSIZE:
        if( _DTOP != NULL && _DTOP->type == Data::TypeArray ) {
          _EPUSH(_DTOP->length);
        } else {
          _EPUSH(0);
        }
        DBG("Size: %lu", _ETOP);
        break;
      case opcodes::DPRINT:
        DBG("DTop: %p", _DTOP);
        if( _DTOP != NULL && _DTOP->type == Data::TypeString ) {
          outputBuffer.append(*(_DTOP->val));
        }
        break;
      case opcodes::DPRINTE:
        DBG("DTop: %p", _DTOP);
        if( _DTOP != NULL && _DTOP->type == Data::TypeString ) {
          htmlspecialchars_append((_DTOP->val), &outputBuffer);
        }
        break;

      /** Data conditionals ------------------------------------------------- */
      case opcodes::DIF_EMPTY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->isEmpty() ) {
          DBG(", empty");
        } else {
          DBG(", not empty");
          SKIP;
        }
        break;
      case opcodes::DIF_NOTEMPTY:
        DBG("DTop %p", _DTOP);
        if( _DTOP != NULL && !_DTOP->isEmpty() ) {
          DBG(", not empty");
        } else {
          DBG(", empty");
          SKIP;
        }
        break;
      case opcodes::DIF_HASH:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeMap ) {
          DBG(", not hash");
          SKIP;
        } else {
          DBG(", hash");
        }
        break;
      case opcodes::DIF_NOTHASH:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeMap ) {
          DBG(", not hash");
        } else {
          DBG(", hash");
          SKIP;
        }
        break;
      case opcodes::DIF_ARRAY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeArray ) {
          DBG(", not array");
          SKIP;
        } else {
          DBG(", array");
        }
        break;
      case opcodes::DIF_NOTARRAY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeArray ) {
          DBG(", not array");
        } else {
          DBG(", array");
          SKIP;
        }
        break;

      /** Unknown ----------------------------------------------------------- */
      case opcodes::CALLEXT:
        DBG("NOT IMPLEMENTED %d\n", OP);
        HADOP;
        break;
      case opcodes::NOOP:
        DBG("Jump: %d", length + 1);
        JUMP(length + 1);
        break;
      default:
        DBG("UNKNOWN 0x%02x\n", CODE);
        break;
    }
    DBGFOOT;
  }

  // Copy the internal output buffer to the output
  output->assign(outputBuffer);

  // Free
  free(symbols);
}

Data * VM::search(uint32_t dataStackSize, std::string * key)
{
  // Resolve up the data stack
  Data * ref = NULL;
  Data::Map::iterator d_it;
  register Data ** _stackPos = this->dataStack + dataStackSize - 1;
  register int i;
  for( i = 0; i < dataStackSize; i++, _stackPos-- ) {
    if( (*_stackPos) == NULL ) continue;
    if( (*_stackPos)->type != Data::TypeMap ) continue;

    d_it = (*_stackPos)->data.find(*key);
    if( d_it != (*_stackPos)->data.end() ) {
      ref = d_it->second;
      if( ref != NULL ) {
        break;
      }
    }
  }
  return ref;
}

Data * VM::searchnr(uint32_t dataStackSize, std::string * key)
{
  Data * back = this->dataStack[dataStackSize - 1];
  if( back == NULL || back->type != Data::TypeMap ) {
    return NULL;
  }

  Data * ref = NULL;
  Data::Map::iterator d_it = back->data.find(*key);
  if( d_it != back->data.end() ) {
    ref = d_it->second;
    if( ref != NULL ) {
      return ref;
    }
  }

  return NULL;
}

}
<commit_msg>Few more VM macro adjustments<commit_after>
#include "vm.hpp"

#define JUMP(pos) loc = codes + pos
#define SKIP ++loc; if( Compiler::hasOperand(*loc) ) loc += _COPERANDSIZE
#define RUN loc = codes + length + 1
#define LOC loc - codes
#define LLOC loc - sloc
#define RLOC sloc - codes
#define CODE (*loc)
#define OP _COPERANDUNPACKA(loc, 1)
#define HADOP loc += _COPERANDSIZE;

#define _EPUSH(v) stack[stackSize++] = v
#define _EPOP stack[--stackSize]
#define _ETOP stack[stackSize - 1]
#define _ETOP1 stack[stackSize - 2]

#define _DPUSH(v) dataStack[dataStackSize++] = v
#define _DPOP dataStack[--dataStackSize]
#define _DTOP dataStack[dataStackSize - 1]
#define _DSEARCH(v) this->search(dataStackSize, v)
#define _DSEARCHNR(v) this->searchnr(dataStackSize, v)

#ifdef DEBUG
#define DBGHEAD printf("%03ld: %03ld: %-8s\t", LOC, LLOC, Compiler::opcodeName(*loc))
#define DBG(...) printf(__VA_ARGS__)
#define DBGFOOT printf("\n");
#else
#define DBGHEAD
#define DBG(...)
#define DBGFOOT
#endif

namespace mustache {

std::string * VM::execute(uint8_t * codes, size_t length, Data * data)
{
  std::string * output = new std::string;
  execute(codes, length, data, output);
  return output;
}

void VM::execute(std::vector<uint8_t> * codes, Data * data, std::string * output)
{
#ifdef HAVE_CXX11
  execute(codes->data(), codes->size(), data, output);
#else
  uint8_t * codes_buf = NULL;
  size_t codes_length = 0;
  Compiler::vectorToBuffer(codes, &codes_buf, &codes_length);
  execute(codes_buf, codes_length, data, output);
  free(codes_buf);
#endif
}

void VM::execute(uint8_t * codes, size_t length, Data * data, std::string * output)
{
  register uint8_t * loc = codes;
  register uint8_t * end = codes + length;
  register uint8_t * sloc = loc;
  register uint32_t * symbols = NULL;
  register uint32_t * stack = this->stack;
  register uint32_t stackSize = 0;
  register Data ** dataStack = this->dataStack;
  register uint32_t dataStackSize = 0;

  // Clear the output buffer
  outputBuffer.clear();

  // Push the initial data onto the data stack
  _DPUSH(data);

  // Read the symbol table
  {
    uint32_t nSymbols = _UNPACK4A(loc, 0);
    uint32_t i;
    loc += 4;
    symbols = (uint32_t *) malloc(sizeof(uint32_t) * nSymbols);
    for( i = 0; i < nSymbols; i++ ) {
      symbols[i] = _UNPACK4A(loc, 0);
      DBG("Symbol %d @ %u\n", i, symbols[i]);
      loc += 4;
    }
  }

  // Jump to main
  sloc = loc = codes + symbols[0] + 2;

  // First thing to put on stack is code past the end of length so that the VM
  // will terminate when returning from main
  _EPUSH(LOC);
  _EPUSH(length + 1);

  for( ; loc < end; loc++ ) {
    DBGHEAD;
    switch( CODE ) {
      /** Basic operations -------------------------------------------------- */
      case opcodes::PRINTL:
        DBG("Jump: %u", OP);
        outputBuffer.append((const char *) (codes + OP));
        HADOP;
        break;
      case opcodes::PRINTSYM:
        DBG("Symbol: %u, Jump: %u", OP, symbols[OP]);
        outputBuffer.append((const char *) (codes + symbols[OP] + 2)); // Need 2 to skip symbol name and type marker
        HADOP;
        break;
      case opcodes::CALL:
        DBG("Push: %ld, Jump: %u", LOC, OP);
        _EPUSH(RLOC);
        _EPUSH(LOC + _COPERANDSIZE);
        JUMP(OP - 1);  // Need -1 so increment on loop will cancel out
        // Don't need HADOP because JUMP
        sloc = loc + 1;
        break;
      case opcodes::CALLSYM:
        DBG("Symbol: %d, Push: %ld, Jump: %u", OP, LOC, symbols[OP]);
        _EPUSH(RLOC);
        _EPUSH(LOC + _COPERANDSIZE);
        JUMP(symbols[OP] + 2 - 1);  // Need -1 so increment on loop will cancel out
        // Don't need HADOP because JUMP
        sloc = loc + 1;
        break;
      case opcodes::RETURN:
        DBG("Jump: %lu", _ETOP);
        JUMP(_EPOP);
        sloc = codes + _EPOP;
        break;
      case opcodes::JUMP:
        DBG("Jump: %u", OP);
        JUMP(OP - 1); // -1 to cancel out the next loop increment
        // Don't need HADOP because JUMP
        break;
      case opcodes::JUMPL:
        DBG("Jump: %u", (RLOC) + OP);
        JUMP((RLOC) + OP - 1); // -1 to cancel out the next loop increment
        // Don't need HADOP because JUMP
        break;
      case opcodes::PUSH:
        DBG("Push: %u", *(1 + loc));
        _EPUSH(OP);
        HADOP;
        break;
      case opcodes::POP:
        DBG("Top: %lu", _ETOP);
        _EPOP;
        break;
      case opcodes::INCR:
        DBG("%lu+1", _ETOP);
        _ETOP++;
        break;
      case opcodes::IF_GE:
        DBG("%ld >= %ld", _ETOP, _ETOP1);
        if( _ETOP >= _ETOP1 ) {
          DBG(", GE");
        } else {
          DBG(", !GE");
          SKIP;
        }
        break;

      /** Data operations --------------------------------------------------- */
//      case opcodes::DPUSH:
//        DBG("Top %p", (Data *) _ETOP);
//        _DPUSH((Data *) _ETOP);
//        break;
      case opcodes::DPOP:
        DBG("DTop: %p", (Data *) _DTOP);
        _DPOP;
        break;
      case opcodes::DLOOKUP: {
        DBG("Symbol: %u", OP);
        const char * cstr = (const char *) (codes + OP);
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCH(&lookupstr));
        _DPUSH(_DSEARCH(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPSYM: {
        DBG("Symbol: %u, Jump: %d", OP, symbols[OP]);
        const char * cstr = (const char *) (codes + symbols[OP] + 2); // Need 2 to skip symbol name and type
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCH(&lookupstr));
        _DPUSH(_DSEARCH(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPNR: {
        DBG("Symbol: %u", *(1 + loc));
        char * cstr = (/*unsigned*/ char *) (codes + OP);
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCHNR(&lookupstr));
        _DPUSH(_DSEARCHNR(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPNRSYM: {
        DBG("Symbol: %u, Jump: %d", OP, symbols[OP]);
        const char * cstr = (const char *) (codes + symbols[OP] + 2); // Need 2 to skip symbol name and type
        DBG(", String: %s", cstr);
        lookupstr.assign(cstr);
        DBG(", DPush: %p", _DSEARCHNR(&lookupstr));
        _DPUSH(_DSEARCHNR(&lookupstr));
        HADOP;
        break;
      }
      case opcodes::DLOOKUPA: {
        DBG("Index: %lu, DPush: %p", _ETOP, _DTOP->array + _ETOP);
        _DPUSH(_DTOP->array + _ETOP);
        break;
      }
      case opcodes::DARRSIZE:
        if( _DTOP != NULL && _DTOP->type == Data::TypeArray ) {
          _EPUSH(_DTOP->length);
        } else {
          _EPUSH(0);
        }
        DBG("Size: %lu", _ETOP);
        break;
      case opcodes::DPRINT:
        DBG("DTop: %p", _DTOP);
        if( _DTOP != NULL && _DTOP->type == Data::TypeString ) {
          outputBuffer.append(*(_DTOP->val));
        }
        break;
      case opcodes::DPRINTE:
        DBG("DTop: %p", _DTOP);
        if( _DTOP != NULL && _DTOP->type == Data::TypeString ) {
          htmlspecialchars_append((_DTOP->val), &outputBuffer);
        }
        break;

      /** Data conditionals ------------------------------------------------- */
      case opcodes::DIF_EMPTY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->isEmpty() ) {
          DBG(", empty");
        } else {
          DBG(", not empty");
          SKIP;
        }
        break;
      case opcodes::DIF_NOTEMPTY:
        DBG("DTop %p", _DTOP);
        if( _DTOP != NULL && !_DTOP->isEmpty() ) {
          DBG(", not empty");
        } else {
          DBG(", empty");
          SKIP;
        }
        break;
      case opcodes::DIF_HASH:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeMap ) {
          DBG(", not hash");
          SKIP;
        } else {
          DBG(", hash");
        }
        break;
      case opcodes::DIF_NOTHASH:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeMap ) {
          DBG(", not hash");
        } else {
          DBG(", hash");
          SKIP;
        }
        break;
      case opcodes::DIF_ARRAY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeArray ) {
          DBG(", not array");
          SKIP;
        } else {
          DBG(", array");
        }
        break;
      case opcodes::DIF_NOTARRAY:
        DBG("DTop %p", _DTOP);
        if( _DTOP == NULL || _DTOP->type != Data::TypeArray ) {
          DBG(", not array");
        } else {
          DBG(", array");
          SKIP;
        }
        break;

      /** Unknown ----------------------------------------------------------- */
      case opcodes::CALLEXT:
        DBG("NOT IMPLEMENTED %d\n", OP);
        HADOP;
        break;
      case opcodes::NOOP:
        DBG("Jump: %d", length + 1);
        JUMP(length + 1);
        break;
      default:
        DBG("UNKNOWN 0x%02x\n", CODE);
        break;
    }
    DBGFOOT;
  }

  // Copy the internal output buffer to the output
  output->assign(outputBuffer);

  // Free
  free(symbols);
}

Data * VM::search(uint32_t dataStackSize, std::string * key)
{
  // Resolve up the data stack
  Data * ref = NULL;
  Data::Map::iterator d_it;
  register Data ** _stackPos = this->dataStack + dataStackSize - 1;
  register int i;
  for( i = 0; i < dataStackSize; i++, _stackPos-- ) {
    if( (*_stackPos) == NULL ) continue;
    if( (*_stackPos)->type != Data::TypeMap ) continue;

    d_it = (*_stackPos)->data.find(*key);
    if( d_it != (*_stackPos)->data.end() ) {
      ref = d_it->second;
      if( ref != NULL ) {
        break;
      }
    }
  }
  return ref;
}

Data * VM::searchnr(uint32_t dataStackSize, std::string * key)
{
  Data * back = this->dataStack[dataStackSize - 1];
  if( back == NULL || back->type != Data::TypeMap ) {
    return NULL;
  }

  Data * ref = NULL;
  Data::Map::iterator d_it = back->data.find(*key);
  if( d_it != back->data.end() ) {
    ref = d_it->second;
    if( ref != NULL ) {
      return ref;
    }
  }

  return NULL;
}

}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <iostream>
#include <mutex>

#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/Execution/SignalHandlers.h"
#include "Stroika/Foundation/Execution/WaitableEvent.h"
#include "Stroika/Foundation/IO/Network/Transfer/Client.h"

#include "Stroika/Frameworks/UPnP/DeviceDescription.h"
#include "Stroika/Frameworks/UPnP/SSDP/Client/Listener.h"
#include "Stroika/Frameworks/UPnP/SSDP/Client/Search.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Frameworks::UPnP;
using namespace Stroika::Frameworks::UPnP::SSDP;

using Characters::String;
using Client::Listener;
using Client::Search;
using Containers::Sequence;

namespace {
    mutex kStdOutMutex_; // If the listener impl uses multiple listen threads, prevent display from getting messed up
}

namespace {
    // Ignore if fails
    void DoPrintDeviceDescription_ (const URI& deviceDescriptionURL)
    {
        try {
            using namespace IO::Network::Transfer;
            Connection::Ptr c = IO::Network::Transfer::CreateConnection ();
            Response        r = c.GET (deviceDescriptionURL);
            if (r.GetSucceeded ()) {
                DeviceDescription deviceInfo = DeSerialize (r.GetData ());
                cout << "\t\tDevice-Decsciption: " << Characters::ToString (deviceInfo).AsNarrowSDKString () << endl;
            }
        }
        catch (...) {
            DbgTrace (L"failed to fetch description: %s", Characters::ToString (current_exception ()).c_str ());
        }
    }
}

namespace {
    void DoListening_ (Listener* l)
    {
        cout << "Listening..." << endl;
        l->AddOnFoundCallback ([] (const SSDP::Advertisement& d) {
            lock_guard<mutex> critSection (kStdOutMutex_);
            cout << "\tFound device (NOTIFY):" << endl;
            cout << "\t\tUSN:      " << d.fUSN.AsUTF8 () << endl;
            if (d.fAlive.has_value ()) {
                cout << "\t\tAlive:    " << (*d.fAlive ? "true" : "false") << endl;
            }
            cout << "\t\tST:       " << d.fTarget.AsUTF8 () << endl;
            cout << "\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8 () << endl;
            if (not d.fServer.empty ()) {
                cout << "\t\tServer:   " << d.fServer.AsUTF8 () << endl;
            }
            DoPrintDeviceDescription_ (d.fLocation);
            cout << endl;
        });
        l->Start ();
    }
}

namespace {
    void DoSearching_ (Search* searcher, const String& searchFor)
    {
        cout << "Searching for '" << searchFor.AsUTF8 () << "'..." << endl;
        searcher->AddOnFoundCallback ([] (const SSDP::Advertisement& d) {
            lock_guard<mutex> critSection (kStdOutMutex_);
            cout << "\tFound device (MATCHED SEARCH):" << endl;
            cout << "\t\tUSN:      " << d.fUSN.AsUTF8 () << endl;
            cout << "\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8 () << endl;
            cout << "\t\tST:       " << d.fTarget.AsUTF8 () << endl;
            if (not d.fServer.empty ()) {
                cout << "\t\tServer:   " << d.fServer.AsUTF8 () << endl;
            }
            DoPrintDeviceDescription_ (d.fLocation);
            cout << endl;
        });
        searcher->Start (searchFor);
    }
}

int main (int argc, const char* argv[])
{
    Debug::TraceContextBumper ctx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"main", L"argv=%s", Characters::ToString (vector<const char*>{argv, argv + argc}).c_str ())};
#if qPlatform_POSIX
    Execution::SignalHandlerRegistry::Get ().SetSignalHandlers (SIGPIPE, Execution::SignalHandlerRegistry::kIGNORED);
#endif
    bool             listen = false;
    optional<String> searchFor;

    Sequence<String> args = Execution::ParseCommandLine (argc, argv);
    for (auto argi = args.begin (); argi != args.end (); ++argi) {
        if (Execution::MatchesCommandLineArgument (*argi, L"l")) {
            listen = true;
        }
        if (Execution::MatchesCommandLineArgument (*argi, L"s")) {
            ++argi;
            if (argi != args.end ()) {
                searchFor = *argi;
            }
            else {
                cerr << "Expected arg to -s" << endl;
                return EXIT_FAILURE;
            }
        }
    }
    if (not listen and not searchFor.has_value ()) {
        cerr << "Usage: SSDPClient [-l] [-s SEARCHFOR]" << endl;
        cerr << "   e.g. SSDPClient -l" << endl;
        cerr << "   e.g. SSDPClient -s \"upnp:rootdevice\"" << endl;
        return EXIT_FAILURE;
    }

    try {
        Listener l;
        if (listen) {
            DoListening_ (&l);
        }
        Search s;
        if (searchFor.has_value ()) {
            DoSearching_ (&s, *searchFor);
        }

        if (listen or searchFor.has_value ()) {
            Execution::WaitableEvent{}.Wait (); // wait forever - til user hits ctrl-c
        }
        else {
            cerr << "Specify -l to listen or -s STRING to search" << endl;
            return EXIT_FAILURE;
        }
    }
    catch (...) {
        String exceptMsg = Characters::ToString (current_exception ());
        cerr << "Exception - " << exceptMsg.AsNarrowSDKString () << " - terminating..." << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<commit_msg>cleanup<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <iostream>
#include <mutex>

#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/Execution/SignalHandlers.h"
#include "Stroika/Foundation/Execution/WaitableEvent.h"
#include "Stroika/Foundation/IO/Network/Transfer/Client.h"

#include "Stroika/Frameworks/UPnP/DeviceDescription.h"
#include "Stroika/Frameworks/UPnP/SSDP/Client/Listener.h"
#include "Stroika/Frameworks/UPnP/SSDP/Client/Search.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Frameworks::UPnP;
using namespace Stroika::Frameworks::UPnP::SSDP;

using Characters::String;
using Client::Listener;
using Client::Search;
using Containers::Sequence;

namespace {
    mutex kStdOutMutex_; // If the listener impl uses multiple listen threads, prevent display from getting messed up
}

namespace {
    // Ignore if fails
    void DoPrintDeviceDescription_ (const URI& deviceDescriptionURL)
    {
        try {
            using namespace IO::Network::Transfer;
            Connection::Ptr c = Connection::New ();
            Response        r = c.GET (deviceDescriptionURL);
            if (r.GetSucceeded ()) {
                DeviceDescription deviceInfo = DeSerialize (r.GetData ());
                cout << "\t\tDevice-Decsciption: " << Characters::ToString (deviceInfo).AsNarrowSDKString () << endl;
            }
        }
        catch (...) {
            DbgTrace (L"failed to fetch description: %s", Characters::ToString (current_exception ()).c_str ());
        }
    }
}

namespace {
    void DoListening_ (Listener* l)
    {
        cout << "Listening..." << endl;
        l->AddOnFoundCallback ([] (const SSDP::Advertisement& d) {
            lock_guard<mutex> critSection (kStdOutMutex_);
            cout << "\tFound device (NOTIFY):" << endl;
            cout << "\t\tUSN:      " << d.fUSN.AsUTF8 () << endl;
            if (d.fAlive.has_value ()) {
                cout << "\t\tAlive:    " << (*d.fAlive ? "true" : "false") << endl;
            }
            cout << "\t\tST:       " << d.fTarget.AsUTF8 () << endl;
            cout << "\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8 () << endl;
            if (not d.fServer.empty ()) {
                cout << "\t\tServer:   " << d.fServer.AsUTF8 () << endl;
            }
            DoPrintDeviceDescription_ (d.fLocation);
            cout << endl;
        });
        l->Start ();
    }
}

namespace {
    void DoSearching_ (Search* searcher, const String& searchFor)
    {
        cout << "Searching for '" << searchFor.AsUTF8 () << "'..." << endl;
        searcher->AddOnFoundCallback ([] (const SSDP::Advertisement& d) {
            lock_guard<mutex> critSection (kStdOutMutex_);
            cout << "\tFound device (MATCHED SEARCH):" << endl;
            cout << "\t\tUSN:      " << d.fUSN.AsUTF8 () << endl;
            cout << "\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8 () << endl;
            cout << "\t\tST:       " << d.fTarget.AsUTF8 () << endl;
            if (not d.fServer.empty ()) {
                cout << "\t\tServer:   " << d.fServer.AsUTF8 () << endl;
            }
            DoPrintDeviceDescription_ (d.fLocation);
            cout << endl;
        });
        searcher->Start (searchFor);
    }
}

int main (int argc, const char* argv[])
{
    Debug::TraceContextBumper ctx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"main", L"argv=%s", Characters::ToString (vector<const char*>{argv, argv + argc}).c_str ())};
#if qPlatform_POSIX
    Execution::SignalHandlerRegistry::Get ().SetSignalHandlers (SIGPIPE, Execution::SignalHandlerRegistry::kIGNORED);
#endif
    bool             listen = false;
    optional<String> searchFor;

    Sequence<String> args = Execution::ParseCommandLine (argc, argv);
    for (auto argi = args.begin (); argi != args.end (); ++argi) {
        if (Execution::MatchesCommandLineArgument (*argi, L"l")) {
            listen = true;
        }
        if (Execution::MatchesCommandLineArgument (*argi, L"s")) {
            ++argi;
            if (argi != args.end ()) {
                searchFor = *argi;
            }
            else {
                cerr << "Expected arg to -s" << endl;
                return EXIT_FAILURE;
            }
        }
    }
    if (not listen and not searchFor.has_value ()) {
        cerr << "Usage: SSDPClient [-l] [-s SEARCHFOR]" << endl;
        cerr << "   e.g. SSDPClient -l" << endl;
        cerr << "   e.g. SSDPClient -s \"upnp:rootdevice\"" << endl;
        return EXIT_FAILURE;
    }

    try {
        Listener l;
        if (listen) {
            DoListening_ (&l);
        }
        Search s;
        if (searchFor.has_value ()) {
            DoSearching_ (&s, *searchFor);
        }

        if (listen or searchFor.has_value ()) {
            Execution::WaitableEvent{}.Wait (); // wait forever - til user hits ctrl-c
        }
        else {
            cerr << "Specify -l to listen or -s STRING to search" << endl;
            return EXIT_FAILURE;
        }
    }
    catch (...) {
        String exceptMsg = Characters::ToString (current_exception ());
        cerr << "Exception - " << exceptMsg.AsNarrowSDKString () << " - terminating..." << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<|endoftext|>