<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include "../../../fem/libceed/ceed.hpp"

using namespace mfem;

namespace ceed_test
{

double coeff_function(const Vector &x)
{
   return 1 + x[0]*x[0];
}

void test_assembly_level(Mesh &&mesh, int order, const CeedCoeff coeff_type,
                         const int pb, const AssemblyLevel assembly)
{
   mesh.EnsureNodes();
   int dim = mesh.Dimension();

   H1_FECollection fec(order, dim);
   FiniteElementSpace fespace(&mesh, &fec);

   BilinearForm k_test(&fespace);
   BilinearForm k_ref(&fespace);

   GridFunction gf(&fespace);
   FunctionCoefficient f_coeff(coeff_function);

   Coefficient *coeff = nullptr;
   switch (coeff_type)
   {
      case CeedCoeff::Const:
         coeff = new ConstantCoefficient(1.0);
         break;
      case CeedCoeff::Grid:
         gf.ProjectCoefficient(f_coeff);
         coeff = new GridFunctionCoefficient(&gf);
         break;
      case CeedCoeff::Quad:
         coeff = &f_coeff;
         break;
      default:
         mfem_error("Unexpected coefficient type.");
         break;
   }

   if (pb==0) // Mass
   {
      k_ref.AddDomainIntegrator(new MassIntegrator(*coeff));
      k_test.AddDomainIntegrator(new MassIntegrator(*coeff));
   }
   else if (pb==2) // Diffusion
   {
      k_ref.AddDomainIntegrator(new DiffusionIntegrator(*coeff));
      k_test.AddDomainIntegrator(new DiffusionIntegrator(*coeff));
   }

   k_ref.Assemble();
   k_ref.Finalize();

   k_test.SetAssemblyLevel(assembly);
   k_test.Assemble();

   GridFunction x(&fespace), y_ref(&fespace), y_test(&fespace);

   x.Randomize(1);

   k_ref.Mult(x,y_ref);
   k_test.Mult(x,y_test);

   y_test -= y_ref;

   REQUIRE(y_test.Norml2() < 1.e-12);
}

TEST_CASE("CEED", "[CEED]")
{
   SECTION("Continuous Galerkin")
   {
      SECTION("2D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  for (int order : {2, 3, 4})
                  {
                     test_assembly_level(Mesh("../../data/inline-quad.mesh", 1, 1),
                                         order, coeff_type, pb, assembly);
                     // test_assembly_level(Mesh("../../data/periodic-hexagon.mesh", 1, 1),
                     //                     order, coeff_type, pb, assembly);
                     test_assembly_level(Mesh("../../data/star-q3.mesh", 1, 1),
                                         order, coeff_type, pb, assembly);
                  }
               }
            }
         }
      }
      SECTION("3D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  int order = 2;
                  test_assembly_level(Mesh("../../data/inline-hex.mesh", 1, 1),
                                      order, coeff_type, pb, assembly);
                  test_assembly_level(Mesh("../../data/fichera-q3.mesh", 1, 1),
                                      order, coeff_type, pb, assembly);
               }
            }
         }
      }
      SECTION("AMR 2D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  for (int order : {2, 3, 4})
                  {
                     test_assembly_level(Mesh("../../data/amr-quad.mesh", 1, 1),
                                         order, coeff_type, 0, assembly);
                  }
               }
            }
         }
      }
      SECTION("AMR 3D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  int order = 2;
                  test_assembly_level(Mesh("../../data/fichera-amr.mesh", 1, 1),
                                      order, coeff_type, 0, assembly);
               }
            }
         }
      }
   }
} // test case

} // namespace ceed_test

int main(int argc, char *argv[])
{
   // There must be exactly one instance.
   Catch::Session session;

   const char *device_str = (argc == 1) ? "ceed-cpu" : argv[argc-1];

   // Apply provided command line arguments.
   int r = session.applyCommandLine((argc == 1) ? argc : argc - 1, argv);
   if (r != 0)
   {
      return r;
   }

   Device device(device_str);

   int result = session.run();

   return result;
}
<commit_msg>Change orders in test_ceed.<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include "../../../fem/libceed/ceed.hpp"

using namespace mfem;

namespace ceed_test
{

double coeff_function(const Vector &x)
{
   return 1 + x[0]*x[0];
}

void test_assembly_level(Mesh &&mesh, int order, const CeedCoeff coeff_type,
                         const int pb, const AssemblyLevel assembly)
{
   mesh.EnsureNodes();
   int dim = mesh.Dimension();

   H1_FECollection fec(order, dim);
   FiniteElementSpace fespace(&mesh, &fec);

   BilinearForm k_test(&fespace);
   BilinearForm k_ref(&fespace);

   GridFunction gf(&fespace);
   FunctionCoefficient f_coeff(coeff_function);

   Coefficient *coeff = nullptr;
   switch (coeff_type)
   {
      case CeedCoeff::Const:
         coeff = new ConstantCoefficient(1.0);
         break;
      case CeedCoeff::Grid:
         gf.ProjectCoefficient(f_coeff);
         coeff = new GridFunctionCoefficient(&gf);
         break;
      case CeedCoeff::Quad:
         coeff = &f_coeff;
         break;
      default:
         mfem_error("Unexpected coefficient type.");
         break;
   }

   if (pb==0) // Mass
   {
      k_ref.AddDomainIntegrator(new MassIntegrator(*coeff));
      k_test.AddDomainIntegrator(new MassIntegrator(*coeff));
   }
   else if (pb==2) // Diffusion
   {
      k_ref.AddDomainIntegrator(new DiffusionIntegrator(*coeff));
      k_test.AddDomainIntegrator(new DiffusionIntegrator(*coeff));
   }

   k_ref.Assemble();
   k_ref.Finalize();

   k_test.SetAssemblyLevel(assembly);
   k_test.Assemble();

   GridFunction x(&fespace), y_ref(&fespace), y_test(&fespace);

   x.Randomize(1);

   k_ref.Mult(x,y_ref);
   k_test.Mult(x,y_test);

   y_test -= y_ref;

   REQUIRE(y_test.Norml2() < 1.e-12);
}

TEST_CASE("CEED", "[CEED]")
{
   SECTION("Continuous Galerkin")
   {
      SECTION("2D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  for (int order : {3, 4})
                  {
                     test_assembly_level(Mesh("../../data/inline-quad.mesh", 1, 1),
                                         order, coeff_type, pb, assembly);
                     // test_assembly_level(Mesh("../../data/periodic-hexagon.mesh", 1, 1),
                     //                     order, coeff_type, pb, assembly);
                     test_assembly_level(Mesh("../../data/star-q3.mesh", 1, 1),
                                         order, coeff_type, pb, assembly);
                  }
               }
            }
         }
      }
      SECTION("3D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  int order = 3;
                  test_assembly_level(Mesh("../../data/inline-hex.mesh", 1, 1),
                                      order, coeff_type, pb, assembly);
                  test_assembly_level(Mesh("../../data/fichera-q3.mesh", 1, 1),
                                      order, coeff_type, pb, assembly);
               }
            }
         }
      }
      SECTION("AMR 2D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  for (int order : {2, 3, 4})
                  {
                     test_assembly_level(Mesh("../../data/amr-quad.mesh", 1, 1),
                                         order, coeff_type, 0, assembly);
                  }
               }
            }
         }
      }
      SECTION("AMR 3D")
      {
         for (CeedCoeff coeff_type : {CeedCoeff::Const,CeedCoeff::Grid,CeedCoeff::Quad})
         {
            for (AssemblyLevel assembly : {AssemblyLevel::PARTIAL})
            {
               for (int pb : {0, 2})
               {
                  int order = 2;
                  test_assembly_level(Mesh("../../data/fichera-amr.mesh", 1, 1),
                                      order, coeff_type, 0, assembly);
               }
            }
         }
      }
   }
} // test case

} // namespace ceed_test

int main(int argc, char *argv[])
{
   // There must be exactly one instance.
   Catch::Session session;

   const char *device_str = (argc == 1) ? "ceed-cpu" : argv[argc-1];

   // Apply provided command line arguments.
   int r = session.applyCommandLine((argc == 1) ? argc : argc - 1, argv);
   if (r != 0)
   {
      return r;
   }

   Device device(device_str);

   int result = session.run();

   return result;
}
<|endoftext|>


<commit_before>#include "imageinsertdialog.h"

#include <QGridLayout>
#include <QVBoxLayout>
#include <QUrl>
#include <QRegularExpression>
#include <QLabel>
#include <QPushButton>
#include <QRegExpValidator>
#include <QSpinBox>
#include <QSlider>
#include <QScrollArea>
#include <QFileInfo>
#include <QDir>
#include <QFileDialog>
#include <QTimer>
#include <QTemporaryFile>
#include <QCheckBox>

#include <vtextedit/markdownutils.h>
#include <vtextedit/networkutils.h>

#include <widgets/widgetsfactory.h>
#include <widgets/lineedit.h>
#include <utils/fileutils.h>
#include <utils/pathutils.h>
#include <core/sessionconfig.h>
#include <core/configmgr.h>

using namespace vnotex;

int ImageInsertDialog::s_lastScaleSliderValue = 10;

int ImageInsertDialog::s_lastScaleWidth = -1;

bool ImageInsertDialog::s_fixedScaleWidth = false;

ImageInsertDialog::ImageInsertDialog(const QString &p_title,
                                     const QString &p_imageTitle,
                                     const QString &p_imageAlt,
                                     const QString &p_imagePath,
                                     bool p_browserEnabled,
                                     QWidget *p_parent)
    : Dialog(p_parent),
      m_browserEnabled(p_browserEnabled)
{
    m_imagePathCheckTimer = new QTimer(this);
    m_imagePathCheckTimer->setSingleShot(true);
    m_imagePathCheckTimer->setInterval(500);
    connect(m_imagePathCheckTimer, &QTimer::timeout,
            this, &ImageInsertDialog::checkImagePathInput);

    setupUI(p_title, p_imageTitle, p_imageAlt, p_imagePath);

    checkInput();
}

