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

  Program:   Visualization Toolkit
  Module:    vtkMetaImageWriter.cxx

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

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

=========================================================================*/
#include "vtkMetaImageWriter.h"

#include "vtkObjectFactory.h"
#include "vtkImageData.h"
#include "vtkXMLImageDataWriter.h"

#include <vtkstd/string>

#include <sys/stat.h>

//----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkMetaImageWriter, "1.3");
vtkStandardNewMacro(vtkMetaImageWriter);

//----------------------------------------------------------------------------
vtkMetaImageWriter::vtkMetaImageWriter()
{
  this->MHDFileName = 0;
}

//----------------------------------------------------------------------------
vtkMetaImageWriter::~vtkMetaImageWriter()
{
  this->SetFileName(0);
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::SetFileName(const char* fname)
{
  this->SetMHDFileName(fname);
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::SetRAWFileName(const char* fname)
{
  this->Superclass::SetFileName(fname);
}

//----------------------------------------------------------------------------
char* vtkMetaImageWriter::GetRAWFileName()
{
  return this->Superclass::GetFileName();
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::Write()
{
  vtkImageData* id = this->GetInput();
  if ( !id )
    {
    vtkErrorMacro("Input not specified");
    return;
    }
  if ( !this->MHDFileName )
    {
    vtkErrorMacro("Output file name not specified");
    return;
    }
  if ( !this->GetRAWFileName() )
    {
    vtkDebugMacro("Raw file name not specified. Specifying one...");
    // Allocate new file name and leave space for extension
    char* rfname = new char [ strlen(this->MHDFileName) + 10 ];
    strcpy(rfname, this->MHDFileName);
    size_t cc;
    for ( cc = strlen(rfname)-1; cc > 0; cc -- )
      {
      if ( rfname[cc] == '.' )
        {
        rfname[cc] = 0;
        break;
        }
      if ( rfname[cc] == '/' || rfname[cc] == '\\' )
        {
        break;
        }
      }
    strcat(rfname, ".raw");
    if ( strcmp(rfname, this->MHDFileName) == 0 )
      {
      strcat(rfname, ".raw");
      }
    this->SetRAWFileName(rfname);
    delete [] rfname;
    }

  ofstream ofs(this->MHDFileName, ios::out);
  if ( !ofs )
    {
    vtkErrorMacro("Cannot open file: " << this->MHDFileName << " for writing");
    return;
    }

  int ndims = 3;
  int ext[6];
  id->GetWholeExtent(ext);
  if ( ext[4] == ext[5] )
    {
    ndims = 2;
    if ( ext[2] == ext[3] )
      {
      ndims = 1;
      }
    }
  double origin[3];
  double spacing[3];
  id->GetOrigin(origin);
  id->GetSpacing(spacing);

  const char* scalar_type = 0;
  switch ( id->GetScalarType() )
    {
  case VTK_CHAR:           scalar_type = "MET_CHAR"; break;
  case VTK_UNSIGNED_CHAR:  scalar_type = "MET_UCHAR"; break;
  case VTK_SHORT:          scalar_type = "MET_SHORT"; break;
  case VTK_UNSIGNED_SHORT: scalar_type = "MET_USHORT"; break;
  case VTK_INT:            scalar_type = "MET_INT"; break;
  case VTK_UNSIGNED_INT:   scalar_type = "MET_UINT"; break;
  case VTK_LONG:           scalar_type = "MET_LONG"; break;
  case VTK_UNSIGNED_LONG:  scalar_type = "MET_ULONG"; break;
  case VTK_FLOAT:          scalar_type = "MET_FLOAT"; break;
  case VTK_DOUBLE:         scalar_type = "MET_DOUBLE"; break;
  default:
    vtkErrorMacro("Unknown scalar type: " << id->GetScalarTypeAsString());
    return;
    }

  origin[0] += ext[0];
  origin[1] += ext[2];
  origin[2] += ext[4];

  const char* data_file = this->GetRAWFileName();
  int pos = 0;
  int cc;
  for ( cc = 0; data_file[cc]; cc ++ )
    {
    if ( data_file[cc] == '/' || data_file[cc] == '\\' )
      {
      pos = cc;
      }
    }
  if ( pos > 0 )
    {
    if ( strncmp(data_file, this->GetFileName(), pos) == 0 )
      {
      data_file = this->GetRAWFileName() + pos + 1;
      }
    }

  ofs
    << "ObjectType = Image" << endl
    << "NDims = " << ndims << endl
    << "BinaryData = True" << endl
#ifdef VTK_WORDS_BIGENDIAN
    << "BinaryDataByteOrderMSB = True" << endl
#else
    << "BinaryDataByteOrderMSB = False" << endl
#endif
    << "ElementSpacing = " << spacing[0] << " " << spacing[1] << " " << spacing[2] << endl
    << "DimSize = " << (ext[1]-ext[0]+1) << " " << (ext[3]-ext[2]+1) << " " << (ext[5]-ext[4]+1) << endl
    << "Position = " << origin[0] << " " << origin[1] << " " << origin[2] << endl
    << "ElementNumberOfChannels = " << id->GetNumberOfScalarComponents() << endl
    << "ElementType = " << scalar_type << (id->GetNumberOfScalarComponents() > 1?"_ARRAY":"") << endl
    << "ElementDataFile = " << data_file << endl;
  this->SetFileDimensionality(ndims);
  this->Superclass::Write();
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "MHDFileName: " << (this->MHDFileName?this->MHDFileName:"(none)") << endl;
}
<commit_msg>ERR: Fix warnings by renaming the variable<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMetaImageWriter.cxx

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

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

=========================================================================*/
#include "vtkMetaImageWriter.h"

#include "vtkObjectFactory.h"
#include "vtkImageData.h"
#include "vtkXMLImageDataWriter.h"

#include <vtkstd/string>

#include <sys/stat.h>

//----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkMetaImageWriter, "1.4");
vtkStandardNewMacro(vtkMetaImageWriter);

//----------------------------------------------------------------------------
vtkMetaImageWriter::vtkMetaImageWriter()
{
  this->MHDFileName = 0;
}

//----------------------------------------------------------------------------
vtkMetaImageWriter::~vtkMetaImageWriter()
{
  this->SetFileName(0);
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::SetFileName(const char* fname)
{
  this->SetMHDFileName(fname);
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::SetRAWFileName(const char* fname)
{
  this->Superclass::SetFileName(fname);
}

//----------------------------------------------------------------------------
char* vtkMetaImageWriter::GetRAWFileName()
{
  return this->Superclass::GetFileName();
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::Write()
{
  vtkImageData* id = this->GetInput();
  if ( !id )
    {
    vtkErrorMacro("Input not specified");
    return;
    }
  if ( !this->MHDFileName )
    {
    vtkErrorMacro("Output file name not specified");
    return;
    }
  if ( !this->GetRAWFileName() )
    {
    vtkDebugMacro("Raw file name not specified. Specifying one...");
    // Allocate new file name and leave space for extension
    char* rfname = new char [ strlen(this->MHDFileName) + 10 ];
    strcpy(rfname, this->MHDFileName);
    size_t cc;
    for ( cc = strlen(rfname)-1; cc > 0; cc -- )
      {
      if ( rfname[cc] == '.' )
        {
        rfname[cc] = 0;
        break;
        }
      if ( rfname[cc] == '/' || rfname[cc] == '\\' )
        {
        break;
        }
      }
    strcat(rfname, ".raw");
    if ( strcmp(rfname, this->MHDFileName) == 0 )
      {
      strcat(rfname, ".raw");
      }
    this->SetRAWFileName(rfname);
    delete [] rfname;
    }

  ofstream ofs_with_warning_C4701(this->MHDFileName, ios::out);
  if ( !ofs_with_warning_C4701 )
    {
    vtkErrorMacro("Cannot open file: " << this->MHDFileName << " for writing");
    return;
    }

  int ndims = 3;
  int ext[6];
  id->GetWholeExtent(ext);
  if ( ext[4] == ext[5] )
    {
    ndims = 2;
    if ( ext[2] == ext[3] )
      {
      ndims = 1;
      }
    }
  double origin[3];
  double spacing[3];
  id->GetOrigin(origin);
  id->GetSpacing(spacing);

  const char* scalar_type = 0;
  switch ( id->GetScalarType() )
    {
  case VTK_CHAR:           scalar_type = "MET_CHAR"; break;
  case VTK_UNSIGNED_CHAR:  scalar_type = "MET_UCHAR"; break;
  case VTK_SHORT:          scalar_type = "MET_SHORT"; break;
  case VTK_UNSIGNED_SHORT: scalar_type = "MET_USHORT"; break;
  case VTK_INT:            scalar_type = "MET_INT"; break;
  case VTK_UNSIGNED_INT:   scalar_type = "MET_UINT"; break;
  case VTK_LONG:           scalar_type = "MET_LONG"; break;
  case VTK_UNSIGNED_LONG:  scalar_type = "MET_ULONG"; break;
  case VTK_FLOAT:          scalar_type = "MET_FLOAT"; break;
  case VTK_DOUBLE:         scalar_type = "MET_DOUBLE"; break;
  default:
    vtkErrorMacro("Unknown scalar type: " << id->GetScalarTypeAsString());
    return;
    }

  origin[0] += ext[0];
  origin[1] += ext[2];
  origin[2] += ext[4];

  const char* data_file = this->GetRAWFileName();
  int pos = 0;
  int cc;
  for ( cc = 0; data_file[cc]; cc ++ )
    {
    if ( data_file[cc] == '/' || data_file[cc] == '\\' )
      {
      pos = cc;
      }
    }
  if ( pos > 0 )
    {
    if ( strncmp(data_file, this->GetFileName(), pos) == 0 )
      {
      data_file = this->GetRAWFileName() + pos + 1;
      }
    }

  ofs_with_warning_C4701
    << "ObjectType = Image" << endl
    << "NDims = " << ndims << endl
    << "BinaryData = True" << endl
#ifdef VTK_WORDS_BIGENDIAN
    << "BinaryDataByteOrderMSB = True" << endl
#else
    << "BinaryDataByteOrderMSB = False" << endl
#endif
    << "ElementSpacing = " << spacing[0] << " " << spacing[1] << " " << spacing[2] << endl
    << "DimSize = " << (ext[1]-ext[0]+1) << " " << (ext[3]-ext[2]+1) << " " << (ext[5]-ext[4]+1) << endl
    << "Position = " << origin[0] << " " << origin[1] << " " << origin[2] << endl
    << "ElementNumberOfChannels = " << id->GetNumberOfScalarComponents() << endl
    << "ElementType = " << scalar_type << (id->GetNumberOfScalarComponents() > 1?"_ARRAY":"") << endl
    << "ElementDataFile = " << data_file << endl;
  this->SetFileDimensionality(ndims);
  this->Superclass::Write();
}

//----------------------------------------------------------------------------
void vtkMetaImageWriter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "MHDFileName: " << (this->MHDFileName?this->MHDFileName:"(none)") << endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/window_snapshot/window_snapshot.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/size.h"
#include "ui/gfx/test/gfx_test_utils.h"

#if defined(USE_WEBKIT_COMPOSITOR)
#include "ui/gfx/compositor/compositor_setup.h"
#elif defined(VIEWS_COMPOSITOR)
#include "ui/gfx/compositor/compositor.h"
#endif

namespace {

// Command line flag for overriding the default location for putting generated
// test images that do not match references.
const char kGeneratedDir[] = "generated-dir";
// Command line flag for overriding the default location for reference images.
const char kReferenceDir[] = "reference-dir";

// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
// should have been encoded using |gfx::PNGCodec::Encode|.
bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) {
  DCHECK(bitmap);
  std::string png_data;
  return file_util::ReadFileToString(file_path, &png_data) &&
         gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
                               png_data.length(),
                               bitmap);
}

// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
// parent directory does not have to exist.
bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
  std::vector<unsigned char> png_data;
  if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) &&
      file_util::CreateDirectory(file_path.DirName())) {
    int bytes_written = file_util::WriteFile(
        file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size());
    if (bytes_written == static_cast<int>(png_data.size()))
      return true;
  }
  return false;
}

// Resizes the browser window so that the tab's contents are at a given size.
void ResizeTabContainer(Browser* browser, const gfx::Size& desired_size) {
  gfx::Rect container_rect;
  browser->GetSelectedWebContents()->GetContainerBounds(&container_rect);
  // Size cannot be negative, so use a point.
  gfx::Point correction(desired_size.width() - container_rect.size().width(),
                        desired_size.height() - container_rect.size().height());

  gfx::Rect window_rect = browser->window()->GetRestoredBounds();
  gfx::Size new_size = window_rect.size();
  new_size.Enlarge(correction.x(), correction.y());
  window_rect.set_size(new_size);
  browser->window()->SetBounds(window_rect);
}

}  // namespace

// Test fixture for GPU image comparison tests.
// TODO(kkania): Document how to add to/modify these tests.
class GpuPixelBrowserTest : public InProcessBrowserTest {
 public:
  GpuPixelBrowserTest() : ref_img_revision_no_older_than_(0) {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    InProcessBrowserTest::SetUpCommandLine(command_line);

    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
  }

  virtual void SetUpInProcessBrowserTestFixture() {
    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();

    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
    test_data_dir_ = test_data_dir_.AppendASCII("gpu");

    CommandLine* command_line = CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(kGeneratedDir))
      generated_img_dir_ = command_line->GetSwitchValuePath(kGeneratedDir);
    else
      generated_img_dir_ = test_data_dir_.AppendASCII("generated");
    if (command_line->HasSwitch(kReferenceDir))
      ref_img_dir_ = command_line->GetSwitchValuePath(kReferenceDir);
    else
      ref_img_dir_ = test_data_dir_.AppendASCII("gpu_reference");

    test_name_ = testing::UnitTest::GetInstance()->current_test_info()->name();
    const char* test_status_prefixes[] = {"DISABLED_", "FLAKY_", "FAILS_"};
    for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) {
      ReplaceFirstSubstringAfterOffset(
          &test_name_, 0, test_status_prefixes[i], "");
    }

#if defined(USE_WEBKIT_COMPOSITOR)
    ui::DisableTestCompositor();
#elif defined(VIEWS_COMPOSITOR)
    ui::Compositor::set_compositor_factory_for_testing(NULL);
#endif
  }

  // Compares the generated bitmap with the appropriate reference image on disk.
  // Returns true iff the images were the same.
  //
  // If no valid reference image exists, save the generated bitmap to the disk.
  // The image format is:
  //     <test_name>_<revision>.png
  // E.g.,
  //     WebGLTeapot_19762.png
  // The number is the chromium revision that generated the image.
  //
  // On failure or on ref image generation, the image and diff image will be
  // written to disk. The formats are:
  //     FAIL_<ref_image_name>, DIFF_<ref_image_name>
  // E.g.,
  //     FAIL_WebGLTeapot_19762.png, DIFF_WebGLTeapot_19762.png
  bool CompareImages(const SkBitmap& gen_bmp) {
    SkBitmap ref_bmp_on_disk;
    const SkBitmap* ref_bmp;
    bool save_gen = false;
    bool save_diff = false;
    bool rt = true;
    if (ref_img_path_.empty() ||
        !ReadPNGFile(ref_img_path_, &ref_bmp_on_disk)) {
      chrome::VersionInfo chrome_version_info;
      FilePath img_revision_path = ref_img_dir_.AppendASCII(
          test_name_ + "_" + chrome_version_info.LastChange() + ".png");
      if (!WritePNGFile(gen_bmp, img_revision_path)) {
        LOG(ERROR) << "Can't save generated image to: "
                   << img_revision_path.value()
                   << " as future reference.";
        rt = false;
      }
      if (!ref_img_path_.empty()) {
        LOG(ERROR) << "Can't read the local ref image: "
                   << ref_img_path_.value()
                   << ", reset it.";
        file_util::Delete(ref_img_path_, false);
        rt = false;
      }
      ref_img_path_ = img_revision_path;
      // If we re-generate the ref image, we save the gen and diff images so
      // the ref image can be uploaded to the server and be viewed later.
      save_gen = true;
      save_diff = true;
      ref_bmp = &gen_bmp;
    } else {
      ref_bmp = &ref_bmp_on_disk;
    }

    SkBitmap diff_bmp;
    if (ref_bmp->width() != gen_bmp.width() ||
        ref_bmp->height() != gen_bmp.height()) {
      LOG(ERROR)
          << "Dimensions do not match (Expected) vs (Actual):"
          << "(" << ref_bmp->width() << "x" << ref_bmp->height()
              << ") vs. "
          << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")";
      save_gen = true;
      rt = false;
    } else {
      // Compare pixels and create a simple diff image.
      int diff_pixels_count = 0;
      diff_bmp.setConfig(SkBitmap::kARGB_8888_Config,
                         gen_bmp.width(), gen_bmp.height());
      diff_bmp.allocPixels();
      diff_bmp.eraseColor(SK_ColorWHITE);
      SkAutoLockPixels lock_bmp(gen_bmp);
      SkAutoLockPixels lock_ref_bmp(*ref_bmp);
      SkAutoLockPixels lock_diff_bmp(diff_bmp);
      // The reference images were saved with no alpha channel. Use the mask to
      // set alpha to 0.
      uint32_t kAlphaMask = 0x00FFFFFF;
      for (int x = 0; x < gen_bmp.width(); ++x) {
        for (int y = 0; y < gen_bmp.height(); ++y) {
          if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
              (*ref_bmp->getAddr32(x, y) & kAlphaMask)) {
            ++diff_pixels_count;
            *diff_bmp.getAddr32(x, y) = 192 << 16;  // red
          }
        }
      }
      if (diff_pixels_count > 0) {
        LOG(ERROR) << diff_pixels_count
                   << " pixels do not match.";
        save_gen = true;
        save_diff = true;
        rt = false;
      }
    }

    std::string ref_img_filename = ref_img_path_.BaseName().MaybeAsASCII();
    if (save_gen) {
      FilePath img_fail_path = generated_img_dir_.AppendASCII(
          "FAIL_" + ref_img_filename);
      if (!WritePNGFile(gen_bmp, img_fail_path)) {
        LOG(ERROR) << "Can't save generated image to: "
                   << img_fail_path.value();
      }
    }
    if (save_diff) {
      FilePath img_diff_path = generated_img_dir_.AppendASCII(
          "DIFF_" + ref_img_filename);
      if (!WritePNGFile(diff_bmp, img_diff_path)) {
        LOG(ERROR) << "Can't save generated diff image to: "
                   << img_diff_path.value();
      }
    }
    return rt;
  }

  // This has to be called by every pixel test. If no specific revision is
  // required, just call it with 0.
  void SetRefImageRevisionNoOlderThan(int64 revision) {
    ref_img_revision_no_older_than_ = revision;
    ObtainLocalRefImageFilePath();
  }

 protected:
  FilePath test_data_dir_;

 private:
  FilePath generated_img_dir_;
  FilePath ref_img_dir_;
  FilePath ref_img_path_;
  // The name of the test, with any special prefixes dropped.
  std::string test_name_;

  // Any local ref image generated from older revision is ignored.
  int64 ref_img_revision_no_older_than_;

  // If no valid local ref image is located, the ref_img_path_ remains
  // empty.
  void ObtainLocalRefImageFilePath() {
    FilePath filter;
    filter = filter.AppendASCII(test_name_ + "_*.png");
    file_util::FileEnumerator locator(ref_img_dir_,
                                      false,  // non recursive
                                      file_util::FileEnumerator::FILES,
                                      filter.value());
    int64 max_revision = 0;
    std::vector<FilePath> outdated_ref_imgs;
    for (FilePath full_path = locator.Next();
         !full_path.empty();
         full_path = locator.Next()) {
      std::string filename =
          full_path.BaseName().RemoveExtension().MaybeAsASCII();
      std::string revision_string =
          filename.substr(test_name_.length() + 1);
      int64 revision = 0;
      bool converted = base::StringToInt64(revision_string, &revision);
      if (!converted)
        continue;
      if (revision < ref_img_revision_no_older_than_ ||
          revision < max_revision) {
        outdated_ref_imgs.push_back(full_path);
        continue;
      }
      ref_img_path_ = full_path;
      max_revision = revision;
    }
    for (size_t i = 0; i < outdated_ref_imgs.size(); ++i)
      file_util::Delete(outdated_ref_imgs[i], false);
  }

  DISALLOW_COPY_AND_ASSIGN(GpuPixelBrowserTest);
};

