<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql item block
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2014 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
/// @author Copyright 2014, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/AqlItemBlock.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                                      AqlItemBlock
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief create the block
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock::AqlItemBlock (size_t nrItems,
                            RegisterId nrRegs)
  : _nrItems(nrItems), _nrRegs(nrRegs) {

  TRI_ASSERT(nrItems > 0);  // no, empty AqlItemBlocks are not allowed!

  if (nrItems > 0 && nrRegs > 0) {
    _data.reserve(nrItems * nrRegs);
    for (size_t i = 0; i < nrItems * nrRegs; ++i) {
      _data.emplace_back();
    }
  }

  if (nrRegs > 0) {
    _docColls.reserve(nrRegs);
    for (size_t i = 0; i < nrRegs; ++i) {
      _docColls.push_back(nullptr);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the block
/// TODO: dtor is not exception-safe
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock::~AqlItemBlock () {
  for (size_t i = 0; i < _nrItems * _nrRegs; i++) {
    if (! _data[i].isEmpty()) {
      auto it = _valueCount.find(_data[i]);
      if (it != _valueCount.end()) { // if we know it, we are still responsible
        if (--(it->second) == 0) {
          _data[i].destroy();
          try {
            _valueCount.erase(it);
          }
          catch (...) {
          }
        }
      }
      // Note that if we do not know it the thing it has been stolen from us!
    }
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief shrink the block to the specified number of rows
////////////////////////////////////////////////////////////////////////////////

void AqlItemBlock::shrink (size_t nrItems) {
  TRI_ASSERT(nrItems > 0);

  if (nrItems == _nrItems) {
    // nothing to do
    return;
  }

  if (nrItems > _nrItems) {
    // cannot use shrink() to increase the size of the block
    THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
  }

  // erase all stored values in the region that we freed
  for (size_t i = nrItems; i < _nrItems; ++i) {
    for (RegisterId j = 0; j < _nrRegs; ++j) {
      eraseValue(i, j);
    }
  }

  // adjust the size of the block
  _nrItems = nrItems;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief clears out some columns (registers), this deletes the values if
/// necessary, using the reference count.
////////////////////////////////////////////////////////////////////////////////

void AqlItemBlock::clearRegisters (std::unordered_set<RegisterId>& toClear) {
  for (auto reg : toClear) {
    for (size_t i = 0; i < _nrItems; i++) {
      AqlValue& a(_data[_nrRegs * i + reg]);
      if (! a.isEmpty()) {
        auto it = _valueCount.find(a);
        if (it != _valueCount.end()) {
          if (--it->second == 0) {
            try {
              _valueCount.erase(it);
            }
            catch (...) {
              it->second++;
              throw;
            }
          }
        }
        a.erase();
      }
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief slice/clone, this does a deep copy of all entries
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::slice (size_t from,
                                   size_t to) const {
  TRI_ASSERT(from < to && to <= _nrItems);

  std::unordered_map<AqlValue, AqlValue> cache;
  // TODO: should we pre-reserve space for cache to avoid later re-allocations?

  AqlItemBlock* res = nullptr;
  try {
    res = new AqlItemBlock(to - from, _nrRegs);

    for (RegisterId col = 0; col < _nrRegs; col++) {
      res->_docColls[col] = _docColls[col];
    }
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue const& a(_data[row * _nrRegs + col]);

        if (! a.isEmpty()) {
          auto it = cache.find(a);
          if (it == cache.end()) {
            AqlValue b = a.clone();
            res->_data[(row - from) * _nrRegs + col] = b;
            // TODO: can we use emplace() here instead of insert()?
            cache.insert(make_pair(a, b));
          }
          else {
            res->_data[(row - from) * _nrRegs + col] = it->second;
          }
        }
      }
    }

    return res;
  }
  catch (...) {
    delete res;
    throw;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief slice/clone chosen rows for a subset, this does a deep copy
/// of all entries
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::slice (std::vector<size_t>& chosen,
                                   size_t from,
                                   size_t to) const {
  TRI_ASSERT(from < to && to <= chosen.size());

  std::unordered_map<AqlValue, AqlValue> cache;
  // TODO: should we pre-reserve space for cache to avoid later re-allocations?

  AqlItemBlock* res = nullptr;
  try {
    res = new AqlItemBlock(to - from, _nrRegs);

    for (RegisterId col = 0; col < _nrRegs; col++) {
      res->_docColls[col] = _docColls[col];
    }
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue const& a(_data[chosen[row] * _nrRegs + col]);

        if (! a.isEmpty()) {
          auto it = cache.find(a);
          if (it == cache.end()) {
            AqlValue b = a.clone();
            res->_data[(row - from) * _nrRegs + col] = b;
            // TODO: can we use emplace() here instead of insert()?
            cache.insert(make_pair(a, b));
          }
          else {
            res->_data[(row - from) * _nrRegs + col] = it->second;
          }
        }
      }
    }

    return res;
  }
  catch (...) {
    delete res;
    throw;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief steal for a subset, this does not copy the entries, rather,
/// it remembers which it has taken. This is stored in the
/// this by removing the value counts in _valueCount.
/// It is highly recommended to delete this object right after this
/// operation, because it is unclear, when the values to which our
/// AqlValues point will vanish! In particular, do not use setValue
/// any more.
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::steal (vector<size_t>& chosen,
                                   size_t from, size_t to) {
  TRI_ASSERT(from < to && to <= chosen.size());

  AqlItemBlock* res = new AqlItemBlock(to - from, _nrRegs);
  for (RegisterId col = 0; col < _nrRegs; col++) {
    res->_docColls[col] = _docColls[col];
  }
  try {
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue& a(_data[chosen[row] * _nrRegs + col]);

        if (! a.isEmpty()) {
          steal(a);
          try {
            res->setValue(row - from, col, a);
          }
          catch (...) {
            a.destroy();
          }
          eraseValue(chosen[row], col);
        }
      }
    }
  }
  catch (...) {
    delete res;
    throw;
  }
  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief concatenate multiple blocks, note that the new block now owns all
/// AqlValue pointers in the old blocks, therefore, the latter are all
/// set to nullptr, just to be sure.
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::concatenate (std::vector<AqlItemBlock*> const& blocks) {
  TRI_ASSERT(! blocks.empty());

  auto it = blocks.begin();
  TRI_ASSERT(it != blocks.end());
  size_t totalSize = (*it)->size();
  RegisterId nrRegs = (*it)->getNrRegs();

  while (true) {
    if (++it == blocks.end()) {
      break;
    }
    totalSize += (*it)->size();
    TRI_ASSERT((*it)->getNrRegs() == nrRegs);
  }

  TRI_ASSERT(totalSize > 0);
  TRI_ASSERT(nrRegs > 0);

  auto res = new AqlItemBlock(totalSize, nrRegs);
  try {
    size_t pos = 0;
    for (it = blocks.begin(); it != blocks.end(); ++it) {
      // handle collections
      if (it == blocks.begin()) {
        // copy collection info over
        for (RegisterId col = 0; col < nrRegs; ++col) {
          res->setDocumentCollection(col, (*it)->getDocumentCollection(col));
        }
      }
      else {
        for (RegisterId col = 0; col < nrRegs; ++col) {
          TRI_ASSERT(res->getDocumentCollection(col) ==
                     (*it)->getDocumentCollection(col));
        }
      }

      TRI_ASSERT((*it) != res);
      size_t const n = (*it)->size();
      for (size_t row = 0; row < n; ++row) {
        for (RegisterId col = 0; col < nrRegs; ++col) {
          // copy over value
          if (! (*it)->getValue(row, col).isEmpty()) {
            res->setValue(pos + row, col, (*it)->getValue(row, col));
          }
        }
      }
      (*it)->eraseAll();
      pos += (*it)->size();
    }
  }
  catch (...) {
    delete res;
    throw;
  }

  return res;
}

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

<commit_msg>Fix a memory leak in deletion of AqlValues that are no longer needed.<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql item block
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2014 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
/// @author Copyright 2014, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/AqlItemBlock.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                                      AqlItemBlock
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief create the block
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock::AqlItemBlock (size_t nrItems,
                            RegisterId nrRegs)
  : _nrItems(nrItems), _nrRegs(nrRegs) {

  TRI_ASSERT(nrItems > 0);  // no, empty AqlItemBlocks are not allowed!

  if (nrItems > 0 && nrRegs > 0) {
    _data.reserve(nrItems * nrRegs);
    for (size_t i = 0; i < nrItems * nrRegs; ++i) {
      _data.emplace_back();
    }
  }

  if (nrRegs > 0) {
    _docColls.reserve(nrRegs);
    for (size_t i = 0; i < nrRegs; ++i) {
      _docColls.push_back(nullptr);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the block
/// TODO: dtor is not exception-safe
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock::~AqlItemBlock () {
  for (size_t i = 0; i < _nrItems * _nrRegs; i++) {
    if (! _data[i].isEmpty()) {
      auto it = _valueCount.find(_data[i]);
      if (it != _valueCount.end()) { // if we know it, we are still responsible
        if (--(it->second) == 0) {
          _data[i].destroy();
          try {
            _valueCount.erase(it);
          }
          catch (...) {
          }
        }
      }
      // Note that if we do not know it the thing it has been stolen from us!
    }
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief shrink the block to the specified number of rows
////////////////////////////////////////////////////////////////////////////////

void AqlItemBlock::shrink (size_t nrItems) {
  TRI_ASSERT(nrItems > 0);

  if (nrItems == _nrItems) {
    // nothing to do
    return;
  }

  if (nrItems > _nrItems) {
    // cannot use shrink() to increase the size of the block
    THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
  }

  // erase all stored values in the region that we freed
  for (size_t i = nrItems; i < _nrItems; ++i) {
    for (RegisterId j = 0; j < _nrRegs; ++j) {
      eraseValue(i, j);
    }
  }

  // adjust the size of the block
  _nrItems = nrItems;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief clears out some columns (registers), this deletes the values if
/// necessary, using the reference count.
////////////////////////////////////////////////////////////////////////////////

void AqlItemBlock::clearRegisters (std::unordered_set<RegisterId>& toClear) {
  for (auto reg : toClear) {
    for (size_t i = 0; i < _nrItems; i++) {
      AqlValue& a(_data[_nrRegs * i + reg]);
      if (! a.isEmpty()) {
        auto it = _valueCount.find(a);
        if (it != _valueCount.end()) {
          if (--it->second == 0) {
            try {
              _valueCount.erase(it);
              a.destroy();
            }
            catch (...) {
              it->second++;
              throw;
            }
          }
        }
        a.erase();
      }
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief slice/clone, this does a deep copy of all entries
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::slice (size_t from,
                                   size_t to) const {
  TRI_ASSERT(from < to && to <= _nrItems);

  std::unordered_map<AqlValue, AqlValue> cache;
  // TODO: should we pre-reserve space for cache to avoid later re-allocations?

  AqlItemBlock* res = nullptr;
  try {
    res = new AqlItemBlock(to - from, _nrRegs);

    for (RegisterId col = 0; col < _nrRegs; col++) {
      res->_docColls[col] = _docColls[col];
    }
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue const& a(_data[row * _nrRegs + col]);

        if (! a.isEmpty()) {
          auto it = cache.find(a);
          if (it == cache.end()) {
            AqlValue b = a.clone();
            res->_data[(row - from) * _nrRegs + col] = b;
            // TODO: can we use emplace() here instead of insert()?
            cache.insert(make_pair(a, b));
          }
          else {
            res->_data[(row - from) * _nrRegs + col] = it->second;
          }
        }
      }
    }

    return res;
  }
  catch (...) {
    delete res;
    throw;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief slice/clone chosen rows for a subset, this does a deep copy
/// of all entries
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::slice (std::vector<size_t>& chosen,
                                   size_t from,
                                   size_t to) const {
  TRI_ASSERT(from < to && to <= chosen.size());

  std::unordered_map<AqlValue, AqlValue> cache;
  // TODO: should we pre-reserve space for cache to avoid later re-allocations?

  AqlItemBlock* res = nullptr;
  try {
    res = new AqlItemBlock(to - from, _nrRegs);

    for (RegisterId col = 0; col < _nrRegs; col++) {
      res->_docColls[col] = _docColls[col];
    }
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue const& a(_data[chosen[row] * _nrRegs + col]);

        if (! a.isEmpty()) {
          auto it = cache.find(a);
          if (it == cache.end()) {
            AqlValue b = a.clone();
            res->_data[(row - from) * _nrRegs + col] = b;
            // TODO: can we use emplace() here instead of insert()?
            cache.insert(make_pair(a, b));
          }
          else {
            res->_data[(row - from) * _nrRegs + col] = it->second;
          }
        }
      }
    }

    return res;
  }
  catch (...) {
    delete res;
    throw;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief steal for a subset, this does not copy the entries, rather,
/// it remembers which it has taken. This is stored in the
/// this by removing the value counts in _valueCount.
/// It is highly recommended to delete this object right after this
/// operation, because it is unclear, when the values to which our
/// AqlValues point will vanish! In particular, do not use setValue
/// any more.
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::steal (vector<size_t>& chosen,
                                   size_t from, size_t to) {
  TRI_ASSERT(from < to && to <= chosen.size());

  AqlItemBlock* res = new AqlItemBlock(to - from, _nrRegs);
  for (RegisterId col = 0; col < _nrRegs; col++) {
    res->_docColls[col] = _docColls[col];
  }
  try {
    for (size_t row = from; row < to; row++) {
      for (RegisterId col = 0; col < _nrRegs; col++) {
        AqlValue& a(_data[chosen[row] * _nrRegs + col]);

        if (! a.isEmpty()) {
          steal(a);
          try {
            res->setValue(row - from, col, a);
          }
          catch (...) {
            a.destroy();
          }
          eraseValue(chosen[row], col);
        }
      }
    }
  }
  catch (...) {
    delete res;
    throw;
  }
  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief concatenate multiple blocks, note that the new block now owns all
/// AqlValue pointers in the old blocks, therefore, the latter are all
/// set to nullptr, just to be sure.
////////////////////////////////////////////////////////////////////////////////

AqlItemBlock* AqlItemBlock::concatenate (std::vector<AqlItemBlock*> const& blocks) {
  TRI_ASSERT(! blocks.empty());

  auto it = blocks.begin();
  TRI_ASSERT(it != blocks.end());
  size_t totalSize = (*it)->size();
  RegisterId nrRegs = (*it)->getNrRegs();

  while (true) {
    if (++it == blocks.end()) {
      break;
    }
    totalSize += (*it)->size();
    TRI_ASSERT((*it)->getNrRegs() == nrRegs);
  }

  TRI_ASSERT(totalSize > 0);
  TRI_ASSERT(nrRegs > 0);

  auto res = new AqlItemBlock(totalSize, nrRegs);
  try {
    size_t pos = 0;
    for (it = blocks.begin(); it != blocks.end(); ++it) {
      // handle collections
      if (it == blocks.begin()) {
        // copy collection info over
        for (RegisterId col = 0; col < nrRegs; ++col) {
          res->setDocumentCollection(col, (*it)->getDocumentCollection(col));
        }
      }
      else {
        for (RegisterId col = 0; col < nrRegs; ++col) {
          TRI_ASSERT(res->getDocumentCollection(col) ==
                     (*it)->getDocumentCollection(col));
        }
      }

      TRI_ASSERT((*it) != res);
      size_t const n = (*it)->size();
      for (size_t row = 0; row < n; ++row) {
        for (RegisterId col = 0; col < nrRegs; ++col) {
          // copy over value
          if (! (*it)->getValue(row, col).isEmpty()) {
            res->setValue(pos + row, col, (*it)->getValue(row, col));
          }
        }
      }
      (*it)->eraseAll();
      pos += (*it)->size();
    }
  }
  catch (...) {
    delete res;
    throw;
  }

  return res;
}

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

<|endoftext|>


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

#include "chrome/browser/diagnostics/recon_diagnostics.h"

#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/path_service.h"
#include "chrome/browser/diagnostics/diagnostics_test.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/platform_util.h"
#include "app/app_paths.h"

#if defined(OS_WIN)
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#endif

// Reconnaissance diagnostics. These are the first and most critical
// diagnostic tests. Here we check for the existence of critical files.
// TODO(cpu): Define if it makes sense to localize strings.

namespace {

class InstallTypeTest;
InstallTypeTest* g_install_type = 0;

// Check that the flavor of the operating system is supported.
class OperatingSystemTest : public DiagnosticTest {
 public:
  OperatingSystemTest() : DiagnosticTest(ASCIIToUTF16("Operating System")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    int version = 0;
    int major = 0;
    int minor = 0;
#if defined(OS_WIN)
    version = win_util::GetWinVersion();
    if (version < win_util::WINVERSION_XP) {
      RecordFailure(ASCIIToUTF16("Windows 2000 or earlier"));
      return false;
    }
    win_util::GetServicePackLevel(&major, &minor);
    if ((version == win_util::WINVERSION_XP) && (major < 2)) {
      RecordFailure(ASCIIToUTF16("XP Service Pack 1 or earlier"));
      return false;
    }
#else
    // TODO(port): define the OS criteria for linux and mac.
#endif  // defined(OS_WIN)
    RecordSuccess(ASCIIToUTF16(StringPrintf("%s %s (%d [%d:%d])",
        base::SysInfo::OperatingSystemName().c_str(),
        base::SysInfo::OperatingSystemVersion().c_str(),
        version, major, minor)));
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(OperatingSystemTest);
};

// Check if it is system install or per-user install.
class InstallTypeTest : public DiagnosticTest {
 public:
  InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")),
                      user_level_(false) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
#if defined(OS_WIN)
    FilePath chrome_exe;
    if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
      RecordFailure(ASCIIToUTF16("Path provider failure"));
      return false;
    }
    user_level_ = InstallUtil::IsPerUserInstall(
        chrome_exe.ToWStringHack().c_str());
    const char* type = user_level_ ? "User Level" : "System Level";
    string16 install_type(ASCIIToUTF16(type));
#else
    string16 install_type(ASCIIToUTF16("System Level"));
#endif  // defined(OS_WIN)
    RecordSuccess(install_type);
    g_install_type = this;
    return true;
  }

  bool system_level() const { return !user_level_; }

 private:
  bool user_level_;
  DISALLOW_COPY_AND_ASSIGN(InstallTypeTest);
};

// Check the version of Chrome.
class VersionTest : public DiagnosticTest {
 public:
  VersionTest() : DiagnosticTest(ASCIIToUTF16("Browser Version")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    scoped_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfoForCurrentModule());
    if (!version_info.get()) {
      RecordFailure(ASCIIToUTF16("No Version"));
      return true;
    }
    string16 current_version = WideToUTF16(version_info->file_version());
    if (current_version.empty()) {
      RecordFailure(ASCIIToUTF16("Empty Version"));
      return true;
    }
    string16 version_modifier = platform_util::GetVersionStringModifier();
    if (!version_modifier.empty()) {
      current_version += ASCIIToUTF16(" ");
      current_version += version_modifier;
    }
#if defined(GOOGLE_CHROME_BUILD)
    current_version += ASCIIToUTF16(" GCB");
#endif  // defined(GOOGLE_CHROME_BUILD)
    RecordSuccess(current_version);
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(VersionTest);
};

struct TestPathInfo {
  const char* test_name;
  int dir_id;
  bool test_writable;
  int64 max_size;
};

const int64 kOneKilo = 1024;
const int64 kOneMeg = 1024 * kOneKilo;

const TestPathInfo kPathsToTest[] = {
  {"User data Directory", chrome::DIR_USER_DATA, true, 250 * kOneMeg},
  {"Local state file", chrome::FILE_LOCAL_STATE, true, 200 * kOneKilo},
  {"Dictionaries Directory", chrome::DIR_APP_DICTIONARIES, false, 0},
  {"Inspector Directory", chrome::DIR_INSPECTOR, false, 0}
};

// Check that the user's data directory exists and the paths are writeable.
// If it is a systemwide install some paths are not expected to be writeable.
// This test depends on |InstallTypeTest| having run succesfuly.
class PathTest : public DiagnosticTest {
 public:
  explicit PathTest(const TestPathInfo& path_info)
      : DiagnosticTest(ASCIIToUTF16(path_info.test_name)),
        path_info_(path_info) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    if (!g_install_type) {
      RecordStopFailure(ASCIIToUTF16("dependency failure"));
      return false;
    }
    FilePath dir_or_file;
    if (!PathService::Get(path_info_.dir_id, &dir_or_file)) {
      RecordStopFailure(ASCIIToUTF16("Path provider failure"));
      return false;
    }
    if (!file_util::PathExists(dir_or_file)) {
      RecordFailure(ASCIIToUTF16("Path not found"));
      return true;
    }

    int64 dir_or_file_size;
    if (!file_util::GetFileSize(dir_or_file, &dir_or_file_size)) {
      RecordFailure(ASCIIToUTF16("Cannot obtain size"));
      return true;
    }
    DataUnits units = GetByteDisplayUnits(dir_or_file_size);
    string16 printable_size =
        WideToUTF16(FormatBytes(dir_or_file_size, units, true));

    if (path_info_.max_size > 0) {
      if (dir_or_file_size > path_info_.max_size) {
        RecordFailure(ASCIIToUTF16("Path is too big: ") + printable_size);
        return true;
      }
    }
    if (g_install_type->system_level() && !path_info_.test_writable) {
      RecordSuccess(ASCIIToUTF16("Path exists"));
      return true;
    }
    if (!file_util::PathIsWritable(dir_or_file)) {
      RecordFailure(ASCIIToUTF16("Path is not writable"));
      return true;
    }
    RecordSuccess(ASCIIToUTF16("Path exists and is writable: ")
                  + printable_size);
    return true;
  }

 private:
  TestPathInfo path_info_;
  DISALLOW_COPY_AND_ASSIGN(PathTest);
};

// Check that the disk space in the volume where the user data dir normally
// lives is not dangerosly low.
class DiskSpaceTest : public DiagnosticTest {
 public:
  DiskSpaceTest() : DiagnosticTest(ASCIIToUTF16("Disk Space")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    FilePath data_dir;
    if (!PathService::Get(chrome::DIR_USER_DATA, &data_dir))
      return false;
    int64 disk_space = base::SysInfo::AmountOfFreeDiskSpace(data_dir);
    if (disk_space < 0) {
      RecordFailure(ASCIIToUTF16("Unable to query free space"));
      return true;
    }
    DataUnits units = GetByteDisplayUnits(disk_space);
    string16 printable_size =
        WideToUTF16(FormatBytes(disk_space, units, true));
    if (disk_space < 80 * kOneMeg) {
      RecordFailure(ASCIIToUTF16("Low disk space : ") + printable_size);
      return true;
    }
    RecordSuccess(ASCIIToUTF16("Free space : ") + printable_size);
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DiskSpaceTest);
};

}  // namespace

DiagnosticTest* MakeUserDirTest() {
  return new PathTest(kPathsToTest[0]);
}

DiagnosticTest* MakeLocalStateFileTest() {
  return new PathTest(kPathsToTest[1]);
}

DiagnosticTest* MakeDictonaryDirTest() {
  return new PathTest(kPathsToTest[2]);
}

DiagnosticTest* MakeInspectorDirTest() {
  return new PathTest(kPathsToTest[3]);
}

DiagnosticTest* MakeVersionTest() {
  return new VersionTest();
}

DiagnosticTest* MakeDiskSpaceTest() {
  return new DiskSpaceTest();
}

DiagnosticTest* MakeOperatingSystemTest() {
  return new OperatingSystemTest();
}

DiagnosticTest* MakeInstallTypeTest() {
  return new InstallTypeTest();
}

<commit_msg>Diagnostic mode shows wrong size for certain paths - See the bug, it has a screenshot<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/diagnostics/recon_diagnostics.h"

#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/path_service.h"
#include "chrome/browser/diagnostics/diagnostics_test.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/platform_util.h"
#include "app/app_paths.h"

#if defined(OS_WIN)
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#endif

// Reconnaissance diagnostics. These are the first and most critical
// diagnostic tests. Here we check for the existence of critical files.
// TODO(cpu): Define if it makes sense to localize strings.

namespace {

class InstallTypeTest;
InstallTypeTest* g_install_type = 0;

// Check that the flavor of the operating system is supported.
class OperatingSystemTest : public DiagnosticTest {
 public:
  OperatingSystemTest() : DiagnosticTest(ASCIIToUTF16("Operating System")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    int version = 0;
    int major = 0;
    int minor = 0;
#if defined(OS_WIN)
    version = win_util::GetWinVersion();
    if (version < win_util::WINVERSION_XP) {
      RecordFailure(ASCIIToUTF16("Windows 2000 or earlier"));
      return false;
    }
    win_util::GetServicePackLevel(&major, &minor);
    if ((version == win_util::WINVERSION_XP) && (major < 2)) {
      RecordFailure(ASCIIToUTF16("XP Service Pack 1 or earlier"));
      return false;
    }
#else
    // TODO(port): define the OS criteria for linux and mac.
#endif  // defined(OS_WIN)
    RecordSuccess(ASCIIToUTF16(StringPrintf("%s %s (%d [%d:%d])",
        base::SysInfo::OperatingSystemName().c_str(),
        base::SysInfo::OperatingSystemVersion().c_str(),
        version, major, minor)));
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(OperatingSystemTest);
};

// Check if it is system install or per-user install.
class InstallTypeTest : public DiagnosticTest {
 public:
  InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")),
                      user_level_(false) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
#if defined(OS_WIN)
    FilePath chrome_exe;
    if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
      RecordFailure(ASCIIToUTF16("Path provider failure"));
      return false;
    }
    user_level_ = InstallUtil::IsPerUserInstall(
        chrome_exe.ToWStringHack().c_str());
    const char* type = user_level_ ? "User Level" : "System Level";
    string16 install_type(ASCIIToUTF16(type));
#else
    string16 install_type(ASCIIToUTF16("System Level"));
#endif  // defined(OS_WIN)
    RecordSuccess(install_type);
    g_install_type = this;
    return true;
  }

  bool system_level() const { return !user_level_; }

 private:
  bool user_level_;
  DISALLOW_COPY_AND_ASSIGN(InstallTypeTest);
};

// Check the version of Chrome.
class VersionTest : public DiagnosticTest {
 public:
  VersionTest() : DiagnosticTest(ASCIIToUTF16("Browser Version")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    scoped_ptr<FileVersionInfo> version_info(
        FileVersionInfo::CreateFileVersionInfoForCurrentModule());
    if (!version_info.get()) {
      RecordFailure(ASCIIToUTF16("No Version"));
      return true;
    }
    string16 current_version = WideToUTF16(version_info->file_version());
    if (current_version.empty()) {
      RecordFailure(ASCIIToUTF16("Empty Version"));
      return true;
    }
    string16 version_modifier = platform_util::GetVersionStringModifier();
    if (!version_modifier.empty()) {
      current_version += ASCIIToUTF16(" ");
      current_version += version_modifier;
    }
#if defined(GOOGLE_CHROME_BUILD)
    current_version += ASCIIToUTF16(" GCB");
#endif  // defined(GOOGLE_CHROME_BUILD)
    RecordSuccess(current_version);
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(VersionTest);
};

struct TestPathInfo {
  const char* test_name;
  int  path_id;
  bool is_directory;
  bool is_optional;
  bool test_writable;
  int64 max_size;
};

const int64 kOneKilo = 1024;
const int64 kOneMeg = 1024 * kOneKilo;

const TestPathInfo kPathsToTest[] = {
  {"User data Directory", chrome::DIR_USER_DATA,
      true, false, true, 250 * kOneMeg},
  {"Local state file", chrome::FILE_LOCAL_STATE,
      false, false, true, 100 * kOneKilo},
  {"Dictionaries Directory", chrome::DIR_APP_DICTIONARIES,
      true, true, false, 0},
  {"Inspector Directory", chrome::DIR_INSPECTOR,
      true, false, false, 0}
};

// Check that the user's data directory exists and the paths are writeable.
// If it is a systemwide install some paths are not expected to be writeable.
// This test depends on |InstallTypeTest| having run succesfuly.
class PathTest : public DiagnosticTest {
 public:
  explicit PathTest(const TestPathInfo& path_info)
      : DiagnosticTest(ASCIIToUTF16(path_info.test_name)),
        path_info_(path_info) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    if (!g_install_type) {
      RecordStopFailure(ASCIIToUTF16("dependency failure"));
      return false;
    }
    FilePath dir_or_file;
    if (!PathService::Get(path_info_.path_id, &dir_or_file)) {
      RecordStopFailure(ASCIIToUTF16("Path provider failure"));
      return false;
    }
    if (!file_util::PathExists(dir_or_file)) {
      RecordFailure(ASCIIToUTF16("Path not found"));
      return true;
    }

    int64 dir_or_file_size = 0;
    if (path_info_.is_directory) {
      dir_or_file_size = file_util::ComputeDirectorySize(dir_or_file);
    } else {
      file_util::GetFileSize(dir_or_file, &dir_or_file_size);
    }
    if (!dir_or_file_size && !path_info_.is_optional) {
      RecordFailure(ASCIIToUTF16("Cannot obtain size"));
      return true;
    }
    DataUnits units = GetByteDisplayUnits(dir_or_file_size);
    string16 printable_size =
        WideToUTF16(FormatBytes(dir_or_file_size, units, true));

    if (path_info_.max_size > 0) {
      if (dir_or_file_size > path_info_.max_size) {
        RecordFailure(ASCIIToUTF16("Path is too big: ") + printable_size);
        return true;
      }
    }
    if (g_install_type->system_level() && !path_info_.test_writable) {
      RecordSuccess(ASCIIToUTF16("Path exists"));
      return true;
    }
    if (!file_util::PathIsWritable(dir_or_file)) {
      RecordFailure(ASCIIToUTF16("Path is not writable"));
      return true;
    }
    RecordSuccess(ASCIIToUTF16("Path exists and is writable: ")
                  + printable_size);
    return true;
  }

 private:
  TestPathInfo path_info_;
  DISALLOW_COPY_AND_ASSIGN(PathTest);
};

// Check that the disk space in the volume where the user data dir normally
// lives is not dangerosly low.
class DiskSpaceTest : public DiagnosticTest {
 public:
  DiskSpaceTest() : DiagnosticTest(ASCIIToUTF16("Disk Space")) {}

  virtual int GetId() { return 0; }

  virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) {
    FilePath data_dir;
    if (!PathService::Get(chrome::DIR_USER_DATA, &data_dir))
      return false;
    int64 disk_space = base::SysInfo::AmountOfFreeDiskSpace(data_dir);
    if (disk_space < 0) {
      RecordFailure(ASCIIToUTF16("Unable to query free space"));
      return true;
    }
    DataUnits units = GetByteDisplayUnits(disk_space);
    string16 printable_size =
        WideToUTF16(FormatBytes(disk_space, units, true));
    if (disk_space < 80 * kOneMeg) {
      RecordFailure(ASCIIToUTF16("Low disk space : ") + printable_size);
      return true;
    }
    RecordSuccess(ASCIIToUTF16("Free space : ") + printable_size);
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DiskSpaceTest);
};

}  // namespace

DiagnosticTest* MakeUserDirTest() {
  return new PathTest(kPathsToTest[0]);
}

DiagnosticTest* MakeLocalStateFileTest() {
  return new PathTest(kPathsToTest[1]);
}

DiagnosticTest* MakeDictonaryDirTest() {
  return new PathTest(kPathsToTest[2]);
}

DiagnosticTest* MakeInspectorDirTest() {
  return new PathTest(kPathsToTest[3]);
}

DiagnosticTest* MakeVersionTest() {
  return new VersionTest();
}

DiagnosticTest* MakeDiskSpaceTest() {
  return new DiskSpaceTest();
}

DiagnosticTest* MakeOperatingSystemTest() {
  return new OperatingSystemTest();
}

DiagnosticTest* MakeInstallTypeTest() {
  return new InstallTypeTest();
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <exception>

#include <glog/logging.h>
#include <gtest/gtest.h>
#include <react/uimanager/ComponentDescriptorFactory.h>
#include <react/uimanager/UITemplateProcessor.h>

using namespace facebook::react;

#include <react/components/rncore/ComponentDescriptors.h>
#include <react/components/scrollview/ScrollViewComponentDescriptor.h>
#include <react/components/view/ViewComponentDescriptor.h>
#include <react/config/ReactNativeConfig.h>
#include <react/uimanager/ComponentDescriptorFactory.h>
#include <react/uimanager/ComponentDescriptorRegistry.h>
#include <react/utils/ContextContainer.h>

namespace facebook {
namespace react {

static ComponentRegistryFactory getComponentRegistryFactory() {
  return [](const EventDispatcher::Weak &eventDispatcher,
            const ContextContainer::Shared &contextContainer) {
    auto registry = std::make_shared<ComponentDescriptorRegistry>();
    registry->registerComponentDescriptor(
        std::make_shared<ViewComponentDescriptor>(eventDispatcher));
    registry->registerComponentDescriptor(
        std::make_shared<ScrollViewComponentDescriptor>(eventDispatcher));
    registry->registerComponentDescriptor(
        std::make_shared<ActivityIndicatorViewComponentDescriptor>(
            eventDispatcher));
    return registry;
  };
}

bool mockSimpleTestValue_;

NativeModuleRegistry buildNativeModuleRegistry();

NativeModuleRegistry buildNativeModuleRegistry() {
  NativeModuleRegistry nMR;
  nMR.registerModule(
      "MobileConfig",
      [&](const std::string &methodName, const folly::dynamic &args) {
        return mockSimpleTestValue_;
      });
  return nMR;
}

class MockReactNativeConfig : public ReactNativeConfig {
 public:
  MockReactNativeConfig() {}
  bool getBool(const std::string &param) const override {
    return mockSimpleTestValue_;
  }

  std::string getString(const std::string &param) const override {
    return "";
  }

  int64_t getInt64(const std::string &param) const override {
    return 0;
  }

  double getDouble(const std::string &param) const override {
    return 0.0;
  }
};

std::shared_ptr<const ReactNativeConfig> mockReactNativeConfig_ =
    std::make_shared<const MockReactNativeConfig>();

} // namespace react
} // namespace facebook

TEST(UITemplateProcessorTest, testSimpleBytecode) {
  auto surfaceId = 11;
  auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
  auto componentDescriptorRegistry =
      getComponentRegistryFactory()(eventDispatcher, nullptr);
  auto nativeModuleRegistry = buildNativeModuleRegistry();

  auto bytecode = R"delim({"version":0.1,"commands":[
    ["createNode",2,"RCTView",-1,{"opacity": 0.5, "testId": "root"}],
    ["createNode",4,"RCTView",2,{"testId": "child"}],
    ["returnRoot",2]
  ]})delim";

  mockSimpleTestValue_ = true;

  auto root1 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
#ifndef NDEBUG
  LOG(INFO) << std::endl << root1->getDebugDescription();
#endif
  auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
  ASSERT_NEAR(props1->opacity, 0.5, 0.001);
  ASSERT_STREQ(props1->testId.c_str(), "root");
  auto children1 = root1->getChildren();
  ASSERT_EQ(children1.size(), 1);
  auto child_props1 =
      std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
  ASSERT_STREQ(child_props1->testId.c_str(), "child");
}

TEST(UITemplateProcessorTest, testConditionalBytecode) {
  auto surfaceId = 11;
  auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
  auto componentDescriptorRegistry =
      getComponentRegistryFactory()(eventDispatcher, nullptr);
  auto nativeModuleRegistry = buildNativeModuleRegistry();

  auto bytecode = R"delim({"version":0.1,"commands":[
    ["createNode",2,"RCTView",-1,{"testId": "root"}],
    ["loadNativeBool",1,"MobileConfig","getBool",["qe:simple_test"]],
    ["conditional",1,
      [["createNode",4,"RCTView",2,{"testId": "cond_true"}]],
      [["createNode",4,"RCTView",2,{"testId": "cond_false"}]]
    ],
    ["returnRoot",2]
  ]})delim";

  mockSimpleTestValue_ = true;

  auto root1 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
#ifndef NDEBUG
  LOG(INFO) << std::endl << root1->getDebugDescription();
#endif
  auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
  ASSERT_STREQ(props1->testId.c_str(), "root");
  auto children1 = root1->getChildren();
  ASSERT_EQ(children1.size(), 1);
  auto child_props1 =
      std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
  ASSERT_STREQ(child_props1->testId.c_str(), "cond_true");

  mockSimpleTestValue_ = false;

  auto root2 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
  auto child_props2 = std::dynamic_pointer_cast<const ViewProps>(
      root2->getChildren().at(0)->getProps());
  ASSERT_STREQ(child_props2->testId.c_str(), "cond_false");
}
<commit_msg>Fabric: Using ComponentDescriptorProviderRegistry in UITemplateProcessorTest<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <exception>

#include <glog/logging.h>
#include <gtest/gtest.h>
#include <react/uimanager/ComponentDescriptorFactory.h>
#include <react/uimanager/UITemplateProcessor.h>

using namespace facebook::react;

#include <react/components/rncore/ComponentDescriptors.h>
#include <react/components/scrollview/ScrollViewComponentDescriptor.h>
#include <react/components/view/ViewComponentDescriptor.h>
#include <react/config/ReactNativeConfig.h>
#include <react/uimanager/ComponentDescriptorFactory.h>
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>
#include <react/uimanager/ComponentDescriptorRegistry.h>
#include <react/utils/ContextContainer.h>

namespace facebook {
namespace react {

static ComponentRegistryFactory getComponentRegistryFactory() {
  return [](const EventDispatcher::Weak &eventDispatcher,
            const ContextContainer::Shared &contextContainer) {
    ComponentDescriptorProviderRegistry providerRegistry{};
    providerRegistry.add(
        concreteComponentDescriptorProvider<ViewComponentDescriptor>());
    providerRegistry.add(
        concreteComponentDescriptorProvider<ScrollViewComponentDescriptor>());
    providerRegistry.add(concreteComponentDescriptorProvider<
                         ActivityIndicatorViewComponentDescriptor>());
    return providerRegistry.createComponentDescriptorRegistry(
        {eventDispatcher, contextContainer});
  };
}

bool mockSimpleTestValue_;

NativeModuleRegistry buildNativeModuleRegistry();

NativeModuleRegistry buildNativeModuleRegistry() {
  NativeModuleRegistry nMR;
  nMR.registerModule(
      "MobileConfig",
      [&](const std::string &methodName, const folly::dynamic &args) {
        return mockSimpleTestValue_;
      });
  return nMR;
}

class MockReactNativeConfig : public ReactNativeConfig {
 public:
  MockReactNativeConfig() {}
  bool getBool(const std::string &param) const override {
    return mockSimpleTestValue_;
  }

  std::string getString(const std::string &param) const override {
    return "";
  }

  int64_t getInt64(const std::string &param) const override {
    return 0;
  }

  double getDouble(const std::string &param) const override {
    return 0.0;
  }
};

std::shared_ptr<const ReactNativeConfig> mockReactNativeConfig_ =
    std::make_shared<const MockReactNativeConfig>();

} // namespace react
} // namespace facebook

TEST(UITemplateProcessorTest, testSimpleBytecode) {
  auto surfaceId = 11;
  auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
  auto componentDescriptorRegistry =
      getComponentRegistryFactory()(eventDispatcher, nullptr);
  auto nativeModuleRegistry = buildNativeModuleRegistry();

  auto bytecode = R"delim({"version":0.1,"commands":[
    ["createNode",2,"RCTView",-1,{"opacity": 0.5, "testId": "root"}],
    ["createNode",4,"RCTView",2,{"testId": "child"}],
    ["returnRoot",2]
  ]})delim";

  mockSimpleTestValue_ = true;

  auto root1 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
#ifndef NDEBUG
  LOG(INFO) << std::endl << root1->getDebugDescription();
#endif
  auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
  ASSERT_NEAR(props1->opacity, 0.5, 0.001);
  ASSERT_STREQ(props1->testId.c_str(), "root");
  auto children1 = root1->getChildren();
  ASSERT_EQ(children1.size(), 1);
  auto child_props1 =
      std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
  ASSERT_STREQ(child_props1->testId.c_str(), "child");
}

TEST(UITemplateProcessorTest, testConditionalBytecode) {
  auto surfaceId = 11;
  auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
  auto componentDescriptorRegistry =
      getComponentRegistryFactory()(eventDispatcher, nullptr);
  auto nativeModuleRegistry = buildNativeModuleRegistry();

  auto bytecode = R"delim({"version":0.1,"commands":[
    ["createNode",2,"RCTView",-1,{"testId": "root"}],
    ["loadNativeBool",1,"MobileConfig","getBool",["qe:simple_test"]],
    ["conditional",1,
      [["createNode",4,"RCTView",2,{"testId": "cond_true"}]],
      [["createNode",4,"RCTView",2,{"testId": "cond_false"}]]
    ],
    ["returnRoot",2]
  ]})delim";

  mockSimpleTestValue_ = true;

  auto root1 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
#ifndef NDEBUG
  LOG(INFO) << std::endl << root1->getDebugDescription();
#endif
  auto props1 = std::dynamic_pointer_cast<const ViewProps>(root1->getProps());
  ASSERT_STREQ(props1->testId.c_str(), "root");
  auto children1 = root1->getChildren();
  ASSERT_EQ(children1.size(), 1);
  auto child_props1 =
      std::dynamic_pointer_cast<const ViewProps>(children1.at(0)->getProps());
  ASSERT_STREQ(child_props1->testId.c_str(), "cond_true");

  mockSimpleTestValue_ = false;

  auto root2 = UITemplateProcessor::buildShadowTree(
      bytecode,
      surfaceId,
      folly::dynamic::object(),
      *componentDescriptorRegistry,
      nativeModuleRegistry,
      mockReactNativeConfig_);
  auto child_props2 = std::dynamic_pointer_cast<const ViewProps>(
      root2->getChildren().at(0)->getProps());
  ASSERT_STREQ(child_props2->testId.c_str(), "cond_false");
}
<|endoftext|>


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

#include "chrome/browser/renderer_host/backing_store.h"

#include <utility>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "chrome/common/transport_dib.h"
#include "chrome/common/x11_util.h"
#include "chrome/common/x11_util_internal.h"

// X Backing Stores:
//
// Unlike Windows, where the backing store is kept in heap memory, we keep our
// backing store in the X server, as a pixmap. Thus expose events just require
// instructing the X server to copy from the backing store to the window.
//
// The backing store is in the same format as the visual which our main window
// is using. Bitmaps from the renderer are uploaded to the X server, either via
// shared memory or over the wire, and XRENDER is used to convert them to the
// correct format for the backing store.

BackingStore::BackingStore(const gfx::Size& size,
                           Display* display,
                           int depth,
                           void* visual,
                           Drawable root_window,
                           bool use_render,
                           bool use_shared_memory)
    : size_(size),
      display_(display),
      use_shared_memory_(use_shared_memory),
      use_render_(use_render),
      visual_depth_(depth),
      root_window_(root_window) {
  const int width = size.width();
  const int height = size.height();

  COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian);

  pixmap_ = XCreatePixmap(display_, root_window, width, height, depth);

  if (use_render_) {
    picture_ = XRenderCreatePicture(
        display_, pixmap_,
        x11_util::GetRenderVisualFormat(display_, static_cast<Visual*>(visual)),
        0, NULL);
  } else {
    picture_ = 0;
    pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display, depth);
  }

  pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL);
}

