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

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

=========================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, Kitware SAS 2012

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkExtractSelection.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkCellDistanceSelector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkPointData.h"
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridReader.h"
#include "vtkUnstructuredGridWriter.h"

#include <vtksys/ios/sstream>

// Reference values
vtkIdType cardCellDistanceSelection[] =
{
  125,
  16,
  19,
  73,
};

// ------------------------------------------------------------------------------------------------
static int CheckExtractedUGrid( vtkExtractSelection* extract,
                                const char* tag,
                                int testIdx,
                                bool writeGrid )
{
  // Output must be a multiblock dataset
  vtkMultiBlockDataSet* outputMB = vtkMultiBlockDataSet::SafeDownCast( extract->GetOutput() );
  if ( ! outputMB )
    {
    vtkGenericWarningMacro("Cannot downcast extracted selection to multiblock dataset.");

    return 1;
    }

  // First block must be an unstructured grid
  vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( outputMB->GetBlock( 0 ) );
  if ( ! ugrid )
    {
    vtkGenericWarningMacro("Cannot downcast extracted selection to unstructured grid.");

    return 1;
    }

  // Initialize test status
  int testStatus = 0;
  cerr << endl;

  // Verify selection cardinality
  vtkIdType nCells = ugrid->GetNumberOfCells();
  cout << tag
       << " contains "
       << nCells
       << " cells."
       << endl;

  if ( nCells != cardCellDistanceSelection[testIdx] )
    {
    vtkGenericWarningMacro( "Incorrect cardinality: "
                           << nCells
                           << " != "
                           << cardCellDistanceSelection[testIdx] );
    testStatus = 1;
    }

  // Verify selection cells
  cerr << "Original cell Ids: ";
  ugrid->GetCellData()->SetActiveScalars( "vtkOriginalCellIds" );
  vtkDataArray* oCellIds = ugrid->GetCellData()->GetScalars();
  for ( vtkIdType i = 0; i < oCellIds->GetNumberOfTuples(); ++ i )
    {
    cerr << oCellIds->GetTuple1( i )
         << " ";
    }
  cerr << endl;

  // If requested, write mesh
  if ( writeGrid )
    {
    vtksys_ios::ostringstream fileNameSS;
    fileNameSS << "./CellDistanceExtraction-"
               << testIdx
               << ".vtk";
    vtkSmartPointer<vtkUnstructuredGridWriter> writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New();
    writer->SetFileName( fileNameSS.str().c_str() );
    writer->SetInputData( ugrid );
    writer->Write();
    cerr << "Wrote file "
         << fileNameSS.str()
         << endl;
    }

  return testStatus;
}

//----------------------------------------------------------------------------
int TestCellDistanceSelector( int argc, char * argv [] )
{
  // Initialize test value
  int testIntValue = 0;

  // Read 3D unstructured input mesh
  char* fileName = vtkTestUtilities::ExpandDataFileName( argc, argv, "Data/AngularSector.vtk");
  vtkSmartPointer<vtkUnstructuredGridReader> reader = vtkSmartPointer<vtkUnstructuredGridReader>::New();
  reader->SetFileName( fileName );
  reader->Update();
  delete [] fileName;

  // Create multi-block mesh for linear selector
  vtkSmartPointer<vtkMultiBlockDataSet> mesh = vtkSmartPointer<vtkMultiBlockDataSet>::New();
  mesh->SetNumberOfBlocks( 1 );
  mesh->GetMetaData( static_cast<unsigned>( 0 ) )->Set( vtkCompositeDataSet::NAME(), "Mesh" );
  mesh->SetBlock( 0, reader->GetOutput() );

  // *****************************************************************************
  // 0. Selection within distance of 2 from cell 7010
  // *****************************************************************************

  // Create a selection, sel0, of cell with index 7010
  vtkSmartPointer<vtkIdTypeArray> selArr0 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr0->InsertNextValue( 7010 );
  vtkSmartPointer<vtkSelectionNode> selNode0 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode0->SetContentType( vtkSelectionNode::INDICES );
  selNode0->SetFieldType( vtkSelectionNode::CELL );
  selNode0->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode0->SetSelectionList( selArr0 );
  vtkSmartPointer<vtkSelection> sel0 = vtkSmartPointer<vtkSelection>::New();
  sel0->AddNode( selNode0 );

  // Create selection up to topological distance of 2
  vtkSmartPointer<vtkCellDistanceSelector> ls0 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls0->SetInputMesh( mesh );
  ls0->SetInputSelection( sel0 );
  ls0->SetDistance( 2 );

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es0 =  vtkSmartPointer<vtkExtractSelection>::New();
  es0->SetInputData( 0, mesh );
  es0->SetInputConnection( 1, ls0->GetOutputPort() );
  es0->Update();
  testIntValue += CheckExtractedUGrid( es0, "Selection d({7010})<3", 0, true );

  // *****************************************************************************
  // 1. Selection at distance of 1 from ridge 7643-7499-7355-7211, excluding it
  // *****************************************************************************

  // Create a selection, sel1, of cells with indices 7643-7499-7355-7211
  vtkSmartPointer<vtkIdTypeArray> selArr1 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr1->InsertNextValue( 7643 );
  selArr1->InsertNextValue( 7499 );
  selArr1->InsertNextValue( 7355 );
  selArr1->InsertNextValue( 7211 );
  vtkSmartPointer<vtkSelectionNode> selNode1 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode1->SetContentType( vtkSelectionNode::INDICES );
  selNode1->SetFieldType( vtkSelectionNode::CELL );
  selNode1->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode1->SetSelectionList( selArr1 );
  vtkSmartPointer<vtkSelection> sel1 = vtkSmartPointer<vtkSelection>::New();
  sel1->AddNode( selNode1 );

  // Create selection at distance of 1
  vtkSmartPointer<vtkCellDistanceSelector> ls1 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls1->SetInputMesh( mesh );
  ls1->SetInputSelection( sel1 );
  ls1->SetDistance( 1 );
  ls1->IncludeSeedOff();

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es1 =  vtkSmartPointer<vtkExtractSelection>::New();
  es1->SetInputData( 0, mesh );
  es1->SetInputConnection( 1, ls1->GetOutputPort() );
  es1->Update();
  testIntValue += CheckExtractedUGrid( es1, "Selection d({7643-7499-7355-7211})=1", 1, true );

  // *****************************************************************************
  // 2. Selection at distance of 2 from corner 7632
  // *****************************************************************************

  // Create a selection, sel2, of cell with index 7632
  vtkSmartPointer<vtkIdTypeArray> selArr2 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr2->InsertNextValue( 7632 );
  vtkSmartPointer<vtkSelectionNode> selNode2 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode2->SetContentType( vtkSelectionNode::INDICES );
  selNode2->SetFieldType( vtkSelectionNode::CELL );
  selNode2->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode2->SetSelectionList( selArr2 );
  vtkSmartPointer<vtkSelection> sel2 = vtkSmartPointer<vtkSelection>::New();
  sel2->AddNode( selNode2 );

  // Create selection at distance of 2
  vtkSmartPointer<vtkCellDistanceSelector> ls2 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls2->SetInputMesh( mesh );
  ls2->SetInputSelection( sel2 );
  ls2->SetDistance( 2 );
  ls2->IncludeSeedOff();
  ls2->AddIntermediateOff();

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es2 =  vtkSmartPointer<vtkExtractSelection>::New();
  es2->SetInputData( 0, mesh );
  es2->SetInputConnection( 1, ls2->GetOutputPort() );
  es2->Update();
  testIntValue += CheckExtractedUGrid( es2, "Selection d({7632})=2", 2, true );

  // *****************************************************************************
  // 3. Selection within distance of 1 from cells 6413, 7268, and 7399
  // *****************************************************************************

  // Create a selection, sel3, of cells with indices 6413, 7268, and 7399
  vtkSmartPointer<vtkIdTypeArray> selArr3 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr3->InsertNextValue( 6413 );
  selArr3->InsertNextValue( 7268 );
  selArr3->InsertNextValue( 7399 );
  vtkSmartPointer<vtkSelectionNode> selNode3 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode3->SetContentType( vtkSelectionNode::INDICES );
  selNode3->SetFieldType( vtkSelectionNode::CELL );
  selNode3->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode3->SetSelectionList( selArr3 );
  vtkSmartPointer<vtkSelection> sel3 = vtkSmartPointer<vtkSelection>::New();
  sel3->AddNode( selNode3 );

  // Create selection within distance of 1
  vtkSmartPointer<vtkCellDistanceSelector> ls3 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls3->SetInputMesh( mesh );
  ls3->SetInputSelection( sel3 );
  ls3->SetDistance( 1 );

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es3 =  vtkSmartPointer<vtkExtractSelection>::New();
  es3->SetInputData( 0, mesh );
  es3->SetInputConnection( 1, ls3->GetOutputPort() );
  es3->Update();
  testIntValue += CheckExtractedUGrid( es3, "Selection d({6413,7268,7399})=1", 3, true );

  return testIntValue;
}
<commit_msg>Added a test for the IncludeSeed option when the seed is visible<commit_after>/*=========================================================================

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

=========================================================================*/
// .SECTION Thanks
// This test was written by Philippe Pebay, Kitware SAS 2012

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkExtractSelection.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkCellDistanceSelector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkPointData.h"
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridReader.h"
#include "vtkUnstructuredGridWriter.h"

#include <vtksys/ios/sstream>

// Reference values
vtkIdType cardCellDistanceSelection[] =
{
  125,
  16,
  20,
  73,
};

// ------------------------------------------------------------------------------------------------
static int CheckExtractedUGrid( vtkExtractSelection* extract,
                                const char* tag,
                                int testIdx,
                                bool writeGrid )
{
  // Output must be a multiblock dataset
  vtkMultiBlockDataSet* outputMB = vtkMultiBlockDataSet::SafeDownCast( extract->GetOutput() );
  if ( ! outputMB )
    {
    vtkGenericWarningMacro("Cannot downcast extracted selection to multiblock dataset.");

    return 1;
    }

  // First block must be an unstructured grid
  vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( outputMB->GetBlock( 0 ) );
  if ( ! ugrid )
    {
    vtkGenericWarningMacro("Cannot downcast extracted selection to unstructured grid.");

    return 1;
    }

  // Initialize test status
  int testStatus = 0;
  cerr << endl;

  // Verify selection cardinality
  vtkIdType nCells = ugrid->GetNumberOfCells();
  cout << tag
       << " contains "
       << nCells
       << " cells."
       << endl;

  if ( nCells != cardCellDistanceSelection[testIdx] )
    {
    vtkGenericWarningMacro( "Incorrect cardinality: "
                           << nCells
                           << " != "
                           << cardCellDistanceSelection[testIdx] );
    testStatus = 1;
    }

  // Verify selection cells
  cerr << "Original cell Ids: ";
  ugrid->GetCellData()->SetActiveScalars( "vtkOriginalCellIds" );
  vtkDataArray* oCellIds = ugrid->GetCellData()->GetScalars();
  for ( vtkIdType i = 0; i < oCellIds->GetNumberOfTuples(); ++ i )
    {
    cerr << oCellIds->GetTuple1( i )
         << " ";
    }
  cerr << endl;

  // If requested, write mesh
  if ( writeGrid )
    {
    vtksys_ios::ostringstream fileNameSS;
    fileNameSS << "./CellDistanceExtraction-"
               << testIdx
               << ".vtk";
    vtkSmartPointer<vtkUnstructuredGridWriter> writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New();
    writer->SetFileName( fileNameSS.str().c_str() );
    writer->SetInputData( ugrid );
    writer->Write();
    cerr << "Wrote file "
         << fileNameSS.str()
         << endl;
    }

  return testStatus;
}