// Enable initially only on Windows and progressively enable on more
// platforms.
// Bug tracking test failure on Windows/Mac: http://crbug.com/95214
// Bug tracking test failure on Linux: http://crbug.com/95214
#if defined(OS_WIN)
#define MAYBE_WebGLTeapot WebGLTeapot
#else
#define MAYBE_WebGLTeapot DISABLED_WebGLTeapot
#endif

IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MAYBE_WebGLTeapot) {
  // If test baseline needs to be updated after a given revision, update the
  // revision number in SetRefImageNoOlderThan(#revision).
  SetRefImageRevisionNoOlderThan(0);

  gfx::Size container_size(500, 500);
  ResizeTabContainer(browser(), container_size);

  ui_test_utils::DOMMessageQueue message_queue;
  ui_test_utils::NavigateToURL(
      browser(),
      net::FilePathToFileURL(test_data_dir_.AppendASCII("webgl_teapot").
          AppendASCII("teapot.html")));

  // Wait for message from teapot page indicating the GL calls have been issued.
  ASSERT_TRUE(message_queue.WaitForMessage(NULL));

  std::vector<unsigned char> screenshot_png;

  gfx::Rect root_bounds = browser()->window()->GetBounds();
  gfx::Rect tab_contents_bounds;
  browser()->GetSelectedWebContents()->GetContainerBounds(&tab_contents_bounds);

  gfx::Rect snapshot_bounds(tab_contents_bounds.x() - root_bounds.x(),
                            tab_contents_bounds.y() - root_bounds.y(),
                            tab_contents_bounds.width(),
                            tab_contents_bounds.height());

  gfx::NativeWindow native_window = browser()->window()->GetNativeHandle();
  bool success = browser::GrabWindowSnapshot(native_window, &screenshot_png,
                                             snapshot_bounds);
  ASSERT_TRUE(success);

  SkBitmap bitmap;
  success = gfx::PNGCodec::Decode(
      reinterpret_cast<unsigned char*>(&*screenshot_png.begin()),
      screenshot_png.size(),
      &bitmap);

  ASSERT_TRUE(success);
  ASSERT_TRUE(CompareImages(bitmap));
}
<commit_msg>Regenerate local reference images for gpu pixel tests after r116356.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/window_snapshot/window_snapshot.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/size.h"
#include "ui/gfx/test/gfx_test_utils.h"

