<commit_before>//
// ogrfielddefn.cc
//
//
// Copyright (c) 2011, JF Gigand
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#include "php.h"
#include "php_gdal.h"
#include <ogr_feature.h>
#include "ogrfielddefn.h"

zend_class_entry *gdal_ogrfielddefn_ce;
zend_object_handlers ogrfielddefn_object_handlers;

//
// PHP stuff
//

void ogrfielddefn_free_storage(void *object TSRMLS_DC)
{
  php_ogrfielddefn_object *obj = (php_ogrfielddefn_object *)object;
  //delete obj->fielddefn; // TODO
  zend_hash_destroy(obj->std.properties);
  FREE_HASHTABLE(obj->std.properties);
  efree(obj);
}

zend_object_value ogrfielddefn_create_handler(zend_class_entry *type TSRMLS_DC)
{
  zval *tmp;
  zend_object_value retval;

  php_ogrfielddefn_object *obj =
    (php_ogrfielddefn_object *)emalloc(sizeof(php_ogrfielddefn_object));
  memset(obj, 0, sizeof(php_ogrfielddefn_object));
  obj->std.ce = type;

  ALLOC_HASHTABLE(obj->std.properties);
  zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
  zend_hash_copy(obj->std.properties, &type->default_properties,
                 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
      object_properties_init(&obj->std, type);
#endif

  retval.handle = zend_objects_store_put(obj, NULL,
                                         ogrfielddefn_free_storage, NULL TSRMLS_CC);
  retval.handlers = &ogrfielddefn_object_handlers;

  return retval;

  //pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args TSRMLS_CC);

}

//
// CLASS METHODS
//

PHP_METHOD(OGRFieldDefn, SetName)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  char *name;
  int name_len;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"s",
                            &name, &name_len) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;

  fielddefn->SetName(name);
}

PHP_METHOD(OGRFieldDefn, GetNameRef)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;

  const char *name = fielddefn->GetNameRef();
  if (name) {
    RETURN_STRING((char *)name, 1);
  } else {
    RETURN_NULL();
  }
}

PHP_METHOD(OGRFieldDefn, GetType)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG((long)fielddefn->GetType());
}

PHP_METHOD(OGRFieldDefn, SetType)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long type;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &type) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetType((OGRFieldType)type);
}

PHP_METHOD(OGRFieldDefn, GetJustify)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG((long)fielddefn->GetJustify());
}

PHP_METHOD(OGRFieldDefn, SetJustify)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long justification;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &justification) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetJustify((OGRJustification)justification);
}

PHP_METHOD(OGRFieldDefn, GetWidth)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG(fielddefn->GetWidth());
}

PHP_METHOD(OGRFieldDefn, SetWidth)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long width;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &width) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetWidth(width);
}

PHP_METHOD(OGRFieldDefn, GetPrecision)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG(fielddefn->GetPrecision());
}

PHP_METHOD(OGRFieldDefn, SetPrecision)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long precision;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &precision) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetPrecision(precision);
}

//
// PHP stuff
//

zend_function_entry ogrfielddefn_methods[] = {
  PHP_ME(OGRFieldDefn, SetName,                 NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetNameRef,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetType,                 NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetType,                 NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, GetFieldTypeName,        NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetJustify,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetJustify,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetWidth,                NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetWidth,                NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetPrecision,            NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetPrecision,            NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, Set,                     NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, SetDefault,              NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, GetDefaultRef,           NULL, ZEND_ACC_PUBLIC)
  {NULL, NULL, NULL}
};

void php_gdal_ogrfielddefn_startup(INIT_FUNC_ARGS)
{
  zend_class_entry ce;
  INIT_CLASS_ENTRY(ce, "OGRFieldDefn", ogrfielddefn_methods);
  gdal_ogrfielddefn_ce = zend_register_internal_class(&ce TSRMLS_CC);
  gdal_ogrfielddefn_ce->create_object = ogrfielddefn_create_handler;
  memcpy(&ogrfielddefn_object_handlers,
         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  ogrfielddefn_object_handlers.clone_obj = NULL;
}
<commit_msg>Constructor with name and field type for OGRFieldDefn<commit_after>//
// ogrfielddefn.cc
//
//
// Copyright (c) 2011, JF Gigand
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#include "php.h"
#include "php_gdal.h"
#include <ogr_feature.h>
#include "ogrfielddefn.h"

zend_class_entry *gdal_ogrfielddefn_ce;
zend_object_handlers ogrfielddefn_object_handlers;

//
// PHP stuff
//

void ogrfielddefn_free_storage(void *object TSRMLS_DC)
{
  php_ogrfielddefn_object *obj = (php_ogrfielddefn_object *)object;
  //delete obj->fielddefn; // TODO
  zend_hash_destroy(obj->std.properties);
  FREE_HASHTABLE(obj->std.properties);
  efree(obj);
}

zend_object_value ogrfielddefn_create_handler(zend_class_entry *type TSRMLS_DC)
{
  zval *tmp;
  zend_object_value retval;

  php_ogrfielddefn_object *obj =
    (php_ogrfielddefn_object *)emalloc(sizeof(php_ogrfielddefn_object));
  memset(obj, 0, sizeof(php_ogrfielddefn_object));
  obj->std.ce = type;

  ALLOC_HASHTABLE(obj->std.properties);
  zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
  zend_hash_copy(obj->std.properties, &type->default_properties,
                 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
      object_properties_init(&obj->std, type);
#endif

  retval.handle = zend_objects_store_put(obj, NULL,
                                         ogrfielddefn_free_storage, NULL TSRMLS_CC);
  retval.handlers = &ogrfielddefn_object_handlers;

  return retval;

  //pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args TSRMLS_CC);

}

//
// CLASS METHODS
//

PHP_METHOD(OGRFieldDefn, __construct)
{
  php_ogrfielddefn_object *obj;
  char *name;
  int name_len;
  long type;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"sl",
                            &name, &name_len, &type) == FAILURE) {
    return;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  obj->fielddefn = new OGRFieldDefn(name, (OGRFieldType)type);
}

PHP_METHOD(OGRFieldDefn, SetName)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  char *name;
  int name_len;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"s",
                            &name, &name_len) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;

  fielddefn->SetName(name);
}

PHP_METHOD(OGRFieldDefn, GetNameRef)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;

  const char *name = fielddefn->GetNameRef();
  if (name) {
    RETURN_STRING((char *)name, 1);
  } else {
    RETURN_NULL();
  }
}

PHP_METHOD(OGRFieldDefn, GetType)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG((long)fielddefn->GetType());
}

PHP_METHOD(OGRFieldDefn, SetType)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long type;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &type) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetType((OGRFieldType)type);
}

PHP_METHOD(OGRFieldDefn, GetJustify)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG((long)fielddefn->GetJustify());
}

PHP_METHOD(OGRFieldDefn, SetJustify)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long justification;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &justification) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetJustify((OGRJustification)justification);
}

PHP_METHOD(OGRFieldDefn, GetWidth)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG(fielddefn->GetWidth());
}

PHP_METHOD(OGRFieldDefn, SetWidth)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long width;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &width) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetWidth(width);
}

PHP_METHOD(OGRFieldDefn, GetPrecision)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  RETURN_LONG(fielddefn->GetPrecision());
}

PHP_METHOD(OGRFieldDefn, SetPrecision)
{
  OGRFieldDefn *fielddefn;
  php_ogrfielddefn_object *obj;
  long precision;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
                            &precision) == FAILURE) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrfielddefn_object *)
    zend_object_store_get_object(getThis() TSRMLS_CC);
  fielddefn = obj->fielddefn;
  fielddefn->SetPrecision(precision);
}

//
// PHP stuff
//

zend_function_entry ogrfielddefn_methods[] = {
  PHP_ME(OGRFieldDefn, __construct,                 NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetName,                 NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetNameRef,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetType,                 NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetType,                 NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, GetFieldTypeName,        NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetJustify,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetJustify,              NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetWidth,                NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetWidth,                NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, GetPrecision,            NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRFieldDefn, SetPrecision,            NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, Set,                     NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, SetDefault,              NULL, ZEND_ACC_PUBLIC)
  // PHP_ME(OGRFieldDefn, GetDefaultRef,           NULL, ZEND_ACC_PUBLIC)
  {NULL, NULL, NULL}
};

