<commit_before>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/core/api/flatbuffer_conversions.h"
#include "tensorflow/lite/core/api/tensor_utils.h"
#include "tensorflow/lite/micro/compatibility.h"
#include "tensorflow/lite/micro/micro_allocator.h"
#include "tensorflow/lite/micro/micro_optional_debug_tools.h"

namespace tflite {
namespace {

const char* OpNameFromRegistration(const TfLiteRegistration* registration) {
  if (registration->builtin_code == BuiltinOperator_CUSTOM) {
    return registration->custom_name;
  } else {
    return EnumNameBuiltinOperator(BuiltinOperator(registration->builtin_code));
  }
}

}  // namespace

namespace internal {

TfLiteStatus ContextHelper::AllocatePersistentBuffer(TfLiteContext* ctx,
                                                     size_t bytes, void** ptr) {
  return reinterpret_cast<ContextHelper*>(ctx->impl_)
      ->allocator_->AllocatePersistentBuffer(bytes, ptr);
}

TfLiteStatus ContextHelper::RequestScratchBufferInArena(TfLiteContext* ctx,
                                                        size_t bytes,
                                                        int* buffer_idx) {
  ContextHelper* helper = reinterpret_cast<ContextHelper*>(ctx->impl_);
  return helper->allocator_->RequestScratchBufferInArena(
      helper->current_node_idx_, bytes, buffer_idx);
}

void* ContextHelper::GetScratchBuffer(TfLiteContext* ctx, int buffer_idx) {
  return reinterpret_cast<ContextHelper*>(ctx->impl_)
      ->allocator_->GetScratchBuffer(buffer_idx);
}

void ContextHelper::ReportOpError(struct TfLiteContext* context,
                                  const char* format, ...) {
  ContextHelper* helper = static_cast<ContextHelper*>(context->impl_);
  va_list args;
  va_start(args, format);
  TF_LITE_REPORT_ERROR(helper->error_reporter_, format, args);
  va_end(args);
}

}  // namespace internal

MicroInterpreter::MicroInterpreter(const Model* model,
                                   const OpResolver& op_resolver,
                                   uint8_t* tensor_arena,
                                   size_t tensor_arena_size,
                                   ErrorReporter* error_reporter)
    : model_(model),
      op_resolver_(op_resolver),
      error_reporter_(error_reporter),
      allocator_(&context_, model_, tensor_arena, tensor_arena_size,
                 error_reporter_),
      tensors_allocated_(false),
      context_helper_(error_reporter_, &allocator_) {
  const flatbuffers::Vector<flatbuffers::Offset<SubGraph>>* subgraphs =
      model->subgraphs();
  if (subgraphs->size() != 1) {
    TF_LITE_REPORT_ERROR(error_reporter,
                         "Only 1 subgraph is currently supported.\n");
    initialization_status_ = kTfLiteError;
    return;
  }
  subgraph_ = (*subgraphs)[0];
  tensors_ = subgraph_->tensors();
  operators_ = subgraph_->operators();

  context_.impl_ = static_cast<void*>(&context_helper_);
  context_.ReportError = context_helper_.ReportOpError;
  context_.recommended_num_threads = 1;

  // If the system is big endian then convert weights from the flatbuffer from
  // little to big endian on startup so that it does not need to be done during
  // inference.
  // NOTE: This requires that the flatbuffer is held in memory which can be
  // modified by this process.
  if (!FLATBUFFERS_LITTLEENDIAN) {
    for (size_t t = 0; t < tensors_size(); ++t) {
      TfLiteTensor* thisTensor = &context_.tensors[t];
      if (thisTensor->allocation_type == kTfLiteMmapRo)
        CorrectTensorEndianness(thisTensor);
    }
  }

  initialization_status_ = kTfLiteOk;
}

MicroInterpreter::~MicroInterpreter() {
  if (node_and_registrations_ != nullptr) {
    for (size_t i = 0; i < operators_->size(); ++i) {
      TfLiteNode* node = &(node_and_registrations_[i].node);
      const TfLiteRegistration* registration =
          node_and_registrations_[i].registration;
      // registration is allocated outside the interpreter, so double check to
      // make sure it's not nullptr;
      if (registration != nullptr && registration->free != nullptr) {
        registration->free(&context_, node->user_data);
      }
    }
  }
}

void MicroInterpreter::CorrectTensorEndianness(TfLiteTensor* tensorCorr) {
  int32_t tensorSize = 1;
  for (int d = 0; d < tensorCorr->dims->size; ++d)
    tensorSize *= reinterpret_cast<const int32_t*>(tensorCorr->dims->data)[d];

  switch (tensorCorr->type) {
    case TfLiteType::kTfLiteFloat32:
      CorrectTensorDataEndianness(tensorCorr->data.f, tensorSize);
      break;
    case TfLiteType::kTfLiteFloat16:
      CorrectTensorDataEndianness(tensorCorr->data.f16, tensorSize);
      break;
    case TfLiteType::kTfLiteInt64:
      CorrectTensorDataEndianness(tensorCorr->data.i64, tensorSize);
      break;
    case TfLiteType::kTfLiteInt32:
      CorrectTensorDataEndianness(tensorCorr->data.i32, tensorSize);
      break;
    case TfLiteType::kTfLiteInt16:
      CorrectTensorDataEndianness(tensorCorr->data.i16, tensorSize);
      break;
    case TfLiteType::kTfLiteComplex64:
      CorrectTensorDataEndianness(tensorCorr->data.c64, tensorSize);
      break;
    default:
      // Do nothing for other data types.
      break;
  }
}

template <class T>
void MicroInterpreter::CorrectTensorDataEndianness(T* data, int32_t size) {
  for (int32_t i = 0; i < size; ++i) {
    data[i] = flatbuffers::EndianScalar(data[i]);
  }
}

TfLiteStatus MicroInterpreter::AllocateTensors() {
  TF_LITE_ENSURE_OK(&context_, allocator_.AllocateNodeAndRegistrations(
                                   op_resolver_, &node_and_registrations_));

  // Only allow AllocatePersistentBuffer in Init stage.
  context_.AllocatePersistentBuffer = context_helper_.AllocatePersistentBuffer;
  context_.RequestScratchBufferInArena = nullptr;
  context_.GetScratchBuffer = nullptr;

  for (size_t i = 0; i < operators_->size(); ++i) {
    context_helper_.SetNodeIndex(i);
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;
    size_t init_data_size;
    const char* init_data;
    if (registration->builtin_code == BuiltinOperator_CUSTOM) {
      init_data = reinterpret_cast<const char*>(node->custom_initial_data);
      init_data_size = node->custom_initial_data_size;
    } else {
      init_data = reinterpret_cast<const char*>(node->builtin_data);
      init_data_size = 0;
    }
    if (registration->init) {
      node->user_data =
          registration->init(&context_, init_data, init_data_size);
    }
  }
  context_helper_.SetNodeIndex(-1);

  // Both AllocatePersistentBuffer and RequestScratchBufferInArena is available
  // in Prepare stage.
  context_.RequestScratchBufferInArena =
      context_helper_.RequestScratchBufferInArena;
  for (size_t i = 0; i < operators_->size(); ++i) {
    // Set node idx to annotate the lifetime for scratch buffers.
    context_helper_.SetNodeIndex(i);
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;
    if (registration->prepare) {
      TfLiteStatus prepare_status = registration->prepare(&context_, node);
      if (prepare_status != kTfLiteOk) {
        TF_LITE_REPORT_ERROR(
            error_reporter_,
            "Node %s (number %df) failed to prepare with status %d",
            OpNameFromRegistration(registration), i, prepare_status);
        return kTfLiteError;
      }
    }
  }
  context_helper_.SetNodeIndex(-1);

  // Prepare is done, we're ready for Invoke. Memory allocation is no longer
  // allowed. Kernels can only fetch scratch buffers via GetScratchBuffer.
  context_.AllocatePersistentBuffer = nullptr;
  context_.RequestScratchBufferInArena = nullptr;
  context_.GetScratchBuffer = context_helper_.GetScratchBuffer;

  TF_LITE_ENSURE_OK(&context_, allocator_.FinishTensorAllocation());
  tensors_allocated_ = true;
  return kTfLiteOk;
}
TfLiteStatus MicroInterpreter::Invoke() {
  if (initialization_status_ != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Invoke() called after initialization failed\n");
    return kTfLiteError;
  }

  // Ensure tensors are allocated before the interpreter is invoked to avoid
  // difficult to debug segfaults.
  if (!tensors_allocated_) {
    TF_LITE_ENSURE_OK(&context_, AllocateTensors());
  }

  for (size_t i = 0; i < operators_->size(); ++i) {
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;

    if (registration->invoke) {
      TfLiteStatus invoke_status = registration->invoke(&context_, node);
      if (invoke_status == kTfLiteError) {
        TF_LITE_REPORT_ERROR(
            error_reporter_,
            "Node %s (number %d) failed to invoke with status %d",
            OpNameFromRegistration(registration), i, invoke_status);
        return kTfLiteError;
      } else if (invoke_status != kTfLiteOk) {
        return invoke_status;
      }
    }
  }
  return kTfLiteOk;
}

TfLiteTensor* MicroInterpreter::input(size_t index) {
  const size_t length = inputs_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Input index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &(context_.tensors[inputs().Get(index)]);
}

TfLiteTensor* MicroInterpreter::output(size_t index) {
  const size_t length = outputs_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Output index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &(context_.tensors[outputs().Get(index)]);
}

TfLiteTensor* MicroInterpreter::tensor(size_t index) {
  const size_t length = tensors_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Tensor index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &context_.tensors[index];
}

TfLiteStatus MicroInterpreter::ResetVariableTensors() {
  const size_t length = tensors_size();
  for (size_t i = 0; i < length; ++i) {
    TfLiteTensor* cur_tensor = tensor(i);
    if (cur_tensor->is_variable) {
      TfLiteStatus status = tflite::ResetVariableTensor(cur_tensor);
      if (status != kTfLiteOk) {
        TF_LITE_REPORT_ERROR(error_reporter_,
                             "Failed to reset variable tensor at index: %d", i);
        return status;
      }
    }
  }
  return kTfLiteOk;
}

}  // namespace tflite
<commit_msg>Whitespace fix in micro_interpreter.cc<commit_after>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/core/api/flatbuffer_conversions.h"
#include "tensorflow/lite/core/api/tensor_utils.h"
#include "tensorflow/lite/micro/compatibility.h"
#include "tensorflow/lite/micro/micro_allocator.h"
#include "tensorflow/lite/micro/micro_optional_debug_tools.h"