#if defined(USE_WEBKIT_COMPOSITOR)
#include "ui/gfx/compositor/compositor_setup.h"
#elif defined(VIEWS_COMPOSITOR)
#include "ui/gfx/compositor/compositor.h"
#endif

namespace {

// Command line flag for overriding the default location for putting generated
// test images that do not match references.
const char kGeneratedDir[] = "generated-dir";
// Command line flag for overriding the default location for reference images.
const char kReferenceDir[] = "reference-dir";

// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
// should have been encoded using |gfx::PNGCodec::Encode|.
bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) {
  DCHECK(bitmap);
  std::string png_data;
  return file_util::ReadFileToString(file_path, &png_data) &&
         gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
                               png_data.length(),
                               bitmap);
}

// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
// parent directory does not have to exist.
bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
  std::vector<unsigned char> png_data;
  if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) &&
      file_util::CreateDirectory(file_path.DirName())) {
    int bytes_written = file_util::WriteFile(
        file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size());
    if (bytes_written == static_cast<int>(png_data.size()))
      return true;
  }
  return false;
}

// Resizes the browser window so that the tab's contents are at a given size.
void ResizeTabContainer(Browser* browser, const gfx::Size& desired_size) {
  gfx::Rect container_rect;
  browser->GetSelectedWebContents()->GetContainerBounds(&container_rect);
  // Size cannot be negative, so use a point.
  gfx::Point correction(desired_size.width() - container_rect.size().width(),
                        desired_size.height() - container_rect.size().height());

  gfx::Rect window_rect = browser->window()->GetRestoredBounds();
  gfx::Size new_size = window_rect.size();
  new_size.Enlarge(correction.x(), correction.y());
  window_rect.set_size(new_size);
  browser->window()->SetBounds(window_rect);
}

}  // namespace

// Test fixture for GPU image comparison tests.
// TODO(kkania): Document how to add to/modify these tests.
class GpuPixelBrowserTest : public InProcessBrowserTest {
 public:
  GpuPixelBrowserTest() : ref_img_revision_no_older_than_(0) {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    InProcessBrowserTest::SetUpCommandLine(command_line);

    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
  }

  virtual void SetUpInProcessBrowserTestFixture() {
    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();

    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
    test_data_dir_ = test_data_dir_.AppendASCII("gpu");

    CommandLine* command_line = CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(kGeneratedDir))
      generated_img_dir_ = command_line->GetSwitchValuePath(kGeneratedDir);
    else
      generated_img_dir_ = test_data_dir_.AppendASCII("generated");
    if (command_line->HasSwitch(kReferenceDir))
      ref_img_dir_ = command_line->GetSwitchValuePath(kReferenceDir);
    else
      ref_img_dir_ = test_data_dir_.AppendASCII("gpu_reference");

    test_name_ = testing::UnitTest::GetInstance()->current_test_info()->name();
    const char* test_status_prefixes[] = {"DISABLED_", "FLAKY_", "FAILS_"};
    for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) {
      ReplaceFirstSubstringAfterOffset(
          &test_name_, 0, test_status_prefixes[i], "");
    }

#if defined(USE_WEBKIT_COMPOSITOR)
    ui::DisableTestCompositor();
#elif defined(VIEWS_COMPOSITOR)
    ui::Compositor::set_compositor_factory_for_testing(NULL);
#endif
  }

  // Compares the generated bitmap with the appropriate reference image on disk.
  // Returns true iff the images were the same.
  //
  // If no valid reference image exists, save the generated bitmap to the disk.
  // The image format is:
  //     <test_name>_<revision>.png
  // E.g.,
  //     WebGLTeapot_19762.png
  // The number is the chromium revision that generated the image.
  //
  // On failure or on ref image generation, the image and diff image will be
  // written to disk. The formats are:
  //     FAIL_<ref_image_name>, DIFF_<ref_image_name>
  // E.g.,
  //     FAIL_WebGLTeapot_19762.png, DIFF_WebGLTeapot_19762.png
  bool CompareImages(const SkBitmap& gen_bmp) {
    SkBitmap ref_bmp_on_disk;
    const SkBitmap* ref_bmp;
    bool save_gen = false;
    bool save_diff = false;
    bool rt = true;
    if (ref_img_path_.empty() ||
        !ReadPNGFile(ref_img_path_, &ref_bmp_on_disk)) {
      chrome::VersionInfo chrome_version_info;
      FilePath img_revision_path = ref_img_dir_.AppendASCII(
          test_name_ + "_" + chrome_version_info.LastChange() + ".png");
      if (!WritePNGFile(gen_bmp, img_revision_path)) {
        LOG(ERROR) << "Can't save generated image to: "
                   << img_revision_path.value()
                   << " as future reference.";
        rt = false;
      }
      if (!ref_img_path_.empty()) {
        LOG(ERROR) << "Can't read the local ref image: "
                   << ref_img_path_.value()
                   << ", reset it.";
        file_util::Delete(ref_img_path_, false);
        rt = false;
      }
      ref_img_path_ = img_revision_path;
      // If we re-generate the ref image, we save the gen and diff images so
      // the ref image can be uploaded to the server and be viewed later.
      save_gen = true;
      save_diff = true;
      ref_bmp = &gen_bmp;
    } else {
      ref_bmp = &ref_bmp_on_disk;
    }

    SkBitmap diff_bmp;
    if (ref_bmp->width() != gen_bmp.width() ||
        ref_bmp->height() != gen_bmp.height()) {
      LOG(ERROR)
          << "Dimensions do not match (Expected) vs (Actual):"
          << "(" << ref_bmp->width() << "x" << ref_bmp->height()
              << ") vs. "
          << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")";
      save_gen = true;
      rt = false;
    } else {
      // Compare pixels and create a simple diff image.
      int diff_pixels_count = 0;
      diff_bmp.setConfig(SkBitmap::kARGB_8888_Config,
                         gen_bmp.width(), gen_bmp.height());
      diff_bmp.allocPixels();
      diff_bmp.eraseColor(SK_ColorWHITE);
      SkAutoLockPixels lock_bmp(gen_bmp);
      SkAutoLockPixels lock_ref_bmp(*ref_bmp);
      SkAutoLockPixels lock_diff_bmp(diff_bmp);
      // The reference images were saved with no alpha channel. Use the mask to
      // set alpha to 0.
      uint32_t kAlphaMask = 0x00FFFFFF;
      for (int x = 0; x < gen_bmp.width(); ++x) {
        for (int y = 0; y < gen_bmp.height(); ++y) {
          if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
              (*ref_bmp->getAddr32(x, y) & kAlphaMask)) {
            ++diff_pixels_count;
            *diff_bmp.getAddr32(x, y) = 192 << 16;  // red
          }
        }
      }
      if (diff_pixels_count > 0) {
        LOG(ERROR) << diff_pixels_count
                   << " pixels do not match.";
        save_gen = true;
        save_diff = true;
        rt = false;
      }
    }

    std::string ref_img_filename = ref_img_path_.BaseName().MaybeAsASCII();
    if (save_gen) {
      FilePath img_fail_path = generated_img_dir_.AppendASCII(
          "FAIL_" + ref_img_filename);
      if (!WritePNGFile(gen_bmp, img_fail_path)) {
        LOG(ERROR) << "Can't save generated image to: "
                   << img_fail_path.value();
      }
    }
    if (save_diff) {
      FilePath img_diff_path = generated_img_dir_.AppendASCII(
          "DIFF_" + ref_img_filename);
      if (!WritePNGFile(diff_bmp, img_diff_path)) {
        LOG(ERROR) << "Can't save generated diff image to: "
                   << img_diff_path.value();
      }
    }
    return rt;
  }

  // This has to be called by every pixel test. If no specific revision is
  // required, just call it with 0.
  void SetRefImageRevisionNoOlderThan(int64 revision) {
    ref_img_revision_no_older_than_ = revision;
    ObtainLocalRefImageFilePath();
  }

 protected:
  FilePath test_data_dir_;

 private:
  FilePath generated_img_dir_;
  FilePath ref_img_dir_;
  FilePath ref_img_path_;
  // The name of the test, with any special prefixes dropped.
  std::string test_name_;

  // Any local ref image generated from older revision is ignored.
  int64 ref_img_revision_no_older_than_;

  // If no valid local ref image is located, the ref_img_path_ remains
  // empty.
  void ObtainLocalRefImageFilePath() {
    FilePath filter;
    filter = filter.AppendASCII(test_name_ + "_*.png");
    file_util::FileEnumerator locator(ref_img_dir_,
                                      false,  // non recursive
                                      file_util::FileEnumerator::FILES,
                                      filter.value());
    int64 max_revision = 0;
    std::vector<FilePath> outdated_ref_imgs;
    for (FilePath full_path = locator.Next();
         !full_path.empty();
         full_path = locator.Next()) {
      std::string filename =
          full_path.BaseName().RemoveExtension().MaybeAsASCII();
      std::string revision_string =
          filename.substr(test_name_.length() + 1);
      int64 revision = 0;
      bool converted = base::StringToInt64(revision_string, &revision);
      if (!converted)
        continue;
      if (revision < ref_img_revision_no_older_than_ ||
          revision < max_revision) {
        outdated_ref_imgs.push_back(full_path);
        continue;
      }
      ref_img_path_ = full_path;
      max_revision = revision;
    }
    for (size_t i = 0; i < outdated_ref_imgs.size(); ++i)
      file_util::Delete(outdated_ref_imgs[i], false);
  }

  DISALLOW_COPY_AND_ASSIGN(GpuPixelBrowserTest);
};

