<commit_before>/* Copyright 2017 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/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"

namespace tensorflow {

using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

REGISTER_OP("TPUReplicateMetadata")
    .Attr("num_replicas: int >= 0")
    .Attr("topology: string = \"\"")
    .Attr("device_assignment: list(int) = []")
    .Attr("computation_shape: list(int) = []")
    .SetShapeFn(shape_inference::UnknownShape);

REGISTER_OP("TPUReplicatedInput")
    .Input("inputs: N * T")
    .Output("output: T")
    .Attr("N: int >= 1")
    .Attr("T: type")
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle cur = c->input(c->num_inputs() - 1);
      for (int i = c->num_inputs() - 2; i >= 0; --i) {
        TF_RETURN_WITH_CONTEXT_IF_ERROR(c->Merge(c->input(i), cur, &cur),
                                        "From merging shape ", i,
                                        " with other shapes.");
      }
      c->set_output(0, cur);
      return Status::OK();
    })
    .Doc(
        "Operator that connects N unreplicated inputs to an N-way "
        "replicated TPU computation.");

REGISTER_OP("TPUReplicatedOutput")
    .Input("input: T")
    .Output("outputs: num_replicas * T")
    .Attr("num_replicas: int >= 1")
    .Attr("T: type")
    .SetShapeFn([](InferenceContext* c) {
      for (int i = 0; i < c->num_outputs(); ++i) {
        c->set_output(i, c->input(0));
      }
      return Status::OK();
    })
    .Doc(
        "Operator that connects the output of an N-way replicated TPU "
        "computation to N separate outputs.");

REGISTER_OP("TPUReplicate")
    .Attr("computation: func")
    .Attr("num_replicas: int >= 1")
    .Attr("topology: string = \"\"")
    .Attr("device_assignment: list(int) = []")
    .Attr("computation_shape: list(int) = []")
    .Attr("Tinputs: list(type) >= 0")
    .Attr("Tbroadcast_inputs: list(type) >= 0")
    .Attr("NumVariables: int >= 0")
    .Attr("output_types: list(type) >= 0")
    .Input("inputs: Tinputs")
    .Input("broadcast_inputs: Tbroadcast_inputs")
    .Input("variables: NumVariables * resource")
    .Output("outputs: output_types")
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
Runs replicated computations on a distributed TPU system.

computation: a function containing the computation to run.
num_replicas: the number of replicas of the computation to run.
topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
computation_shape: a [mesh_dimension] array describing the shape of each
  computation replica in numbers of cores in the TPU mesh.
device_assignment: a flattened array with shape
  [replica] + computation_shape + [mesh_dimension] that maps the coordinates of
  logical cores in each replica of a computation to physical coordinates in
  the TPU topology.
Tinputs: the types of the arguments to 'computation'.
inputs: the inputs to 'computation', flattened, in replica-major order.
Tbroadcast_inputs: the types of the additional arguments to broadcast to all
  replicas.
broadcast_inputs: additional arguments to broadcast to all replicas. The
  broadcast inputs are appended to the per-replica inputs when calling
  computation.
output_types: the types of the outputs of 'computation'.
outputs: the outputs of 'computation'.
)doc");

}  // namespace tensorflow
<commit_msg>Adds a 'guaranteed_constants' list of tensors to TPUReplicate Op.<commit_after>/* Copyright 2017 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/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"

namespace tensorflow {

using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

REGISTER_OP("TPUReplicateMetadata")
    .Attr("num_replicas: int >= 0")
    .Attr("topology: string = \"\"")
    .Attr("device_assignment: list(int) = []")
    .Attr("computation_shape: list(int) = []")
    .SetShapeFn(shape_inference::UnknownShape);

REGISTER_OP("TPUReplicatedInput")
    .Input("inputs: N * T")
    .Output("output: T")
    .Attr("N: int >= 1")
    .Attr("T: type")
    .SetShapeFn([](InferenceContext* c) {
      ShapeHandle cur = c->input(c->num_inputs() - 1);
      for (int i = c->num_inputs() - 2; i >= 0; --i) {
        TF_RETURN_WITH_CONTEXT_IF_ERROR(c->Merge(c->input(i), cur, &cur),
                                        "From merging shape ", i,
                                        " with other shapes.");
      }
      c->set_output(0, cur);
      return Status::OK();
    })
    .Doc(
        "Operator that connects N unreplicated inputs to an N-way "
        "replicated TPU computation.");

REGISTER_OP("TPUReplicatedOutput")
    .Input("input: T")
    .Output("outputs: num_replicas * T")
    .Attr("num_replicas: int >= 1")
    .Attr("T: type")
    .SetShapeFn([](InferenceContext* c) {
      for (int i = 0; i < c->num_outputs(); ++i) {
        c->set_output(i, c->input(0));
      }
      return Status::OK();
    })
    .Doc(
        "Operator that connects the output of an N-way replicated TPU "
        "computation to N separate outputs.");

REGISTER_OP("TPUReplicate")
    .Attr("computation: func")
    .Attr("num_replicas: int >= 1")
    .Attr("topology: string = \"\"")
    .Attr("device_assignment: list(int) = []")
    .Attr("computation_shape: list(int) = []")
    .Attr("Tinputs: list(type) >= 0")
    .Attr("Tbroadcast_inputs: list(type) >= 0")
    .Attr("NumVariables: int >= 0")
    .Attr("Tguaranteed_constants: list(type) >= 0")
    .Attr("output_types: list(type) >= 0")
    .Input("inputs: Tinputs")
    .Input("broadcast_inputs: Tbroadcast_inputs")
    .Input("variables: NumVariables * resource")
    .Input("guaranteed_constants: Tguaranteed_constants")
    .Output("outputs: output_types")
    .SetShapeFn(shape_inference::UnknownShape)
    .Doc(R"doc(
Runs replicated computations on a distributed TPU system.

computation: a function containing the computation to run.
num_replicas: the number of replicas of the computation to run.
topology: A serialized tensorflow.tpu.TopologyProto that describes the TPU
topology.
computation_shape: a [mesh_dimension] array describing the shape of each
  computation replica in numbers of cores in the TPU mesh.
device_assignment: a flattened array with shape
  [replica] + computation_shape + [mesh_dimension] that maps the coordinates of
  logical cores in each replica of a computation to physical coordinates in
  the TPU topology.
Tinputs: the types of the arguments to 'computation'.
inputs: the inputs to 'computation', flattened, in replica-major order.
Tbroadcast_inputs: the types of the additional arguments to broadcast to all
  replicas.
Tguaranteed_constants: the types of the arguments to 'guaranteed_constants'.
broadcast_inputs: additional arguments to broadcast to all replicas. The
  broadcast inputs are appended to the per-replica inputs when calling
  computation.
guaranteed_constants: arguments which have been guaranteed to not
change their values during the session lifetime. These contain tensors marked as
constant using the GuaranteeConstOp.
output_types: the types of the outputs of 'computation'.
outputs: the outputs of 'computation'.
)doc");

}  // namespace tensorflow
<|endoftext|>


<commit_before><commit_msg>Spike Model auto creating any unused components.<commit_after><|endoftext|>


<commit_before><commit_msg>BUG: Added back extra start-points for T2 fitting<commit_after><|endoftext|>


<commit_before><commit_msg>TitanHideTest: do not call CheckSystemDebugControl() under WOW64<commit_after><|endoftext|>


<commit_before>#include <cassert>
#include <cstddef>
#include <cstring>

#include "alloc.h"
#include "cons.h"

namespace
{
using namespace mclisp;

const std::string kPname = "PNAME";

ConsCell* AtomMagic()
{
  return const_cast<ConsCell*>(Alloc::AtomMagic());
}

std::string Barf(ConsCell * const * c)
{
  // Barf sizeof c bytes into s. The length of the string may be less than
  // sizeof c bytes, in which case we truncate the string at the null byte.
  std::string s(reinterpret_cast<const char *>(c), sizeof c);
  return s.substr(0, s.find('\0'));
}

std::string Slurp(ConsCell** c, const std::string& s)
{
  strncpy(reinterpret_cast<char *>(c), s.c_str(), sizeof c);
  return s.length() > sizeof c ? s.substr(sizeof c, std::string::npos) : "";
}

const ConsCell* Get(std::string key, const ConsCell* alist)
{
  std::string thiskey;
  const ConsCell* next = alist;
  while (thiskey != key && next != kNil)
  {
    thiskey = Barf(&next->car_);
    next = next->cdr_;
  }
  return next == kNil ? kNil : next->car_;
}

std::string StringFromPname(const ConsCell* c)
{
  std::string pname;
  const ConsCell* data;

  while (c != kNil)
  {
    data = c->car_;
    pname += Barf(&data->car_);
    pname += Barf(&data->cdr_);
    c = c->cdr_;
  }

  return pname;
}

ConsCell* MakePnameList(const std::string& name)
{
  std::string rest(name);
  ConsCell *head, *prev, *curr, *data;
  head = prev = curr = data = nullptr;

  while (rest.length() > 0)
  {
    curr = Alloc::Allocate();
    data = Alloc::Allocate();
    rest = Slurp(&data->car_, rest);
    rest = Slurp(&data->cdr_, rest);

    if (!head)
      head = curr;
    if (prev)
      prev->cdr_ = curr;

    curr->car_ = data;
    prev = curr;
  }

  curr->cdr_ = const_cast<ConsCell*>(kNil);
  return head;
}

ConsCell* MakeAssociationList(const std::string& name)
{
  ConsCell* pname = Alloc::Allocate();
  ConsCell* link = Alloc::Allocate();

  Slurp(&pname->car_, kPname);
  pname->cdr_ = link;

  link->car_ = MakePnameList(name);
  link->cdr_ = const_cast<ConsCell*>(kNil);

  return pname;
}

} // namespace

namespace mclisp
{
const ConsCell* kT = nullptr;
const ConsCell* kNil = nullptr;

void HackToFixNil()
{
  // TODO Get rid of HackToFixNil.
  // The association list of kNil should have only one item, it's pname. The
  // structure of kNil's alist should look like this:
  //          +----+----+     +-----+----+      +----+----+
  // kNil --->|ATOM|    |---->|PNAME|    |----->|    |    |-----> nullptr
  //          +----+----+     +-----+----+      +----+----+
  //                                              |
  //                                        +-----+
  //                                        |   +----+----+
  //                                        +-->|    |    |-----> nullptr
  //                                            +----+----+
  //                                              |
  //                                        +-----+
  //                                        |   +----+----+
  //                                        +-->|NIL |    |
  //                                            +----+----+
  //
  // The nullptr's need to be converted now to Nil's. The reason for this hack
  // is that Nil is symbol that is created and interned in Reader::Init. But
  // like all symbols, Nil's alist references Nil as the list terminator. At the
  // time when Nil is being created, kNil is still pointing to nullptr, and thus
  // we must go back an replace the nullptr's with pointers to kNil after kNil
  // has been initialized. The other option is to just nullptr as the list
  // terminator for symbol alist structure. That would avoid the need for this
  // hack, but would mean the symbol alist is not a proper list.
  assert (kNil->cdr_->cdr_->cdr_ == nullptr);
  assert (kNil->cdr_->cdr_->car_->cdr_ == nullptr);
  kNil->cdr_->cdr_->cdr_ = const_cast<ConsCell *>(kNil);
  kNil->cdr_->cdr_->car_->cdr_ = const_cast<ConsCell *>(kNil);
}

const ConsCell* MakeCons(const ConsCell* car, const ConsCell* cdr)
{
  ConsCell* c = Alloc::Allocate();
  c->car_ = const_cast<ConsCell*>(car);
  c->cdr_ = const_cast<ConsCell*>(cdr);
  return c;
}

const ConsCell* MakeSymbol(const std::string& name)
{
  assert(name.length());
  ConsCell* c = Alloc::Allocate();
  c->car_ = AtomMagic();
  c->cdr_ = MakeAssociationList(name);
  return c;
}

inline bool Symbolp(const ConsCell* c)
{
  return c->car_ == AtomMagic();
}

inline bool Consp(const ConsCell* c)
{
  return !Symbolp(c);
}

const std::string SymbolName(const ConsCell* symbol)
{
  if (!Symbolp(symbol))
    // TODO Throw better error.
    throw std::logic_error("Attempt to call SymbolName on a non-symbol.");
  return StringFromPname(Get(kPname, symbol->cdr_));
}

// Logical and relational operators (==, !=, <, >, <=, >=)
bool operator==(const ConsCell& lhs, const ConsCell& rhs)
{
  if (Symbolp(&lhs) && Symbolp(&rhs))
    return &lhs == &rhs;

  if (Consp(&lhs) && Consp(&rhs))
    return *lhs.car_ == *rhs.car_ && *lhs.cdr_ == *rhs.cdr_;

  return false;
}

bool operator< (const ConsCell& lhs, const ConsCell& rhs)
{
  if (Symbolp(&lhs) && Symbolp(&rhs))
    return SymbolName(&lhs) < SymbolName(&rhs);

  if (Consp(&lhs) && Consp(&rhs))
    return (*lhs.car_ < *rhs.car_ ||
            (*lhs.car_ == *rhs.car_ && *lhs.cdr_ < *rhs.cdr_));

  return false;
}
bool operator!=(const ConsCell& lhs, const ConsCell& rhs){return !operator==(lhs,rhs);}
bool operator> (const ConsCell& lhs, const ConsCell& rhs){return  operator< (rhs,lhs);}
bool operator<=(const ConsCell& lhs, const ConsCell& rhs){return !operator> (lhs,rhs);}
bool operator>=(const ConsCell& lhs, const ConsCell& rhs){return !operator< (lhs,rhs);}

std::ostream& operator<<(std::ostream& os, const ConsCell& cons)
{
  if (Symbolp(&cons))
    return os << SymbolName(&cons);

  // FIXME
  //return os << "(" << *cons.car_ << " . " << *cons.cdr_ << ")";
  return os;
}

} // namespace mclisp
<commit_msg>Implement operator<< for conses.<commit_after>#include <cassert>
#include <cstddef>
#include <cstring>

#include "alloc.h"
#include "cons.h"

namespace
{
using namespace mclisp;

const std::string kPname = "PNAME";

ConsCell* AtomMagic()
{
  return const_cast<ConsCell*>(Alloc::AtomMagic());
}

std::string Barf(ConsCell * const * c)
{
  // Barf sizeof c bytes into s. The length of the string may be less than
  // sizeof c bytes, in which case we truncate the string at the null byte.
  std::string s(reinterpret_cast<const char *>(c), sizeof c);
  return s.substr(0, s.find('\0'));
}

std::string Slurp(ConsCell** c, const std::string& s)
{
  strncpy(reinterpret_cast<char *>(c), s.c_str(), sizeof c);
  return s.length() > sizeof c ? s.substr(sizeof c, std::string::npos) : "";
}

const ConsCell* Get(std::string key, const ConsCell* alist)
{
  std::string thiskey;
  const ConsCell* next = alist;
  while (thiskey != key && next != kNil)
  {
    thiskey = Barf(&next->car_);
    next = next->cdr_;
  }
  return next == kNil ? kNil : next->car_;
}

std::string StringFromPname(const ConsCell* c)
{
  std::string pname;
  const ConsCell* data;

  while (c != kNil)
  {
    data = c->car_;
    pname += Barf(&data->car_);
    pname += Barf(&data->cdr_);
    c = c->cdr_;
  }

  return pname;
}

ConsCell* MakePnameList(const std::string& name)
{
  std::string rest(name);
  ConsCell *head, *prev, *curr, *data;
  head = prev = curr = data = nullptr;

  while (rest.length() > 0)
  {
    curr = Alloc::Allocate();
    data = Alloc::Allocate();
    rest = Slurp(&data->car_, rest);
    rest = Slurp(&data->cdr_, rest);

    if (!head)
      head = curr;
    if (prev)
      prev->cdr_ = curr;

    curr->car_ = data;
    prev = curr;
  }

  curr->cdr_ = const_cast<ConsCell*>(kNil);
  return head;
}

ConsCell* MakeAssociationList(const std::string& name)
{
  ConsCell* pname = Alloc::Allocate();
  ConsCell* link = Alloc::Allocate();

  Slurp(&pname->car_, kPname);
  pname->cdr_ = link;

  link->car_ = MakePnameList(name);
  link->cdr_ = const_cast<ConsCell*>(kNil);

  return pname;
}

} // namespace

namespace mclisp
{
const ConsCell* kT = nullptr;
const ConsCell* kNil = nullptr;

void HackToFixNil()
{
  // TODO Get rid of HackToFixNil.
  // The association list of kNil should have only one item, it's pname. The
  // structure of kNil's alist should look like this:
  //          +----+----+     +-----+----+      +----+----+
  // kNil --->|ATOM|    |---->|PNAME|    |----->|    |    |-----> nullptr
  //          +----+----+     +-----+----+      +----+----+
  //                                              |
  //                                        +-----+
  //                                        |   +----+----+
  //                                        +-->|    |    |-----> nullptr
  //                                            +----+----+
  //                                              |
  //                                        +-----+
  //                                        |   +----+----+
  //                                        +-->|NIL |    |
  //                                            +----+----+
  //
  // The nullptr's need to be converted now to Nil's. The reason for this hack
  // is that Nil is symbol that is created and interned in Reader::Init. But
  // like all symbols, Nil's alist references Nil as the list terminator. At the
  // time when Nil is being created, kNil is still pointing to nullptr, and thus
  // we must go back an replace the nullptr's with pointers to kNil after kNil
  // has been initialized. The other option is to just nullptr as the list
  // terminator for symbol alist structure. That would avoid the need for this
  // hack, but would mean the symbol alist is not a proper list.
  assert (kNil->cdr_->cdr_->cdr_ == nullptr);
  assert (kNil->cdr_->cdr_->car_->cdr_ == nullptr);
  kNil->cdr_->cdr_->cdr_ = const_cast<ConsCell *>(kNil);
  kNil->cdr_->cdr_->car_->cdr_ = const_cast<ConsCell *>(kNil);
}

const ConsCell* MakeCons(const ConsCell* car, const ConsCell* cdr)
{
  ConsCell* c = Alloc::Allocate();
  c->car_ = const_cast<ConsCell*>(car);
  c->cdr_ = const_cast<ConsCell*>(cdr);
  return c;
}

const ConsCell* MakeSymbol(const std::string& name)
{
  assert(name.length());
  ConsCell* c = Alloc::Allocate();
  c->car_ = AtomMagic();
  c->cdr_ = MakeAssociationList(name);
  return c;
}

inline bool Symbolp(const ConsCell* c)
{
  return c->car_ == AtomMagic();
}

inline bool Consp(const ConsCell* c)
{
  return !Symbolp(c);
}

const std::string SymbolName(const ConsCell* symbol)
{
  if (!Symbolp(symbol))
    // TODO Throw better error.
    throw std::logic_error("Attempt to call SymbolName on a non-symbol.");
  return StringFromPname(Get(kPname, symbol->cdr_));
}

// Logical and relational operators (==, !=, <, >, <=, >=)
bool operator==(const ConsCell& lhs, const ConsCell& rhs)
{
  if (Symbolp(&lhs) && Symbolp(&rhs))
    return &lhs == &rhs;

  if (Consp(&lhs) && Consp(&rhs))
    return *lhs.car_ == *rhs.car_ && *lhs.cdr_ == *rhs.cdr_;

  return false;
}

bool operator< (const ConsCell& lhs, const ConsCell& rhs)
{
  if (Symbolp(&lhs) && Symbolp(&rhs))
    return SymbolName(&lhs) < SymbolName(&rhs);

  if (Consp(&lhs) && Consp(&rhs))
    return (*lhs.car_ < *rhs.car_ ||
            (*lhs.car_ == *rhs.car_ && *lhs.cdr_ < *rhs.cdr_));

  return false;
}
bool operator!=(const ConsCell& lhs, const ConsCell& rhs){return !operator==(lhs,rhs);}
bool operator> (const ConsCell& lhs, const ConsCell& rhs){return  operator< (rhs,lhs);}
bool operator<=(const ConsCell& lhs, const ConsCell& rhs){return !operator> (lhs,rhs);}
bool operator>=(const ConsCell& lhs, const ConsCell& rhs){return !operator< (lhs,rhs);}

std::ostream& operator<<(std::ostream& os, const ConsCell& cons)
{
  if (Symbolp(&cons))
    return os << SymbolName(&cons);

  if (!cons.car_ || !cons.cdr_)
    // TODO error handling.
    throw std::logic_error("Attempted to print ConsCell with null car/cdr.");

  // TODO Pretty-print proper lists.
  // TODO Handle circular list structure.
  // TODO Figure out what C++ templating hell causes stream formatting to fail
  // when specifying a literal const char*, rather than a std::string.
  // return os << "(" << *cons.car_ << " . " << *cons.cdr_ << ")";
  static const std::string open("(");
  static const std::string dot(" . ");
  static const std::string close(")");
  return os << open << *cons.car_ << dot << *cons.cdr_ << close;
}

} // namespace mclisp
<|endoftext|>


<commit_before>// Copyright 2013 Mirus Project

// 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.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>
#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>

namespace mirus
{
    extern "C" void kernel_main()
    {
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();

        while (true);
    }
} // !namespace
<commit_msg>Updated ISR init code in kernel.cpp<commit_after>// Copyright 2013 Mirus Project

// 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.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>
#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>
#include <cpu/isr.hpp>

namespace mirus
{
    extern "C" void kernel_main()
    {
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();

        while (true);
    }
} // !namespace
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "FileHelper.h"
#include "ConfigMgr.h"
#include "Exception.h"

#ifndef _WIN32
#include <libgen.h>
#else
#include <direct.h>
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>

#include <map>
#include <cstring>
#include <iostream>
#include <fstream>

using namespace std;

namespace avg {

string getPath(const string& sFilename)
{
    if (sFilename.length() > 0 && sFilename.at(sFilename.length()-1) == '/') {
        return sFilename;
    }
#ifdef _WIN32
    int pos = int(sFilename.find_last_of("\\/"));
    string dirName;
    if (pos >= 0) {
        dirName = sFilename.substr(0, pos+1);
    } else {
        dirName = sFilename;
    }
#else
    char * pszBuffer = strdup(sFilename.c_str());

    string dirName(dirname(pszBuffer));
    free(pszBuffer);
    dirName += "/";
#endif

    return dirName;
}

string getFilenamePart(const string& sFilename)
{
    if (sFilename.find_last_of("\\/") == 0) {
        return sFilename;
    }
#ifdef _WIN32
    int pos = int(sFilename.find_last_of("\\/"));
    string BaseName(sFilename.substr(pos+1));
#else
    char * pszBuffer = strdup(sFilename.c_str());

    string BaseName(basename(pszBuffer));
    free(pszBuffer);
#endif

    return BaseName;
}

string getExtension(const string& sFilename)
{
    int pos = int(sFilename.find_last_of("."));
    if (pos == 0) {
        return "";
    } else {
        return sFilename.substr(pos+1);
    }
}

string getCWD()
{

    char szBuf[1024];
#ifdef _WIN32
    char * pBuf = _getcwd(szBuf, 1024);
#else
    char * pBuf = getcwd(szBuf, 1024);
#endif
    return string(pBuf)+"/";
}

bool isAbsPath(const std::string& path)
{
#ifdef _WIN32
    return ((path.length() != 0) && path[1] == ':') || path[0] == '\\' || path[0] == '/';
#else
    return path[0] == '/';
#endif

}

bool fileExists(const string& sFilename)
{
    struct stat myStat;
    return stat(sFilename.c_str(), &myStat) != -1;
}

void readWholeFile(const string& sFilename, string& sContent)
{
    ifstream file(sFilename.c_str());
    if (!file) {
        throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
                " for reading failed.");
    }
    vector<char> buffer(65536);
    sContent.resize(0);
    while (file) {
        file.read(&(*buffer.begin()), (streamsize)(buffer.size()));
        sContent.append(&(*buffer.begin()), (unsigned)file.gcount());
    }
    if (!file.eof() || file.bad()) {
        throw Exception(AVG_ERR_FILEIO, "Reading "+sFilename+
                " failed.");
    }
}

void writeWholeFile(const string& sFilename, const string& sContent)
{
    ofstream outFile(sFilename.c_str());
    if (!outFile) {
        throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
                " for writing failed.");
    }
    outFile << sContent;
}

void copyFile(const string& sSourceFile, const string& sDestFile)
{
    string sData;

    readWholeFile(sSourceFile, sData);
    writeWholeFile(sDestFile, sData);
}

}
<commit_msg>vertexsubmit branch: Include cleanup.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "FileHelper.h"
#include "Exception.h"

#ifndef _WIN32
#include <libgen.h>
#else
#include <direct.h>
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include <vector>
#include <map>
#include <cstring>
#include <iostream>
#include <fstream>

using namespace std;

namespace avg {

string getPath(const string& sFilename)
{
    if (sFilename.length() > 0 && sFilename.at(sFilename.length()-1) == '/') {
        return sFilename;
    }
#ifdef _WIN32
    int pos = int(sFilename.find_last_of("\\/"));
    string dirName;
    if (pos >= 0) {
        dirName = sFilename.substr(0, pos+1);
    } else {
        dirName = sFilename;
    }
#else
    char * pszBuffer = strdup(sFilename.c_str());

    string dirName(dirname(pszBuffer));
    free(pszBuffer);
    dirName += "/";
#endif

    return dirName;
}

string getFilenamePart(const string& sFilename)
{
    if (sFilename.find_last_of("\\/") == 0) {
        return sFilename;
    }
#ifdef _WIN32
    int pos = int(sFilename.find_last_of("\\/"));
    string BaseName(sFilename.substr(pos+1));
#else
    char * pszBuffer = strdup(sFilename.c_str());

    string BaseName(basename(pszBuffer));
    free(pszBuffer);
#endif

    return BaseName;
}

string getExtension(const string& sFilename)
{
    int pos = int(sFilename.find_last_of("."));
    if (pos == 0) {
        return "";
    } else {
        return sFilename.substr(pos+1);
    }
}

string getCWD()
{

    char szBuf[1024];
#ifdef _WIN32
    char * pBuf = _getcwd(szBuf, 1024);
#else
    char * pBuf = getcwd(szBuf, 1024);
#endif
    return string(pBuf)+"/";
}

bool isAbsPath(const std::string& path)
{
#ifdef _WIN32
    return ((path.length() != 0) && path[1] == ':') || path[0] == '\\' || path[0] == '/';
#else
    return path[0] == '/';
#endif

}

bool fileExists(const string& sFilename)
{
    struct stat myStat;
    return stat(sFilename.c_str(), &myStat) != -1;
}

void readWholeFile(const string& sFilename, string& sContent)
{
    ifstream file(sFilename.c_str());
    if (!file) {
        throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
                " for reading failed.");
    }
    vector<char> buffer(65536);
    sContent.resize(0);
    while (file) {
        file.read(&(*buffer.begin()), (streamsize)(buffer.size()));
        sContent.append(&(*buffer.begin()), (unsigned)file.gcount());
    }
    if (!file.eof() || file.bad()) {
        throw Exception(AVG_ERR_FILEIO, "Reading "+sFilename+
                " failed.");
    }
}

void writeWholeFile(const string& sFilename, const string& sContent)
{
    ofstream outFile(sFilename.c_str());
    if (!outFile) {
        throw Exception(AVG_ERR_FILEIO, "Opening "+sFilename+
                " for writing failed.");
    }
    outFile << sContent;
}

void copyFile(const string& sSourceFile, const string& sDestFile)
{
    string sData;

    readWholeFile(sSourceFile, sData);
    writeWholeFile(sDestFile, sData);
}

}
<|endoftext|>


<commit_before>/*VRP*********************************************************************
 *
 * vehicle routing problems
 *      A collection of C++ classes for developing VRP solutions
 *      and specific solutions developed using these classes.
 *
 * Copyright 2014 Stephen Woodbridge <woodbri@imaptools.com>
 * Copyright 2014 Vicky Vergara <vicky_vergara@hotmail.com>
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the MIT License. Please file LICENSE for details.
 *
 ********************************************************************VRP*/