void ImageInsertDialog::setupUI(const QString &p_title,
                                const QString &p_imageTitle,
                                const QString &p_imageAlt,
                                const QString &p_imagePath)
{
    auto mainWidget = new QWidget(this);
    setCentralWidget(mainWidget);

    auto mainLayout = new QVBoxLayout(mainWidget);

    auto gridLayout = new QGridLayout();
    mainLayout->addLayout(gridLayout);

    mainLayout->addStretch();

    // Image Path.
    m_imagePathEdit = WidgetsFactory::createLineEdit(p_imagePath, mainWidget);
    m_imagePathEdit->setReadOnly(!m_browserEnabled);
    gridLayout->addWidget(new QLabel(tr("From:"), mainWidget), 0, 0, 1, 1);
    gridLayout->addWidget(m_imagePathEdit, 0, 1, 1, 3);
    connect(m_imagePathEdit, &QLineEdit::textChanged,
            this, [this]() {
                m_imagePathCheckTimer->start();
            });

    m_browseBtn = new QPushButton(tr("&Browse"), mainWidget);
    m_browseBtn->setEnabled(m_browserEnabled);
    gridLayout->addWidget(m_browseBtn, 0, 4, 1, 1);
    connect(m_browseBtn, &QPushButton::clicked,
            this, &ImageInsertDialog::browseFile);

    // Image Title.
    m_imageTitleEdit = WidgetsFactory::createLineEdit(p_imageTitle, mainWidget);
    auto titleValidator = new QRegExpValidator(QRegExp(vte::MarkdownUtils::c_imageTitleRegExp), m_imageTitleEdit);
    m_imageTitleEdit->setValidator(titleValidator);
    gridLayout->addWidget(new QLabel(tr("Title:"), mainWidget), 1, 0, 1, 1);
    gridLayout->addWidget(m_imageTitleEdit, 1, 1, 1, 3);
    connect(m_imageTitleEdit, &QLineEdit::textChanged,
            this, &ImageInsertDialog::checkInput);

    // Image Alt.
    m_imageAltEdit = WidgetsFactory::createLineEdit(p_imageAlt, mainWidget);
    auto altValidator = new QRegExpValidator(QRegExp(vte::MarkdownUtils::c_imageAltRegExp), m_imageAltEdit);
    m_imageAltEdit->setValidator(altValidator);
    gridLayout->addWidget(new QLabel(tr("Alt text:"), mainWidget), 2, 0, 1, 1);
    gridLayout->addWidget(m_imageAltEdit, 2, 1, 1, 3);

    // Scale.
    m_widthSpin = WidgetsFactory::createSpinBox(mainWidget);
    m_widthSpin->setMinimum(1);
    m_widthSpin->setSingleStep(10);
    m_widthSpin->setSuffix(" px");
    connect(m_widthSpin, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            this, [this](int p_val) {
                if (m_image.isNull()) {
                    return;
                }

                int height = m_image.height() * (1.0 * p_val / m_image.width());
                m_imageLabel->resize(p_val, height);

                s_lastScaleWidth = p_val;
            });
    // 0.1 to 2.0 -> 1 to 20.
    m_scaleSlider = new QSlider(mainWidget);
    m_scaleSlider->setOrientation(Qt::Horizontal);
    m_scaleSlider->setMinimum(1);
    m_scaleSlider->setMaximum(50);
    m_scaleSlider->setValue(s_lastScaleSliderValue);
    m_scaleSlider->setSingleStep(1);
    m_scaleSlider->setPageStep(5);
    connect(m_scaleSlider, &QSlider::valueChanged,
            this, &ImageInsertDialog::handleScaleSliderValueChanged);
    m_sliderLabel = new QLabel("1x", mainWidget);
    gridLayout->addWidget(new QLabel(tr("Scaling width:"), mainWidget), 3, 0, 1, 1);
    gridLayout->addWidget(m_widthSpin, 3, 1, 1, 1);
    gridLayout->addWidget(m_scaleSlider, 3, 2, 1, 2);
    gridLayout->addWidget(m_sliderLabel, 3, 4, 1, 1);

    {
        auto fixedWidthCheckBox = WidgetsFactory::createCheckBox(tr("Fixed scaling width"), mainWidget);
        fixedWidthCheckBox->setChecked(s_fixedScaleWidth);
        connect(fixedWidthCheckBox, &QCheckBox::stateChanged,
                this, [](int p_state) {
                    s_fixedScaleWidth = p_state == Qt::Checked;
                });
        gridLayout->addWidget(fixedWidthCheckBox, 4, 1, 1, 1);
    }

    // Preview area.
    m_imageLabel = new QLabel(mainWidget);
    m_imageLabel->setScaledContents(true);
    m_previewArea = new QScrollArea(mainWidget);
    m_previewArea->setBackgroundRole(QPalette::Dark);
    m_previewArea->setWidget(m_imageLabel);
    m_previewArea->setMinimumSize(256, 256);
    gridLayout->addWidget(m_previewArea, 5, 0, 1, 5);

    setImageControlsVisible(false);

    gridLayout->setColumnStretch(0, 0);
    gridLayout->setColumnStretch(1, 0);
    gridLayout->setColumnStretch(2, 1);
    gridLayout->setColumnStretch(3, 1);
    gridLayout->setColumnStretch(4, 0);

    setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

    setWindowTitle(p_title);
}

void ImageInsertDialog::setImageControlsVisible(bool p_visible)
{
    m_widthSpin->setEnabled(p_visible);
    m_scaleSlider->setEnabled(p_visible);
    m_sliderLabel->setEnabled(p_visible);

    m_previewArea->setVisible(p_visible);
}

void ImageInsertDialog::showEvent(QShowEvent *p_event)
{
    Dialog::showEvent(p_event);

    m_imageTitleEdit->selectAll();
    m_imageTitleEdit->setFocus();
}

void ImageInsertDialog::checkImagePathInput()
{
    const QString text = m_imagePathEdit->text();
    QUrl url = QUrl::fromUserInput(text);
    if (text.isEmpty() || !url.isValid()) {
        setImage(QImage());
        return;
    }

    if (url.isLocalFile()) {
        const auto localFile = url.toLocalFile();
        if (QFileInfo::exists(localFile)) {
            setImage(FileUtils::imageFromFile(localFile));
        } else {
            setImage(QImage());
        }

        m_source = Source::LocalFile;
    } else {
        setImage(QImage());
        m_source = Source::ImageData;

        if (!m_downloader) {
            m_downloader = new vte::NetworkAccess(this);
            connect(m_downloader, &vte::NetworkAccess::requestFinished,
                    this, &ImageInsertDialog::handleImageDownloaded);
        }

        m_downloader->requestAsync(url);
    }

    m_imageTitleEdit->setText(QFileInfo(text).baseName());

    checkInput();
}

void ImageInsertDialog::checkInput()
{
    setButtonEnabled(QDialogButtonBox::Ok, !m_image.isNull());
}

void ImageInsertDialog::browseFile()
{
    auto &sessionConfig = ConfigMgr::getInst().getSessionConfig();
    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("Select Image To Insert"),
                                                    sessionConfig.getExternalMediaDefaultPath(),
                                                    tr("Images (*.png *.xpm *.jpg *.bmp *.gif *.svg *.webp);;All (*.*)"));
    if (filePath.isEmpty()) {
        return;
    }

    sessionConfig.setExternalMediaDefaultPath(filePath);

    m_source = Source::LocalFile;

    setImagePath(filePath);

    m_imageTitleEdit->selectAll();
    m_imageTitleEdit->setFocus();
}

QString ImageInsertDialog::getImageTitle() const
{
    return m_imageTitleEdit->text();
}

QString ImageInsertDialog::getImageAltText() const
{
    return m_imageAltEdit->text();
}

QString ImageInsertDialog::getImagePath() const
{
    if (m_tempFile.isNull()) {
        return m_imagePathEdit->text();
    } else {
        return m_tempFile->fileName();
    }
}

ImageInsertDialog::Source ImageInsertDialog::getImageSource() const
{
    return m_source;
}

void ImageInsertDialog::setImageSource(ImageInsertDialog::Source p_source)
{
    m_source = p_source;
}

const QImage &ImageInsertDialog::getImage() const
{
    return m_image;
}

void ImageInsertDialog::setImage(const QImage &p_image)
{
    m_image = p_image;
    if (m_image.isNull()) {
        m_imageLabel->clear();
        setImageControlsVisible(false);
    } else {
        m_imageLabel->setPixmap(QPixmap::fromImage(m_image));

        m_imageLabel->adjustSize();

        m_widthSpin->setMaximum(m_image.width() * 5);

        if (s_fixedScaleWidth) {
            m_widthSpin->setValue(s_lastScaleWidth);
        } else {
            // Set the scaling widgets.
            if (m_scaleSlider->value() == s_lastScaleSliderValue) {
                // Trigger it manually.
                handleScaleSliderValueChanged(s_lastScaleSliderValue);
            } else {
                m_scaleSlider->setValue(s_lastScaleSliderValue);
            }
        }

        setImageControlsVisible(true);
    }

    checkInput();
}

void ImageInsertDialog::setImagePath(const QString &p_path)
{
    m_tempFile.reset();
    m_imagePathEdit->setText(p_path);
}

int ImageInsertDialog::getScaledWidth() const
{
    if (m_image.isNull()) {
        return 0;
    }

    int val = m_widthSpin->value();
    return val == m_image.width() ? 0 : val;
}

void ImageInsertDialog::handleImageDownloaded(const vte::NetworkReply &p_data, const QString &p_url)
{
    setImage(QImage::fromData(p_data.m_data));

    // Save it to a temp file to avoid potential data loss via QImage.
    bool savedToFile = false;
    if (!p_data.m_data.isEmpty()) {
        auto format = QFileInfo(PathUtils::removeUrlParameters(p_url)).suffix();
        m_tempFile.reset(FileUtils::createTemporaryFile(format));
        if (m_tempFile->open()) {
            savedToFile = -1 != m_tempFile->write(p_data.m_data);
            m_tempFile->close();
        }
    }

    m_source = savedToFile ? Source::LocalFile : Source::ImageData;
    if (!savedToFile) {
        m_tempFile.reset();
    }
}

void ImageInsertDialog::handleScaleSliderValueChanged(int p_val)
{
    if (m_image.isNull()) {
        return;
    }

    int width = m_image.width();
    qreal factor = 1.0;
    if (p_val != 10) {
        factor = p_val / 10.0;
        width = m_image.width() * factor;
    }

    m_widthSpin->setValue(width);
    m_sliderLabel->setText(QString::number(factor) + "x");

    s_lastScaleSliderValue = p_val;
}
<commit_msg>fix path<commit_after>#include "imageinsertdialog.h"

#include <QGridLayout>
#include <QVBoxLayout>
#include <QUrl>
#include <QRegularExpression>
#include <QLabel>
#include <QPushButton>
#include <QRegExpValidator>
#include <QSpinBox>
#include <QSlider>
#include <QScrollArea>
#include <QFileInfo>
#include <QDir>
#include <QFileDialog>
#include <QTimer>
#include <QTemporaryFile>
#include <QCheckBox>

#include <vtextedit/markdownutils.h>
#include <vtextedit/networkutils.h>