//----------------------------------------------------------------------------
int TestCellDistanceSelector( int argc, char * argv [] )
{
  // Initialize test value
  int testIntValue = 0;

  // Read 3D unstructured input mesh
  char* fileName = vtkTestUtilities::ExpandDataFileName( argc, argv, "Data/AngularSector.vtk");
  vtkSmartPointer<vtkUnstructuredGridReader> reader = vtkSmartPointer<vtkUnstructuredGridReader>::New();
  reader->SetFileName( fileName );
  reader->Update();
  delete [] fileName;

  // Create multi-block mesh for linear selector
  vtkSmartPointer<vtkMultiBlockDataSet> mesh = vtkSmartPointer<vtkMultiBlockDataSet>::New();
  mesh->SetNumberOfBlocks( 1 );
  mesh->GetMetaData( static_cast<unsigned>( 0 ) )->Set( vtkCompositeDataSet::NAME(), "Mesh" );
  mesh->SetBlock( 0, reader->GetOutput() );

  // *****************************************************************************
  // 0. Selection within distance of 2 from cell 7010
  // *****************************************************************************

  // Create a selection, sel0, of cell with index 7010
  vtkSmartPointer<vtkIdTypeArray> selArr0 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr0->InsertNextValue( 7010 );
  vtkSmartPointer<vtkSelectionNode> selNode0 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode0->SetContentType( vtkSelectionNode::INDICES );
  selNode0->SetFieldType( vtkSelectionNode::CELL );
  selNode0->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode0->SetSelectionList( selArr0 );
  vtkSmartPointer<vtkSelection> sel0 = vtkSmartPointer<vtkSelection>::New();
  sel0->AddNode( selNode0 );

  // Create selection up to topological distance of 2
  vtkSmartPointer<vtkCellDistanceSelector> ls0 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls0->SetInputMesh( mesh );
  ls0->SetInputSelection( sel0 );
  ls0->SetDistance( 2 );

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es0 =  vtkSmartPointer<vtkExtractSelection>::New();
  es0->SetInputData( 0, mesh );
  es0->SetInputConnection( 1, ls0->GetOutputPort() );
  es0->Update();
  testIntValue += CheckExtractedUGrid( es0, "Selection d({7010})<3", 0, true );

  // *****************************************************************************
  // 1. Selection at distance of 1 from ridge 7643-7499-7355-7211, excluding it
  // *****************************************************************************

  // Create a selection, sel1, of cells with indices 7643-7499-7355-7211
  vtkSmartPointer<vtkIdTypeArray> selArr1 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr1->InsertNextValue( 7643 );
  selArr1->InsertNextValue( 7499 );
  selArr1->InsertNextValue( 7355 );
  selArr1->InsertNextValue( 7211 );
  vtkSmartPointer<vtkSelectionNode> selNode1 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode1->SetContentType( vtkSelectionNode::INDICES );
  selNode1->SetFieldType( vtkSelectionNode::CELL );
  selNode1->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode1->SetSelectionList( selArr1 );
  vtkSmartPointer<vtkSelection> sel1 = vtkSmartPointer<vtkSelection>::New();
  sel1->AddNode( selNode1 );

  // Create selection at distance of 1
  vtkSmartPointer<vtkCellDistanceSelector> ls1 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls1->SetInputMesh( mesh );
  ls1->SetInputSelection( sel1 );
  ls1->SetDistance( 1 );
  ls1->IncludeSeedOff();

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es1 =  vtkSmartPointer<vtkExtractSelection>::New();
  es1->SetInputData( 0, mesh );
  es1->SetInputConnection( 1, ls1->GetOutputPort() );
  es1->Update();
  testIntValue += CheckExtractedUGrid( es1, "Selection d({7643-7499-7355-7211})=1", 1, true );

  // *****************************************************************************
  // 2. Selection at distance of 2 from corner 7632, retaining seed
  // *****************************************************************************

  // Create a selection, sel2, of cell with index 7632
  vtkSmartPointer<vtkIdTypeArray> selArr2 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr2->InsertNextValue( 7632 );
  vtkSmartPointer<vtkSelectionNode> selNode2 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode2->SetContentType( vtkSelectionNode::INDICES );
  selNode2->SetFieldType( vtkSelectionNode::CELL );
  selNode2->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode2->SetSelectionList( selArr2 );
  vtkSmartPointer<vtkSelection> sel2 = vtkSmartPointer<vtkSelection>::New();
  sel2->AddNode( selNode2 );

  // Create selection at distance of 2
  vtkSmartPointer<vtkCellDistanceSelector> ls2 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls2->SetInputMesh( mesh );
  ls2->SetInputSelection( sel2 );
  ls2->SetDistance( 2 );
  ls2->AddIntermediateOff();

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es2 =  vtkSmartPointer<vtkExtractSelection>::New();
  es2->SetInputData( 0, mesh );
  es2->SetInputConnection( 1, ls2->GetOutputPort() );
  es2->Update();
  testIntValue += CheckExtractedUGrid( es2, "Selection d({7632})=0|2", 2, true );

  // *****************************************************************************
  // 3. Selection within distance of 1 from cells 6413, 7268, and 7399
  // *****************************************************************************

  // Create a selection, sel3, of cells with indices 6413, 7268, and 7399
  vtkSmartPointer<vtkIdTypeArray> selArr3 = vtkSmartPointer<vtkIdTypeArray>::New();
  selArr3->InsertNextValue( 6413 );
  selArr3->InsertNextValue( 7268 );
  selArr3->InsertNextValue( 7399 );
  vtkSmartPointer<vtkSelectionNode> selNode3 = vtkSmartPointer<vtkSelectionNode>::New();
  selNode3->SetContentType( vtkSelectionNode::INDICES );
  selNode3->SetFieldType( vtkSelectionNode::CELL );
  selNode3->GetProperties()->Set( vtkSelectionNode::COMPOSITE_INDEX(), 1 );
  selNode3->SetSelectionList( selArr3 );
  vtkSmartPointer<vtkSelection> sel3 = vtkSmartPointer<vtkSelection>::New();
  sel3->AddNode( selNode3 );

  // Create selection within distance of 1
  vtkSmartPointer<vtkCellDistanceSelector> ls3 = vtkSmartPointer<vtkCellDistanceSelector>::New();
  ls3->SetInputMesh( mesh );
  ls3->SetInputSelection( sel3 );
  ls3->SetDistance( 1 );

  // Extract selection from mesh
  vtkSmartPointer<vtkExtractSelection> es3 =  vtkSmartPointer<vtkExtractSelection>::New();
  es3->SetInputData( 0, mesh );
  es3->SetInputConnection( 1, ls3->GetOutputPort() );
  es3->Update();
  testIntValue += CheckExtractedUGrid( es3, "Selection d({6413,7268,7399})=1", 3, true );

  return testIntValue;
}
<|endoftext|>


<commit_before>//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "AuxVector.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

static bool GetMaxU64(DataExtractor &data, lldb::offset_t *offset_ptr,
                      uint64_t *value, unsigned int byte_size) {
  lldb::offset_t saved_offset = *offset_ptr;
  *value = data.GetMaxU64(offset_ptr, byte_size);
  return *offset_ptr != saved_offset;
}

static bool ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
                           lldb::offset_t *offset_ptr, unsigned int byte_size) {
  if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
    return false;

  if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
    return false;

  return true;
}

DataBufferSP AuxVector::GetAuxvData() {
  if (m_process)
    return m_process->GetAuxvData();
  else
    return DataBufferSP();
}

void AuxVector::ParseAuxv(DataExtractor &data) {
  const unsigned int byte_size = m_process->GetAddressByteSize();
  lldb::offset_t offset = 0;

  for (;;) {
    Entry entry;

    if (!ParseAuxvEntry(data, entry, &offset, byte_size))
      break;

    if (entry.type == AUXV_AT_NULL)
      break;

    if (entry.type == AUXV_AT_IGNORE)
      continue;

    m_auxv.push_back(entry);
  }
}

AuxVector::AuxVector(Process *process) : m_process(process) {
  DataExtractor data;
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));

  data.SetData(GetAuxvData());
  data.SetByteOrder(m_process->GetByteOrder());
  data.SetAddressByteSize(m_process->GetAddressByteSize());

  ParseAuxv(data);

  if (log)
    DumpToLog(log);
}

AuxVector::iterator AuxVector::FindEntry(EntryType type) const {
  for (iterator I = begin(); I != end(); ++I) {
    if (I->type == static_cast<uint64_t>(type))
      return I;
  }

  return end();
}

void AuxVector::DumpToLog(Log *log) const {
  if (!log)
    return;

  log->PutCString("AuxVector: ");
  for (iterator I = begin(); I != end(); ++I) {
    log->Printf("   %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type,
                I->value);
  }
}