BackingStore::BackingStore(const gfx::Size& size)
    : size_(size),
      display_(NULL),
      use_shared_memory_(false),
      use_render_(false),
      visual_depth_(-1),
      root_window_(0) {
}

BackingStore::~BackingStore() {
  // In unit tests, display_ may be NULL.
  if (!display_)
    return;

  XRenderFreePicture(display_, picture_);
  XFreePixmap(display_, pixmap_);
  XFreeGC(display_, static_cast<GC>(pixmap_gc_));
}

void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap,
                                           const gfx::Rect &bitmap_rect) {
  const int width = bitmap_rect.width();
  const int height = bitmap_rect.height();
  Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height,
                                visual_depth_);

  XImage image;
  memset(&image, 0, sizeof(image));

  image.width = width;
  image.height = height;
  image.format = ZPixmap;
  image.byte_order = LSBFirst;
  image.bitmap_unit = 8;
  image.bitmap_bit_order = LSBFirst;
  image.red_mask = 0xff;
  image.green_mask = 0xff00;
  image.blue_mask = 0xff0000;

  if (pixmap_bpp_ == 32) {
    // If the X server depth is already 32-bits, then our job is easy.
    image.depth = visual_depth_;
    image.bits_per_pixel = 32;
    image.bytes_per_line = width * 4;
    image.data = static_cast<char*>(bitmap->memory());

    XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);
  } else if (pixmap_bpp_ == 24) {
    // In this case we just need to strip the alpha channel out of each
    // pixel. This is the case which covers VNC servers since they don't
    // support Xrender but typically have 24-bit visuals.
    //
    // It's possible to use some fancy SSE tricks here, but since this is the
    // slow path anyway, we do it slowly.

    uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * width * height));
    const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory());
    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        const uint32_t pixel = *(bitmap_in++);
        bitmap24[0] = (pixel >> 16) & 0xff;
        bitmap24[1] = (pixel >> 8) & 0xff;
        bitmap24[2] = pixel & 0xff;
        bitmap24 += 3;
      }
    }

    image.depth = visual_depth_;
    image.bits_per_pixel = 24;
    image.bytes_per_line = width * 3;
    image.data = reinterpret_cast<char*>(bitmap24);

    XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);

    free(bitmap24);
  } else {
    CHECK(false) << "Sorry, we don't support your visual depth without "
                    "Xrender support (depth:" << visual_depth_
                 << " bpp:" << pixmap_bpp_ << ")";
  }

  XCopyArea(display_, pixmap /* source */, pixmap_ /* target */,
            static_cast<GC>(pixmap_gc_),
            0, 0 /* source x, y */, bitmap_rect.width(), bitmap_rect.height(),
            bitmap_rect.x(), bitmap_rect.y() /* dest x, y */);

  XFreePixmap(display_, pixmap);
}

