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

  Program:   Visualization Toolkit
  Module:    vtkPoints.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 "vtkPoints.h"

#include "vtkBitArray.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkLongArray.h"
#include "vtkObjectFactory.h"
#include "vtkShortArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"

vtkCxxRevisionMacro(vtkPoints, "1.55");

//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkPoints);

//----------------------------------------------------------------------------
vtkPoints* vtkPoints::New(int dataType)
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkPoints");
  if(ret)
    {
    if(dataType != VTK_FLOAT)
      {
      static_cast<vtkPoints*>(ret)->SetDataType(dataType);
      }
    return static_cast<vtkPoints*>(ret);
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkPoints(dataType);
}

vtkPoints* vtkPoints::New()
{
  return vtkPoints::New(VTK_FLOAT);
}

// Construct object with an initial data array of type float.
vtkPoints::vtkPoints(int dataType)
{
  this->Data = vtkFloatArray::New();
  this->Data->Register(this);
  this->Data->Delete();
  this->SetDataType(dataType);

  this->Data->SetNumberOfComponents(3);
  this->Data->SetName("Points");

  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = 0.0;
  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
}

vtkPoints::~vtkPoints()
{
  this->Data->UnRegister(this);
}

// Given a list of pt ids, return an array of points.
void vtkPoints::GetPoints(vtkIdList *ptIds, vtkPoints *fp)
{
  vtkIdType num = ptIds->GetNumberOfIds();

  for (vtkIdType i=0; i < num; i++)
    {
    fp->InsertPoint(i, this->GetPoint(ptIds->GetId(i)));
    }
}

// Determine (xmin,xmax, ymin,ymax, zmin,zmax) bounds of points.
void vtkPoints::ComputeBounds()
{
  vtkIdType i;
  int j;
  double *x;

  if ( this->GetMTime() > this->ComputeTime )
    {
    this->Bounds[0] = this->Bounds[2] = this->Bounds[4] =  VTK_DOUBLE_MAX;
    this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
    for (i=0; i<this->GetNumberOfPoints(); i++)
      {
      x = this->GetPoint(i);
      for (j=0; j<3; j++)
        {
        if ( x[j] < this->Bounds[2*j] )
          {
          this->Bounds[2*j] = x[j];
          }
        if ( x[j] > this->Bounds[2*j+1] )
          {
          this->Bounds[2*j+1] = x[j];
          }
        }
      }

    this->ComputeTime.Modified();
    }
}

// Return the bounds of the points.
double *vtkPoints::GetBounds()
{
  this->ComputeBounds();
  return this->Bounds;
}

// Return the bounds of the points.
void vtkPoints::GetBounds(double bounds[6])
{
  this->ComputeBounds();
  for (int i=0; i<6; i++)
    {
    bounds[i] = this->Bounds[i];
    }
}

int vtkPoints::Allocate(const vtkIdType sz, const vtkIdType ext)
{
  int numComp=this->Data->GetNumberOfComponents();
  return this->Data->Allocate(sz*numComp,ext*numComp);
}

void vtkPoints::Initialize()
{
  this->Data->Initialize();
}

int vtkPoints::GetDataType()
{
  return this->Data->GetDataType();
}

// Specify the underlying data type of the object.
void vtkPoints::SetDataType(int dataType)
{
  if ( dataType == this->Data->GetDataType() )
    {
    return;
    }

  this->Modified();

  this->Data->Delete();
  this->Data = vtkDataArray::CreateDataArray(dataType);
  this->Data->SetNumberOfComponents(3);
  this->Data->SetName("Points");
}

// Set the data for this object. The tuple dimension must be consistent with
// the object.
void vtkPoints::SetData(vtkDataArray *data)
{
  if ( data != this->Data && data != NULL )
    {
    if (data->GetNumberOfComponents() != this->Data->GetNumberOfComponents() )
      {
      vtkErrorMacro(<<"Number of components is different...can't set data");
      return;
      }
    this->Data->UnRegister(this);
    this->Data = data;
    this->Data->Register(this);
    this->Modified();
    }
}

// Deep copy of data. Checks consistency to make sure this operation
// makes sense.
void vtkPoints::DeepCopy(vtkPoints *da)
{
  if (da == NULL)
    {
    return;
    }
  if ( da->Data != this->Data && da->Data != NULL )
    {
    if (da->Data->GetNumberOfComponents() != this->Data->GetNumberOfComponents() )
      {
      vtkErrorMacro(<<"Number of components is different...can't copy");
      return;
      }
    this->Data->DeepCopy(da->Data);
    this->Modified();
    }
}

// Shallow copy of data (i.e. via reference counting). Checks
// consistency to make sure this operation makes sense.
void vtkPoints::ShallowCopy(vtkPoints *da)
{
  this->SetData(da->GetData());
}

unsigned long vtkPoints::GetActualMemorySize()
{
  return this->Data->GetActualMemorySize();
}

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

  double *bounds;

  os << indent << "Data: " << this->Data << "\n";
  if ( this->Data )
    {
    if ( this->Data->GetName() )
      {
      os << indent << "Data Array Name: " << this->Data->GetName() << "\n";
      }
    else
      {
      os << indent << "Data Array Name: (none)\n";
      }
    }

  os << indent << "Number Of Points: " << this->GetNumberOfPoints() << "\n";
  bounds = this->GetBounds();
  os << indent << "Bounds: \n";
  os << indent << "  Xmin,Xmax: (" << bounds[0] << ", " << bounds[1] << ")\n";
  os << indent << "  Ymin,Ymax: (" << bounds[2] << ", " << bounds[3] << ")\n";
  os << indent << "  Zmin,Zmax: (" << bounds[4] << ", " << bounds[5] << ")\n";
}
<commit_msg>BUG: Assign some default name to points array.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPoints.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 "vtkPoints.h"

#include "vtkBitArray.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkLongArray.h"
#include "vtkObjectFactory.h"
#include "vtkShortArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"

vtkCxxRevisionMacro(vtkPoints, "1.56");

//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkPoints);

//----------------------------------------------------------------------------
vtkPoints* vtkPoints::New(int dataType)
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkPoints");
  if(ret)
    {
    if(dataType != VTK_FLOAT)
      {
      static_cast<vtkPoints*>(ret)->SetDataType(dataType);
      }
    return static_cast<vtkPoints*>(ret);
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkPoints(dataType);
}

vtkPoints* vtkPoints::New()
{
  return vtkPoints::New(VTK_FLOAT);
}

// Construct object with an initial data array of type float.
vtkPoints::vtkPoints(int dataType)
{
  this->Data = vtkFloatArray::New();
  this->Data->Register(this);
  this->Data->Delete();
  this->SetDataType(dataType);

  this->Data->SetNumberOfComponents(3);
  this->Data->SetName("Points");

  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = 0.0;
  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
}

vtkPoints::~vtkPoints()
{
  this->Data->UnRegister(this);
}

// Given a list of pt ids, return an array of points.
void vtkPoints::GetPoints(vtkIdList *ptIds, vtkPoints *fp)
{
  vtkIdType num = ptIds->GetNumberOfIds();

  for (vtkIdType i=0; i < num; i++)
    {
    fp->InsertPoint(i, this->GetPoint(ptIds->GetId(i)));
    }
}

// Determine (xmin,xmax, ymin,ymax, zmin,zmax) bounds of points.
void vtkPoints::ComputeBounds()
{
  vtkIdType i;
  int j;
  double *x;

  if ( this->GetMTime() > this->ComputeTime )
    {
    this->Bounds[0] = this->Bounds[2] = this->Bounds[4] =  VTK_DOUBLE_MAX;
    this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
    for (i=0; i<this->GetNumberOfPoints(); i++)
      {
      x = this->GetPoint(i);
      for (j=0; j<3; j++)
        {
        if ( x[j] < this->Bounds[2*j] )
          {
          this->Bounds[2*j] = x[j];
          }
        if ( x[j] > this->Bounds[2*j+1] )
          {
          this->Bounds[2*j+1] = x[j];
          }
        }
      }

    this->ComputeTime.Modified();
    }
}

// Return the bounds of the points.
double *vtkPoints::GetBounds()
{
  this->ComputeBounds();
  return this->Bounds;
}

// Return the bounds of the points.
void vtkPoints::GetBounds(double bounds[6])
{
  this->ComputeBounds();
  for (int i=0; i<6; i++)
    {
    bounds[i] = this->Bounds[i];
    }
}

int vtkPoints::Allocate(const vtkIdType sz, const vtkIdType ext)
{
  int numComp=this->Data->GetNumberOfComponents();
  return this->Data->Allocate(sz*numComp,ext*numComp);
}

void vtkPoints::Initialize()
{
  this->Data->Initialize();
}

int vtkPoints::GetDataType()
{
  return this->Data->GetDataType();
}

// Specify the underlying data type of the object.
void vtkPoints::SetDataType(int dataType)
{
  if ( dataType == this->Data->GetDataType() )
    {
    return;
    }

  this->Modified();

  this->Data->Delete();
  this->Data = vtkDataArray::CreateDataArray(dataType);
  this->Data->SetNumberOfComponents(3);
  this->Data->SetName("Points");
}

// Set the data for this object. The tuple dimension must be consistent with
// the object.
void vtkPoints::SetData(vtkDataArray *data)
{
  if ( data != this->Data && data != NULL )
    {
    if (data->GetNumberOfComponents() != this->Data->GetNumberOfComponents() )
      {
      vtkErrorMacro(<<"Number of components is different...can't set data");
      return;
      }
    this->Data->UnRegister(this);
    this->Data = data;
    this->Data->Register(this);
    if (!this->Data->GetName())
      {
      this->Data->SetName("Points");
      }
    this->Modified();
    }
}

// Deep copy of data. Checks consistency to make sure this operation
// makes sense.
void vtkPoints::DeepCopy(vtkPoints *da)
{
  if (da == NULL)
    {
    return;
    }
  if ( da->Data != this->Data && da->Data != NULL )
    {
    if (da->Data->GetNumberOfComponents() != this->Data->GetNumberOfComponents() )
      {
      vtkErrorMacro(<<"Number of components is different...can't copy");
      return;
      }
    this->Data->DeepCopy(da->Data);
    this->Modified();
    }
}

// Shallow copy of data (i.e. via reference counting). Checks
// consistency to make sure this operation makes sense.
void vtkPoints::ShallowCopy(vtkPoints *da)
{
  this->SetData(da->GetData());
}