const char *AuxVector::GetEntryName(EntryType type) {
  const char *name = "AT_???";

#define ENTRY_NAME(_type) \
  _type:                  \
  name = #_type + 5
  switch (type) {
    case ENTRY_NAME(AUXV_AT_NULL);           break;
    case ENTRY_NAME(AUXV_AT_IGNORE);         break;
    case ENTRY_NAME(AUXV_AT_EXECFD);         break;
    case ENTRY_NAME(AUXV_AT_PHDR);           break;
    case ENTRY_NAME(AUXV_AT_PHENT);          break;
    case ENTRY_NAME(AUXV_AT_PHNUM);          break;
    case ENTRY_NAME(AUXV_AT_PAGESZ);         break;
    case ENTRY_NAME(AUXV_AT_BASE);           break;
    case ENTRY_NAME(AUXV_AT_FLAGS);          break;
    case ENTRY_NAME(AUXV_AT_ENTRY);          break;
    case ENTRY_NAME(AUXV_AT_NOTELF);         break;
    case ENTRY_NAME(AUXV_AT_UID);            break;
    case ENTRY_NAME(AUXV_AT_EUID);           break;
    case ENTRY_NAME(AUXV_AT_GID);            break;
    case ENTRY_NAME(AUXV_AT_EGID);           break;
    case ENTRY_NAME(AUXV_AT_CLKTCK);         break;
    case ENTRY_NAME(AUXV_AT_PLATFORM);       break;
    case ENTRY_NAME(AUXV_AT_HWCAP);          break;
    case ENTRY_NAME(AUXV_AT_FPUCW);          break;
    case ENTRY_NAME(AUXV_AT_DCACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_ICACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_UCACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_IGNOREPPC);      break;
    case ENTRY_NAME(AUXV_AT_SECURE);         break;
    case ENTRY_NAME(AUXV_AT_BASE_PLATFORM);  break;
    case ENTRY_NAME(AUXV_AT_RANDOM);         break;
    case ENTRY_NAME(AUXV_AT_EXECFN);         break;
    case ENTRY_NAME(AUXV_AT_SYSINFO);        break;
    case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR);   break;
    case ENTRY_NAME(AUXV_AT_L1I_CACHESHAPE); break;
    case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break;
    case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE);  break;
    case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE);  break;
    }
#undef ENTRY_NAME

    return name;
}
<commit_msg>[lldb] Fix -Wstring-plus-int warning in POSIX-DYLD/AuxVector.cpp<commit_after>//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "AuxVector.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

static bool GetMaxU64(DataExtractor &data, lldb::offset_t *offset_ptr,
                      uint64_t *value, unsigned int byte_size) {
  lldb::offset_t saved_offset = *offset_ptr;
  *value = data.GetMaxU64(offset_ptr, byte_size);
  return *offset_ptr != saved_offset;
}

static bool ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
                           lldb::offset_t *offset_ptr, unsigned int byte_size) {
  if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
    return false;

  if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
    return false;

  return true;
}

DataBufferSP AuxVector::GetAuxvData() {
  if (m_process)
    return m_process->GetAuxvData();
  else
    return DataBufferSP();
}

void AuxVector::ParseAuxv(DataExtractor &data) {
  const unsigned int byte_size = m_process->GetAddressByteSize();
  lldb::offset_t offset = 0;

  for (;;) {
    Entry entry;

    if (!ParseAuxvEntry(data, entry, &offset, byte_size))
      break;

    if (entry.type == AUXV_AT_NULL)
      break;

    if (entry.type == AUXV_AT_IGNORE)
      continue;

    m_auxv.push_back(entry);
  }
}

AuxVector::AuxVector(Process *process) : m_process(process) {
  DataExtractor data;
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));

  data.SetData(GetAuxvData());
  data.SetByteOrder(m_process->GetByteOrder());
  data.SetAddressByteSize(m_process->GetAddressByteSize());

  ParseAuxv(data);

  if (log)
    DumpToLog(log);
}

AuxVector::iterator AuxVector::FindEntry(EntryType type) const {
  for (iterator I = begin(); I != end(); ++I) {
    if (I->type == static_cast<uint64_t>(type))
      return I;
  }

  return end();
}

void AuxVector::DumpToLog(Log *log) const {
  if (!log)
    return;

  log->PutCString("AuxVector: ");
  for (iterator I = begin(); I != end(); ++I) {
    log->Printf("   %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type,
                I->value);
  }
}

const char *AuxVector::GetEntryName(EntryType type) {
  const char *name = "AT_???";

#define ENTRY_NAME(_type) \
  _type:                  \
  name = &#_type[5]
  switch (type) {
    case ENTRY_NAME(AUXV_AT_NULL);           break;
    case ENTRY_NAME(AUXV_AT_IGNORE);         break;
    case ENTRY_NAME(AUXV_AT_EXECFD);         break;
    case ENTRY_NAME(AUXV_AT_PHDR);           break;
    case ENTRY_NAME(AUXV_AT_PHENT);          break;
    case ENTRY_NAME(AUXV_AT_PHNUM);          break;
    case ENTRY_NAME(AUXV_AT_PAGESZ);         break;
    case ENTRY_NAME(AUXV_AT_BASE);           break;
    case ENTRY_NAME(AUXV_AT_FLAGS);          break;
    case ENTRY_NAME(AUXV_AT_ENTRY);          break;
    case ENTRY_NAME(AUXV_AT_NOTELF);         break;
    case ENTRY_NAME(AUXV_AT_UID);            break;
    case ENTRY_NAME(AUXV_AT_EUID);           break;
    case ENTRY_NAME(AUXV_AT_GID);            break;
    case ENTRY_NAME(AUXV_AT_EGID);           break;
    case ENTRY_NAME(AUXV_AT_CLKTCK);         break;
    case ENTRY_NAME(AUXV_AT_PLATFORM);       break;
    case ENTRY_NAME(AUXV_AT_HWCAP);          break;
    case ENTRY_NAME(AUXV_AT_FPUCW);          break;
    case ENTRY_NAME(AUXV_AT_DCACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_ICACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_UCACHEBSIZE);    break;
    case ENTRY_NAME(AUXV_AT_IGNOREPPC);      break;
    case ENTRY_NAME(AUXV_AT_SECURE);         break;
    case ENTRY_NAME(AUXV_AT_BASE_PLATFORM);  break;
    case ENTRY_NAME(AUXV_AT_RANDOM);         break;
    case ENTRY_NAME(AUXV_AT_EXECFN);         break;
    case ENTRY_NAME(AUXV_AT_SYSINFO);        break;
    case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR);   break;
    case ENTRY_NAME(AUXV_AT_L1I_CACHESHAPE); break;
    case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break;
    case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE);  break;
    case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE);  break;
    }
#undef ENTRY_NAME

    return name;
}
<|endoftext|>


<commit_before>#pragma once

#include "depthai-shared/common/CameraBoardSocket.hpp"
#include "depthai-shared/common/CameraImageOrientation.hpp"
#include "depthai-shared/datatype/RawCameraControl.hpp"
#include "depthai-shared/properties/Properties.hpp"

namespace dai {

/**
 *  Specify properties for ColorCamera such as camera ID, ...
 */
struct ColorCameraProperties : PropertiesSerializable<Properties, ColorCameraProperties> {
    static constexpr int AUTO = -1;

    struct IspScale {
        int32_t horizNumerator = 0;
        int32_t horizDenominator = 0;
        int32_t vertNumerator = 0;
        int32_t vertDenominator = 0;

        DEPTHAI_SERIALIZE(IspScale, horizNumerator, horizDenominator, vertNumerator, vertDenominator);
    };

    /**
     * Select the camera sensor resolution
     */
    enum class SensorResolution : int32_t { THE_1080_P, THE_1200_P, THE_4_K, THE_5_MP, THE_12_MP, THE_12P0_MP, THE_13_MP, THE_5312X6000, THE_48_MP, THE_720_P, THE_800_P };

    /**
     * For 24 bit color these can be either RGB or BGR
     */
    enum class ColorOrder : int32_t { BGR, RGB };

    /*
     * Initial controls applied to ColorCamera node
     */
    RawCameraControl initialControl;

    /**
     * Which socket will color camera use
     */
    CameraBoardSocket boardSocket = CameraBoardSocket::AUTO;

    /**
     * Camera sensor image orientation / pixel readout
     */
    CameraImageOrientation imageOrientation = CameraImageOrientation::AUTO;

    /**
     * For 24 bit color these can be either RGB or BGR
     */
    ColorOrder colorOrder = ColorOrder::BGR;
    /**
     * Are colors interleaved (R1G1B1, R2G2B2, ...) or planar (R1R2..., G1G2..., B1B2)
     */
    bool interleaved = true;
    /**
     * Are values FP16 type (0.0 - 255.0)
     */
    bool fp16 = false;

    /**
     * Preview frame output height
     */
    uint32_t previewHeight = 300;
    /**
     * Preview frame output width
     */
    uint32_t previewWidth = 300;

    /**
     * Preview frame output width
     */
    int32_t videoWidth = AUTO;

    /**
     * Preview frame output height
     */
    int32_t videoHeight = AUTO;

    /**
     * Preview frame output width
     */
    int32_t stillWidth = AUTO;

    /**
     * Preview frame output height
     */
    int32_t stillHeight = AUTO;

    /**
     * Select the camera sensor resolution
     */
    SensorResolution resolution = SensorResolution::THE_1080_P;
    /**
     * Camera sensor FPS
     */
    float fps = 30.0;

    /**
     * Initial sensor crop, -1 signifies center crop
     */
    float sensorCropX = AUTO;
    float sensorCropY = AUTO;

    /**
     * Whether to keep aspect ratio of input (video size) or not
     */
    bool previewKeepAspectRatio = true;

    /**
     * Configure scaling for `isp` output.
     */
    IspScale ispScale;

    /**
     * Pool sizes
     */
    int numFramesPoolRaw = 3;
    int numFramesPoolIsp = 3;
    int numFramesPoolVideo = 4;
    int numFramesPoolPreview = 4;
    int numFramesPoolStill = 4;
};

DEPTHAI_SERIALIZE_EXT(ColorCameraProperties,
                      initialControl,
                      boardSocket,
                      imageOrientation,
                      colorOrder,
                      interleaved,
                      fp16,
                      previewHeight,
                      previewWidth,
                      videoWidth,
                      videoHeight,
                      stillWidth,
                      stillHeight,
                      resolution,
                      fps,
                      sensorCropX,
                      sensorCropY,
                      previewKeepAspectRatio,
                      ispScale,
                      numFramesPoolRaw,
                      numFramesPoolIsp,
                      numFramesPoolVideo,
                      numFramesPoolPreview,
                      numFramesPoolStill);

}  // namespace dai
<commit_msg>`make clangformat`<commit_after>#pragma once

#include "depthai-shared/common/CameraBoardSocket.hpp"
#include "depthai-shared/common/CameraImageOrientation.hpp"
#include "depthai-shared/datatype/RawCameraControl.hpp"
#include "depthai-shared/properties/Properties.hpp"

namespace dai {

/**
 *  Specify properties for ColorCamera such as camera ID, ...
 */
struct ColorCameraProperties : PropertiesSerializable<Properties, ColorCameraProperties> {
    static constexpr int AUTO = -1;

    struct IspScale {
        int32_t horizNumerator = 0;
        int32_t horizDenominator = 0;
        int32_t vertNumerator = 0;
        int32_t vertDenominator = 0;

        DEPTHAI_SERIALIZE(IspScale, horizNumerator, horizDenominator, vertNumerator, vertDenominator);
    };