void BackingStore::PaintRect(base::ProcessHandle process,
                             TransportDIB* bitmap,
                             const gfx::Rect& bitmap_rect) {
  if (!display_)
    return;

  if (!use_render_)
    return PaintRectWithoutXrender(bitmap, bitmap_rect);

  const int width = bitmap_rect.width();
  const int height = bitmap_rect.height();
  Picture picture;
  Pixmap pixmap;

  if (use_shared_memory_) {
    const XID shmseg = bitmap->MapToX(display_);

    XShmSegmentInfo shminfo;
    memset(&shminfo, 0, sizeof(shminfo));
    shminfo.shmseg = shmseg;

    // The NULL in the following is the |data| pointer: this is an artifact of
    // Xlib trying to be helpful, rather than just exposing the X protocol. It
    // assumes that we have the shared memory segment mapped into our memory,
    // which we don't, and it's trying to calculate an offset by taking the
    // difference between the |data| pointer and the address of the mapping in
    // |shminfo|. Since both are NULL, the offset will be calculated to be 0,
    // which is correct for us.
    pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo, width,
                              height, 32);
  } else {
    // No shared memory support, we have to copy the bitmap contents to the X
    // server. Xlib wraps the underlying PutImage call behind several layers of
    // functions which try to convert the image into the format which the X
    // server expects. The following values hopefully disable all conversions.
    XImage image;
    memset(&image, 0, sizeof(image));

    image.width = width;
    image.height = height;
    image.depth = 32;
    image.bits_per_pixel = 32;
    image.format = ZPixmap;
    image.byte_order = LSBFirst;
    image.bitmap_unit = 8;
    image.bitmap_bit_order = LSBFirst;
    image.bytes_per_line = width * 4;
    image.red_mask = 0xff;
    image.green_mask = 0xff00;
    image.blue_mask = 0xff0000;
    image.data = static_cast<char*>(bitmap->memory());

    pixmap = XCreatePixmap(display_, root_window_, width, height, 32);
    GC gc = XCreateGC(display_, pixmap, 0, NULL);
    XPutImage(display_, pixmap, gc, &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);
    XFreeGC(display_, gc);
  }

  picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap);
  XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */,
                   picture_ /* dest */, 0, 0 /* source x, y */,
                   0, 0 /* mask x, y */,
                   bitmap_rect.x(), bitmap_rect.y() /* target x, y */,
                   width, height);

  // In the case of shared memory, we wait for the composite to complete so that
  // we are sure that the X server has finished reading.
  if (use_shared_memory_)
    XSync(display_, False);

  XRenderFreePicture(display_, picture);
  XFreePixmap(display_, pixmap);
}