// Enable initially only on Windows and progressively enable on more
// platforms.
// Bug tracking test failure on Windows/Mac: http://crbug.com/95214
// Bug tracking test failure on Linux: http://crbug.com/95214
#if defined(OS_WIN)
#define MAYBE_WebGLTeapot WebGLTeapot
#else
#define MAYBE_WebGLTeapot DISABLED_WebGLTeapot
#endif

IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MAYBE_WebGLTeapot) {
  // If test baseline needs to be updated after a given revision, update the
  // revision number in SetRefImageNoOlderThan(#revision).
  SetRefImageRevisionNoOlderThan(116356);

  gfx::Size container_size(500, 500);
  ResizeTabContainer(browser(), container_size);

  ui_test_utils::DOMMessageQueue message_queue;
  ui_test_utils::NavigateToURL(
      browser(),
      net::FilePathToFileURL(test_data_dir_.AppendASCII("webgl_teapot").
          AppendASCII("teapot.html")));

  // Wait for message from teapot page indicating the GL calls have been issued.
  ASSERT_TRUE(message_queue.WaitForMessage(NULL));

  std::vector<unsigned char> screenshot_png;

  gfx::Rect root_bounds = browser()->window()->GetBounds();
  gfx::Rect tab_contents_bounds;
  browser()->GetSelectedWebContents()->GetContainerBounds(&tab_contents_bounds);

  gfx::Rect snapshot_bounds(tab_contents_bounds.x() - root_bounds.x(),
                            tab_contents_bounds.y() - root_bounds.y(),
                            tab_contents_bounds.width(),
                            tab_contents_bounds.height());

  gfx::NativeWindow native_window = browser()->window()->GetNativeHandle();
  bool success = browser::GrabWindowSnapshot(native_window, &screenshot_png,
                                             snapshot_bounds);
  ASSERT_TRUE(success);

  SkBitmap bitmap;
  success = gfx::PNGCodec::Decode(
      reinterpret_cast<unsigned char*>(&*screenshot_png.begin()),
      screenshot_png.size(),
      &bitmap);

  ASSERT_TRUE(success);
  ASSERT_TRUE(CompareImages(bitmap));
}
<|endoftext|>


<commit_before>#include "qtpropertycommon.h"

QString formatDoubleToString(const double value, const bool allowScientific, const uint precision)
{
	QString number = QString::number(value, allowScientific ? 'g' : 'f', precision);
	const bool isFractional = (abs(value - floor(value)) > 0);

	if (isFractional)
	{
		while (number.at(number.length() - 1) == QChar('0'))
			number.remove(number.length() - 1, 1);

        if (number.at(number.length() - 1) == QChar('.'))
            number.remove(number.length() - 1, 1);
	}
	else
	{
		number = QString::number(value, allowScientific ? 'g' : 'f', allowScientific ? precision : 0);
	}

    return number;
}<commit_msg>- double formatting fixed - rounding changed to the nearest number<commit_after>#include "qtpropertycommon.h"

QString formatDoubleToString(const double value, const bool allowScientific, const uint precision)
{
  QString number = QString::number(value, allowScientific ? 'g' : 'f', precision);
  double rounded = static_cast<int>(value + 0.5);
  const bool isFractional = (abs(value - rounded) > 0);

  if (isFractional)
  {
    while (number.at(number.length() - 1) == QChar('0'))
      number.remove(number.length() - 1, 1);

    if (number.at(number.length() - 1) == QChar('.'))
      number.remove(number.length() - 1, 1);

    if (number.toDouble() == 0.0)
      number = QString("0");
  }
  else
  {
    number = QString::number(value, allowScientific ? 'g' : 'f', allowScientific ? precision : 0);
  }

  return number;
}<|endoftext|>


<commit_before>/*
 * cvlan.cpp
 *
 *  Created on: 07.08.2014
 *      Author: andreas
 */

#include "cvlan.hpp"

using namespace roflibs::ethernet;

void
cvlan::handle_dpt_open(
		rofl::crofdpt& dpt)
{
	try {
		state = STATE_ATTACHED;
		group_id = dpt.get_next_idle_group_id();

		// set flooding group entry itself
		update_group_entry_buckets(rofl::openflow::OFPGC_ADD);

		// set redirecting entry for this vlan's flooding group entry
		rofl::openflow::cofflowmod fm(dpt.get_version());
		fm.set_command(rofl::openflow::OFPFC_ADD);
		fm.set_table_id(table_id_eth_dst);
		fm.set_buffer_id(rofl::openflow::OFP_NO_BUFFER);
		fm.set_idle_timeout(0);
		fm.set_hard_timeout(0);
		fm.set_priority(0x8000);
		fm.set_match().set_vlan_vid(vid | rofl::openflow::OFPVID_PRESENT);
		fm.set_instructions().set_inst_apply_actions().
				set_actions().add_action_group(rofl::cindex(0)).set_group_id(group_id);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// set broadcast entry in src stage
		fm.set_table_id(table_id_eth_src);
		fm.set_priority(0x8100);
		fm.set_match().set_eth_dst(rofl::caddress_ll("ff:ff:ff:ff:ff:ff"), rofl::caddress_ll("01:00:00:00:00:00"));
		fm.set_instructions().set_inst_goto_table().set_table_id(table_id_eth_local);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// send notification to all ethernet endpoints
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

		// send notification to all member ports
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

		// send notification to all fib entries
		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_open] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_open] control channel not connected" << std::endl;
	}
}

void
cvlan::handle_dpt_close(
		rofl::crofdpt& dpt)
{
	try {
		// send notification to all fib entries
		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// send notification to all member ports
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// send notification to all ethernet endpoints
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// remove redirecting entry for this vlan's flooding group entry
		rofl::openflow::cofflowmod fm(dpt.get_version());
		fm.set_command(rofl::openflow::OFPFC_DELETE_STRICT);
		fm.set_table_id(table_id_eth_dst);
		fm.set_buffer_id(rofl::openflow::OFP_NO_BUFFER);
		fm.set_idle_timeout(0);
		fm.set_hard_timeout(0);
		fm.set_priority(0x8000);
		fm.set_match().set_vlan_vid(vid | rofl::openflow::OFPVID_PRESENT);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// remove broadcast entry in src stage
		fm.set_table_id(table_id_eth_src);
		fm.set_priority(0x8100);
		fm.set_match().set_eth_dst(rofl::caddress_ll("ff:ff:ff:ff:ff:ff"), rofl::caddress_ll("01:00:00:00:00:00"));
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// remove flooding group entry itself
		rofl::openflow::cofgroupmod gm(dpt.get_version());
		gm.set_command(rofl::openflow::OFPGC_DELETE);
		gm.set_group_id(group_id);
		gm.set_type(rofl::openflow::OFPGT_ALL);

	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_close] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_close] control channel not connected" << std::endl;
	} catch(...) {

	}

	state = STATE_DETACHED;
	dpt.release_group_id(group_id); group_id = 0;
}

void
cvlan::handle_packet_in(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_packet_in& msg)
{
	try {
		assert(dpid == dpt.get_dpid());
		assert(vid == (msg.get_match().get_vlan_vid_value() & (uint16_t)(~rofl::openflow::OFPVID_PRESENT)));

		uint32_t in_port = msg.get_match().get_in_port();
		const rofl::caddress_ll& lladdr = msg.get_match().get_eth_src_addr();
		if (lladdr.is_multicast() || lladdr.is_null()) {
			rofcore::logging::debug << "[cvlan][handle_packet_in] invalid source lladdr found" << std::endl << msg;
			dpt.drop_buffer(auxid, msg.get_buffer_id());
			return;
		}

		set_fib_entry(lladdr, in_port).handle_packet_in(dpt, auxid, msg);

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_packet_in] match(es) not found" << std::endl << msg;
		dpt.drop_buffer(auxid, msg.get_buffer_id());
	} catch (eFibEntryPortNotMember& e) {
		rofcore::logging::debug << "[cvlan][handle_packet_in] packet-in on invalid port" << std::endl << msg;
		dpt.drop_buffer(auxid, msg.get_buffer_id());
	}
}

void
cvlan::handle_flow_removed(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_flow_removed& msg)
{
	try {
		assert(dpid == dpt.get_dpid());
		assert(vid == (msg.get_match().get_vlan_vid_value() & (uint16_t)(~rofl::openflow::OFPVID_PRESENT)));

		// TODO: check port here?

		rofl::caddress_ll lladdr;

		if (msg.get_table_id() == 1) {
			lladdr = msg.get_match().get_eth_src_addr();
		} else
		if (msg.get_table_id() == 2) {
			lladdr = msg.get_match().get_eth_dst_addr();
		} else {
			return;
		}

		if (lladdr.is_multicast() || lladdr.is_null()) {
			rofcore::logging::debug << "[cvlan][handle_flow_removed] invalid source lladdr found" << std::endl << msg;
			return;
		}

		if (has_fib_entry(lladdr)) {
			set_fib_entry(lladdr).handle_flow_removed(dpt, auxid, msg); // notify fib entry
		}

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_flow_removed] match(es) not found" << std::endl << msg;
	}
}