    /**
     * Select the camera sensor resolution
     */
    enum class SensorResolution : int32_t {
        THE_1080_P,
        THE_1200_P,
        THE_4_K,
        THE_5_MP,
        THE_12_MP,
        THE_12P0_MP,
        THE_13_MP,
        THE_5312X6000,
        THE_48_MP,
        THE_720_P,
        THE_800_P
    };

    /**
     * For 24 bit color these can be either RGB or BGR
     */
    enum class ColorOrder : int32_t { BGR, RGB };

    /*
     * Initial controls applied to ColorCamera node
     */
    RawCameraControl initialControl;

    /**
     * Which socket will color camera use
     */
    CameraBoardSocket boardSocket = CameraBoardSocket::AUTO;

    /**
     * Camera sensor image orientation / pixel readout
     */
    CameraImageOrientation imageOrientation = CameraImageOrientation::AUTO;

    /**
     * For 24 bit color these can be either RGB or BGR
     */
    ColorOrder colorOrder = ColorOrder::BGR;
    /**
     * Are colors interleaved (R1G1B1, R2G2B2, ...) or planar (R1R2..., G1G2..., B1B2)
     */
    bool interleaved = true;
    /**
     * Are values FP16 type (0.0 - 255.0)
     */
    bool fp16 = false;

    /**
     * Preview frame output height
     */
    uint32_t previewHeight = 300;
    /**
     * Preview frame output width
     */
    uint32_t previewWidth = 300;

    /**
     * Preview frame output width
     */
    int32_t videoWidth = AUTO;

    /**
     * Preview frame output height
     */
    int32_t videoHeight = AUTO;

    /**
     * Preview frame output width
     */
    int32_t stillWidth = AUTO;

    /**
     * Preview frame output height
     */
    int32_t stillHeight = AUTO;

    /**
     * Select the camera sensor resolution
     */
    SensorResolution resolution = SensorResolution::THE_1080_P;
    /**
     * Camera sensor FPS
     */
    float fps = 30.0;

    /**
     * Initial sensor crop, -1 signifies center crop
     */
    float sensorCropX = AUTO;
    float sensorCropY = AUTO;

    /**
     * Whether to keep aspect ratio of input (video size) or not
     */
    bool previewKeepAspectRatio = true;

    /**
     * Configure scaling for `isp` output.
     */
    IspScale ispScale;

    /**
     * Pool sizes
     */
    int numFramesPoolRaw = 3;
    int numFramesPoolIsp = 3;
    int numFramesPoolVideo = 4;
    int numFramesPoolPreview = 4;
    int numFramesPoolStill = 4;
};

DEPTHAI_SERIALIZE_EXT(ColorCameraProperties,
                      initialControl,
                      boardSocket,
                      imageOrientation,
                      colorOrder,
                      interleaved,
                      fp16,
                      previewHeight,
                      previewWidth,
                      videoWidth,
                      videoHeight,
                      stillWidth,
                      stillHeight,
                      resolution,
                      fps,
                      sensorCropX,
                      sensorCropY,
                      previewKeepAspectRatio,
                      ispScale,
                      numFramesPoolRaw,
                      numFramesPoolIsp,
                      numFramesPoolVideo,
                      numFramesPoolPreview,
                      numFramesPoolStill);

}  // namespace dai
<|endoftext|>


<commit_before>#include "MeshRenderer.hh"

#include "ResourceManager/Texture.hh"

#include "Core/Engine.hh"

namespace Components
{

	MeshRenderer::MeshRenderer(std::string const &name, std::string const &resource) :
		AComponent(name),
		_mesh(GameEngine::instance()->resources().getResource(resource)),
		_next(NULL)
	{
	}

	MeshRenderer::~MeshRenderer(void)
	{
	}

	void	MeshRenderer::start()
	{
	}

	void	MeshRenderer::update()
	{
		GameEngine::instance()->renderer().addToRenderQueue(this);
	}

	void	MeshRenderer::stop()
	{
	}

	bool	MeshRenderer::setShader(std::string const &name)
	{
		_shader = name;
		return (true);
	}

	std::string const		&MeshRenderer::getShader() const
	{
		return (_shader);
	}

	SmartPointer<Resources::SharedMesh> const &MeshRenderer::getMesh() const
	{
		return (_mesh);
	}

	void MeshRenderer::addTexture(const std::string &textureName, const std::string &name, unsigned int priority)
	{
		SmartPointer<Resources::Texture> texture = GameEngine::instance()->resources().getResource(textureName);

		for (textureMapIt it = _textures.begin(); it != _textures.end(); ++it)
		{
			if (it->second.first == name)
				return;
		}
		_textures.insert(std::make_pair(priority, std::make_pair(name, texture)));
	}

	void MeshRenderer::removeTexture(const std::string &name)
	{
		for (textureMapIt it = _textures.begin(); it != _textures.end(); ++it)
		{
			if (it->second.first == name)
			{
				_textures.erase(it);
				return;
			}
		}
	}

	void MeshRenderer::bindTextures() const
	{
		unsigned int c = 0;
		for (textureMap::const_iterator it = _textures.begin(); it != _textures.end(); ++it)
		{
			glActiveTexture(GL_TEXTURE0 + c);
			glBindTexture(GL_TEXTURE_2D, it->second.second->getId());
			++c;
		}
	}

	void MeshRenderer::unbindTextures() const
	{
		//unsigned int c = 0;
		//for (textureMap::const_iterator it = _textures.begin(); it != _textures.end(); ++it)
		//{
		//	glActiveTexture(GL_TEXTURE0 + c);
		//	glBindTexture(GL_TEXTURE_2D, 0);
		//	++c;
		//}
		//glActiveTexture(GL_TEXTURE0);
	}

	void			MeshRenderer::setNext(MeshRenderer *next)
	{
		_next = next;
	}

	MeshRenderer	*MeshRenderer::getNext() const
	{
		return (_next);
	}

	void MeshRenderer::addMaterial(SmartPointer<Material> material)
	{
		material->addObject(this);
		_materials.insert(material->getName());
	}

	void MeshRenderer::removeMaterial(SmartPointer<Material> material)
	{
		// be carefull when iterating on it
		material->removeObject(this);
		_materials.erase(material->getName());
	}

	void MeshRenderer::addMaterial(const std::string &material)
	{
		SmartPointer<Material> m = GameEngine::instance()->renderer().getMaterialManager().getMaterial(material);
		if (!m.get())
			return;
		m->addObject(this);
		_materials.insert(m->getName());
	}

	void MeshRenderer::removeMaterial(const std::string &material)
	{
		SmartPointer<Material> m = GameEngine::instance()->renderer().getMaterialManager().getMaterial(material);
		if (!m.get())
			return;
		m->removeObject(this);
		_materials.erase(m->getName());
	}
}<commit_msg>Some comments<commit_after>#include "MeshRenderer.hh"

#include "ResourceManager/Texture.hh"

#include "Core/Engine.hh"

namespace Components
{

	MeshRenderer::MeshRenderer(std::string const &name, std::string const &resource) :
		AComponent(name),
		_mesh(GameEngine::instance()->resources().getResource(resource)),
		_next(NULL)
	{
	}

	MeshRenderer::~MeshRenderer(void)
	{
	}

	void	MeshRenderer::start()
	{
	}

	void	MeshRenderer::update()
	{
		GameEngine::instance()->renderer().addToRenderQueue(this);
	}

	void	MeshRenderer::stop()
	{
	}

	bool	MeshRenderer::setShader(std::string const &name)
	{
		_shader = name;
		return (true);
	}

	std::string const		&MeshRenderer::getShader() const
	{
		return (_shader);
	}

	SmartPointer<Resources::SharedMesh> const &MeshRenderer::getMesh() const
	{
		return (_mesh);
	}

	void MeshRenderer::addTexture(const std::string &textureName, const std::string &name, unsigned int priority)
	{
		SmartPointer<Resources::Texture> texture = GameEngine::instance()->resources().getResource(textureName);

		for (textureMapIt it = _textures.begin(); it != _textures.end(); ++it)
		{
			if (it->second.first == name)
				return;
		}
		_textures.insert(std::make_pair(priority, std::make_pair(name, texture)));
	}

	void MeshRenderer::removeTexture(const std::string &name)
	{
		for (textureMapIt it = _textures.begin(); it != _textures.end(); ++it)
		{
			if (it->second.first == name)
			{
				_textures.erase(it);
				return;
			}
		}
	}

	void MeshRenderer::bindTextures() const
	{
		//
		// a little bit hardcodeded -> to clean
		//
		unsigned int c = 0;
		for (textureMap::const_iterator it = _textures.begin(); it != _textures.end(); ++it)
		{
			glActiveTexture(GL_TEXTURE0 + c);
			glBindTexture(GL_TEXTURE_2D, it->second.second->getId());
			++c;
		}
	}

	void MeshRenderer::unbindTextures() const
	{
		//unsigned int c = 0;
		//for (textureMap::const_iterator it = _textures.begin(); it != _textures.end(); ++it)
		//{
		//	glActiveTexture(GL_TEXTURE0 + c);
		//	glBindTexture(GL_TEXTURE_2D, 0);
		//	++c;
		//}
		//glActiveTexture(GL_TEXTURE0);
	}

	void			MeshRenderer::setNext(MeshRenderer *next)
	{
		_next = next;
	}

	MeshRenderer	*MeshRenderer::getNext() const
	{
		return (_next);
	}

	void MeshRenderer::addMaterial(SmartPointer<Material> material)
	{
		material->addObject(this);
		_materials.insert(material->getName());
	}

	void MeshRenderer::removeMaterial(SmartPointer<Material> material)
	{
		// be carefull when iterating on it
		material->removeObject(this);
		_materials.erase(material->getName());
	}

	void MeshRenderer::addMaterial(const std::string &material)
	{
		SmartPointer<Material> m = GameEngine::instance()->renderer().getMaterialManager().getMaterial(material);
		if (!m.get())
			return;
		m->addObject(this);
		_materials.insert(m->getName());
	}

	void MeshRenderer::removeMaterial(const std::string &material)
	{
		SmartPointer<Material> m = GameEngine::instance()->renderer().getMaterialManager().getMaterial(material);
		if (!m.get())
			return;
		m->removeObject(this);
		_materials.erase(m->getName());
	}
}<|endoftext|>


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

#include <vector>
#include <unistd.h>

#include "h2olog.h"

using namespace std;

#define VERSION "0.1.0"
#define POLL_TIMEOUT (1000)

static void usage(void)
{
    printf(R"(h2olog (v%s)
Usage: h2olog -p PID
       h2olog quic -p PID
       h2olog quic -t event_type -p PID
       h2olog quic -v -s response_header_name -p PID
Other options:
    -h Shows this help and exit.
    -d Shows debugging information.
)",
           VERSION);
    return;
}