#include <cmath>
#include <string>
#include <iostream>
#include <sstream>

#ifdef DOVRPLOG
#include "./logger.h"
#endif

#include "./node.h"

/*!
 * \brief Compute the Haversine spherical distance between two nodes.
 *
 * Haversine spherical distance between two nodes with lat/lon values when
 * the nodes x,y is loaded with longitude,latitude values.
 *
 */
double Node::haversineDistance(const Node &other) const {
  const double pi = 3.14159265358979323846;
  const double deg2rad = pi / 180.0;
  const double radius = 6367000;  // Earth radius 6367 Km in meters
  double dlon = (other.x_ - x_) * deg2rad;
  double dlat = (other.y_ - y_) * deg2rad;
  double a = pow(sin(dlat / 2.0), 2) + cos(y_) * cos(other.y_) *
             pow(sin(dlon / 2.0), 2);
  double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
  double dist = radius * c;
  return dist;
}

double Node::distance(const Node &other) const {
  if (!(isLatLon() && other.isLatLon())) return distanceTo(other);

  return haversineDistance(other);
}

/*!  * \brief Set attributes for this node.  */
void Node::set(UID id, double x, double y) {
  id_ = nid_ = id;
  x_ = x;
  y_ = y;
  valid_ = true;
}

void Node::clear() {
  nid_ = 0; id_ = 0;
  x_ = 0.0; y_ = 0.0;
  hint_ = "";
  valid_ = false;
}
/*! \brief Set attributes by parsing a string.  */
void Node::set(const std::string &line) {
  clear();
  std::istringstream buffer(line);
  long int ids;
  buffer >> ids;
  buffer >> x_;
  buffer >> y_;
  hint_ = "";
  if (ids < 0) {
    valid_ = false;
  } else {
    nid_ = UID(ids);
    id_ = UID(ids);
  }
}