#include <widgets/widgetsfactory.h>
#include <widgets/lineedit.h>
#include <utils/fileutils.h>
#include <utils/pathutils.h>
#include <core/sessionconfig.h>
#include <core/configmgr.h>

using namespace vnotex;

int ImageInsertDialog::s_lastScaleSliderValue = 10;

int ImageInsertDialog::s_lastScaleWidth = -1;

bool ImageInsertDialog::s_fixedScaleWidth = false;

ImageInsertDialog::ImageInsertDialog(const QString &p_title,
                                     const QString &p_imageTitle,
                                     const QString &p_imageAlt,
                                     const QString &p_imagePath,
                                     bool p_browserEnabled,
                                     QWidget *p_parent)
    : Dialog(p_parent),
      m_browserEnabled(p_browserEnabled)
{
    m_imagePathCheckTimer = new QTimer(this);
    m_imagePathCheckTimer->setSingleShot(true);
    m_imagePathCheckTimer->setInterval(500);
    connect(m_imagePathCheckTimer, &QTimer::timeout,
            this, &ImageInsertDialog::checkImagePathInput);

    setupUI(p_title, p_imageTitle, p_imageAlt, p_imagePath);

    checkInput();
}

void ImageInsertDialog::setupUI(const QString &p_title,
                                const QString &p_imageTitle,
                                const QString &p_imageAlt,
                                const QString &p_imagePath)
{
    auto mainWidget = new QWidget(this);
    setCentralWidget(mainWidget);

    auto mainLayout = new QVBoxLayout(mainWidget);

    auto gridLayout = new QGridLayout();
    mainLayout->addLayout(gridLayout);

    mainLayout->addStretch();

    // Image Path.
    m_imagePathEdit = WidgetsFactory::createLineEdit(p_imagePath, mainWidget);
    m_imagePathEdit->setReadOnly(!m_browserEnabled);
    gridLayout->addWidget(new QLabel(tr("From:"), mainWidget), 0, 0, 1, 1);
    gridLayout->addWidget(m_imagePathEdit, 0, 1, 1, 3);
    connect(m_imagePathEdit, &QLineEdit::textChanged,
            this, [this]() {
                m_imagePathCheckTimer->start();
            });

    m_browseBtn = new QPushButton(tr("&Browse"), mainWidget);
    m_browseBtn->setEnabled(m_browserEnabled);
    gridLayout->addWidget(m_browseBtn, 0, 4, 1, 1);
    connect(m_browseBtn, &QPushButton::clicked,
            this, &ImageInsertDialog::browseFile);

    // Image Title.
    m_imageTitleEdit = WidgetsFactory::createLineEdit(p_imageTitle, mainWidget);
    auto titleValidator = new QRegExpValidator(QRegExp(vte::MarkdownUtils::c_imageTitleRegExp), m_imageTitleEdit);
    m_imageTitleEdit->setValidator(titleValidator);
    gridLayout->addWidget(new QLabel(tr("Title:"), mainWidget), 1, 0, 1, 1);
    gridLayout->addWidget(m_imageTitleEdit, 1, 1, 1, 3);
    connect(m_imageTitleEdit, &QLineEdit::textChanged,
            this, &ImageInsertDialog::checkInput);

    // Image Alt.
    m_imageAltEdit = WidgetsFactory::createLineEdit(p_imageAlt, mainWidget);
    auto altValidator = new QRegExpValidator(QRegExp(vte::MarkdownUtils::c_imageAltRegExp), m_imageAltEdit);
    m_imageAltEdit->setValidator(altValidator);
    gridLayout->addWidget(new QLabel(tr("Alt text:"), mainWidget), 2, 0, 1, 1);
    gridLayout->addWidget(m_imageAltEdit, 2, 1, 1, 3);

    // Scale.
    m_widthSpin = WidgetsFactory::createSpinBox(mainWidget);
    m_widthSpin->setMinimum(1);
    m_widthSpin->setSingleStep(10);
    m_widthSpin->setSuffix(" px");
    connect(m_widthSpin, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            this, [this](int p_val) {
                if (m_image.isNull()) {
                    return;
                }

                int height = m_image.height() * (1.0 * p_val / m_image.width());
                m_imageLabel->resize(p_val, height);

                s_lastScaleWidth = p_val;
            });
    // 0.1 to 2.0 -> 1 to 20.
    m_scaleSlider = new QSlider(mainWidget);
    m_scaleSlider->setOrientation(Qt::Horizontal);
    m_scaleSlider->setMinimum(1);
    m_scaleSlider->setMaximum(50);
    m_scaleSlider->setValue(s_lastScaleSliderValue);
    m_scaleSlider->setSingleStep(1);
    m_scaleSlider->setPageStep(5);
    connect(m_scaleSlider, &QSlider::valueChanged,
            this, &ImageInsertDialog::handleScaleSliderValueChanged);
    m_sliderLabel = new QLabel("1x", mainWidget);
    gridLayout->addWidget(new QLabel(tr("Scaling width:"), mainWidget), 3, 0, 1, 1);
    gridLayout->addWidget(m_widthSpin, 3, 1, 1, 1);
    gridLayout->addWidget(m_scaleSlider, 3, 2, 1, 2);
    gridLayout->addWidget(m_sliderLabel, 3, 4, 1, 1);

    {
        auto fixedWidthCheckBox = WidgetsFactory::createCheckBox(tr("Fixed scaling width"), mainWidget);
        fixedWidthCheckBox->setChecked(s_fixedScaleWidth);
        connect(fixedWidthCheckBox, &QCheckBox::stateChanged,
                this, [](int p_state) {
                    s_fixedScaleWidth = p_state == Qt::Checked;
                });
        gridLayout->addWidget(fixedWidthCheckBox, 4, 1, 1, 1);
    }

    // Preview area.
    m_imageLabel = new QLabel(mainWidget);
    m_imageLabel->setScaledContents(true);
    m_previewArea = new QScrollArea(mainWidget);
    m_previewArea->setBackgroundRole(QPalette::Dark);
    m_previewArea->setWidget(m_imageLabel);
    m_previewArea->setMinimumSize(256, 256);
    gridLayout->addWidget(m_previewArea, 5, 0, 1, 5);

    setImageControlsVisible(false);

    gridLayout->setColumnStretch(0, 0);
    gridLayout->setColumnStretch(1, 0);
    gridLayout->setColumnStretch(2, 1);
    gridLayout->setColumnStretch(3, 1);
    gridLayout->setColumnStretch(4, 0);

    setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

    setWindowTitle(p_title);
}

void ImageInsertDialog::setImageControlsVisible(bool p_visible)
{
    m_widthSpin->setEnabled(p_visible);
    m_scaleSlider->setEnabled(p_visible);
    m_sliderLabel->setEnabled(p_visible);

    m_previewArea->setVisible(p_visible);
}

void ImageInsertDialog::showEvent(QShowEvent *p_event)
{
    Dialog::showEvent(p_event);

    m_imageTitleEdit->selectAll();
    m_imageTitleEdit->setFocus();
}

void ImageInsertDialog::checkImagePathInput()
{
    const QString text = m_imagePathEdit->text();
    QUrl url = QUrl::fromUserInput(text);
    if (text.isEmpty() || !url.isValid()) {
        setImage(QImage());
        return;
    }

    if (url.isLocalFile()) {
        const auto localFile = url.toLocalFile();
        if (QFileInfo::exists(localFile)) {
            setImage(FileUtils::imageFromFile(localFile));
        } else {
            setImage(QImage());
        }

        m_source = Source::LocalFile;
    } else {
        setImage(QImage());
        m_source = Source::ImageData;

        if (!m_downloader) {
            m_downloader = new vte::NetworkAccess(this);
            connect(m_downloader, &vte::NetworkAccess::requestFinished,
                    this, &ImageInsertDialog::handleImageDownloaded);
        }

        m_downloader->requestAsync(url);
    }

    m_imageTitleEdit->setText(QFileInfo(text).baseName());

    checkInput();
}

void ImageInsertDialog::checkInput()
{
    setButtonEnabled(QDialogButtonBox::Ok, !m_image.isNull());
}

void ImageInsertDialog::browseFile()
{
    auto &sessionConfig = ConfigMgr::getInst().getSessionConfig();
    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("Select Image To Insert"),
                                                    sessionConfig.getExternalMediaDefaultPath(),
                                                    tr("Images (*.png *.xpm *.jpg *.bmp *.gif *.svg *.webp);;All (*.*)"));
    if (filePath.isEmpty()) {
        return;
    }

    sessionConfig.setExternalMediaDefaultPath(PathUtils::parentDirPath(filePath));

    m_source = Source::LocalFile;

    setImagePath(filePath);

    m_imageTitleEdit->selectAll();
    m_imageTitleEdit->setFocus();
}

QString ImageInsertDialog::getImageTitle() const
{
    return m_imageTitleEdit->text();
}

QString ImageInsertDialog::getImageAltText() const
{
    return m_imageAltEdit->text();
}

QString ImageInsertDialog::getImagePath() const
{
    if (m_tempFile.isNull()) {
        return m_imagePathEdit->text();
    } else {
        return m_tempFile->fileName();
    }
}

ImageInsertDialog::Source ImageInsertDialog::getImageSource() const
{
    return m_source;
}

void ImageInsertDialog::setImageSource(ImageInsertDialog::Source p_source)
{
    m_source = p_source;
}

const QImage &ImageInsertDialog::getImage() const
{
    return m_image;
}

void ImageInsertDialog::setImage(const QImage &p_image)
{
    m_image = p_image;
    if (m_image.isNull()) {
        m_imageLabel->clear();
        setImageControlsVisible(false);
    } else {
        m_imageLabel->setPixmap(QPixmap::fromImage(m_image));

        m_imageLabel->adjustSize();

        m_widthSpin->setMaximum(m_image.width() * 5);

        if (s_fixedScaleWidth) {
            m_widthSpin->setValue(s_lastScaleWidth);
        } else {
            // Set the scaling widgets.
            if (m_scaleSlider->value() == s_lastScaleSliderValue) {
                // Trigger it manually.
                handleScaleSliderValueChanged(s_lastScaleSliderValue);
            } else {
                m_scaleSlider->setValue(s_lastScaleSliderValue);
            }
        }

        setImageControlsVisible(true);
    }

    checkInput();
}

void ImageInsertDialog::setImagePath(const QString &p_path)
{
    m_tempFile.reset();
    m_imagePathEdit->setText(p_path);
}

int ImageInsertDialog::getScaledWidth() const
{
    if (m_image.isNull()) {
        return 0;
    }

    int val = m_widthSpin->value();
    return val == m_image.width() ? 0 : val;
}