unsigned long vtkPoints::GetActualMemorySize()
{
  return this->Data->GetActualMemorySize();
}

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

  double *bounds;

  os << indent << "Data: " << this->Data << "\n";
  if ( this->Data )
    {
    if ( this->Data->GetName() )
      {
      os << indent << "Data Array Name: " << this->Data->GetName() << "\n";
      }
    else
      {
      os << indent << "Data Array Name: (none)\n";
      }
    }

  os << indent << "Number Of Points: " << this->GetNumberOfPoints() << "\n";
  bounds = this->GetBounds();
  os << indent << "Bounds: \n";
  os << indent << "  Xmin,Xmax: (" << bounds[0] << ", " << bounds[1] << ")\n";
  os << indent << "  Ymin,Ymax: (" << bounds[2] << ", " << bounds[3] << ")\n";
  os << indent << "  Zmin,Zmax: (" << bounds[4] << ", " << bounds[5] << ")\n";
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @mss_const.H
/// @This file contains constants for the memory team.
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_CONST_H_
#define _MSS_CONST_H_

namespace mss
{

enum sizes
{
    PORTS_PER_MCS = 2,
    PORTS_PER_MCBIST = 4,
    MAX_DIMM_PER_PORT = 2,
    MAX_RANK_PER_DIMM = 4,
    RANK_MID_POINT = 4,            ///< Which rank number indicates the switch to the other DIMM
    DEFAULT_POLL_LIMIT = 10,       ///< the number of poll attempts in the event we can't calculate another
    MAX_NUM_IMP = 4,               ///< number of impedances valid per slew type
    MAX_NUM_CAL_SLEW_RATES = 4,    ///< 3V/ns, 4V/ns, 5V/ns, 6V/n
    MAX_SLEW_VALUE = 15,           ///< 4 bit value
    MAX_SUPPORTED_FREQUENCIES = 1, ///< Number of supported frequencies. Right now it's only 2400

    // All need to be attributes - BRS
    // 48:51, 0b1100, (def_is_sim);       # BIG_STEP = 12 (changed from default for SIM)
    // 48:51, 0b0000, any;       # BIG_STEP = 0  SWyatt
    // #48:51, 0b0010, any;       # BIG_STEP = 2  (default)
    // 52:54,  0b000,  any;       # SMALL_STEP = 0 (default)      SWyatt
    //#52:54,  0b001,  any;       # SMALL_STEP = 1        (!! recommend setting to 0)
    // 55:60,  0b101010, any;     # WR_PRE_DLY = 42
    WR_LVL_BIG_STEP = 0b1100,
    WR_LVL_SMALL_STEP = 0b000,
    WR_LVL_PRE_DLY = 0b101010,
    WR_LVL_NUM_VALID_SAMPLES = 0x5,

    // THIS IS LIKELY INCORRECT - Should be defined in the DDR4 write centering protocol BRS
    // This field must be set to the larger of the two values in number of memory clock cycles.
    // FW_RD_WR = max(tWTR + 11, AL + tRTP + 3)
    WR_CNTR_FW_RD_WR = 0x11 + 4,
    WR_CNTR_FW_WR_RD = 0x0,

    // Attribute? BRS
    COARSE_CAL_STEP_SIZE = 0x4,
    CONSEQ_PASS = 0x8,
};

enum times
{
    CONVERT_PS_IN_A_NS      = 1000,     ///< 1000 pico in an nano
    CONVERT_PS_IN_A_US      = 1000000,  ///< 1000000 picos in a micro

    DELAY_1NS               = 1,
    DELAY_10NS              = 10 ,      ///< general purpose 10  ns delay for HW mode
    DELAY_100NS             = 100,      ///< general purpose 100 ns delay for HW mode
    DELAY_1US               = 1000,     ///< general purpose 1 usec delay for HW mode
    DELAY_100US             = 100000,   ///< general purpose 100 usec delay for HW mode

    // From the DDR4spec 2400 speed - need to be changed to read attributes. BRS
    tWLO = 10,
    tWLOE = 2,
};

enum states
{
    LOW = 0,
    HIGH = 1,
    START = 1,
    STOP = 0,
    START_N = 0,
    STOP_N = 1,
    ON = 1,
    OFF = 0,
    ON_N = 0,
    OFF_N = 1,
    YES = 1,
    NO = 0,
    YES_N = 0,
    NO_N = 1,
    INVALID = 0xFF,

    // This needs to be an attribute I think - BRS. Used as a boolean.
    CAL_ABORT_ON_ERROR = 1,
};

// Static consts describing the bits used in the cal_step_enable attribute
// These are bit positions. 0 is the left most bit.
enum cal_steps
{
    EXT_ZQCAL         = 0,
    WR_LEVEL          = 1,
    DQS_ALIGN         = 2,
    RDCLK_ALIGN       = 3,
    READ_CTR          = 4,
    READ_CTR_2D_VREF  = 5,
    WRITE_CTR         = 6,
    WRITE_CTR_2D_VREF = 7,
    COARSE_WR         = 8,
    COARSE_RD         = 9,
};

namespace mcbist
{
enum data_mode
{
    // MCBIST test data modes
    FIXED_DATA_MODE   = 0b000,
    RAND_FWD_MODE     = 0b001,
    RAND_REV_MODE     = 0b010,
    RAND_FWD_MAINT    = 0b011,
    RAND_REV_MAINT    = 0b100,
    DATA_EQ_ADDR      = 0b101,
    ROTATE_LEFT_MODE  = 0b110,
    ROTATE_RIGHT_MODE = 0b111,
};

// 0:3  Operation Type
enum op_type
{
    WRITE            = 0b0000, // fast, with no concurrent traffic
    READ             = 0b0001, // fast, with no concurrent traffic
    READ_WRITE       = 0b0010,
    WRITE_READ       = 0b0011,
    READ_WRITE_READ  = 0b0100,
    READ_WRITE_WRITE = 0b0101,
    RAND_SEQ         = 0b0110,
    READ_READ_WRITE  = 0b1000,
    SCRUB_RRWR       = 0b1001,
    STEER_RW         = 0b1010,
    ALTER            = 0b1011, // (W)
    DISPLAY          = 0b1100, // (R, slow)
    CCS_EXECUTE      = 0b1111,

    // if bits 9:11 (Data Mode bits)  = 000  (bits 4:8 used to specify which subtest to go to)
    // Refresh only cmd if bits 9:11 (Data Mode bits) /= 000
    GOTO_SUBTEST_N = 0b0111,
};

enum test_type
{
    USER_MODE = 0,
    CENSHMOO = 1,
    SUREFAIL = 2,
    MEMWRITE = 3,
    MEMREAD = 4,
    CBR_REFRESH = 5,
    MCBIST_SHORT = 6,
    SHORT_SEQ = 7,
    DELTA_I = 8,
    DELTA_I_LOOP = 9,
    SHORT_RAND = 10,
    LONG1 = 11,
    BUS_TAT = 12,
    SIMPLE_FIX = 13,
    SIMPLE_RAND = 14,
    SIMPLE_RAND_2W = 15,
    SIMPLE_RAND_FIXD = 16,
    SIMPLE_RA_RD_WR = 17,
    SIMPLE_RA_RD_R = 18,
    SIMPLE_RA_FD_R = 19,
    SIMPLE_RA_FD_R_INF = 20,
    SIMPLE_SA_FD_R = 21,
    SIMPLE_RA_FD_W = 22,
    INFINITE = 23,
    WR_ONLY = 24,
    W_ONLY = 25,
    R_ONLY = 26,
    W_ONLY_RAND = 27,
    R_ONLY_RAND = 28,
    R_ONLY_MULTI = 29,
    SHORT = 30,
    SIMPLE_RAND_BARI = 31,
    W_R_INFINITE = 32,
    W_R_RAND_INFINITE = 33,
    R_INFINITE1 = 34,
    R_INFINITE_RF = 35,
    MARCH = 36,
    SIMPLE_FIX_RF = 37,
    SHMOO_STRESS = 38,
    SIMPLE_RAND_RA = 39,
    SIMPLE_FIX_RA = 40,
    SIMPLE_FIX_RF_RA = 41,
    TEST_RR = 42,
    TEST_RF = 43,
    W_ONLY_INFINITE_RAND = 44,
    MCB_2D_CUP_SEQ = 45,
    MCB_2D_CUP_RAND = 46,
    SHMOO_STRESS_INFINITE = 47,
    HYNIX_1_COL = 48,
    RMWFIX = 49,
    RMWFIX_I = 50,
    W_INFINITE = 51,
    R_INFINITE = 52,
};

} // namespace mcbist

}
#endif
<commit_msg>Add L2 p9_mss_scrub<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @mss_const.H
/// @This file contains constants for the memory team.
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_CONST_H_
#define _MSS_CONST_H_

namespace mss
{

enum sizes
{
    PORTS_PER_MCS = 2,
    PORTS_PER_MCBIST = 4,
    MAX_DIMM_PER_PORT = 2,
    MAX_RANK_PER_DIMM = 4,
    RANK_MID_POINT = 4,            ///< Which rank number indicates the switch to the other DIMM
    DEFAULT_POLL_LIMIT = 10,       ///< the number of poll attempts in the event we can't calculate another
    MAX_NUM_IMP = 4,               ///< number of impedances valid per slew type
    MAX_NUM_CAL_SLEW_RATES = 4,    ///< 3V/ns, 4V/ns, 5V/ns, 6V/n
    MAX_SLEW_VALUE = 15,           ///< 4 bit value
    MAX_SUPPORTED_FREQUENCIES = 1, ///< Number of supported frequencies. Right now it's only 2400

    // All need to be attributes - BRS
    // 48:51, 0b1100, (def_is_sim);       # BIG_STEP = 12 (changed from default for SIM)
    // 48:51, 0b0000, any;       # BIG_STEP = 0  SWyatt
    // #48:51, 0b0010, any;       # BIG_STEP = 2  (default)
    // 52:54,  0b000,  any;       # SMALL_STEP = 0 (default)      SWyatt
    //#52:54,  0b001,  any;       # SMALL_STEP = 1        (!! recommend setting to 0)
    // 55:60,  0b101010, any;     # WR_PRE_DLY = 42
    WR_LVL_BIG_STEP = 0b1100,
    WR_LVL_SMALL_STEP = 0b000,
    WR_LVL_PRE_DLY = 0b101010,
    WR_LVL_NUM_VALID_SAMPLES = 0x5,

    // THIS IS LIKELY INCORRECT - Should be defined in the DDR4 write centering protocol BRS
    // This field must be set to the larger of the two values in number of memory clock cycles.
    // FW_RD_WR = max(tWTR + 11, AL + tRTP + 3)
    WR_CNTR_FW_RD_WR = 0x11 + 4,
    WR_CNTR_FW_WR_RD = 0x0,

    // Attribute? BRS
    COARSE_CAL_STEP_SIZE = 0x4,
    CONSEQ_PASS = 0x8,
};

enum times
{
    CONVERT_PS_IN_A_NS      = 1000,     ///< 1000 pico in an nano
    CONVERT_PS_IN_A_US      = 1000000,  ///< 1000000 picos in a micro