void BackingStore::ScrollRect(base::ProcessHandle process,
                              TransportDIB* bitmap,
                              const gfx::Rect& bitmap_rect,
                              int dx, int dy,
                              const gfx::Rect& clip_rect,
                              const gfx::Size& view_size) {
  if (!display_)
    return;

  // We only support scrolling in one direction at a time.
  DCHECK(dx == 0 || dy == 0);

  if (dy) {
    // Positive values of |dy| scroll up
    XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
              0, std::max(0, -dy) /* source x, y */,
              size_.width(), size_.height() - abs(dy),
              0, std::max(0, dy) /* dest x, y */);
  } else if (dx) {
    // Positive values of |dx| scroll right
    XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
              std::max(0, -dx), 0 /* source x, y */,
              size_.width() - abs(dx), size_.height(),
              std::max(0, dx), 0 /* dest x, y */);
  }

  PaintRect(process, bitmap, bitmap_rect);
}

void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {
  XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_),
            rect.x(), rect.y(), rect.width(), rect.height(),
            rect.x(), rect.y());
}
<commit_msg>Added missing <stdlib.h>, needed on ubuntu 8.10.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/backing_store.h"

#include <stdlib.h>
#include <utility>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "chrome/common/transport_dib.h"
#include "chrome/common/x11_util.h"
#include "chrome/common/x11_util_internal.h"