void
cvlan::handle_port_status(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_port_status& msg)
{
	try {
		uint32_t portno = msg.get_port().get_port_no();

		if (not has_phy_port(portno)) {
			return;
		}

		set_phy_port(portno).handle_port_status(dpt, auxid, msg);

		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_port_status(dpt, auxid, msg);
		}

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_port_status] port not found" << std::endl << msg;
	}
}

void
cvlan::handle_error_message(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_error& msg)
{
	// TODO
}

void
cvlan::update_group_entry_buckets(uint16_t command)
{
	try {
		if (STATE_ATTACHED != state) {
			return;
		}

		// update flooding group entry
		rofl::openflow::cofgroupmod gm(rofl::crofdpt::get_dpt(dpid).get_version());
		gm.set_command(command);
		gm.set_group_id(group_id);
		gm.set_type(rofl::openflow::OFPGT_ALL);
		unsigned int bucket_id = 0;
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			rofl::cindex index(0);
			if (not it->second.get_tagged()) {
				gm.set_buckets().add_bucket(bucket_id).set_actions().
						add_action_pop_vlan(index++);
			}
			gm.set_buckets().set_bucket(bucket_id).set_actions().
						add_action_output(index++).set_port_no(it->second.get_port_no());
			bucket_id++;
		}

#if 0
		// NO!!!

		// this sends Packet-Ins for each single ethernet endpoint
		// TODO: rethink this strategy???
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			rofl::cindex index(0);
			if (not it->second.get_tagged()) {
				gm.set_buckets().add_bucket(bucket_id).set_actions().
						add_action_pop_vlan(index++);
			}
			gm.set_buckets().set_bucket(bucket_id).set_actions().
						add_action_output(index++).set_port_no(rofl::openflow::OFPP_CONTROLLER);
			bucket_id++;
		}
#endif

		rofl::crofdpt::get_dpt(dpid).send_group_mod_message(rofl::cauxid(0), gm);

	} catch (rofl::eRofBaseCongested& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel congested" << std::endl;
	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel not connected" << std::endl;
	} catch (rofl::eRofDptNotFound& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] dpt not found" << std::endl;
	}
}

<commit_msg>clean-up<commit_after>/*
 * cvlan.cpp
 *
 *  Created on: 07.08.2014
 *      Author: andreas
 */

#include "cvlan.hpp"

using namespace roflibs::ethernet;

void
cvlan::handle_dpt_open(
		rofl::crofdpt& dpt)
{
	try {
		state = STATE_ATTACHED;
		group_id = dpt.get_next_idle_group_id();

		// set flooding group entry itself
		update_group_entry_buckets(rofl::openflow::OFPGC_ADD);

		// set redirecting entry for this vlan's flooding group entry
		rofl::openflow::cofflowmod fm(dpt.get_version());
		fm.set_command(rofl::openflow::OFPFC_ADD);
		fm.set_table_id(table_id_eth_dst);
		fm.set_buffer_id(rofl::openflow::OFP_NO_BUFFER);
		fm.set_idle_timeout(0);
		fm.set_hard_timeout(0);
		fm.set_priority(0x8000);
		fm.set_match().set_vlan_vid(vid | rofl::openflow::OFPVID_PRESENT);
		fm.set_instructions().set_inst_apply_actions().
				set_actions().add_action_group(rofl::cindex(0)).set_group_id(group_id);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// set broadcast entry in src stage
		fm.set_table_id(table_id_eth_src);
		fm.set_priority(0x8100);
		fm.set_match().set_eth_dst(rofl::caddress_ll("01:00:00:00:00:00"), rofl::caddress_ll("01:00:00:00:00:00"));
		fm.set_instructions().set_inst_goto_table().set_table_id(table_id_eth_local);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// send notification to all ethernet endpoints
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

		// send notification to all member ports
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

		// send notification to all fib entries
		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_dpt_open(dpt);
		}

	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_open] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_open] control channel not connected" << std::endl;
	}
}

void
cvlan::handle_dpt_close(
		rofl::crofdpt& dpt)
{
	try {
		// send notification to all fib entries
		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// send notification to all member ports
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// send notification to all ethernet endpoints
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			it->second.handle_dpt_close(dpt);
		}

		// remove redirecting entry for this vlan's flooding group entry
		rofl::openflow::cofflowmod fm(dpt.get_version());
		fm.set_command(rofl::openflow::OFPFC_DELETE_STRICT);
		fm.set_table_id(table_id_eth_dst);
		fm.set_buffer_id(rofl::openflow::OFP_NO_BUFFER);
		fm.set_idle_timeout(0);
		fm.set_hard_timeout(0);
		fm.set_priority(0x8000);
		fm.set_match().set_vlan_vid(vid | rofl::openflow::OFPVID_PRESENT);
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// remove broadcast entry in src stage
		fm.set_table_id(table_id_eth_src);
		fm.set_priority(0x8100);
		fm.set_match().set_eth_dst(rofl::caddress_ll("01:00:00:00:00:00"), rofl::caddress_ll("01:00:00:00:00:00"));
		dpt.send_flow_mod_message(rofl::cauxid(0), fm);

		// remove flooding group entry itself
		rofl::openflow::cofgroupmod gm(dpt.get_version());
		gm.set_command(rofl::openflow::OFPGC_DELETE);
		gm.set_group_id(group_id);
		gm.set_type(rofl::openflow::OFPGT_ALL);

	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_close] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][handle_dpt_close] control channel not connected" << std::endl;
	} catch(...) {

	}

	state = STATE_DETACHED;
	dpt.release_group_id(group_id); group_id = 0;
}

void
cvlan::handle_packet_in(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_packet_in& msg)
{
	try {
		assert(dpid == dpt.get_dpid());
		assert(vid == (msg.get_match().get_vlan_vid_value() & (uint16_t)(~rofl::openflow::OFPVID_PRESENT)));

		uint32_t in_port = msg.get_match().get_in_port();
		const rofl::caddress_ll& lladdr = msg.get_match().get_eth_src_addr();
		if (lladdr.is_multicast() || lladdr.is_null()) {
			rofcore::logging::debug << "[cvlan][handle_packet_in] invalid source lladdr found" << std::endl << msg;
			dpt.drop_buffer(auxid, msg.get_buffer_id());
			return;
		}

		set_fib_entry(lladdr, in_port).handle_packet_in(dpt, auxid, msg);

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_packet_in] match(es) not found" << std::endl << msg;
		dpt.drop_buffer(auxid, msg.get_buffer_id());
	} catch (eFibEntryPortNotMember& e) {
		rofcore::logging::debug << "[cvlan][handle_packet_in] packet-in on invalid port" << std::endl << msg;
		dpt.drop_buffer(auxid, msg.get_buffer_id());
	}
}

void
cvlan::handle_flow_removed(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_flow_removed& msg)
{
	try {
		assert(dpid == dpt.get_dpid());
		assert(vid == (msg.get_match().get_vlan_vid_value() & (uint16_t)(~rofl::openflow::OFPVID_PRESENT)));

		// TODO: check port here?

		rofl::caddress_ll lladdr;

		if (msg.get_table_id() == 1) {
			lladdr = msg.get_match().get_eth_src_addr();
		} else
		if (msg.get_table_id() == 2) {
			lladdr = msg.get_match().get_eth_dst_addr();
		} else {
			return;
		}

		if (lladdr.is_multicast() || lladdr.is_null()) {
			rofcore::logging::debug << "[cvlan][handle_flow_removed] invalid source lladdr found" << std::endl << msg;
			return;
		}

		if (has_fib_entry(lladdr)) {
			set_fib_entry(lladdr).handle_flow_removed(dpt, auxid, msg); // notify fib entry
		}

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_flow_removed] match(es) not found" << std::endl << msg;
	}
}

void
cvlan::handle_port_status(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_port_status& msg)
{
	try {
		uint32_t portno = msg.get_port().get_port_no();

		if (not has_phy_port(portno)) {
			return;
		}

		set_phy_port(portno).handle_port_status(dpt, auxid, msg);

		for (std::map<rofl::caddress_ll, cfibentry>::iterator
				it = fib.begin(); it != fib.end(); ++it) {
			it->second.handle_port_status(dpt, auxid, msg);
		}

	} catch (rofl::openflow::eOxmNotFound& e) {
		rofcore::logging::debug << "[cvlan][handle_port_status] port not found" << std::endl << msg;
	}
}

void
cvlan::handle_error_message(
		rofl::crofdpt& dpt, const rofl::cauxid& auxid, rofl::openflow::cofmsg_error& msg)
{
	// TODO
}

void
cvlan::update_group_entry_buckets(uint16_t command)
{
	try {
		if (STATE_ATTACHED != state) {
			return;
		}

		// update flooding group entry
		rofl::openflow::cofgroupmod gm(rofl::crofdpt::get_dpt(dpid).get_version());
		gm.set_command(command);
		gm.set_group_id(group_id);
		gm.set_type(rofl::openflow::OFPGT_ALL);
		unsigned int bucket_id = 0;
		for (std::map<uint32_t, cmemberport>::iterator
				it = phyports.begin(); it != phyports.end(); ++it) {
			rofl::cindex index(0);
			if (not it->second.get_tagged()) {
				gm.set_buckets().add_bucket(bucket_id).set_actions().
						add_action_pop_vlan(index++);
			}
			gm.set_buckets().set_bucket(bucket_id).set_actions().
						add_action_output(index++).set_port_no(it->second.get_port_no());
			bucket_id++;
		}

#if 0
		// NO!!!

		// this sends Packet-Ins for each single ethernet endpoint
		// TODO: rethink this strategy???
		for (std::map<rofl::caddress_ll, cethendpnt>::iterator
				it = ethendpnts.begin(); it != ethendpnts.end(); ++it) {
			rofl::cindex index(0);
			if (not it->second.get_tagged()) {
				gm.set_buckets().add_bucket(bucket_id).set_actions().
						add_action_pop_vlan(index++);
			}
			gm.set_buckets().set_bucket(bucket_id).set_actions().
						add_action_output(index++).set_port_no(rofl::openflow::OFPP_CONTROLLER);
			bucket_id++;
		}
#endif

		rofl::crofdpt::get_dpt(dpid).send_group_mod_message(rofl::cauxid(0), gm);

	} catch (rofl::eRofBaseCongested& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel congested" << std::endl;
	} catch (rofl::eRofSockTxAgain& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel congested" << std::endl;
	} catch (rofl::eRofBaseNotConnected& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] control channel not connected" << std::endl;
	} catch (rofl::eRofDptNotFound& e) {
		rofcore::logging::debug << "[cvlan][update_group_entry_buckets] dpt not found" << std::endl;
	}
}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkNetCDFCAMReader.cxx

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

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