namespace tflite {
namespace {

const char* OpNameFromRegistration(const TfLiteRegistration* registration) {
  if (registration->builtin_code == BuiltinOperator_CUSTOM) {
    return registration->custom_name;
  } else {
    return EnumNameBuiltinOperator(BuiltinOperator(registration->builtin_code));
  }
}

}  // namespace

namespace internal {

TfLiteStatus ContextHelper::AllocatePersistentBuffer(TfLiteContext* ctx,
                                                     size_t bytes, void** ptr) {
  return reinterpret_cast<ContextHelper*>(ctx->impl_)
      ->allocator_->AllocatePersistentBuffer(bytes, ptr);
}

TfLiteStatus ContextHelper::RequestScratchBufferInArena(TfLiteContext* ctx,
                                                        size_t bytes,
                                                        int* buffer_idx) {
  ContextHelper* helper = reinterpret_cast<ContextHelper*>(ctx->impl_);
  return helper->allocator_->RequestScratchBufferInArena(
      helper->current_node_idx_, bytes, buffer_idx);
}

void* ContextHelper::GetScratchBuffer(TfLiteContext* ctx, int buffer_idx) {
  return reinterpret_cast<ContextHelper*>(ctx->impl_)
      ->allocator_->GetScratchBuffer(buffer_idx);
}

void ContextHelper::ReportOpError(struct TfLiteContext* context,
                                  const char* format, ...) {
  ContextHelper* helper = static_cast<ContextHelper*>(context->impl_);
  va_list args;
  va_start(args, format);
  TF_LITE_REPORT_ERROR(helper->error_reporter_, format, args);
  va_end(args);
}

}  // namespace internal

MicroInterpreter::MicroInterpreter(const Model* model,
                                   const OpResolver& op_resolver,
                                   uint8_t* tensor_arena,
                                   size_t tensor_arena_size,
                                   ErrorReporter* error_reporter)
    : model_(model),
      op_resolver_(op_resolver),
      error_reporter_(error_reporter),
      allocator_(&context_, model_, tensor_arena, tensor_arena_size,
                 error_reporter_),
      tensors_allocated_(false),
      context_helper_(error_reporter_, &allocator_) {
  const flatbuffers::Vector<flatbuffers::Offset<SubGraph>>* subgraphs =
      model->subgraphs();
  if (subgraphs->size() != 1) {
    TF_LITE_REPORT_ERROR(error_reporter,
                         "Only 1 subgraph is currently supported.\n");
    initialization_status_ = kTfLiteError;
    return;
  }
  subgraph_ = (*subgraphs)[0];
  tensors_ = subgraph_->tensors();
  operators_ = subgraph_->operators();

  context_.impl_ = static_cast<void*>(&context_helper_);
  context_.ReportError = context_helper_.ReportOpError;
  context_.recommended_num_threads = 1;

  // If the system is big endian then convert weights from the flatbuffer from
  // little to big endian on startup so that it does not need to be done during
  // inference.
  // NOTE: This requires that the flatbuffer is held in memory which can be
  // modified by this process.
  if (!FLATBUFFERS_LITTLEENDIAN) {
    for (size_t t = 0; t < tensors_size(); ++t) {
      TfLiteTensor* thisTensor = &context_.tensors[t];
      if (thisTensor->allocation_type == kTfLiteMmapRo)
        CorrectTensorEndianness(thisTensor);
    }
  }

  initialization_status_ = kTfLiteOk;
}

MicroInterpreter::~MicroInterpreter() {
  if (node_and_registrations_ != nullptr) {
    for (size_t i = 0; i < operators_->size(); ++i) {
      TfLiteNode* node = &(node_and_registrations_[i].node);
      const TfLiteRegistration* registration =
          node_and_registrations_[i].registration;
      // registration is allocated outside the interpreter, so double check to
      // make sure it's not nullptr;
      if (registration != nullptr && registration->free != nullptr) {
        registration->free(&context_, node->user_data);
      }
    }
  }
}

void MicroInterpreter::CorrectTensorEndianness(TfLiteTensor* tensorCorr) {
  int32_t tensorSize = 1;
  for (int d = 0; d < tensorCorr->dims->size; ++d)
    tensorSize *= reinterpret_cast<const int32_t*>(tensorCorr->dims->data)[d];

  switch (tensorCorr->type) {
    case TfLiteType::kTfLiteFloat32:
      CorrectTensorDataEndianness(tensorCorr->data.f, tensorSize);
      break;
    case TfLiteType::kTfLiteFloat16:
      CorrectTensorDataEndianness(tensorCorr->data.f16, tensorSize);
      break;
    case TfLiteType::kTfLiteInt64:
      CorrectTensorDataEndianness(tensorCorr->data.i64, tensorSize);
      break;
    case TfLiteType::kTfLiteInt32:
      CorrectTensorDataEndianness(tensorCorr->data.i32, tensorSize);
      break;
    case TfLiteType::kTfLiteInt16:
      CorrectTensorDataEndianness(tensorCorr->data.i16, tensorSize);
      break;
    case TfLiteType::kTfLiteComplex64:
      CorrectTensorDataEndianness(tensorCorr->data.c64, tensorSize);
      break;
    default:
      // Do nothing for other data types.
      break;
  }
}

template <class T>
void MicroInterpreter::CorrectTensorDataEndianness(T* data, int32_t size) {
  for (int32_t i = 0; i < size; ++i) {
    data[i] = flatbuffers::EndianScalar(data[i]);
  }
}

TfLiteStatus MicroInterpreter::AllocateTensors() {
  TF_LITE_ENSURE_OK(&context_, allocator_.AllocateNodeAndRegistrations(
                                   op_resolver_, &node_and_registrations_));

  // Only allow AllocatePersistentBuffer in Init stage.
  context_.AllocatePersistentBuffer = context_helper_.AllocatePersistentBuffer;
  context_.RequestScratchBufferInArena = nullptr;
  context_.GetScratchBuffer = nullptr;

  for (size_t i = 0; i < operators_->size(); ++i) {
    context_helper_.SetNodeIndex(i);
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;
    size_t init_data_size;
    const char* init_data;
    if (registration->builtin_code == BuiltinOperator_CUSTOM) {
      init_data = reinterpret_cast<const char*>(node->custom_initial_data);
      init_data_size = node->custom_initial_data_size;
    } else {
      init_data = reinterpret_cast<const char*>(node->builtin_data);
      init_data_size = 0;
    }
    if (registration->init) {
      node->user_data =
          registration->init(&context_, init_data, init_data_size);
    }
  }
  context_helper_.SetNodeIndex(-1);

  // Both AllocatePersistentBuffer and RequestScratchBufferInArena is available
  // in Prepare stage.
  context_.RequestScratchBufferInArena =
      context_helper_.RequestScratchBufferInArena;
  for (size_t i = 0; i < operators_->size(); ++i) {
    // Set node idx to annotate the lifetime for scratch buffers.
    context_helper_.SetNodeIndex(i);
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;
    if (registration->prepare) {
      TfLiteStatus prepare_status = registration->prepare(&context_, node);
      if (prepare_status != kTfLiteOk) {
        TF_LITE_REPORT_ERROR(
            error_reporter_,
            "Node %s (number %df) failed to prepare with status %d",
            OpNameFromRegistration(registration), i, prepare_status);
        return kTfLiteError;
      }
    }
  }
  context_helper_.SetNodeIndex(-1);

  // Prepare is done, we're ready for Invoke. Memory allocation is no longer
  // allowed. Kernels can only fetch scratch buffers via GetScratchBuffer.
  context_.AllocatePersistentBuffer = nullptr;
  context_.RequestScratchBufferInArena = nullptr;
  context_.GetScratchBuffer = context_helper_.GetScratchBuffer;

  TF_LITE_ENSURE_OK(&context_, allocator_.FinishTensorAllocation());
  tensors_allocated_ = true;
  return kTfLiteOk;
}

TfLiteStatus MicroInterpreter::Invoke() {
  if (initialization_status_ != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Invoke() called after initialization failed\n");
    return kTfLiteError;
  }

  // Ensure tensors are allocated before the interpreter is invoked to avoid
  // difficult to debug segfaults.
  if (!tensors_allocated_) {
    TF_LITE_ENSURE_OK(&context_, AllocateTensors());
  }

  for (size_t i = 0; i < operators_->size(); ++i) {
    auto* node = &(node_and_registrations_[i].node);
    auto* registration = node_and_registrations_[i].registration;

    if (registration->invoke) {
      TfLiteStatus invoke_status = registration->invoke(&context_, node);
      if (invoke_status == kTfLiteError) {
        TF_LITE_REPORT_ERROR(
            error_reporter_,
            "Node %s (number %d) failed to invoke with status %d",
            OpNameFromRegistration(registration), i, invoke_status);
        return kTfLiteError;
      } else if (invoke_status != kTfLiteOk) {
        return invoke_status;
      }
    }
  }
  return kTfLiteOk;
}

TfLiteTensor* MicroInterpreter::input(size_t index) {
  const size_t length = inputs_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Input index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &(context_.tensors[inputs().Get(index)]);
}

TfLiteTensor* MicroInterpreter::output(size_t index) {
  const size_t length = outputs_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Output index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &(context_.tensors[outputs().Get(index)]);
}

TfLiteTensor* MicroInterpreter::tensor(size_t index) {
  const size_t length = tensors_size();
  if ((index < 0) || (index >= length)) {
    TF_LITE_REPORT_ERROR(error_reporter_,
                         "Tensor index %d out of range (length is %d)", index,
                         length);
    return nullptr;
  }
  return &context_.tensors[index];
}

TfLiteStatus MicroInterpreter::ResetVariableTensors() {
  const size_t length = tensors_size();
  for (size_t i = 0; i < length; ++i) {
    TfLiteTensor* cur_tensor = tensor(i);
    if (cur_tensor->is_variable) {
      TfLiteStatus status = tflite::ResetVariableTensor(cur_tensor);
      if (status != kTfLiteOk) {
        TF_LITE_REPORT_ERROR(error_reporter_,
                             "Failed to reset variable tensor at index: %d", i);
        return status;
      }
    }
  }
  return kTfLiteOk;
}

}  // namespace tflite
<|endoftext|>