static void show_event_per_sec(h2o_tracer_t *tracer, time_t *t0)
{
    time_t t1 = time(NULL);
    int64_t d = t1 - *t0;
    if (d > 10) {
        uint64_t c = tracer->count / d;
        if (c > 0) {
            struct tm t;
            localtime_r(&t1, &t);
            char s[100];
            const char *iso8601format = "%FT%TZ";
            strftime(s, sizeof(s), iso8601format, &t);

            fprintf(stderr, "%s %20lu events/s\n", s, c);
            tracer->count = 0;
        }
        *t0 = t1;
    }
}

static void show_process(pid_t pid)
{
    char cmdline[256];
    char proc_file[256];
    snprintf(proc_file, sizeof(proc_file), "/proc/%d/cmdline", pid);
    FILE *f = fopen(proc_file, "r");
    if (f == nullptr) {
        fprintf(stderr, "Failed to open %s: %s\n", proc_file, strerror(errno));
        exit(EXIT_FAILURE);
    }
    size_t nread = fread(cmdline, 1, sizeof(cmdline), f);
    fclose(f);
    for (size_t i = 0; i < nread; i++) {
        if (cmdline[i] == '\0') {
            cmdline[i] = ' ';
        }
    }
    fprintf(stderr, "Attaching pid=%d (%s)\n", pid, cmdline);
}

static std::string join_str(const std::string &sep, const std::vector<std::string> &strs)
{
    std::string s;
    for (auto iter = strs.cbegin(); iter != strs.cend(); ++iter) {
        if (iter != strs.cbegin()) {
            s += sep;
        }
        s += *iter;
    }
    return s;
}

static std::string generate_header_filter_cflag(const std::vector<std::string> &tokens)
{
    std::vector<std::string> conditions;

    for (auto &token : tokens) {
        char buf[256];
        snprintf(buf, sizeof(buf), "/* %s */ (slen) == %lu", token.c_str(), token.size());
        std::vector<std::string> exprs = {buf};

        for (size_t i = 0; i < token.size(); ++i) {
            snprintf(buf, sizeof(buf), "(s)[%lu] == '%c'", i, token[i]);
            exprs.push_back(buf);
        }
        conditions.push_back("(" + join_str(" && ", exprs) + ")");
    }

    std::string cflag("-DCHECK_ALLOWED_RES_HEADER_NAME(s,slen)=(");
    cflag += join_str(" || ", conditions);
    cflag += ")";
    return cflag;
}

int main(int argc, char **argv)
{
    h2o_tracer_t tracer = {};
    if (argc > 1 && strcmp(argv[1], "quic") == 0) {
        init_quic_tracer(&tracer);
        --argc;
        ++argv;
    } else {
        init_http_tracer(&tracer);
    }

    bool debug = false;
    const char *out_file = nullptr;
    std::vector<std::string> event_type_filters;
    std::vector<std::string> response_header_filters;
    int c;
    pid_t h2o_pid = -1;
    while ((c = getopt(argc, argv, "hdp:t:s:o:")) != -1) {
        switch (c) {
        case 'p':
            h2o_pid = atoi(optarg);
            break;
        case 't':
            event_type_filters.push_back(optarg);
            break;
        case 's':
            response_header_filters.push_back(optarg);
            break;
        case 'o':
            out_file = optarg;
            break;
        case 'd':
            debug = true;
            break;
        case 'h':
            usage();
            exit(EXIT_SUCCESS);
        default:
            usage();
            exit(EXIT_FAILURE);
        }
    }

    if (argc > optind) {
        fprintf(stderr, "Error: too many aruments\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (h2o_pid == -1) {
        fprintf(stderr, "Error: -p option is missing\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (geteuid() != 0) {
        fprintf(stderr, "Error: root privilege is required\n");
        exit(EXIT_FAILURE);
    }

    if (out_file != nullptr) {
        FILE *out = fopen(out_file, "w");
        if (out == nullptr) {
            fprintf(stderr, "Error: failed to open %s: %s", out_file, strerror(errno));
            exit(EXIT_FAILURE);
        }
        tracer.out = out;
    } else {
        tracer.out = stdout;
    }

    std::vector<std::string> cflags;

    if (!response_header_filters.empty()) {
        cflags.push_back(generate_header_filter_cflag(response_header_filters));
    }

    ebpf::BPF *bpf = new ebpf::BPF();
    std::vector<ebpf::USDT> probes = tracer.init_usdt_probes(h2o_pid);

    ebpf::StatusTuple ret = bpf->init(tracer.bpf_text(), cflags, probes);
    if (ret.code() != 0) {
        fprintf(stderr, "init: %s\n", ret.msg().c_str());
        return EXIT_FAILURE;
    }

    for (auto &probe : probes) {
        ret = bpf->attach_usdt(probe);
        if (ret.code() != 0) {
            fprintf(stderr, "attach_usdt: %s\n", ret.msg().c_str());
            return EXIT_FAILURE;
        }
    }

    ret = bpf->open_perf_buffer("events", tracer.handle_event, nullptr, &tracer, 64);
    if (ret.code() != 0) {
        fprintf(stderr, "open_perf_buffer: %s\n", ret.msg().c_str());
        return EXIT_FAILURE;
    }

    if (debug) {
        show_process(h2o_pid);
    }

    ebpf::BPFPerfBuffer *perf_buffer = bpf->get_perf_buffer("events");
    if (perf_buffer) {
        time_t t0 = time(NULL);

        while (true) {
            perf_buffer->poll(POLL_TIMEOUT);
            fflush(tracer.out);

            if (debug) {
                show_event_per_sec(&tracer, &t0);
            }
        }
    }

    fprintf(stderr, "Error: failed to get_perf_buffer()\n");
    return EXIT_FAILURE;
}
<commit_msg>use "%zu" for size_t value (thanks to @syohex for review)<commit_after>/*
 * Copyright (c) 2019-2020 Fastly, Inc., Toru Maesaka, Goro Fuji
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <vector>
#include <unistd.h>

#include "h2olog.h"

using namespace std;

#define VERSION "0.1.0"
#define POLL_TIMEOUT (1000)

static void usage(void)
{
    printf(R"(h2olog (v%s)
Usage: h2olog -p PID
       h2olog quic -p PID
       h2olog quic -t event_type -p PID
       h2olog quic -v -s response_header_name -p PID
Other options:
    -h Shows this help and exit.
    -d Shows debugging information.
)",
           VERSION);
    return;
}

static void show_event_per_sec(h2o_tracer_t *tracer, time_t *t0)
{
    time_t t1 = time(NULL);
    int64_t d = t1 - *t0;
    if (d > 10) {
        uint64_t c = tracer->count / d;
        if (c > 0) {
            struct tm t;
            localtime_r(&t1, &t);
            char s[100];
            const char *iso8601format = "%FT%TZ";
            strftime(s, sizeof(s), iso8601format, &t);

            fprintf(stderr, "%s %20lu events/s\n", s, c);
            tracer->count = 0;
        }
        *t0 = t1;
    }
}

static void show_process(pid_t pid)
{
    char cmdline[256];
    char proc_file[256];
    snprintf(proc_file, sizeof(proc_file), "/proc/%d/cmdline", pid);
    FILE *f = fopen(proc_file, "r");
    if (f == nullptr) {
        fprintf(stderr, "Failed to open %s: %s\n", proc_file, strerror(errno));
        exit(EXIT_FAILURE);
    }
    size_t nread = fread(cmdline, 1, sizeof(cmdline), f);
    fclose(f);
    for (size_t i = 0; i < nread; i++) {
        if (cmdline[i] == '\0') {
            cmdline[i] = ' ';
        }
    }
    fprintf(stderr, "Attaching pid=%d (%s)\n", pid, cmdline);
}

static std::string join_str(const std::string &sep, const std::vector<std::string> &strs)
{
    std::string s;
    for (auto iter = strs.cbegin(); iter != strs.cend(); ++iter) {
        if (iter != strs.cbegin()) {
            s += sep;
        }
        s += *iter;
    }
    return s;
}

static std::string generate_header_filter_cflag(const std::vector<std::string> &tokens)
{
    std::vector<std::string> conditions;

    for (auto &token : tokens) {
        char buf[256];
        snprintf(buf, sizeof(buf), "/* %s */ (slen) == %zu", token.c_str(), token.size());
        std::vector<std::string> exprs = {buf};

        for (size_t i = 0; i < token.size(); ++i) {
            snprintf(buf, sizeof(buf), "(s)[%zu] == '%c'", i, token[i]);
            exprs.push_back(buf);
        }
        conditions.push_back("(" + join_str(" && ", exprs) + ")");
    }

    std::string cflag("-DCHECK_ALLOWED_RES_HEADER_NAME(s,slen)=(");
    cflag += join_str(" || ", conditions);
    cflag += ")";
    return cflag;
}