/*!  * \brief Print the contents of this node.  */
#ifdef DOVRPLOG
void Node::dump() const {
  DLOG(INFO) << nid_
             << ", " << x_
             << ", " << y_
             << ", " << hint_;
}
#endif

// Vector Operations

/*! \brief Create a new Node by performing vector addition.  */
Node  Node::operator+(const Node &v) const {
  return Node( x_ + v.x_, y_ + v.y_ );
}

/*! \brief Create a new Node by performing vector subtraction.  */
Node  Node::operator-(const Node &v) const {
  return Node( x_ - v.x_, y_ - v.y_ );
}

/*! \brief Create a new Node by scaling and existing node by a factor \c f.*/
Node  Node::operator*(double f) const { return Node( x_ * f, y_ * f ); }

/*! \brief Compute the vector dot product between two Nodes.*/
double Node::dotProduct( const Node &p ) const { return x_ * p.x_ + y_ * p.y_; }

/*! \brief Compute the Euclidean length of a vector */
double Node::length() const { return sqrt( x_ * x_ + y_ * y_ ); }

/*! \brief Compute the gradient or slope of a vector defined by the vector n->p
 * \bug This is not safe as it can generate a divide by zero
 * \todo This needs to be fixed to avoid divide by zero errors
 */
double Node::gradient(const Node &p) const {
  double deltaY = p.y_ - y_;
  double deltaX = p.x_ - x_;

  if (deltaX == 0) {
    if (deltaY >= 0)
      return VRP_MAX();
    else
      return VRP_MIN();
  } else {
    return  deltaY / deltaX;
  }
}