// X Backing Stores:
//
// Unlike Windows, where the backing store is kept in heap memory, we keep our
// backing store in the X server, as a pixmap. Thus expose events just require
// instructing the X server to copy from the backing store to the window.
//
// The backing store is in the same format as the visual which our main window
// is using. Bitmaps from the renderer are uploaded to the X server, either via
// shared memory or over the wire, and XRENDER is used to convert them to the
// correct format for the backing store.

BackingStore::BackingStore(const gfx::Size& size,
                           Display* display,
                           int depth,
                           void* visual,
                           Drawable root_window,
                           bool use_render,
                           bool use_shared_memory)
    : size_(size),
      display_(display),
      use_shared_memory_(use_shared_memory),
      use_render_(use_render),
      visual_depth_(depth),
      root_window_(root_window) {
  const int width = size.width();
  const int height = size.height();

  COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian);

  pixmap_ = XCreatePixmap(display_, root_window, width, height, depth);

  if (use_render_) {
    picture_ = XRenderCreatePicture(
        display_, pixmap_,
        x11_util::GetRenderVisualFormat(display_, static_cast<Visual*>(visual)),
        0, NULL);
  } else {
    picture_ = 0;
    pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display, depth);
  }

  pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL);
}

BackingStore::BackingStore(const gfx::Size& size)
    : size_(size),
      display_(NULL),
      use_shared_memory_(false),
      use_render_(false),
      visual_depth_(-1),
      root_window_(0) {
}

BackingStore::~BackingStore() {
  // In unit tests, display_ may be NULL.
  if (!display_)
    return;

  XRenderFreePicture(display_, picture_);
  XFreePixmap(display_, pixmap_);
  XFreeGC(display_, static_cast<GC>(pixmap_gc_));
}

void BackingStore::PaintRectWithoutXrender(TransportDIB* bitmap,
                                           const gfx::Rect &bitmap_rect) {
  const int width = bitmap_rect.width();
  const int height = bitmap_rect.height();
  Pixmap pixmap = XCreatePixmap(display_, root_window_, width, height,
                                visual_depth_);

  XImage image;
  memset(&image, 0, sizeof(image));

  image.width = width;
  image.height = height;
  image.format = ZPixmap;
  image.byte_order = LSBFirst;
  image.bitmap_unit = 8;
  image.bitmap_bit_order = LSBFirst;
  image.red_mask = 0xff;
  image.green_mask = 0xff00;
  image.blue_mask = 0xff0000;

  if (pixmap_bpp_ == 32) {
    // If the X server depth is already 32-bits, then our job is easy.
    image.depth = visual_depth_;
    image.bits_per_pixel = 32;
    image.bytes_per_line = width * 4;
    image.data = static_cast<char*>(bitmap->memory());

    XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);
  } else if (pixmap_bpp_ == 24) {
    // In this case we just need to strip the alpha channel out of each
    // pixel. This is the case which covers VNC servers since they don't
    // support Xrender but typically have 24-bit visuals.
    //
    // It's possible to use some fancy SSE tricks here, but since this is the
    // slow path anyway, we do it slowly.

    uint8_t* bitmap24 = static_cast<uint8_t*>(malloc(3 * width * height));
    const uint32_t* bitmap_in = static_cast<const uint32_t*>(bitmap->memory());
    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        const uint32_t pixel = *(bitmap_in++);
        bitmap24[0] = (pixel >> 16) & 0xff;
        bitmap24[1] = (pixel >> 8) & 0xff;
        bitmap24[2] = pixel & 0xff;
        bitmap24 += 3;
      }
    }

    image.depth = visual_depth_;
    image.bits_per_pixel = 24;
    image.bytes_per_line = width * 3;
    image.data = reinterpret_cast<char*>(bitmap24);

    XPutImage(display_, pixmap, static_cast<GC>(pixmap_gc_), &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);

    free(bitmap24);
  } else {
    CHECK(false) << "Sorry, we don't support your visual depth without "
                    "Xrender support (depth:" << visual_depth_
                 << " bpp:" << pixmap_bpp_ << ")";
  }

  XCopyArea(display_, pixmap /* source */, pixmap_ /* target */,
            static_cast<GC>(pixmap_gc_),
            0, 0 /* source x, y */, bitmap_rect.width(), bitmap_rect.height(),
            bitmap_rect.x(), bitmap_rect.y() /* dest x, y */);

  XFreePixmap(display_, pixmap);
}