int main(int argc, char **argv)
{
    h2o_tracer_t tracer = {};
    if (argc > 1 && strcmp(argv[1], "quic") == 0) {
        init_quic_tracer(&tracer);
        --argc;
        ++argv;
    } else {
        init_http_tracer(&tracer);
    }

    bool debug = false;
    const char *out_file = nullptr;
    std::vector<std::string> event_type_filters;
    std::vector<std::string> response_header_filters;
    int c;
    pid_t h2o_pid = -1;
    while ((c = getopt(argc, argv, "hdp:t:s:o:")) != -1) {
        switch (c) {
        case 'p':
            h2o_pid = atoi(optarg);
            break;
        case 't':
            event_type_filters.push_back(optarg);
            break;
        case 's':
            response_header_filters.push_back(optarg);
            break;
        case 'o':
            out_file = optarg;
            break;
        case 'd':
            debug = true;
            break;
        case 'h':
            usage();
            exit(EXIT_SUCCESS);
        default:
            usage();
            exit(EXIT_FAILURE);
        }
    }

    if (argc > optind) {
        fprintf(stderr, "Error: too many aruments\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (h2o_pid == -1) {
        fprintf(stderr, "Error: -p option is missing\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (geteuid() != 0) {
        fprintf(stderr, "Error: root privilege is required\n");
        exit(EXIT_FAILURE);
    }

    if (out_file != nullptr) {
        FILE *out = fopen(out_file, "w");
        if (out == nullptr) {
            fprintf(stderr, "Error: failed to open %s: %s", out_file, strerror(errno));
            exit(EXIT_FAILURE);
        }
        tracer.out = out;
    } else {
        tracer.out = stdout;
    }

    std::vector<std::string> cflags;

    if (!response_header_filters.empty()) {
        cflags.push_back(generate_header_filter_cflag(response_header_filters));
    }

    ebpf::BPF *bpf = new ebpf::BPF();
    std::vector<ebpf::USDT> probes = tracer.init_usdt_probes(h2o_pid);

    ebpf::StatusTuple ret = bpf->init(tracer.bpf_text(), cflags, probes);
    if (ret.code() != 0) {
        fprintf(stderr, "init: %s\n", ret.msg().c_str());
        return EXIT_FAILURE;
    }

    for (auto &probe : probes) {
        ret = bpf->attach_usdt(probe);
        if (ret.code() != 0) {
            fprintf(stderr, "attach_usdt: %s\n", ret.msg().c_str());
            return EXIT_FAILURE;
        }
    }

    ret = bpf->open_perf_buffer("events", tracer.handle_event, nullptr, &tracer, 64);
    if (ret.code() != 0) {
        fprintf(stderr, "open_perf_buffer: %s\n", ret.msg().c_str());
        return EXIT_FAILURE;
    }

    if (debug) {
        show_process(h2o_pid);
    }

    ebpf::BPFPerfBuffer *perf_buffer = bpf->get_perf_buffer("events");
    if (perf_buffer) {
        time_t t0 = time(NULL);

        while (true) {
            perf_buffer->poll(POLL_TIMEOUT);
            fflush(tracer.out);

            if (debug) {
                show_event_per_sec(&tracer, &t0);
            }
        }
    }

    fprintf(stderr, "Error: failed to get_perf_buffer()\n");
    return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>
#include <gloperate-osg/OsgFboRenderStage.h>

#include <osgViewer/Viewer>
#include <osgViewer/Renderer>

#include <osg/Camera>
#include <osg/Texture2D>

namespace gloperate_osg
{

void OsgFboRenderStage::updateFbo_osg()
{
    // Get OSG camera
    osg::Camera * camera = (viewer() ? viewer()->getCamera() : nullptr);
    if (camera && m_viewportW > 0 && m_viewportH > 0) {
        // (Re)create color texture
        osg::Texture2D * colorTextureOsg = new osg::Texture2D;
        colorTextureOsg->setTextureSize(m_viewportW, m_viewportH);
        colorTextureOsg->setInternalFormat(GL_RGBA);
        colorTextureOsg->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
        colorTextureOsg->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
        colorTextureOsg->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        colorTextureOsg->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        m_colorTextureOsg = colorTextureOsg;

        // (Re)create depth texture
        osg::Texture2D * depthTextureOsg = new osg::Texture2D;
        depthTextureOsg->setTextureSize(m_viewportW, m_viewportH);
        depthTextureOsg->setSourceFormat(GL_DEPTH_COMPONENT);
        depthTextureOsg->setInternalFormat(GL_DEPTH_COMPONENT24);
        depthTextureOsg->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
        depthTextureOsg->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
        depthTextureOsg->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        depthTextureOsg->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        m_depthTextureOsg = depthTextureOsg;

        // Create FBO for camera
        camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
        camera->detach(osg::Camera::COLOR_BUFFER0);
        camera->attach(osg::Camera::COLOR_BUFFER0, m_colorTextureOsg);
        camera->detach(osg::Camera::DEPTH_BUFFER);
        camera->attach(osg::Camera::DEPTH_BUFFER,  m_depthTextureOsg);
        camera->setViewport(0, 0, m_viewportW, m_viewportH);

        // Update projection matrix to preserve the aspect ratio
        camera->setProjectionMatrixAsPerspective(30.0f, camera->getViewport()->aspectRatio(), 1.0f, 10000.0f);

        // Make sure the camera FBO is rebuilt
        osgViewer::Renderer * renderer = (osgViewer::Renderer*)camera->getRenderer();
        renderer->getSceneView(0)->getRenderStage()->setCameraRequiresSetUp(true);
        renderer->getSceneView(0)->getRenderStage()->setFrameBufferObject(nullptr);
    }
}

unsigned int OsgFboRenderStage::getOsgTextureId(const osg::Texture * texture) const
{
    // Check if everything is setup correctly
    if (m_embedded && texture) {
        // Get texture ID
        unsigned int contextID = m_embedded->getState()->getContextID();
        return texture->getTextureObject(contextID)->id();
    } else {
        // Return invalid ID on error
        return 0;
    }
}

} // namespace gloperate_osg
<commit_msg>Fix compilation for glbinding 2.0<commit_after>
#include <gloperate-osg/OsgFboRenderStage.h>

#undef __gl_h_ // dirtiest hack imaginale
// TODO: find a solution for GL/gl.h and glbinding/gl/gl.h

#include <osgViewer/Viewer>
#include <osgViewer/Renderer>

#include <osg/Camera>
#include <osg/Texture2D>

namespace gloperate_osg
{

void OsgFboRenderStage::updateFbo_osg()
{
    // Get OSG camera
    osg::Camera * camera = (viewer() ? viewer()->getCamera() : nullptr);
    if (camera && m_viewportW > 0 && m_viewportH > 0) {
        // (Re)create color texture
        osg::Texture2D * colorTextureOsg = new osg::Texture2D;
        colorTextureOsg->setTextureSize(m_viewportW, m_viewportH);
        colorTextureOsg->setInternalFormat(GL_RGBA);
        colorTextureOsg->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
        colorTextureOsg->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
        colorTextureOsg->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        colorTextureOsg->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        m_colorTextureOsg = colorTextureOsg;

        // (Re)create depth texture
        osg::Texture2D * depthTextureOsg = new osg::Texture2D;
        depthTextureOsg->setTextureSize(m_viewportW, m_viewportH);
        depthTextureOsg->setSourceFormat(GL_DEPTH_COMPONENT);
        depthTextureOsg->setInternalFormat(GL_DEPTH_COMPONENT24);
        depthTextureOsg->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
        depthTextureOsg->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
        depthTextureOsg->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        depthTextureOsg->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        m_depthTextureOsg = depthTextureOsg;

        // Create FBO for camera
        camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
        camera->detach(osg::Camera::COLOR_BUFFER0);
        camera->attach(osg::Camera::COLOR_BUFFER0, m_colorTextureOsg);
        camera->detach(osg::Camera::DEPTH_BUFFER);
        camera->attach(osg::Camera::DEPTH_BUFFER,  m_depthTextureOsg);
        camera->setViewport(0, 0, m_viewportW, m_viewportH);

        // Update projection matrix to preserve the aspect ratio
        camera->setProjectionMatrixAsPerspective(30.0f, camera->getViewport()->aspectRatio(), 1.0f, 10000.0f);

        // Make sure the camera FBO is rebuilt
        osgViewer::Renderer * renderer = (osgViewer::Renderer*)camera->getRenderer();
        renderer->getSceneView(0)->getRenderStage()->setCameraRequiresSetUp(true);
        renderer->getSceneView(0)->getRenderStage()->setFrameBufferObject(nullptr);
    }
}

unsigned int OsgFboRenderStage::getOsgTextureId(const osg::Texture * texture) const
{
    // Check if everything is setup correctly
    if (m_embedded && texture) {
        // Get texture ID
        unsigned int contextID = m_embedded->getState()->getContextID();
        return texture->getTextureObject(contextID)->id();
    } else {
        // Return invalid ID on error
        return 0;
    }
}

} // namespace gloperate_osg
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonPropFindRequest.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-04 14:35:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _NEONTYPES_HXX_
#include "NeonTypes.hxx"
#endif
#ifndef _DAVEXCEPTION_HXX_
#include "DAVException.hxx"
#endif
#ifndef _DAVPROPERTIES_HXX_
#include "DAVProperties.hxx"
#endif
#ifndef _NEONPROPFINDREQUEST_HXX_
#include "NeonPropFindRequest.hxx"
#endif
#ifndef _LINKSEQUENCE_HXX_
#include "LinkSequence.hxx"
#endif
#ifndef _LOCKSEQUENCE_HXX_
#include "LockSequence.hxx"
#endif
#ifndef _LOCKENTRYSEQUENCE_HXX_
#include "LockEntrySequence.hxx"
#endif
#ifndef _UCBDEADPROPERTYVALUE_HXX_
#include "UCBDeadPropertyValue.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;
using namespace std;
using namespace webdav_ucp;

// -------------------------------------------------------------------
extern "C" int NPFR_propfind_iter( void* userdata,
                                   const NeonPropName* pname,
                                   const char* value,
                                   const HttpStatus* status )
{
    /*
        HTTP Response Status Classes:

          - 1: Informational - Request received, continuing process

          - 2: Success - The action was successfully received,
          understood, and accepted

        - 3: Redirection - Further action must be taken in order to
          complete the request

        - 4: Client Error - The request contains bad syntax or cannot
          be fulfilled

        - 5: Server Error - The server failed to fulfill an apparently
          valid request
    */

    if ( status->klass > 2 )
        return 0; // Error getting this property. Go on.

    // Create & set the PropertyValue
    DAVPropertyValue thePropertyValue;
    thePropertyValue.IsCaseSensitive = true;

    DAVProperties::createUCBPropName( pname->nspace,
                                        pname->name,
                                        thePropertyValue.Name );
    bool bHasValue = false;
    if ( DAVProperties::isUCBDeadProperty( *pname ) )
    {
        // DAV dead property added by WebDAV UCP?
        if ( UCBDeadPropertyValue::createFromXML(
                                        value, thePropertyValue.Value ) )
            OSL_ENSURE( thePropertyValue.Value.hasValue(),
                        "NeonPropFindRequest::propfind_iter - No value!" );
            bHasValue = true;
    }

    if ( !bHasValue )
    {
        if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "resourcetype" ) == 0 )
        {
            OString aValue( value );
            aValue = aValue.trim(); // #107358# remove leading/trailing spaces
            if ( aValue.getLength() )
            {
                aValue = aValue.toAsciiLowerCase();
                if ( aValue.compareTo(
                        RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
                {
                    thePropertyValue.Value
                        <<= OUString::createFromAscii( "collection" );
                }
            }

            if ( !thePropertyValue.Value.hasValue() )
            {
                // Take over the value exactly as supplied by the server.
                thePropertyValue.Value <<= OUString::createFromAscii( value );
            }
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "supportedlock" ) == 0 )
        {
            Sequence< LockEntry > aEntries;
            LockEntrySequence::createFromXML( value, aEntries );
            thePropertyValue.Value <<= aEntries;
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "lockdiscovery" ) == 0 )
        {
            Sequence< Lock > aLocks;
            LockSequence::createFromXML( value, aLocks );
            thePropertyValue.Value <<= aLocks;
        }
        else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
        {
            Sequence< Link > aLinks;
            LinkSequence::createFromXML( value, aLinks );
            thePropertyValue.Value <<= aLinks;
        }
        else
        {
            thePropertyValue.Value
                <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
        }
    }

    // Add the newly created PropertyValue
    DAVResource* theResource = static_cast< DAVResource * >( userdata );
    theResource->properties.push_back( thePropertyValue );

    return 0; // Go on.
}

// -------------------------------------------------------------------
extern "C" void NPFR_propfind_results( void* userdata,
                                       const ne_uri* uri,
                                       const NeonPropFindResultSet* set )
{
    DAVResource theResource(
                        OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );

    ne_propset_iterate( set, NPFR_propfind_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResource > * theResources
        = static_cast< vector< DAVResource > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
extern "C" int NPFR_propnames_iter( void* userdata,
                                    const NeonPropName* pname,
                                    const char* /*value*/,
                                    const HttpStatus* /*status*/ )
{
    OUString aFullName;
    DAVProperties::createUCBPropName( pname->nspace,
                                      pname->name,
                                      aFullName );

    DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
    theResource->properties.push_back( aFullName );
    return 0;
}

// -------------------------------------------------------------------
extern "C" void NPFR_propnames_results( void* userdata,
                                        const ne_uri* uri,
                                        const NeonPropFindResultSet* results )
{
    // @@@ href is not the uri! DAVResourceInfo ctor wants uri!

    // Create entry for the resource.
    DAVResourceInfo theResource(
                        OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
    // Fill entry.
    ne_propset_iterate( results, NPFR_propnames_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResourceInfo > * theResources
        = static_cast< vector< DAVResourceInfo > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
                                          const char* inPath,
                                          const Depth inDepth,
                                          const vector< OUString >& inPropNames,
                                          vector< DAVResource >& ioResources,
                                          int & nError )
{
    // Generate the list of properties we're looking for
    int thePropCount = inPropNames.size();
    if ( thePropCount > 0 )
    {
        NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
        int theIndex;

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
        {
            // Split fullname into namespace and name!
            DAVProperties::createNeonPropName(
                             inPropNames[ theIndex ], thePropNames[ theIndex ] );
        }
        thePropNames[ theIndex ].nspace = NULL;
        thePropNames[ theIndex ].name   = NULL;

        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     thePropNames,
                                     NPFR_propfind_results,
                                     &ioResources );

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
            free( (void *)thePropNames[ theIndex ].name );

        delete [] thePropNames;
    }
    else
    {
        // ALLPROP
        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     NULL, // 0 == allprop
                                     NPFR_propfind_results,
                                     &ioResources );
    }

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResources.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Constructor
// - obtains property names
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest(
                            HttpSession* inSession,
                            const char* inPath,
                                const Depth inDepth,
                            std::vector< DAVResourceInfo > & ioResInfo,
                            int & nError )
{
    nError = ne_propnames( inSession,
                           inPath,
                           inDepth,
                           NPFR_propnames_results,
                           &ioResInfo );

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResInfo.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonPropFindRequest::~NeonPropFindRequest( )
{
}
<commit_msg>#i10000# fix by TKR, NEON_VERSION missing<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonPropFindRequest.cxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-07 12:58:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _NEONTYPES_HXX_
#include "NeonTypes.hxx"
#endif
#ifndef _DAVEXCEPTION_HXX_
#include "DAVException.hxx"
#endif
#ifndef _DAVPROPERTIES_HXX_
#include "DAVProperties.hxx"
#endif
#ifndef _NEONPROPFINDREQUEST_HXX_
#include "NeonPropFindRequest.hxx"
#endif
#ifndef _LINKSEQUENCE_HXX_
#include "LinkSequence.hxx"
#endif
#ifndef _LOCKSEQUENCE_HXX_
#include "LockSequence.hxx"
#endif
#ifndef _LOCKENTRYSEQUENCE_HXX_
#include "LockEntrySequence.hxx"
#endif
#ifndef _UCBDEADPROPERTYVALUE_HXX_
#include "UCBDeadPropertyValue.hxx"
#endif

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;
using namespace std;
using namespace webdav_ucp;

// -------------------------------------------------------------------
extern "C" int NPFR_propfind_iter( void* userdata,
                                   const NeonPropName* pname,
                                   const char* value,
                                   const HttpStatus* status )
{
    /*
        HTTP Response Status Classes:

          - 1: Informational - Request received, continuing process

          - 2: Success - The action was successfully received,
          understood, and accepted

        - 3: Redirection - Further action must be taken in order to
          complete the request

        - 4: Client Error - The request contains bad syntax or cannot
          be fulfilled

        - 5: Server Error - The server failed to fulfill an apparently
          valid request
    */

    if ( status->klass > 2 )
        return 0; // Error getting this property. Go on.

    // Create & set the PropertyValue
    DAVPropertyValue thePropertyValue;
    thePropertyValue.IsCaseSensitive = true;

    DAVProperties::createUCBPropName( pname->nspace,
                                        pname->name,
                                        thePropertyValue.Name );
    bool bHasValue = false;
    if ( DAVProperties::isUCBDeadProperty( *pname ) )
    {
        // DAV dead property added by WebDAV UCP?
        if ( UCBDeadPropertyValue::createFromXML(
                                        value, thePropertyValue.Value ) )
            OSL_ENSURE( thePropertyValue.Value.hasValue(),
                        "NeonPropFindRequest::propfind_iter - No value!" );
            bHasValue = true;
    }

    if ( !bHasValue )
    {
        if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "resourcetype" ) == 0 )
        {
            OString aValue( value );
            aValue = aValue.trim(); // #107358# remove leading/trailing spaces
            if ( aValue.getLength() )
            {
                aValue = aValue.toAsciiLowerCase();
                if ( aValue.compareTo(
                        RTL_CONSTASCII_STRINGPARAM( "<collection" ) ) == 0 )
                {
                    thePropertyValue.Value
                        <<= OUString::createFromAscii( "collection" );
                }
            }

            if ( !thePropertyValue.Value.hasValue() )
            {
                // Take over the value exactly as supplied by the server.
                thePropertyValue.Value <<= OUString::createFromAscii( value );
            }
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "supportedlock" ) == 0 )
        {
            Sequence< LockEntry > aEntries;
            LockEntrySequence::createFromXML( value, aEntries );
            thePropertyValue.Value <<= aEntries;
        }
        else if ( rtl_str_compareIgnoreAsciiCase(
                                    pname->name, "lockdiscovery" ) == 0 )
        {
            Sequence< Lock > aLocks;
            LockSequence::createFromXML( value, aLocks );
            thePropertyValue.Value <<= aLocks;
        }
        else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 )
        {
            Sequence< Link > aLinks;
            LinkSequence::createFromXML( value, aLinks );
            thePropertyValue.Value <<= aLinks;
        }
        else
        {
            thePropertyValue.Value
                <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 );
        }
    }

    // Add the newly created PropertyValue
    DAVResource* theResource = static_cast< DAVResource * >( userdata );
    theResource->properties.push_back( thePropertyValue );

    return 0; // Go on.
}