/*! \brief Compute the Euclidean distance between to Nodes.
 * \sa Node::length, Node::distance, Node::distanceToSquared
 */
double Node::distanceTo(const Node &p) const {
  return sqrt(distanceToSquared(p));
}

/*!  \brief Compute the Euclidean distance squared between two Nodes.
 *
 * \sa Node::length, Node::distanceTo, Node::distance
 */
double Node::distanceToSquared(const Node &p) const {
  const double dX = p.x_ - x_;
  const double dY = p.y_ - y_;

  return dX * dX + dY * dY;
}

/*!  \brief Calculates the unit vector of the reference Node.  */
Node Node::unit() const {
  double scale = 0.0;
  double len = length();

  if ( len != 0.0 )
    scale = 1.0 / len;

  return (*this) * scale;
}

/*! \brief Compute the shortest distance from a Node to a line segment*/
double Node::distanceToSegment(const Node &v, const Node &w) const {
  Node q;
  return distanceToSegment( v, w, q );
}

/*! \brief Compute the shortest distance from a Node to a line segment */
double Node::distanceToSegment(const Node &v, const Node &w, Node &q) const {
  // i.e. |w-v|^2 ... avoid a sqrt
  double distSq = v.distanceToSquared(w);

  if (distSq == 0.0) {  // v == w case
    q = v;
    return distanceTo(v);
  }

  // consider the line extending the segment, parameterized as v + t (w - v)
  // we find projection of point p onto the line
  // it falls where t = [(p-v) . (w-v)] / |w-v|^2

  double t = ((*this) - v).dotProduct(w - v) / distSq;

  if ( t < 0.0 ) {  // beyond the v end of the segment
    q = v;
    return distanceTo(v);
  }

  if ( t > 1.0 ) {  // beyond the w end of the segment
    q = w;
    return distanceTo(w);
  }

  // projection falls on the segment
  Node projection = v + ((w - v) * t);

  q = projection;

  return distanceTo(projection);
}

/*! \bref Compute position along the line segment
 *  Check if the node is on the line segment and return -1.0 if distance
 *  exceeds tol. Otherwise project the node onto the line segment and
 *  return is position as a percentage.
 *  \param[in] v start of segment
 *  \param[in] w end of segment
 *  \param[in] tol tolerance for distance test
 *  \return position 0.0 to 1.0 along the segment of -1.0 if it is not within tolerance
*/
double Node::positionAlongSegment(const Node &v, const Node &w, double tol) const {
  double tolSq = tol * tol;

  // i.e. |w-v|^2 ... avoid a sqrt
  double distSq = v.distanceToSquared(w);

  if (distSq == 0.0) {  // v == w case
    if (distanceToSquared(v) < tolSq)
      return 0.0;       // node == v == w case
    else
      return -1.0;      // node is not within tol
  }

  // consider the line extending the segment, parameterized as v + t (w - v)
  // we find projection of point p onto the line
  // it falls where t = [(p-v) . (w-v)] / |w-v|^2

  double t = ((*this) - v).dotProduct(w - v) / distSq;

  // beyond the v end of the segment
  if ( t < 0.0 ) {
    if (distanceToSquared(v) > tolSq )
      return -1.0;
    else
      return 0.0;
  }

  // beyond the w end of the segment
  if ( t > 1.0 ) {
    if ( distanceToSquared(w) > tolSq )
      return -1.0;
    else
      return 1.0;
  }

  // projection falls on the segment
  Node projection = v + ((w - v) * t);

  if (distanceToSquared(projection) > tolSq )
    return -1.0;

  return t;
}

/*! \brief Compute the shortest distance
    * Compute the shortest distance and x,y position on the segment of the
    * closest point.
*/
double Node::distanceToSegment(double segmentX1, double segmentY1,
                               double segmentX2, double segmentY2,
                               double &qX, double &qY) const {
  Node q;

  double distance = distanceToSegment(Node(segmentX1, segmentY1),
                                      Node(segmentX2, segmentY2), q);

  qX = q.x_;
  qY = q.y_;

  return distance;
}

// Constructors

/*! \brief Construct a new Node that needs the user to set its attributes.  */
Node::Node()
  : nid_(0), id_(0), x_(0.0), y_(0.0), hint_(""), valid_(false) {
}

/*! \brief Construct a new Node and assign it \c x and \c y values.  */
Node::Node(double x, double y)
  : nid_(0), id_(0), x_(x), y_(y), hint_(""), valid_(false) {
}

/*! \brief Construct a new Node and assign it the associated values.  */
Node::Node(UID nid, UID id , double x, double y)
  : nid_(nid), id_(id), x_(x), y_(y), hint_(""), valid_(true) {
}

/*! \brief Create a new Node by parsing a string.  */
Node::Node(const std::string &line)
     : nid_(0), id_(0), x_(0.0), y_(0.0), hint_(""), valid_(true) {
  std::istringstream buffer(line);
  long int ids;
  buffer >> ids;
  buffer >> x_;
  buffer >> y_;
  hint_ = "";
  if (ids < 0) {
    valid_ = false;
  } else {
    nid_ = UID(ids);
    id_ = UID(ids);
  }
}
<commit_msg>Changed Node::positionAlongSegment() so it will not return nodes projected onto extension of the segment.<commit_after>/*VRP*********************************************************************
 *
 * vehicle routing problems
 *      A collection of C++ classes for developing VRP solutions
 *      and specific solutions developed using these classes.
 *
 * Copyright 2014 Stephen Woodbridge <woodbri@imaptools.com>
 * Copyright 2014 Vicky Vergara <vicky_vergara@hotmail.com>
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the MIT License. Please file LICENSE for details.
 *
 ********************************************************************VRP*/

#include <cmath>
#include <string>
#include <iostream>
#include <sstream>

#ifdef DOVRPLOG
#include "./logger.h"
#endif

#include "./node.h"

/*!
 * \brief Compute the Haversine spherical distance between two nodes.
 *
 * Haversine spherical distance between two nodes with lat/lon values when
 * the nodes x,y is loaded with longitude,latitude values.
 *
 */
double Node::haversineDistance(const Node &other) const {
  const double pi = 3.14159265358979323846;
  const double deg2rad = pi / 180.0;
  const double radius = 6367000;  // Earth radius 6367 Km in meters
  double dlon = (other.x_ - x_) * deg2rad;
  double dlat = (other.y_ - y_) * deg2rad;
  double a = pow(sin(dlat / 2.0), 2) + cos(y_) * cos(other.y_) *
             pow(sin(dlon / 2.0), 2);
  double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
  double dist = radius * c;
  return dist;
}

double Node::distance(const Node &other) const {
  if (!(isLatLon() && other.isLatLon())) return distanceTo(other);

  return haversineDistance(other);
}

/*!  * \brief Set attributes for this node.  */
void Node::set(UID id, double x, double y) {
  id_ = nid_ = id;
  x_ = x;
  y_ = y;
  valid_ = true;
}

void Node::clear() {
  nid_ = 0; id_ = 0;
  x_ = 0.0; y_ = 0.0;
  hint_ = "";
  valid_ = false;
}
/*! \brief Set attributes by parsing a string.  */
void Node::set(const std::string &line) {
  clear();
  std::istringstream buffer(line);
  long int ids;
  buffer >> ids;
  buffer >> x_;
  buffer >> y_;
  hint_ = "";
  if (ids < 0) {
    valid_ = false;
  } else {
    nid_ = UID(ids);
    id_ = UID(ids);
  }
}