<commit_before>#include "../utils.h"
#include "../plugin.h"

#include <libgfx/transform.h>
#include <libgfx/mesh.h>
#include <libgfx/utility.h>

#include "LSystem3D.h"
#include "render.h"

namespace CG {

  class ZBuffering : public Plugin
  {
    public:
      GFX::Color extractColor(const ini::Entry &entry) const
      {
        try {
          std::vector<double> rgb = entry;
          return GFX::Color(255 * rgb.at(0), 255 * rgb.at(1), 255 * rgb.at(2));
        } catch (const std::exception &e) {
          std::cerr << "Could not parse color (using default black)" << std::endl;
        }

        return GFX::Color(0, 0, 0);
      }

      GFX::mat4 modelMatrix(const std::string &figureName, const ini::Configuration &conf)
      {
        GFX::mat4 m;

        // translation
        std::vector<double> center = conf[figureName]["center"];
        m = GFX::translationMatrix(center[0], center[1], center[2]);
        // rotation around Z
        GFX::Real angleZ = conf[figureName]["rotateZ"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleZ), 0, 0, 1);
        // rotation around Y
        GFX::Real angleY = conf[figureName]["rotateY"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleY), 0, 1, 0);
        // rotation around X
        GFX::Real angleX = conf[figureName]["rotateX"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleX), 1, 0, 0);
        // scale
        GFX::Real scale = conf[figureName]["scale"].as_double_or_die();
        m *= GFX::scaleMatrix(scale);

        return m;
      }

      img::EasyImage image(const ini::Configuration &conf)
      {
        int size;
        std::vector<double> eye;
        GFX::Color bgColor;
        int nrFigures;

        // read General section from *.ini file
        try {
          size = conf["General"]["size"];
          eye = conf["General"]["eye"];
          bgColor = extractColor(conf["General"]["backgroundcolor"]);
          nrFigures = conf["General"]["nrFigures"];
        } catch (const std::exception &e) {
          std::cerr << e.what() << std::endl;
          return img::EasyImage();
        }

        GFX::mat4 project = GFX::projectionMatrix(eye[0], eye[1], eye[2]);

        std::vector<std::shared_ptr<GFX::Mesh> > meshes;
        std::vector<GFX::mat4> modelMatrices;
        std::vector<GFX::Color> colors;

        for (int i = 0; i < nrFigures; ++i) {
          std::string figureName = make_string("Figure", i);

          try {
            std::string type = conf[figureName]["type"].as_string_or_die();
            GFX::Color color = extractColor(conf[figureName]["color"]);
            colors.push_back(color);

            GFX::mat4 model = modelMatrix(figureName, conf);
            modelMatrices.push_back(model);

            if (type == "Cube") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cube();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Tetrahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::tetrahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Octahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::octahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Icosahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::icosahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Dodecahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::dodecahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Cone") {

              int n = conf[figureName]["n"];
              GFX::Real h = conf[figureName]["height"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cone(n, h);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Cylinder") {

              int n = conf[figureName]["n"];
              GFX::Real h = conf[figureName]["height"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cylinder(n, h);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Sphere") {

              int n = conf[figureName]["n"];
              //renderMesh(*GFX::Mesh::sphere(n), color, project * model, lines);
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::sphere(n);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Torus") {

              int n = conf[figureName]["n"];
              int m = conf[figureName]["m"];
              GFX::Real R = conf[figureName]["R"].as_double_or_die();
              GFX::Real r = conf[figureName]["r"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::torus(n, m, R, r);
              mesh->triangulate();
              meshes.push_back(mesh);

            }

          } catch (const std::exception &e) {
            std::cerr << e.what() << std::endl;
            return img::EasyImage();
          }
        }

        return draw_zbuffered_meshes(meshes, project, modelMatrices, colors, size, img::Color(255 * bgColor.r, 255 * bgColor.g, 255 * bgColor.b));
      }

  };

  PLUGIN_FACTORY("ZBuffering", ZBuffering)

}
<commit_msg>Complete Z-buffering 3D fractals<commit_after>#include "../utils.h"
#include "../plugin.h"

#include <libgfx/transform.h>
#include <libgfx/mesh.h>
#include <libgfx/utility.h>

#include "LSystem3D.h"
#include "render.h"

namespace CG {

  class ZBuffering : public Plugin
  {
    public:
      GFX::Color extractColor(const ini::Entry &entry) const
      {
        try {
          std::vector<double> rgb = entry;
          return GFX::Color(255 * rgb.at(0), 255 * rgb.at(1), 255 * rgb.at(2));
        } catch (const std::exception &e) {
          std::cerr << "Could not parse color (using default black)" << std::endl;
        }

        return GFX::Color(0, 0, 0);
      }

      GFX::mat4 modelMatrix(const std::string &figureName, const ini::Configuration &conf)
      {
        GFX::mat4 m;

        // translation
        std::vector<double> center = conf[figureName]["center"];
        m = GFX::translationMatrix(center[0], center[1], center[2]);
        // rotation around Z
        GFX::Real angleZ = conf[figureName]["rotateZ"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleZ), 0, 0, 1);
        // rotation around Y
        GFX::Real angleY = conf[figureName]["rotateY"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleY), 0, 1, 0);
        // rotation around X
        GFX::Real angleX = conf[figureName]["rotateX"].as_double_or_die();
        m *= GFX::rotationMatrix(GFX::deg2rad(angleX), 1, 0, 0);
        // scale
        GFX::Real scale = conf[figureName]["scale"].as_double_or_die();
        m *= GFX::scaleMatrix(scale);