    DELAY_1NS               = 1,
    DELAY_10NS              = 10 ,      ///< general purpose 10  ns delay for HW mode
    DELAY_100NS             = 100,      ///< general purpose 100 ns delay for HW mode
    DELAY_1US               = 1000,     ///< general purpose 1 usec delay for HW mode
    DELAY_100US             = 100000,   ///< general purpose 100 usec delay for HW mode
    DELAY_1MS               = 1000000,  ///< general purpose 1 ms delay for HW mode

    // From the DDR4spec 2400 speed - need to be changed to read attributes. BRS
    tWLO = 10,
    tWLOE = 2,
};

enum states
{
    LOW = 0,
    HIGH = 1,
    START = 1,
    STOP = 0,
    START_N = 0,
    STOP_N = 1,
    ON = 1,
    OFF = 0,
    ON_N = 0,
    OFF_N = 1,
    YES = 1,
    NO = 0,
    YES_N = 0,
    NO_N = 1,
    INVALID = 0xFF,

    // This needs to be an attribute I think - BRS. Used as a boolean.
    CAL_ABORT_ON_ERROR = 1,
};

// Static consts describing the bits used in the cal_step_enable attribute
// These are bit positions. 0 is the left most bit.
enum cal_steps
{
    EXT_ZQCAL         = 0,
    WR_LEVEL          = 1,
    DQS_ALIGN         = 2,
    RDCLK_ALIGN       = 3,
    READ_CTR          = 4,
    READ_CTR_2D_VREF  = 5,
    WRITE_CTR         = 6,
    WRITE_CTR_2D_VREF = 7,
    COARSE_WR         = 8,
    COARSE_RD         = 9,
};

namespace mcbist
{
enum data_mode
{
    // MCBIST test data modes
    FIXED_DATA_MODE   = 0b000,
    RAND_FWD_MODE     = 0b001,
    RAND_REV_MODE     = 0b010,
    RAND_FWD_MAINT    = 0b011,
    RAND_REV_MAINT    = 0b100,
    DATA_EQ_ADDR      = 0b101,
    ROTATE_LEFT_MODE  = 0b110,
    ROTATE_RIGHT_MODE = 0b111,
};

// 0:3  Operation Type
enum op_type
{
    WRITE            = 0b0000, // fast, with no concurrent traffic
    READ             = 0b0001, // fast, with no concurrent traffic
    READ_WRITE       = 0b0010,
    WRITE_READ       = 0b0011,
    READ_WRITE_READ  = 0b0100,
    READ_WRITE_WRITE = 0b0101,
    RAND_SEQ         = 0b0110,
    READ_READ_WRITE  = 0b1000,
    SCRUB_RRWR       = 0b1001,
    STEER_RW         = 0b1010,
    ALTER            = 0b1011, // (W)
    DISPLAY          = 0b1100, // (R, slow)
    CCS_EXECUTE      = 0b1111,

    // if bits 9:11 (Data Mode bits)  = 000  (bits 4:8 used to specify which subtest to go to)
    // Refresh only cmd if bits 9:11 (Data Mode bits) /= 000
    GOTO_SUBTEST_N = 0b0111,
};

enum test_type
{
    USER_MODE = 0,
    CENSHMOO = 1,
    SUREFAIL = 2,
    MEMWRITE = 3,
    MEMREAD = 4,
    CBR_REFRESH = 5,
    MCBIST_SHORT = 6,
    SHORT_SEQ = 7,
    DELTA_I = 8,
    DELTA_I_LOOP = 9,
    SHORT_RAND = 10,
    LONG1 = 11,
    BUS_TAT = 12,
    SIMPLE_FIX = 13,
    SIMPLE_RAND = 14,
    SIMPLE_RAND_2W = 15,
    SIMPLE_RAND_FIXD = 16,
    SIMPLE_RA_RD_WR = 17,
    SIMPLE_RA_RD_R = 18,
    SIMPLE_RA_FD_R = 19,
    SIMPLE_RA_FD_R_INF = 20,
    SIMPLE_SA_FD_R = 21,
    SIMPLE_RA_FD_W = 22,
    INFINITE = 23,
    WR_ONLY = 24,
    W_ONLY = 25,
    R_ONLY = 26,
    W_ONLY_RAND = 27,
    R_ONLY_RAND = 28,
    R_ONLY_MULTI = 29,
    SHORT = 30,
    SIMPLE_RAND_BARI = 31,
    W_R_INFINITE = 32,
    W_R_RAND_INFINITE = 33,
    R_INFINITE1 = 34,
    R_INFINITE_RF = 35,
    MARCH = 36,
    SIMPLE_FIX_RF = 37,
    SHMOO_STRESS = 38,
    SIMPLE_RAND_RA = 39,
    SIMPLE_FIX_RA = 40,
    SIMPLE_FIX_RF_RA = 41,
    TEST_RR = 42,
    TEST_RF = 43,
    W_ONLY_INFINITE_RAND = 44,
    MCB_2D_CUP_SEQ = 45,
    MCB_2D_CUP_RAND = 46,
    SHMOO_STRESS_INFINITE = 47,
    HYNIX_1_COL = 48,
    RMWFIX = 49,
    RMWFIX_I = 50,
    W_INFINITE = 51,
    R_INFINITE = 52,
};

} // namespace mcbist

}
#endif
<|endoftext|>


<commit_before>#include "avx2.h"

#include "scalar.h"
#include <immintrin.h>

uint64_t avx2_count_byte(const uint8_t* data, size_t size, uint8_t byte) {

    const __m256i v = _mm256_set1_epi8(byte);

    const uint8_t* end = data + size;
    const uint8_t* ptr = data;

    __m256i global_sum = _mm256_setzero_si256();
    __m256i local_sum;

    // 1. blocks of 256 registers
    while (ptr + 256*32 < end) {
        local_sum = _mm256_setzero_si256();

        // update 32 x 8-bit counter
        for (int i=0; i < 256; i++, ptr += 32) {
            const __m256i in = _mm256_loadu_si256((const __m256i*)ptr);
            const __m256i eq = _mm256_cmpeq_epi8(in, v); // 0 or -1

            local_sum = _mm256_sub_epi8(local_sum, eq);
        }

        // update the global accumulator 2 x 64-bit
        const __m256i tmp = _mm256_sad_epu8(local_sum, _mm256_setzero_si256());
        global_sum = _mm256_add_epi64(global_sum, tmp);
    }

    // 2. tail of < 256 registers
    local_sum = _mm256_setzero_si256();
    while (ptr + 32 < end) {
        const __m256i in = _mm256_loadu_si256((const __m256i*)ptr);
        const __m256i eq = _mm256_cmpeq_epi8(in, v);

        local_sum = _mm256_sub_epi8(local_sum, eq);

        ptr += 32;
    }

    const __m256i tmp = _mm256_sad_epu8(local_sum, _mm256_setzero_si256());
    global_sum = _mm256_add_epi64(global_sum, tmp);

    // 3. process tail < 16 bytes
    uint64_t result = _mm256_extract_epi64(global_sum, 0)
                    + _mm256_extract_epi64(global_sum, 1)
                    + _mm256_extract_epi64(global_sum, 2)
                    + _mm256_extract_epi64(global_sum, 3);

    return result + scalar_count_bytes(ptr, end - ptr, byte);
}

uint64_t avx2_count_byte_popcount(const uint8_t* data, size_t size, uint8_t byte) {

    const __m256i v = _mm256_set1_epi8(byte);

    const uint8_t* end = data + size;
    const uint8_t* ptr = data;

    uint64_t result = 0;

    // 1. blocks of 8 registers
    while (ptr + 8*32 < end) {
        const __m256i eq0 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 0*16)));
        const __m256i eq1 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 1*16)));
        const __m256i eq2 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 2*16)));
        const __m256i eq3 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 3*16)));
        const __m256i eq4 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 4*16)));
        const __m256i eq5 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 5*16)));
        const __m256i eq6 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 6*16)));
        const __m256i eq7 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 7*16)));

        const __m256i eq0bit = _mm256_and_si256(eq0, _mm256_set1_epi8(0x01));
        const __m256i eq1bit = _mm256_and_si256(eq1, _mm256_set1_epi8(0x02));
        const __m256i eq2bit = _mm256_and_si256(eq2, _mm256_set1_epi8(0x04));
        const __m256i eq3bit = _mm256_and_si256(eq3, _mm256_set1_epi8(0x08));
        const __m256i eq4bit = _mm256_and_si256(eq4, _mm256_set1_epi8(0x10));
        const __m256i eq5bit = _mm256_and_si256(eq5, _mm256_set1_epi8(0x20));
        const __m256i eq6bit = _mm256_and_si256(eq6, _mm256_set1_epi8(0x40));
        const __m256i eq7bit = _mm256_and_si256(eq7, _mm256_set1_epi8(int8_t(0x80)));

        const __m256i m01    = _mm256_or_si256(eq0bit, eq1bit);
        const __m256i m23    = _mm256_or_si256(eq2bit, eq3bit);
        const __m256i m45    = _mm256_or_si256(eq4bit, eq5bit);
        const __m256i m67    = _mm256_or_si256(eq6bit, eq7bit);

        const __m256i m0123  = _mm256_or_si256(m01, m23);
        const __m256i m4567  = _mm256_or_si256(m45, m67);

        const __m256i merged = _mm256_or_si256(m0123, m4567);

        result += __builtin_popcountll(_mm256_extract_epi64(merged, 0));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 1));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 2));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 3));

        ptr += 8 * 32;
    }

    return result + scalar_count_bytes(ptr, end - ptr, byte);
}
<commit_msg>Fix AVX2 implementation<commit_after>#include "avx2.h"

#include "scalar.h"
#include <immintrin.h>

uint64_t avx2_count_byte(const uint8_t* data, size_t size, uint8_t byte) {

    const __m256i v = _mm256_set1_epi8(byte);

    const uint8_t* end = data + size;
    const uint8_t* ptr = data;

    __m256i global_sum = _mm256_setzero_si256();
    __m256i local_sum;

    // 1. blocks of 256 registers
    while (ptr + 256*32 < end) {
        local_sum = _mm256_setzero_si256();

        // update 32 x 8-bit counter
        for (int i=0; i < 256; i++, ptr += 32) {
            const __m256i in = _mm256_loadu_si256((const __m256i*)ptr);
            const __m256i eq = _mm256_cmpeq_epi8(in, v); // 0 or -1

            local_sum = _mm256_sub_epi8(local_sum, eq);
        }

        // update the global accumulator 2 x 64-bit
        const __m256i tmp = _mm256_sad_epu8(local_sum, _mm256_setzero_si256());
        global_sum = _mm256_add_epi64(global_sum, tmp);
    }

    // 2. tail of < 256 registers
    local_sum = _mm256_setzero_si256();
    while (ptr + 32 < end) {
        const __m256i in = _mm256_loadu_si256((const __m256i*)ptr);
        const __m256i eq = _mm256_cmpeq_epi8(in, v);

        local_sum = _mm256_sub_epi8(local_sum, eq);

        ptr += 32;
    }

    const __m256i tmp = _mm256_sad_epu8(local_sum, _mm256_setzero_si256());
    global_sum = _mm256_add_epi64(global_sum, tmp);

    // 3. process tail < 32 bytes
    uint64_t result = _mm256_extract_epi64(global_sum, 0)
                    + _mm256_extract_epi64(global_sum, 1)
                    + _mm256_extract_epi64(global_sum, 2)
                    + _mm256_extract_epi64(global_sum, 3);

    return result + scalar_count_bytes(ptr, end - ptr, byte);
}