/*!  * \brief Print the contents of this node.  */
#ifdef DOVRPLOG
void Node::dump() const {
  DLOG(INFO) << nid_
             << ", " << x_
             << ", " << y_
             << ", " << hint_;
}
#endif

// Vector Operations

/*! \brief Create a new Node by performing vector addition.  */
Node  Node::operator+(const Node &v) const {
  return Node( x_ + v.x_, y_ + v.y_ );
}

/*! \brief Create a new Node by performing vector subtraction.  */
Node  Node::operator-(const Node &v) const {
  return Node( x_ - v.x_, y_ - v.y_ );
}

/*! \brief Create a new Node by scaling and existing node by a factor \c f.*/
Node  Node::operator*(double f) const { return Node( x_ * f, y_ * f ); }

/*! \brief Compute the vector dot product between two Nodes.*/
double Node::dotProduct( const Node &p ) const { return x_ * p.x_ + y_ * p.y_; }

/*! \brief Compute the Euclidean length of a vector */
double Node::length() const { return sqrt( x_ * x_ + y_ * y_ ); }

/*! \brief Compute the gradient or slope of a vector defined by the vector n->p
 * \bug This is not safe as it can generate a divide by zero
 * \todo This needs to be fixed to avoid divide by zero errors
 */
double Node::gradient(const Node &p) const {
  double deltaY = p.y_ - y_;
  double deltaX = p.x_ - x_;

  if (deltaX == 0) {
    if (deltaY >= 0)
      return VRP_MAX();
    else
      return VRP_MIN();
  } else {
    return  deltaY / deltaX;
  }
}

/*! \brief Compute the Euclidean distance between to Nodes.
 * \sa Node::length, Node::distance, Node::distanceToSquared
 */
double Node::distanceTo(const Node &p) const {
  return sqrt(distanceToSquared(p));
}

/*!  \brief Compute the Euclidean distance squared between two Nodes.
 *
 * \sa Node::length, Node::distanceTo, Node::distance
 */
double Node::distanceToSquared(const Node &p) const {
  const double dX = p.x_ - x_;
  const double dY = p.y_ - y_;

  return dX * dX + dY * dY;
}

/*!  \brief Calculates the unit vector of the reference Node.  */
Node Node::unit() const {
  double scale = 0.0;
  double len = length();

  if ( len != 0.0 )
    scale = 1.0 / len;

  return (*this) * scale;
}

/*! \brief Compute the shortest distance from a Node to a line segment*/
double Node::distanceToSegment(const Node &v, const Node &w) const {
  Node q;
  return distanceToSegment( v, w, q );
}

/*! \brief Compute the shortest distance from a Node to a line segment */
double Node::distanceToSegment(const Node &v, const Node &w, Node &q) const {
  // i.e. |w-v|^2 ... avoid a sqrt
  double distSq = v.distanceToSquared(w);

  if (distSq == 0.0) {  // v == w case
    q = v;
    return distanceTo(v);
  }

  // consider the line extending the segment, parameterized as v + t (w - v)
  // we find projection of point p onto the line
  // it falls where t = [(p-v) . (w-v)] / |w-v|^2

  double t = ((*this) - v).dotProduct(w - v) / distSq;

  if ( t < 0.0 ) {  // beyond the v end of the segment
    q = v;
    return distanceTo(v);
  }

  if ( t > 1.0 ) {  // beyond the w end of the segment
    q = w;
    return distanceTo(w);
  }

  // projection falls on the segment
  Node projection = v + ((w - v) * t);

  q = projection;

  return distanceTo(projection);
}

/*! \bref Compute position along the line segment
 *  Check if the node is on the line segment and return -1.0 if distance
 *  exceeds tol. Otherwise project the node onto the line segment and
 *  return is position as a percentage.
 *  \param[in] v start of segment
 *  \param[in] w end of segment
 *  \param[in] tol tolerance for distance test
 *  \return position 0.0 to 1.0 along the segment of -1.0 if it is not within tolerance
*/
double Node::positionAlongSegment(const Node &v, const Node &w, double tol) const {
  double tolSq = tol * tol;

  // i.e. |w-v|^2 ... avoid a sqrt
  double distSq = v.distanceToSquared(w);

  if (distSq == 0.0) {  // v == w case
    if (distanceToSquared(v) < tolSq)
      return 0.0;       // node == v == w case
    else
      return -1.0;      // node is not within tol
  }

  // consider the line extending the segment, parameterized as v + t (w - v)
  // we find projection of point p onto the line
  // it falls where t = [(p-v) . (w-v)] / |w-v|^2

  double t = ((*this) - v).dotProduct(w - v) / distSq;

  // beyond the v end of the segment
  if ( t < 0.0 ) {
      return -1.0;
  }

  // beyond the w end of the segment
  if ( t > 1.0 ) {
      return -1.0;
  }

  // projection falls on the segment
  Node projection = v + ((w - v) * t);

  if (distanceToSquared(projection) > tolSq )
    return -1.0;

  return t;
}

/*! \brief Compute the shortest distance
    * Compute the shortest distance and x,y position on the segment of the
    * closest point.
*/
double Node::distanceToSegment(double segmentX1, double segmentY1,
                               double segmentX2, double segmentY2,
                               double &qX, double &qY) const {
  Node q;

  double distance = distanceToSegment(Node(segmentX1, segmentY1),
                                      Node(segmentX2, segmentY2), q);

  qX = q.x_;
  qY = q.y_;

  return distance;
}

// Constructors

/*! \brief Construct a new Node that needs the user to set its attributes.  */
Node::Node()
  : nid_(0), id_(0), x_(0.0), y_(0.0), hint_(""), valid_(false) {
}

/*! \brief Construct a new Node and assign it \c x and \c y values.  */
Node::Node(double x, double y)
  : nid_(0), id_(0), x_(x), y_(y), hint_(""), valid_(false) {
}

/*! \brief Construct a new Node and assign it the associated values.  */
Node::Node(UID nid, UID id , double x, double y)
  : nid_(nid), id_(id), x_(x), y_(y), hint_(""), valid_(true) {
}

/*! \brief Create a new Node by parsing a string.  */
Node::Node(const std::string &line)
     : nid_(0), id_(0), x_(0.0), y_(0.0), hint_(""), valid_(true) {
  std::istringstream buffer(line);
  long int ids;
  buffer >> ids;
  buffer >> x_;
  buffer >> y_;
  hint_ = "";
  if (ids < 0) {
    valid_ = false;
  } else {
    nid_ = UID(ids);
    id_ = UID(ids);
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * 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: guisaveas.hxx,v $
 * $Revision: 1.12 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef _SFX_GUISAVEAS_HXX_
#define _SFX_GUISAVEAS_HXX_

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XContainerQuery.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>

#include <comphelper/sequenceashashmap.hxx>

namespace com { namespace sun { namespace star {
    namespace document {
        class XDocumentInfo;
    }
} } }

class Window;
class ModelData_Impl;

class SfxStoringHelper
{
    friend class ModelData_Impl;

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xFilterCFG;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > m_xFilterQuery;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > m_xModuleManager;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xNamedModManager;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > GetServiceFactory();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetFilterConfiguration();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > GetFilterQuery();
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > GetModuleManager();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetNamedModuleManager();

public:
    SfxStoringHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory );

    sal_Bool GUIStoreModel(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
                    const ::rtl::OUString& aSlotName,
                    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgsSequence,
                    sal_Bool bPreselectPassword );

    static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SearchForFilter(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery >& xFilterQuery,
                    const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aSearchRequest,
                    sal_Int32 nMustFlags,
                    sal_Int32 nDontFlags );

    static sal_Bool CheckFilterOptionsAppearence(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xFilterCFG,
                    const ::rtl::OUString& aFilterName );

    static void SetDocInfoState(
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
        const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentInfo>& i_xOldDocInfo,
        sal_Bool bNoModify );

    static sal_Bool WarnUnacceptableFormat(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
                                    ::rtl::OUString aOldUIName,
                                    ::rtl::OUString aDefUIName,
                                    sal_Bool bCanProceedFurther );

    static void ExecuteFilterDialog( SfxStoringHelper& _rStorageHelper
                                    ,const ::rtl::OUString& sFilterName
                                    ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel
                                    ,/*OUT*/::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgsSequence
                                );

    static Window* GetModelWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel );

};

#endif

<commit_msg>INTEGRATION: CWS calcshare2 (1.11.20); FILE MERGED 2008/03/27 14:12:58 mav 1.11.20.1: #i87504# let the expected location be used<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: guisaveas.hxx,v $
 * $Revision: 1.13 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef _SFX_GUISAVEAS_HXX_
#define _SFX_GUISAVEAS_HXX_

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XContainerQuery.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>

#include <comphelper/sequenceashashmap.hxx>

namespace com { namespace sun { namespace star {
    namespace document {
        class XDocumentInfo;
    }
} } }

class Window;
class ModelData_Impl;