        return m;
      }

      std::shared_ptr<GFX::Mesh> createFractal(std::vector<GFX::vec4> &points0, std::vector<GFX::Mesh::Face> &faces,
          int nrIterations, double fractalScale)
      {
        // compute center
        GFX::vec4 center(GFX::vec4::Zero());
        for (std::size_t i = 0; i < points0.size(); ++i)
          center += points0[i];
        // center figure
        for (std::size_t i = 0; i < points0.size(); ++i)
          points0[i] -= center;

        std::size_t h = points0.size();
        std::vector<GFX::vec4> lastPoints = points0, points;

        for (int i = 0; i < nrIterations; ++i) {
          points.clear();

          for (std::size_t k = 0; k < lastPoints.size(); ++k) {
            std::size_t j = (k % h);

            // scale initial points
            std::vector<GFX::vec4> addPoints;
            for (std::size_t l = 0; l < h; ++l)
              addPoints.push_back(points0[l] / std::pow(fractalScale, i + 1));

            // translate small figure to origin
            GFX::vec4 point_j = addPoints[j];
            for (std::size_t l = 0; l < addPoints.size(); ++l)
              addPoints[l] -= point_j;

            // translate small figure to point on figure from previous iteration
            for (std::size_t l = 0; l < addPoints.size(); ++l)
              points.push_back(addPoints[l] + lastPoints[k]);
          }

          lastPoints.swap(points);
        }

        std::size_t offset = points0.size();

        std::size_t f = faces.size();
        std::size_t numFaces = f * std::pow(h, nrIterations);
        while (faces.size() < numFaces) {

          for (std::size_t i = 0; i < f; ++i) {
            faces.resize(faces.size() + 1);
            for (std::size_t j = 0; j < faces[i].size(); ++j) {
              faces.back().push_back(offset + faces[i][j]);
            }
          }

          offset += points0.size();
        }

        std::shared_ptr<GFX::Mesh> mesh(new GFX::Mesh);
        for (std::size_t i = 0; i < lastPoints.size(); ++i)
          mesh->addVertex(lastPoints[i].x(), lastPoints[i].y(), lastPoints[i].z());
        for (std::size_t i = 0; i < faces.size(); ++i)
          mesh->addFace(faces[i]);

        return mesh;
      }

      img::EasyImage image(const ini::Configuration &conf)
      {
        int size;
        std::vector<double> eye;
        GFX::Color bgColor;
        int nrFigures;

        // read General section from *.ini file
        try {
          size = conf["General"]["size"];
          eye = conf["General"]["eye"];
          bgColor = extractColor(conf["General"]["backgroundcolor"]);
          nrFigures = conf["General"]["nrFigures"];
        } catch (const std::exception &e) {
          std::cerr << e.what() << std::endl;
          return img::EasyImage();
        }

        GFX::mat4 project = GFX::projectionMatrix(eye[0], eye[1], eye[2]);

        std::vector<std::shared_ptr<GFX::Mesh> > meshes;
        std::vector<GFX::mat4> modelMatrices;
        std::vector<GFX::Color> colors;

        for (int i = 0; i < nrFigures; ++i) {
          std::string figureName = make_string("Figure", i);

          try {
            std::string type = conf[figureName]["type"].as_string_or_die();
            GFX::Color color = extractColor(conf[figureName]["color"]);
            colors.push_back(color);

            GFX::mat4 model = modelMatrix(figureName, conf);
            modelMatrices.push_back(model);

            if (type == "Cube") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cube();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Tetrahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::tetrahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Octahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::octahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Icosahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::icosahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Dodecahedron") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::dodecahedron();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "BuckyBall") {

              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::buckyball();
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Cone") {

              int n = conf[figureName]["n"];
              GFX::Real h = conf[figureName]["height"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cone(n, h);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Cylinder") {

              int n = conf[figureName]["n"];
              GFX::Real h = conf[figureName]["height"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cylinder(n, h);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Sphere") {

              int n = conf[figureName]["n"];
              //renderMesh(*GFX::Mesh::sphere(n), color, project * model, lines);
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::sphere(n);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type == "Torus") {

              int n = conf[figureName]["n"];
              int m = conf[figureName]["m"];
              GFX::Real R = conf[figureName]["R"].as_double_or_die();
              GFX::Real r = conf[figureName]["r"].as_double_or_die();
              std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::torus(n, m, R, r);
              mesh->triangulate();
              meshes.push_back(mesh);

            } else if (type.substr(0, 7) == "Fractal") {

              //
              // 3D Fractals
              //

              int nrIterations = conf[figureName]["nrIterations"];
              double fractalScale = conf[figureName]["fractalScale"];

              std::shared_ptr<GFX::Mesh> unit;

              if (type == "FractalTetrahedron")
                unit = GFX::Mesh::tetrahedron();
              else if (type == "FractalCube")
                unit = GFX::Mesh::cube();
              else if (type == "FractalIcosahedron")
                unit = GFX::Mesh::icosahedron();
              else if (type == "FractalOctahedron")
                unit = GFX::Mesh::octahedron();
              else if (type == "FractalDodecahedron")
                unit = GFX::Mesh::dodecahedron();
              else if (type == "FractalBuckyBall")
                unit = GFX::Mesh::buckyball();

              std::vector<GFX::vec4> points0 = unit->vertices();
              std::vector<GFX::Mesh::Face> faces = unit->faces();

              std::shared_ptr<GFX::Mesh> mesh = createFractal(points0, faces, nrIterations, fractalScale);
              mesh->triangulate();

              meshes.push_back(mesh);

            } else if (type == "MengerSponge") {

              //
              // MengerSponge
              //

              int nrIterations = conf[figureName]["nrIterations"];

              std::vector<std::pair<GFX::vec3, GFX::vec3> > cubes(1, std::make_pair(GFX::vec3(-1, -1, -1), GFX::vec3(1, 1, 1)));

              for (int i = 0; i < nrIterations; ++i) {
                assert(cubes.size());
                std::vector<std::pair<GFX::vec3, GFX::vec3> > nextCubes;

                // the new cube size
                GFX::Real delta = (cubes.front().second.x() - cubes.front().first.x()) / 3.0;

                for (auto cube : cubes) {
                  // the reference point
                  GFX::vec3 p = cube.first;

                  // front, bottom
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 0 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 1 * delta, p.z() + 1 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 1 * delta, p.y() + 0 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 2 * delta, p.y() + 1 * delta, p.z() + 1 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 0 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 1 * delta, p.z() + 1 * delta)));
                  // front, middle
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 1 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 2 * delta, p.z() + 1 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 1 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 2 * delta, p.z() + 1 * delta)));
                  // front, top
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 2 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 3 * delta, p.z() + 1 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 1 * delta, p.y() + 2 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 2 * delta, p.y() + 3 * delta, p.z() + 1 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 2 * delta, p.z() + 0 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 3 * delta, p.z() + 1 * delta)));

                  // middle, bottom
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 0 * delta, p.z() + 1 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 1 * delta, p.z() + 2 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 0 * delta, p.z() + 1 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 1 * delta, p.z() + 2 * delta)));
                  // middle, top
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 2 * delta, p.z() + 1 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 3 * delta, p.z() + 2 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 2 * delta, p.z() + 1 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 3 * delta, p.z() + 2 * delta)));

                  // back, bottom
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 0 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 1 * delta, p.z() + 3 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 1 * delta, p.y() + 0 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 2 * delta, p.y() + 1 * delta, p.z() + 3 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 0 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 1 * delta, p.z() + 3 * delta)));
                  // back, middle
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 1 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 2 * delta, p.z() + 3 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 1 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 2 * delta, p.z() + 3 * delta)));
                  // back, top
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 0 * delta, p.y() + 2 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 1 * delta, p.y() + 3 * delta, p.z() + 3 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 1 * delta, p.y() + 2 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 2 * delta, p.y() + 3 * delta, p.z() + 3 * delta)));
                  nextCubes.push_back(std::make_pair(GFX::vec3(p.x() + 2 * delta, p.y() + 2 * delta, p.z() + 2 * delta), GFX::vec3(p.x() + 3 * delta, p.y() + 3 * delta, p.z() + 3 * delta)));

                }

                cubes.swap(nextCubes);
              }

              for (auto cube : cubes) {
                std::shared_ptr<GFX::Mesh> mesh = GFX::Mesh::cube();

                // scale the cube mesh
                GFX::Real s = (cube.second.x() - cube.first.x()) / 2.0;
                for (GFX::vec4 &v : mesh->vertices()) {
                  v.x() *= s;
                  v.y() *= s;
                  v.z() *= s;
                }

                // translate the cube mesh
                GFX::vec3 c = (cube.first + cube.second) / 2.0;
                for (GFX::vec4 &v : mesh->vertices()) {
                  v.x() -= c.x();
                  v.y() -= c.y();
                  v.z() -= c.z();
                }

                mesh->triangulate();
                meshes.push_back(mesh);
              }

              while (modelMatrices.size() < meshes.size())
                modelMatrices.push_back(modelMatrices.back());
              while (colors.size() < meshes.size())
                colors.push_back(colors.back());

            }

          } catch (const std::exception &e) {
            std::cerr << e.what() << std::endl;
            return img::EasyImage();
          }
        }

        return draw_zbuffered_meshes(meshes, project, modelMatrices, colors, size, img::Color(255 * bgColor.r, 255 * bgColor.g, 255 * bgColor.b));
      }

  };

  PLUGIN_FACTORY("ZBuffering", ZBuffering)

}
<|endoftext|>


<commit_before>#ifndef LOCK_QUEUE
#define LOCK_QUEUE
#include<memory>	//allocator, shared_ptr
#include<utility>	//move
#include"Node.hpp"
#include"../tool/CAlloc_obj.hpp"

namespace nThread
{
	template<class T,class Mutex,class Alloc=std::allocator<T>>
	struct Lock_queue
	{
		using allocator_type=Alloc;
		using element_type=Node<nTool::CAlloc_obj<T,Alloc>>;
		using mutex_type=Mutex;
		using size_type=typename nTool::CAlloc_obj<T,Alloc>::size_type;
		using value_type=T;
		std::shared_ptr<element_type> begin;
		std::shared_ptr<element_type> end;
		mutex_type mut;
		Lock_queue()=default;
		Lock_queue(const Lock_queue &)=delete;
		void emplace(std::shared_ptr<element_type> &&val)
		{
			val->next.reset();
			std::lock_guard<mutex_type> lock{mut};
			emplace_(std::move(val));
		}
		//do not call Lock_queue::emplace, emplace_not_ts, Lock_queue::pop or Lock_queue::pop_not_ts at same time
		inline void emplace_not_ts(std::shared_ptr<element_type> &&val) noexcept
		{
			emplace_(std::move(val));
		}
		inline bool empty() const noexcept
		{
			return !std::atomic_load_explicit(&begin,std::memory_order_acquire).operator bool();
		}
		std::shared_ptr<element_type> pop()
		{
			std::lock_guard<mutex_type> lock{mut};
			return pop_not_ts();
		}
		std::shared_ptr<element_type> pop_if_exist()
		{
			if(empty())
				return std::shared_ptr<element_type>{};
			std::lock_guard<mutex_type> lock{mut};
			if(empty())
				return std::shared_ptr<element_type>{};
			return pop_not_ts();
		}
		//do not call Lock_queue::emplace, Lock_queue::emplace_not_ts, Lock_queue::pop or pop_not_ts at same time
		std::shared_ptr<element_type> pop_not_ts() noexcept
		{
			const std::shared_ptr<element_type> node{std::move(begin)};
			begin=node->next;
			if(empty())
				end.reset();
			return node;
		}
		Lock_queue& operator=(const Lock_queue &)=delete;
	private:
		void emplace_(std::shared_ptr<element_type> &&val) noexcept
		{
			if(empty())
			{
				std::atomic_store_explicit(&begin,val,std::memory_order_release);
				end=std::move(val);
			}
			else
			{
				end->next=std::move(val);
				end=end->next;
			}
		}
	};
}

#endif<commit_msg>fix bug<commit_after>#ifndef LOCK_QUEUE
#define LOCK_QUEUE
#include<memory>	//allocator, shared_ptr
#include<utility>	//move
#include"Node.hpp"
#include"../tool/CAlloc_obj.hpp"