void BackingStore::PaintRect(base::ProcessHandle process,
                             TransportDIB* bitmap,
                             const gfx::Rect& bitmap_rect) {
  if (!display_)
    return;

  if (!use_render_)
    return PaintRectWithoutXrender(bitmap, bitmap_rect);

  const int width = bitmap_rect.width();
  const int height = bitmap_rect.height();
  Picture picture;
  Pixmap pixmap;

  if (use_shared_memory_) {
    const XID shmseg = bitmap->MapToX(display_);

    XShmSegmentInfo shminfo;
    memset(&shminfo, 0, sizeof(shminfo));
    shminfo.shmseg = shmseg;

    // The NULL in the following is the |data| pointer: this is an artifact of
    // Xlib trying to be helpful, rather than just exposing the X protocol. It
    // assumes that we have the shared memory segment mapped into our memory,
    // which we don't, and it's trying to calculate an offset by taking the
    // difference between the |data| pointer and the address of the mapping in
    // |shminfo|. Since both are NULL, the offset will be calculated to be 0,
    // which is correct for us.
    pixmap = XShmCreatePixmap(display_, root_window_, NULL, &shminfo, width,
                              height, 32);
  } else {
    // No shared memory support, we have to copy the bitmap contents to the X
    // server. Xlib wraps the underlying PutImage call behind several layers of
    // functions which try to convert the image into the format which the X
    // server expects. The following values hopefully disable all conversions.
    XImage image;
    memset(&image, 0, sizeof(image));

    image.width = width;
    image.height = height;
    image.depth = 32;
    image.bits_per_pixel = 32;
    image.format = ZPixmap;
    image.byte_order = LSBFirst;
    image.bitmap_unit = 8;
    image.bitmap_bit_order = LSBFirst;
    image.bytes_per_line = width * 4;
    image.red_mask = 0xff;
    image.green_mask = 0xff00;
    image.blue_mask = 0xff0000;
    image.data = static_cast<char*>(bitmap->memory());

    pixmap = XCreatePixmap(display_, root_window_, width, height, 32);
    GC gc = XCreateGC(display_, pixmap, 0, NULL);
    XPutImage(display_, pixmap, gc, &image,
              0, 0 /* source x, y */, 0, 0 /* dest x, y */,
              width, height);
    XFreeGC(display_, gc);
  }

  picture = x11_util::CreatePictureFromSkiaPixmap(display_, pixmap);
  XRenderComposite(display_, PictOpSrc, picture /* source */, 0 /* mask */,
                   picture_ /* dest */, 0, 0 /* source x, y */,
                   0, 0 /* mask x, y */,
                   bitmap_rect.x(), bitmap_rect.y() /* target x, y */,
                   width, height);

  // In the case of shared memory, we wait for the composite to complete so that
  // we are sure that the X server has finished reading.
  if (use_shared_memory_)
    XSync(display_, False);

  XRenderFreePicture(display_, picture);
  XFreePixmap(display_, pixmap);
}

void BackingStore::ScrollRect(base::ProcessHandle process,
                              TransportDIB* bitmap,
                              const gfx::Rect& bitmap_rect,
                              int dx, int dy,
                              const gfx::Rect& clip_rect,
                              const gfx::Size& view_size) {
  if (!display_)
    return;

  // We only support scrolling in one direction at a time.
  DCHECK(dx == 0 || dy == 0);

  if (dy) {
    // Positive values of |dy| scroll up
    XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
              0, std::max(0, -dy) /* source x, y */,
              size_.width(), size_.height() - abs(dy),
              0, std::max(0, dy) /* dest x, y */);
  } else if (dx) {
    // Positive values of |dx| scroll right
    XCopyArea(display_, pixmap_, pixmap_, static_cast<GC>(pixmap_gc_),
              std::max(0, -dx), 0 /* source x, y */,
              size_.width() - abs(dx), size_.height(),
              std::max(0, dx), 0 /* dest x, y */);
  }

  PaintRect(process, bitmap, bitmap_rect);
}

void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {
  XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_),
            rect.x(), rect.y(), rect.width(), rect.height(),
            rect.x(), rect.y());
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/Engine.hpp"
#include "Methcla/Audio/Group.hpp"

using namespace Methcla::Audio;

#define METHCLA_ASSERT_NODE_IS_BLANK(node) \
    BOOST_ASSERT(node != nullptr); \
    BOOST_ASSERT(node->m_parent == nullptr); \
    BOOST_ASSERT(node->m_prev == nullptr); \
    BOOST_ASSERT(node->m_next == nullptr); \

#define METHCLA_ASSERT_NODE_IS_LINKED(node) \
    BOOST_ASSERT(m_first != nullptr); \
    BOOST_ASSERT(m_last != nullptr); \
    BOOST_ASSERT(node->m_prev != nullptr || node == m_first); \
    BOOST_ASSERT(node->m_next != nullptr || node == m_last); \
    BOOST_ASSERT(m_first != m_last || (m_first == node && node == m_last));

Group::Group(Environment& env, NodeId nodeId)
    : Node(env, nodeId)
    , m_first(nullptr)
    , m_last(nullptr)
{
}

Group::~Group()
{
    freeAll();
}

Group* Group::construct(Environment& env, NodeId nodeId)
{
    return new (env.rtMem().alloc(sizeof(Group))) Group(env, nodeId);
}

void Group::doProcess(size_t numFrames)
{
    Node* node = m_first;
    while (node != nullptr) {
        // Store pointer to next node because current node might be destroyed by done action after process.
        Node* nextNode = node->m_next;
        node->process(numFrames);
        node = nextNode;
    }
}