void php_gdal_ogrfielddefn_startup(INIT_FUNC_ARGS)
{
  zend_class_entry ce;
  INIT_CLASS_ENTRY(ce, "OGRFieldDefn", ogrfielddefn_methods);
  gdal_ogrfielddefn_ce = zend_register_internal_class(&ce TSRMLS_CC);
  gdal_ogrfielddefn_ce->create_object = ogrfielddefn_create_handler;
  memcpy(&ogrfielddefn_object_handlers,
         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  ogrfielddefn_object_handlers.clone_obj = NULL;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkAxesTransformRepresentation.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.

=========================================================================*/
#include "vtkAxesTransformRepresentation.h"
#include "vtkPointHandleRepresentation3D.h"
#include "vtkPolyDataMapper.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkVectorText.h"
#include "vtkFollower.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include "vtkCoordinate.h"
#include "vtkRenderer.h"
#include "vtkObjectFactory.h"
#include "vtkInteractorObserver.h"
#include "vtkMath.h"
#include "vtkWindow.h"
#include "vtkSmartPointer.h"
#include "vtkBox.h"
#include "vtkGlyph3D.h"
#include "vtkCylinderSource.h"
#include "vtkDoubleArray.h"
#include "vtkPointData.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkTransform.h"
#include "vtkSmartPointer.h"

vtkStandardNewMacro(vtkAxesTransformRepresentation);

//----------------------------------------------------------------------
vtkAxesTransformRepresentation::vtkAxesTransformRepresentation()
{
  // By default, use one of these handles
  this->OriginRepresentation  = vtkPointHandleRepresentation3D::New();
  this->SelectionRepresentation  = vtkPointHandleRepresentation3D::New();

  // The line
  this->LinePoints = vtkPoints::New();
  this->LinePoints->SetDataTypeToDouble();
  this->LinePoints->SetNumberOfPoints(2);
  this->LinePolyData = vtkPolyData::New();
  this->LinePolyData->SetPoints(this->LinePoints);
  vtkSmartPointer<vtkCellArray> line = vtkSmartPointer<vtkCellArray>::New();
  line->InsertNextCell(2);
  line->InsertCellPoint(0);
  line->InsertCellPoint(1);
  this->LinePolyData->SetLines(line);
  this->LineMapper = vtkPolyDataMapper::New();
  this->LineMapper->SetInput(this->LinePolyData);
  this->LineActor = vtkActor::New();
  this->LineActor->SetMapper(this->LineMapper);

  // The label
  this->LabelText = vtkVectorText::New();
  this->LabelMapper = vtkPolyDataMapper::New();
  this->LabelMapper->SetInputConnection(this->LabelText->GetOutputPort());
  this->LabelActor = vtkFollower::New();
  this->LabelActor->SetMapper(this->LabelMapper);

  // The tick marks
  this->GlyphPoints = vtkPoints::New();
  this->GlyphPoints->SetDataTypeToDouble();
  this->GlyphVectors = vtkDoubleArray::New();
  this->GlyphVectors->SetNumberOfComponents(3);
  this->GlyphPolyData = vtkPolyData::New();
  this->GlyphPolyData->SetPoints(this->GlyphPoints);
  this->GlyphPolyData->GetPointData()->SetVectors(this->GlyphVectors);
  this->GlyphCylinder = vtkCylinderSource::New();
  this->GlyphCylinder->SetRadius(0.5);
  this->GlyphCylinder->SetHeight(0.1);
  this->GlyphCylinder->SetResolution(12);
  vtkSmartPointer<vtkTransform> xform = vtkSmartPointer<vtkTransform>::New();
  this->GlyphXForm = vtkTransformPolyDataFilter::New();
  this->GlyphXForm->SetInputConnection(this->GlyphCylinder->GetOutputPort());
  this->GlyphXForm->SetTransform(xform);
  xform->RotateZ(90);
  this->Glyph3D = vtkGlyph3D::New();
  this->Glyph3D->SetInput(this->GlyphPolyData);
  this->Glyph3D->SetSourceConnection(this->GlyphXForm->GetOutputPort());
  this->Glyph3D->SetScaleModeToDataScalingOff();
  this->GlyphMapper = vtkPolyDataMapper::New();
  this->GlyphMapper->SetInputConnection(this->Glyph3D->GetOutputPort());
  this->GlyphActor = vtkActor::New();
  this->GlyphActor->SetMapper(this->GlyphMapper);

  // The bounding box
  this->BoundingBox = vtkBox::New();

}

//----------------------------------------------------------------------
vtkAxesTransformRepresentation::~vtkAxesTransformRepresentation()
{
  this->LinePoints->Delete();
  this->LinePolyData->Delete();
  this->LineMapper->Delete();
  this->LineActor->Delete();

  this->LabelText->Delete();
  this->LabelMapper->Delete();
  this->LabelActor->Delete();

  this->GlyphPoints->Delete();
  this->GlyphVectors->Delete();
  this->GlyphPolyData->Delete();
  this->GlyphCylinder->Delete();
  this->GlyphXForm->Delete();
  this->Glyph3D->Delete();
  this->GlyphMapper->Delete();
  this->GlyphActor->Delete();

  this->BoundingBox->Delete();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::GetOriginWorldPosition(double pos[3])
{
  this->OriginRepresentation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
double* vtkAxesTransformRepresentation::GetOriginWorldPosition()
{
  if (!this->OriginRepresentation)
    {
    static double temp[3]=  {0, 0, 0};
    return temp;
    }
  return this->OriginRepresentation->GetWorldPosition();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetOriginDisplayPosition(double x[3])
{
  this->OriginRepresentation->SetDisplayPosition(x);
  double p[3];
  this->OriginRepresentation->GetWorldPosition(p);
  this->OriginRepresentation->SetWorldPosition(p);
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetOriginWorldPosition(double x[3])
{
  if (this->OriginRepresentation)
    {
    this->OriginRepresentation->SetWorldPosition(x);
    }
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::GetOriginDisplayPosition(double pos[3])
{
  this->OriginRepresentation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
double *vtkAxesTransformRepresentation::GetBounds()
{
  this->BuildRepresentation();

  this->BoundingBox->SetBounds(this->OriginRepresentation->GetBounds());
  this->BoundingBox->AddBounds(this->SelectionRepresentation->GetBounds());
  this->BoundingBox->AddBounds(this->LineActor->GetBounds());

  return this->BoundingBox->GetBounds();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::StartWidgetInteraction(double e[2])
{
  // Store the start position
  this->StartEventPosition[0] = e[0];
  this->StartEventPosition[1] = e[1];
  this->StartEventPosition[2] = 0.0;

  // Store the start position
  this->LastEventPosition[0] = e[0];
  this->LastEventPosition[1] = e[1];
  this->LastEventPosition[2] = 0.0;

  // Get the coordinates of the three handles
//   this->OriginRepresentation->GetWorldPosition(this->StartP1);
//   this->SelectionRepresentation->GetWorldPosition(this->StartP2);
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::WidgetInteraction(double e[2])
{

  // Store the start position
  this->LastEventPosition[0] = e[0];
  this->LastEventPosition[1] = e[1];
  this->LastEventPosition[2] = 0.0;
}

//----------------------------------------------------------------------------
int vtkAxesTransformRepresentation::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
{
  // Check if we are on the origin. Use the handle to determine this.
  int p1State = this->OriginRepresentation->ComputeInteractionState(X,Y,0);

  if ( p1State == vtkHandleRepresentation::Nearby )
    {
    this->InteractionState = vtkAxesTransformRepresentation::OnOrigin;
//     this->SetRepresentationState(vtkAxesTransformRepresentation::OnOrigin);
    }
  else
    {
    this->InteractionState = vtkAxesTransformRepresentation::Outside;
    }

  // Okay if we're near a handle return, otherwise test the line
  if ( this->InteractionState != vtkAxesTransformRepresentation::Outside )
    {
    return this->InteractionState;
    }

  return this->InteractionState;
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::BuildRepresentation()
{
  if ( this->GetMTime() > this->BuildTime ||
       this->OriginRepresentation->GetMTime() > this->BuildTime ||
       this->SelectionRepresentation->GetMTime() > this->BuildTime ||
       (this->Renderer && this->Renderer->GetVTKWindow() &&
        this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
    {

    this->BuildTime.Modified();
    }
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::
ReleaseGraphicsResources(vtkWindow *w)
{
  this->LineActor->ReleaseGraphicsResources(w);
  this->LabelActor->ReleaseGraphicsResources(w);
  this->GlyphActor->ReleaseGraphicsResources(w);
}

//----------------------------------------------------------------------
int vtkAxesTransformRepresentation::
RenderOpaqueGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  this->LineActor->RenderOpaqueGeometry(v);
  this->LabelActor->RenderOpaqueGeometry(v);
  this->GlyphActor->RenderOpaqueGeometry(v);

  return 3;
}

//----------------------------------------------------------------------
int vtkAxesTransformRepresentation::
RenderTranslucentPolygonalGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  this->LineActor->RenderTranslucentPolygonalGeometry(v);
  this->LabelActor->RenderTranslucentPolygonalGeometry(v);
  this->GlyphActor->RenderTranslucentPolygonalGeometry(v);

  return 3;
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetLabelScale( double scale[3] )
{
  this->LabelActor->SetScale( scale );
}

//----------------------------------------------------------------------
double * vtkAxesTransformRepresentation::GetLabelScale()
{
  return this->LabelActor->GetScale();
}

//----------------------------------------------------------------------------
vtkProperty * vtkAxesTransformRepresentation::GetLabelProperty()
{
  return this->LabelActor->GetProperty();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
  //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>Fix Widgets printself test.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAxesTransformRepresentation.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.

=========================================================================*/
#include "vtkAxesTransformRepresentation.h"
#include "vtkPointHandleRepresentation3D.h"
#include "vtkPolyDataMapper.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkVectorText.h"
#include "vtkFollower.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include "vtkCoordinate.h"
#include "vtkRenderer.h"
#include "vtkObjectFactory.h"
#include "vtkInteractorObserver.h"
#include "vtkMath.h"
#include "vtkWindow.h"
#include "vtkSmartPointer.h"
#include "vtkBox.h"
#include "vtkGlyph3D.h"
#include "vtkCylinderSource.h"
#include "vtkDoubleArray.h"
#include "vtkPointData.h"
#include "vtkTransformPolyDataFilter.h"
#include "vtkTransform.h"
#include "vtkSmartPointer.h"

vtkStandardNewMacro(vtkAxesTransformRepresentation);

//----------------------------------------------------------------------
vtkAxesTransformRepresentation::vtkAxesTransformRepresentation()
{
  // By default, use one of these handles
  this->OriginRepresentation  = vtkPointHandleRepresentation3D::New();
  this->SelectionRepresentation  = vtkPointHandleRepresentation3D::New();

  // The line
  this->LinePoints = vtkPoints::New();
  this->LinePoints->SetDataTypeToDouble();
  this->LinePoints->SetNumberOfPoints(2);
  this->LinePolyData = vtkPolyData::New();
  this->LinePolyData->SetPoints(this->LinePoints);
  vtkSmartPointer<vtkCellArray> line = vtkSmartPointer<vtkCellArray>::New();
  line->InsertNextCell(2);
  line->InsertCellPoint(0);
  line->InsertCellPoint(1);
  this->LinePolyData->SetLines(line);
  this->LineMapper = vtkPolyDataMapper::New();
  this->LineMapper->SetInput(this->LinePolyData);
  this->LineActor = vtkActor::New();
  this->LineActor->SetMapper(this->LineMapper);

  // The label
  this->LabelText = vtkVectorText::New();
  this->LabelMapper = vtkPolyDataMapper::New();
  this->LabelMapper->SetInputConnection(this->LabelText->GetOutputPort());
  this->LabelActor = vtkFollower::New();
  this->LabelActor->SetMapper(this->LabelMapper);

  // The tick marks
  this->GlyphPoints = vtkPoints::New();
  this->GlyphPoints->SetDataTypeToDouble();
  this->GlyphVectors = vtkDoubleArray::New();
  this->GlyphVectors->SetNumberOfComponents(3);
  this->GlyphPolyData = vtkPolyData::New();
  this->GlyphPolyData->SetPoints(this->GlyphPoints);
  this->GlyphPolyData->GetPointData()->SetVectors(this->GlyphVectors);
  this->GlyphCylinder = vtkCylinderSource::New();
  this->GlyphCylinder->SetRadius(0.5);
  this->GlyphCylinder->SetHeight(0.1);
  this->GlyphCylinder->SetResolution(12);
  vtkSmartPointer<vtkTransform> xform = vtkSmartPointer<vtkTransform>::New();
  this->GlyphXForm = vtkTransformPolyDataFilter::New();
  this->GlyphXForm->SetInputConnection(this->GlyphCylinder->GetOutputPort());
  this->GlyphXForm->SetTransform(xform);
  xform->RotateZ(90);
  this->Glyph3D = vtkGlyph3D::New();
  this->Glyph3D->SetInput(this->GlyphPolyData);
  this->Glyph3D->SetSourceConnection(this->GlyphXForm->GetOutputPort());
  this->Glyph3D->SetScaleModeToDataScalingOff();
  this->GlyphMapper = vtkPolyDataMapper::New();
  this->GlyphMapper->SetInputConnection(this->Glyph3D->GetOutputPort());
  this->GlyphActor = vtkActor::New();
  this->GlyphActor->SetMapper(this->GlyphMapper);

  // The bounding box
  this->BoundingBox = vtkBox::New();

}

//----------------------------------------------------------------------
vtkAxesTransformRepresentation::~vtkAxesTransformRepresentation()
{
  this->LinePoints->Delete();
  this->LinePolyData->Delete();
  this->LineMapper->Delete();
  this->LineActor->Delete();

  this->LabelText->Delete();
  this->LabelMapper->Delete();
  this->LabelActor->Delete();

  this->GlyphPoints->Delete();
  this->GlyphVectors->Delete();
  this->GlyphPolyData->Delete();
  this->GlyphCylinder->Delete();
  this->GlyphXForm->Delete();
  this->Glyph3D->Delete();
  this->GlyphMapper->Delete();
  this->GlyphActor->Delete();

  this->BoundingBox->Delete();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::GetOriginWorldPosition(double pos[3])
{
  this->OriginRepresentation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
double* vtkAxesTransformRepresentation::GetOriginWorldPosition()
{
  if (!this->OriginRepresentation)
    {
    static double temp[3]=  {0, 0, 0};
    return temp;
    }
  return this->OriginRepresentation->GetWorldPosition();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetOriginDisplayPosition(double x[3])
{
  this->OriginRepresentation->SetDisplayPosition(x);
  double p[3];
  this->OriginRepresentation->GetWorldPosition(p);
  this->OriginRepresentation->SetWorldPosition(p);
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetOriginWorldPosition(double x[3])
{
  if (this->OriginRepresentation)
    {
    this->OriginRepresentation->SetWorldPosition(x);
    }
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::GetOriginDisplayPosition(double pos[3])
{
  this->OriginRepresentation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
double *vtkAxesTransformRepresentation::GetBounds()
{
  this->BuildRepresentation();

  this->BoundingBox->SetBounds(this->OriginRepresentation->GetBounds());
  this->BoundingBox->AddBounds(this->SelectionRepresentation->GetBounds());
  this->BoundingBox->AddBounds(this->LineActor->GetBounds());

  return this->BoundingBox->GetBounds();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::StartWidgetInteraction(double e[2])
{
  // Store the start position
  this->StartEventPosition[0] = e[0];
  this->StartEventPosition[1] = e[1];
  this->StartEventPosition[2] = 0.0;

  // Store the start position
  this->LastEventPosition[0] = e[0];
  this->LastEventPosition[1] = e[1];
  this->LastEventPosition[2] = 0.0;

  // Get the coordinates of the three handles
//   this->OriginRepresentation->GetWorldPosition(this->StartP1);
//   this->SelectionRepresentation->GetWorldPosition(this->StartP2);
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::WidgetInteraction(double e[2])
{

  // Store the start position
  this->LastEventPosition[0] = e[0];
  this->LastEventPosition[1] = e[1];
  this->LastEventPosition[2] = 0.0;
}

//----------------------------------------------------------------------------
int vtkAxesTransformRepresentation::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
{
  // Check if we are on the origin. Use the handle to determine this.
  int p1State = this->OriginRepresentation->ComputeInteractionState(X,Y,0);

  if ( p1State == vtkHandleRepresentation::Nearby )
    {
    this->InteractionState = vtkAxesTransformRepresentation::OnOrigin;
//     this->SetRepresentationState(vtkAxesTransformRepresentation::OnOrigin);
    }
  else
    {
    this->InteractionState = vtkAxesTransformRepresentation::Outside;
    }

  // Okay if we're near a handle return, otherwise test the line
  if ( this->InteractionState != vtkAxesTransformRepresentation::Outside )
    {
    return this->InteractionState;
    }

  return this->InteractionState;
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::BuildRepresentation()
{
  if ( this->GetMTime() > this->BuildTime ||
       this->OriginRepresentation->GetMTime() > this->BuildTime ||
       this->SelectionRepresentation->GetMTime() > this->BuildTime ||
       (this->Renderer && this->Renderer->GetVTKWindow() &&
        this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
    {

    this->BuildTime.Modified();
    }
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::
ReleaseGraphicsResources(vtkWindow *w)
{
  this->LineActor->ReleaseGraphicsResources(w);
  this->LabelActor->ReleaseGraphicsResources(w);
  this->GlyphActor->ReleaseGraphicsResources(w);
}

//----------------------------------------------------------------------
int vtkAxesTransformRepresentation::
RenderOpaqueGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  this->LineActor->RenderOpaqueGeometry(v);
  this->LabelActor->RenderOpaqueGeometry(v);
  this->GlyphActor->RenderOpaqueGeometry(v);

  return 3;
}

//----------------------------------------------------------------------
int vtkAxesTransformRepresentation::
RenderTranslucentPolygonalGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  this->LineActor->RenderTranslucentPolygonalGeometry(v);
  this->LabelActor->RenderTranslucentPolygonalGeometry(v);
  this->GlyphActor->RenderTranslucentPolygonalGeometry(v);

  return 3;
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::SetLabelScale( double scale[3] )
{
  this->LabelActor->SetScale( scale );
}

//----------------------------------------------------------------------
double * vtkAxesTransformRepresentation::GetLabelScale()
{
  return this->LabelActor->GetScale();
}

//----------------------------------------------------------------------------
vtkProperty * vtkAxesTransformRepresentation::GetLabelProperty()
{
  return this->LabelActor->GetProperty();
}

//----------------------------------------------------------------------
void vtkAxesTransformRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
  std::cout << "LabelFormat: " << this->LabelFormat << std::endl;
  std::cout << "Tolerance: " << this->Tolerance << std::endl;
  std::cout << "InteractionState: " << this->InteractionState << std::endl;
  std::cout << "OriginRepresentation: " << this->OriginRepresentation << endl;
  std::cout << "SelectionRepresentation: " << this->SelectionRepresentation << endl;

  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>
//#define __STRICT_ANSI__

#define ERROR_VALUE -1

#include "SerialClass.h"
#include "stdio.h"
#include <string>
#include <errno.h>
#include "error.h"
Serial::Serial(char *portName) {
  // We're not yet connected
  this->connected = false;

#ifdef _WIN32
  // Try to connect to the given port throuh CreateFile
  this->hSerial = CreateFileA(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  // Check if the connection was successfull
  if (this->hSerial == INVALID_HANDLE_VALUE) {
    // If not success full display an Error
    if (GetLastError() == ERROR_FILE_NOT_FOUND) {
      // Print Error if neccessary
      throw new Error(ConsoleColor(ConsoleColor::red),"Error: Handle was not attached. Reason: %s not available.\n",
             portName);

    } else {
      throw new Error(ConsoleColor(ConsoleColor::red),"Unknown error on com port!");
    }
  } else {
    // If connected we try to set the comm parameters
    DCB dcbSerialParams = {0};

    // Try to get the current
    if (!GetCommState(this->hSerial, &dcbSerialParams)) {
      // If impossible, show an error
      printf("failed to get current serial parameters!");
    } else {
      // Define serial connection parameters for the arduino board
      dcbSerialParams.BaudRate = CBR_9600;
      dcbSerialParams.ByteSize = 8;
      dcbSerialParams.StopBits = ONESTOPBIT;
      dcbSerialParams.Parity = NOPARITY;
      dcbSerialParams.XonLim = 42;
      dcbSerialParams.XoffLim = 42;
      dcbSerialParams.fAbortOnError = TRUE;
      dcbSerialParams.fDtrControl = DTR_CONTROL_HANDSHAKE;
      dcbSerialParams.fRtsControl = RTS_CONTROL_HANDSHAKE;
      dcbSerialParams.fBinary = TRUE;
      dcbSerialParams.fParity = FALSE;
      dcbSerialParams.fInX = FALSE;
      dcbSerialParams.fOutX = FALSE;
      dcbSerialParams.XonChar = (unsigned char) 0x11;
      dcbSerialParams.XoffChar = (unsigned char) 0x13;
      dcbSerialParams.fErrorChar = FALSE;
      dcbSerialParams.fNull = FALSE;
      dcbSerialParams.fOutxCtsFlow = FALSE;
      dcbSerialParams.fOutxDsrFlow = FALSE;

      // Set the parameters and check for their proper application
      if (!SetCommState(hSerial, &dcbSerialParams)) {
        throw new Error(ConsoleColor(ConsoleColor::red),"Error: Could not set Serial Port parameters");
      } else {
        // If everything went fine we're connected
        this->connected = true;
        // Flush any remaining characters in the buffers
        PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
        // We wait 2s as the arduino board will be reseting
        Sleep(ARDUINO_WAIT_TIME);
      }
    }
  }
#else
  com = open(portName, O_RDWR | O_NOCTTY);
  memset(&tty, 0, sizeof tty);

  /* Error Handling */
  if (tcgetattr(com, &tty) != 0) {
    throw new Error(ConsoleColor(ConsoleColor::red),"Error handling  %d from tcgetattr: %s\n", errno, strerror(errno));
  }

  /* Save old tty parameters */
  tty_old = tty;

  /* Set Baud Rate */
  cfsetospeed(&tty, (speed_t)B9600);

  /* Setting other Port Stuff */
  tty.c_cflag &= ~PARENB;  // Make 8n1
  tty.c_cflag &= ~CSTOPB;
  tty.c_cflag &= ~CSIZE;
  tty.c_cflag |= CS8;

  tty.c_cflag &= ~CRTSCTS;        // no flow control
  tty.c_cc[VMIN] = 1;             // read doesn't block
  tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
  tty.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines

  /* Make raw */
  cfmakeraw(&tty);

  /* Flush Port, then applies attributes */
  tcflush(com, TCIFLUSH);
  if (tcsetattr(com, TCSANOW, &tty) != 0) {
    throw new Error(ConsoleColor(ConsoleColor::red), "Error apply attributes %d from tcsetattr\n", errno);
  }
  this->connected = true;
#endif
}

Serial::~Serial() {
  // Check if we are connected before trying to disconnect
  if (this->connected) {
    // We're no longer connected
    this->connected = false;
#ifdef _WIN32
    // Close the serial handler
    CloseHandle(this->hSerial);
#else
    close(com);
#endif
  }
}

bool Serial::WriteData(unsigned char *buffer, unsigned int nbChar) {
#ifdef _WIN32
  DWORD bytesSend;

  // Try to write the buffer on the Serial port
  if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0)) {
    // In case it don't work get comm error and return false
    ClearCommError(this->hSerial, &this->errors, &this->status);
    return false;
  } else
    ::Sleep(250);          // Sleep 250ms to ensure a good break
    FlushFileBuffers(this->hSerial);
    PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
    return true;
#else
  if (write(com, buffer, nbChar) == ERROR_VALUE) {
    return false;
  };
  return true;
#endif
}

bool Serial::IsConnected() {
  // Simply return the connection status
  return this->connected;
}<commit_msg>Поправлен баг при сборке под Linux<commit_after>
//#define __STRICT_ANSI__

#define ERROR_VALUE -1

#include "SerialClass.h"
#include "stdio.h"
#include <string>
#include "string.h"
#include <errno.h>
#include "error.h"
Serial::Serial(char *portName) {
  // We're not yet connected
  this->connected = false;

#ifdef _WIN32
  // Try to connect to the given port throuh CreateFile
  this->hSerial = CreateFileA(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  // Check if the connection was successfull
  if (this->hSerial == INVALID_HANDLE_VALUE) {
    // If not success full display an Error
    if (GetLastError() == ERROR_FILE_NOT_FOUND) {
      // Print Error if neccessary
      throw new Error(ConsoleColor(ConsoleColor::red),"Error: Handle was not attached. Reason: %s not available.\n",
             portName);

    } else {
      throw new Error(ConsoleColor(ConsoleColor::red),"Unknown error on com port!");
    }
  } else {
    // If connected we try to set the comm parameters
    DCB dcbSerialParams = {0};

    // Try to get the current
    if (!GetCommState(this->hSerial, &dcbSerialParams)) {
      // If impossible, show an error
      printf("failed to get current serial parameters!");
    } else {
      // Define serial connection parameters for the arduino board
      dcbSerialParams.BaudRate = CBR_9600;
      dcbSerialParams.ByteSize = 8;
      dcbSerialParams.StopBits = ONESTOPBIT;
      dcbSerialParams.Parity = NOPARITY;
      dcbSerialParams.XonLim = 42;
      dcbSerialParams.XoffLim = 42;
      dcbSerialParams.fAbortOnError = TRUE;
      dcbSerialParams.fDtrControl = DTR_CONTROL_HANDSHAKE;
      dcbSerialParams.fRtsControl = RTS_CONTROL_HANDSHAKE;
      dcbSerialParams.fBinary = TRUE;
      dcbSerialParams.fParity = FALSE;
      dcbSerialParams.fInX = FALSE;
      dcbSerialParams.fOutX = FALSE;
      dcbSerialParams.XonChar = (unsigned char) 0x11;
      dcbSerialParams.XoffChar = (unsigned char) 0x13;
      dcbSerialParams.fErrorChar = FALSE;
      dcbSerialParams.fNull = FALSE;
      dcbSerialParams.fOutxCtsFlow = FALSE;
      dcbSerialParams.fOutxDsrFlow = FALSE;

      // Set the parameters and check for their proper application
      if (!SetCommState(hSerial, &dcbSerialParams)) {
        throw new Error(ConsoleColor(ConsoleColor::red),"Error: Could not set Serial Port parameters");
      } else {
        // If everything went fine we're connected
        this->connected = true;
        // Flush any remaining characters in the buffers
        PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
        // We wait 2s as the arduino board will be reseting
        Sleep(ARDUINO_WAIT_TIME);
      }
    }
  }
#else
  com = open(portName, O_RDWR | O_NOCTTY);
  memset(&tty, 0, sizeof tty);

  /* Error Handling */
  if (tcgetattr(com, &tty) != 0) {
    throw new Error(ConsoleColor(ConsoleColor::red),"Error handling  %d from tcgetattr: %s\n", errno, strerror(errno));
  }

  /* Save old tty parameters */
  tty_old = tty;

  /* Set Baud Rate */
  cfsetospeed(&tty, (speed_t)B9600);

  /* Setting other Port Stuff */
  tty.c_cflag &= ~PARENB;  // Make 8n1
  tty.c_cflag &= ~CSTOPB;
  tty.c_cflag &= ~CSIZE;
  tty.c_cflag |= CS8;

  tty.c_cflag &= ~CRTSCTS;        // no flow control
  tty.c_cc[VMIN] = 1;             // read doesn't block
  tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
  tty.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines

  /* Make raw */
  cfmakeraw(&tty);

  /* Flush Port, then applies attributes */
  tcflush(com, TCIFLUSH);
  if (tcsetattr(com, TCSANOW, &tty) != 0) {
    throw new Error(ConsoleColor(ConsoleColor::red), "Error apply attributes %d from tcsetattr\n", errno);
  }
  this->connected = true;
#endif
}

Serial::~Serial() {
  // Check if we are connected before trying to disconnect
  if (this->connected) {
    // We're no longer connected
    this->connected = false;
#ifdef _WIN32
    // Close the serial handler
    CloseHandle(this->hSerial);
#else
    close(com);
#endif
  }
}

bool Serial::WriteData(unsigned char *buffer, unsigned int nbChar) {
#ifdef _WIN32
  DWORD bytesSend;

  // Try to write the buffer on the Serial port
  if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0)) {
    // In case it don't work get comm error and return false
    ClearCommError(this->hSerial, &this->errors, &this->status);
    return false;
  } else
    ::Sleep(250);          // Sleep 250ms to ensure a good break
    FlushFileBuffers(this->hSerial);
    PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
    return true;
#else
  if (write(com, buffer, nbChar) == ERROR_VALUE) {
    return false;
  };
  return true;
#endif
}

bool Serial::IsConnected() {
  // Simply return the connection status
  return this->connected;
}<|endoftext|>


<commit_before>/*
 * Copyright 2010, Milos Pejovic. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include <support/String.h>
#include <stdio.h>
#include "ScaleDialog.h"

extern char* kOk;
extern char* kCancel;

const char* kScaleTitle = "Adjust the scale value";

ScaleDialog::ScaleDialog(char* title, float width, float height,
                         char* text, int32 value, int32 minValue, int32 maxValue,
                         int32 step, bool printPartial, bool hideValue)
                         : Dialog(title, width, height)
{
    if (title == NULL)
        SetTitle(kScaleTitle);

    fText = (text != NULL ? text : kScaleTitle);

    fMinValue = (minValue >= 0 ? minValue : 0);

    fMaxValue = (maxValue > 0 ? maxValue : 100);

    fStep = (fStep > 0 ? step : 1);

    fValue = (fValue >= fMinValue && fValue <= fMaxValue ? value : 0);

    fPrintPartial = printPartial;
    fHideValue = hideValue;

    if (width < 1.0)
        width = 200;

    if (height < 1.0)
        height = 110;

    CreateViews();

    ResizeTo(width, height);

    InitControls();
}

void
ScaleDialog::CreateViews()
{
    BButton* okayButton = new BButton(
        BRect(0, 1, 80, 1), "okayButton", kOk, new BMessage(MSG_OK_CLICKED),
        B_FOLLOW_RIGHT);

    okayButton->MakeDefault(true);

    BButton* cancelButton = new BButton(
        BRect(0, 1, 80, 1), "cancelButton", kCancel, new BMessage(MSG_CANCEL_CLICKED),
        B_FOLLOW_RIGHT);

    BStringView* textLabel = new BStringView(
                    BRect(0, 0, 1, 1), NULL, fText);
    textLabel->SetAlignment(B_ALIGN_LEFT);
    textLabel->SetExplicitMaxSize(
        BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));

    fSlider = new BSlider(
    			 BRect(0, 0, 1, 1), "slider", NULL, new BMessage('SlDE'), fMinValue, fMaxValue);

    fSlider->SetExplicitMaxSize(
        BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));

    if (!fHideValue) {
    	BString val;

    	val << fValue;

    	fValueLabel = new BStringView(
                    BRect(0, 0, 1, 1), NULL, val.String());
    }

    // Build the layout
    SetLayout(new BGroupLayout(B_HORIZONTAL));

    BGroupLayoutBuilder builder = BGroupLayoutBuilder(B_VERTICAL, 10).Add(textLabel);

	if (!fHideValue)
		builder.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5)
        	.Add(fSlider)
        	.Add(fValueLabel)
        );
	else
		builder.Add(fSlider);

    AddChild(
        builder.AddGlue()
        .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
            .AddGlue()
            .Add(cancelButton)
            .AddGlue()
            .Add(okayButton)
            .AddGlue()
        )
        .SetInsets(5, 5, 5, 5)
    );
}

void
ScaleDialog::InitControls()
{
    Lock();

    fSlider->SetValue(fValue);
    fSlider->SetKeyIncrementValue(fStep);
    fSlider->MakeFocus(true);

    CenterOnScreen();

    Unlock();
}

void
ScaleDialog::MessageReceived(BMessage* message)
{
    switch (message->what) {
        case MSG_OK_CLICKED:
        {
        	BString val;
        	val << fSlider->Value();

        	fprintf(stdout, "%s\n", val.String());

            Hide();
            be_app->PostMessage(MSG_OK_CLICKED);

            break;
        }

        case MSG_CANCEL_CLICKED:

            Hide();
            be_app->PostMessage(MSG_CANCEL_CLICKED);

            break;

        case 'SlDE':
    	{
    		fValue = fSlider->Value();
    		BString val;

    		val << fValue;

        	if (!fHideValue)
    			fValueLabel->SetText(val.String());

        	if (fPrintPartial)
        		fprintf(stdout, "%s\n", val.String());

        	break;
		}

        default:
            Dialog::MessageReceived(message);
            break;
    }
}

<commit_msg>now using ModificationMessage<commit_after>/*
 * Copyright 2010, Milos Pejovic. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include <support/String.h>
#include <stdio.h>
#include "ScaleDialog.h"

extern char* kOk;
extern char* kCancel;

const char* kScaleTitle = "Adjust the scale value";

ScaleDialog::ScaleDialog(char* title, float width, float height,
                         char* text, int32 value, int32 minValue, int32 maxValue,
                         int32 step, bool printPartial, bool hideValue)
                         : Dialog(title, width, height)
{
    if (title == NULL)
        SetTitle(kScaleTitle);

    fText = (text != NULL ? text : kScaleTitle);

    fMinValue = (minValue >= 0 ? minValue : 0);

    fMaxValue = (maxValue > 0 ? maxValue : 100);

    fStep = (fStep > 0 ? step : 1);

    fValue = (fValue >= fMinValue && fValue <= fMaxValue ? value : 0);

    fPrintPartial = printPartial;
    fHideValue = hideValue;

    if (width < 1.0)
        width = 200;

    if (height < 1.0)
        height = 110;

    CreateViews();

    ResizeTo(width, height);

    InitControls();
}

void
ScaleDialog::CreateViews()
{
    BButton* okayButton = new BButton(
        BRect(0, 1, 80, 1), "okayButton", kOk, new BMessage(MSG_OK_CLICKED),
        B_FOLLOW_RIGHT);

    okayButton->MakeDefault(true);

    BButton* cancelButton = new BButton(
        BRect(0, 1, 80, 1), "cancelButton", kCancel, new BMessage(MSG_CANCEL_CLICKED),
        B_FOLLOW_RIGHT);

    BStringView* textLabel = new BStringView(
                    BRect(0, 0, 1, 1), NULL, fText);
    textLabel->SetAlignment(B_ALIGN_LEFT);
    textLabel->SetExplicitMaxSize(
        BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));

    fSlider = new BSlider(
    			 BRect(0, 0, 1, 1), "slider", NULL, NULL, fMinValue, fMaxValue);

    fSlider->SetModificationMessage(new BMessage('SlDE'));

    fSlider->SetExplicitMaxSize(
        BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));

    if (!fHideValue) {
    	BString val;

    	val << fValue;

    	fValueLabel = new BStringView(
                    BRect(0, 0, 1, 1), NULL, val.String());
    }

    // Build the layout
    SetLayout(new BGroupLayout(B_HORIZONTAL));

    BGroupLayoutBuilder builder = BGroupLayoutBuilder(B_VERTICAL, 10).Add(textLabel);

	if (!fHideValue)
		builder.Add(BGroupLayoutBuilder(B_HORIZONTAL, 5)
        	.Add(fSlider)
        	.Add(fValueLabel)
        );
	else
		builder.Add(fSlider);

    AddChild(
        builder.AddGlue()
        .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
            .AddGlue()
            .Add(cancelButton)
            .AddGlue()
            .Add(okayButton)
            .AddGlue()
        )
        .SetInsets(5, 5, 5, 5)
    );
}

void
ScaleDialog::InitControls()
{
    Lock();

    fSlider->SetValue(fValue);
    fSlider->SetKeyIncrementValue(fStep);
    fSlider->MakeFocus(true);

    CenterOnScreen();

    Unlock();
}

void
ScaleDialog::MessageReceived(BMessage* message)
{
    switch (message->what) {
        case MSG_OK_CLICKED:
        {
        	BString val;
        	val << fSlider->Value();

        	fprintf(stdout, "%s\n", val.String());

            Hide();
            be_app->PostMessage(MSG_OK_CLICKED);

            break;
        }

        case MSG_CANCEL_CLICKED:

            Hide();
            be_app->PostMessage(MSG_CANCEL_CLICKED);

            break;

        case 'SlDE':
    	{
    		int32 newValue = fSlider->Value();

    		// Avoid repeating same numbers
    		if (fValue != newValue) {
    			fValue = newValue;
    		} else {
    			return;
    		}

    		BString val;

    		val << fValue;

        	if (!fHideValue)
    			fValueLabel->SetText(val.String());

        	if (fPrintPartial)
        		fprintf(stdout, "%s\n", val.String());

        	break;
		}

        default:
            Dialog::MessageReceived(message);
            break;
    }
}

<|endoftext|>


<commit_before>#include "BigFix/ArchiveReader.h"
#include "BigFix/ArchiveStream.h"
#include "BigFix/DataRef.h"
#include "BigFix/InflateStream.h"
#include <iostream>

using namespace BigFix;

class ArchiveListStream : public ArchiveStream
{
public:
  virtual void Directory( const char* name,
                          ArchiveEncoding nameEncoding,
                          time_t mtime )
  {
    std::cout << name << std::endl;
  }

  virtual void FileStart( const char* name,
                          ArchiveEncoding nameEncoding,
                          time_t mtime,
                          uint64_t length )
  {
    std::cout << name << std::endl;
  }

  virtual void FileWrite( const uint8_t* start, const uint8_t* end ) {}

  virtual void FileEnd() {}
};

int main()
{
  ArchiveListStream list;
  ArchiveReader reader( list );
  InflateStream inflate( reader );

  char buffer[4096];

  while ( true )
  {
    ssize_t nread = read( 0, buffer, sizeof( buffer ) );
    if ( nread == 0 )
    {
      inflate.End();
      return 0;
    }

    if ( nread < 0 )
    {
      std::cerr << "Error reading from stdin" << std::endl;
      return 1;
    }

    inflate.Write( DataRef( (uint8_t*)buffer, (uint8_t*)buffer + nread ) );
  }
}
<commit_msg>Fix build<commit_after>#include "BigFix/ArchiveReader.h"
#include "BigFix/ArchiveStream.h"
#include "BigFix/DataRef.h"
#include "BigFix/InflateStream.h"
#include <iostream>

using namespace BigFix;

class ArchiveListStream : public ArchiveStream
{
public:
  virtual void Directory( const char* name,
                          ArchiveEncoding nameEncoding,
                          const DateTime& mtime )
  {
    std::cout << name << std::endl;
  }

  virtual void FileStart( const char* name,
                          ArchiveEncoding nameEncoding,
                          const DateTime& mtime,
                          uint64_t length )
  {
    std::cout << name << std::endl;
  }

  virtual void FileWrite( const uint8_t* start, const uint8_t* end ) {}

  virtual void FileEnd() {}
};

int main()
{
  ArchiveListStream list;
  ArchiveReader reader( list );
  InflateStream inflate( reader );

  char buffer[4096];

  while ( true )
  {
    ssize_t nread = read( 0, buffer, sizeof( buffer ) );
    if ( nread == 0 )
    {
      inflate.End();
      return 0;
    }

    if ( nread < 0 )
    {
      std::cerr << "Error reading from stdin" << std::endl;
      return 1;
    }

    inflate.Write( DataRef( (uint8_t*)buffer, (uint8_t*)buffer + nread ) );
  }
}
<|endoftext|>


<commit_before>/* Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// libevent based server implementation

#include "tensorflow_serving/util/net_http/server/internal/evhttp_server.h"

#include <netinet/in.h>
#include <sys/socket.h>
#include <cstdint>
#include <memory>
#include <utility>

#include "absl/base/call_once.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/memory/memory.h"

#include "libevent/include/event2/event.h"
#include "libevent/include/event2/http.h"
#include "libevent/include/event2/thread.h"
#include "libevent/include/event2/util.h"

namespace tensorflow {
namespace serving {
namespace net_http {

namespace {

absl::once_flag libevent_init_once;

void InitLibEvent() {
  if (evthread_use_pthreads() != 0) {
    ABSL_RAW_LOG(FATAL, "Server requires pthread support.");
  }

  // TODO(wenboz): windows support needed?
}

void GlobalInitialize() { absl::call_once(libevent_init_once, &InitLibEvent); }

}  // namespace

EvHTTPServer::EvHTTPServer(std::unique_ptr<ServerOptions> options)
    : server_options_(std::move(options)), accepting_requests_() {}

// May crash the server if called before WaitForTermination() returns
EvHTTPServer::~EvHTTPServer() {
  if (!is_terminating()) {
    ABSL_RAW_LOG(ERROR,
                 "Serer has not been terminated. Force termination now.");
    Terminate();
  }

  if (ev_http_ != nullptr) {
    // this frees the socket handlers too
    evhttp_free(ev_http_);
  }

  if (ev_base_ != nullptr) {
    event_base_free(ev_base_);
  }
}

// Checks options.
// TODO(wenboz): support multiple ports
bool EvHTTPServer::Initialize() {
  if (server_options_->executor() == nullptr) {
    ABSL_RAW_LOG(FATAL, "Default EventExecutor is not configured.");
    return false;
  }

  if (server_options_->ports().empty()) {
    ABSL_RAW_LOG(FATAL, "Server port is not specified.");
    return false;
  }

  GlobalInitialize();

  // This ev_base_ created per-server v.s. global
  ev_base_ = event_base_new();
  if (ev_base_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Failed to create an event_base.");
    return false;
  }

  timeval tv_zero = {0, 0};
  immediate_ = event_base_init_common_timeout(ev_base_, &tv_zero);

  ev_http_ = evhttp_new(ev_base_);
  if (ev_http_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Failed to create evhttp.");
    return false;
  }

  evhttp_set_gencb(ev_http_, &DispatchEvRequestFn, this);

  return true;
}

// static function pointer
void EvHTTPServer::DispatchEvRequestFn(evhttp_request* req, void* server) {
  EvHTTPServer* http_server = static_cast<EvHTTPServer*>(server);
  http_server->DispatchEvRequest(req);
}

void EvHTTPServer::DispatchEvRequest(evhttp_request* req) {
  auto parsed_request = absl::make_unique<ParsedEvRequest>(req);

  if (!parsed_request->decode()) {
    evhttp_send_error(req, HTTP_BADREQUEST, nullptr);
    return;
  }

  std::string path(parsed_request->path);

  bool dispatched = false;
  std::unique_ptr<EvHTTPRequest> ev_request(
      new EvHTTPRequest(std::move(parsed_request), this));

  if (!ev_request->Initialize()) {
    evhttp_send_error(req, HTTP_SERVUNAVAIL, nullptr);
    return;
  }

  {
    absl::MutexLock l(&request_mu_);

    auto handler_map_it = uri_handlers_.find(path);
    if (handler_map_it != uri_handlers_.end()) {
      IncOps();
      dispatched = true;
      ScheduleHandlerReference(handler_map_it->second.handler,
                               ev_request.release());
    }

    if (!dispatched) {
      for (const auto& dispatcher : dispatchers_) {
        auto handler = dispatcher.dispatcher(ev_request.get());
        if (handler == nullptr) {
          continue;
        }
        IncOps();
        dispatched = true;
        ScheduleHandler(std::move(handler), ev_request.release());
        break;
      }
    }
  }

  if (!dispatched) {
    evhttp_send_error(req, HTTP_NOTFOUND, nullptr);
    return;
  }
}

void EvHTTPServer::ScheduleHandlerReference(const RequestHandler& handler,
                                            EvHTTPRequest* ev_request) {
  server_options_->executor()->Schedule(
      [&handler, ev_request]() { handler(ev_request); });
}

// Exactly one copy of the handler argument
// with the lambda passed by value to Schedule()
void EvHTTPServer::ScheduleHandler(RequestHandler&& handler,
                                   EvHTTPRequest* ev_request) {
  server_options_->executor()->Schedule(
      [handler, ev_request]() { handler(ev_request); });
}

namespace {

void ResolveEphemeralPort(evhttp_bound_socket* listener, int* port) {
  sockaddr_storage ss = {};
  ev_socklen_t socklen = sizeof(ss);

  evutil_socket_t fd = evhttp_bound_socket_get_fd(listener);
  if (getsockname(fd, reinterpret_cast<sockaddr*>(&ss), &socklen)) {
    ABSL_RAW_LOG(ERROR, "getsockname() failed");
    return;
  }

  if (ss.ss_family == AF_INET) {
    *port = ntohs((reinterpret_cast<sockaddr_in*>(&ss))->sin_port);
  } else if (ss.ss_family == AF_INET6) {
    *port = ntohs((reinterpret_cast<sockaddr_in6*>(&ss))->sin6_port);
  } else {
    ABSL_RAW_LOG(ERROR, "Unknown address family %d", ss.ss_family);
  }
}

}  // namespace

bool EvHTTPServer::StartAcceptingRequests() {
  if (ev_http_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Server has not been successfully initialized");
    return false;
  }

  const int port = server_options_->ports().front();

  ev_listener_ = evhttp_bind_socket_with_handle(ev_http_,
                                                "::",  // in6addr_any
                                                static_cast<ev_uint16_t>(port));
  if (ev_listener_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Couldn't bind to port %d", port);
    return false;
  }

  IncOps();

  port_ = port;
  if (port_ == 0) {
    ResolveEphemeralPort(ev_listener_, &port_);
  }

  IncOps();
  server_options_->executor()->Schedule([this]() {
    ABSL_RAW_LOG(INFO, "Entering the event loop ...");
    int result = event_base_dispatch(ev_base_);
    ABSL_RAW_LOG(INFO, "event_base_dispatch() exits with value %d", result);

    DecOps();
  });

  accepting_requests_.Notify();

  return true;
}

int EvHTTPServer::listen_port() const { return port_; }

bool EvHTTPServer::is_accepting_requests() const {
  return accepting_requests_.HasBeenNotified();
}

void EvHTTPServer::Terminate() {
  if (!is_accepting_requests()) {
    ABSL_RAW_LOG(ERROR, "Server is not running ...");
    return;
  }

  if (is_terminating()) {
    ABSL_RAW_LOG(ERROR, "Server is already being terminated ...");
    return;
  }

  terminating_.Notify();

  // call exit-loop from the event loop
  this->EventLoopSchedule([this]() {
    // Stop the listener first, which will delete ev_listener_
    // This may cause the loop to exit, so need be scheduled from within
    evhttp_del_accept_socket(ev_http_, ev_listener_);
    DecOps();
  });

  // Current shut-down behavior:
  // - we don't proactively delete/close any HTTP connections as part of
  //   Terminate(). This is not an issue as we don't support read-streaming yet.
  // - we don't wait for all dispatched requests to run to completion
  //   before we stop the event loop.
  // - and otherwise, this is meant to be a clean shutdown
}

bool EvHTTPServer::is_terminating() const {
  return terminating_.HasBeenNotified();
}

void EvHTTPServer::IncOps() {
  absl::MutexLock l(&ops_mu_);
  num_pending_ops_++;
}

void EvHTTPServer::DecOps() {
  absl::MutexLock l(&ops_mu_);
  num_pending_ops_--;
}

void EvHTTPServer::WaitForTermination() {
  {
    absl::MutexLock l(&ops_mu_);
    ops_mu_.Await(absl::Condition(+[](int64_t* count) { return *count <= 1; },
                                  &num_pending_ops_));
  }

  int result = event_base_loopexit(ev_base_, nullptr);
  ABSL_RAW_LOG(INFO, "event_base_loopexit() exits with value %d", result);

  {
    absl::MutexLock l(&ops_mu_);
    ops_mu_.Await(absl::Condition(+[](int64_t* count) { return *count == 0; },
                                  &num_pending_ops_));
  }
}

bool EvHTTPServer::WaitForTerminationWithTimeout(absl::Duration timeout) {
  bool wait_result = true;

  {
    absl::MutexLock l(&ops_mu_);
    wait_result = ops_mu_.AwaitWithTimeout(
        absl::Condition(+[](int64_t* count) { return *count <= 1; },
                        &num_pending_ops_),
        timeout);
  }

  if (wait_result) {
    int result = event_base_loopexit(ev_base_, nullptr);
    ABSL_RAW_LOG(INFO, "event_base_loopexit() exits with value %d", result);

    // This should pass immediately
    {
      absl::MutexLock l(&ops_mu_);
      wait_result = ops_mu_.AwaitWithTimeout(
          absl::Condition(+[](int64_t* count) { return *count == 0; },
                          &num_pending_ops_),
          timeout);
    }
  }

  return wait_result;
}

EvHTTPServer::UriHandlerInfo::UriHandlerInfo(
    absl::string_view uri_in, RequestHandler handler_in,
    const RequestHandlerOptions& options_in)
    : uri(uri_in.data(), uri_in.size()),
      handler(std::move(handler_in)),
      options(options_in) {}

EvHTTPServer::DispatcherInfo::DispatcherInfo(
    RequestDispatcher dispatcher_in, const RequestHandlerOptions& options_in)
    : dispatcher(std::move(dispatcher_in)), options(options_in) {}

void EvHTTPServer::RegisterRequestHandler(
    absl::string_view uri, RequestHandler handler,
    const RequestHandlerOptions& options) {
  absl::MutexLock l(&request_mu_);
  auto result = uri_handlers_.emplace(
      std::piecewise_construct, std::forward_as_tuple(uri),
      std::forward_as_tuple(uri, handler, options));

  if (!result.second) {
    ABSL_RAW_LOG(INFO,
                 "Overwrite the existing handler registered under "
                 "the URI path %.*s",
                 static_cast<int>(uri.size()), uri.data());

    uri_handlers_.erase(result.first);
    if (!uri_handlers_
             .emplace(std::piecewise_construct, std::forward_as_tuple(uri),
                      std::forward_as_tuple(uri, handler, options))
             .second) {
      ABSL_RAW_LOG(ERROR,
                   "Failed to register an handler under the URI path %.*s",
                   static_cast<int>(uri.size()), uri.data());
    }
  }
}

void EvHTTPServer::RegisterRequestDispatcher(
    RequestDispatcher dispatcher, const RequestHandlerOptions& options) {
  absl::MutexLock l(&request_mu_);
  dispatchers_.emplace_back(dispatcher, options);
}

namespace {

void EvImmediateCallback(evutil_socket_t socket, int16_t flags, void* arg) {
  auto fn = static_cast<std::function<void()>*>(arg);
  (*fn)();
  delete fn;
}

}  // namespace

bool EvHTTPServer::EventLoopSchedule(std::function<void()> fn) {
  auto scheduled_fn = new std::function<void()>(std::move(fn));
  int result = event_base_once(ev_base_, -1, EV_TIMEOUT, EvImmediateCallback,
                               static_cast<void*>(scheduled_fn), immediate_);
  return result == 0;
}

}  // namespace net_http
}  // namespace serving
}  // namespace tensorflow
<commit_msg>Support ipv4-only hosts.<commit_after>/* Copyright 2018 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// libevent based server implementation

#include "tensorflow_serving/util/net_http/server/internal/evhttp_server.h"

#include <netinet/in.h>
#include <sys/socket.h>
#include <cstdint>
#include <memory>
#include <utility>

#include "absl/base/call_once.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/memory/memory.h"

#include "libevent/include/event2/event.h"
#include "libevent/include/event2/http.h"
#include "libevent/include/event2/thread.h"
#include "libevent/include/event2/util.h"

namespace tensorflow {
namespace serving {
namespace net_http {

namespace {

absl::once_flag libevent_init_once;

void InitLibEvent() {
  if (evthread_use_pthreads() != 0) {
    ABSL_RAW_LOG(FATAL, "Server requires pthread support.");
  }

  // TODO(wenboz): windows support needed?
}

void GlobalInitialize() { absl::call_once(libevent_init_once, &InitLibEvent); }

}  // namespace

EvHTTPServer::EvHTTPServer(std::unique_ptr<ServerOptions> options)
    : server_options_(std::move(options)), accepting_requests_() {}

// May crash the server if called before WaitForTermination() returns
EvHTTPServer::~EvHTTPServer() {
  if (!is_terminating()) {
    ABSL_RAW_LOG(ERROR,
                 "Serer has not been terminated. Force termination now.");
    Terminate();
  }

  if (ev_http_ != nullptr) {
    // this frees the socket handlers too
    evhttp_free(ev_http_);
  }

  if (ev_base_ != nullptr) {
    event_base_free(ev_base_);
  }
}

// Checks options.
// TODO(wenboz): support multiple ports
bool EvHTTPServer::Initialize() {
  if (server_options_->executor() == nullptr) {
    ABSL_RAW_LOG(FATAL, "Default EventExecutor is not configured.");
    return false;
  }

  if (server_options_->ports().empty()) {
    ABSL_RAW_LOG(FATAL, "Server port is not specified.");
    return false;
  }

  GlobalInitialize();

  // This ev_base_ created per-server v.s. global
  ev_base_ = event_base_new();
  if (ev_base_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Failed to create an event_base.");
    return false;
  }

  timeval tv_zero = {0, 0};
  immediate_ = event_base_init_common_timeout(ev_base_, &tv_zero);

  ev_http_ = evhttp_new(ev_base_);
  if (ev_http_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Failed to create evhttp.");
    return false;
  }

  evhttp_set_gencb(ev_http_, &DispatchEvRequestFn, this);

  return true;
}

// static function pointer
void EvHTTPServer::DispatchEvRequestFn(evhttp_request* req, void* server) {
  EvHTTPServer* http_server = static_cast<EvHTTPServer*>(server);
  http_server->DispatchEvRequest(req);
}

void EvHTTPServer::DispatchEvRequest(evhttp_request* req) {
  auto parsed_request = absl::make_unique<ParsedEvRequest>(req);

  if (!parsed_request->decode()) {
    evhttp_send_error(req, HTTP_BADREQUEST, nullptr);
    return;
  }

  std::string path(parsed_request->path);

  bool dispatched = false;
  std::unique_ptr<EvHTTPRequest> ev_request(
      new EvHTTPRequest(std::move(parsed_request), this));

  if (!ev_request->Initialize()) {
    evhttp_send_error(req, HTTP_SERVUNAVAIL, nullptr);
    return;
  }

  {
    absl::MutexLock l(&request_mu_);

    auto handler_map_it = uri_handlers_.find(path);
    if (handler_map_it != uri_handlers_.end()) {
      IncOps();
      dispatched = true;
      ScheduleHandlerReference(handler_map_it->second.handler,
                               ev_request.release());
    }

    if (!dispatched) {
      for (const auto& dispatcher : dispatchers_) {
        auto handler = dispatcher.dispatcher(ev_request.get());
        if (handler == nullptr) {
          continue;
        }
        IncOps();
        dispatched = true;
        ScheduleHandler(std::move(handler), ev_request.release());
        break;
      }
    }
  }

  if (!dispatched) {
    evhttp_send_error(req, HTTP_NOTFOUND, nullptr);
    return;
  }
}

void EvHTTPServer::ScheduleHandlerReference(const RequestHandler& handler,
                                            EvHTTPRequest* ev_request) {
  server_options_->executor()->Schedule(
      [&handler, ev_request]() { handler(ev_request); });
}

// Exactly one copy of the handler argument
// with the lambda passed by value to Schedule()
void EvHTTPServer::ScheduleHandler(RequestHandler&& handler,
                                   EvHTTPRequest* ev_request) {
  server_options_->executor()->Schedule(
      [handler, ev_request]() { handler(ev_request); });
}

namespace {

void ResolveEphemeralPort(evhttp_bound_socket* listener, int* port) {
  sockaddr_storage ss = {};
  ev_socklen_t socklen = sizeof(ss);

  evutil_socket_t fd = evhttp_bound_socket_get_fd(listener);
  if (getsockname(fd, reinterpret_cast<sockaddr*>(&ss), &socklen)) {
    ABSL_RAW_LOG(ERROR, "getsockname() failed");
    return;
  }

  if (ss.ss_family == AF_INET) {
    *port = ntohs((reinterpret_cast<sockaddr_in*>(&ss))->sin_port);
  } else if (ss.ss_family == AF_INET6) {
    *port = ntohs((reinterpret_cast<sockaddr_in6*>(&ss))->sin6_port);
  } else {
    ABSL_RAW_LOG(ERROR, "Unknown address family %d", ss.ss_family);
  }
}

}  // namespace

bool EvHTTPServer::StartAcceptingRequests() {
  if (ev_http_ == nullptr) {
    ABSL_RAW_LOG(FATAL, "Server has not been successfully initialized");
    return false;
  }

  const int port = server_options_->ports().front();

  // "::"  =>  in6addr_any
  ev_uint16_t ev_port = static_cast<ev_uint16_t>(port);
  ev_listener_ = evhttp_bind_socket_with_handle(ev_http_, "::", ev_port);
  if (ev_listener_ == nullptr) {
    // in case ipv6 is not supported, fallback to inaddr_any
    ev_listener_ = evhttp_bind_socket_with_handle(ev_http_, nullptr, ev_port);
    if (ev_listener_ == nullptr) {
      ABSL_RAW_LOG(FATAL, "Couldn't bind to port %d", port);
      return false;
    }
  }

  // Listener counts as an active operation
  IncOps();

  port_ = port;
  if (port_ == 0) {
    ResolveEphemeralPort(ev_listener_, &port_);
  }

  IncOps();
  server_options_->executor()->Schedule([this]() {
    ABSL_RAW_LOG(INFO, "Entering the event loop ...");
    int result = event_base_dispatch(ev_base_);
    ABSL_RAW_LOG(INFO, "event_base_dispatch() exits with value %d", result);

    DecOps();
  });

  accepting_requests_.Notify();

  return true;
}

int EvHTTPServer::listen_port() const { return port_; }

bool EvHTTPServer::is_accepting_requests() const {
  return accepting_requests_.HasBeenNotified();
}

void EvHTTPServer::Terminate() {
  if (!is_accepting_requests()) {
    ABSL_RAW_LOG(ERROR, "Server is not running ...");
    return;
  }

  if (is_terminating()) {
    ABSL_RAW_LOG(ERROR, "Server is already being terminated ...");
    return;
  }

  terminating_.Notify();

  // call exit-loop from the event loop
  this->EventLoopSchedule([this]() {
    // Stop the listener first, which will delete ev_listener_
    // This may cause the loop to exit, so need be scheduled from within
    evhttp_del_accept_socket(ev_http_, ev_listener_);
    DecOps();
  });

  // Current shut-down behavior:
  // - we don't proactively delete/close any HTTP connections as part of
  //   Terminate(). This is not an issue as we don't support read-streaming yet.
  // - we don't wait for all dispatched requests to run to completion
  //   before we stop the event loop.
  // - and otherwise, this is meant to be a clean shutdown
}

bool EvHTTPServer::is_terminating() const {
  return terminating_.HasBeenNotified();
}

void EvHTTPServer::IncOps() {
  absl::MutexLock l(&ops_mu_);
  num_pending_ops_++;
}

void EvHTTPServer::DecOps() {
  absl::MutexLock l(&ops_mu_);
  num_pending_ops_--;
}

void EvHTTPServer::WaitForTermination() {
  {
    absl::MutexLock l(&ops_mu_);
    ops_mu_.Await(absl::Condition(+[](int64_t* count) { return *count <= 1; },
                                  &num_pending_ops_));
  }

  int result = event_base_loopexit(ev_base_, nullptr);
  ABSL_RAW_LOG(INFO, "event_base_loopexit() exits with value %d", result);

  {
    absl::MutexLock l(&ops_mu_);
    ops_mu_.Await(absl::Condition(+[](int64_t* count) { return *count == 0; },
                                  &num_pending_ops_));
  }
}

bool EvHTTPServer::WaitForTerminationWithTimeout(absl::Duration timeout) {
  bool wait_result = true;

  {
    absl::MutexLock l(&ops_mu_);
    wait_result = ops_mu_.AwaitWithTimeout(
        absl::Condition(+[](int64_t* count) { return *count <= 1; },
                        &num_pending_ops_),
        timeout);
  }

  if (wait_result) {
    int result = event_base_loopexit(ev_base_, nullptr);
    ABSL_RAW_LOG(INFO, "event_base_loopexit() exits with value %d", result);

    // This should pass immediately
    {
      absl::MutexLock l(&ops_mu_);
      wait_result = ops_mu_.AwaitWithTimeout(
          absl::Condition(+[](int64_t* count) { return *count == 0; },
                          &num_pending_ops_),
          timeout);
    }
  }

  return wait_result;
}

EvHTTPServer::UriHandlerInfo::UriHandlerInfo(
    absl::string_view uri_in, RequestHandler handler_in,
    const RequestHandlerOptions& options_in)
    : uri(uri_in.data(), uri_in.size()),
      handler(std::move(handler_in)),
      options(options_in) {}

EvHTTPServer::DispatcherInfo::DispatcherInfo(
    RequestDispatcher dispatcher_in, const RequestHandlerOptions& options_in)
    : dispatcher(std::move(dispatcher_in)), options(options_in) {}

void EvHTTPServer::RegisterRequestHandler(
    absl::string_view uri, RequestHandler handler,
    const RequestHandlerOptions& options) {
  absl::MutexLock l(&request_mu_);
  auto result = uri_handlers_.emplace(
      std::piecewise_construct, std::forward_as_tuple(uri),
      std::forward_as_tuple(uri, handler, options));

  if (!result.second) {
    ABSL_RAW_LOG(INFO,
                 "Overwrite the existing handler registered under "
                 "the URI path %.*s",
                 static_cast<int>(uri.size()), uri.data());

    uri_handlers_.erase(result.first);
    if (!uri_handlers_
             .emplace(std::piecewise_construct, std::forward_as_tuple(uri),
                      std::forward_as_tuple(uri, handler, options))
             .second) {
      ABSL_RAW_LOG(ERROR,
                   "Failed to register an handler under the URI path %.*s",
                   static_cast<int>(uri.size()), uri.data());
    }
  }
}

void EvHTTPServer::RegisterRequestDispatcher(
    RequestDispatcher dispatcher, const RequestHandlerOptions& options) {
  absl::MutexLock l(&request_mu_);
  dispatchers_.emplace_back(dispatcher, options);
}

namespace {

void EvImmediateCallback(evutil_socket_t socket, int16_t flags, void* arg) {
  auto fn = static_cast<std::function<void()>*>(arg);
  (*fn)();
  delete fn;
}

}  // namespace

bool EvHTTPServer::EventLoopSchedule(std::function<void()> fn) {
  auto scheduled_fn = new std::function<void()>(std::move(fn));
  int result = event_base_once(ev_base_, -1, EV_TIMEOUT, EvImmediateCallback,
                               static_cast<void*>(scheduled_fn), immediate_);
  return result == 0;
}

}  // namespace net_http
}  // namespace serving
}  // namespace tensorflow
<|endoftext|>


<commit_before>//project
#include "SuperRegion.h"

SuperRegion::SuperRegion()
	: reward(0)
{
}

SuperRegion::SuperRegion(const int& pReward)
	: reward(pReward)
{
}

SuperRegion::~SuperRegion()
{
}

void SuperRegion::addRegion(const int& region)
{
	regions.push_back(region);
}
<commit_msg>added methods to SuperRegion<commit_after>//project
#include "SuperRegion.h"

SuperRegion::SuperRegion()
	: reward(0), Counterwastelands(0), neutrals(0), WASTESIZE(6)
{
}

SuperRegion::SuperRegion(const int& pReward)
	: reward(pReward)
{
}

SuperRegion::~SuperRegion()
{
}

void SuperRegion::addRegion(const int& region)
{
	regions.push_back(region);
}
void SuperRegion::calcWastelands(std::vector<int> Wastelands)
{
  for(int j=0; j < Wastelands.size(); ++j)
	for (int i = 0; i < regions.size(); ++i)
	{
		if (regions[i] == Wastelands[j])
		{
			Counterwastelands = Wastelands;
			break;
		}
	}
  calcNeutrals();
}
void SuperRegion::calcNeutrals()
{
	neutrals = regions.size()*2;
	neutrals += Counterwastelands* WASTESIZE;
}<|endoftext|>


<commit_before>/*
   Copyright 2012 Tzvetan Mikov <tmikov@gmail.com>
   All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef SYMBOLTABLE_HPP
#define	SYMBOLTABLE_HPP

#include <list>

#include <boost/unordered_map.hpp>

#include "base.hpp"
#include "SourceCoords.hpp"

#define _DEF_RESWORDS \
  _MK_ENUM(NONE) \
  _MK_ENUM(QUOTE) \
/* Handled by a macro \
  _MK_ENUM(QUASIQUOTE) \
  _MK_ENUM(UNQUOTE) \
  _MK_ENUM(UNQUOTE_SPLICING) \
*/ \
  _MK_ENUM(SYNTAX) \
  _MK_ENUM(QUASISYNTAX) \
  _MK_ENUM(UNSYNTAX) \
  _MK_ENUM(UNSYNTAX_SPLICING) \
  \
  _MK_ENUM(IF) \
  _MK_ENUM(BEGIN) \
  _MK_ENUM(LAMBDA) \
  _MK_ENUM(DEFINE) \
  _MK_ENUM(SETBANG) \
  _MK_ENUM(LET) \
  _MK_ENUM(LETREC) \
  _MK_ENUM(LETREC_STAR) \
  \
  _MK_ENUM(BUILTIN) \
  _MK_ENUM(DEFINE_MACRO) \
  _MK_ENUM(DEFINE_IDENTIFIER_MACRO) \
  _MK_ENUM(DEFINE_SET_MACRO) \
  _MK_ENUM(MACRO_ENV) \
  \
  _MK_ENUM(UNSPECIFIED)

struct ResWord
{
  #define _MK_ENUM(x)  x,
  enum Enum
  {
    _DEF_RESWORDS
  };
  #undef _MK_ENUM

  static const char * name ( Enum x )  { return s_names[x]; }
private:
  static const char * s_names[];
};

class Binding;
class Symbol;
class Scope;
class SymbolTable;

#define _DEF_BIND_TYPES \
  _MK_ENUM(NONE) \
  _MK_ENUM(RESWORD) \
  _MK_ENUM(VAR)

struct BindingType
{
  #define _MK_ENUM(x)  x,
  enum Enum
  {
    _DEF_BIND_TYPES
  };
  #undef _MK_ENUM

  static const char * name ( Enum x )  { return s_names[x]; }
private:
  static const char * s_names[];
};

class Scope : public gc
{
public:
  Scope ( SymbolTable * symbolTable, Scope * parent_ )
    : m_symbolTable(symbolTable), parent( parent_ ), level(parent?parent->level+1:-1)
  {
    m_bindingList = NULL;
    m_active = false;
  }

  /**
    *
    * @param res
    * @param sym
    * @return true if a new symbol was defined, false if it was already present in the scope
    */
  bool bind ( Binding * & res, Symbol * sym, BindingType::Enum btype, const SourceCoords & defCoords );
  Binding * lookupOnlyHere ( Symbol * sym );
  Binding * lookupHereAndUp ( Symbol * sym );

  void addToBindingList ( Binding * bnd );

  bool isActive () const { return m_active; }

public:
  Scope * const parent;
  int const level;

private:
  SymbolTable * const m_symbolTable;
  Binding * m_bindingList; //< linking Binding::prevInScope
  bool m_active;

  void popBindings ();

  friend class SymbolTable;
};

class Binding : public gc
{
public:
  Binding ( Symbol * sym_, Scope * scope_, BindingType::Enum btype_, const SourceCoords & defCoords_ )
    : sym(sym_), scope(scope_), btype(btype_), defCoords(defCoords_)
  {
    this->prev = NULL;
  }

  Symbol * const sym;
  Scope * const scope;
  SourceCoords defCoords; //< coordinates of the source definition

  const BindingType::Enum btype;
  union
  {
    ResWord::Enum resWord;
    class Variable * var;
  } u;

private:
  Binding * prev; //< the same symbol in the previous scope
  Binding * prevInScope; //< link to the prev binding in our scope

  friend class Scope;
  friend class Symbol;
};

std::ostream & operator << ( std::ostream & os, Binding & bnd );

inline void Scope::addToBindingList ( Binding * bnd )
{
  assert( bnd->prevInScope == NULL );
  bnd->prevInScope = m_bindingList;
  m_bindingList = bnd;
}

struct Symbol : public gc, public boost::noncopyable
{
  Symbol ( const gc_char * name_, uint32_t uid_ )
    : name( name_ ), uid( uid_ )
  {
    top = NULL;
  }

  void push ( Binding * bind )
  {
    bind->prev = this->top;
    this->top = bind;
  }

  void pop ( Binding * bnd )
  {
    assert( this->top == bnd );
    this->top = this->top->prev;
  }

  const gc_char * const name;
  uint32_t const uid; //< different value for each symbol
  Binding * top;
};

class SymbolTable : public gc
{
public:
  SymbolTable();
  ~SymbolTable();

  Symbol * newSymbol ( const gc_char * name );

  Binding * lookup ( const Symbol * sym )
  {
    return sym->top;
  }

  Scope * newScope ();

  void popThisScope ( Scope * scope )
  {
    assert( m_topScope == scope );
    popScope();
  }

  void popScope ();

  Scope * topScope () const { return m_topScope; }

private:
  struct gc_charstr_equal : public std::binary_function<const gc_char *,const gc_char *,bool>
  {
    bool operator () ( const gc_char * a, const gc_char * b ) const
    {
      return std::strcmp( a, b ) == 0;
    }
  };

  struct gc_charstr_hash : std::unary_function<const gc_char *, std::size_t>
  {
    std::size_t operator () ( const gc_char * a ) const
    {
      std::size_t seed = 0;
      unsigned t;
      while ( (t = *((unsigned char *)a)) != 0)
      {
        boost::hash_combine( seed, t );
        ++a;
      }
      return seed;
    }
  };

  typedef boost::unordered_map<const gc_char *,
                               Symbol *,
                               gc_charstr_hash,
                               gc_charstr_equal,
                               gc_allocator<const gc_char *> > Map;
  Map m_map;
  uint32_t m_uid;
  Scope * m_topScope;
};

class ScopePopper
{
public:
  ScopePopper ( SymbolTable & symbolTable, Scope * scope ) : m_symbolTable(symbolTable), m_scope(scope) {};

  ~ScopePopper ()
  {
    m_symbolTable.popThisScope(m_scope);
  }
private:
  SymbolTable & m_symbolTable;
  Scope * m_scope;
};

#endif	/* SYMBOLTABLE_HPP */

<commit_msg>SymbolTable: add Macro<commit_after>/*
   Copyright 2012 Tzvetan Mikov <tmikov@gmail.com>
   All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef SYMBOLTABLE_HPP
#define	SYMBOLTABLE_HPP

#include <list>

#include <boost/unordered_map.hpp>

#include "base.hpp"
#include "SourceCoords.hpp"

#define _DEF_RESWORDS \
  _MK_ENUM(NONE) \
  _MK_ENUM(QUOTE) \
/* Handled by a macro \
  _MK_ENUM(QUASIQUOTE) \
  _MK_ENUM(UNQUOTE) \
  _MK_ENUM(UNQUOTE_SPLICING) \
*/ \
  _MK_ENUM(SYNTAX) \
  _MK_ENUM(QUASISYNTAX) \
  _MK_ENUM(UNSYNTAX) \
  _MK_ENUM(UNSYNTAX_SPLICING) \
  \
  _MK_ENUM(IF) \
  _MK_ENUM(BEGIN) \
  _MK_ENUM(LAMBDA) \
  _MK_ENUM(DEFINE) \
  _MK_ENUM(SETBANG) \
  _MK_ENUM(LET) \
  _MK_ENUM(LETREC) \
  _MK_ENUM(LETREC_STAR) \
  \
  _MK_ENUM(BUILTIN) \
  _MK_ENUM(DEFINE_MACRO) \
  _MK_ENUM(DEFINE_IDENTIFIER_MACRO) \
  _MK_ENUM(DEFINE_SET_MACRO) \
  _MK_ENUM(MACRO_ENV) \
  \
  _MK_ENUM(UNSPECIFIED)

struct ResWord
{
  #define _MK_ENUM(x)  x,
  enum Enum
  {
    _DEF_RESWORDS
  };
  #undef _MK_ENUM

  static const char * name ( Enum x )  { return s_names[x]; }
private:
  static const char * s_names[];
};

class Binding;
class Symbol;
class Scope;
class SymbolTable;

#define _DEF_BIND_TYPES \
  _MK_ENUM(NONE) \
  _MK_ENUM(RESWORD) \
  _MK_ENUM(VAR) \
  _MK_ENUM(MACRO)

struct BindingType
{
  #define _MK_ENUM(x)  x,
  enum Enum
  {
    _DEF_BIND_TYPES
  };
  #undef _MK_ENUM

  static const char * name ( Enum x )  { return s_names[x]; }
private:
  static const char * s_names[];
};

class Scope : public gc
{
public:
  Scope ( SymbolTable * symbolTable, Scope * parent_ )
    : m_symbolTable(symbolTable), parent( parent_ ), level(parent?parent->level+1:-1)
  {
    m_bindingList = NULL;
    m_active = false;
  }

  /**
    *
    * @param res
    * @param sym
    * @return true if a new symbol was defined, false if it was already present in the scope
    */
  bool bind ( Binding * & res, Symbol * sym, BindingType::Enum btype, const SourceCoords & defCoords );
  Binding * lookupOnlyHere ( Symbol * sym );
  Binding * lookupHereAndUp ( Symbol * sym );

  void addToBindingList ( Binding * bnd );

  bool isActive () const { return m_active; }

public:
  Scope * const parent;
  int const level;

private:
  SymbolTable * const m_symbolTable;
  Binding * m_bindingList; //< linking Binding::prevInScope
  bool m_active;

  void popBindings ();

  friend class SymbolTable;
};

class Syntax;

class Macro : public gc
{
public:
  Scope * const scope;
  Macro ( Scope * scope_ ) : scope(scope_) {}
  virtual Syntax * expand ( Syntax * datum ) = 0;
};

class Binding : public gc
{
public:
  Binding ( Symbol * sym_, Scope * scope_, BindingType::Enum btype_, const SourceCoords & defCoords_ )
    : sym(sym_), scope(scope_), btype(btype_), defCoords(defCoords_)
  {
    this->prev = NULL;
  }

  Symbol * const sym;
  Scope * const scope;
  SourceCoords defCoords; //< coordinates of the source definition

  const BindingType::Enum btype;
  union
  {
    ResWord::Enum resWord;
    class Variable * var;
    Macro * macro;
  } u;

private:
  Binding * prev; //< the same symbol in the previous scope
  Binding * prevInScope; //< link to the prev binding in our scope

  friend class Scope;
  friend class Symbol;
};

std::ostream & operator << ( std::ostream & os, Binding & bnd );

inline void Scope::addToBindingList ( Binding * bnd )
{
  assert( bnd->prevInScope == NULL );
  bnd->prevInScope = m_bindingList;
  m_bindingList = bnd;
}

struct Symbol : public gc, public boost::noncopyable
{
  Symbol ( const gc_char * name_, uint32_t uid_ )
    : name( name_ ), uid( uid_ )
  {
    top = NULL;
  }

  void push ( Binding * bind )
  {
    bind->prev = this->top;
    this->top = bind;
  }

  void pop ( Binding * bnd )
  {
    assert( this->top == bnd );
    this->top = this->top->prev;
  }

  const gc_char * const name;
  uint32_t const uid; //< different value for each symbol
  Binding * top;
};

class SymbolTable : public gc
{
public:
  SymbolTable();
  ~SymbolTable();

  Symbol * newSymbol ( const gc_char * name );

  Binding * lookup ( const Symbol * sym )
  {
    return sym->top;
  }

  Scope * newScope ();

  void popThisScope ( Scope * scope )
  {
    assert( m_topScope == scope );
    popScope();
  }

  void popScope ();

  Scope * topScope () const { return m_topScope; }

private:
  struct gc_charstr_equal : public std::binary_function<const gc_char *,const gc_char *,bool>
  {
    bool operator () ( const gc_char * a, const gc_char * b ) const
    {
      return std::strcmp( a, b ) == 0;
    }
  };

  struct gc_charstr_hash : std::unary_function<const gc_char *, std::size_t>
  {
    std::size_t operator () ( const gc_char * a ) const
    {
      std::size_t seed = 0;
      unsigned t;
      while ( (t = *((unsigned char *)a)) != 0)
      {
        boost::hash_combine( seed, t );
        ++a;
      }
      return seed;
    }
  };

  typedef boost::unordered_map<const gc_char *,
                               Symbol *,
                               gc_charstr_hash,
                               gc_charstr_equal,
                               gc_allocator<const gc_char *> > Map;
  Map m_map;
  uint32_t m_uid;
  Scope * m_topScope;
};

class ScopePopper
{
public:
  ScopePopper ( SymbolTable & symbolTable, Scope * scope ) : m_symbolTable(symbolTable), m_scope(scope) {};

  ~ScopePopper ()
  {
    m_symbolTable.popThisScope(m_scope);
  }
private:
  SymbolTable & m_symbolTable;
  Scope * m_scope;
};

#endif	/* SYMBOLTABLE_HPP */

<|endoftext|>