namespace nThread
{
	template<class T,class Mutex,class Alloc=std::allocator<T>>
	struct Lock_queue
	{
		using allocator_type=Alloc;
		using element_type=Node<nTool::CAlloc_obj<T,Alloc>>;
		using mutex_type=Mutex;
		using size_type=typename nTool::CAlloc_obj<T,Alloc>::size_type;
		using value_type=T;
		std::shared_ptr<element_type> begin;
		std::shared_ptr<element_type> end;
		mutex_type mut;
		Lock_queue()
			:begin{make_shared<element_type>()},end{make_shared<element_type>()}
		{
			begin->next=end;
		}
		Lock_queue(const Lock_queue &)=delete;
		void emplace(std::shared_ptr<element_type> &&val)
		{
			val->next.reset();
			std::lock_guard<mutex_type> lock{mut};
			emplace_(std::move(val));
		}
		//do not call other member functions (including const member functions) at same time
		inline void emplace_not_ts(std::shared_ptr<element_type> &&val) noexcept
		{
			emplace_(std::move(val));
		}
		inline bool empty() const noexcept
		{
			return !std::atomic_load_explicit(&std::atomic_load_explicit(&begin->next,std::memory_order_acquire)->next,std::memory_order_acquire);
		}
		std::shared_ptr<element_type> pop()
		{
			std::lock_guard<mutex_type> lock{mut};
			return pop_();
		}
		std::shared_ptr<element_type> pop_if_exist()
		{
			if(empty())
				return std::shared_ptr<element_type>{};
			std::lock_guard<mutex_type> lock{mut};
			if(empty())
				return std::shared_ptr<element_type>{};
			return pop_();
		}
		//do not call other member functions (including const member functions) at same time
		std::shared_ptr<element_type> pop_not_ts() noexcept
		{
			const std::shared_ptr<element_type> node{std::move(begin->next)};
			begin->next=node->next;
			return node;
		}
		Lock_queue& operator=(const Lock_queue &)=delete;
	private:
		void emplace_(std::shared_ptr<element_type> &&val) noexcept
		{
			end->next=val;
			std::swap(end->data,val->data);
			end=std::move(val);
		}
		std::shared_ptr<element_type> pop_() noexcept
		{
			using namespace std;
			const shared_ptr<element_type> node{atomic_load_explicit(&begin->next,memory_order_acquire)};
			atomic_store_explicit(&begin->next,atomic_load_explicit(&node->next,memory_order_acquire),memory_order_release);
			return node;
		}
	};
}

#endif<|endoftext|>


<commit_before>#include "globals.hh"
#include "util.hh"
#include "archive.hh"

#include <map>
#include <algorithm>
#include <unistd.h>

namespace nix {

/* The default location of the daemon socket, relative to nixStateDir.
   The socket is in a directory to allow you to control access to the
   Nix daemon by setting the mode/ownership of the directory
   appropriately.  (This wouldn't work on the socket itself since it
   must be deleted and recreated on startup.) */
#define DEFAULT_SOCKET_PATH "/daemon-socket/socket"

Settings settings;

Settings::Settings()
{
    nixPrefix = NIX_PREFIX;
    nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)));
    nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
    nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR));
    nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR));
    nixConfDir = canonPath(getEnv("NIX_CONF_DIR", NIX_CONF_DIR));
    nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR));
    nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR));
    nixDaemonSocketFile = canonPath(nixStateDir + DEFAULT_SOCKET_PATH);

    // should be set with the other config options, but depends on nixLibexecDir
#ifdef __APPLE__
    preBuildHook = nixLibexecDir + "/nix/resolve-system-dependencies";
#endif

    keepFailed = false;
    keepGoing = false;
    tryFallback = false;
    maxBuildJobs = 1;
    buildCores = 1;
#ifdef _SC_NPROCESSORS_ONLN
    long res = sysconf(_SC_NPROCESSORS_ONLN);
    if (res > 0) buildCores = res;
#endif
    readOnlyMode = false;
    thisSystem = SYSTEM;
    maxSilentTime = 0;
    buildTimeout = 0;
    useBuildHook = true;
    reservedSize = 8 * 1024 * 1024;
    fsyncMetadata = true;
    useSQLiteWAL = true;
    syncBeforeRegistering = false;
    useSubstitutes = true;
    buildUsersGroup = getuid() == 0 ? "nixbld" : "";
    useSshSubstituter = true;
    impersonateLinux26 = false;
    keepLog = true;
    compressLog = true;
    maxLogSize = 0;
    pollInterval = 5;
    checkRootReachability = false;
    gcKeepOutputs = false;
    gcKeepDerivations = true;
    autoOptimiseStore = false;
    envKeepDerivations = false;
    lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
    showTrace = false;
    enableImportNative = false;
    netrcFile = fmt("%s/%s", nixConfDir, "netrc");
}

void Settings::loadConfFile()
{
    Path settingsFile = (format("%1%/%2%") % nixConfDir % "nix.conf").str();
    if (!pathExists(settingsFile)) return;
    string contents = readFile(settingsFile);

    unsigned int pos = 0;

    while (pos < contents.size()) {
        string line;
        while (pos < contents.size() && contents[pos] != '\n')
            line += contents[pos++];
        pos++;

        string::size_type hash = line.find('#');
        if (hash != string::npos)
            line = string(line, 0, hash);

        vector<string> tokens = tokenizeString<vector<string> >(line);
        if (tokens.empty()) continue;

        if (tokens.size() < 2 || tokens[1] != "=")
            throw Error(format("illegal configuration line ‘%1%’ in ‘%2%’") % line % settingsFile);

        string name = tokens[0];

        vector<string>::iterator i = tokens.begin();
        advance(i, 2);
        settings[name] = concatStringsSep(" ", Strings(i, tokens.end())); // FIXME: slow
    };
}

void Settings::set(const string & name, const string & value)
{
    settings[name] = value;
    overrides[name] = value;
}

string Settings::get(const string & name, const string & def)
{
    auto i = settings.find(name);
    if (i == settings.end()) return def;
    return i->second;
}

Strings Settings::get(const string & name, const Strings & def)
{
    auto i = settings.find(name);
    if (i == settings.end()) return def;
    return tokenizeString<Strings>(i->second);
}

bool Settings::get(const string & name, bool def)
{
    bool res = def;
    _get(res, name);
    return res;
}

int Settings::get(const string & name, int def)
{
    int res = def;
    _get(res, name);
    return res;
}

void Settings::update()
{
    _get(tryFallback, "build-fallback");
    _get(maxBuildJobs, "build-max-jobs");
    _get(buildCores, "build-cores");
    _get(thisSystem, "system");
    _get(maxSilentTime, "build-max-silent-time");
    _get(buildTimeout, "build-timeout");
    _get(reservedSize, "gc-reserved-space");
    _get(fsyncMetadata, "fsync-metadata");
    _get(useSQLiteWAL, "use-sqlite-wal");
    _get(syncBeforeRegistering, "sync-before-registering");
    _get(useSubstitutes, "build-use-substitutes");
    _get(buildUsersGroup, "build-users-group");
    _get(impersonateLinux26, "build-impersonate-linux-26");
    _get(keepLog, "build-keep-log");
    _get(compressLog, "build-compress-log");
    _get(maxLogSize, "build-max-log-size");
    _get(pollInterval, "build-poll-interval");
    _get(checkRootReachability, "gc-check-reachability");
    _get(gcKeepOutputs, "gc-keep-outputs");
    _get(gcKeepDerivations, "gc-keep-derivations");
    _get(autoOptimiseStore, "auto-optimise-store");
    _get(envKeepDerivations, "env-keep-derivations");
    _get(sshSubstituterHosts, "ssh-substituter-hosts");
    _get(useSshSubstituter, "use-ssh-substituter");
    _get(logServers, "log-servers");
    _get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
    _get(useCaseHack, "use-case-hack");
    _get(preBuildHook, "pre-build-hook");
    _get(keepGoing, "keep-going");
    _get(keepFailed, "keep-failed");
    _get(netrcFile, "netrc-file");
}

void Settings::_get(string & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res = i->second;
}

void Settings::_get(bool & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    if (i->second == "true") res = true;
    else if (i->second == "false") res = false;
    else throw Error(format("configuration option ‘%1%’ should be either ‘true’ or ‘false’, not ‘%2%’")
        % name % i->second);
}

void Settings::_get(StringSet & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res.clear();
    Strings ss = tokenizeString<Strings>(i->second);
    res.insert(ss.begin(), ss.end());
}

void Settings::_get(Strings & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res = tokenizeString<Strings>(i->second);
}

template<class N> void Settings::_get(N & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    if (!string2Int(i->second, res))
        throw Error(format("configuration setting ‘%1%’ should have an integer value") % name);
}

string Settings::pack()
{
    string s;
    for (auto & i : settings) {
        if (i.first.find('\n') != string::npos ||
            i.first.find('=') != string::npos ||
            i.second.find('\n') != string::npos)
            throw Error("illegal option name/value");
        s += i.first; s += '='; s += i.second; s += '\n';
    }
    return s;
}

void Settings::unpack(const string & pack) {
    Strings lines = tokenizeString<Strings>(pack, "\n");
    for (auto & i : lines) {
        string::size_type eq = i.find('=');
        if (eq == string::npos)
            throw Error("illegal option name/value");
        set(i.substr(0, eq), i.substr(eq + 1));
    }
}

Settings::SettingsMap Settings::getOverrides()
{
    return overrides;
}

const string nixVersion = PACKAGE_VERSION;

}
<commit_msg>_SC_NPROCESSORS_ONLN -> std::thread::hardware_concurrency()<commit_after>#include "globals.hh"
#include "util.hh"
#include "archive.hh"

#include <algorithm>
#include <map>
#include <thread>