void ImageInsertDialog::handleImageDownloaded(const vte::NetworkReply &p_data, const QString &p_url)
{
    setImage(QImage::fromData(p_data.m_data));

    // Save it to a temp file to avoid potential data loss via QImage.
    bool savedToFile = false;
    if (!p_data.m_data.isEmpty()) {
        auto format = QFileInfo(PathUtils::removeUrlParameters(p_url)).suffix();
        m_tempFile.reset(FileUtils::createTemporaryFile(format));
        if (m_tempFile->open()) {
            savedToFile = -1 != m_tempFile->write(p_data.m_data);
            m_tempFile->close();
        }
    }

    m_source = savedToFile ? Source::LocalFile : Source::ImageData;
    if (!savedToFile) {
        m_tempFile.reset();
    }
}

void ImageInsertDialog::handleScaleSliderValueChanged(int p_val)
{
    if (m_image.isNull()) {
        return;
    }

    int width = m_image.width();
    qreal factor = 1.0;
    if (p_val != 10) {
        factor = p_val / 10.0;
        width = m_image.width() * factor;
    }

    m_widthSpin->setValue(width);
    m_sliderLabel->setText(QString::number(factor) + "x");

    s_lastScaleSliderValue = p_val;
}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "WorldMapWidget.h"
#include "ImageItem.h"
#include <QGraphicsScene>

#include "MemoryLeakCheck.h"

namespace WorldMap
{
    WorldMapWidget::WorldMapWidget() :
        update_timer_(new QTimer(this)),
        brush_(Qt::white),
        sim_name_(QString(""))
    {
        setupUi(this);
    }

    WorldMapWidget::~WorldMapWidget()
    {
        if (avatar_items_.size() > 0)
        {
            for (QMap<QString, WorldMap::ImageItem *>::iterator iter = avatar_items_.begin(); iter!=avatar_items_.end(); ++iter)
            {
                SAFE_DELETE(iter.value());
            }
        }
    }

    void WorldMapWidget::SetMyAvatarId(QString avatar_id)
    {
        my_avatar_id_ = avatar_id;
    }

    void WorldMapWidget::StartUpdateTimer()
    {
        update_timer_->setSingleShot(false);
        update_timer_->start(1000);
        connect(update_timer_, SIGNAL(timeout()), SLOT(UpdateAvatarPosition()));

    }

    void WorldMapWidget::StopUpdateTimer()
    {
    }

    void WorldMapWidget::SetSimName(QString simName)
    {
        sim_name_ = simName;
        DrawMap();
    }

    void WorldMapWidget::RemoveAvatar(QString avatar_id)
    {
        if (!avatar_id.isEmpty())
        {
            ImageItem *item = 0;
            if (avatar_items_.contains(avatar_id))
            {
                item = avatar_items_.value(avatar_id);
                if (item)
                    SAFE_DELETE(item);

                avatar_items_.remove(avatar_id);
            }

            if (avatar_names_.contains(avatar_id))
            {
                avatar_names_.remove(avatar_id);
            }
        }
    }

    void WorldMapWidget::StoreMapData(QPixmap &image, QString map_id)
    {
        if (!region_images_.contains(map_id))
        {
            region_images_.insert(map_id, image);
            DrawMap();
        }
    }

    void WorldMapWidget::DrawMap()
    {

        //Try to draw current region map.
        if (sim_name_.isEmpty())
            return;

        if (region_images_.size() == 0)
            return;

        QGraphicsScene *scene = worldMapGraphicsView->scene();
        if (!scene)
            scene = new QGraphicsScene(this);

        if (map_blocks_.size() == 0)
            return;

        ProtocolUtilities::MapBlock *currentBlock;

        foreach (ProtocolUtilities::MapBlock block, map_blocks_)
        {
            if (sim_name_ == QString(block.regionName.c_str()))
            {
                currentBlock = █
                break;
            }
        }

        if (currentBlock)
        {
            if (region_images_.size() > 0)
            {
                for (QMap<QString, QPixmap>::iterator iter = region_images_.begin(); iter!=region_images_.end(); ++iter)
                {
                    if (iter.key() == currentBlock->mapImageID.ToQString())
                    {
                        scene->addPixmap(iter.value());

                        QGraphicsScene *graphicsViewScene = worldMapGraphicsView->scene();
                        if (!graphicsViewScene)
                            graphicsViewScene = new QGraphicsScene(this);

                        QGraphicsTextItem *item = new QGraphicsTextItem(0, scene);
                        item->font().setPixelSize(6);
                        item->setHtml(currentBlock->regionName.c_str());
                        graphicsViewScene->addItem(item);

                        worldMapGraphicsView->setScene(scene);
                        worldMapGraphicsView->update();

                        break;
                    }
                }
            }
        }

    }

    void WorldMapWidget::UpdateAvatarPosition(Vector3df position, QString avatar_id, QString avatar_name)
    {
        QGraphicsScene *scene = worldMapGraphicsView->scene();
        if (!scene)
            scene = new QGraphicsScene(this);

        ImageItem *item = 0;
        if (avatar_items_.contains(avatar_id))
        {
            item = avatar_items_.value(avatar_id);
        }
        else
        {
            item = new ImageItem(QPixmap("./data/ui/images/worldmap/default_avatar.png"), 0, scene);
            if (!my_avatar_id_.isEmpty() && my_avatar_id_ == avatar_id)
            {
                item->SetMyAvatar(true);
            }

            item->SetAvatarName(avatar_name);
            scene->addItem(item);
            avatar_items_.insert(avatar_id, item); //Add to items
        }

        if (!avatar_names_.contains(avatar_id))
            avatar_names_.insert(avatar_id, avatar_name); //Add to names

        item->setPos(position.x, position.y);
        item->SetTextPosition(position.x, position.y);
        item->UpdateTextPosition();
        item->setOffset(-10, -10);
        item->show();
        scene->update();

    }

}

<commit_msg>Worldmap graphics item display fixes.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "WorldMapWidget.h"
#include "ImageItem.h"
#include <QGraphicsScene>

#include "MemoryLeakCheck.h"

namespace WorldMap
{
    WorldMapWidget::WorldMapWidget() :
        update_timer_(new QTimer(this)),
        brush_(Qt::white),
        sim_name_(QString(""))
    {
        setupUi(this);
    }

    WorldMapWidget::~WorldMapWidget()
    {
        if (avatar_items_.size() > 0)
        {
            for (QMap<QString, WorldMap::ImageItem *>::iterator iter = avatar_items_.begin(); iter!=avatar_items_.end(); ++iter)
            {
                SAFE_DELETE(iter.value());
            }
        }
    }

    void WorldMapWidget::SetMyAvatarId(QString avatar_id)
    {
        my_avatar_id_ = avatar_id;
    }

    void WorldMapWidget::StartUpdateTimer()
    {
        update_timer_->setSingleShot(false);
        update_timer_->start(1000);
        connect(update_timer_, SIGNAL(timeout()), SLOT(UpdateAvatarPosition()));

    }

    void WorldMapWidget::StopUpdateTimer()
    {
    }

    void WorldMapWidget::SetSimName(QString simName)
    {
        sim_name_ = simName;
        DrawMap();
    }

    void WorldMapWidget::RemoveAvatar(QString avatar_id)
    {
        if (!avatar_id.isEmpty())
        {
            ImageItem *item = 0;
            if (avatar_items_.contains(avatar_id))
            {
                item = avatar_items_.value(avatar_id);
                if (item)
                    SAFE_DELETE(item);

                avatar_items_.remove(avatar_id);
            }

            if (avatar_names_.contains(avatar_id))
            {
                avatar_names_.remove(avatar_id);
            }
        }
    }

    void WorldMapWidget::StoreMapData(QPixmap &image, QString map_id)
    {
        if (!region_images_.contains(map_id))
        {
            region_images_.insert(map_id, image);
            DrawMap();
        }
    }

    void WorldMapWidget::DrawMap()
    {

        //Try to draw current region map.
        if (sim_name_.isEmpty())
            return;

        if (region_images_.size() == 0)
            return;

        QGraphicsScene *scene = worldMapGraphicsView->scene();
        if (!scene)
            scene = new QGraphicsScene(this);

        if (map_blocks_.size() == 0)
            return;

        ProtocolUtilities::MapBlock *currentBlock;

        foreach (ProtocolUtilities::MapBlock block, map_blocks_)
        {
            if (sim_name_ == QString(block.regionName.c_str()))
            {
                currentBlock = █
                break;
            }
        }

        if (currentBlock)
        {
            if (region_images_.size() > 0)
            {
                for (QMap<QString, QPixmap>::iterator iter = region_images_.begin(); iter!=region_images_.end(); ++iter)
                {
                    if (iter.key() == currentBlock->mapImageID.ToQString())
                    {
                        scene->addPixmap(iter.value());
                        worldMapGraphicsView->setScene(scene);

                        QGraphicsTextItem *item = new QGraphicsTextItem(0, scene);
                        item->setHtml(sim_name_);
                        scene->addItem(item);
                        item->show();

                        worldMapGraphicsView->update();
                        scene->update();

                        break;
                    }
                }
            }
        }

    }

    void WorldMapWidget::UpdateAvatarPosition(Vector3df position, QString avatar_id, QString avatar_name)
    {
        QGraphicsScene *scene = worldMapGraphicsView->scene();
        if (!scene)
            scene = new QGraphicsScene(this);

        worldMapGraphicsView->setScene(scene);

        ImageItem *item = 0;
        if (avatar_items_.contains(avatar_id))
        {
            item = avatar_items_.value(avatar_id);
        }
        else
        {
            item = new ImageItem(QPixmap("./data/ui/images/worldmap/default_avatar.png"), 0, scene);
            if (!my_avatar_id_.isEmpty() && my_avatar_id_ == avatar_id)
            {
                item->SetMyAvatar(true);
            }

            item->SetAvatarName(avatar_name);
            scene->addItem(item);
            avatar_items_.insert(avatar_id, item); //Add to items
        }

        if (!avatar_names_.contains(avatar_id))
            avatar_names_.insert(avatar_id, avatar_name); //Add to names

        if (!scene->items().contains(item))
            scene->addItem(item);

        item->setPos(position.x, position.y);
        item->SetTextPosition(position.x, position.y);
        item->UpdateTextPosition();
        item->setOffset(-10, -10);
        item->show();
        scene->update();

    }

}

<|endoftext|>


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

/*
 * $Log$
 * Revision 1.1  2003/09/18 18:29:58  peiyongz
 * Interface: Binary Output Stream
 *
 * $Id$
 *
 */

#if !defined(BIN_OUTPUT_STREAM_HPP)
#define BIN_OUTPUT_STREAM_HPP