class SfxStoringHelper
{
    friend class ModelData_Impl;

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xFilterCFG;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > m_xFilterQuery;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > m_xModuleManager;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xNamedModManager;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > GetServiceFactory();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetFilterConfiguration();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > GetFilterQuery();
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > GetModuleManager();
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetNamedModuleManager();

public:
    SfxStoringHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory );

    sal_Bool GUIStoreModel(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
                    const ::rtl::OUString& aSlotName,
                    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgsSequence,
                    sal_Bool bPreselectPassword,
                    ::rtl::OUString aUserSelectedName );

    static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SearchForFilter(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery >& xFilterQuery,
                    const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aSearchRequest,
                    sal_Int32 nMustFlags,
                    sal_Int32 nDontFlags );

    static sal_Bool CheckFilterOptionsAppearence(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xFilterCFG,
                    const ::rtl::OUString& aFilterName );

    static void SetDocInfoState(
        const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
        const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentInfo>& i_xOldDocInfo,
        sal_Bool bNoModify );

    static sal_Bool WarnUnacceptableFormat(
                                    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel,
                                    ::rtl::OUString aOldUIName,
                                    ::rtl::OUString aDefUIName,
                                    sal_Bool bCanProceedFurther );

    static void ExecuteFilterDialog( SfxStoringHelper& _rStorageHelper
                                    ,const ::rtl::OUString& sFilterName
                                    ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel
                                    ,/*OUT*/::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgsSequence
                                );

    static Window* GetModelWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel );

};

#endif

<|endoftext|>


<commit_before>#ifndef SERIALIZATION_BOOL_HPP_57D2463B_8AA8_479C_94E3_BB6555E9C59B
#define SERIALIZATION_BOOL_HPP_57D2463B_8AA8_479C_94E3_BB6555E9C59B

#include <szn/big_endian.hpp>
#include <szn/format.hpp>

namespace szn
{
	template <class Format, class ValuePolicy>
	struct basic_bool SZN_FINAL
	{
		static length_type const min_size = min_size<Format>::value;
		static length_type const max_size = max_size<Format>::value;

		typedef bool default_type;

		template <class Sink>
		void serialize(Sink &sink, bool value) const
		{
			Format().serialize(sink, ValuePolicy::fromBool(value));
		}

		template <class Source>
		void deserialize(Source &source, bool &value) const
		{
			typename ValuePolicy::value_type buffer;
			Format().deserialize(source, buffer);
			value = ValuePolicy::toBool(buffer);
		}
	};

	struct byte_bool SZN_FINAL
	{
		typedef unsigned char value_type;

		static value_type fromBool(bool value)
		{
			//explicit cast to silence warning by GCC 4.3
			return static_cast<value_type>(value ? 1 : 0);
		}

		static bool toBool(value_type value)
		{
			return (value != 0);
		}
	};

	typedef basic_bool<be8, byte_bool> boolean;

	template <class UnderlyingBool>
	struct boolean_not SZN_FINAL
	{
		typedef typename UnderlyingBool::default_type default_type;

		static length_type const min_size = min_size<UnderlyingBool>::value;
		static length_type const max_size = max_size<UnderlyingBool>::value;

		template <class Sink>
		void serialize(Sink &sink, bool value) const
		{
			UnderlyingBool().serialize(sink, !value);
		}

		template <class Source>
		void deserialize(Source &source, bool &value) const
		{
			bool underlying_value = false;
			UnderlyingBool().deserialize(source, underlying_value);
			value = !underlying_value;
		}
	};
}

#endif
<commit_msg>fix naming style<commit_after>#ifndef SERIALIZATION_BOOL_HPP_57D2463B_8AA8_479C_94E3_BB6555E9C59B
#define SERIALIZATION_BOOL_HPP_57D2463B_8AA8_479C_94E3_BB6555E9C59B

#include <szn/big_endian.hpp>
#include <szn/format.hpp>

namespace szn
{
	template <class Format, class ValuePolicy>
	struct basic_bool SZN_FINAL
	{
		static length_type const min_size = min_size<Format>::value;
		static length_type const max_size = max_size<Format>::value;

		typedef bool default_type;

		template <class Sink>
		void serialize(Sink &sink, bool value) const
		{
			Format().serialize(sink, ValuePolicy::from_bool(value));
		}

		template <class Source>
		void deserialize(Source &source, bool &value) const
		{
			typename ValuePolicy::value_type buffer;
			Format().deserialize(source, buffer);
			value = ValuePolicy::to_bool(buffer);
		}
	};

	struct byte_bool SZN_FINAL
	{
		typedef unsigned char value_type;

		static value_type from_bool(bool value)
		{
			//explicit cast to silence warning by GCC 4.3
			return static_cast<value_type>(value ? 1 : 0);
		}

		static bool to_bool(value_type value)
		{
			return (value != 0);
		}
	};

	typedef basic_bool<be8, byte_bool> boolean;

	template <class UnderlyingBool>
	struct boolean_not SZN_FINAL
	{
		typedef typename UnderlyingBool::default_type default_type;

		static length_type const min_size = min_size<UnderlyingBool>::value;
		static length_type const max_size = max_size<UnderlyingBool>::value;

		template <class Sink>
		void serialize(Sink &sink, bool value) const
		{
			UnderlyingBool().serialize(sink, !value);
		}

		template <class Source>
		void deserialize(Source &source, bool &value) const
		{
			bool underlying_value = false;
			UnderlyingBool().deserialize(source, underlying_value);
			value = !underlying_value;
		}
	};
}

#endif
<|endoftext|>


<commit_before>#ifndef SERIALIZATION_UTIL_HPP_5595449D_4B56_4FD3_983C_CC91E7E873D2
#define SERIALIZATION_UTIL_HPP_5595449D_4B56_4FD3_983C_CC91E7E873D2

//GCC supports override and final beginning with version 4.7
#if defined(__GNUC__) && (__GNUC__ >= 4) && ((__GNUC__ > 4) || (__GNUC_MINOR__ >= 7))
#	define SZN_FINAL final
#	define SZN_OVERRIDE override

//Clang has supported override and final since 3.0 and this library requires Clang 3.2
#elif defined(__clang__)
#	define SZN_FINAL final
#	define SZN_OVERRIDE override

//VC++ 2010 is supported and it has override
#elif defined(_MSC_VER)
#	define SZN_FINAL
#	define SZN_OVERRIDE override

#else
#	define SZN_FINAL
#	define SZN_OVERRIDE
#endif

namespace szn
{
	struct Sink;
	struct Source;

	/// just an alternative way of calling format.serialize
	template <class Value, class Format>
	void serialize(Sink &sink, const Value &value, const Format &format)
	{
		format.serialize(sink, value);
	}

	/// just an alternative way of calling format.deserialize
	template <class Value, class Format>
	void deserialize(Source &source, Value &value, const Format &format)
	{
		format.deserialize(source, value);
	}

	/// a format for structures with serialize/deserialize methods
	struct ByMethod SZN_FINAL
	{
		template <class Value>
		void serialize(Sink &sink, const Value &value) const
		{
			value.serialize(sink);
		}

		template <class Value>
		void deserialize(Source &source, Value &value) const
		{
			value.deserialize(source);
		}
	};

	struct ByADL SZN_FINAL
	{
		template <class Value>
		void serialize(Sink &sink, const Value &value) const
		{
			using szn::serialize;
			serialize(sink, value);
		}

		template <class Value>
		void deserialize(Source &source, Value &value) const
		{
			using szn::deserialize;
			deserialize(source, value);
		}
	};
}

#endif
<commit_msg>add noexcept compatibility macro for later use<commit_after>#ifndef SERIALIZATION_UTIL_HPP_5595449D_4B56_4FD3_983C_CC91E7E873D2
#define SERIALIZATION_UTIL_HPP_5595449D_4B56_4FD3_983C_CC91E7E873D2

#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
//	GCC supports override and final beginning with version 4.7
#	if ((__GNUC__ > 4) || (__GNUC_MINOR__ >= 7))
#		define SZN_FINAL final
#		define SZN_OVERRIDE override
#	else
#		define SZN_FINAL
#		define SZN_OVERRIDE
#	endif
//	GCC 4.6 introduced noexcept
#	define SZN_NOEXCEPT noexcept

#elif defined(__clang__)
//	Clang has supported override, final and noexcept since 3.0
#	define SZN_FINAL final
#	define SZN_OVERRIDE override
#	define SZN_NOEXCEPT noexcept

#elif defined(_MSC_VER)
//	VC++ 2010 has override
#	define SZN_FINAL
#	define SZN_OVERRIDE override
#	define SZN_NOEXCEPT

#else
#	define SZN_FINAL
#	define SZN_OVERRIDE
#	define SZN_NOEXCEPT
#endif

namespace szn
{
	struct Sink;
	struct Source;

	/// just an alternative way of calling format.serialize
	template <class Value, class Format>
	void serialize(Sink &sink, const Value &value, const Format &format)
	{
		format.serialize(sink, value);
	}

	/// just an alternative way of calling format.deserialize
	template <class Value, class Format>
	void deserialize(Source &source, Value &value, const Format &format)
	{
		format.deserialize(source, value);
	}

	/// a format for structures with serialize/deserialize methods
	struct ByMethod SZN_FINAL
	{
		template <class Value>
		void serialize(Sink &sink, const Value &value) const
		{
			value.serialize(sink);
		}

		template <class Value>
		void deserialize(Source &source, Value &value) const
		{
			value.deserialize(source);
		}
	};

	struct ByADL SZN_FINAL
	{
		template <class Value>
		void serialize(Sink &sink, const Value &value) const
		{
			using szn::serialize;
			serialize(sink, value);
		}