uint64_t avx2_count_byte_popcount(const uint8_t* data, size_t size, uint8_t byte) {

    const __m256i v = _mm256_set1_epi8(byte);

    const uint8_t* end = data + size;
    const uint8_t* ptr = data;

    uint64_t result = 0;

    // 1. blocks of 8 registers
    while (ptr + 8*32 < end) {
        const __m256i eq0 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 0*32)));
        const __m256i eq1 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 1*32)));
        const __m256i eq2 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 2*32)));
        const __m256i eq3 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 3*32)));
        const __m256i eq4 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 4*32)));
        const __m256i eq5 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 5*32)));
        const __m256i eq6 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 6*32)));
        const __m256i eq7 = _mm256_cmpeq_epi8(v, _mm256_loadu_si256((const __m256i*)(ptr + 7*32)));

        const __m256i eq0bit = _mm256_and_si256(eq0, _mm256_set1_epi8(0x01));
        const __m256i eq1bit = _mm256_and_si256(eq1, _mm256_set1_epi8(0x02));
        const __m256i eq2bit = _mm256_and_si256(eq2, _mm256_set1_epi8(0x04));
        const __m256i eq3bit = _mm256_and_si256(eq3, _mm256_set1_epi8(0x08));
        const __m256i eq4bit = _mm256_and_si256(eq4, _mm256_set1_epi8(0x10));
        const __m256i eq5bit = _mm256_and_si256(eq5, _mm256_set1_epi8(0x20));
        const __m256i eq6bit = _mm256_and_si256(eq6, _mm256_set1_epi8(0x40));
        const __m256i eq7bit = _mm256_and_si256(eq7, _mm256_set1_epi8(int8_t(0x80)));

        const __m256i m01    = _mm256_or_si256(eq0bit, eq1bit);
        const __m256i m23    = _mm256_or_si256(eq2bit, eq3bit);
        const __m256i m45    = _mm256_or_si256(eq4bit, eq5bit);
        const __m256i m67    = _mm256_or_si256(eq6bit, eq7bit);

        const __m256i m0123  = _mm256_or_si256(m01, m23);
        const __m256i m4567  = _mm256_or_si256(m45, m67);

        const __m256i merged = _mm256_or_si256(m0123, m4567);

        result += __builtin_popcountll(_mm256_extract_epi64(merged, 0));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 1));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 2));
        result += __builtin_popcountll(_mm256_extract_epi64(merged, 3));

        ptr += 8 * 32;
    }

    return result + scalar_count_bytes(ptr, end - ptr, byte);
}
<|endoftext|>


<commit_before>#include <HM3/HM3Hooks.h>

#include <HM3/HM3Module.h>
#include <HM3/HM3Functions.h>
#include <HM3/HM3Pointers.h>

#include <HM3/Structs/HM3NPC.h>
#include <HM3/Structs/HM3Stats.h>
#include <HM3/Structs/UnknownClass01.h>
#include <HM3/Structs/UnknownClass02.h>
#include <HM3/Structs/UnknownClass03.h>
#include <HM3/Structs/UnknownClass04.h>

HM3Hooks::EndLevel_t HM3Hooks::EndLevel = nullptr;

int __fastcall HM3Hooks::c_EndLevel(UnknownClass01* th, int)
{
	if (!g_Module || !g_Module->Pointers() || !g_Module->Functions())
		return EndLevel(th);

	// Reset witness count.
	if (g_Module->Pointers()->m_Stats)
		g_Module->Pointers()->m_Stats->m_Witnesses = 0;

	// Custom "Hitman 2016" logic.
	if (g_Module && g_Module->Hitman2016Mode())
	{
		auto s_Class03 = *reinterpret_cast<UnknownClass03**>(0x0081F83C);

		/*auto s_WeaponsInHand = 0;

		if (s_Class03 && th->m_Unknown03 && s_Class03->m_Unknown02)
		{
			g_Module->Functions()->UnknownFunction01(th->m_Unknown03, s_Class03->m_Unknown02);
			s_WeaponsInHand += g_Module->Functions()->UnknownFunction02(th->m_Unknown03);
		}

		if (s_Class03 && th->m_Unknown04 && s_Class03->m_Unknown02)
		{
			g_Module->Functions()->UnknownFunction01(th->m_Unknown04, s_Class03->m_Unknown02);
			s_WeaponsInHand += g_Module->Functions()->UnknownFunction02(th->m_Unknown04);
		}

		// Set necessary values for disabling items.
		if (g_Module->Pointers()->m_Stats)
			th->m_WeaponsLeftOnLevel = s_WeaponsInHand - g_Module->Functions()->GetNPCWeaponCount();*/

		if (s_Class03 && s_Class03->m_Unknown01)
			s_Class03->m_Unknown01->m_Unknown01 = s_Class03->m_Unknown01->m_Unknown02 = nullptr;
	}

	return EndLevel(th);
}<commit_msg>Update s_Class03 address<commit_after>#include <HM3/HM3Hooks.h>

#include <HM3/HM3Module.h>
#include <HM3/HM3Functions.h>
#include <HM3/HM3Pointers.h>

#include <HM3/Structs/HM3NPC.h>
#include <HM3/Structs/HM3Stats.h>
#include <HM3/Structs/UnknownClass01.h>
#include <HM3/Structs/UnknownClass02.h>
#include <HM3/Structs/UnknownClass03.h>
#include <HM3/Structs/UnknownClass04.h>

HM3Hooks::EndLevel_t HM3Hooks::EndLevel = nullptr;

int __fastcall HM3Hooks::c_EndLevel(UnknownClass01* th, int)
{
	if (!g_Module || !g_Module->Pointers() || !g_Module->Functions())
		return EndLevel(th);

	// Reset witness count.
	if (g_Module->Pointers()->m_Stats)
		g_Module->Pointers()->m_Stats->m_Witnesses = 0;

	// Custom "Hitman 2016" logic.
	if (g_Module && g_Module->Hitman2016Mode())
	{
		auto s_Class03 = *reinterpret_cast<UnknownClass03**>(0x0082083C);

		/*auto s_WeaponsInHand = 0;

		if (s_Class03 && th->m_Unknown03 && s_Class03->m_Unknown02)
		{
			g_Module->Functions()->UnknownFunction01(th->m_Unknown03, s_Class03->m_Unknown02);
			s_WeaponsInHand += g_Module->Functions()->UnknownFunction02(th->m_Unknown03);
		}

		if (s_Class03 && th->m_Unknown04 && s_Class03->m_Unknown02)
		{
			g_Module->Functions()->UnknownFunction01(th->m_Unknown04, s_Class03->m_Unknown02);
			s_WeaponsInHand += g_Module->Functions()->UnknownFunction02(th->m_Unknown04);
		}

		// Set necessary values for disabling items.
		if (g_Module->Pointers()->m_Stats)
			th->m_WeaponsLeftOnLevel = s_WeaponsInHand - g_Module->Functions()->GetNPCWeaponCount();*/

		if (s_Class03 && s_Class03->m_Unknown01)
			s_Class03->m_Unknown01->m_Unknown01 = s_Class03->m_Unknown01->m_Unknown02 = nullptr;
	}

	return EndLevel(th);
}<|endoftext|>


<commit_before>// magvar.cxx -- magnetic variation wrapper class
//
// Written by Curtis Olson, started July 2000.
//
// Copyright (C) 2000  Curtis L. Olson  - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <math.h>

#include <simgear/magvar/magvar.hxx>

#include "coremag.hxx"
#include "magvar.hxx"

SGMagVar::SGMagVar() {
}

SGMagVar::~SGMagVar() {
}

void SGMagVar::update( double lon, double lat, double alt_m, double jd ) {
    // Calculate local magnetic variation
    double field[6];
    // cout << "alt_m = " << alt_m << endl;
    magvar = calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
    magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4]));
}

double sgGetMagVar( double lon, double lat, double alt_m, double jd ) {
    // cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m
    //      << " JD = " << jd << endl;

    double field[6];
    return calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
}
<commit_msg>Patch from Melchior Franz:<commit_after>// magvar.cxx -- magnetic variation wrapper class
//
// Written by Curtis Olson, started July 2000.
//
// Copyright (C) 2000  Curtis L. Olson  - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$

#include <math.h>

#include <simgear/magvar/magvar.hxx>

#include "coremag.hxx"
#include "magvar.hxx"

SGMagVar::SGMagVar()
  : magvar(0.0),
    magdip(0.0)
{
}

SGMagVar::~SGMagVar() {
}

void SGMagVar::update( double lon, double lat, double alt_m, double jd ) {
    // Calculate local magnetic variation
    double field[6];
    // cout << "alt_m = " << alt_m << endl;
    magvar = calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
    magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4]));
}

double sgGetMagVar( double lon, double lat, double alt_m, double jd ) {
    // cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m
    //      << " JD = " << jd << endl;

    double field[6];
    return calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
}
<|endoftext|>


<commit_before>#include "app_logprint.h"
#include "main.h"
#include "pagebrowser.h"
#include "crosstable.h"
#include "automation.h"
#include <QMessageBox>

// OCTOPUS STATUS
#define STATUS_IDLE       0
#define STATUS_STARTING   1
#define STATUS_READY      2
#define STATUS_TESTING    3
#define STATUS_DONE       4
#define STATUS_RESETTING  5
#define STATUS_STOPPING   6
#define STATUS_ERROR      7

// TEST_STATUS
#define TEST_STATUS_LOCAL  0x0000
#define TEST_STATUS_REMOTE 0x00D8
#define TEST_STATUS_DONE   0x002A

// LOCAL DIGITAL INPUTS
#define PLC_PWR_SWITCH PLC_DigIn_1
#define PLC_GO_BUTTON PLC_DigIn_4