namespace nix {

/* The default location of the daemon socket, relative to nixStateDir.
   The socket is in a directory to allow you to control access to the
   Nix daemon by setting the mode/ownership of the directory
   appropriately.  (This wouldn't work on the socket itself since it
   must be deleted and recreated on startup.) */
#define DEFAULT_SOCKET_PATH "/daemon-socket/socket"

Settings settings;

Settings::Settings()
{
    nixPrefix = NIX_PREFIX;
    nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)));
    nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
    nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR));
    nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR));
    nixConfDir = canonPath(getEnv("NIX_CONF_DIR", NIX_CONF_DIR));
    nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR));
    nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR));
    nixDaemonSocketFile = canonPath(nixStateDir + DEFAULT_SOCKET_PATH);

    // should be set with the other config options, but depends on nixLibexecDir
#ifdef __APPLE__
    preBuildHook = nixLibexecDir + "/nix/resolve-system-dependencies";
#endif

    keepFailed = false;
    keepGoing = false;
    tryFallback = false;
    maxBuildJobs = 1;
    buildCores = std::max(1U, std::thread::hardware_concurrency());
    readOnlyMode = false;
    thisSystem = SYSTEM;
    maxSilentTime = 0;
    buildTimeout = 0;
    useBuildHook = true;
    reservedSize = 8 * 1024 * 1024;
    fsyncMetadata = true;
    useSQLiteWAL = true;
    syncBeforeRegistering = false;
    useSubstitutes = true;
    buildUsersGroup = getuid() == 0 ? "nixbld" : "";
    useSshSubstituter = true;
    impersonateLinux26 = false;
    keepLog = true;
    compressLog = true;
    maxLogSize = 0;
    pollInterval = 5;
    checkRootReachability = false;
    gcKeepOutputs = false;
    gcKeepDerivations = true;
    autoOptimiseStore = false;
    envKeepDerivations = false;
    lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1";
    showTrace = false;
    enableImportNative = false;
    netrcFile = fmt("%s/%s", nixConfDir, "netrc");
}

void Settings::loadConfFile()
{
    Path settingsFile = (format("%1%/%2%") % nixConfDir % "nix.conf").str();
    if (!pathExists(settingsFile)) return;
    string contents = readFile(settingsFile);

    unsigned int pos = 0;

    while (pos < contents.size()) {
        string line;
        while (pos < contents.size() && contents[pos] != '\n')
            line += contents[pos++];
        pos++;

        string::size_type hash = line.find('#');
        if (hash != string::npos)
            line = string(line, 0, hash);

        vector<string> tokens = tokenizeString<vector<string> >(line);
        if (tokens.empty()) continue;

        if (tokens.size() < 2 || tokens[1] != "=")
            throw Error(format("illegal configuration line ‘%1%’ in ‘%2%’") % line % settingsFile);

        string name = tokens[0];

        vector<string>::iterator i = tokens.begin();
        advance(i, 2);
        settings[name] = concatStringsSep(" ", Strings(i, tokens.end())); // FIXME: slow
    };
}

void Settings::set(const string & name, const string & value)
{
    settings[name] = value;
    overrides[name] = value;
}

string Settings::get(const string & name, const string & def)
{
    auto i = settings.find(name);
    if (i == settings.end()) return def;
    return i->second;
}

Strings Settings::get(const string & name, const Strings & def)
{
    auto i = settings.find(name);
    if (i == settings.end()) return def;
    return tokenizeString<Strings>(i->second);
}

bool Settings::get(const string & name, bool def)
{
    bool res = def;
    _get(res, name);
    return res;
}

int Settings::get(const string & name, int def)
{
    int res = def;
    _get(res, name);
    return res;
}

void Settings::update()
{
    _get(tryFallback, "build-fallback");
    _get(maxBuildJobs, "build-max-jobs");
    _get(buildCores, "build-cores");
    _get(thisSystem, "system");
    _get(maxSilentTime, "build-max-silent-time");
    _get(buildTimeout, "build-timeout");
    _get(reservedSize, "gc-reserved-space");
    _get(fsyncMetadata, "fsync-metadata");
    _get(useSQLiteWAL, "use-sqlite-wal");
    _get(syncBeforeRegistering, "sync-before-registering");
    _get(useSubstitutes, "build-use-substitutes");
    _get(buildUsersGroup, "build-users-group");
    _get(impersonateLinux26, "build-impersonate-linux-26");
    _get(keepLog, "build-keep-log");
    _get(compressLog, "build-compress-log");
    _get(maxLogSize, "build-max-log-size");
    _get(pollInterval, "build-poll-interval");
    _get(checkRootReachability, "gc-check-reachability");
    _get(gcKeepOutputs, "gc-keep-outputs");
    _get(gcKeepDerivations, "gc-keep-derivations");
    _get(autoOptimiseStore, "auto-optimise-store");
    _get(envKeepDerivations, "env-keep-derivations");
    _get(sshSubstituterHosts, "ssh-substituter-hosts");
    _get(useSshSubstituter, "use-ssh-substituter");
    _get(logServers, "log-servers");
    _get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
    _get(useCaseHack, "use-case-hack");
    _get(preBuildHook, "pre-build-hook");
    _get(keepGoing, "keep-going");
    _get(keepFailed, "keep-failed");
    _get(netrcFile, "netrc-file");
}

void Settings::_get(string & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res = i->second;
}

void Settings::_get(bool & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    if (i->second == "true") res = true;
    else if (i->second == "false") res = false;
    else throw Error(format("configuration option ‘%1%’ should be either ‘true’ or ‘false’, not ‘%2%’")
        % name % i->second);
}

void Settings::_get(StringSet & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res.clear();
    Strings ss = tokenizeString<Strings>(i->second);
    res.insert(ss.begin(), ss.end());
}

void Settings::_get(Strings & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    res = tokenizeString<Strings>(i->second);
}

template<class N> void Settings::_get(N & res, const string & name)
{
    SettingsMap::iterator i = settings.find(name);
    if (i == settings.end()) return;
    if (!string2Int(i->second, res))
        throw Error(format("configuration setting ‘%1%’ should have an integer value") % name);
}

string Settings::pack()
{
    string s;
    for (auto & i : settings) {
        if (i.first.find('\n') != string::npos ||
            i.first.find('=') != string::npos ||
            i.second.find('\n') != string::npos)
            throw Error("illegal option name/value");
        s += i.first; s += '='; s += i.second; s += '\n';
    }
    return s;
}

void Settings::unpack(const string & pack) {
    Strings lines = tokenizeString<Strings>(pack, "\n");
    for (auto & i : lines) {
        string::size_type eq = i.find('=');
        if (eq == string::npos)
            throw Error("illegal option name/value");
        set(i.substr(0, eq), i.substr(eq + 1));
    }
}

Settings::SettingsMap Settings::getOverrides()
{
    return overrides;
}

const string nixVersion = PACKAGE_VERSION;

}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/tools/globals.h>

namespace votca { namespace tools {

	bool globals::verbose = false;
	std::string globals::url = "http://www.votca.org";
	std::string globals::email = "devs@votca.org";

        std::string globals::man::option(".TP\n\\fB%1%\\fR\n%2%\n");

        std::string globals::man::header(".TH \"%1%\" 1 \"\" \"Version: %2%\"\n\n");

        std::string globals::man::name(".SH NAME\n"
                           "\n.P\n"
                           "%1% \\- Part of the VOTCA package\n"
                           "\n.P\n"
                           "For more info please visit %2%\n\n"
        );

        std::string globals::man::authors("\n.SH AUTHORS\n"
                            "\n.P\n"
                            "Written and maintained by the VOTCA Development Team <%1%>\n");

        std::string globals::man::copyright("\n.SH COPYRIGHT\n"
                              "\n.P\n\n"
                              "Copyright 2009\\-2013 The VOTCA Development Team (%1%).\n"
                              "\n.P\n"
                              "Licensed under the Apache License, Version 2.0 (the \"License\") "
                              "you may not use this file except in compliance with the License. "
                              "You may obtain a copy of the License at"
                              "\n.P\n"
                              "http://www.apache.org/licenses/LICENSE\\-2.0\n"
                              "\n.P\n"
                              "Unless required by applicable law or agreed to in writing, software "
                              "distributed under the License is distributed on an \"AS IS\" BASIS, "
                              "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. "
                              "See the License for the specific language governing permissions and "
                              "limitations under the License.");

        std::string globals::man::synopsis ("\n.SH SYNOPSIS\n"
                                "\n.P\n\\fB%1%\\fR [\\fIOPTION\\fR] [\\fIARGUMENT\\fR]\n");

        std::string globals::man::description ("\n.SH DESCRIPTION\n"
                                "\n.P\n%1%\n");

        std::string globals::man::options ("\n.SH OPTIONS\n");

        std::string globals::tex::section("\n\\subsection{%1%}");
        std::string globals::tex::label("\n\\label{prog:%1%}");
        std::string globals::tex::description("\n%1%");
        std::string globals::tex::option("\n\\item[ ] \\texttt{%1%} %2%");
        std::string globals::tex::options("\n\\begin{compactitem}%1%\n\\end{compactitem}\n");

}}
<commit_msg>indentation?<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/tools/globals.h>

namespace votca { namespace tools {

        bool globals::verbose = false;
        std::string globals::url = "http://www.votca.org";
        std::string globals::email = "devs@votca.org";

        std::string globals::man::option(".TP\n\\fB%1%\\fR\n%2%\n");

        std::string globals::man::header(".TH \"%1%\" 1 \"\" \"Version: %2%\"\n\n");

        std::string globals::man::name
        (
                ".SH NAME\n"
                "\n.P\n"
                "%1% \\- Part of the VOTCA package\n"
                "\n.P\n"
                "For more info please visit %2%\n\n"
        );