// -------------------------------------------------------------------
extern "C" void NPFR_propfind_results( void* userdata,
#if NEON_VERSION >= 0260
                                       const ne_uri* uri,
#else
                                       const char* href,
#endif
                                       const NeonPropFindResultSet* set )
{
    // @@@ href is not the uri! DAVResource ctor wants uri!

#if NEON_VERSION >= 0260
    DAVResource theResource(
                        OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
#else
    DAVResource theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
#endif

    ne_propset_iterate( set, NPFR_propfind_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResource > * theResources
        = static_cast< vector< DAVResource > * >( userdata );
    theResources->push_back( theResource );
}
// -------------------------------------------------------------------
extern "C" int NPFR_propnames_iter( void* userdata,
                                    const NeonPropName* pname,
                                    const char* /*value*/,
                                    const HttpStatus* /*status*/ )
{
    OUString aFullName;
    DAVProperties::createUCBPropName( pname->nspace,
                                      pname->name,
                                      aFullName );

    DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata );
    theResource->properties.push_back( aFullName );
    return 0;
}

// -------------------------------------------------------------------
extern "C" void NPFR_propnames_results( void* userdata,
#if NEON_VERSION >= 0260
                                        const ne_uri* uri,
#else
                                        const char* href,
#endif
                                        const NeonPropFindResultSet* results )
{
    // @@@ href is not the uri! DAVResourceInfo ctor wants uri!
    // Create entry for the resource.
#if NEON_VERSION >= 0260
    DAVResourceInfo theResource(
                        OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) );
#else
    DAVResourceInfo theResource(
                        OStringToOUString( href, RTL_TEXTENCODING_UTF8 ) );
#endif

    // Fill entry.
    ne_propset_iterate( results, NPFR_propnames_iter, &theResource );

    // Add entry to resources list.
    vector< DAVResourceInfo > * theResources
        = static_cast< vector< DAVResourceInfo > * >( userdata );
    theResources->push_back( theResource );
}

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession,
                                          const char* inPath,
                                          const Depth inDepth,
                                          const vector< OUString >& inPropNames,
                                          vector< DAVResource >& ioResources,
                                          int & nError )
{
    // Generate the list of properties we're looking for
    int thePropCount = inPropNames.size();
    if ( thePropCount > 0 )
    {
        NeonPropName* thePropNames = new NeonPropName[ thePropCount + 1 ];
        int theIndex;

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
        {
            // Split fullname into namespace and name!
            DAVProperties::createNeonPropName(
                             inPropNames[ theIndex ], thePropNames[ theIndex ] );
        }
        thePropNames[ theIndex ].nspace = NULL;
        thePropNames[ theIndex ].name   = NULL;

        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     thePropNames,
                                     NPFR_propfind_results,
                                     &ioResources );

        for ( theIndex = 0; theIndex < thePropCount; theIndex ++ )
            free( (void *)thePropNames[ theIndex ].name );

        delete [] thePropNames;
    }
    else
    {
        // ALLPROP
        nError = ne_simple_propfind( inSession,
                                     inPath,
                                     inDepth,
                                     NULL, // 0 == allprop
                                     NPFR_propfind_results,
                                     &ioResources );
    }

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResources.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Constructor
// - obtains property names
// -------------------------------------------------------------------