// PRODUCT_NAMES <-- PRODUCT_ID
static char product_name[][15] = {
    /*00*/ "-",
    /*01*/ "TP1043_01_A"   ,
    /*02*/ "TP1043_02_A"   ,
    /*03*/ "TP1043_02_B"   ,
    /*04*/ "TP1070_01_A"   ,
    /*05*/ "TP1070_01_B"   ,
    /*06*/ "TP1070_01_C"   ,
    /*07*/ "TPAC1005"      ,
    /*08*/ "TPAC1007_03"   ,
    /*09*/ "TPAC1007_04_AA",
    /*10*/ "TPAC1007_04_AB",
    /*11*/ "TPAC1007_04_AC",
    /*12*/ "TPAC1007_04_AD",
    /*13*/ "TPAC1007_04_AE",
    /*14*/ "TPAC1008_02_AA",
    /*15*/ "TPAC1008_02_AB",
    /*16*/ "TPAC1008_02_AD",
    /*17*/ "TPAC1008_02_AE",
    /*18*/ "TPAC1008_02_AF",
    /*19*/ "TPAC1008_03_AC",
    /*20*/ "TPAC1008_03_AD",
    /*21*/ "TPLC050_01_AA" ,
    /*22*/ "TPLC100_01_AA" ,
    /*23*/ "TPLC100_01_AB" ,
    /*24*/ "TPX1043_03_C"  ,
    /*25*/ "TPX1070_03_D"  ,
    /*26*/ "TPX1070_03_E"
};
#define PRODUCT_MAX 26
#define RECIPE_MAX 4
static char recipe_name[][RECIPE_MAX] = {"-", "1", "2", "3", "4"};

#define abs(v) (((v) > 0)? (v):-(v))

// TST_... (Zeroes)
QList<u_int16_t> zeroesIndexes;
QList<u_int32_t> zeroesTable[MAX_RCP_STEP];
// TST_...
QList<u_int16_t> testsIndexes;
QList<u_int32_t> testsTable[MAX_RCP_STEP];
// VAL_...
QList<u_int16_t> valuesIndexes;
QList<u_int32_t> valuesTable[MAX_RCP_STEP];

static void doReload();
extern int checkRecipe(int step, QList<u_int16_t> *indexes, QList<u_int32_t> table[]);

static u_int16_t previous_PLC_Heartbeat;
static u_int16_t previous_MPNC_HeartBeat;
static float previous_PLC_time;
static float last_PLC_time;
static page300 *thePage = NULL;

void setup(void)
{
    qDebug() << HMIversion;
    while (PLC_EngineStatus < 2) {
        fputc('*', stderr);
        sleep(1);
    }
    doWrite_PLC_HMI_Version(3394);

    previous_PLC_time = PLC_time;
    last_PLC_time = PLC_time;
    previous_PLC_Heartbeat = PLC_Heartbeat;
    previous_MPNC_HeartBeat = MPNC_HeartBeat;

    beginWrite();
    {
        // check the retentive values
        if (PRODUCT_ID == 0 or PRODUCT_ID > PRODUCT_MAX) {
           addWrite_PRODUCT_ID(2); // 2 TP1043_02_A
        }
        if (TEST_ID == 0 or TEST_ID > RECIPE_MAX) {
           addWrite_TEST_ID(2); // 2 An+Dig
        }

        // force loading the recipes
        addWrite_RESULT(RESULT_UNKNOWN);
        addWrite_DO_RELOAD(1);
    }
    endWrite();
}

void setTheWidget(page300 *p)
{
    thePage = p;
}

static int failed_writeRecipe = 0;
static int failed_checkRecipe = 0;
static int failed_doWrite = 0;

void update_message()
{
    char msg[255];

    sprintf(msg, "#%u@%u,%u: writeRecipe=%d, checkRecipe=%d, doWrite=%d",
            TEST_STEP, RESULTS_OK, RESULTS_NG,
            failed_writeRecipe, failed_checkRecipe, failed_doWrite);
    thePage->setMessage(msg);
}