        std::string globals::man::authors
        (
                "\n.SH AUTHORS\n"
                "\n.P\n"
                "Written and maintained by the VOTCA Development Team <%1%>\n"
        );

        std::string globals::man::copyright
        (
                "\n.SH COPYRIGHT\n"
                "\n.P\n\n"
                "Copyright 2009\\-2013 The VOTCA Development Team (%1%).\n"
                "\n.P\n"
                "Licensed under the Apache License, Version 2.0 (the \"License\") "
                "you may not use this file except in compliance with the License. "
                "You may obtain a copy of the License at"
                "\n.P\n"
                "http://www.apache.org/licenses/LICENSE\\-2.0\n"
                "\n.P\n"
                "Unless required by applicable law or agreed to in writing, software "
                "distributed under the License is distributed on an \"AS IS\" BASIS, "
                "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. "
                "See the License for the specific language governing permissions and "
                "limitations under the License."
        );

        std::string globals::man::synopsis
        (
                "\n.SH SYNOPSIS\n"
                "\n.P\n\\fB%1%\\fR [\\fIOPTION\\fR] [\\fIARGUMENT\\fR]\n"
        );

        std::string globals::man::description
        (
                "\n.SH DESCRIPTION\n"
                "\n.P\n%1%\n"
        );

        std::string globals::man::options("\n.SH OPTIONS\n");

        std::string globals::tex::section("\n\\subsection{%1%}");
        std::string globals::tex::label("\n\\label{prog:%1%}");
        std::string globals::tex::description("\n%1%");
        std::string globals::tex::option("\n\\item[ ] \\texttt{%1%} %2%");
        std::string globals::tex::options("\n\\begin{compactitem}%1%\n\\end{compactitem}\n");

}}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: FormPropOOoTContext.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:20:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _XMLOFF_MUTABLEATTRLIST_HXX
#include "MutableAttrList.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif
#ifndef _XMLOFF_IGNORETCONTEXT_HXX
#include "IgnoreTContext.hxx"
#endif
#ifndef _XMLOFF_ACTIONMAPTYPESOOo_HXX
#include "ActionMapTypesOOo.hxx"
#endif
#ifndef _XMLOFF_ATTRTRANSFORMERACTION_HXX
#include "AttrTransformerAction.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERACTIONS_HXX
#include "TransformerActions.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif
#ifndef _XMLOFF_FORMPROPOOOTCONTEXT_HXX
#include "FormPropOOoTContext.hxx"
#endif

using ::rtl::OUString;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;

class XMLFormPropValueTContext_Impl : public XMLTransformerContext
{
    OUString m_aAttrQName;
    ::rtl::OUString m_aCharacters;
    sal_Bool m_bPersistent;
    sal_Bool m_bIsVoid;

public:
    TYPEINFO();

    // element content persistence only
    XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
                           const OUString& rQName );
    XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
                           const OUString& rQName,
                              sal_uInt16 nAttrPrefix,
                           XMLTokenEnum eAttrToken );

    virtual ~XMLFormPropValueTContext_Impl();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

    virtual void EndElement();

    virtual void Characters( const ::rtl::OUString& rChars );

    virtual sal_Bool IsPersistent() const;

    sal_Bool IsVoid() const { return m_bIsVoid; }
    const ::rtl::OUString& GetTextContent() const { return m_aCharacters; }
};

TYPEINIT1( XMLFormPropValueTContext_Impl, XMLTransformerContext );

XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
        XMLTransformerBase& rTransformer,
        const ::rtl::OUString& rQName ) :
    XMLTransformerContext( rTransformer, rQName ),
    m_bPersistent( sal_True ),
    m_bIsVoid( sal_False )
{
}

XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
        XMLTransformerBase& rTransformer,
        const ::rtl::OUString& rQName,
        sal_uInt16 nAttrPrefix,
        XMLTokenEnum eAttrToken ) :
    XMLTransformerContext( rTransformer, rQName ),
    m_aAttrQName( rTransformer.GetNamespaceMap().GetQNameByKey(
                    nAttrPrefix, GetXMLToken(eAttrToken) ) ),
    m_bPersistent( sal_True ),
    m_bIsVoid( sal_False )
{
}

XMLFormPropValueTContext_Impl::~XMLFormPropValueTContext_Impl()
{
}

void XMLFormPropValueTContext_Impl::StartElement(
    const Reference< XAttributeList >& rAttrList )
{
    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
                                                                 &aLocalName );
        if( XML_NAMESPACE_FORM == nPrefix &&
            IsXMLToken( aLocalName, XML_PROPERTY_IS_VOID ) &&
             IsXMLToken( rAttrList->getValueByIndex( i ), XML_TRUE ) )
            m_bIsVoid = sal_True;
    }
}

void XMLFormPropValueTContext_Impl::EndElement()
{
    if( !m_bPersistent )
    {
        XMLMutableAttributeList *pMutableAttrList =
            new XMLMutableAttributeList;
        Reference< XAttributeList > xAttrList( pMutableAttrList );
        pMutableAttrList->AddAttribute( m_aAttrQName,
                                        m_aCharacters );

        OUString aElemQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_FORM, GetXMLToken(XML_LIST_VALUE) ) );
        GetTransformer().GetDocHandler()->startElement( aElemQName,
                                                    xAttrList );
        GetTransformer().GetDocHandler()->endElement( aElemQName );
    }
}

void XMLFormPropValueTContext_Impl::Characters( const OUString& rChars )
{
    m_aCharacters += rChars;
}

sal_Bool XMLFormPropValueTContext_Impl::IsPersistent() const
{
    return m_bPersistent;
}

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

TYPEINIT1( XMLFormPropOOoTransformerContext, XMLTransformerContext );

XMLFormPropOOoTransformerContext::XMLFormPropOOoTransformerContext(
        XMLTransformerBase& rImp,
        const OUString& rQName ) :
    XMLTransformerContext( rImp, rQName ),
    m_aElemQName( rQName ),
    m_nValueTypeAttr( -1 ),
    m_eValueToken( XML_VALUE ),
    m_eValueTypeToken( XML_TOKEN_END ),
    m_bIsList( sal_False )
{
}

XMLFormPropOOoTransformerContext::~XMLFormPropOOoTransformerContext()
{
}

XMLTransformerContext *XMLFormPropOOoTransformerContext::CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const OUString& rQName,
        const Reference< XAttributeList >& )
{
    XMLTransformerContext *pContext = 0;

    if( XML_NAMESPACE_FORM == nPrefix &&
        IsXMLToken( rLocalName, XML_PROPERTY_VALUE ) )
    {
        if( m_bIsList )
        {
            pContext = new XMLFormPropValueTContext_Impl( GetTransformer(),
                                                          rQName,
                                                          XML_NAMESPACE_OFFICE,
                                                          m_eValueToken );
        }
        else if( !m_xValueContext.is() )
        {
            m_xValueContext=
                new XMLFormPropValueTContext_Impl( GetTransformer(), rQName );
            pContext = m_xValueContext.get();
        }
    }

    // default is ignore
    if( !pContext )
        pContext = new XMLIgnoreTransformerContext( GetTransformer(), rQName,
                                             sal_True, sal_True );
    return pContext;
}

void XMLFormPropOOoTransformerContext::StartElement(
    const Reference< XAttributeList >& rAttrList )
{

    XMLTransformerActions *pActions =
        GetTransformer().GetUserDefinedActions( OOO_FORM_PROP_ACTIONS );
    OSL_ENSURE( pActions, "go no actions" );

    XMLMutableAttributeList *pMutableAttrList =
        new XMLMutableAttributeList( rAttrList, sal_True );
    m_xAttrList = pMutableAttrList;

    OUString aValueType;
    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
                                                                 &aLocalName );
        XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
        XMLTransformerActions::const_iterator aIter =
            pActions->find( aKey );
        if( !(aIter == pActions->end() ) )
        {
            const OUString& rAttrValue = rAttrList->getValueByIndex( i );
            switch( (*aIter).second.m_nActionType )
            {
            case XML_ATACTION_RENAME:
                if( IsXMLToken( aLocalName, XML_PROPERTY_TYPE ) )
                {
                    aValueType = rAttrValue;
                    m_nValueTypeAttr = i;
                }
                {
                    OUString aNewAttrQName(
                        GetTransformer().GetNamespaceMap().GetQNameByKey(
                                (*aIter).second.GetQNamePrefixFromParam1(),
                                ::xmloff::token::GetXMLToken(
                                    (*aIter).second.GetQNameTokenFromParam1()) ) );
                    pMutableAttrList->RenameAttributeByIndex( i, aNewAttrQName );
                }
                break;
            case XML_ATACTION_REMOVE:
                if( IsXMLToken( aLocalName, XML_PROPERTY_IS_LIST ) )
                {
                    m_aElemQName =
                        GetTransformer().GetNamespaceMap().GetQNameByKey(
                        XML_NAMESPACE_FORM, GetXMLToken( XML_LIST_PROPERTY ) );
                    m_bIsList = sal_True;
                }
                pMutableAttrList->RemoveAttributeByIndex( i );
                --i;
                --nAttrCount;
                break;
            default:
                OSL_ENSURE( !this, "unknown action" );
                break;
            }
        }
    }

    if( aValueType.getLength() )
    {
        if( IsXMLToken( aValueType, XML_STRING ) )
            m_eValueToken = XML_STRING_VALUE;
        else if( IsXMLToken( aValueType, XML_BOOLEAN ) )
            m_eValueToken = XML_BOOLEAN_VALUE;
        else if( IsXMLToken( aValueType, XML_SHORT ) ||
                 IsXMLToken( aValueType, XML_INT ) ||
                 IsXMLToken( aValueType, XML_LONG ) ||
                 IsXMLToken( aValueType, XML_DOUBLE ) )
            m_eValueTypeToken = XML_FLOAT;
    }
}