=========================================================================*/
#include "vtkNetCDFCAMReader.h"

#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkFieldData.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnstructuredGrid.h"

#include <map>
#include <vtk_netcdfcpp.h>

vtkStandardNewMacro(vtkNetCDFCAMReader);

//============================================================================
#define CALL_NETCDF(call) \
{ \
  int errorcode = call; \
  if (errorcode != NC_NOERR) \
  { \
    vtkErrorMacro(<< "netCDF Error: " << nc_strerror(errorcode)); \
    return 0; \
  } \
}

//----------------------------------------------------------------------------
vtkNetCDFCAMReader::vtkNetCDFCAMReader()
{
  this->FileName = NULL;
  this->ConnectivityFileName = NULL;
  this->PointsFile = NULL;
  this->ConnectivityFile = NULL;
  this->SetNumberOfInputPorts(0);
  this->SetNumberOfOutputPorts(1);
}

//----------------------------------------------------------------------------
vtkNetCDFCAMReader::~vtkNetCDFCAMReader()
{
  this->SetFileName(NULL);
  this->SetConnectivityFileName(NULL);
  if(this->PointsFile)
    {
    delete this->PointsFile;
    this->PointsFile = NULL;
    }
  if(this->ConnectivityFile)
    {
    delete this->ConnectivityFile;
    this->ConnectivityFile = NULL;
    }
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::CanReadFile(const char* fileName)
{
  NcFile file(fileName, NcFile::ReadOnly);
  return file.is_valid();
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::SetFileName(const char* fileName)
{
  vtkDebugMacro(<<" setting FileName to " << (fileName?fileName:"(null)") );
  if ( this->FileName == NULL && fileName == NULL)
    {
    return;
    }
  if ( this->FileName && fileName && (!strcmp(this->FileName,fileName)))
    {
    return;
    }
  if(this->PointsFile)
    {
    delete this->PointsFile;
    this->PointsFile = NULL;
    }
  if (this->FileName)
    {
    delete [] this->FileName;
    }
  if (fileName)
    {
    size_t n = strlen(fileName) + 1;
    char *cp1 =  new char[n];
    const char *cp2 = (fileName);
    this->FileName = cp1;
    do
      {
      *cp1++ = *cp2++;
      }
    while ( --n );
    }
   else
    {
    this->FileName = NULL;
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::SetConnectivityFileName(const char* fileName)
{
  vtkDebugMacro(<<" setting ConnectivityFileName to "
                << (fileName?fileName:"(null)") );
  if ( this->ConnectivityFileName == NULL && fileName == NULL)
    {
    return;
    }
  if ( this->ConnectivityFileName && fileName &&
       (!strcmp(this->ConnectivityFileName,fileName)))
    {
    return;
    }
  if(this->ConnectivityFile)
    {
    delete this->ConnectivityFile;
    this->ConnectivityFile = NULL;
    }
  if (this->ConnectivityFileName)
    {
    delete [] this->ConnectivityFileName;
    }
  if (fileName)
    {
    size_t n = strlen(fileName) + 1;
    char *cp1 =  new char[n];
    const char *cp2 = (fileName);
    this->ConnectivityFileName = cp1;
    do
      {
      *cp1++ = *cp2++;
      }
    while ( --n );
    }
   else
    {
    this->ConnectivityFileName = NULL;
    }
  this->Modified();
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::RequestUpdateExtent(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  if(this->FileName == NULL || this->ConnectivityFileName == NULL)
    {
    vtkWarningMacro("Missing a file name.");
    return 0;
    }
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  int piece =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  int numPieces =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());

  // make sure piece is valid
  if (piece < 0 || piece >= numPieces)
    {
    return 1;
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  if(this->FileName == NULL || this->ConnectivityFileName == NULL)
    {
    vtkWarningMacro("Missing a file name.");
    return 0;
    }

  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // All of the data in the first piece.
  if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  vtkDebugMacro(<<"Reading NetCDF CAM file.");

  if(this->PointsFile == NULL)
    {
    this->PointsFile = new NcFile(this->FileName, NcFile::ReadOnly);
    if(this->PointsFile->is_valid() == 0)
      {
      vtkErrorMacro(<< "Can't read file " << this->FileName);
      delete this->PointsFile;
      this->PointsFile = NULL;
      return 0;
      }
    }
  if(this->ConnectivityFile == NULL)
    {
    this->ConnectivityFile = new NcFile(this->ConnectivityFileName,
                                        NcFile::ReadOnly);
    if(this->ConnectivityFile->is_valid() == 0)
      {
      vtkErrorMacro(<< "Can't read file " << this->ConnectivityFileName);
      delete this->ConnectivityFile;
      this->ConnectivityFile = NULL;
      return 0;
      }
    }

  // read in the points first
  NcDim* dimension = this->PointsFile->get_dim("ncol");
  NcVar* lon = this->PointsFile->get_var("lon");
  NcVar* lat = this->PointsFile->get_var("lat");
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  long numPoints = dimension->size();
  if(lat == NULL || lon == NULL)
    {
    vtkErrorMacro("Cannot find coordinates.");
    return 0;
    }
  if(lat->type() == ncDouble)
    {
    points->SetDataTypeToDouble();
    points->SetNumberOfPoints(numPoints);
    std::vector<double> array(numPoints*2);
    if(!lon->get(&array[0], numPoints))
      {
      return 0;
      }
    if(!lat->get(&array[numPoints], numPoints))
      {
      return 0;
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    }
  else
    {
    points->SetDataTypeToFloat();
    points->SetNumberOfPoints(numPoints);
    std::vector<float> array(numPoints*2);
    if(!lon->get(&array[0], numPoints))
      {
      return 0;
      }
    if(!lat->get(&array[numPoints], numPoints))
      {
      return 0;
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    }
  output->SetPoints(points);

  // read in any point data with dimensions (time, lev, ncol)
  NcDim* levelsDimension = this->PointsFile->get_dim("lev");
  long numLevels = levelsDimension->size();
  for(int i=0;i<this->PointsFile->num_vars();i++)
    {
    NcVar* variable = this->PointsFile->get_var(i);
    if(variable->num_dims() != 3 || variable->get_dim(0)->size() != 1 ||
       variable->get_dim(1)->size() != numLevels ||
       variable->get_dim(2)->size() != numPoints)
      { // not a field variable
      continue;
      }
    NcToken variableName = variable->name();
    // if we have a different level, that should be set here
    long level = 0;
    variable->set_cur(0, level, 0);
    vtkDataArray* dataArray = NULL;
    if(variable->type() == ncDouble)
      {
      vtkDoubleArray* doubleArray = vtkDoubleArray::New();
      doubleArray->SetNumberOfTuples(numPoints);
      if(!variable->get(doubleArray->GetPointer(0),
                        1, 1, numPoints))
        {
        return 0;
        }
      dataArray = doubleArray;
      }
    else
      {
      vtkFloatArray* floatArray = vtkFloatArray::New();
      floatArray->SetNumberOfTuples(numPoints);
      if(!variable->get(floatArray->GetPointer(0),
                        1, 1, numPoints))
        {
        return 0;
        }
      dataArray = floatArray;
      }
    dataArray->SetName(variableName);
    output->GetPointData()->AddArray(dataArray);
    dataArray->Delete();
    }

  // now read in the cell connectivity.  note that this is a periodic
  // domain and only the points on the left boundary are included in
  // the points file.  if a cell uses a point that is on the left
  // boundary and it should be on the right boundary we will have
  // to create that point.  that's what boundaryPoints is used for.
  std::map<vtkIdType, vtkIdType> boundaryPoints;
  dimension = this->ConnectivityFile->get_dim("ncenters");
  if(dimension == NULL)
    {  //supposed to be ncells but in example dataset it is ncenters
    this->ConnectivityFile->get_dim("ncenters");
    }
  NcVar* connectivity = this->ConnectivityFile->get_var("element_corners");
  long numCells = dimension->size();
  output->Allocate(numCells);
  if(connectivity == NULL)
    {
    vtkErrorMacro("Cannot find cell connectivity.");
    return 0;
    }
  std::vector<int> cellConnectivity(4*numCells);
  connectivity->get(&(cellConnectivity[0]), 4, numCells);
  double bounds[6];
  output->GetBounds(bounds);
  double leftSide = bounds[0] + .25*(bounds[1]-bounds[0]);
  double rightSide = bounds[0] + .75*(bounds[1]-bounds[0]);
  for(long i=0;i<numCells;i++)
    {
    vtkIdType pointIds[4];
    bool nearRightBoundary = false;
    bool nearLeftBoundary = false;
    double point[3];
    for(int j=0;j<4;j++)
      {
      pointIds[j] = cellConnectivity[i+j*numCells]-1;
      output->GetPoint(pointIds[j], point);
      if(point[0] > rightSide)
        {
        nearRightBoundary = true;
        }
      else if(point[0] < leftSide)
        {
        nearLeftBoundary = true;
        }
      }
    if(nearLeftBoundary == true && nearRightBoundary == true)
      {
      for(int j=0;j<4;j++)
        {
        output->GetPoint(pointIds[j], point);
        if(point[0] < leftSide)
          {
          std::map<vtkIdType, vtkIdType>::iterator otherPoint =
            boundaryPoints.find(pointIds[j]);
          if(otherPoint != boundaryPoints.end())
            { // already made point on the right boundary
            pointIds[j] = otherPoint->second;
            }
          else
            { // need to make point on the right boundary
            pointIds[j] = boundaryPoints[pointIds[j]] =
              points->InsertNextPoint(point[0]+360., point[1], point[2]);
            }
          }
        }
      }
    output->InsertNextCell(VTK_QUAD, 4, pointIds);
    }

  output->GetPointData()->CopyAllOn();
  output->GetPointData()->CopyAllocate(output->GetPointData(),
                                       output->GetNumberOfPoints());
  vtkPointData* pointData = output->GetPointData();
  for(std::map<vtkIdType, vtkIdType>::const_iterator it=
        boundaryPoints.begin();it!=boundaryPoints.end();it++)
    {
    pointData->CopyData(pointData, it->first, it->second);
    }

  vtkDebugMacro(<<"Read " <<output->GetNumberOfPoints() <<" points,"
                <<output->GetNumberOfCells() <<" cells.\n");

  return 1;
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::FillOutputPortInformation(int,
                                                  vtkInformation* info)
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkUnstructuredGrid");
  return 1;
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>Improved error handling as NetCDF calls exit by default for errors.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkNetCDFCAMReader.cxx

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

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

=========================================================================*/
#include "vtkNetCDFCAMReader.h"

#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkFieldData.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnstructuredGrid.h"

#include <map>
#include <vtk_netcdfcpp.h>

vtkStandardNewMacro(vtkNetCDFCAMReader);

//----------------------------------------------------------------------------
vtkNetCDFCAMReader::vtkNetCDFCAMReader()
{
  this->FileName = NULL;
  this->ConnectivityFileName = NULL;
  this->PointsFile = NULL;
  this->ConnectivityFile = NULL;
  this->SetNumberOfInputPorts(0);
  this->SetNumberOfOutputPorts(1);
}

//----------------------------------------------------------------------------
vtkNetCDFCAMReader::~vtkNetCDFCAMReader()
{
  this->SetFileName(NULL);
  this->SetConnectivityFileName(NULL);
  if(this->PointsFile)
    {
    delete this->PointsFile;
    this->PointsFile = NULL;
    }
  if(this->ConnectivityFile)
    {
    delete this->ConnectivityFile;
    this->ConnectivityFile = NULL;
    }
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::CanReadFile(const char* fileName)
{
  NcFile file(fileName, NcFile::ReadOnly);
  return file.is_valid();
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::SetFileName(const char* fileName)
{
  vtkDebugMacro(<<" setting FileName to " << (fileName?fileName:"(null)") );
  if ( this->FileName == NULL && fileName == NULL)
    {
    return;
    }
  if ( this->FileName && fileName && (!strcmp(this->FileName,fileName)))
    {
    return;
    }
  if(this->PointsFile)
    {
    delete this->PointsFile;
    this->PointsFile = NULL;
    }
  if (this->FileName)
    {
    delete [] this->FileName;
    }
  if (fileName)
    {
    size_t n = strlen(fileName) + 1;
    char *cp1 =  new char[n];
    const char *cp2 = (fileName);
    this->FileName = cp1;
    do
      {
      *cp1++ = *cp2++;
      }
    while ( --n );
    }
   else
    {
    this->FileName = NULL;
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::SetConnectivityFileName(const char* fileName)
{
  vtkDebugMacro(<<" setting ConnectivityFileName to "
                << (fileName?fileName:"(null)") );
  if ( this->ConnectivityFileName == NULL && fileName == NULL)
    {
    return;
    }
  if ( this->ConnectivityFileName && fileName &&
       (!strcmp(this->ConnectivityFileName,fileName)))
    {
    return;
    }
  if(this->ConnectivityFile)
    {
    delete this->ConnectivityFile;
    this->ConnectivityFile = NULL;
    }
  if (this->ConnectivityFileName)
    {
    delete [] this->ConnectivityFileName;
    }
  if (fileName)
    {
    size_t n = strlen(fileName) + 1;
    char *cp1 =  new char[n];
    const char *cp2 = (fileName);
    this->ConnectivityFileName = cp1;
    do
      {
      *cp1++ = *cp2++;
      }
    while ( --n );
    }
   else
    {
    this->ConnectivityFileName = NULL;
    }
  this->Modified();
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::RequestUpdateExtent(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  if(this->FileName == NULL || this->ConnectivityFileName == NULL)
    {
    vtkWarningMacro("Missing a file name.");
    return 0;
    }
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  int piece =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  int numPieces =
    outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());

  // make sure piece is valid
  if (piece < 0 || piece >= numPieces)
    {
    return 1;
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::RequestData(
  vtkInformation *,vtkInformationVector **,vtkInformationVector *outputVector)
{
  if(this->FileName == NULL || this->ConnectivityFileName == NULL)
    {
    vtkWarningMacro("Missing a file name.");
    return 0;
    }

  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // All of the data in the first piece.
  if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
    {
    return 1;
    }

  vtkDebugMacro(<<"Reading NetCDF CAM file.");

  if(this->PointsFile == NULL)
    {
    this->PointsFile = new NcFile(this->FileName, NcFile::ReadOnly);
    if(this->PointsFile->is_valid() == 0)
      {
      vtkErrorMacro(<< "Can't read file " << this->FileName);
      delete this->PointsFile;
      this->PointsFile = NULL;
      return 0;
      }
    }
  if(this->ConnectivityFile == NULL)
    {
    this->ConnectivityFile = new NcFile(this->ConnectivityFileName,
                                        NcFile::ReadOnly);
    if(this->ConnectivityFile->is_valid() == 0)
      {
      vtkErrorMacro(<< "Can't read file " << this->ConnectivityFileName);
      delete this->ConnectivityFile;
      this->ConnectivityFile = NULL;
      return 0;
      }
    }

  // Set the NetCDF error handler to not kill the application.
  // Upon exiting this method the error handler will be restored
  // to its previous state.
  NcError ncError(NcError::verbose_nonfatal);

  // read in the points first
  NcDim* dimension = this->PointsFile->get_dim("ncol");
  if(dimension == NULL)
    {
    vtkErrorMacro("Cannot find the number of points (ncol dimension).");
    return 0;
    }
  NcVar* lon = this->PointsFile->get_var("lon");
  NcVar* lat = this->PointsFile->get_var("lat");
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  long numPoints = dimension->size();
  if(lat == NULL || lon == NULL)
    {
    vtkErrorMacro("Cannot find coordinates (lat or lon variable).");
    return 0;
    }
  if(lat->type() == ncDouble)
    {
    points->SetDataTypeToDouble();
    points->SetNumberOfPoints(numPoints);
    std::vector<double> array(numPoints*2);
    if(!lon->get(&array[0], numPoints))
      {
      return 0;
      }
    if(!lat->get(&array[numPoints], numPoints))
      {
      return 0;
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    }
  else
    {
    points->SetDataTypeToFloat();
    points->SetNumberOfPoints(numPoints);
    std::vector<float> array(numPoints*2);
    if(!lon->get(&array[0], numPoints))
      {
      return 0;
      }
    if(!lat->get(&array[numPoints], numPoints))
      {
      return 0;
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    for(long i=0;i<numPoints;i++)
      {
      points->SetPoint(i, array[i], array[i+numPoints], 0.);
      }
    }
  output->SetPoints(points);

  // read in any point data with dimensions (time, lev, ncol)
  NcDim* levelsDimension = this->PointsFile->get_dim("lev");
  if(levelsDimension == NULL)
    {
    vtkErrorMacro("Cannot find the number of levels (lev dimension).");
    return 0;
    }

  //long numLevels = levelsDimension->size();
  for(int i=0;i<this->PointsFile->num_vars();i++)
    {
    NcVar* variable = this->PointsFile->get_var(i);
    if(variable->num_dims() != 3 ||
       strcmp(variable->get_dim(0)->name(), "time") != 0 ||
       strcmp(variable->get_dim(1)->name(), "lev") != 0 ||
       strcmp(variable->get_dim(2)->name(), "ncol") != 0)
      { // not a field variable
      continue;
      }
    NcToken variableName = variable->name();
    // if we have a different level, that should be set here
    long level = 0;
    variable->set_cur(0, level, 0);
    vtkDataArray* dataArray = NULL;
    if(variable->type() == ncDouble)
      {
      vtkDoubleArray* doubleArray = vtkDoubleArray::New();
      doubleArray->SetNumberOfTuples(numPoints);
      if(!variable->get(doubleArray->GetPointer(0),
                        1, 1, numPoints))
        {
        return 0;
        }
      dataArray = doubleArray;
      }
    else
      {
      vtkFloatArray* floatArray = vtkFloatArray::New();
      floatArray->SetNumberOfTuples(numPoints);
      if(!variable->get(floatArray->GetPointer(0),
                        1, 1, numPoints))
        {
        return 0;
        }
      dataArray = floatArray;
      }
    dataArray->SetName(variableName);
    output->GetPointData()->AddArray(dataArray);
    dataArray->Delete();
    }

  // now read in the cell connectivity.  note that this is a periodic
  // domain and only the points on the left boundary are included in
  // the points file.  if a cell uses a point that is on the left
  // boundary and it should be on the right boundary we will have
  // to create that point.  that's what boundaryPoints is used for.
  std::map<vtkIdType, vtkIdType> boundaryPoints;
  dimension = this->ConnectivityFile->get_dim("ncells");
  if(dimension == NULL)
    {
    vtkErrorMacro("Cannot find the number of cells (ncells dimension).");
    return 0;
    }
  NcVar* connectivity =
    this->ConnectivityFile->get_var("element_corners");
  if(connectivity == NULL)
    {
    vtkErrorMacro("Cannot find cell connectivity (element_corners dimension).");
    return 0;
    }
  long numCells = dimension->size();
  output->Allocate(numCells);
  std::vector<int> cellConnectivity(4*numCells);
  connectivity->get(&(cellConnectivity[0]), 4, numCells);
  double bounds[6];
  output->GetBounds(bounds);
  double leftSide = bounds[0] + .25*(bounds[1]-bounds[0]);
  double rightSide = bounds[0] + .75*(bounds[1]-bounds[0]);
  for(long i=0;i<numCells;i++)
    {
    vtkIdType pointIds[4];
    bool nearRightBoundary = false;
    bool nearLeftBoundary = false;
    double point[3];
    for(int j=0;j<4;j++)
      {
      pointIds[j] = cellConnectivity[i+j*numCells]-1;
      output->GetPoint(pointIds[j], point);
      if(point[0] > rightSide)
        {
        nearRightBoundary = true;
        }
      else if(point[0] < leftSide)
        {
        nearLeftBoundary = true;
        }
      }
    if(nearLeftBoundary == true && nearRightBoundary == true)
      {
      for(int j=0;j<4;j++)
        {
        output->GetPoint(pointIds[j], point);
        if(point[0] < leftSide)
          {
          std::map<vtkIdType, vtkIdType>::iterator otherPoint =
            boundaryPoints.find(pointIds[j]);
          if(otherPoint != boundaryPoints.end())
            { // already made point on the right boundary
            pointIds[j] = otherPoint->second;
            }
          else
            { // need to make point on the right boundary
            pointIds[j] = boundaryPoints[pointIds[j]] =
              points->InsertNextPoint(point[0]+360., point[1], point[2]);
            }
          }
        }
      }
    output->InsertNextCell(VTK_QUAD, 4, pointIds);
    }

  output->GetPointData()->CopyAllOn();
  output->GetPointData()->CopyAllocate(output->GetPointData(),
                                       output->GetNumberOfPoints());
  vtkPointData* pointData = output->GetPointData();
  for(std::map<vtkIdType, vtkIdType>::const_iterator it=
        boundaryPoints.begin();it!=boundaryPoints.end();it++)
    {
    pointData->CopyData(pointData, it->first, it->second);
    }

  vtkDebugMacro(<<"Read " << output->GetNumberOfPoints() <<" points,"
                << output->GetNumberOfCells() <<" cells.\n");

  return 1;
}

//----------------------------------------------------------------------------
int vtkNetCDFCAMReader::FillOutputPortInformation(int,
                                                  vtkInformation* info)
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkUnstructuredGrid");
  return 1;
}

//----------------------------------------------------------------------------
void vtkNetCDFCAMReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "sal/config.h"
#include "sal/precppunit.hxx"

#ifdef IOS
#define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTest_osl_old_test_file
#endif

// LLA:
// this file is converted to use with testshl2
// original was placed in sal/test/textenc.cxx

#include <stdio.h>

#include <osl/file.h>
#include <osl/process.h>
#include <rtl/ustring.hxx>
#ifdef SAL_UNX
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#define TEST_VOLUME ""
#else
// WINDOWS
#define TEST_VOLUME "c:/"
#endif

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

namespace osl_test_file
{

// -----------------------------------------------------------------------------

class oldtestfile : public CppUnit::TestFixture
{
public:
    void test_file_001();
    void test_file_002();
    void test_file_004();

    CPPUNIT_TEST_SUITE( oldtestfile );
    CPPUNIT_TEST( test_file_001 );
    CPPUNIT_TEST( test_file_002 );
    CPPUNIT_TEST( test_file_004 );
    CPPUNIT_TEST_SUITE_END( );
};

const char * const aSource1[] =
{
    "a"    , "file:///" TEST_VOLUME "bla/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/"   , "file:///" TEST_VOLUME "bla/a",
    "../a" , "file:///" TEST_VOLUME "a" ,
    "a/.." , "file:///" TEST_VOLUME "bla/",
    "a/../b" , "file:///" TEST_VOLUME "bla/b",
    ".."   , "file:///" TEST_VOLUME "",
    "a/b/c/d"   , "file:///" TEST_VOLUME "bla/a/b/c/d",
    "a/./c"   , "file:///" TEST_VOLUME "bla/a/c",
    "file:///bla/blub", "file:///"  "bla/blub",
    0 , 0
};

const char * const aSource2[ ] =
{
    "a" , "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/", "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    "../a", "file:///" TEST_VOLUME "bla/blubs/a",
    "../../a", "file:///" TEST_VOLUME "bla/a",
    "../../../a", "file:///" TEST_VOLUME "a",
    "../../../a/b/c/d", "file:///" TEST_VOLUME "a/b/c/d",
    0,0
};

const char * const aSource3[ ] =
{
    ".." , "/a",
    "../a" , "/a/a",
    "e/f" , "/c/e/f",
    "../..", "",
    0,0
};

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;
void oldtestfile::test_file_001()
{
#ifdef WIN32
    return;
#endif

    OUString base1( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla" ) );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base1.pData, rel.pData , &target.pData );
        //fprintf(stderr, "%d : %s -- %s -- %s\n", i, aSource1[i], aSource1[i+1], OUStringToOString(target , RTL_TEXTENCODING_ASCII_US ).getStr() );
        CPPUNIT_ASSERT_MESSAGE("failure #1",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #1.1",  target.equalsAscii( aSource1[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base1 , RTL_TEXTENCODING_ASCII_US );
        // fprintf( stderr, "%d %s + %s = %s\n" ,e, obase.getStr(), aSource1[i], o.pData->buffer );
    }

    OUString err1( RTL_CONSTASCII_USTRINGPARAM( "../.." ) );
    OUString target;
    // CPPUNIT_ASSERT_MESSAGE("failure #11",  osl_File_E_None != osl_getAbsoluteFileURL( base1.pData , err1.pData , &target.pData ) );

}

void oldtestfile::test_file_002()
{
#ifdef WIN32
    return;
#endif

    OUString base2( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla/blubs/schnubbel" ) );
    int i;
    for(  i = 0 ; aSource2[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource2[i] );
        oslFileError e = osl_getAbsoluteFileURL( base2.pData, rel.pData , &target.pData );
        //fprintf(stderr, "%d : %s -- %s -- %s\n", i, aSource2[i], aSource2[i+1], OUStringToOString(target , RTL_TEXTENCODING_ASCII_US ).getStr() );
        CPPUNIT_ASSERT_MESSAGE("failure #2",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #2.1",  target.equalsAscii( aSource2[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base2 , RTL_TEXTENCODING_ASCII_US );
//      fprintf( stderr, "%d %s + %s = %s\n" ,e, obase.getStr(), aSource2[i], o.pData->buffer );
    }
}

void oldtestfile::test_file_004()
{
#ifdef WIN32
    return;
#endif

    OUString base4( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla/" ) );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base4.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #10",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #10.1",  target.equalsAscii( aSource1[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base4 , RTL_TEXTENCODING_ASCII_US );
        //fprintf( stderr, "%d %s + %s = %s\n" ,e, obase.getStr(), aSource1[i], o.pData->buffer );
    }

// fprintf( stderr, "test_file done\n" );
}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( osl_test_file::oldtestfile);

// -----------------------------------------------------------------------------
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>WaE: msvc, unreachable code<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "sal/config.h"
#include "sal/precppunit.hxx"

#ifdef IOS
#define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTest_osl_old_test_file
#endif

// LLA:
// this file is converted to use with testshl2
// original was placed in sal/test/textenc.cxx

#include <stdio.h>

#include <osl/file.h>
#include <osl/process.h>
#include <rtl/ustring.hxx>
#ifdef SAL_UNX
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#define TEST_VOLUME ""
#else
// WINDOWS
#define TEST_VOLUME "c:/"
#endif

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

namespace osl_test_file
{

// -----------------------------------------------------------------------------

class oldtestfile : public CppUnit::TestFixture
{
public:
    void test_file_001();
    void test_file_002();
    void test_file_004();

    CPPUNIT_TEST_SUITE( oldtestfile );
    CPPUNIT_TEST( test_file_001 );
    CPPUNIT_TEST( test_file_002 );
    CPPUNIT_TEST( test_file_004 );
    CPPUNIT_TEST_SUITE_END( );
};

const char * const aSource1[] =
{
    "a"    , "file:///" TEST_VOLUME "bla/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/"   , "file:///" TEST_VOLUME "bla/a",
    "../a" , "file:///" TEST_VOLUME "a" ,
    "a/.." , "file:///" TEST_VOLUME "bla/",
    "a/../b" , "file:///" TEST_VOLUME "bla/b",
    ".."   , "file:///" TEST_VOLUME "",
    "a/b/c/d"   , "file:///" TEST_VOLUME "bla/a/b/c/d",
    "a/./c"   , "file:///" TEST_VOLUME "bla/a/c",
    "file:///bla/blub", "file:///"  "bla/blub",
    0 , 0
};

const char * const aSource2[ ] =
{
    "a" , "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/", "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    "../a", "file:///" TEST_VOLUME "bla/blubs/a",
    "../../a", "file:///" TEST_VOLUME "bla/a",
    "../../../a", "file:///" TEST_VOLUME "a",
    "../../../a/b/c/d", "file:///" TEST_VOLUME "a/b/c/d",
    0,0
};

const char * const aSource3[ ] =
{
    ".." , "/a",
    "../a" , "/a/a",
    "e/f" , "/c/e/f",
    "../..", "",
    0,0
};

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;

void oldtestfile::test_file_001()
{
#ifndef WIN32
    OUString base1( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla" ) );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base1.pData, rel.pData , &target.pData );
        //fprintf(stderr, "%d : %s -- %s -- %s\n", i, aSource1[i], aSource1[i+1], OUStringToOString(target , RTL_TEXTENCODING_ASCII_US ).getStr() );
        CPPUNIT_ASSERT_MESSAGE("failure #1",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #1.1",  target.equalsAscii( aSource1[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base1 , RTL_TEXTENCODING_ASCII_US );
        // fprintf( stderr, "%d %s + %s = %s\n" ,e, obase.getStr(), aSource1[i], o.pData->buffer );
    }

    OUString err1( RTL_CONSTASCII_USTRINGPARAM( "../.." ) );
    OUString target;
    // CPPUNIT_ASSERT_MESSAGE("failure #11",  osl_File_E_None != osl_getAbsoluteFileURL( base1.pData , err1.pData , &target.pData ) );
#endif
}

void oldtestfile::test_file_002()
{
#ifndef WIN32
    OUString base2( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla/blubs/schnubbel" ) );
    int i;
    for(  i = 0 ; aSource2[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource2[i] );
        oslFileError e = osl_getAbsoluteFileURL( base2.pData, rel.pData , &target.pData );
        //fprintf(stderr, "%d : %s -- %s -- %s\n", i, aSource2[i], aSource2[i+1], OUStringToOString(target , RTL_TEXTENCODING_ASCII_US ).getStr() );
        CPPUNIT_ASSERT_MESSAGE("failure #2",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #2.1",  target.equalsAscii( aSource2[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base2 , RTL_TEXTENCODING_ASCII_US );
    }
#endif
}

void oldtestfile::test_file_004()
{
#ifndef WIN32
    OUString base4( RTL_CONSTASCII_USTRINGPARAM( "file:///" TEST_VOLUME "bla/" ) );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base4.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #10",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #10.1",  target.equalsAscii( aSource1[i+1] ) );
        }
        OString o = OUStringToOString( target , RTL_TEXTENCODING_ASCII_US );
        OString obase = OUStringToOString( base4 , RTL_TEXTENCODING_ASCII_US );
        //fprintf( stderr, "%d %s + %s = %s\n" ,e, obase.getStr(), aSource1[i], o.pData->buffer );
    }
#endif
}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( osl_test_file::oldtestfile);

// -----------------------------------------------------------------------------
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>