#include <xercesc/util/XMemory.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class XMLUTIL_EXPORT BinOutputStream : public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Virtual destructor for derived classes
    // -----------------------------------------------------------------------
    virtual ~BinOutputStream();

    // -----------------------------------------------------------------------
    //  The virtual input stream interface
    // -----------------------------------------------------------------------
    virtual unsigned int curPos() const = 0;

    virtual void writeBytes
    (
                XMLByte* const      toGo
        , const unsigned int        maxToWrite
    ) = 0;

protected :
    // -----------------------------------------------------------------------
    //  Hidden Constructors
    // -----------------------------------------------------------------------
    BinOutputStream();

private :
    // -----------------------------------------------------------------------
    //  Unimplemented Constructors
    // -----------------------------------------------------------------------
    BinOutputStream(const BinOutputStream&);
    BinOutputStream& operator=(const BinOutputStream&);
};

XERCES_CPP_NAMESPACE_END

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

/*
 * $Log$
 * Revision 1.2  2003/12/16 17:17:25  peiyongz
 * typo fixed
 *
 * Revision 1.1  2003/09/18 18:29:58  peiyongz
 * Interface: Binary Output Stream
 *
 * $Id$
 *
 */

#if !defined(BIN_OUTPUT_STREAM_HPP)
#define BIN_OUTPUT_STREAM_HPP

#include <xercesc/util/XMemory.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class XMLUTIL_EXPORT BinOutputStream : public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Virtual destructor for derived classes
    // -----------------------------------------------------------------------
    virtual ~BinOutputStream();

    // -----------------------------------------------------------------------
    //  The virtual output stream interface
    // -----------------------------------------------------------------------
    virtual unsigned int curPos() const = 0;

    virtual void writeBytes
    (
                XMLByte* const      toGo
        , const unsigned int        maxToWrite
    ) = 0;

protected :
    // -----------------------------------------------------------------------
    //  Hidden Constructors
    // -----------------------------------------------------------------------
    BinOutputStream();

private :
    // -----------------------------------------------------------------------
    //  Unimplemented Constructors
    // -----------------------------------------------------------------------
    BinOutputStream(const BinOutputStream&);
    BinOutputStream& operator=(const BinOutputStream&);
};

XERCES_CPP_NAMESPACE_END

#endif
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
//!
//! \file   tstParticleBank.cpp
//! \author Alex Robinson
//! \brief  Particle bank unit test
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <iostream>

// Trilinos Includes
#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_VerboseObject.hpp>

// FRENSIE Includes
#include "MonteCarlo_ParticleBank.hpp"
#include "MonteCarlo_NeutronState.hpp"
#include "MonteCarlo_PhotonState.hpp"
#include "MonteCarlo_ElectronState.hpp"
#include "Utility_GlobalOpenMPSession.hpp"

//---------------------------------------------------------------------------//
// Tests.
//---------------------------------------------------------------------------//
// Check that particles can be pushed to the particle bank
TEUCHOS_UNIT_TEST( ParticleBank, push )
{
#pragma omp parallel num_threads( Utility::GlobalOpenMPSession::getRequestedNumberOfThreads() )
  {
    MonteCarlo::ParticleBank bank;

    TEST_ASSERT( bank.empty() );

    unsigned history_number = Teuchos::GlobalMPISession::getRank()*
      Utility::GlobalOpenMPSession::getRequestedNumberOfThreads() +
      Utility::GlobalOpenMPSession::getThreadId();

    MonteCarlo::ParticleState::pointerType particle;

    particle.reset( new MonteCarlo::PhotonState( history_number ) );

    bank.push( particle );

    #pragma omp critical( test_update )
    {
      std::cout << bank.top()->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 1 );
    }

    particle.reset( new MonteCarlo::NeutronState( history_number ) );

    bank.push( particle, MonteCarlo::N__N_ELASTIC_REACTION );

    #pragma omp critical( test_update )
    {
      std::cout << particle->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 2 );
    }
cd
    particle.reset( new MonteCarlo::ElectronState( history_number ) );

    bank.push( particle );

    #pragma omp critical( test_update )
    {
      std::cout << particle->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 3 );
    }

    #pragma omp barrier
  }
}

//---------------------------------------------------------------------------//
// Check that that the top element of the bank can be accessed
TEUCHOS_UNIT_TEST( ParticleBank, top )
{
  MonteCarlo::ParticleBank bank;

  MonteCarlo::ParticleState::pointerType particle(
					     new MonteCarlo::PhotonState( 0ull ) );

  bank.push( particle );

  TEST_EQUALITY( particle,  bank.top() );

  const MonteCarlo::ParticleBank& const_bank = bank;

  TEST_EQUALITY( particle,  const_bank.top() );
}

//---------------------------------------------------------------------------//
// Check that particles can be removed from the bank
TEUCHOS_UNIT_TEST( ParticleBank, pop )
{
  MonteCarlo::ParticleBank bank;

  MonteCarlo::ParticleState::pointerType particle(
					     new MonteCarlo::PhotonState( 0ull ) );

  bank.push( particle );

  TEST_ASSERT( !bank.empty() );

  bank.pop();

  TEST_ASSERT( bank.empty() );
}

//---------------------------------------------------------------------------//
// Custom main function
//---------------------------------------------------------------------------//
int main( int argc, char** argv )
{
  Teuchos::CommandLineProcessor& clp = Teuchos::UnitTestRepository::getCLP();

  int threads = 1;

  clp.setOption( "threads",
		 &threads,
		 "Number of threads to use" );

  Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return =
    clp.parse(argc,argv);

  const Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();

  if ( parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) {
    *out << "\nEnd Result: TEST FAILED" << std::endl;
    return parse_return;
  }

  // Set up the global OpenMP session
  if( Utility::GlobalOpenMPSession::isOpenMPUsed() )
    Utility::GlobalOpenMPSession::setNumberOfThreads( threads );

  // Run the unit tests
  Teuchos::GlobalMPISession mpiSession( &argc, &argv );

  out->setProcRankAndSize( mpiSession.getRank(), mpiSession.getNProc() );
  out->setOutputToRootOnly( 0 );

  const bool success = Teuchos::UnitTestRepository::runUnitTests(*out);

  if (success)
    *out << "\nEnd Result: TEST PASSED" << std::endl;
  else
    *out << "\nEnd Result: TEST FAILED" << std::endl;

  clp.printFinalTimerSummary(out.ptr());

  return (success ? 0 : 1);
}

//---------------------------------------------------------------------------//
// end tstParticleBank.cpp
//---------------------------------------------------------------------------//
<commit_msg>fixed small typo<commit_after>//---------------------------------------------------------------------------//
//!
//! \file   tstParticleBank.cpp
//! \author Alex Robinson
//! \brief  Particle bank unit test
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <iostream>

// Trilinos Includes
#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_VerboseObject.hpp>

// FRENSIE Includes
#include "MonteCarlo_ParticleBank.hpp"
#include "MonteCarlo_NeutronState.hpp"
#include "MonteCarlo_PhotonState.hpp"
#include "MonteCarlo_ElectronState.hpp"
#include "Utility_GlobalOpenMPSession.hpp"

//---------------------------------------------------------------------------//
// Tests.
//---------------------------------------------------------------------------//
// Check that particles can be pushed to the particle bank
TEUCHOS_UNIT_TEST( ParticleBank, push )
{
#pragma omp parallel num_threads( Utility::GlobalOpenMPSession::getRequestedNumberOfThreads() )
  {
    MonteCarlo::ParticleBank bank;

    TEST_ASSERT( bank.empty() );

    unsigned history_number = Teuchos::GlobalMPISession::getRank()*
      Utility::GlobalOpenMPSession::getRequestedNumberOfThreads() +
      Utility::GlobalOpenMPSession::getThreadId();

    MonteCarlo::ParticleState::pointerType particle;

    particle.reset( new MonteCarlo::PhotonState( history_number ) );

    bank.push( particle );

    #pragma omp critical( test_update )
    {
      std::cout << bank.top()->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 1 );
    }

    particle.reset( new MonteCarlo::NeutronState( history_number ) );

    bank.push( particle, MonteCarlo::N__N_ELASTIC_REACTION );

    #pragma omp critical( test_update )
    {
      std::cout << particle->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 2 );
    }

    particle.reset( new MonteCarlo::ElectronState( history_number ) );

    bank.push( particle );

    #pragma omp critical( test_update )
    {
      std::cout << particle->getHistoryNumber() << std::endl;

      TEST_ASSERT( !bank.empty() );
      TEST_EQUALITY_CONST( bank.size(), 3 );
    }

    #pragma omp barrier
  }
}

//---------------------------------------------------------------------------//
// Check that that the top element of the bank can be accessed
TEUCHOS_UNIT_TEST( ParticleBank, top )
{
  MonteCarlo::ParticleBank bank;

  MonteCarlo::ParticleState::pointerType particle(
					     new MonteCarlo::PhotonState( 0ull ) );

  bank.push( particle );

  TEST_EQUALITY( particle,  bank.top() );

  const MonteCarlo::ParticleBank& const_bank = bank;

  TEST_EQUALITY( particle,  const_bank.top() );
}

//---------------------------------------------------------------------------//
// Check that particles can be removed from the bank
TEUCHOS_UNIT_TEST( ParticleBank, pop )
{
  MonteCarlo::ParticleBank bank;

  MonteCarlo::ParticleState::pointerType particle(
					     new MonteCarlo::PhotonState( 0ull ) );

  bank.push( particle );

  TEST_ASSERT( !bank.empty() );

  bank.pop();

  TEST_ASSERT( bank.empty() );
}

//---------------------------------------------------------------------------//
// Custom main function
//---------------------------------------------------------------------------//
int main( int argc, char** argv )
{
  Teuchos::CommandLineProcessor& clp = Teuchos::UnitTestRepository::getCLP();

  int threads = 1;

  clp.setOption( "threads",
		 &threads,
		 "Number of threads to use" );

  Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return =
    clp.parse(argc,argv);

  const Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();

  if ( parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) {
    *out << "\nEnd Result: TEST FAILED" << std::endl;
    return parse_return;
  }

  // Set up the global OpenMP session
  if( Utility::GlobalOpenMPSession::isOpenMPUsed() )
    Utility::GlobalOpenMPSession::setNumberOfThreads( threads );

  // Run the unit tests
  Teuchos::GlobalMPISession mpiSession( &argc, &argv );

  out->setProcRankAndSize( mpiSession.getRank(), mpiSession.getNProc() );
  out->setOutputToRootOnly( 0 );

  const bool success = Teuchos::UnitTestRepository::runUnitTests(*out);

  if (success)
    *out << "\nEnd Result: TEST PASSED" << std::endl;
  else
    *out << "\nEnd Result: TEST FAILED" << std::endl;

  clp.printFinalTimerSummary(out.ptr());

  return (success ? 0 : 1);
}