NeonPropFindRequest::NeonPropFindRequest(
                            HttpSession* inSession,
                            const char* inPath,
                                const Depth inDepth,
                            std::vector< DAVResourceInfo > & ioResInfo,
                            int & nError )
{
    nError = ne_propnames( inSession,
                           inPath,
                           inDepth,
                           NPFR_propnames_results,
                           &ioResInfo );

    // #87585# - Sometimes neon lies (because some servers lie).
    if ( ( nError == NE_OK ) && ioResInfo.empty() )
        nError = NE_ERROR;
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonPropFindRequest::~NeonPropFindRequest( )
{
}
<|endoftext|>


<commit_before>// CSV or DSV format (comma- or more generally delimiter-separated values)
// Licence: Lesser GNU Public License 2.1 (LGPL)
// $Id: $

#define BUILDING_XYLIB
#include "csv.h"
#include "util.h"
#include <limits>
#include <boost/tokenizer.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

using namespace std;
using namespace xylib::util;

namespace xylib {

typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;

const FormatInfo CsvDataSet::fmt_info(
    "csv",
    "comma-separated values",
    "csv tsv tab",
    false,                       // whether binary
    false,                       // whether has multi-blocks
    &CsvDataSet::ctor,
    &CsvDataSet::check
);

static
double read_field(const char* field)
{
    char* endptr;
    double d = strtod(field, &endptr);
    if (endptr != field && *endptr == '\0')
        return d;
    else
        return numeric_limits<double>::quiet_NaN();
}

static
int count_numbers(const string& line, char sep, int *number_count)
{
    int field_count = 0;
    *number_count = 0;
    Tokenizer t(line, boost::escaped_list_separator<char>('\\', sep, '"'));
    for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i) {
        double d = read_field(i->c_str());
        ++field_count;
        if (!boost::math::isnan(d))
            ++(*number_count);
    }
    return field_count;
}

static
void read_numbers_from_line(const string& line, char sep, vector<double> *out)
{
    Tokenizer t(line, boost::escaped_list_separator<char>('\\', sep, '"'));
    for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i)
        out->push_back(read_field(i->c_str()));
}

static
bool is_space(const char* str)
{
    while (*str) {
        if (!isspace(*str))
            return false;
        ++str;
    }
    return true;
}

static
char read_4lines(istream &f, bool decimal_comma,
                         vector<vector<double> > *out,
                         vector<string> *column_names)
{
    char buffer[1600]; // more than enough for one line
    string lines[4];
    buffer[1600-1]=0;
    for (int all_lines = 0, nonempty_lines=0;
            nonempty_lines < 4; ++all_lines) {
        // it can be a large file without new lines, limit line length
        f.getline(buffer, 1600);
        if (!f || buffer[1600-1] != 0)
            throw FormatError("reading line " + S(all_lines) + " failed.");
        if (!is_space(buffer)) {
            if (decimal_comma)
                for (char* p = buffer; *p != '\0'; ++p)
                    if (*p == ',')
                        *p = '.';
            lines[nonempty_lines] = buffer;
            ++nonempty_lines;
        }
    }
    // The first line can be header. Second line should not be a header,
    // but just in case, let's check lines 3 and 4.
    int max_number_count = 0;
    int max_field_count = 0;
    char sep = 0;
    const char* separators = "\t,;|:/ ";
    for (const char* isep = separators; *isep != '\0'; ++isep) {
        int num2;
        int fields1 = count_numbers(lines[2], *isep, &num2);
        int num3;
        int fields2 = count_numbers(lines[3], *isep, &num3);
        if (fields1 == 0 || fields2 != fields1)
            continue;
        int num = min(num2, num3);
        if (num > max_number_count || (num == max_number_count &&
                                       fields1 > max_field_count)) {
            max_number_count = num;
            max_field_count = fields1;
            sep = *isep;
        }
    }
    int num0;
    int fields0 = count_numbers(lines[0], sep, &num0);
    if (fields0 != max_field_count)
        throw FormatError("different field count (`" + S(sep) +
                          "'-separated) in lines 1 and 3.");
    bool has_header = (num0 < max_number_count);
    if (has_header && column_names) {
        Tokenizer t(lines[0],
                    boost::escaped_list_separator<char>('\\', sep, '"'));
        for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i)
            column_names->push_back(*i);
    }
    if (out != NULL) {
        if (!has_header) {
            out->resize(out->size() + 1);
            read_numbers_from_line(lines[0], sep, &out->back());
        }
        for (int i = 1; i != 4; ++i) {
            out->resize(out->size() + 1);
            read_numbers_from_line(lines[i], sep, &out->back());
        }
    }
    return sep;
}

bool CsvDataSet::check(istream &f)
{
    try {
        return read_4lines(f, false, NULL, NULL) != 0;
    }
    catch (FormatError &) {
        return false;
    }
}

void CsvDataSet::load_data(istream &f)
{
    bool decimal_comma = has_option("decimal_comma");

    vector<vector<double> > data;
    vector<string> column_names;
    string line;
    line.reserve(100);

    char sep = read_4lines(f, decimal_comma, &data, &column_names);
    size_t n_col = data[0].size();
    while (getline(f, line)) {
        if (is_space(line.c_str()))
            continue;
        if (decimal_comma)
            for (string::iterator p = line.begin(); p != line.end(); ++p)
                if (*p == ',')
                    *p = '.';
        data.resize(data.size() + 1);
        data.back().reserve(n_col);
        read_numbers_from_line(line, sep, &data.back());
    }

    Block* blk = new Block;
    for (size_t i = 0; i != n_col; ++i) {
        VecColumn *col = new VecColumn;
        if (column_names.size() > i)
            col->set_name(column_names[i]);
        col->reserve(data.size());
        for (size_t j = 0; j != data.size(); ++j)
            col->add_val(data[j].size() > i ? data[j][i]
                                      : numeric_limits<double>::quiet_NaN());
        blk->add_column(col);
    }
    add_block(blk);
}

} // namespace xylib

<commit_msg>workaround for compiling with Boost < 1.35<commit_after>// CSV or DSV format (comma- or more generally delimiter-separated values)
// Licence: Lesser GNU Public License 2.1 (LGPL)
// $Id: $

#define BUILDING_XYLIB
#include "csv.h"
#include "util.h"
#include <limits>
#include <boost/tokenizer.hpp>

#include <boost/version.hpp>
#if BOOST_VERSION >= 103500
#include <boost/math/special_functions/fpclassify.hpp>
#else
namespace boost { namespace math { bool isnan(double f) { return f != f; } }}
#endif

using namespace std;
using namespace xylib::util;

namespace xylib {

typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;

const FormatInfo CsvDataSet::fmt_info(
    "csv",
    "comma-separated values",
    "csv tsv tab",
    false,                       // whether binary
    false,                       // whether has multi-blocks
    &CsvDataSet::ctor,
    &CsvDataSet::check
);

static
double read_field(const char* field)
{
    char* endptr;
    double d = strtod(field, &endptr);
    if (endptr != field && *endptr == '\0')
        return d;
    else
        return numeric_limits<double>::quiet_NaN();
}

static
int count_numbers(const string& line, char sep, int *number_count)
{
    int field_count = 0;
    *number_count = 0;
    Tokenizer t(line, boost::escaped_list_separator<char>('\\', sep, '"'));
    for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i) {
        double d = read_field(i->c_str());
        ++field_count;
        if (!boost::math::isnan(d))
            ++(*number_count);
    }
    return field_count;
}

static
void read_numbers_from_line(const string& line, char sep, vector<double> *out)
{
    Tokenizer t(line, boost::escaped_list_separator<char>('\\', sep, '"'));
    for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i)
        out->push_back(read_field(i->c_str()));
}

static
bool is_space(const char* str)
{
    while (*str) {
        if (!isspace(*str))
            return false;
        ++str;
    }
    return true;
}

static
char read_4lines(istream &f, bool decimal_comma,
                         vector<vector<double> > *out,
                         vector<string> *column_names)
{
    char buffer[1600]; // more than enough for one line
    string lines[4];
    buffer[1600-1]=0;
    for (int all_lines = 0, nonempty_lines=0;
            nonempty_lines < 4; ++all_lines) {
        // it can be a large file without new lines, limit line length
        f.getline(buffer, 1600);
        if (!f || buffer[1600-1] != 0)
            throw FormatError("reading line " + S(all_lines) + " failed.");
        if (!is_space(buffer)) {
            if (decimal_comma)
                for (char* p = buffer; *p != '\0'; ++p)
                    if (*p == ',')
                        *p = '.';
            lines[nonempty_lines] = buffer;
            ++nonempty_lines;
        }
    }
    // The first line can be header. Second line should not be a header,
    // but just in case, let's check lines 3 and 4.
    int max_number_count = 0;
    int max_field_count = 0;
    char sep = 0;
    const char* separators = "\t,;|:/ ";
    for (const char* isep = separators; *isep != '\0'; ++isep) {
        int num2;
        int fields1 = count_numbers(lines[2], *isep, &num2);
        int num3;
        int fields2 = count_numbers(lines[3], *isep, &num3);
        if (fields1 == 0 || fields2 != fields1)
            continue;
        int num = min(num2, num3);
        if (num > max_number_count || (num == max_number_count &&
                                       fields1 > max_field_count)) {
            max_number_count = num;
            max_field_count = fields1;
            sep = *isep;
        }
    }
    int num0;
    int fields0 = count_numbers(lines[0], sep, &num0);
    if (fields0 != max_field_count)
        throw FormatError("different field count (`" + S(sep) +
                          "'-separated) in lines 1 and 3.");
    bool has_header = (num0 < max_number_count);
    if (has_header && column_names) {
        Tokenizer t(lines[0],
                    boost::escaped_list_separator<char>('\\', sep, '"'));
        for (Tokenizer::iterator i = t.begin(); i != t.end(); ++i)
            column_names->push_back(*i);
    }
    if (out != NULL) {
        if (!has_header) {
            out->resize(out->size() + 1);
            read_numbers_from_line(lines[0], sep, &out->back());
        }
        for (int i = 1; i != 4; ++i) {
            out->resize(out->size() + 1);
            read_numbers_from_line(lines[i], sep, &out->back());
        }
    }
    return sep;
}

bool CsvDataSet::check(istream &f)
{
    try {
        return read_4lines(f, false, NULL, NULL) != 0;
    }
    catch (FormatError &) {
        return false;
    }
}

void CsvDataSet::load_data(istream &f)
{
    bool decimal_comma = has_option("decimal_comma");

    vector<vector<double> > data;
    vector<string> column_names;
    string line;
    line.reserve(100);

    char sep = read_4lines(f, decimal_comma, &data, &column_names);
    size_t n_col = data[0].size();
    while (getline(f, line)) {
        if (is_space(line.c_str()))
            continue;
        if (decimal_comma)
            for (string::iterator p = line.begin(); p != line.end(); ++p)
                if (*p == ',')
                    *p = '.';
        data.resize(data.size() + 1);
        data.back().reserve(n_col);
        read_numbers_from_line(line, sep, &data.back());
    }

    Block* blk = new Block;
    for (size_t i = 0; i != n_col; ++i) {
        VecColumn *col = new VecColumn;
        if (column_names.size() > i)
            col->set_name(column_names[i]);
        col->reserve(data.size());
        for (size_t j = 0; j != data.size(); ++j)
            col->add_val(data[j].size() > i ? data[j][i]
                                      : numeric_limits<double>::quiet_NaN());
        blk->add_column(col);
    }
    add_block(blk);
}

} // namespace xylib

<|endoftext|>