		template <class Value>
		void deserialize(Source &source, Value &value) const
		{
			using szn::deserialize;
			deserialize(source, value);
		}
	};
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2013 Arista Networks, Inc.  All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

#include "eos/ip_route.h"

namespace eos {

ip_route_mgr::ip_route_mgr() {
}

class ip_route_mgr_impl : public ip_route_mgr {
 public:
   ip_route_mgr_impl() {
   }
};

ip_route_mgr *
get_ip_route_mgr() {
   static ip_route_mgr_impl impl;
   return &impl;
}

ip_route_iter_t::ip_route_iter_t(ip_route_iter_impl * const impl)
   : iter_base(0) {
}

ip_route_iter_t
ip_route_mgr::ip_route_iter() const {
   ip_route_iter_t * nop = 0;
   return *nop;  // TODO: No op impl.
}

ip_route_via_iter_t
ip_route_mgr::ip_route_via_iter(ip_route_key_t const & key) const {
   ip_route_via_iter_t * nop = 0;
   return *nop;  // TODO: No op impl.
}

void
ip_route_mgr::ip_route_foreach(callback_func_route handler, void *context) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_foreach(callback_func_route handler, void *context,
                               const ip_route_t & bookmark) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_foreach(const ip_route_key_t & route_key,
                                   callback_func_via handler, void *context) {
   // TODO: No op impl.
}

bool
ip_route_mgr::exists(const ip_route_key_t & route_key) const {
   return false;  // TODO: No op impl.
}

bool
ip_route_mgr::exists(const ip_route_via_t & route_via) const {
   return false;  // TODO: No op impl.
}

void
ip_route_mgr::ip_route_set(const ip_route_t & route) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_del(const ip_route_key_t & route_key) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_set(const ip_route_via_t & route_via) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_del(const ip_route_via_t & route_via) {
   // TODO: No op impl.
}

}  // end namespace eos
<commit_msg>@1656230 Fix invokation of the parent template class ctor for older GCC versions.<commit_after>// Copyright (c) 2013 Arista Networks, Inc.  All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

#include "eos/ip_route.h"

namespace eos {

ip_route_mgr::ip_route_mgr() {
}

class ip_route_mgr_impl : public ip_route_mgr {
 public:
   ip_route_mgr_impl() {
   }
};

ip_route_mgr *
get_ip_route_mgr() {
   static ip_route_mgr_impl impl;
   return &impl;
}

ip_route_iter_t::ip_route_iter_t(ip_route_iter_impl * const impl)
   : iter_base<ip_route_t, ip_route_iter_impl>(0) {
}

ip_route_iter_t
ip_route_mgr::ip_route_iter() const {
   ip_route_iter_t * nop = 0;
   return *nop;  // TODO: No op impl.
}

ip_route_via_iter_t
ip_route_mgr::ip_route_via_iter(ip_route_key_t const & key) const {
   ip_route_via_iter_t * nop = 0;
   return *nop;  // TODO: No op impl.
}

void
ip_route_mgr::ip_route_foreach(callback_func_route handler, void *context) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_foreach(callback_func_route handler, void *context,
                               const ip_route_t & bookmark) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_foreach(const ip_route_key_t & route_key,
                                   callback_func_via handler, void *context) {
   // TODO: No op impl.
}

bool
ip_route_mgr::exists(const ip_route_key_t & route_key) const {
   return false;  // TODO: No op impl.
}

bool
ip_route_mgr::exists(const ip_route_via_t & route_via) const {
   return false;  // TODO: No op impl.
}

void
ip_route_mgr::ip_route_set(const ip_route_t & route) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_del(const ip_route_key_t & route_key) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_set(const ip_route_via_t & route_via) {
   // TODO: No op impl.
}

void
ip_route_mgr::ip_route_via_del(const ip_route_via_t & route_via) {
   // TODO: No op impl.
}

}  // end namespace eos
<|endoftext|>


<commit_before>/**
 * @file gfx.cpp
 * @brief Platform-independent bitmap graphics transformation functionality
 *
 * (c) 2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/gfx.h"

namespace mega {
const int GfxProc::dimensions[][2] = {
    { 200, 0 },     // THUMBNAIL: square thumbnail, cropped from near center
    { 1000, 1000 }  // PREVIEW: scaled version inside 1000x1000 bounding square
};

const int GfxProc::dimensionsavatar[][2] = {
    { 250, 0 }      // AVATAR250X250: square thumbnail, cropped from near center
};

bool GfxProc::isgfx(string* localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedformats()))
    {
        return true;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

bool GfxProc::isvideo(string *localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedvideoformats()))
    {
        return false;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

const char* GfxProc::supportedformats()
{
    return NULL;
}

const char* GfxProc::supportedvideoformats()
{
    return NULL;
}

void *GfxProc::threadEntryPoint(void *param)
{
    GfxProc* gfxProcessor = (GfxProc*)param;
    gfxProcessor->loop();
    return NULL;
}

void GfxProc::loop()
{
    GfxJob *job = NULL;
    while (!finished)
    {
        waiter.init(NEVER);
        waiter.wait();
        if (finished)
        {
            break;
        }

        while (job = requests.pop())
        {
            mutex.lock();
            LOG_debug << "Processing media file: " << job->h;

            // (this assumes that the width of the largest dimension is max)
            if (readbitmap(NULL, &job->localfilename, dimensions[sizeof dimensions/sizeof dimensions[0]-1][0]))
            {
                for (int i = 0; i < job->imagetypes.size(); i++)
                {
                    // successively downscale the original image
                    string* jpeg = new string();
                    int w = dimensions[job->imagetypes[i]][0];
                    int h = dimensions[job->imagetypes[i]][1];

                    if (job->imagetypes[i] == PREVIEW && this->w < w && this->h < h )
                    {
                        LOG_debug << "Skipping upsizing of preview";
                        w = this->w;
                        h = this->h;
                    }

                    if (!resizebitmap(w, h, jpeg))
                    {
                        delete jpeg;
                        jpeg = NULL;
                    }
                    job->images.push_back(jpeg);
                }
                freebitmap();
            }
            else
            {
                for (int i = 0; i < job->imagetypes.size(); i++)
                {
                    job->images.push_back(NULL);
                }
            }

            mutex.unlock();
            responses.push(job);
            client->waiter->notify();
        }
    }

    while (job = requests.pop())
    {
        delete job;
    }

    while (job = responses.pop())
    {
        for (int i = 0; i < job->imagetypes.size(); i++)
        {
            delete job->images[i];
        }
        delete job;
    }
}

int GfxProc::checkevents(Waiter *)
{
    if (!client)
    {
        return 0;
    }

    GfxJob *job = NULL;
    bool needexec = false;
    SymmCipher key;
    while (job = responses.pop())
    {
        for (int i = 0; i < job->images.size(); i++)
        {
            if (job->images[i])
            {
                LOG_debug << "Media file correctly processed. Attaching file attribute: " << job->h;

                // store the file attribute data - it will be attached to the file
                // immediately if the upload has already completed; otherwise, once
                // the upload completes
                key.setkey(job->key);
                int creqtag = client->reqtag;
                client->reqtag = 0;
                client->putfa(job->h, (meta_t)job->imagetypes[i], &key, job->images[i], job->flag);
                client->reqtag = creqtag;
            }
            else
            {
                LOG_debug << "Unable to process media file: " << job->h;

                Transfer *transfer = NULL;
                handletransfer_map::iterator htit = client->faputcompletion.find(job->h);
                if (htit != client->faputcompletion.end())
                {
                    transfer = htit->second;
                }
                else
                {
                    // check if the failed attribute belongs to an active upload
                    for (transfer_map::iterator it = client->transfers[PUT].begin(); it != client->transfers[PUT].end(); it++)
                    {
                        if (it->second->uploadhandle == job->h)
                        {
                            transfer = it->second;
                            break;
                        }
                    }
                }

                if (transfer)
                {
                    // reduce the number of required attributes to let the upload continue
                    transfer->minfa--;
                    client->checkfacompletion(job->h);
                }
                else
                {
                    LOG_debug << "Transfer related to media file not found: " << job->h;
                }
            }
            needexec = true;
        }
        delete job;
    }

    return needexec ? Waiter::NEEDEXEC : 0;
}

void GfxProc::transform(int& w, int& h, int& rw, int& rh, int& px, int& py)
{
    if (rh)
    {
        // rectangular rw*rh bounding box
        if (h*rw > w*rh)
        {
            w = w * rh / h;
            h = rh;
        }
        else
        {
            h = h * rw / w;
            w = rw;
        }

        px = 0;
        py = 0;

        rw = w;
        rh = h;
    }
    else
    {
        // square rw*rw crop thumbnail
        if (w < h)
        {
            h = h * rw / w;
            w = rw;
        }
        else
        {
            w = w * rw / h;
            h = rw;
        }

        px = (w - rw) / 2;
        py = (h - rw) / 3;

        rh = rw;
    }
}

// load bitmap image, generate all designated sizes, attach to specified upload/node handle
// FIXME: move to a worker thread to keep the engine nonblocking
int GfxProc::gendimensionsputfa(FileAccess* fa, string* localfilename, handle th, SymmCipher* key, int missing, bool checkAccess)
{
    if (SimpleLogger::logCurrentLevel >= logDebug)
    {
        string utf8path;
        client->fsaccess->local2path(localfilename, &utf8path);
        LOG_debug << "Creating thumb/preview for " << utf8path;
    }

    GfxJob *job = new GfxJob();
    job->h = th;
    job->flag = checkAccess;
    memcpy(job->key, key->key, SymmCipher::KEYLENGTH);
    job->localfilename = *localfilename;
    for (int i = sizeof dimensions/sizeof dimensions[0]; i--; )
    {
        if (missing & (1 << i))
        {
            job->imagetypes.push_back(i);
        }
    }

    if (!job->imagetypes.size())
    {
        delete job;
        return 0;
    }

    requests.push(job);
    waiter.notify();
    return job->imagetypes.size();
}

bool GfxProc::savefa(string *localfilepath, int width, int height, string *localdstpath)
{
    if (!isgfx(localfilepath))
    {
        return false;
    }

    mutex.lock();
    if (!readbitmap(NULL, localfilepath, width > height ? width : height))
    {
        mutex.unlock();
        return false;
    }

    int w = width;
    int h = height;
    if (this->w < w && this->h < h)
    {
        LOG_debug << "Skipping upsizing of local preview";
        w = this->w;
        h = this->h;
    }

    string jpeg;
    bool success = resizebitmap(w, h, &jpeg);
    freebitmap();
    mutex.unlock();

    if (!success)
    {
        return false;
    }

    FileAccess *f = client->fsaccess->newfileaccess();
    client->fsaccess->unlinklocal(localdstpath);
    if (!f->fopen(localdstpath, false, true))
    {
        delete f;
        return false;
    }

    if (!f->fwrite((const byte*)jpeg.data(), jpeg.size(), 0))
    {
        delete f;
        return false;
    }

    delete f;
    return true;
}

GfxProc::GfxProc() : mutex(false)
{
    client = NULL;
    finished = false;
    thread.start(threadEntryPoint, this);
}

GfxProc::~GfxProc()
{
    finished = true;
    waiter.notify();
    thread.join();
}

GfxJobQueue::GfxJobQueue() : mutex(false)
{

}

void GfxJobQueue::push(GfxJob *job)
{
    mutex.lock();
    jobs.push_back(job);
    mutex.unlock();
}

GfxJob *GfxJobQueue::pop()
{
    mutex.lock();
    if (jobs.empty())
    {
        mutex.unlock();
        return NULL;
    }
    GfxJob *job = jobs.front();
    jobs.pop_front();
    mutex.unlock();
    return job;
}

GfxJob::GfxJob()
{

}

} // namespace
<commit_msg>Do not continue processing gfx requests if the object is being deleted<commit_after>/**
 * @file gfx.cpp
 * @brief Platform-independent bitmap graphics transformation functionality
 *
 * (c) 2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/gfx.h"

namespace mega {
const int GfxProc::dimensions[][2] = {
    { 200, 0 },     // THUMBNAIL: square thumbnail, cropped from near center
    { 1000, 1000 }  // PREVIEW: scaled version inside 1000x1000 bounding square
};

const int GfxProc::dimensionsavatar[][2] = {
    { 250, 0 }      // AVATAR250X250: square thumbnail, cropped from near center
};

bool GfxProc::isgfx(string* localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedformats()))
    {
        return true;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

bool GfxProc::isvideo(string *localfilename)
{
    char ext[8];
    const char* supported;

    if (!(supported = supportedvideoformats()))
    {
        return false;
    }

    if (client->fsaccess->getextension(localfilename, ext, sizeof ext))
    {
        const char* ptr;

        // FIXME: use hash
        if ((ptr = strstr(supported, ext)) && ptr[strlen(ext)] == '.')
        {
            return true;
        }
    }

    return false;
}

const char* GfxProc::supportedformats()
{
    return NULL;
}

const char* GfxProc::supportedvideoformats()
{
    return NULL;
}

void *GfxProc::threadEntryPoint(void *param)
{
    GfxProc* gfxProcessor = (GfxProc*)param;
    gfxProcessor->loop();
    return NULL;
}

void GfxProc::loop()
{
    GfxJob *job = NULL;
    while (!finished)
    {
        waiter.init(NEVER);
        waiter.wait();
        while (job = requests.pop())
        {
            if (finished)
            {
                delete job;
                break;
            }

            mutex.lock();
            LOG_debug << "Processing media file: " << job->h;

            // (this assumes that the width of the largest dimension is max)
            if (readbitmap(NULL, &job->localfilename, dimensions[sizeof dimensions/sizeof dimensions[0]-1][0]))
            {
                for (int i = 0; i < job->imagetypes.size(); i++)
                {
                    // successively downscale the original image
                    string* jpeg = new string();
                    int w = dimensions[job->imagetypes[i]][0];
                    int h = dimensions[job->imagetypes[i]][1];

                    if (job->imagetypes[i] == PREVIEW && this->w < w && this->h < h )
                    {
                        LOG_debug << "Skipping upsizing of preview";
                        w = this->w;
                        h = this->h;
                    }

                    if (!resizebitmap(w, h, jpeg))
                    {
                        delete jpeg;
                        jpeg = NULL;
                    }
                    job->images.push_back(jpeg);
                }
                freebitmap();
            }
            else
            {
                for (int i = 0; i < job->imagetypes.size(); i++)
                {
                    job->images.push_back(NULL);
                }
            }

            mutex.unlock();
            responses.push(job);
            client->waiter->notify();
        }
    }

    while (job = requests.pop())
    {
        delete job;
    }

    while (job = responses.pop())
    {
        for (int i = 0; i < job->imagetypes.size(); i++)
        {
            delete job->images[i];
        }
        delete job;
    }
}

int GfxProc::checkevents(Waiter *)
{
    if (!client)
    {
        return 0;
    }

    GfxJob *job = NULL;
    bool needexec = false;
    SymmCipher key;
    while (job = responses.pop())
    {
        for (int i = 0; i < job->images.size(); i++)
        {
            if (job->images[i])
            {
                LOG_debug << "Media file correctly processed. Attaching file attribute: " << job->h;

                // store the file attribute data - it will be attached to the file
                // immediately if the upload has already completed; otherwise, once
                // the upload completes
                key.setkey(job->key);
                int creqtag = client->reqtag;
                client->reqtag = 0;
                client->putfa(job->h, (meta_t)job->imagetypes[i], &key, job->images[i], job->flag);
                client->reqtag = creqtag;
            }
            else
            {
                LOG_debug << "Unable to process media file: " << job->h;

                Transfer *transfer = NULL;
                handletransfer_map::iterator htit = client->faputcompletion.find(job->h);
                if (htit != client->faputcompletion.end())
                {
                    transfer = htit->second;
                }
                else
                {
                    // check if the failed attribute belongs to an active upload
                    for (transfer_map::iterator it = client->transfers[PUT].begin(); it != client->transfers[PUT].end(); it++)
                    {
                        if (it->second->uploadhandle == job->h)
                        {
                            transfer = it->second;
                            break;
                        }
                    }
                }

                if (transfer)
                {
                    // reduce the number of required attributes to let the upload continue
                    transfer->minfa--;
                    client->checkfacompletion(job->h);
                }
                else
                {
                    LOG_debug << "Transfer related to media file not found: " << job->h;
                }
            }
            needexec = true;
        }
        delete job;
    }

    return needexec ? Waiter::NEEDEXEC : 0;
}

void GfxProc::transform(int& w, int& h, int& rw, int& rh, int& px, int& py)
{
    if (rh)
    {
        // rectangular rw*rh bounding box
        if (h*rw > w*rh)
        {
            w = w * rh / h;
            h = rh;
        }
        else
        {
            h = h * rw / w;
            w = rw;
        }

        px = 0;
        py = 0;

        rw = w;
        rh = h;
    }
    else
    {
        // square rw*rw crop thumbnail
        if (w < h)
        {
            h = h * rw / w;
            w = rw;
        }
        else
        {
            w = w * rw / h;
            h = rw;
        }

        px = (w - rw) / 2;
        py = (h - rw) / 3;

        rh = rw;
    }
}

// load bitmap image, generate all designated sizes, attach to specified upload/node handle
// FIXME: move to a worker thread to keep the engine nonblocking
int GfxProc::gendimensionsputfa(FileAccess* fa, string* localfilename, handle th, SymmCipher* key, int missing, bool checkAccess)
{
    if (SimpleLogger::logCurrentLevel >= logDebug)
    {
        string utf8path;
        client->fsaccess->local2path(localfilename, &utf8path);
        LOG_debug << "Creating thumb/preview for " << utf8path;
    }

    GfxJob *job = new GfxJob();
    job->h = th;
    job->flag = checkAccess;
    memcpy(job->key, key->key, SymmCipher::KEYLENGTH);
    job->localfilename = *localfilename;
    for (int i = sizeof dimensions/sizeof dimensions[0]; i--; )
    {
        if (missing & (1 << i))
        {
            job->imagetypes.push_back(i);
        }
    }

    if (!job->imagetypes.size())
    {
        delete job;
        return 0;
    }

    requests.push(job);
    waiter.notify();
    return job->imagetypes.size();
}

bool GfxProc::savefa(string *localfilepath, int width, int height, string *localdstpath)
{
    if (!isgfx(localfilepath))
    {
        return false;
    }

    mutex.lock();
    if (!readbitmap(NULL, localfilepath, width > height ? width : height))
    {
        mutex.unlock();
        return false;
    }

    int w = width;
    int h = height;
    if (this->w < w && this->h < h)
    {
        LOG_debug << "Skipping upsizing of local preview";
        w = this->w;
        h = this->h;
    }

    string jpeg;
    bool success = resizebitmap(w, h, &jpeg);
    freebitmap();
    mutex.unlock();

    if (!success)
    {
        return false;
    }

    FileAccess *f = client->fsaccess->newfileaccess();
    client->fsaccess->unlinklocal(localdstpath);
    if (!f->fopen(localdstpath, false, true))
    {
        delete f;
        return false;
    }

    if (!f->fwrite((const byte*)jpeg.data(), jpeg.size(), 0))
    {
        delete f;
        return false;
    }

    delete f;
    return true;
}

GfxProc::GfxProc() : mutex(false)
{
    client = NULL;
    finished = false;
    thread.start(threadEntryPoint, this);
}

GfxProc::~GfxProc()
{
    finished = true;
    waiter.notify();
    thread.join();
}

GfxJobQueue::GfxJobQueue() : mutex(false)
{

}

void GfxJobQueue::push(GfxJob *job)
{
    mutex.lock();
    jobs.push_back(job);
    mutex.unlock();
}

GfxJob *GfxJobQueue::pop()
{
    mutex.lock();
    if (jobs.empty())
    {
        mutex.unlock();
        return NULL;
    }
    GfxJob *job = jobs.front();
    jobs.pop_front();
    mutex.unlock();
    return job;
}

GfxJob::GfxJob()
{

}

} // namespace
<|endoftext|>