//---------------------------------------------------------------------------//
// end tstParticleBank.cpp
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>#include "misc.h"

/**
 * Returns a statm_t object containing information about memory usage.
 */
statm_t * memory_get_usage() {

  const char* statm_path = "/proc/self/statm";

  statm_t * result = (statm_t *) malloc(sizeof(statm_t));
  result->size = 0;
  result->resident = 0;
  result->share = 0;
  result->text = 0;
  result->lib = 0;
  result->data = 0;
  result->dt = 0;

  FILE *f = fopen(statm_path,"r");
  if(f){
    fscanf(f,"%ld %ld %ld %ld %ld %ld %ld",
      &result->size,
      &result->resident,
      &result->share,
      &result->text,
      &result->lib,
      &result->data,
      &result->dt
    );
    fclose(f);
  }
  return result;
}

/**
 *
 */
int is_numeric(char * string) {
  // ASCII value of
  // '-': 45
  // '.': 46
  // '0': 48
  // '9': 57
  int num_period = 0;
  unsigned int i;
  int good = 0;

  // all remaining characters can be numeric but with only one period
  for (i = 0; i < strlen(string); i++) {
    good = 0;
    if (string[i] >= 48 && string[i] <= 57) {
      good = 1;
    }
    // periods are acceptable, but only one.
    if (string[i] == 46) {
      num_period++;
      good = 1;
      // we can only have one period
      if (num_period > 1) {
        good = 0;
      }
    }
    // the minus sign is acceptable if it appears first
    if (string[i] == 45 && i == 0) {
      good = 1;
    }
    if (!good) {
      return 0;
    }
  }
  return 1;
}
<commit_msg>Fixed bug in checking if ematrix value is numeric<commit_after>#include "misc.h"

/**
 * Returns a statm_t object containing information about memory usage.
 */
statm_t * memory_get_usage() {

  const char* statm_path = "/proc/self/statm";

  statm_t * result = (statm_t *) malloc(sizeof(statm_t));
  result->size = 0;
  result->resident = 0;
  result->share = 0;
  result->text = 0;
  result->lib = 0;
  result->data = 0;
  result->dt = 0;

  FILE *f = fopen(statm_path,"r");
  if(f){
    fscanf(f,"%ld %ld %ld %ld %ld %ld %ld",
      &result->size,
      &result->resident,
      &result->share,
      &result->text,
      &result->lib,
      &result->data,
      &result->dt
    );
    fclose(f);
  }
  return result;
}

/**
 *
 */
int is_numeric(char * string) {
  // ASCII value of
  // '-': 45
  // '.': 46
  // '0': 48
  // '9': 57
  // 'e': 101
  int num_period = 0;
  unsigned int i;
  int good = 0;
  // the position of the e in scientific notation
  unsigned int epos = 0;

  // all remaining characters can be numeric but with only one period
  for (i = 0; i < strlen(string); i++) {
    good = 0;
    if (string[i] >= 48 && string[i] <= 57) {
      good = 1;
    }
    // periods are acceptable, but only one.
    if (string[i] == 46) {
      num_period++;
      good = 1;
      // we can only have one period
      if (num_period > 1) {
        good = 0;
      }
    }
    // the minus sign is acceptable if it appears first in the string or
    // after an e in scientific notation
    if (string[i] == 45) {
      if (i == 0) {
        good = 1;
      }
      if (i == epos + 1) {
        good = 1;
      }
    }
    if (string[i] == 101) {
      good = 1;
      epos = i;
    }
    if (!good) {
      return 0;
    }
  }
  return 1;
}
<|endoftext|>


<commit_before>/*
 * File:   DebugServer.cpp
 * Author: thomas
 *
 * Created on 10. September 2010, 15:38
 */

#include <string>
#include <stdlib.h>

#include <iostream>
#include <string.h>

#include "DebugServer.h"

DebugServer::DebugServer(unsigned int port)
: comm(port)
{
  commands = g_async_queue_new();
  answers = g_async_queue_new();

  g_async_queue_ref(commands);
  g_async_queue_ref(answers);

  if (g_thread_supported())
  {
    comm.init();

    GError* err = NULL;
    g_message("Starting debug server as two seperate threads (reader and writer)");
    readerThread = g_thread_create(reader_static, this, true, &err);
    writerThread = g_thread_create(writer_static, this, true, &err);

    registerCommand("help", "list available commands or get the description of a specific command", this);

  } else
  {
    g_warning("No threading support: DebugServer not available");
  }
}

void DebugServer::mainReader()
{
  g_message("Reader init");
  g_async_queue_ref(commands);

  g_message("Starting DebugServer reader loop");
  while (true)
  {
    char* msg = comm.readMessage();
    if (msg == NULL)
    {
      // error occured, we should empty the command queue (the answer queue is cleared by the writer)
      while (g_async_queue_length(commands) > 0)
      {
        char* tmp = (char*) g_async_queue_pop(commands);
        g_free(tmp);
      }
    } else
    {
      g_async_queue_push(commands, msg);
    }
    g_thread_yield();
  }
  g_async_queue_unref(commands);
}

void DebugServer::mainWriter()
{
  g_message("Writer init");
  g_async_queue_ref(answers);

  g_message("Starting DebugServer writer loop");
  while (true)
  {
    char* answer = (char*) g_async_queue_pop(answers);

    if (!comm.sendMessage(answer, strlen(answer) + 1))
    {
      // error, clear answer queue
      while (g_async_queue_length(answers) > 0)
      {
        char* tmp = (char*) g_async_queue_pop(answers);
        g_free(tmp);
      }
    }
    g_free(answer);
    g_thread_yield();
  }
  g_async_queue_unref(answers);
}

void DebugServer::execute()
{
  while (g_async_queue_length(commands) > 0)
  {
    char* cmdRaw = (char*) g_async_queue_pop(commands);

    GString* answer = g_string_new("");
    handleCommand(cmdRaw, answer);

    g_string_append(answer, "\r\n\0");

    g_async_queue_push(answers, g_string_free(answer, false));

    g_free(cmdRaw);
  }
}

void DebugServer::handleCommand(char* cmdRaw, GString* answer)
{
  // parse command
  GError* parseError = NULL;
  int argc;
  char** argv;
  g_shell_parse_argv(cmdRaw, &argc, &argv, &parseError);

  if (parseError)
  {
    g_string_append(answer, "parsing error: ");
    g_string_append(answer, parseError->message);
  } else
  {
    std::map<std::string, std::string> arguments;
    std::string commandName = "";
    // iterate over the command parts and build up the arguments as map
    bool answerAsBase64 = false;
    // command name
    if (argc > 0)
    {

      if (g_str_has_prefix(argv[0], "+"))
      {
        answerAsBase64 = true;
        commandName.assign(argv[0] + 1);
      } else
      {
        answerAsBase64 = false;
        commandName.assign(argv[0]);
      }
    }
    // argument names and if existings their values
    std::string lastKey;
    bool nextIsValue = false;
    bool valueIsBase64 = false;
    for (int i = 1; i < argc; i++)
    {
      if (nextIsValue)
      {
        if (lastKey != "")
        {
          if (valueIsBase64)
          {
            size_t len;
            char* decoded = (char*) g_base64_decode(argv[i], &len);
            arguments[lastKey].assign(decoded);
            g_free(decoded);
          } else
          {
            arguments[lastKey].assign(argv[i]);
          }
        }

        lastKey.assign("");
        nextIsValue = false;
      } else
      {
        if (g_str_has_prefix(argv[i], "-"))
        {
          nextIsValue = true;
          valueIsBase64 = false;

          lastKey.assign(argv[i] + 1);
        } else if (g_str_has_prefix(argv[i], "+"))
        {
          nextIsValue = true;
          valueIsBase64 = true;

          lastKey.assign(argv[i] + 1);
        } else
        {
          nextIsValue = false;
          lastKey.assign(argv[i]);
        }
        arguments[lastKey] = "";

      }
    }

    g_strfreev(argv);

    handleCommand(commandName, arguments, answer, answerAsBase64);

  }

}

void DebugServer::handleCommand(std::string command, std::map<std::string,
  std::string> arguments, GString* answer, bool encodeBase64)
{

  std::stringstream answerFromHandler;
  if (executorMap.find(command) != executorMap.end())
  {
    executorMap[command]->executeDebugCommand(command, arguments, answerFromHandler);
  } else
  {
    answerFromHandler << "Unknown command \"" << command
      << "\", use \"help\" for a list of available commands";
  }

  if (encodeBase64)
  {
    char* encoded = g_base64_encode((guchar*) answerFromHandler.str().c_str(),
      answerFromHandler.str().length());
    g_string_append(answer, encoded);
    g_free(encoded);
  } else
  {
    g_string_append(answer, answerFromHandler.str().c_str());
  }

}

bool DebugServer::registerCommand(std::string command, std::string description,
  DebugCommandExecutor* executor)
{
  if (executorMap.find(command) == executorMap.end())
  {
    // new command
    executorMap[command] = executor;
    descriptionMap[command] = description;
    return true;
  }
  return false;
}

void DebugServer::objectDestructed(DebugCommandExecutor* object)
{
  std::list<std::string> registeredKeys;

  // search all registered keys of the object
  std::map<std::string, DebugCommandExecutor*>::const_iterator iter;
  for (iter = executorMap.begin(); iter != executorMap.end(); iter++)
  {
    if ((*iter).second == object)
    {
      registeredKeys.push_back((*iter).first);
    }//end if
  }//end for

  // unregister all found commands
  std::list<std::string>::const_iterator iter_key;
  for (iter_key = registeredKeys.begin(); iter_key != registeredKeys.end(); iter_key++)
  {
    executorMap.erase(*iter_key);

    std::cout << "[DebugServer] " << "unregistering command "
      << (*iter_key) << std::endl;
  }//end for
}

void DebugServer::executeDebugCommand(const std::string& command, const std::map<std::string, std::string>& arguments,
  std::stringstream& out)
{
  if (command == "help")
  {
    if (arguments.empty())
    {
      // list all available commands
      out << "Available commands, use \"help <command>\" for a description:\n";
      std::map<std::string, std::string>::const_iterator iter = descriptionMap.begin();
      while (iter != descriptionMap.end())
      {
        out << iter->first;
        iter++;
        if (iter != descriptionMap.end())
        {
          out << ", ";
        }
      }
    } else
    {
      std::string firstArg = arguments.begin()->first;
      if (descriptionMap.find(firstArg) != descriptionMap.end())
      {
        out << firstArg << "\n";
        out << "------------------\n";
        out << descriptionMap[firstArg];
        out << "\n";
      } else
      {
        out << "Unknown command \"" << firstArg
          << "\", use \"help\" for a list of available commands";
      }

    }
  }
}