void loop(void)
{
    static int substatus = 0;
    static int next_step = 0;

    if (thePage == NULL) {
        previous_PLC_Heartbeat = PLC_Heartbeat;
        last_PLC_time = PLC_time;
        previous_PLC_time = PLC_time;
        previous_MPNC_HeartBeat = MPNC_HeartBeat;
        return;
    }

    // fcrts UDP communication test @100 ms
    if (PLC_time == previous_PLC_time) {
        thePage->messageBox(RESULT_UNKNOWN, "PLC_time hangup :(\nWhat happened to fcrts?");
    }
    previous_PLC_time = PLC_time;

    // LPC RTU3 communication test @ 100ms
    if (previous_PLC_Heartbeat == PLC_Heartbeat) {
        thePage->messageBox(RESULT_UNKNOWN, "RTU3 hangup :(\nWhat happened to LPC?");
    }
    previous_PLC_Heartbeat = PLC_Heartbeat;

    // MPNC RTU0 communication test @ 1s
    if ((PLC_time - last_PLC_time) > 1.5) {
        if (previous_MPNC_HeartBeat == MPNC_HeartBeat) {
            thePage->messageBox(RESULT_UNKNOWN, "RTU0 hangup :(\nWhat happened to MPNC?");
        }
        last_PLC_time = PLC_time;
        previous_MPNC_HeartBeat = MPNC_HeartBeat;
    }

    switch (STATUS) {   // OCTOPUS STATE MACHINE

    case STATUS_IDLE:
        /* this state is managed in PLC */
        logStop();
        if (DO_RELOAD) {
            doReload();
            sleep(1); // just for viewing the led change
        }
        substatus = 0;
        break;

    case STATUS_STARTING:
        /* this state is managed in PLC */
        logStop();
        substatus = 0;
        break;

    case STATUS_READY:
        if (!PLC_PWR_SWITCH) {
            doWrite_STATUS(STATUS_STOPPING);
            return;
        }
        if (DO_RELOAD) {
            doReload();
            substatus = 0;
            return;
        }
        if (TEST2_STATUS != TEST_STATUS_REMOTE || TESTx_STATUS != TEST_STATUS_REMOTE) {
            doWrite_STATUS(STATUS_STARTING);
            substatus = 0;
            return;
        }
        switch (substatus) {
        case 0:
        case 1:
            if (AUTOMATIC || PLC_GO_BUTTON) {
                if (TEST_STEP_MAX == 0) {
                    return;
                }
                // next step
                next_step = TEST_STEP;
                if (next_step >= TEST_STEP_MAX) {
                    if (DO_REPEAT) {
                        next_step = 1;
                    } else {
                        logStop();
                        if (substatus == 0) {
                            if (RESULTS_OK == TEST_STEP_MAX && RESULTS_NG == 0) {
                                thePage->messageBox(RESULT_OK, "now PWR_OFF\nthen touch me");
                            } else if (RESULTS_NG > 0) {
                                thePage->messageBox(RESULT_NG, "now PWR_OFF\nthen touch me");
                            } else {
                                thePage->messageBox(RESULT_UNKNOWN, "now PWR_OFF\nthen touch me");
                            }
                        }
                        substatus = 1;
                        return;
                    }
                } else {
                    ++next_step;
                }
                logStart();
                doWrite_TEST_STEP(next_step);
                substatus = 10;
            }
            break;
        case 10:
            if (writeRecipe(0, &zeroesIndexes, zeroesTable) != 0) {
                fprintf(stderr, "writeRecipe(zeroes) failed, retry after 100ms");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 11;
            }
            break;
        case 11:
            substatus = 12;
            break;
        case 12:
            substatus = 13;
            break;
        case 13:
            if (! checkRecipe(0, &zeroesIndexes, zeroesTable)) {
                fprintf(stderr, "checkRecipe(zeroes) failed after 300 ms, rewrite after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 10;
            } else {
                substatus = 20;
            }
            break;
        case 20:
            if (writeRecipe(next_step - 1, &testsIndexes, testsTable) != 0) {
                fprintf(stderr, "writeRecipe(tests) failed, retry after 100ms\n");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 21;
            }
            break;
        case 21:
            substatus = 22;
            break;
        case 22:
            substatus = 23;
            break;
        case 23:
            if (! checkRecipe(next_step - 1, &testsIndexes, testsTable)) {
                fprintf(stderr, "checkRecipe(tests) failed after 300 ms, rewrite  after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 20;
            } else {
                substatus = 30;
            }
            break;
        case 30:
            if (writeRecipe(next_step - 1, &valuesIndexes, valuesTable) != 0) {
                fprintf(stderr, "writeRecipe(values) failed, retry after 100ms\n");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 31;
            }
            break;
        case 31:
            substatus = 32;
            break;
        case 32:
            substatus = 33;
            break;
        case 33:
            if (! checkRecipe(next_step - 1, &valuesIndexes, valuesTable)) {
                fprintf(stderr, "checkRecipe(values) failed after 300 ms, rewrite after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 30;
            } else {
                substatus = 40;
            }
            break;
        case 40:
            doWrite_STATUS(STATUS_TESTING);
            substatus = 41;
            break;
        case 41:
            fprintf(stderr, "check (STATUS==STATUS_TESTING) failed\n");
            ++failed_doWrite;
            update_message();
            substatus = 42;
        case 42:
            break;
        default:
            substatus = 0;
        }
        break;

    case STATUS_ERROR:
        if (!PLC_PWR_SWITCH) {
            doWrite_STATUS(STATUS_STOPPING);
            return;
        }
        if (PLC_GO_BUTTON) {
            doWrite_TEST2_COMMAND(TEST_STATUS_LOCAL);
            doWrite_TESTx_COMMAND(TEST_STATUS_LOCAL);
            doWrite_RESULT(RESULT_UNKNOWN);
            doWrite_STATUS(STATUS_RESETTING);
            return;
        }
        substatus = 0;
        break;

    case STATUS_TESTING:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_DONE:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_RESETTING:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_STOPPING:
        /* this state is managed in PLC */
        logStop();
        substatus = 0;
        break;

    default:
        substatus = 0;
    }
}

static void doReload()
{
    char filename[256];
    int z, t, v;

    // file: /local/data/recipe/Zeroes/0.csv
    snprintf(filename, 256, "%s/%s/%s.csv", RECIPE_DIR, "Zeroes", "0");
    z = loadRecipe(filename, &zeroesIndexes, zeroesTable);

    // file: /local/data/recipe/TPAC1007_4AA/2.csv
    snprintf(filename, 256, "%s/%s/%s.csv", RECIPE_DIR, product_name[PRODUCT_ID], recipe_name[TEST_ID]);
    t = loadRecipe(filename, &testsIndexes, testsTable);

    // file: /local/data/recipe/Values/2.csv
    snprintf(filename, 256, "%s/Values/%s.csv", RECIPE_DIR, recipe_name[TEST_ID]);
    v = loadRecipe(filename, &valuesIndexes, valuesTable);

    if (z == 1 && t > 0 && v > 0 && t <= v) {
        doWrite_TEST_STEP_MAX(t);
        doWrite_DO_RELOAD(0);
    } else {
        doWrite_TEST_STEP_MAX(0);
    }
}
<commit_msg>octopus: HMI head version<commit_after>#include "app_logprint.h"
#include "main.h"
#include "pagebrowser.h"
#include "crosstable.h"
#include "automation.h"
#include <QMessageBox>

// OCTOPUS STATUS
#define STATUS_IDLE       0
#define STATUS_STARTING   1
#define STATUS_READY      2
#define STATUS_TESTING    3
#define STATUS_DONE       4
#define STATUS_RESETTING  5
#define STATUS_STOPPING   6
#define STATUS_ERROR      7

// TEST_STATUS
#define TEST_STATUS_LOCAL  0x0000
#define TEST_STATUS_REMOTE 0x00D8
#define TEST_STATUS_DONE   0x002A

// LOCAL DIGITAL INPUTS
#define PLC_PWR_SWITCH PLC_DigIn_1
#define PLC_GO_BUTTON PLC_DigIn_4

// PRODUCT_NAMES <-- PRODUCT_ID
static char product_name[][15] = {
    /*00*/ "-",
    /*01*/ "TP1043_01_A"   ,
    /*02*/ "TP1043_02_A"   ,
    /*03*/ "TP1043_02_B"   ,
    /*04*/ "TP1070_01_A"   ,
    /*05*/ "TP1070_01_B"   ,
    /*06*/ "TP1070_01_C"   ,
    /*07*/ "TPAC1005"      ,
    /*08*/ "TPAC1007_03"   ,
    /*09*/ "TPAC1007_04_AA",
    /*10*/ "TPAC1007_04_AB",
    /*11*/ "TPAC1007_04_AC",
    /*12*/ "TPAC1007_04_AD",
    /*13*/ "TPAC1007_04_AE",
    /*14*/ "TPAC1008_02_AA",
    /*15*/ "TPAC1008_02_AB",
    /*16*/ "TPAC1008_02_AD",
    /*17*/ "TPAC1008_02_AE",
    /*18*/ "TPAC1008_02_AF",
    /*19*/ "TPAC1008_03_AC",
    /*20*/ "TPAC1008_03_AD",
    /*21*/ "TPLC050_01_AA" ,
    /*22*/ "TPLC100_01_AA" ,
    /*23*/ "TPLC100_01_AB" ,
    /*24*/ "TPX1043_03_C"  ,
    /*25*/ "TPX1070_03_D"  ,
    /*26*/ "TPX1070_03_E"
};
#define PRODUCT_MAX 26
#define RECIPE_MAX 4
static char recipe_name[][RECIPE_MAX] = {"-", "1", "2", "3", "4"};

#define abs(v) (((v) > 0)? (v):-(v))

// TST_... (Zeroes)
QList<u_int16_t> zeroesIndexes;
QList<u_int32_t> zeroesTable[MAX_RCP_STEP];
// TST_...
QList<u_int16_t> testsIndexes;
QList<u_int32_t> testsTable[MAX_RCP_STEP];
// VAL_...
QList<u_int16_t> valuesIndexes;
QList<u_int32_t> valuesTable[MAX_RCP_STEP];

static void doReload();
extern int checkRecipe(int step, QList<u_int16_t> *indexes, QList<u_int32_t> table[]);

static u_int16_t previous_PLC_Heartbeat;
static u_int16_t previous_MPNC_HeartBeat;
static float previous_PLC_time;
static float last_PLC_time;
static page300 *thePage = NULL;

void setup(void)
{
    qDebug() << HMIversion;
    while (PLC_EngineStatus < 2) {
        fputc('*', stderr);
        sleep(1);
    }
    doWrite_PLC_HMI_Version(3395);

    previous_PLC_time = PLC_time;
    last_PLC_time = PLC_time;
    previous_PLC_Heartbeat = PLC_Heartbeat;
    previous_MPNC_HeartBeat = MPNC_HeartBeat;

    beginWrite();
    {
        // check the retentive values
        if (PRODUCT_ID == 0 or PRODUCT_ID > PRODUCT_MAX) {
           addWrite_PRODUCT_ID(2); // 2 TP1043_02_A
        }
        if (TEST_ID == 0 or TEST_ID > RECIPE_MAX) {
           addWrite_TEST_ID(2); // 2 An+Dig
        }

        // force loading the recipes
        addWrite_RESULT(RESULT_UNKNOWN);
        addWrite_DO_RELOAD(1);
    }
    endWrite();
}

void setTheWidget(page300 *p)
{
    thePage = p;
}

static int failed_writeRecipe = 0;
static int failed_checkRecipe = 0;
static int failed_doWrite = 0;

void update_message()
{
    char msg[255];

    sprintf(msg, "#%u@%u,%u: writeRecipe=%d, checkRecipe=%d, doWrite=%d",
            TEST_STEP, RESULTS_OK, RESULTS_NG,
            failed_writeRecipe, failed_checkRecipe, failed_doWrite);
    thePage->setMessage(msg);
}

void loop(void)
{
    static int substatus = 0;
    static int next_step = 0;

    if (thePage == NULL) {
        previous_PLC_Heartbeat = PLC_Heartbeat;
        last_PLC_time = PLC_time;
        previous_PLC_time = PLC_time;
        previous_MPNC_HeartBeat = MPNC_HeartBeat;
        return;
    }

    // fcrts UDP communication test @100 ms
    if (PLC_time == previous_PLC_time) {
        thePage->messageBox(RESULT_UNKNOWN, "PLC_time hangup :(\nWhat happened to fcrts?");
    }
    previous_PLC_time = PLC_time;

    // LPC RTU3 communication test @ 100ms
    if (previous_PLC_Heartbeat == PLC_Heartbeat) {
        thePage->messageBox(RESULT_UNKNOWN, "RTU3 hangup :(\nWhat happened to LPC?");
    }
    previous_PLC_Heartbeat = PLC_Heartbeat;

    // MPNC RTU0 communication test @ 1s
    if ((PLC_time - last_PLC_time) > 1.5) {
        if (previous_MPNC_HeartBeat == MPNC_HeartBeat) {
            thePage->messageBox(RESULT_UNKNOWN, "RTU0 hangup :(\nWhat happened to MPNC?");
        }
        last_PLC_time = PLC_time;
        previous_MPNC_HeartBeat = MPNC_HeartBeat;
    }

    switch (STATUS) {   // OCTOPUS STATE MACHINE

    case STATUS_IDLE:
        /* this state is managed in PLC */
        logStop();
        if (DO_RELOAD) {
            doReload();
            sleep(1); // just for viewing the led change
        }
        substatus = 0;
        break;

    case STATUS_STARTING:
        /* this state is managed in PLC */
        logStop();
        substatus = 0;
        break;

    case STATUS_READY:
        if (!PLC_PWR_SWITCH) {
            doWrite_STATUS(STATUS_STOPPING);
            return;
        }
        if (DO_RELOAD) {
            doReload();
            substatus = 0;
            return;
        }
        if (TEST2_STATUS != TEST_STATUS_REMOTE || TESTx_STATUS != TEST_STATUS_REMOTE) {
            doWrite_STATUS(STATUS_STARTING);
            substatus = 0;
            return;
        }
        switch (substatus) {
        case 0:
        case 1:
            if (AUTOMATIC || PLC_GO_BUTTON) {
                if (TEST_STEP_MAX == 0) {
                    return;
                }
                // next step
                next_step = TEST_STEP;
                if (next_step >= TEST_STEP_MAX) {
                    if (DO_REPEAT) {
                        next_step = 1;
                    } else {
                        logStop();
                        if (substatus == 0) {
                            if (RESULTS_OK == TEST_STEP_MAX && RESULTS_NG == 0) {
                                thePage->messageBox(RESULT_OK, "now PWR_OFF\nthen touch me");
                            } else if (RESULTS_NG > 0) {
                                thePage->messageBox(RESULT_NG, "now PWR_OFF\nthen touch me");
                            } else {
                                thePage->messageBox(RESULT_UNKNOWN, "now PWR_OFF\nthen touch me");
                            }
                        }
                        substatus = 1;
                        return;
                    }
                } else {
                    ++next_step;
                }
                logStart();
                doWrite_TEST_STEP(next_step);
                substatus = 10;
            }
            break;
        case 10:
            if (writeRecipe(0, &zeroesIndexes, zeroesTable) != 0) {
                fprintf(stderr, "writeRecipe(zeroes) failed, retry after 100ms");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 11;
            }
            break;
        case 11:
            substatus = 12;
            break;
        case 12:
            substatus = 13;
            break;
        case 13:
            if (! checkRecipe(0, &zeroesIndexes, zeroesTable)) {
                fprintf(stderr, "checkRecipe(zeroes) failed after 300 ms, rewrite after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 10;
            } else {
                substatus = 20;
            }
            break;
        case 20:
            if (writeRecipe(next_step - 1, &testsIndexes, testsTable) != 0) {
                fprintf(stderr, "writeRecipe(tests) failed, retry after 100ms\n");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 21;
            }
            break;
        case 21:
            substatus = 22;
            break;
        case 22:
            substatus = 23;
            break;
        case 23:
            if (! checkRecipe(next_step - 1, &testsIndexes, testsTable)) {
                fprintf(stderr, "checkRecipe(tests) failed after 300 ms, rewrite  after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 20;
            } else {
                substatus = 30;
            }
            break;
        case 30:
            if (writeRecipe(next_step - 1, &valuesIndexes, valuesTable) != 0) {
                fprintf(stderr, "writeRecipe(values) failed, retry after 100ms\n");
                ++failed_writeRecipe;
                update_message();
            } else {
                substatus = 31;
            }
            break;
        case 31:
            substatus = 32;
            break;
        case 32:
            substatus = 33;
            break;
        case 33:
            if (! checkRecipe(next_step - 1, &valuesIndexes, valuesTable)) {
                fprintf(stderr, "checkRecipe(values) failed after 300 ms, rewrite after 100ms\n");
                ++failed_checkRecipe;
                update_message();
                substatus = 30;
            } else {
                substatus = 40;
            }
            break;
        case 40:
            doWrite_STATUS(STATUS_TESTING);
            substatus = 41;
            break;
        case 41:
            fprintf(stderr, "check (STATUS==STATUS_TESTING) failed\n");
            ++failed_doWrite;
            update_message();
            substatus = 42;
        case 42:
            break;
        default:
            substatus = 0;
        }
        break;

    case STATUS_ERROR:
        if (!PLC_PWR_SWITCH) {
            doWrite_STATUS(STATUS_STOPPING);
            return;
        }
        if (PLC_GO_BUTTON) {
            doWrite_TEST2_COMMAND(TEST_STATUS_LOCAL);
            doWrite_TESTx_COMMAND(TEST_STATUS_LOCAL);
            doWrite_RESULT(RESULT_UNKNOWN);
            doWrite_STATUS(STATUS_RESETTING);
            return;
        }
        substatus = 0;
        break;

    case STATUS_TESTING:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_DONE:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_RESETTING:
        /* this state is managed in PLC */
        substatus = 0;
        break;

    case STATUS_STOPPING:
        /* this state is managed in PLC */
        logStop();
        substatus = 0;
        break;

    default:
        substatus = 0;
    }
}

static void doReload()
{
    char filename[256];
    int z, t, v;

    // file: /local/data/recipe/Zeroes/0.csv
    snprintf(filename, 256, "%s/%s/%s.csv", RECIPE_DIR, "Zeroes", "0");
    z = loadRecipe(filename, &zeroesIndexes, zeroesTable);

    // file: /local/data/recipe/TPAC1007_4AA/2.csv
    snprintf(filename, 256, "%s/%s/%s.csv", RECIPE_DIR, product_name[PRODUCT_ID], recipe_name[TEST_ID]);
    t = loadRecipe(filename, &testsIndexes, testsTable);

    // file: /local/data/recipe/Values/2.csv
    snprintf(filename, 256, "%s/Values/%s.csv", RECIPE_DIR, recipe_name[TEST_ID]);
    v = loadRecipe(filename, &valuesIndexes, valuesTable);

    if (z == 1 && t > 0 && v > 0 && t <= v) {
        doWrite_TEST_STEP_MAX(t);
        doWrite_DO_RELOAD(0);
    } else {
        doWrite_TEST_STEP_MAX(0);
    }
}
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/

#include <fstream>
#include "otbVectorImage.h"
#include "otbImage.h"
#include "otbSOMMap.h"
#include "otbSOMClassifier.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkListSample.h"

int otbSOMClassifier(int argc, char* argv[])
{
  if (argc != 4)
    {
    std::cout << "Usage : " << argv[0] << " inputImage modelFile outputImage"
              << std::endl;
    return EXIT_FAILURE;
    }

  const char * imageFilename  = argv[1];
  const char * mapFilename  = argv[2];
  const char * outputFilename = argv[3];

  typedef double InputPixelType;
  typedef int    LabelPixelType;
  const unsigned int Dimension = 2;

  typedef itk::VariableLengthVector<InputPixelType>                  PixelType;
  typedef itk::Statistics::EuclideanDistanceMetric<PixelType>              DistanceType;
  typedef otb::SOMMap<PixelType, DistanceType, Dimension>            SOMMapType;
  typedef otb::VectorImage<InputPixelType, Dimension>                InputImageType;
  typedef otb::ImageFileReader<InputImageType>                       ReaderType;
  typedef otb::ImageFileReader<SOMMapType>                           SOMReaderType;
  typedef itk::Statistics::ListSample<PixelType>                     SampleType;
  typedef otb::SOMClassifier<SampleType, SOMMapType, LabelPixelType> ClassifierType;
  typedef otb::Image<LabelPixelType, Dimension>                      OutputImageType;
  typedef itk::ImageRegionIterator<OutputImageType>                  OutputIteratorType;
  typedef otb::ImageFileWriter<OutputImageType>                      WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(imageFilename);
  reader->Update();
  std::cout << "Image read" << std::endl;

  SOMReaderType::Pointer somreader = SOMReaderType::New();
  somreader->SetFileName(mapFilename);
  somreader->Update();
  std::cout << "SOM map read" << std::endl;

  SampleType::Pointer listSample = SampleType::New();
  listSample->SetMeasurementVectorSize(reader->GetOutput()->GetNumberOfComponentsPerPixel());

  itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(), reader->GetOutput()->GetLargestPossibleRegion());

  it.GoToBegin();

  while (!it.IsAtEnd())
    {
    listSample->PushBack(it.Get());
    ++it;
    }

  ClassifierType::Pointer classifier = ClassifierType::New();
  classifier->SetSample(listSample.GetPointer());
  classifier->SetMap(somreader->GetOutput());
  classifier->Update();

  OutputImageType::Pointer outputImage = OutputImageType::New();
  outputImage->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
  outputImage->Allocate();

  ClassifierType::OutputType*               membershipSample = classifier->GetOutput();
  ClassifierType::OutputType::ConstIterator m_iter =  membershipSample->Begin();
  ClassifierType::OutputType::ConstIterator m_last =  membershipSample->End();

  OutputIteratorType outIt(outputImage, outputImage->GetLargestPossibleRegion());
  outIt.GoToBegin();

  while (m_iter != m_last && !outIt.IsAtEnd())
    {
    outIt.Set(m_iter.GetClassLabel());
    ++m_iter;
    ++outIt;
    }

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFilename);
  writer->SetInput(outputImage);
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH: #942: rectify test so that leTvSOMClassifier and leTvSOMImageClassificationFilter can share the same baseline<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/

#include <fstream>
#include "otbVectorImage.h"
#include "otbImage.h"
#include "otbSOMMap.h"
#include "otbSOMClassifier.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkListSample.h"

int otbSOMClassifier(int argc, char* argv[])
{
  if (argc != 4)
    {
    std::cout << "Usage : " << argv[0] << " inputImage modelFile outputImage"
              << std::endl;
    return EXIT_FAILURE;
    }

  const char * imageFilename  = argv[1];
  const char * mapFilename  = argv[2];
  const char * outputFilename = argv[3];

  typedef double InputPixelType;
  typedef int    LabelPixelType;
  const unsigned int Dimension = 2;

  typedef itk::VariableLengthVector<InputPixelType>                  PixelType;
  typedef itk::Statistics::EuclideanDistanceMetric<PixelType>              DistanceType;
  typedef otb::SOMMap<PixelType, DistanceType, Dimension>            SOMMapType;
  typedef otb::VectorImage<InputPixelType, Dimension>                InputImageType;
  typedef otb::ImageFileReader<InputImageType>                       ReaderType;
  typedef otb::ImageFileReader<SOMMapType>                           SOMReaderType;
  typedef itk::Statistics::ListSample<PixelType>                     SampleType;
  typedef otb::SOMClassifier<SampleType, SOMMapType, LabelPixelType> ClassifierType;
  typedef otb::Image<LabelPixelType, Dimension>                      OutputImageType;
  typedef itk::ImageRegionIterator<OutputImageType>                  OutputIteratorType;
  typedef otb::ImageFileWriter<OutputImageType>                      WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(imageFilename);
  reader->Update();
  std::cout << "Image read" << std::endl;

  SOMReaderType::Pointer somreader = SOMReaderType::New();
  somreader->SetFileName(mapFilename);
  somreader->Update();
  std::cout << "SOM map read" << std::endl;

  SampleType::Pointer listSample = SampleType::New();
  listSample->SetMeasurementVectorSize(reader->GetOutput()->GetNumberOfComponentsPerPixel());

  itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(), reader->GetOutput()->GetLargestPossibleRegion());

  it.GoToBegin();

  while (!it.IsAtEnd())
    {
    listSample->PushBack(it.Get());
    ++it;
    }

  ClassifierType::Pointer classifier = ClassifierType::New();
  classifier->SetSample(listSample.GetPointer());
  classifier->SetMap(somreader->GetOutput());
  classifier->Update();

  OutputImageType::Pointer outputImage = OutputImageType::New();
  outputImage->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
  outputImage->SetOrigin(reader->GetOutput()->GetOrigin());
  outputImage->SetSpacing(reader->GetOutput()->GetSpacing());
  outputImage->Allocate();

  ClassifierType::OutputType*               membershipSample = classifier->GetOutput();
  ClassifierType::OutputType::ConstIterator m_iter =  membershipSample->Begin();
  ClassifierType::OutputType::ConstIterator m_last =  membershipSample->End();

  OutputIteratorType outIt(outputImage, outputImage->GetLargestPossibleRegion());
  outIt.GoToBegin();

  while (m_iter != m_last && !outIt.IsAtEnd())
    {
    outIt.Set(m_iter.GetClassLabel());
    ++m_iter;
    ++outIt;
    }

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFilename);
  writer->SetInput(outputImage);
  writer->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XalanEXSLTString.hpp"
#include "XalanEXSLTStringImpl.hpp"

#include <PlatformSupport/DoubleSupport.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathEnvSupportDefault.hpp>

XALAN_CPP_NAMESPACE_BEGIN

const XalanDOMChar	XalanEXSLTFunctionAlign::s_centerString[] =
{
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_r,
	0
};

const XalanDOMChar	XalanEXSLTFunctionAlign::s_rightString[] =
{
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	0
};

XObjectPtr
XalanEXSLTFunctionAlign::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	const XObjectArgVectorType::size_type	theSize = args.size();

	if (theSize != 2 && theSize != 3)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false && args[1].null() == false && (theSize == 2 || args[2].null() == false));

	const XalanDOMString&	theTargetString = args[0]->str();
	const XalanDOMString&	thePaddingString = args[1]->str();

	const XalanDOMString::size_type		theTargetStringLength = theTargetString.length();
	const XalanDOMString::size_type		thePaddingStringLength = thePaddingString.length();

	if (theTargetStringLength == thePaddingStringLength)
	{
		return XObjectPtr(args[0]);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		if (theTargetStringLength > thePaddingStringLength)
		{
			theResult.assign(theTargetString, 0, thePaddingStringLength);
		}
		else
		{
			theResult.reserve(thePaddingStringLength);

			enum eAlignment { eCenter, eLeft, eRight };

			eAlignment	theAlignment = eLeft;

			if (theSize == 3)
			{
				const XalanDOMString&	theAlignmentString = args[2]->str();

				if (equals(
							s_centerString,
							theAlignmentString.c_str(),
							sizeof(s_centerString) / sizeof(s_centerString[0]) - 1) == true)
				{
					theAlignment = eCenter;
				}
				else if (equals(
							s_rightString,
							theAlignmentString.c_str(),
							sizeof(s_rightString) / sizeof(s_rightString[0]) - 1) == true)
				{
					theAlignment = eRight;
				}
			}

			if (theAlignment == eLeft)
			{
				theResult = theTargetString;

				theResult.append(thePaddingString, theTargetStringLength, thePaddingStringLength - theTargetStringLength);
			}
			else if (theAlignment == eRight)
			{
				theResult.assign(thePaddingString, 0, thePaddingStringLength - theTargetStringLength);
				theResult.append(theTargetString);
			}
			else if (theAlignment == eCenter)
			{
				const XalanDOMString::size_type		theStartIndex =
					(thePaddingStringLength - theTargetStringLength) / 2;

				theResult.assign(thePaddingString, 0, theStartIndex);

				theResult.append(theTargetString);

				theResult.append(
					thePaddingString,
					theTargetStringLength + theStartIndex,
					thePaddingStringLength - theTargetStringLength - theStartIndex);
			}
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

static const XalanDOMString		s_emptyString;

XObjectPtr
XalanEXSLTFunctionConcat::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	if (args.size() != 1)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false);

	const NodeRefListBase&				theNodeSet = args[0]->nodeset();
	const NodeRefListBase::size_type	theLength = theNodeSet.getLength();

	if (theLength == 0)
	{
		return executionContext.getXObjectFactory().createStringReference(s_emptyString);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		for(NodeRefListBase::size_type i = 0; i < theLength; ++i)
		{
			assert(theNodeSet.item(i) != 0);

			DOMServices::getNodeData(*theNodeSet.item(i), theResult);
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

const XalanDOMChar	XalanEXSLTFunctionPadding::s_spaceString[] =
{
	XalanUnicode::charSpace,
	0
};

XObjectPtr
XalanEXSLTFunctionPadding::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	assert(m_space.length() == 1);

	const XObjectArgVectorType::size_type	theSize = args.size();

	if (theSize != 1 && theSize != 2)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false && (theSize == 1 || args[1].null() == false));

	const double						theLength = DoubleSupport::round(args[0]->num());
	const XalanDOMString&				thePaddingString = theSize == 2 ? args[1]->str() : m_space;
	const XalanDOMString::size_type		thePaddingStringLength = thePaddingString.length();

	if (theLength == 0.0 || thePaddingStringLength == 0)
	{
		return executionContext.getXObjectFactory().createStringReference(s_emptyString);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		if (thePaddingStringLength == 1)
		{
			theResult.assign(XalanDOMString::size_type(theLength), thePaddingString[0]);
		}
		else
		{
			XalanDOMString::size_type	theRemainingLength = XalanDOMString::size_type(theLength);

			for(;;)
			{
				if (theRemainingLength > thePaddingStringLength)
				{
					theResult.append(thePaddingString);

					theRemainingLength -= thePaddingStringLength;
				}
				else
				{
					theResult.append(
						thePaddingString,
						0,
						XalanDOMString::size_type(theRemainingLength));

					break;
				}
			}
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

static const XalanDOMChar	s_stringNamespace[] =
{
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_t,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_s,
	0
};

static const XalanDOMChar	s_alignFunctionName[] =
{
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_n,
	0
};

static const XalanDOMChar	s_concatFunctionName[] =
{
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	0
};

static const XalanDOMChar	s_paddingFunctionName[] =
{
	XalanUnicode::charLetter_p,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_g,
	0
};

static const XalanEXSLTFunctionAlign	s_alignFunction;
static const XalanEXSLTFunctionConcat	s_concatFunction;
// Note this is a special constructor of XalanEXSLTFunctionPadding which
// allocates no memory.  It is only used here, so we can have table-based
// initialization, but not have any memory allocation.
static const XalanEXSLTFunctionPadding	s_paddingFunction(1);

static const XalanEXSLTStringFunctionsInstaller::FunctionTableEntry		theFunctionTable[] =
{
	{ s_alignFunctionName, &s_alignFunction },
	{ s_concatFunctionName, &s_concatFunction },
	{ s_paddingFunctionName, &s_paddingFunction },
	{ 0, 0 }
};

void
XalanEXSLTStringFunctionsInstaller::installLocal(XPathEnvSupportDefault&		theSupport)
{
	doInstallLocal(s_stringNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTStringFunctionsInstaller::installGlobal()
{
	doInstallGlobal(s_stringNamespace, theFunctionTable);
}

void
XalanEXSLTStringFunctionsInstaller::uninstallLocal(XPathEnvSupportDefault&	theSupport)
{
	doUninstallLocal(s_stringNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTStringFunctionsInstaller::uninstallGlobal()
{
	doUninstallGlobal(s_stringNamespace, theFunctionTable);
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Better assert.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XalanEXSLTString.hpp"
#include "XalanEXSLTStringImpl.hpp"

#include <PlatformSupport/DoubleSupport.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathEnvSupportDefault.hpp>

XALAN_CPP_NAMESPACE_BEGIN

const XalanDOMChar	XalanEXSLTFunctionAlign::s_centerString[] =
{
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_r,
	0
};

const XalanDOMChar	XalanEXSLTFunctionAlign::s_rightString[] =
{
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	0
};

XObjectPtr
XalanEXSLTFunctionAlign::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	const XObjectArgVectorType::size_type	theSize = args.size();

	if (theSize != 2 && theSize != 3)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false && args[1].null() == false && (theSize == 2 || args[2].null() == false));

	const XalanDOMString&	theTargetString = args[0]->str();
	const XalanDOMString&	thePaddingString = args[1]->str();

	const XalanDOMString::size_type		theTargetStringLength = theTargetString.length();
	const XalanDOMString::size_type		thePaddingStringLength = thePaddingString.length();

	if (theTargetStringLength == thePaddingStringLength)
	{
		return XObjectPtr(args[0]);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		if (theTargetStringLength > thePaddingStringLength)
		{
			theResult.assign(theTargetString, 0, thePaddingStringLength);
		}
		else
		{
			theResult.reserve(thePaddingStringLength);

			enum eAlignment { eCenter, eLeft, eRight };

			eAlignment	theAlignment = eLeft;

			if (theSize == 3)
			{
				const XalanDOMString&	theAlignmentString = args[2]->str();

				if (equals(
							s_centerString,
							theAlignmentString.c_str(),
							sizeof(s_centerString) / sizeof(s_centerString[0]) - 1) == true)
				{
					theAlignment = eCenter;
				}
				else if (equals(
							s_rightString,
							theAlignmentString.c_str(),
							sizeof(s_rightString) / sizeof(s_rightString[0]) - 1) == true)
				{
					theAlignment = eRight;
				}
			}

			if (theAlignment == eLeft)
			{
				theResult = theTargetString;

				theResult.append(thePaddingString, theTargetStringLength, thePaddingStringLength - theTargetStringLength);
			}
			else if (theAlignment == eRight)
			{
				theResult.assign(thePaddingString, 0, thePaddingStringLength - theTargetStringLength);
				theResult.append(theTargetString);
			}
			else if (theAlignment == eCenter)
			{
				const XalanDOMString::size_type		theStartIndex =
					(thePaddingStringLength - theTargetStringLength) / 2;

				theResult.assign(thePaddingString, 0, theStartIndex);

				theResult.append(theTargetString);

				theResult.append(
					thePaddingString,
					theTargetStringLength + theStartIndex,
					thePaddingStringLength - theTargetStringLength - theStartIndex);
			}
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

static const XalanDOMString		s_emptyString;

XObjectPtr
XalanEXSLTFunctionConcat::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	if (args.size() != 1)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false);

	const NodeRefListBase&				theNodeSet = args[0]->nodeset();
	const NodeRefListBase::size_type	theLength = theNodeSet.getLength();

	if (theLength == 0)
	{
		return executionContext.getXObjectFactory().createStringReference(s_emptyString);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		for(NodeRefListBase::size_type i = 0; i < theLength; ++i)
		{
			assert(theNodeSet.item(i) != 0);

			DOMServices::getNodeData(*theNodeSet.item(i), theResult);
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

const XalanDOMChar	XalanEXSLTFunctionPadding::s_spaceString[] =
{
	XalanUnicode::charSpace,
	0
};

XObjectPtr
XalanEXSLTFunctionPadding::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	assert(m_space == s_spaceString);

	const XObjectArgVectorType::size_type	theSize = args.size();

	if (theSize != 1 && theSize != 2)
	{
		executionContext.error(getError(), context, locator);
	}

	assert(args[0].null() == false && (theSize == 1 || args[1].null() == false));

	const double						theLength = DoubleSupport::round(args[0]->num());
	const XalanDOMString&				thePaddingString = theSize == 2 ? args[1]->str() : m_space;
	const XalanDOMString::size_type		thePaddingStringLength = thePaddingString.length();

	if (theLength == 0.0 || thePaddingStringLength == 0)
	{
		return executionContext.getXObjectFactory().createStringReference(s_emptyString);
	}
	else
	{
		XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theResult = theGuard.get();

		if (thePaddingStringLength == 1)
		{
			theResult.assign(XalanDOMString::size_type(theLength), thePaddingString[0]);
		}
		else
		{
			XalanDOMString::size_type	theRemainingLength = XalanDOMString::size_type(theLength);

			for(;;)
			{
				if (theRemainingLength > thePaddingStringLength)
				{
					theResult.append(thePaddingString);

					theRemainingLength -= thePaddingStringLength;
				}
				else
				{
					theResult.append(
						thePaddingString,
						0,
						XalanDOMString::size_type(theRemainingLength));

					break;
				}
			}
		}

		return executionContext.getXObjectFactory().createString(theResult);
	}
}

static const XalanDOMChar	s_stringNamespace[] =
{
	XalanUnicode::charLetter_h,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_p,
	XalanUnicode::charColon,
	XalanUnicode::charSolidus,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_e,
	XalanUnicode::charLetter_x,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_t,
	XalanUnicode::charFullStop,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_g,
	XalanUnicode::charSolidus,
	XalanUnicode::charLetter_s,
	XalanUnicode::charLetter_t,
	XalanUnicode::charLetter_r,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_s,
	0
};

static const XalanDOMChar	s_alignFunctionName[] =
{
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_l,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_g,
	XalanUnicode::charLetter_n,
	0
};

static const XalanDOMChar	s_concatFunctionName[] =
{
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_o,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_c,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_t,
	0
};

static const XalanDOMChar	s_paddingFunctionName[] =
{
	XalanUnicode::charLetter_p,
	XalanUnicode::charLetter_a,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_d,
	XalanUnicode::charLetter_i,
	XalanUnicode::charLetter_n,
	XalanUnicode::charLetter_g,
	0
};

static const XalanEXSLTFunctionAlign	s_alignFunction;
static const XalanEXSLTFunctionConcat	s_concatFunction;
// Note this is a special constructor of XalanEXSLTFunctionPadding which
// allocates no memory.  It is only used here, so we can have table-based
// initialization, but not have any memory allocation.
static const XalanEXSLTFunctionPadding	s_paddingFunction(1);

static const XalanEXSLTStringFunctionsInstaller::FunctionTableEntry		theFunctionTable[] =
{
	{ s_alignFunctionName, &s_alignFunction },
	{ s_concatFunctionName, &s_concatFunction },
	{ s_paddingFunctionName, &s_paddingFunction },
	{ 0, 0 }
};

void
XalanEXSLTStringFunctionsInstaller::installLocal(XPathEnvSupportDefault&		theSupport)
{
	doInstallLocal(s_stringNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTStringFunctionsInstaller::installGlobal()
{
	doInstallGlobal(s_stringNamespace, theFunctionTable);
}

void
XalanEXSLTStringFunctionsInstaller::uninstallLocal(XPathEnvSupportDefault&	theSupport)
{
	doUninstallLocal(s_stringNamespace, theFunctionTable, theSupport);
}

void
XalanEXSLTStringFunctionsInstaller::uninstallGlobal()
{
	doUninstallGlobal(s_stringNamespace, theFunctionTable);
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>