void XMLFormPropOOoTransformerContext::EndElement()
{
    if( m_xValueContext.is() )
    {
        if( m_xValueContext->IsVoid() )
        {
            m_eValueTypeToken = XML_VOID;
        }
        else
        {
            OUString aAttrQName(
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_OFFICE, GetXMLToken(m_eValueToken) ) );
            static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
                ->AddAttribute( aAttrQName, m_xValueContext->GetTextContent() );
        }
    }

    if( m_nValueTypeAttr != -1 && m_eValueTypeToken != XML_TOKEN_END )
    {
        static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
            ->SetValueByIndex( m_nValueTypeAttr ,
                                GetXMLToken( m_eValueTypeToken ) );
    }

    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
                                                    m_xAttrList );
    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
}
<commit_msg>INTEGRATION: CWS changefileheader (1.6.162); FILE MERGED 2008/04/01 13:05:46 thb 1.6.162.2: #i85898# Stripping all external header guards 2008/03/31 16:28:50 rt 1.6.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: FormPropOOoTContext.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include "MutableAttrList.hxx"
#include "xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include "IgnoreTContext.hxx"
#ifndef _XMLOFF_ACTIONMAPTYPESOOo_HXX
#include "ActionMapTypesOOo.hxx"
#endif
#include "AttrTransformerAction.hxx"
#include "TransformerActions.hxx"
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif
#include "FormPropOOoTContext.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;

class XMLFormPropValueTContext_Impl : public XMLTransformerContext
{
    OUString m_aAttrQName;
    ::rtl::OUString m_aCharacters;
    sal_Bool m_bPersistent;
    sal_Bool m_bIsVoid;

public:
    TYPEINFO();

    // element content persistence only
    XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
                           const OUString& rQName );
    XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
                           const OUString& rQName,
                              sal_uInt16 nAttrPrefix,
                           XMLTokenEnum eAttrToken );

    virtual ~XMLFormPropValueTContext_Impl();

    virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

    virtual void EndElement();

    virtual void Characters( const ::rtl::OUString& rChars );

    virtual sal_Bool IsPersistent() const;

    sal_Bool IsVoid() const { return m_bIsVoid; }
    const ::rtl::OUString& GetTextContent() const { return m_aCharacters; }
};

TYPEINIT1( XMLFormPropValueTContext_Impl, XMLTransformerContext );

XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
        XMLTransformerBase& rTransformer,
        const ::rtl::OUString& rQName ) :
    XMLTransformerContext( rTransformer, rQName ),
    m_bPersistent( sal_True ),
    m_bIsVoid( sal_False )
{
}

XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
        XMLTransformerBase& rTransformer,
        const ::rtl::OUString& rQName,
        sal_uInt16 nAttrPrefix,
        XMLTokenEnum eAttrToken ) :
    XMLTransformerContext( rTransformer, rQName ),
    m_aAttrQName( rTransformer.GetNamespaceMap().GetQNameByKey(
                    nAttrPrefix, GetXMLToken(eAttrToken) ) ),
    m_bPersistent( sal_True ),
    m_bIsVoid( sal_False )
{
}

XMLFormPropValueTContext_Impl::~XMLFormPropValueTContext_Impl()
{
}

void XMLFormPropValueTContext_Impl::StartElement(
    const Reference< XAttributeList >& rAttrList )
{
    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
                                                                 &aLocalName );
        if( XML_NAMESPACE_FORM == nPrefix &&
            IsXMLToken( aLocalName, XML_PROPERTY_IS_VOID ) &&
             IsXMLToken( rAttrList->getValueByIndex( i ), XML_TRUE ) )
            m_bIsVoid = sal_True;
    }
}

void XMLFormPropValueTContext_Impl::EndElement()
{
    if( !m_bPersistent )
    {
        XMLMutableAttributeList *pMutableAttrList =
            new XMLMutableAttributeList;
        Reference< XAttributeList > xAttrList( pMutableAttrList );
        pMutableAttrList->AddAttribute( m_aAttrQName,
                                        m_aCharacters );

        OUString aElemQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_FORM, GetXMLToken(XML_LIST_VALUE) ) );
        GetTransformer().GetDocHandler()->startElement( aElemQName,
                                                    xAttrList );
        GetTransformer().GetDocHandler()->endElement( aElemQName );
    }
}

void XMLFormPropValueTContext_Impl::Characters( const OUString& rChars )
{
    m_aCharacters += rChars;
}

sal_Bool XMLFormPropValueTContext_Impl::IsPersistent() const
{
    return m_bPersistent;
}

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

TYPEINIT1( XMLFormPropOOoTransformerContext, XMLTransformerContext );

XMLFormPropOOoTransformerContext::XMLFormPropOOoTransformerContext(
        XMLTransformerBase& rImp,
        const OUString& rQName ) :
    XMLTransformerContext( rImp, rQName ),
    m_aElemQName( rQName ),
    m_nValueTypeAttr( -1 ),
    m_eValueToken( XML_VALUE ),
    m_eValueTypeToken( XML_TOKEN_END ),
    m_bIsList( sal_False )
{
}

XMLFormPropOOoTransformerContext::~XMLFormPropOOoTransformerContext()
{
}

XMLTransformerContext *XMLFormPropOOoTransformerContext::CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const OUString& rQName,
        const Reference< XAttributeList >& )
{
    XMLTransformerContext *pContext = 0;

    if( XML_NAMESPACE_FORM == nPrefix &&
        IsXMLToken( rLocalName, XML_PROPERTY_VALUE ) )
    {
        if( m_bIsList )
        {
            pContext = new XMLFormPropValueTContext_Impl( GetTransformer(),
                                                          rQName,
                                                          XML_NAMESPACE_OFFICE,
                                                          m_eValueToken );
        }
        else if( !m_xValueContext.is() )
        {
            m_xValueContext=
                new XMLFormPropValueTContext_Impl( GetTransformer(), rQName );
            pContext = m_xValueContext.get();
        }
    }

    // default is ignore
    if( !pContext )
        pContext = new XMLIgnoreTransformerContext( GetTransformer(), rQName,
                                             sal_True, sal_True );
    return pContext;
}

void XMLFormPropOOoTransformerContext::StartElement(
    const Reference< XAttributeList >& rAttrList )
{

    XMLTransformerActions *pActions =
        GetTransformer().GetUserDefinedActions( OOO_FORM_PROP_ACTIONS );
    OSL_ENSURE( pActions, "go no actions" );

    XMLMutableAttributeList *pMutableAttrList =
        new XMLMutableAttributeList( rAttrList, sal_True );
    m_xAttrList = pMutableAttrList;

    OUString aValueType;
    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
                                                                 &aLocalName );
        XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
        XMLTransformerActions::const_iterator aIter =
            pActions->find( aKey );
        if( !(aIter == pActions->end() ) )
        {
            const OUString& rAttrValue = rAttrList->getValueByIndex( i );
            switch( (*aIter).second.m_nActionType )
            {
            case XML_ATACTION_RENAME:
                if( IsXMLToken( aLocalName, XML_PROPERTY_TYPE ) )
                {
                    aValueType = rAttrValue;
                    m_nValueTypeAttr = i;
                }
                {
                    OUString aNewAttrQName(
                        GetTransformer().GetNamespaceMap().GetQNameByKey(
                                (*aIter).second.GetQNamePrefixFromParam1(),
                                ::xmloff::token::GetXMLToken(
                                    (*aIter).second.GetQNameTokenFromParam1()) ) );
                    pMutableAttrList->RenameAttributeByIndex( i, aNewAttrQName );
                }
                break;
            case XML_ATACTION_REMOVE:
                if( IsXMLToken( aLocalName, XML_PROPERTY_IS_LIST ) )
                {
                    m_aElemQName =
                        GetTransformer().GetNamespaceMap().GetQNameByKey(
                        XML_NAMESPACE_FORM, GetXMLToken( XML_LIST_PROPERTY ) );
                    m_bIsList = sal_True;
                }
                pMutableAttrList->RemoveAttributeByIndex( i );
                --i;
                --nAttrCount;
                break;
            default:
                OSL_ENSURE( !this, "unknown action" );
                break;
            }
        }
    }

    if( aValueType.getLength() )
    {
        if( IsXMLToken( aValueType, XML_STRING ) )
            m_eValueToken = XML_STRING_VALUE;
        else if( IsXMLToken( aValueType, XML_BOOLEAN ) )
            m_eValueToken = XML_BOOLEAN_VALUE;
        else if( IsXMLToken( aValueType, XML_SHORT ) ||
                 IsXMLToken( aValueType, XML_INT ) ||
                 IsXMLToken( aValueType, XML_LONG ) ||
                 IsXMLToken( aValueType, XML_DOUBLE ) )
            m_eValueTypeToken = XML_FLOAT;
    }
}

void XMLFormPropOOoTransformerContext::EndElement()
{
    if( m_xValueContext.is() )
    {
        if( m_xValueContext->IsVoid() )
        {
            m_eValueTypeToken = XML_VOID;
        }
        else
        {
            OUString aAttrQName(
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_OFFICE, GetXMLToken(m_eValueToken) ) );
            static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
                ->AddAttribute( aAttrQName, m_xValueContext->GetTextContent() );
        }
    }

    if( m_nValueTypeAttr != -1 && m_eValueTypeToken != XML_TOKEN_END )
    {
        static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
            ->SetValueByIndex( m_nValueTypeAttr ,
                                GetXMLToken( m_eValueTypeToken ) );
    }

    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
                                                    m_xAttrList );
    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
}
<|endoftext|>