void* DebugServer::reader_static(void* ref)
{
  ((DebugServer*) ref)->mainReader();
  return NULL;
}

void* DebugServer::writer_static(void* ref)
{
  ((DebugServer*) ref)->mainWriter();
  return NULL;
}

DebugServer::~DebugServer()
{
  g_free(readerThread);
  g_free(writerThread);
  g_async_queue_unref(commands);
  g_async_queue_unref(answers);
}

<commit_msg>added destruction listener to unregister destroyed commands<commit_after>/*
 * File:   DebugServer.cpp
 * Author: thomas
 *
 * Created on 10. September 2010, 15:38
 */

#include <string>
#include <stdlib.h>

#include <iostream>
#include <string.h>

#include "DebugServer.h"

DebugServer::DebugServer(unsigned int port)
: comm(port)
{
  commands = g_async_queue_new();
  answers = g_async_queue_new();

  g_async_queue_ref(commands);
  g_async_queue_ref(answers);

  if (g_thread_supported())
  {
    comm.init();

    GError* err = NULL;
    g_message("Starting debug server as two seperate threads (reader and writer)");
    readerThread = g_thread_create(reader_static, this, true, &err);
    writerThread = g_thread_create(writer_static, this, true, &err);

    registerCommand("help", "list available commands or get the description of a specific command", this);

  } else
  {
    g_warning("No threading support: DebugServer not available");
  }
}

void DebugServer::mainReader()
{
  g_message("Reader init");
  g_async_queue_ref(commands);

  g_message("Starting DebugServer reader loop");
  while (true)
  {
    char* msg = comm.readMessage();
    if (msg == NULL)
    {
      // error occured, we should empty the command queue (the answer queue is cleared by the writer)
      while (g_async_queue_length(commands) > 0)
      {
        char* tmp = (char*) g_async_queue_pop(commands);
        g_free(tmp);
      }
    } else
    {
      g_async_queue_push(commands, msg);
    }
    g_thread_yield();
  }
  g_async_queue_unref(commands);
}

void DebugServer::mainWriter()
{
  g_message("Writer init");
  g_async_queue_ref(answers);

  g_message("Starting DebugServer writer loop");
  while (true)
  {
    char* answer = (char*) g_async_queue_pop(answers);

    if (!comm.sendMessage(answer, strlen(answer) + 1))
    {
      // error, clear answer queue
      while (g_async_queue_length(answers) > 0)
      {
        char* tmp = (char*) g_async_queue_pop(answers);
        g_free(tmp);
      }
    }
    g_free(answer);
    g_thread_yield();
  }
  g_async_queue_unref(answers);
}

void DebugServer::execute()
{
  while (g_async_queue_length(commands) > 0)
  {
    char* cmdRaw = (char*) g_async_queue_pop(commands);

    GString* answer = g_string_new("");
    handleCommand(cmdRaw, answer);

    g_string_append(answer, "\r\n\0");

    g_async_queue_push(answers, g_string_free(answer, false));

    g_free(cmdRaw);
  }
}

void DebugServer::handleCommand(char* cmdRaw, GString* answer)
{
  // parse command
  GError* parseError = NULL;
  int argc;
  char** argv;
  g_shell_parse_argv(cmdRaw, &argc, &argv, &parseError);

  if (parseError)
  {
    g_string_append(answer, "parsing error: ");
    g_string_append(answer, parseError->message);
  } else
  {
    std::map<std::string, std::string> arguments;
    std::string commandName = "";
    // iterate over the command parts and build up the arguments as map
    bool answerAsBase64 = false;
    // command name
    if (argc > 0)
    {

      if (g_str_has_prefix(argv[0], "+"))
      {
        answerAsBase64 = true;
        commandName.assign(argv[0] + 1);
      } else
      {
        answerAsBase64 = false;
        commandName.assign(argv[0]);
      }
    }
    // argument names and if existings their values
    std::string lastKey;
    bool nextIsValue = false;
    bool valueIsBase64 = false;
    for (int i = 1; i < argc; i++)
    {
      if (nextIsValue)
      {
        if (lastKey != "")
        {
          if (valueIsBase64)
          {
            size_t len;
            char* decoded = (char*) g_base64_decode(argv[i], &len);
            arguments[lastKey].assign(decoded);
            g_free(decoded);
          } else
          {
            arguments[lastKey].assign(argv[i]);
          }
        }

        lastKey.assign("");
        nextIsValue = false;
      } else
      {
        if (g_str_has_prefix(argv[i], "-"))
        {
          nextIsValue = true;
          valueIsBase64 = false;

          lastKey.assign(argv[i] + 1);
        } else if (g_str_has_prefix(argv[i], "+"))
        {
          nextIsValue = true;
          valueIsBase64 = true;

          lastKey.assign(argv[i] + 1);
        } else
        {
          nextIsValue = false;
          lastKey.assign(argv[i]);
        }
        arguments[lastKey] = "";

      }
    }

    g_strfreev(argv);

    handleCommand(commandName, arguments, answer, answerAsBase64);

  }

}

void DebugServer::handleCommand(std::string command, std::map<std::string,
  std::string> arguments, GString* answer, bool encodeBase64)
{

  std::stringstream answerFromHandler;
  if (executorMap.find(command) != executorMap.end())
  {
    executorMap[command]->executeDebugCommand(command, arguments, answerFromHandler);
  } else
  {
    answerFromHandler << "Unknown command \"" << command
      << "\", use \"help\" for a list of available commands";
  }

  if (encodeBase64)
  {
    char* encoded = g_base64_encode((guchar*) answerFromHandler.str().c_str(),
      answerFromHandler.str().length());
    g_string_append(answer, encoded);
    g_free(encoded);
  } else
  {
    g_string_append(answer, answerFromHandler.str().c_str());
  }

}//end handleCommand

bool DebugServer::registerCommand(std::string command, std::string description,
  DebugCommandExecutor* executor)
{
  if (executorMap.find(command) == executorMap.end())
  {
    // new command
    executorMap[command] = executor;
    descriptionMap[command] = description;
    executor->registerDestructionListener(*this);
    return true;
  }
  return false;
}//end registerCommand

void DebugServer::objectDestructed(DebugCommandExecutor* object)
{
  std::list<std::string> registeredKeys;

  // search all registered keys of the object
  std::map<std::string, DebugCommandExecutor*>::const_iterator iter;
  for (iter = executorMap.begin(); iter != executorMap.end(); iter++)
  {
    if ((*iter).second == object)
    {
      registeredKeys.push_back((*iter).first);
    }//end if
  }//end for

  // unregister all found commands
  std::list<std::string>::const_iterator iter_key;
  for (iter_key = registeredKeys.begin(); iter_key != registeredKeys.end(); iter_key++)
  {
    executorMap.erase(*iter_key);

    std::cout << "[DebugServer] " << "unregistering command "
      << (*iter_key) << std::endl;
  }//end for
}

void DebugServer::executeDebugCommand(const std::string& command, const std::map<std::string, std::string>& arguments,
  std::stringstream& out)
{
  if (command == "help")
  {
    if (arguments.empty())
    {
      // list all available commands
      out << "Available commands, use \"help <command>\" for a description:\n";
      std::map<std::string, std::string>::const_iterator iter = descriptionMap.begin();
      while (iter != descriptionMap.end())
      {
        out << iter->first;
        iter++;
        if (iter != descriptionMap.end())
        {
          out << ", ";
        }
      }
    } else
    {
      std::string firstArg = arguments.begin()->first;
      if (descriptionMap.find(firstArg) != descriptionMap.end())
      {
        out << firstArg << "\n";
        out << "------------------\n";
        out << descriptionMap[firstArg];
        out << "\n";
      } else
      {
        out << "Unknown command \"" << firstArg
          << "\", use \"help\" for a list of available commands";
      }

    }
  }
}

void* DebugServer::reader_static(void* ref)
{
  ((DebugServer*) ref)->mainReader();
  return NULL;
}

void* DebugServer::writer_static(void* ref)
{
  ((DebugServer*) ref)->mainWriter();
  return NULL;
}

DebugServer::~DebugServer()
{
  g_free(readerThread);
  g_free(writerThread);
  g_async_queue_unref(commands);
  g_async_queue_unref(answers);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ZipPackageBuffer.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: mtg $ $Date: 2001-04-19 14:16:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _ZIP_PACKAGE_BUFFER_HXX
#include <ZipPackageBuffer.hxx>
#endif

using namespace com::sun::star::uno;
using namespace com::sun::star::io;

ZipPackageBuffer::ZipPackageBuffer(sal_Int64 nNewBufferSize)
: nBufferSize (nNewBufferSize)
, aBuffer (static_cast < sal_Int32 > (nNewBufferSize))
, nCurrent(0)
, nEnd(0)
{
}
ZipPackageBuffer::~ZipPackageBuffer(void)
{
}
Any SAL_CALL  ZipPackageBuffer::queryInterface( const Type& rType )
        throw(RuntimeException)
{
    return ::cppu::queryInterface ( rType                                       ,
                                        // OWeakObject interfaces
                                        reinterpret_cast< XInterface*       > ( this )  ,
                                        static_cast< XWeak*         > ( this )  ,
                                        // my interfaces
                                        static_cast< XInputStream*      > ( this )  ,
                                        static_cast< XSeekable*     > ( this )  ,
                                        static_cast< XOutputStream*     > ( this ) );

}
void SAL_CALL  ZipPackageBuffer::acquire(void)
    throw()
{
    OWeakObject::acquire();
}
void SAL_CALL  ZipPackageBuffer::release(void)
    throw()
{
    OWeakObject::release();
}
sal_Int32 SAL_CALL ZipPackageBuffer::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    //const sal_Int8 *pBuffer = aBuffer.getConstArray()+nCurrent;

    if (nBytesToRead < 0)
        throw BufferSizeExceededException(::rtl::OUString(),*this);

    if (nBytesToRead + nCurrent > nEnd)
        nBytesToRead = static_cast < sal_Int32 > (nEnd - nCurrent);

    memcpy(aData.getArray(), aBuffer.getConstArray() + nCurrent, nBytesToRead);
    nCurrent +=nBytesToRead;
    return nBytesToRead;
    //aData.realloc(nBytesToRead);
    //memcpy(aData.getArray(), pBuffer + nCurrent, nBytesToRead);
    //memcpy(pData, pBuffer, nBytesToRead);

    // Optimisations for often called cases
    /*
    switch (nBytesToRead)
    {
        case 0:
            return 0;
        case 1:
            *(pData++)    = *pBuffer;
            nCurrent +=1;
            return 1;
        case 2:
            *(pData++)   = *(pBuffer++);
            * pData      = *pBuffer;
            nCurrent +=2;
            return 2;
        case 4:
            *(pData++) = *(pBuffer++);
            *(pData++) = *(pBuffer++);
            *(pData++) = *(pBuffer++);
            * pData    = * pBuffer;
            nCurrent +=4;
            return 4;
        default:
            memcpy(pData, pBuffer, nBytesToRead);
            nCurrent +=nBytesToRead;
            return nBytesToRead;
    }
    //return nBytesToRead;
    */
}