void Group::addToHead(Node* node)
{
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_next = m_first;

    if (m_first != nullptr) {
        m_first->m_prev = node;
    }

    m_first = node;

    if (m_last == nullptr) {
        m_last = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addToTail(Node* node)
{
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_prev = m_last;

    if (m_last != nullptr) {
        m_last->m_next = node;
    }

    m_last = node;

    if (m_first == nullptr) {
        m_first = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addBefore(Node* target, Node* node)
{
    BOOST_ASSERT(target != nullptr);
    BOOST_ASSERT(target->parent() == this);
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_prev = target->m_prev;
    target->m_prev = node;
    node->m_next = target;

    if (target == m_first) {
        BOOST_ASSERT(node->m_prev == nullptr);
        m_first = node;
    } else {
        BOOST_ASSERT(node->m_prev != nullptr);
        node->m_prev->m_next = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addAfter(Node* target, Node* node)
{
    BOOST_ASSERT(target != nullptr);
    BOOST_ASSERT(target->parent() == this);
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_next = target->m_next;
    target->m_next = node;
    node->m_prev = target;

    if (target == m_last) {
        BOOST_ASSERT(node->m_next == nullptr);
        m_last = node;
    } else {
        BOOST_ASSERT(node->m_next != nullptr);
        node->m_next->m_prev = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::remove(Node* node)
{
    BOOST_ASSERT(node != nullptr);
    BOOST_ASSERT(node->parent() == this);
    BOOST_ASSERT(   (node == m_first && node == m_last && node->m_prev == nullptr && node->m_next == nullptr)
                || !((node->m_prev == nullptr) && (node->m_next == nullptr)) );

    if (node == m_first) {
        BOOST_ASSERT(node->m_prev == nullptr);
        m_first = node->m_next;
        if (m_first != nullptr) {
            m_first->m_prev = nullptr;
        }
    } else {
        node->m_prev->m_next = node->m_next;
    }

    if (node == m_last) {
        BOOST_ASSERT(node->m_next == nullptr);
        m_last = node->m_prev;
        if (m_last != nullptr) {
            m_last->m_next = nullptr;
        }
    } else {
        node->m_next->m_prev = node->m_prev;
    }

    node->m_parent = nullptr;
    node->m_prev = nullptr;
    node->m_next = nullptr;
}

bool Group::isEmpty() const
{
    return m_first == nullptr;
}

void Group::freeAll()
{
    Node* node = m_first;
    while (node != nullptr) {
        // Store pointer to next node because current node might be destroyed by done action after process.
        Node* nextNode = node->m_next;
        node->free();
        node = nextNode;
    }
}
<commit_msg>Add more node tree assertions<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/Engine.hpp"
#include "Methcla/Audio/Group.hpp"

using namespace Methcla::Audio;

#define METHCLA_ASSERT_NODE_IS_BLANK(node) \
    BOOST_ASSERT(node != nullptr); \
    BOOST_ASSERT(node->m_parent == nullptr); \
    BOOST_ASSERT(node->m_prev == nullptr); \
    BOOST_ASSERT(node->m_next == nullptr); \

#define METHCLA_ASSERT_NODE_IS_LINKED(node) \
    BOOST_ASSERT(m_first != nullptr); \
    BOOST_ASSERT(m_last != nullptr); \
    BOOST_ASSERT(node != nullptr); \
    BOOST_ASSERT(node->m_parent == this); \
    BOOST_ASSERT(node->m_prev != nullptr || node == m_first); \
    BOOST_ASSERT(node->m_next != nullptr || node == m_last); \
    BOOST_ASSERT(m_first != m_last || (m_first == node && node == m_last));

Group::Group(Environment& env, NodeId nodeId)
    : Node(env, nodeId)
    , m_first(nullptr)
    , m_last(nullptr)
{
}

Group::~Group()
{
    freeAll();
}

Group* Group::construct(Environment& env, NodeId nodeId)
{
    return new (env.rtMem().alloc(sizeof(Group))) Group(env, nodeId);
}

void Group::doProcess(size_t numFrames)
{
    Node* node = m_first;
    while (node != nullptr) {
        // Store pointer to next node because current node might be destroyed by done action after process.
        Node* nextNode = node->m_next;
        node->process(numFrames);
        node = nextNode;
    }
}

void Group::addToHead(Node* node)
{
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_next = m_first;

    if (m_first != nullptr) {
        m_first->m_prev = node;
    }

    m_first = node;

    if (m_last == nullptr) {
        m_last = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addToTail(Node* node)
{
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_prev = m_last;

    if (m_last != nullptr) {
        m_last->m_next = node;
    }

    m_last = node;

    if (m_first == nullptr) {
        m_first = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addBefore(Node* target, Node* node)
{
    BOOST_ASSERT(target != nullptr);
    BOOST_ASSERT(target->parent() == this);
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_prev = target->m_prev;
    target->m_prev = node;
    node->m_next = target;

    if (target == m_first) {
        BOOST_ASSERT(node->m_prev == nullptr);
        m_first = node;
    } else {
        BOOST_ASSERT(node->m_prev != nullptr);
        node->m_prev->m_next = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::addAfter(Node* target, Node* node)
{
    BOOST_ASSERT(target != nullptr);
    BOOST_ASSERT(target->parent() == this);
    METHCLA_ASSERT_NODE_IS_BLANK(node);

    node->m_parent = this;
    node->m_next = target->m_next;
    target->m_next = node;
    node->m_prev = target;

    if (target == m_last) {
        BOOST_ASSERT(node->m_next == nullptr);
        m_last = node;
    } else {
        BOOST_ASSERT(node->m_next != nullptr);
        node->m_next->m_prev = node;
    }

    METHCLA_ASSERT_NODE_IS_LINKED(node);
}

void Group::remove(Node* node)
{
    METHCLA_ASSERT_NODE_IS_LINKED(node);

    if (node == m_first) {
        m_first = node->m_next;
        if (m_first != nullptr) {
            m_first->m_prev = nullptr;
        }
    } else {
        node->m_prev->m_next = node->m_next;
    }

    if (node == m_last) {
        m_last = node->m_prev;
        if (m_last != nullptr) {
            m_last->m_next = nullptr;
        }
    } else {
        node->m_next->m_prev = node->m_prev;
    }

    node->m_parent = nullptr;
    node->m_prev = nullptr;
    node->m_next = nullptr;
}

bool Group::isEmpty() const
{
    BOOST_ASSERT(m_first != nullptr || m_last == nullptr);
    return m_first == nullptr;
}

void Group::freeAll()
{
    Node* node = m_first;
    while (node != nullptr) {
        // Store pointer to next node because current node might be destroyed by done action after process.
        Node* nextNode = node->m_next;
        node->free();
        node = nextNode;
    }
    BOOST_ASSERT(isEmpty());
}
<|endoftext|>


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

#include "webkit/support/platform_support.h"

#include "base/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/resource_util.h"
#include "base/string16.h"
#include "base/string_piece.h"
#include "grit/webkit_chromium_resources.h"
#include "grit/webkit_resources.h"

#define MAX_LOADSTRING 100

namespace {

FilePath GetResourceFilePath(const char* ascii_name) {
  FilePath path;
  PathService::Get(base::DIR_EXE, &path);
  path = path.AppendASCII("DumpRenderTree_resources");
  return path.AppendASCII(ascii_name);
}

base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
  void* data_ptr;
  size_t data_size;
  return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
                                         &data_size)
      ? base::StringPiece(static_cast<char*>(data_ptr), data_size)
      : base::StringPiece();
}

base::StringPiece NetResourceProvider(int key) {
  return GetRawDataResource(::GetModuleHandle(NULL), key);
}

}  // namespace

namespace webkit_support {

// TODO(tkent): Implement some of the followings for platform-dependent tasks
// such as loading resource.

void BeforeInitialize() {
}

void AfterInitialize() {
}

void BeforeShutdown() {
}

void AfterShutdown() {
}

}  // namespace webkit_support

namespace webkit_glue {

string16 GetLocalizedString(int message_id) {
  wchar_t localized[MAX_LOADSTRING];
  int length = ::LoadString(::GetModuleHandle(NULL), message_id,
                            localized, MAX_LOADSTRING);
  if (!length && ::GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND) {
    NOTREACHED();
    return L"No string for this identifier!";
  }
  return string16(localized, length);
}

base::StringPiece GetDataResource(int resource_id) {
  switch (resource_id) {
  case IDR_BROKENIMAGE: {
    // Use webkit's broken image icon (16x16)
    static std::string broken_image_data;
    if (broken_image_data.empty()) {
      FilePath path = GetResourceFilePath("missingImage.gif");
      bool success = file_util::ReadFileToString(path, &broken_image_data);
      if (!success) {
        LOG(FATAL) << "Failed reading: " << path.value();
      }
    }
    return broken_image_data;
  }
  case IDR_TEXTAREA_RESIZER: {
    // Use webkit's text area resizer image.
    static std::string resize_corner_data;
    if (resize_corner_data.empty()) {
      FilePath path = GetResourceFilePath("textAreaResizeCorner.png");
      bool success = file_util::ReadFileToString(path, &resize_corner_data);
      if (!success) {
        LOG(FATAL) << "Failed reading: " << path.value();
      }
    }
    return resize_corner_data;
  }

  case IDR_SEARCH_CANCEL:
  case IDR_SEARCH_CANCEL_PRESSED:
  case IDR_SEARCH_MAGNIFIER:
  case IDR_SEARCH_MAGNIFIER_RESULTS:
  case IDR_MEDIA_PAUSE_BUTTON:
  case IDR_MEDIA_PLAY_BUTTON:
  case IDR_MEDIA_PLAY_BUTTON_DISABLED:
  case IDR_MEDIA_SOUND_FULL_BUTTON:
  case IDR_MEDIA_SOUND_NONE_BUTTON:
  case IDR_MEDIA_SOUND_DISABLED:
  case IDR_MEDIA_SLIDER_THUMB:
  case IDR_MEDIA_VOLUME_SLIDER_THUMB:
  case IDR_DEVTOOLS_INJECT_WEBKIT_JS:
  case IDR_DEVTOOLS_INJECT_DISPATCH_JS:
  case IDR_DEVTOOLS_DEBUGGER_SCRIPT_JS:
    return NetResourceProvider(resource_id);

  default:
    break;
  }

  return base::StringPiece();
}

}  // namespace webkit_glue
<commit_msg>DevTools: remove one more reference to InjectDispatch.js<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/support/platform_support.h"

#include "base/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/resource_util.h"
#include "base/string16.h"
#include "base/string_piece.h"
#include "grit/webkit_chromium_resources.h"
#include "grit/webkit_resources.h"

#define MAX_LOADSTRING 100

namespace {

FilePath GetResourceFilePath(const char* ascii_name) {
  FilePath path;
  PathService::Get(base::DIR_EXE, &path);
  path = path.AppendASCII("DumpRenderTree_resources");
  return path.AppendASCII(ascii_name);
}

base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
  void* data_ptr;
  size_t data_size;
  return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
                                         &data_size)
      ? base::StringPiece(static_cast<char*>(data_ptr), data_size)
      : base::StringPiece();
}

base::StringPiece NetResourceProvider(int key) {
  return GetRawDataResource(::GetModuleHandle(NULL), key);
}

}  // namespace

namespace webkit_support {

// TODO(tkent): Implement some of the followings for platform-dependent tasks
// such as loading resource.

void BeforeInitialize() {
}

void AfterInitialize() {
}

void BeforeShutdown() {
}

void AfterShutdown() {
}

}  // namespace webkit_support

namespace webkit_glue {

string16 GetLocalizedString(int message_id) {
  wchar_t localized[MAX_LOADSTRING];
  int length = ::LoadString(::GetModuleHandle(NULL), message_id,
                            localized, MAX_LOADSTRING);
  if (!length && ::GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND) {
    NOTREACHED();
    return L"No string for this identifier!";
  }
  return string16(localized, length);
}

base::StringPiece GetDataResource(int resource_id) {
  switch (resource_id) {
  case IDR_BROKENIMAGE: {
    // Use webkit's broken image icon (16x16)
    static std::string broken_image_data;
    if (broken_image_data.empty()) {
      FilePath path = GetResourceFilePath("missingImage.gif");
      bool success = file_util::ReadFileToString(path, &broken_image_data);
      if (!success) {
        LOG(FATAL) << "Failed reading: " << path.value();
      }
    }
    return broken_image_data;
  }
  case IDR_TEXTAREA_RESIZER: {
    // Use webkit's text area resizer image.
    static std::string resize_corner_data;
    if (resize_corner_data.empty()) {
      FilePath path = GetResourceFilePath("textAreaResizeCorner.png");
      bool success = file_util::ReadFileToString(path, &resize_corner_data);
      if (!success) {
        LOG(FATAL) << "Failed reading: " << path.value();
      }
    }
    return resize_corner_data;
  }

  case IDR_SEARCH_CANCEL:
  case IDR_SEARCH_CANCEL_PRESSED:
  case IDR_SEARCH_MAGNIFIER:
  case IDR_SEARCH_MAGNIFIER_RESULTS:
  case IDR_MEDIA_PAUSE_BUTTON:
  case IDR_MEDIA_PLAY_BUTTON:
  case IDR_MEDIA_PLAY_BUTTON_DISABLED:
  case IDR_MEDIA_SOUND_FULL_BUTTON:
  case IDR_MEDIA_SOUND_NONE_BUTTON:
  case IDR_MEDIA_SOUND_DISABLED:
  case IDR_MEDIA_SLIDER_THUMB:
  case IDR_MEDIA_VOLUME_SLIDER_THUMB:
  case IDR_DEVTOOLS_INJECT_WEBKIT_JS:
  case IDR_DEVTOOLS_DEBUGGER_SCRIPT_JS:
    return NetResourceProvider(resource_id);

  default:
    break;
  }

  return base::StringPiece();
}

}  // namespace webkit_glue
<|endoftext|>


<commit_before>#include "third_robot_driver.hpp"

// inclusive dependency
#include "ThirdRobotInterface/ThirdRobotInterface.h"

// dependency to ROS
#include <nav_msgs/Odometry.h> // odom

// dependency to Boost
#include <boost/thread.hpp>

// dependency to std
#include <iostream>

using namespace std; // FIXME: this software is library to third_robot_driver_node, don't erosion grobal area.

cirkit::ThirdRobotDriver::ThirdRobotDriver(ros::NodeHandle nh)
  : nh_(nh), rate_(100)
{
  ros::NodeHandle n("~");
  n.param<std::string>("imcs01_port", imcs01_port_, "/dev/urbtc0");
  double pulse_rate = 0;
  double geer_rate = 0;
  double wheel_diameter_right = 0;
  double wheel_diameter_left = 0;
  double tred_width = 0;
  n.param("pulse_rate", pulse_rate, 40.0);
  n.param("geer_rate", geer_rate, 33.0);
  n.param("wheel_diameter_right", wheel_diameter_right, 0.275);
  n.param("wheel_diameter_left", wheel_diameter_left, 0.275);
  n.param("tred_width", tred_width, 0.595);

  thirdrobot_ = new cirkit::ThirdRobotInterface(imcs01_port_, 0);
  thirdrobot_->setParams(pulse_rate, geer_rate, wheel_diameter_right, wheel_diameter_left, tred_width);

  odom_pub_ = nh_.advertise<nav_msgs::Odometry>("/odom", 1);
  steer_pub_ = nh_.advertise<geometry_msgs::Twist>("/steer_ctrl", 1);
  cmd_vel_sub_ = nh_.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, boost::bind(&cirkit::ThirdRobotDriver::cmdVelReceived, this, _1));
}

void cirkit::ThirdRobotDriver::init()
{
  if(thirdrobot_->openSerialPort() == 0)
	{
	  ROS_INFO("Connected to Third Robot.");
	  thirdrobot_->driveDirect(0, 0);
	}
  else
	{
	  ROS_FATAL("Could not connect to Third Robot.");
	  ROS_BREAK();
	}

  thirdrobot_->resetOdometry();
  thirdrobot_->setOdometry(0, 0, 0);
}

void cirkit::ThirdRobotDriver::run()
{
  double last_x, last_y, last_yaw;
  double vel_x, vel_y, vel_yaw;
  double dt;

  init();

  while(nh_.ok())
	{
	  current_time_ = ros::Time::now();
	  last_x = thirdrobot_->odometry_x_;
	  last_y = thirdrobot_->odometry_y_;
	  last_yaw = thirdrobot_->odometry_yaw_;
	  {
		boost::mutex::scoped_lock(access_mutex_);
        if( thirdrobot_->getEncoderPacket() == -1){
		  ROS_ERROR("Could not retrieve encoder packet.");
        }else{
		  thirdrobot_->calculateOdometry();
        }
	  }
	  dt = (current_time_ - last_time_).toSec();
	  vel_x = (thirdrobot_->odometry_x_ - last_x)/dt;
	  vel_y = (thirdrobot_->odometry_y_ - last_y)/dt;
	  vel_yaw = (thirdrobot_->odometry_yaw_ - last_yaw)/dt;

	  geometry_msgs::Quaternion odom_quat
		= tf::createQuaternionMsgFromYaw(thirdrobot_->odometry_yaw_);
	  geometry_msgs::TransformStamped odom_trans;
	  odom_trans.header.stamp = current_time_;
	  odom_trans.header.frame_id = "odom";
	  odom_trans.child_frame_id = "base_link";

	  odom_trans.transform.translation.x = thirdrobot_->odometry_x_;
	  odom_trans.transform.translation.y = thirdrobot_->odometry_y_;
	  odom_trans.transform.translation.z = 0.0;
	  odom_trans.transform.rotation = odom_quat;

	  odom_broadcaster_.sendTransform(odom_trans);

	  nav_msgs::Odometry odom;
	  odom.header.stamp = current_time_;
	  odom.header.frame_id = "odom";

	  //set the position
	  odom.pose.pose.position.x = thirdrobot_->odometry_x_;
	  odom.pose.pose.position.y = thirdrobot_->odometry_y_;
	  odom.pose.pose.position.z = 0.0;
	  odom.pose.pose.orientation = odom_quat;

	  //set the velocity
	  odom.child_frame_id = "base_link";
	  odom.twist.twist.linear.x = vel_x;
	  odom.twist.twist.linear.y = vel_y;
	  odom.twist.twist.angular.z = vel_yaw;

	  //publish the message
	  odom_pub_.publish(odom);

	  ros::spinOnce();
	  rate_.sleep();
	}
}

cirkit::ThirdRobotDriver::~ThirdRobotDriver()
{
  thirdrobot_->closeSerialPort();
}

void cirkit::ThirdRobotDriver::cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
{
  static int steer = 0;
  {
	boost::mutex::scoped_lock(access_mutex_);
	// cout << "cmdreived.x :" << cmd_vel->linear.x << endl;
	// cout << "cmdreived.z :" << cmd_vel->angular.z << endl;
	steer_dir_ = thirdrobot_->drive(cmd_vel->linear.x, cmd_vel->angular.z);
  }
  steer_pub_.publish(steer_dir_);

}
<commit_msg>Update init variable for rosparams<commit_after>#include "third_robot_driver.hpp"

// inclusive dependency
#include "ThirdRobotInterface/ThirdRobotInterface.h"

// dependency to ROS
#include <nav_msgs/Odometry.h> // odom

// dependency to Boost
#include <boost/thread.hpp>

// dependency to std
#include <iostream>

using namespace std; // FIXME: this software is library to third_robot_driver_node, don't erosion grobal area.

cirkit::ThirdRobotDriver::ThirdRobotDriver(ros::NodeHandle nh)
  : nh_(nh), rate_(100)
{
  ros::NodeHandle n("~");
  n.param<std::string>("imcs01_port", imcs01_port_, "/dev/urbtc0");
  double pulse_rate = 40.0;
  double geer_rate = 33.0;
  double wheel_diameter_right = 0.275;
  double wheel_diameter_left = 0.275;
  double tred_width = 0.595;
  n.param("pulse_rate", pulse_rate, pulse_rate);
  n.param("geer_rate", geer_rate, geer_rate);
  n.param("wheel_diameter_right", whel_diameter_right, whel_diameter_right);
  n.param("wheel_diameter_left", wheel_diameter_left, wheel_diameter_left);
  n.param("tred_width", tred_width, tred_width);

  thirdrobot_ = new cirkit::ThirdRobotInterface(imcs01_port_, 0); // FIXME: path received by argument for constructor
  thirdrobot_->setParams(pulse_rate, geer_rate, wheel_diameter_right, wheel_diameter_left, tred_width);

  odom_pub_ = nh_.advertise<nav_msgs::Odometry>("/odom", 1);
  steer_pub_ = nh_.advertise<geometry_msgs::Twist>("/steer_ctrl", 1);
  cmd_vel_sub_ = nh_.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, boost::bind(&cirkit::ThirdRobotDriver::cmdVelReceived, this, _1));
}

void cirkit::ThirdRobotDriver::init()
{
  if(thirdrobot_->openSerialPort() == 0)
	{
	  ROS_INFO("Connected to Third Robot.");
	  thirdrobot_->driveDirect(0, 0);
	}
  else
	{
	  ROS_FATAL("Could not connect to Third Robot.");
	  ROS_BREAK();
	}

  thirdrobot_->resetOdometry();
  thirdrobot_->setOdometry(0, 0, 0);
}

void cirkit::ThirdRobotDriver::run()
{
  double last_x, last_y, last_yaw;
  double vel_x, vel_y, vel_yaw;
  double dt;

  init();

  while(nh_.ok())
	{
	  current_time_ = ros::Time::now();
	  last_x = thirdrobot_->odometry_x_;
	  last_y = thirdrobot_->odometry_y_;
	  last_yaw = thirdrobot_->odometry_yaw_;
	  {
		boost::mutex::scoped_lock(access_mutex_);
        if( thirdrobot_->getEncoderPacket() == -1){
		  ROS_ERROR("Could not retrieve encoder packet.");
        }else{
		  thirdrobot_->calculateOdometry();
        }
	  }
	  dt = (current_time_ - last_time_).toSec();
	  vel_x = (thirdrobot_->odometry_x_ - last_x)/dt;
	  vel_y = (thirdrobot_->odometry_y_ - last_y)/dt;
	  vel_yaw = (thirdrobot_->odometry_yaw_ - last_yaw)/dt;

	  geometry_msgs::Quaternion odom_quat
		= tf::createQuaternionMsgFromYaw(thirdrobot_->odometry_yaw_);
	  geometry_msgs::TransformStamped odom_trans;
	  odom_trans.header.stamp = current_time_;
	  odom_trans.header.frame_id = "odom";
	  odom_trans.child_frame_id = "base_link";

	  odom_trans.transform.translation.x = thirdrobot_->odometry_x_;
	  odom_trans.transform.translation.y = thirdrobot_->odometry_y_;
	  odom_trans.transform.translation.z = 0.0;
	  odom_trans.transform.rotation = odom_quat;

	  odom_broadcaster_.sendTransform(odom_trans);

	  nav_msgs::Odometry odom;
	  odom.header.stamp = current_time_;
	  odom.header.frame_id = "odom";

	  //set the position
	  odom.pose.pose.position.x = thirdrobot_->odometry_x_;
	  odom.pose.pose.position.y = thirdrobot_->odometry_y_;
	  odom.pose.pose.position.z = 0.0;
	  odom.pose.pose.orientation = odom_quat;

	  //set the velocity
	  odom.child_frame_id = "base_link";
	  odom.twist.twist.linear.x = vel_x;
	  odom.twist.twist.linear.y = vel_y;
	  odom.twist.twist.angular.z = vel_yaw;

	  //publish the message
	  odom_pub_.publish(odom);

	  ros::spinOnce();
	  rate_.sleep();
	}
}

cirkit::ThirdRobotDriver::~ThirdRobotDriver()
{
  thirdrobot_->closeSerialPort();
}

void cirkit::ThirdRobotDriver::cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
{
  static int steer = 0;
  {
	boost::mutex::scoped_lock(access_mutex_);
	// cout << "cmdreived.x :" << cmd_vel->linear.x << endl;
	// cout << "cmdreived.z :" << cmd_vel->angular.z << endl;
	steer_dir_ = thirdrobot_->drive(cmd_vel->linear.x, cmd_vel->angular.z);
  }
  steer_pub_.publish(steer_dir_);

}
<|endoftext|>


<commit_before><commit_msg>FEM: cpp commands post, do not use create, same like constraints, data at point<commit_after><|endoftext|>


<commit_before>/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int closestValue(TreeNode* root, double target) {

        TreeNode* left = root->left;
        TreeNode* right = root->right;

        int closest = root->val;
        if (target < root->val && root->left) {
            int leftClosest = closestValue(root->left, target);
            if (fabs(target - leftClosest) < fabs(target - closest)) {
                closest = leftClosest;
            }
        }

        if (target > root->val && root->right) {
            int rightClosest = closestValue(root->right, target);
            if (fabs(target - rightClosest) < fabs(target - closest)) {
                closest = rightClosest;
            }
        }

        return closest;
    }
};<commit_msg>added solutions<commit_after>/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int closestValue(TreeNode* root, double target) {
        double diff = target - root->val;

        if (diff < 0 && root->left != NULL) {
            int leftVal = closestValue(root->left, target);
            return fabs(diff) < fabs(leftVal - target) ? root->val : leftVal;
        } else if (diff > 0 && root->right != NULL) {
            int rightVal = closestValue(root->right, target);
            return fabs(diff) < fabs(rightVal - target) ? root->val : rightVal;
        }
        return root->val;
    }
};<|endoftext|>