sal_Int32 SAL_CALL ZipPackageBuffer::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    /*
    if (nMaxBytesToRead + nCurrent > nEnd)
        nMaxBytesToRead = nEnd - nCurrent;
    sal_Int64 nEndRead = nMaxBytesToRead+nCurrent;

    for (sal_Int64 i =0; nCurrent < nEndRead; nCurrent++, i++)
        aData[i] = aBuffer[nCurrent];
    return nMaxBytesToRead;
    */

    // all data is available at once
    return readBytes(aData, nMaxBytesToRead);
}
void SAL_CALL ZipPackageBuffer::skipBytes( sal_Int32 nBytesToSkip )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    if (nBytesToSkip < 0)
        throw BufferSizeExceededException(::rtl::OUString(),*this);

    if (nBytesToSkip + nCurrent > nEnd)
        nBytesToSkip = static_cast < sal_Int32 > (nEnd - nCurrent);

    nCurrent+=nBytesToSkip;
}
sal_Int32 SAL_CALL ZipPackageBuffer::available(  )
        throw(NotConnectedException, IOException, RuntimeException)
{
    return static_cast < sal_Int32 > (nEnd - nCurrent);
}
void SAL_CALL ZipPackageBuffer::closeInput(  )
        throw(NotConnectedException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::writeBytes( const Sequence< sal_Int8 >& aData )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    sal_Int64 nDataLen = aData.getLength();
    const sal_Int8 *pData   = aData.getConstArray();

    if (nEnd + nDataLen > nBufferSize)
    {
        while (nEnd + nDataLen > nBufferSize)
            nBufferSize *=2;
        aBuffer.realloc(static_cast < sal_Int32 > (nBufferSize));
    }
    /*
    sal_Int8 *pBuffer = aBuffer.getArray()+nCurrent;
    switch (nDataLen)
    {
        case 0:
            break;
        case 1:
            * pBuffer    = *pData;
            nCurrent++;
            break;
        case 2:
            *(pBuffer++) = *(pData++);
            * pBuffer    = * pData   ;
            nCurrent +=2;
            break;
        case 4:
            *(pBuffer++) = *(pData++);
            *(pBuffer++) = *(pData++);
            *(pBuffer++) = *(pData++);
            * pBuffer    = * pData   ;
            nCurrent +=4;
            break;
        default:
            memcpy(pBuffer, pData, static_cast < sal_Int32 > (nDataLen));
            nCurrent += nDataLen;
            break;
    }
    */
    //memcpy( pBuffer + nCurrent, aData.getConstArray(), static_cast < sal_Int32 > (nDataLen));
    memcpy( aBuffer.getArray() + nCurrent, aData.getConstArray(), static_cast < sal_Int32 > (nDataLen));
    nCurrent+=nDataLen;
    if (nCurrent>nEnd)
        nEnd = nCurrent;
}
void SAL_CALL ZipPackageBuffer::flush(  )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::closeOutput(  )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::seek( sal_Int64 location )
        throw(::com::sun::star::lang::IllegalArgumentException, IOException, RuntimeException)
{
    nCurrent = location;
}
sal_Int64 SAL_CALL ZipPackageBuffer::getPosition(  )
        throw(IOException, RuntimeException)
{
    return nCurrent;
}
sal_Int64 SAL_CALL ZipPackageBuffer::getLength(  )
        throw(IOException, RuntimeException)
{
    return nEnd;
}
<commit_msg>readBytes is responsible for reallocing the calling stream<commit_after>/*************************************************************************
 *
 *  $RCSfile: ZipPackageBuffer.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-15 13:05:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _ZIP_PACKAGE_BUFFER_HXX
#include <ZipPackageBuffer.hxx>
#endif

using namespace com::sun::star::uno;
using namespace com::sun::star::io;

ZipPackageBuffer::ZipPackageBuffer(sal_Int64 nNewBufferSize)
: nBufferSize (nNewBufferSize)
, aBuffer (static_cast < sal_Int32 > (nNewBufferSize))
, nCurrent(0)
, nEnd(0)
{
}
ZipPackageBuffer::~ZipPackageBuffer(void)
{
}
Any SAL_CALL  ZipPackageBuffer::queryInterface( const Type& rType )
        throw(RuntimeException)
{
    return ::cppu::queryInterface ( rType                                       ,
                                        // OWeakObject interfaces
                                        reinterpret_cast< XInterface*       > ( this )  ,
                                        static_cast< XWeak*         > ( this )  ,
                                        // my interfaces
                                        static_cast< XInputStream*      > ( this )  ,
                                        static_cast< XSeekable*     > ( this )  ,
                                        static_cast< XOutputStream*     > ( this ) );

}
void SAL_CALL  ZipPackageBuffer::acquire(void)
    throw()
{
    OWeakObject::acquire();
}
void SAL_CALL  ZipPackageBuffer::release(void)
    throw()
{
    OWeakObject::release();
}
sal_Int32 SAL_CALL ZipPackageBuffer::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    //const sal_Int8 *pBuffer = aBuffer.getConstArray()+nCurrent;

    if (nBytesToRead < 0)
        throw BufferSizeExceededException(::rtl::OUString(),*this);

    if (nBytesToRead + nCurrent > nEnd)
        nBytesToRead = static_cast < sal_Int32 > (nEnd - nCurrent);

    aData.realloc ( nBytesToRead );
    memcpy(aData.getArray(), aBuffer.getConstArray() + nCurrent, nBytesToRead);
    nCurrent +=nBytesToRead;
    return nBytesToRead;
    //aData.realloc(nBytesToRead);
    //memcpy(aData.getArray(), pBuffer + nCurrent, nBytesToRead);
    //memcpy(pData, pBuffer, nBytesToRead);

    // Optimisations for often called cases
    /*
    switch (nBytesToRead)
    {
        case 0:
            return 0;
        case 1:
            *(pData++)    = *pBuffer;
            nCurrent +=1;
            return 1;
        case 2:
            *(pData++)   = *(pBuffer++);
            * pData      = *pBuffer;
            nCurrent +=2;
            return 2;
        case 4:
            *(pData++) = *(pBuffer++);
            *(pData++) = *(pBuffer++);
            *(pData++) = *(pBuffer++);
            * pData    = * pBuffer;
            nCurrent +=4;
            return 4;
        default:
            memcpy(pData, pBuffer, nBytesToRead);
            nCurrent +=nBytesToRead;
            return nBytesToRead;
    }
    //return nBytesToRead;
    */
}

sal_Int32 SAL_CALL ZipPackageBuffer::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    /*
    if (nMaxBytesToRead + nCurrent > nEnd)
        nMaxBytesToRead = nEnd - nCurrent;
    sal_Int64 nEndRead = nMaxBytesToRead+nCurrent;

    for (sal_Int64 i =0; nCurrent < nEndRead; nCurrent++, i++)
        aData[i] = aBuffer[nCurrent];
    return nMaxBytesToRead;
    */

    // all data is available at once
    return readBytes(aData, nMaxBytesToRead);
}
void SAL_CALL ZipPackageBuffer::skipBytes( sal_Int32 nBytesToSkip )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    if (nBytesToSkip < 0)
        throw BufferSizeExceededException(::rtl::OUString(),*this);

    if (nBytesToSkip + nCurrent > nEnd)
        nBytesToSkip = static_cast < sal_Int32 > (nEnd - nCurrent);

    nCurrent+=nBytesToSkip;
}
sal_Int32 SAL_CALL ZipPackageBuffer::available(  )
        throw(NotConnectedException, IOException, RuntimeException)
{
    return static_cast < sal_Int32 > (nEnd - nCurrent);
}
void SAL_CALL ZipPackageBuffer::closeInput(  )
        throw(NotConnectedException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::writeBytes( const Sequence< sal_Int8 >& aData )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    sal_Int64 nDataLen = aData.getLength();
    const sal_Int8 *pData   = aData.getConstArray();

    if (nEnd + nDataLen > nBufferSize)
    {
        while (nEnd + nDataLen > nBufferSize)
            nBufferSize *=2;
        aBuffer.realloc(static_cast < sal_Int32 > (nBufferSize));
    }
    /*
    sal_Int8 *pBuffer = aBuffer.getArray()+nCurrent;
    switch (nDataLen)
    {
        case 0:
            break;
        case 1:
            * pBuffer    = *pData;
            nCurrent++;
            break;
        case 2:
            *(pBuffer++) = *(pData++);
            * pBuffer    = * pData   ;
            nCurrent +=2;
            break;
        case 4:
            *(pBuffer++) = *(pData++);
            *(pBuffer++) = *(pData++);
            *(pBuffer++) = *(pData++);
            * pBuffer    = * pData   ;
            nCurrent +=4;
            break;
        default:
            memcpy(pBuffer, pData, static_cast < sal_Int32 > (nDataLen));
            nCurrent += nDataLen;
            break;
    }
    */
    //memcpy( pBuffer + nCurrent, aData.getConstArray(), static_cast < sal_Int32 > (nDataLen));
    memcpy( aBuffer.getArray() + nCurrent, aData.getConstArray(), static_cast < sal_Int32 > (nDataLen));
    nCurrent+=nDataLen;
    if (nCurrent>nEnd)
        nEnd = nCurrent;
}
void SAL_CALL ZipPackageBuffer::flush(  )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::closeOutput(  )
        throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
}
void SAL_CALL ZipPackageBuffer::seek( sal_Int64 location )
        throw(::com::sun::star::lang::IllegalArgumentException, IOException, RuntimeException)
{
    nCurrent = location;
}
sal_Int64 SAL_CALL ZipPackageBuffer::getPosition(  )
        throw(IOException, RuntimeException)
{
    return nCurrent;
}
sal_Int64 SAL_CALL ZipPackageBuffer::getLength(  )
        throw(IOException, RuntimeException)
{
    return nEnd;
}
<|endoftext|>