<commit_before>// Copyright (c) 2018 The OTS 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 "stat.h"
#include "name.h"

namespace ots {

// -----------------------------------------------------------------------------
// OpenTypeSTAT
// -----------------------------------------------------------------------------

bool OpenTypeSTAT::ValidateNameId(uint16_t nameid, bool allowPredefined) {
  OpenTypeNAME* name = static_cast<OpenTypeNAME*>(
      GetFont()->GetTypedTable(OTS_TAG_NAME));

  if (!name->IsValidNameId(nameid)) {
    Drop("Invalid nameID: %d", nameid);
    return false;
  }

  if (!allowPredefined && nameid < 26) {
    Warning("nameID out of range: %d", nameid);
    return true;
  }

  if ((nameid >= 26 && nameid <= 255) || nameid >= 32768) {
    Warning("nameID out of range: %d", nameid);
    return true;
  }

  return  true;
}

bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
  Buffer table(data, length);
  if (!table.ReadU16(&this->majorVersion) ||
      !table.ReadU16(&this->minorVersion) ||
      !table.ReadU16(&this->designAxisSize) ||
      !table.ReadU16(&this->designAxisCount) ||
      !table.ReadU32(&this->designAxesOffset) ||
      !table.ReadU16(&this->axisValueCount) ||
      !table.ReadU32(&this->offsetToAxisValueOffsets) ||
      !(this->minorVersion < 1 || table.ReadU16(&this->elidedFallbackNameID))) {
    return Drop("Failed to read table header");
  }
  if (this->majorVersion != 1) {
    return Drop("Unknown table version");
  }
  if (this->minorVersion > 2) {
    Warning("Unknown minor version, downgrading to 2");
    this->minorVersion = 2;
  }

  if (this->designAxisSize < sizeof(AxisRecord)) {
    return Drop("Invalid designAxisSize");
  }

  size_t headerEnd = table.offset();

  if (this->designAxisCount == 0) {
    if (this->designAxesOffset != 0) {
      Warning("Unexpected non-zero designAxesOffset");
      this->designAxesOffset = 0;
    }
  } else {
    if (this->designAxesOffset < headerEnd ||
        size_t(this->designAxesOffset) +
          size_t(this->designAxisCount) * size_t(this->designAxisSize) > length) {
      return Drop("Invalid designAxesOffset");
    }
  }

  for (size_t i = 0; i < this->designAxisCount; i++) {
    table.set_offset(this->designAxesOffset + i * this->designAxisSize);
    this->designAxes.emplace_back();
    auto& axis = this->designAxes[i];
    if (!table.ReadU32(&axis.axisTag) ||
        !table.ReadU16(&axis.axisNameID) ||
        !table.ReadU16(&axis.axisOrdering)) {
      return Drop("Failed to read design axis");
    }
    if (!CheckTag(axis.axisTag)) {
      return Drop("Bad design axis tag");
    }
    if (!ValidateNameId(axis.axisNameID, false)) {
      return true;
    }
  }

  // TODO
  // - check that all axes defined in fvar are covered by STAT
  // - check that axisOrdering values are not duplicated (warn only)

  if (this->axisValueCount == 0) {
    if (this->offsetToAxisValueOffsets != 0) {
      Warning("Unexpected non-zero offsetToAxisValueOffsets");
      this->offsetToAxisValueOffsets = 0;
    }
  } else {
    if (this->offsetToAxisValueOffsets < headerEnd ||
        size_t(this->offsetToAxisValueOffsets) +
          size_t(this->axisValueCount) * sizeof(uint16_t) > length) {
      return Drop("Invalid offsetToAxisValueOffsets");
    }
  }

  for (size_t i = 0; i < this->axisValueCount; i++) {
    table.set_offset(this->offsetToAxisValueOffsets + i * sizeof(uint16_t));
    uint16_t axisValueOffset;
    if (!table.ReadU16(&axisValueOffset)) {
      return Drop("Failed to read axis value offset");
    }
    if (this->offsetToAxisValueOffsets + axisValueOffset > length) {
      return Drop("Invalid axis value offset");
    }
    table.set_offset(this->offsetToAxisValueOffsets + axisValueOffset);
    uint16_t format;
    if (!table.ReadU16(&format)) {
      return Drop("Failed to read axis value format");
    }
    this->axisValues.emplace_back(format);
    auto& axisValue = axisValues[i];
    switch (format) {
    case 1:
      if (!table.ReadU16(&axisValue.format1.axisIndex) ||
          !table.ReadU16(&axisValue.format1.flags) ||
          !table.ReadU16(&axisValue.format1.valueNameID) ||
          !table.ReadS32(&axisValue.format1.value)) {
        return Drop("Failed to read axis value (format 1)");
      }
      if (axisValue.format1.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format1.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format1.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format1.valueNameID)) {
        return true;
      }
      break;
    case 2:
      if (!table.ReadU16(&axisValue.format2.axisIndex) ||
          !table.ReadU16(&axisValue.format2.flags) ||
          !table.ReadU16(&axisValue.format2.valueNameID) ||
          !table.ReadS32(&axisValue.format2.nominalValue) ||
          !table.ReadS32(&axisValue.format2.rangeMinValue) ||
          !table.ReadS32(&axisValue.format2.rangeMaxValue)) {
        return Drop("Failed to read axis value (format 2)");
      }
      if (axisValue.format2.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format2.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format1.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format2.valueNameID)) {
        return true;
      }
      if (!(axisValue.format2.rangeMinValue <= axisValue.format2.nominalValue &&
            axisValue.format2.nominalValue <= axisValue.format2.rangeMaxValue)) {
        Warning("Bad axis value range or nominal value");
      }
      break;
    case 3:
      if (!table.ReadU16(&axisValue.format3.axisIndex) ||
          !table.ReadU16(&axisValue.format3.flags) ||
          !table.ReadU16(&axisValue.format3.valueNameID) ||
          !table.ReadS32(&axisValue.format3.value) ||
          !table.ReadS32(&axisValue.format3.linkedValue)) {
        return Drop("Failed to read axis value (format 3)");
      }
      if (axisValue.format3.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format3.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format3.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format3.valueNameID)) {
        return true;
      }
      break;
    case 4:
      if (this->minorVersion < 2) {
        Warning("Invalid table version for format 4 axis values - updating");
        this->minorVersion = 2;
      }
      if (!table.ReadU16(&axisValue.format4.axisCount) ||
          !table.ReadU16(&axisValue.format4.flags) ||
          !table.ReadU16(&axisValue.format4.valueNameID)) {
        return Drop("Failed to read axis value (format 4)");
      }
      if (axisValue.format4.axisCount > this->designAxisCount) {
        return Drop("Axis count out of range");
      }
      if ((axisValue.format4.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format4.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format4.valueNameID)) {
        return true;
      }
      for (unsigned j = 0; j < axisValue.format4.axisCount; j++) {
        axisValue.format4.axisValues.emplace_back();
        auto& v = axisValue.format4.axisValues[j];
        if (!table.ReadU16(&v.axisIndex) ||
            !table.ReadS32(&v.value)) {
          return Drop("Failed to read axis value");
        }
        if (v.axisIndex >= this->designAxisCount) {
          return Drop("Axis index out of range");
        }
      }
      break;
    default:
      return Drop("Unknown axis value format");
    }
  }

  return true;
}

bool OpenTypeSTAT::Serialize(OTSStream* out) {
  off_t tableStart = out->Tell();

  size_t headerSize = 5 * sizeof(uint16_t) + 2 * sizeof(uint32_t);
  if (this->minorVersion >= 1) {
    headerSize += sizeof(uint16_t);
  }

  if (this->designAxisCount == 0) {
    this->designAxesOffset = 0;
  } else {
    this->designAxesOffset = headerSize;
  }

  this->designAxisSize = sizeof(AxisRecord);

  if (this->axisValueCount == 0) {
    this->offsetToAxisValueOffsets = 0;
  } else {
    if (this->designAxesOffset == 0) {
      this->offsetToAxisValueOffsets = headerSize;
    } else {
      this->offsetToAxisValueOffsets = this->designAxesOffset + this->designAxisCount * this->designAxisSize;
    }
  }

  if (!out->WriteU16(this->majorVersion) ||
      !out->WriteU16(this->minorVersion) ||
      !out->WriteU16(this->designAxisSize) ||
      !out->WriteU16(this->designAxisCount) ||
      !out->WriteU32(this->designAxesOffset) ||
      !out->WriteU16(this->axisValueCount) ||
      !out->WriteU32(this->offsetToAxisValueOffsets) ||
      !(this->minorVersion < 1 || out->WriteU16(this->elidedFallbackNameID))) {
    return Error("Failed to write table header");
  }

  if (this->designAxisCount > 0) {
    if (out->Tell() - tableStart != this->designAxesOffset) {
      return Error("Error computing designAxesOffset");
    }
  }

  for (unsigned i = 0; i < this->designAxisCount; i++) {
    const auto& axis = this->designAxes[i];
    if (!out->WriteU32(axis.axisTag) ||
        !out->WriteU16(axis.axisNameID) ||
        !out->WriteU16(axis.axisOrdering)) {
      return Error("Failed to write design axis");
    }
  }

  if (this->axisValueCount > 0) {
    if (out->Tell() - tableStart != this->offsetToAxisValueOffsets) {
      return Error("Error computing offsetToAxisValueOffsets");
    }
  }

  uint32_t axisValueOffset = this->axisValueCount * sizeof(uint16_t);
  for (unsigned i = 0; i < this->axisValueCount; i++) {
    const auto& value = this->axisValues[i];
    if (!out->WriteU16(axisValueOffset)) {
      return Error("Failed to write axis value offset");
    }
    axisValueOffset += value.Length();
  }
  for (unsigned i = 0; i < this->axisValueCount; i++) {
    const auto& value = this->axisValues[i];
    if (!out->WriteU16(value.format)) {
      return Error("Failed to write axis value");
    }
    switch (value.format) {
    case 1:
      if (!out->WriteU16(value.format1.axisIndex) ||
          !out->WriteU16(value.format1.flags) ||
          !out->WriteU16(value.format1.valueNameID) ||
          !out->WriteS32(value.format1.value)) {
        return Error("Failed to write axis value");
      }
      break;
    case 2:
      if (!out->WriteU16(value.format2.axisIndex) ||
          !out->WriteU16(value.format2.flags) ||
          !out->WriteU16(value.format2.valueNameID) ||
          !out->WriteS32(value.format2.nominalValue) ||
          !out->WriteS32(value.format2.rangeMinValue) ||
          !out->WriteS32(value.format2.rangeMaxValue)) {
        return Error("Failed to write axis value");
      }
      break;
    case 3:
      if (!out->WriteU16(value.format3.axisIndex) ||
          !out->WriteU16(value.format3.flags) ||
          !out->WriteU16(value.format3.valueNameID) ||
          !out->WriteS32(value.format3.value) ||
          !out->WriteS32(value.format3.linkedValue)) {
        return Error("Failed to write axis value");
      }
      break;
    case 4:
      if (!out->WriteU16(value.format4.axisCount) ||
          !out->WriteU16(value.format4.flags) ||
          !out->WriteU16(value.format4.valueNameID)) {
        return Error("Failed to write axis value");
      }
      for (unsigned j = 0; j < value.format4.axisValues.size(); j++) {
        if (!out->WriteU16(value.format4.axisValues[j].axisIndex) ||
            !out->WriteS32(value.format4.axisValues[j].value)) {
          return Error("Failed to write axis value");
        }
      }
      break;
    default:
      return Error("Bad value format");
    }
  }

  return true;
}

}  // namespace ots
<commit_msg>[STAT] Add null-check to silence coverity warning<commit_after>// Copyright (c) 2018 The OTS 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 "stat.h"
#include "name.h"

namespace ots {

// -----------------------------------------------------------------------------
// OpenTypeSTAT
// -----------------------------------------------------------------------------

bool OpenTypeSTAT::ValidateNameId(uint16_t nameid, bool allowPredefined) {
  OpenTypeNAME* name = static_cast<OpenTypeNAME*>(
      GetFont()->GetTypedTable(OTS_TAG_NAME));

  if (!name || !name->IsValidNameId(nameid)) {
    Drop("Invalid nameID: %d", nameid);
    return false;
  }

  if (!allowPredefined && nameid < 26) {
    Warning("nameID out of range: %d", nameid);
    return true;
  }

  if ((nameid >= 26 && nameid <= 255) || nameid >= 32768) {
    Warning("nameID out of range: %d", nameid);
    return true;
  }

  return  true;
}

bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
  Buffer table(data, length);
  if (!table.ReadU16(&this->majorVersion) ||
      !table.ReadU16(&this->minorVersion) ||
      !table.ReadU16(&this->designAxisSize) ||
      !table.ReadU16(&this->designAxisCount) ||
      !table.ReadU32(&this->designAxesOffset) ||
      !table.ReadU16(&this->axisValueCount) ||
      !table.ReadU32(&this->offsetToAxisValueOffsets) ||
      !(this->minorVersion < 1 || table.ReadU16(&this->elidedFallbackNameID))) {
    return Drop("Failed to read table header");
  }
  if (this->majorVersion != 1) {
    return Drop("Unknown table version");
  }
  if (this->minorVersion > 2) {
    Warning("Unknown minor version, downgrading to 2");
    this->minorVersion = 2;
  }

  if (this->designAxisSize < sizeof(AxisRecord)) {
    return Drop("Invalid designAxisSize");
  }

  size_t headerEnd = table.offset();

  if (this->designAxisCount == 0) {
    if (this->designAxesOffset != 0) {
      Warning("Unexpected non-zero designAxesOffset");
      this->designAxesOffset = 0;
    }
  } else {
    if (this->designAxesOffset < headerEnd ||
        size_t(this->designAxesOffset) +
          size_t(this->designAxisCount) * size_t(this->designAxisSize) > length) {
      return Drop("Invalid designAxesOffset");
    }
  }

  for (size_t i = 0; i < this->designAxisCount; i++) {
    table.set_offset(this->designAxesOffset + i * this->designAxisSize);
    this->designAxes.emplace_back();
    auto& axis = this->designAxes[i];
    if (!table.ReadU32(&axis.axisTag) ||
        !table.ReadU16(&axis.axisNameID) ||
        !table.ReadU16(&axis.axisOrdering)) {
      return Drop("Failed to read design axis");
    }
    if (!CheckTag(axis.axisTag)) {
      return Drop("Bad design axis tag");
    }
    if (!ValidateNameId(axis.axisNameID, false)) {
      return true;
    }
  }

  // TODO
  // - check that all axes defined in fvar are covered by STAT
  // - check that axisOrdering values are not duplicated (warn only)

  if (this->axisValueCount == 0) {
    if (this->offsetToAxisValueOffsets != 0) {
      Warning("Unexpected non-zero offsetToAxisValueOffsets");
      this->offsetToAxisValueOffsets = 0;
    }
  } else {
    if (this->offsetToAxisValueOffsets < headerEnd ||
        size_t(this->offsetToAxisValueOffsets) +
          size_t(this->axisValueCount) * sizeof(uint16_t) > length) {
      return Drop("Invalid offsetToAxisValueOffsets");
    }
  }

  for (size_t i = 0; i < this->axisValueCount; i++) {
    table.set_offset(this->offsetToAxisValueOffsets + i * sizeof(uint16_t));
    uint16_t axisValueOffset;
    if (!table.ReadU16(&axisValueOffset)) {
      return Drop("Failed to read axis value offset");
    }
    if (this->offsetToAxisValueOffsets + axisValueOffset > length) {
      return Drop("Invalid axis value offset");
    }
    table.set_offset(this->offsetToAxisValueOffsets + axisValueOffset);
    uint16_t format;
    if (!table.ReadU16(&format)) {
      return Drop("Failed to read axis value format");
    }
    this->axisValues.emplace_back(format);
    auto& axisValue = axisValues[i];
    switch (format) {
    case 1:
      if (!table.ReadU16(&axisValue.format1.axisIndex) ||
          !table.ReadU16(&axisValue.format1.flags) ||
          !table.ReadU16(&axisValue.format1.valueNameID) ||
          !table.ReadS32(&axisValue.format1.value)) {
        return Drop("Failed to read axis value (format 1)");
      }
      if (axisValue.format1.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format1.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format1.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format1.valueNameID)) {
        return true;
      }
      break;
    case 2:
      if (!table.ReadU16(&axisValue.format2.axisIndex) ||
          !table.ReadU16(&axisValue.format2.flags) ||
          !table.ReadU16(&axisValue.format2.valueNameID) ||
          !table.ReadS32(&axisValue.format2.nominalValue) ||
          !table.ReadS32(&axisValue.format2.rangeMinValue) ||
          !table.ReadS32(&axisValue.format2.rangeMaxValue)) {
        return Drop("Failed to read axis value (format 2)");
      }
      if (axisValue.format2.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format2.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format1.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format2.valueNameID)) {
        return true;
      }
      if (!(axisValue.format2.rangeMinValue <= axisValue.format2.nominalValue &&
            axisValue.format2.nominalValue <= axisValue.format2.rangeMaxValue)) {
        Warning("Bad axis value range or nominal value");
      }
      break;
    case 3:
      if (!table.ReadU16(&axisValue.format3.axisIndex) ||
          !table.ReadU16(&axisValue.format3.flags) ||
          !table.ReadU16(&axisValue.format3.valueNameID) ||
          !table.ReadS32(&axisValue.format3.value) ||
          !table.ReadS32(&axisValue.format3.linkedValue)) {
        return Drop("Failed to read axis value (format 3)");
      }
      if (axisValue.format3.axisIndex >= this->designAxisCount) {
        return Drop("Axis index out of range");
      }
      if ((axisValue.format3.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format3.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format3.valueNameID)) {
        return true;
      }
      break;
    case 4:
      if (this->minorVersion < 2) {
        Warning("Invalid table version for format 4 axis values - updating");
        this->minorVersion = 2;
      }
      if (!table.ReadU16(&axisValue.format4.axisCount) ||
          !table.ReadU16(&axisValue.format4.flags) ||
          !table.ReadU16(&axisValue.format4.valueNameID)) {
        return Drop("Failed to read axis value (format 4)");
      }
      if (axisValue.format4.axisCount > this->designAxisCount) {
        return Drop("Axis count out of range");
      }
      if ((axisValue.format4.flags & 0xFFFCu) != 0) {
        Warning("Unexpected axis value flags");
        axisValue.format4.flags &= ~0xFFFCu;
      }
      if (!ValidateNameId(axisValue.format4.valueNameID)) {
        return true;
      }
      for (unsigned j = 0; j < axisValue.format4.axisCount; j++) {
        axisValue.format4.axisValues.emplace_back();
        auto& v = axisValue.format4.axisValues[j];
        if (!table.ReadU16(&v.axisIndex) ||
            !table.ReadS32(&v.value)) {
          return Drop("Failed to read axis value");
        }
        if (v.axisIndex >= this->designAxisCount) {
          return Drop("Axis index out of range");
        }
      }
      break;
    default:
      return Drop("Unknown axis value format");
    }
  }

  return true;
}

bool OpenTypeSTAT::Serialize(OTSStream* out) {
  off_t tableStart = out->Tell();

  size_t headerSize = 5 * sizeof(uint16_t) + 2 * sizeof(uint32_t);
  if (this->minorVersion >= 1) {
    headerSize += sizeof(uint16_t);
  }

  if (this->designAxisCount == 0) {
    this->designAxesOffset = 0;
  } else {
    this->designAxesOffset = headerSize;
  }

  this->designAxisSize = sizeof(AxisRecord);

  if (this->axisValueCount == 0) {
    this->offsetToAxisValueOffsets = 0;
  } else {
    if (this->designAxesOffset == 0) {
      this->offsetToAxisValueOffsets = headerSize;
    } else {
      this->offsetToAxisValueOffsets = this->designAxesOffset + this->designAxisCount * this->designAxisSize;
    }
  }

  if (!out->WriteU16(this->majorVersion) ||
      !out->WriteU16(this->minorVersion) ||
      !out->WriteU16(this->designAxisSize) ||
      !out->WriteU16(this->designAxisCount) ||
      !out->WriteU32(this->designAxesOffset) ||
      !out->WriteU16(this->axisValueCount) ||
      !out->WriteU32(this->offsetToAxisValueOffsets) ||
      !(this->minorVersion < 1 || out->WriteU16(this->elidedFallbackNameID))) {
    return Error("Failed to write table header");
  }

  if (this->designAxisCount > 0) {
    if (out->Tell() - tableStart != this->designAxesOffset) {
      return Error("Error computing designAxesOffset");
    }
  }

  for (unsigned i = 0; i < this->designAxisCount; i++) {
    const auto& axis = this->designAxes[i];
    if (!out->WriteU32(axis.axisTag) ||
        !out->WriteU16(axis.axisNameID) ||
        !out->WriteU16(axis.axisOrdering)) {
      return Error("Failed to write design axis");
    }
  }

  if (this->axisValueCount > 0) {
    if (out->Tell() - tableStart != this->offsetToAxisValueOffsets) {
      return Error("Error computing offsetToAxisValueOffsets");
    }
  }

  uint32_t axisValueOffset = this->axisValueCount * sizeof(uint16_t);
  for (unsigned i = 0; i < this->axisValueCount; i++) {
    const auto& value = this->axisValues[i];
    if (!out->WriteU16(axisValueOffset)) {
      return Error("Failed to write axis value offset");
    }
    axisValueOffset += value.Length();
  }
  for (unsigned i = 0; i < this->axisValueCount; i++) {
    const auto& value = this->axisValues[i];
    if (!out->WriteU16(value.format)) {
      return Error("Failed to write axis value");
    }
    switch (value.format) {
    case 1:
      if (!out->WriteU16(value.format1.axisIndex) ||
          !out->WriteU16(value.format1.flags) ||
          !out->WriteU16(value.format1.valueNameID) ||
          !out->WriteS32(value.format1.value)) {
        return Error("Failed to write axis value");
      }
      break;
    case 2:
      if (!out->WriteU16(value.format2.axisIndex) ||
          !out->WriteU16(value.format2.flags) ||
          !out->WriteU16(value.format2.valueNameID) ||
          !out->WriteS32(value.format2.nominalValue) ||
          !out->WriteS32(value.format2.rangeMinValue) ||
          !out->WriteS32(value.format2.rangeMaxValue)) {
        return Error("Failed to write axis value");
      }
      break;
    case 3:
      if (!out->WriteU16(value.format3.axisIndex) ||
          !out->WriteU16(value.format3.flags) ||
          !out->WriteU16(value.format3.valueNameID) ||
          !out->WriteS32(value.format3.value) ||
          !out->WriteS32(value.format3.linkedValue)) {
        return Error("Failed to write axis value");
      }
      break;
    case 4:
      if (!out->WriteU16(value.format4.axisCount) ||
          !out->WriteU16(value.format4.flags) ||
          !out->WriteU16(value.format4.valueNameID)) {
        return Error("Failed to write axis value");
      }
      for (unsigned j = 0; j < value.format4.axisValues.size(); j++) {
        if (!out->WriteU16(value.format4.axisValues[j].axisIndex) ||
            !out->WriteS32(value.format4.axisValues[j].value)) {
          return Error("Failed to write axis value");
        }
      }
      break;
    default:
      return Error("Bad value format");
    }
  }

  return true;
}

}  // namespace ots
<|endoftext|>


<commit_before>/*
 * Copyright 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <boost/algorithm/cxx11/any_of.hpp>
#include <boost/range/irange.hpp>
#include <vector>
#include <random>

#include "utils/dynamic_bitset.hh"

BOOST_AUTO_TEST_CASE(test_set_clear_test) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    for (size_t i = 0; i < 178; i++) {
        if (i % 2) {
            BOOST_REQUIRE(!bits.test(i));
        } else {
            BOOST_REQUIRE(bits.test(i));
        }
    }

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    for (size_t i = 0; i < 178; i++) {
        if (i % 2 || i % 4 == 0) {
            BOOST_REQUIRE(!bits.test(i));
        } else {
            BOOST_REQUIRE(bits.test(i));
        }
    }
}

BOOST_AUTO_TEST_CASE(test_find_first_next) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }
    BOOST_REQUIRE_EQUAL(bits.find_first_set(), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    size_t i = bits.find_first_set();
    BOOST_REQUIRE_EQUAL(i, 0);
    do {
        auto j = bits.find_next_set(i);
        BOOST_REQUIRE_EQUAL(i + 2, j);
        i = j;
    } while (i < 176);
    BOOST_REQUIRE_EQUAL(bits.find_next_set(i), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    i = bits.find_first_set();
    BOOST_REQUIRE_EQUAL(i, 2);
    do {
        auto j = bits.find_next_set(i);
        BOOST_REQUIRE_EQUAL(i + 4, j);
        i = j;
    } while (i < 174);
    BOOST_REQUIRE_EQUAL(bits.find_next_set(i), utils::dynamic_bitset::npos);

}

BOOST_AUTO_TEST_CASE(test_find_last_prev) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }
    BOOST_REQUIRE_EQUAL(bits.find_last_set(), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    size_t i = bits.find_last_set();
    BOOST_REQUIRE_EQUAL(i, 176);

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    i = bits.find_last_set();
    BOOST_REQUIRE_EQUAL(i, 174);
}

static void test_random_ops(size_t size, std::random_device& rd ) {
    // BOOST_REQUIRE and friends are very slow, just use regular throws instead.
    auto require = [] (bool b) {
        if (!b) {
            throw 0;
        }
    };
    auto require_equal = [&] (const auto& a, const auto& b) {
        require(a == b);
    };

    utils::dynamic_bitset db{size};
    std::vector<bool> bv(size, false);
    std::uniform_int_distribution<size_t> global_op_dist(0, size-1);
    std::uniform_int_distribution<size_t> bit_dist(0, size-1);
    std::uniform_int_distribution<int> global_op_selection_dist(0, 1);
    std::uniform_int_distribution<int> single_op_selection_dist(0, 5);
    auto is_set = [&] (size_t i) -> bool {
        return bv[i];
    };
    size_t limit = size * 100;
#ifdef SEASTAR_DEBUG
    limit = std::min<size_t>(limit, 20000);
#endif
    for (size_t i = 0; i != limit; ++i) {
        if (global_op_dist(rd) == 0) {
            // perform a global operation
            switch (global_op_selection_dist(rd)) {
            case 0:
                for (size_t j = 0; j != size; ++j) {
                    db.clear(j);
                    bv[j] = false;
                }
                break;
            case 1:
                for (size_t j = 0; j != size; ++j) {
                    db.set(j);
                    bv[j] = true;
                }
                break;
            }
        } else {
            // perform a single-bit operation
            switch (single_op_selection_dist(rd)) {
            case 0: {
                auto bit = bit_dist(rd);
                db.set(bit);
                bv[bit] = true;
                break;
            }
            case 1: {
                auto bit = bit_dist(rd);
                db.clear(bit);
                bv[bit] = false;
                break;
            }
            case 2: {
                auto bit = bit_dist(rd);
                bool dbb = db.test(bit);
                bool bvb = bv[bit];
                require_equal(dbb, bvb);
                break;
            }
            case 3: {
                auto bit = bit_dist(rd);
                auto next = db.find_next_set(bit);
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(bit+1, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(bit+1, next), is_set));
                    require(is_set(next));
                }
                break;            }
            case 4: {
                auto next = db.find_first_set();
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, next), is_set));
                    require(is_set(next));
                }
                break;
            }
            case 5: {
                auto next = db.find_last_set();
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(next + 1, size), is_set));
                    require(is_set(next));
                }
                break;
            }
            }
        }
    }
}

BOOST_AUTO_TEST_CASE(test_random_operations) {
    std::random_device rd;
    for (auto size : { 1, 63, 64, 65, 2000, 4096-65, 4096-64, 4096-63, 4096-1, 4096, 4096+1, 262144-1, 262144, 262144+1}) {
        BOOST_CHECK_NO_THROW(test_random_ops(size, rd));
    }
}
<commit_msg>tests: reduce the number of iterations of dynamic_bitset_test<commit_after>/*
 * Copyright 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <boost/algorithm/cxx11/any_of.hpp>
#include <boost/range/irange.hpp>
#include <vector>
#include <random>

#include "utils/dynamic_bitset.hh"

BOOST_AUTO_TEST_CASE(test_set_clear_test) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    for (size_t i = 0; i < 178; i++) {
        if (i % 2) {
            BOOST_REQUIRE(!bits.test(i));
        } else {
            BOOST_REQUIRE(bits.test(i));
        }
    }

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    for (size_t i = 0; i < 178; i++) {
        if (i % 2 || i % 4 == 0) {
            BOOST_REQUIRE(!bits.test(i));
        } else {
            BOOST_REQUIRE(bits.test(i));
        }
    }
}

BOOST_AUTO_TEST_CASE(test_find_first_next) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }
    BOOST_REQUIRE_EQUAL(bits.find_first_set(), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    size_t i = bits.find_first_set();
    BOOST_REQUIRE_EQUAL(i, 0);
    do {
        auto j = bits.find_next_set(i);
        BOOST_REQUIRE_EQUAL(i + 2, j);
        i = j;
    } while (i < 176);
    BOOST_REQUIRE_EQUAL(bits.find_next_set(i), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    i = bits.find_first_set();
    BOOST_REQUIRE_EQUAL(i, 2);
    do {
        auto j = bits.find_next_set(i);
        BOOST_REQUIRE_EQUAL(i + 4, j);
        i = j;
    } while (i < 174);
    BOOST_REQUIRE_EQUAL(bits.find_next_set(i), utils::dynamic_bitset::npos);

}

BOOST_AUTO_TEST_CASE(test_find_last_prev) {
    utils::dynamic_bitset bits(178);
    for (size_t i = 0; i < 178; i++) {
        BOOST_REQUIRE(!bits.test(i));
    }
    BOOST_REQUIRE_EQUAL(bits.find_last_set(), utils::dynamic_bitset::npos);

    for (size_t i = 0; i < 178; i += 2) {
        bits.set(i);
    }

    size_t i = bits.find_last_set();
    BOOST_REQUIRE_EQUAL(i, 176);

    for (size_t i = 0; i < 178; i += 4) {
        bits.clear(i);
    }

    i = bits.find_last_set();
    BOOST_REQUIRE_EQUAL(i, 174);
}

static void test_random_ops(size_t size, std::random_device& rd ) {
    // BOOST_REQUIRE and friends are very slow, just use regular throws instead.
    auto require = [] (bool b) {
        if (!b) {
            throw 0;
        }
    };
    auto require_equal = [&] (const auto& a, const auto& b) {
        require(a == b);
    };

    utils::dynamic_bitset db{size};
    std::vector<bool> bv(size, false);
    std::uniform_int_distribution<size_t> global_op_dist(0, size-1);
    std::uniform_int_distribution<size_t> bit_dist(0, size-1);
    std::uniform_int_distribution<int> global_op_selection_dist(0, 1);
    std::uniform_int_distribution<int> single_op_selection_dist(0, 5);
    auto is_set = [&] (size_t i) -> bool {
        return bv[i];
    };
    size_t limit = std::log(size) * 1000;
    for (size_t i = 0; i != limit; ++i) {
        if (global_op_dist(rd) == 0) {
            // perform a global operation
            switch (global_op_selection_dist(rd)) {
            case 0:
                for (size_t j = 0; j != size; ++j) {
                    db.clear(j);
                    bv[j] = false;
                }
                break;
            case 1:
                for (size_t j = 0; j != size; ++j) {
                    db.set(j);
                    bv[j] = true;
                }
                break;
            }
        } else {
            // perform a single-bit operation
            switch (single_op_selection_dist(rd)) {
            case 0: {
                auto bit = bit_dist(rd);
                db.set(bit);
                bv[bit] = true;
                break;
            }
            case 1: {
                auto bit = bit_dist(rd);
                db.clear(bit);
                bv[bit] = false;
                break;
            }
            case 2: {
                auto bit = bit_dist(rd);
                bool dbb = db.test(bit);
                bool bvb = bv[bit];
                require_equal(dbb, bvb);
                break;
            }
            case 3: {
                auto bit = bit_dist(rd);
                auto next = db.find_next_set(bit);
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(bit+1, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(bit+1, next), is_set));
                    require(is_set(next));
                }
                break;            }
            case 4: {
                auto next = db.find_first_set();
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, next), is_set));
                    require(is_set(next));
                }
                break;
            }
            case 5: {
                auto next = db.find_last_set();
                if (next == db.npos) {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(0, size), is_set));
                } else {
                    require(!boost::algorithm::any_of(boost::irange<size_t>(next + 1, size), is_set));
                    require(is_set(next));
                }
                break;
            }
            }
        }
    }
}

BOOST_AUTO_TEST_CASE(test_random_operations) {
    std::random_device rd;
    for (auto size : { 1, 63, 64, 65, 2000, 4096-65, 4096-64, 4096-63, 4096-1, 4096, 4096+1, 262144-1, 262144, 262144+1}) {
        BOOST_CHECK_NO_THROW(test_random_ops(size, rd));
    }
}
<|endoftext|>


<commit_before>#include "openslideobject.h"

Nan::Persistent<v8::Function> OpenSlideObject::constructor;

OpenSlideObject::OpenSlideObject(string fileName) {
    _fileName = fileName;
}

OpenSlideObject::~OpenSlideObject() {
  if (_osr != NULL) {
    openslide_close(_osr);
  }
}

void OpenSlideObject::Init(v8::Local<v8::Object> exports) {
    Nan::HandleScope scope;

    // Prepare constructor template
    v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
    tpl->SetClassName(Nan::New("OpenSlideObject").ToLocalChecked());
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    Nan::SetPrototypeMethod(tpl,"open",Open);

    constructor.Reset(tpl->GetFunction());
    exports->Set(Nan::New("OpenSlideObject").ToLocalChecked(), tpl->GetFunction());
}

void OpenSlideObject::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  if (info.IsConstructCall()) {
    // Invoked as constructor: `new OpenSlideObject(...)`
    v8::String::Utf8Value val(info[0]->ToString());
    std::string filePath (*val);
    OpenSlideObject *obj = new OpenSlideObject(filePath);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // Invoked as plain function `OpenSlideObject(...)`, turn into construct call.
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = { info[0] };
    v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
    info.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void OpenSlideObject::Open(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    OpenSlideObject *obj = ObjectWrap::Unwrap<OpenSlideObject>(info.Holder());
    openslide_t *osr = openslide_open(obj->_fileName.c_str());
    bool success = osr != NULL;
    if (!success) {
      info.GetReturnValue().Set(Nan::New(success));
      return;
    }
    // Assign osr to member variable
    obj->_osr = osr;

    // Store level count
    int32_t levelCount = openslide_get_level_count(osr);
    obj->_levelCount = levelCount;

    // Store dimensions
    for (int i = 0; i < levelCount; i++) {
      int64_t w, h;
      double downsample;
      openslide_get_level_dimensions(osr,i,&w,&h);
      downsample = openslide_get_level_downsample(osr,i);
      obj->_levelWidths.push_back(w);
      obj->_levelHeights.push_back(h);
      obj->_levelDownsamples.push_back(downsample);
    }

    // Properties
    const char* const *pNames = openslide_get_property_names(osr);
    int i = 0;
    while (pNames[i] != 0) {
      const char *pValue = openslide_get_property_value(osr,pNames[i]);
      obj->_properties[pNames[i]] = pValue;
    }

    // Return success
    info.GetReturnValue().Set(Nan::New(success));
}<commit_msg>Fix get properties error<commit_after>#include "openslideobject.h"

Nan::Persistent<v8::Function> OpenSlideObject::constructor;

OpenSlideObject::OpenSlideObject(string fileName) {
    _fileName = fileName;
}

OpenSlideObject::~OpenSlideObject() {
  if (_osr != NULL) {
    openslide_close(_osr);
  }
}

void OpenSlideObject::Init(v8::Local<v8::Object> exports) {
    Nan::HandleScope scope;

    // Prepare constructor template
    v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
    tpl->SetClassName(Nan::New("OpenSlideObject").ToLocalChecked());
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    Nan::SetPrototypeMethod(tpl,"open",Open);

    constructor.Reset(tpl->GetFunction());
    exports->Set(Nan::New("OpenSlideObject").ToLocalChecked(), tpl->GetFunction());
}

void OpenSlideObject::New(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  if (info.IsConstructCall()) {
    // Invoked as constructor: `new OpenSlideObject(...)`
    v8::String::Utf8Value val(info[0]->ToString());
    std::string filePath (*val);
    OpenSlideObject *obj = new OpenSlideObject(filePath);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    // Invoked as plain function `OpenSlideObject(...)`, turn into construct call.
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = { info[0] };
    v8::Local<v8::Function> cons = Nan::New<v8::Function>(constructor);
    info.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void OpenSlideObject::Open(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    OpenSlideObject *obj = ObjectWrap::Unwrap<OpenSlideObject>(info.Holder());
    openslide_t *osr = openslide_open(obj->_fileName.c_str());
    bool success = osr != NULL;
    if (!success) {
      info.GetReturnValue().Set(Nan::New(success));
      return;
    }
    info.GetReturnValue().Set(Nan::New(success));
    return;

    // Assign osr to member variable
    obj->_osr = osr;

    // Store level count
    int32_t levelCount = openslide_get_level_count(osr);
    obj->_levelCount = levelCount;

    // Store dimensions
    for (int i = 0; i < levelCount; i++) {
      int64_t w, h;
      double downsample;
      openslide_get_level_dimensions(osr,i,&w,&h);
      downsample = openslide_get_level_downsample(osr,i);
      obj->_levelWidths.push_back(w);
      obj->_levelHeights.push_back(h);
      obj->_levelDownsamples.push_back(downsample);
    }

    // Properties
    const char* const *pNames = openslide_get_property_names(osr);
    int i = 0;
    while (pNames[i] != 0) {
      const char *pValue = openslide_get_property_value(osr,pNames[i]);
      obj->_properties[pNames[i]] = pValue;
      i++;
    }

    // Return success
    info.GetReturnValue().Set(Nan::New(success));
}<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03

// <utility>

// template <class T, class U> struct pair;

// pair(pair const&) = default;
// pair(pair &&) = default;
// pair& operator=(pair const&);
// pair& operator=(pair&&);

// Test that the copy/move constructors and assignment operators are
// correctly defined or deleted based on the properties of `T` and `U`.

#include <cassert>
#include <string>
#include <tuple>

#include "archetypes.hpp"

namespace ConstructorTest {

template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
  using P1 = std::pair<T1, int>;
  using P2 = std::pair<int, T1>;
  static_assert(std::is_copy_constructible<P1>::value == CanCopy);
  static_assert(std::is_move_constructible<P1>::value == CanMove);
  static_assert(std::is_copy_constructible<P2>::value == CanCopy);
  static_assert(std::is_move_constructible<P2>::value == CanMove);
};

} // namespace ConstructorTest

void test_constructors_exist() {
  using namespace ConstructorTest;
  {
    test<int>();
    test<int &>();
    test<int &&, false, true>();
    test<const int>();
    test<const int &>();
    test<const int &&, false, true>();
  }
  {
    test<Copyable>();
    test<Copyable &>();
    test<Copyable &&, false, true>();
  }
  {
    test<NonCopyable, false>();
    test<NonCopyable &, true>();
    test<NonCopyable &&, false, true>();
  }
  {
    // Even though CopyOnly has an explicitly deleted move constructor
    // pair's move constructor is only implicitly deleted and therefore
    // it doesn't participate in overload resolution.
    test<CopyOnly, true, true>();
    test<CopyOnly &, true>();
    test<CopyOnly &&, false, true>();
  }
  {
    test<MoveOnly, false, true>();
    test<MoveOnly &, true>();
    test<MoveOnly &&, false, true>();
  }
}

namespace AssignmentOperatorTest {

template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
  using P1 = std::pair<T1, int>;
  using P2 = std::pair<int, T1>;
  static_assert(std::is_copy_assignable<P1>::value == CanCopy);
  static_assert(std::is_move_assignable<P1>::value == CanMove);
  static_assert(std::is_copy_assignable<P2>::value == CanCopy);
  static_assert(std::is_move_assignable<P2>::value == CanMove);
};

} // namespace AssignmentOperatorTest

void test_assignment_operator_exists() {
  using namespace AssignmentOperatorTest;
  {
    test<int>();
    test<int &>();
    test<int &&>();
    test<const int, false>();
    test<const int &, false>();
    test<const int &&, false>();
  }
  {
    test<Copyable>();
    test<Copyable &>();
    test<Copyable &&>();
  }
  {
    test<NonCopyable, false>();
    test<NonCopyable &, false>();
    test<NonCopyable &&, false>();
  }
  {
    test<CopyOnly, true>();
    test<CopyOnly &, true>();
    test<CopyOnly &&, true>();
  }
  {
    test<MoveOnly, false, true>();
    test<MoveOnly &, false, false>();
    test<MoveOnly &&, false, true>();
  }
}

int main() {
  test_constructors_exist();
  test_assignment_operator_exists();
}
<commit_msg>Remove use of C++1z static assert in C++11 test<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03

// <utility>

// template <class T, class U> struct pair;

// pair(pair const&) = default;
// pair(pair &&) = default;
// pair& operator=(pair const&);
// pair& operator=(pair&&);

// Test that the copy/move constructors and assignment operators are
// correctly defined or deleted based on the properties of `T` and `U`.

#include <cassert>
#include <string>
#include <tuple>

#include "archetypes.hpp"

namespace ConstructorTest {

template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
  using P1 = std::pair<T1, int>;
  using P2 = std::pair<int, T1>;
  static_assert(std::is_copy_constructible<P1>::value == CanCopy, "");
  static_assert(std::is_move_constructible<P1>::value == CanMove, "");
  static_assert(std::is_copy_constructible<P2>::value == CanCopy, "");
  static_assert(std::is_move_constructible<P2>::value == CanMove, "");
};

} // namespace ConstructorTest

void test_constructors_exist() {
  using namespace ConstructorTest;
  {
    test<int>();
    test<int &>();
    test<int &&, false, true>();
    test<const int>();
    test<const int &>();
    test<const int &&, false, true>();
  }
  {
    test<Copyable>();
    test<Copyable &>();
    test<Copyable &&, false, true>();
  }
  {
    test<NonCopyable, false>();
    test<NonCopyable &, true>();
    test<NonCopyable &&, false, true>();
  }
  {
    // Even though CopyOnly has an explicitly deleted move constructor
    // pair's move constructor is only implicitly deleted and therefore
    // it doesn't participate in overload resolution.
    test<CopyOnly, true, true>();
    test<CopyOnly &, true>();
    test<CopyOnly &&, false, true>();
  }
  {
    test<MoveOnly, false, true>();
    test<MoveOnly &, true>();
    test<MoveOnly &&, false, true>();
  }
}

namespace AssignmentOperatorTest {

template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
  using P1 = std::pair<T1, int>;
  using P2 = std::pair<int, T1>;
  static_assert(std::is_copy_assignable<P1>::value == CanCopy, "");
  static_assert(std::is_move_assignable<P1>::value == CanMove, "");
  static_assert(std::is_copy_assignable<P2>::value == CanCopy, "");
  static_assert(std::is_move_assignable<P2>::value == CanMove, "");
};

} // namespace AssignmentOperatorTest

void test_assignment_operator_exists() {
  using namespace AssignmentOperatorTest;
  {
    test<int>();
    test<int &>();
    test<int &&>();
    test<const int, false>();
    test<const int &, false>();
    test<const int &&, false>();
  }
  {
    test<Copyable>();
    test<Copyable &>();
    test<Copyable &&>();
  }
  {
    test<NonCopyable, false>();
    test<NonCopyable &, false>();
    test<NonCopyable &&, false>();
  }
  {
    test<CopyOnly, true>();
    test<CopyOnly &, true>();
    test<CopyOnly &&, true>();
  }
  {
    test<MoveOnly, false, true>();
    test<MoveOnly &, false, false>();
    test<MoveOnly &&, false, true>();
  }
}

int main() {
  test_constructors_exist();
  test_assignment_operator_exists();
}
<|endoftext|>


<commit_before>namespace mimosa
{
  template <typename Value, StringRef (*GetKey)(Value value)>
  inline
  Trie<Value, GetKey>::Trie(uint32_t depth)
    : value_(),
      childs_(nullptr),
      depth_(depth),
      size_(0)
  {
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline
  Trie<Value, GetKey>::~Trie()
  {
    clear();
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::clear()
  {
    if (childs_) {
      for (int i = 0; i < 256; ++i)
        delete childs_[i];
      free(childs_);
      childs_ = nullptr;
    }
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::allocateChilds()
  {
    assert(!childs_);
    childs_ = (Trie<Value, GetKey>**)calloc(sizeof (*childs_), 256);

    // check if value_ should go to childs_
    if (!value_)
      return;

    StringRef key = GetKey(value_);
    if (key.size() == depth_)
      return;

    insert(key, value_);
    value_ = nullptr;
    --size_;
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline bool
  Trie<Value, GetKey>::insert(const StringRef & key, Value value)
  {
    assert(key.size() >= depth_);

    if (key.size() == depth_) {
      if (!value_) {
        value_ = value;
        ++size_;
        return true;
      }

      if (GetKey(value_).size() > depth_) {
        std::swap(value, value_);
        insert(value);
        return true;
      }

      return false;
    }

    if (!value_ && !childs_) {
      value_ = value;
      ++size_;
      return true;
    }

    if (!childs_)
      allocateChilds();

    if (!childs_[(uint8_t)key[depth_]])
      childs_[(uint8_t)key[depth_]] = new Trie<Value, GetKey>(depth_ + 1);
    if (!childs_[(uint8_t)key[depth_]]->insert(key, value))
      return false;
    ++size_;
    return true;
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline Value
  Trie<Value, GetKey>::find(const StringRef & key) const
  {
    assert(key.size() >= depth_);

    if (key.size() == depth_) {
      if (value_)
        return value_;
      return nullptr;
    }

    if (!childs_ || !childs_[(uint8_t)key[depth_]])
      return nullptr;

    return childs_[(uint8_t)key[depth_]]->find(key);
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::erase(const StringRef & key)
  {
    if (key.size() == depth_) {
      value_ = nullptr;
      --size_;
      return;
    }

    if (!childs_ || !childs_[(uint8_t)key[depth_]])
      return;

    childs_[(uint8_t)key[depth_]]->erase(key);
    --size_;

    if (childs_[(uint8_t)key[depth_]]->empty()) {
      delete childs_[(uint8_t)key[depth_]];
      childs_[(uint8_t)key[depth_]] = nullptr;
    }
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::foreach(const std::function<void (Value)> & callback) const
  {
    if (value_)
      callback(value_);

    if (childs_)
      for (int i = 0; i < 256; ++i)
        if (childs_[i])
          childs_[i]->foreach(callback);
  }
}
<commit_msg>Trie: fix a bug in insert() and remove()<commit_after>namespace mimosa
{
  template <typename Value, StringRef (*GetKey)(Value value)>
  inline
  Trie<Value, GetKey>::Trie(uint32_t depth)
    : value_(),
      childs_(nullptr),
      depth_(depth),
      size_(0)
  {
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline
  Trie<Value, GetKey>::~Trie()
  {
    clear();
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::clear()
  {
    if (childs_) {
      for (int i = 0; i < 256; ++i)
        delete childs_[i];
      free(childs_);
      childs_ = nullptr;
    }
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::allocateChilds()
  {
    assert(!childs_);
    childs_ = (Trie<Value, GetKey>**)calloc(sizeof (*childs_), 256);

    // check if value_ should go to childs_
    if (!value_)
      return;

    StringRef key = GetKey(value_);
    if (key.size() == depth_)
      return;

    insert(key, value_);
    value_ = nullptr;
    --size_;
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline bool
  Trie<Value, GetKey>::insert(const StringRef & key, Value value)
  {
    assert(key.size() >= depth_);

    if (key.size() == depth_) {
      if (!value_) {
        value_ = value;
        ++size_;
        return true;
      }

      if (GetKey(value_).size() > depth_) {
        std::swap(value, value_);
        insert(value);
        return true;
      }

      return false;
    }

    if (!value_ && !childs_) {
      value_ = value;
      ++size_;
      return true;
    }

    if (!childs_)
      allocateChilds();

    if (!childs_[(uint8_t)key[depth_]])
      childs_[(uint8_t)key[depth_]] = new Trie<Value, GetKey>(depth_ + 1);
    if (!childs_[(uint8_t)key[depth_]]->insert(key, value))
      return false;
    ++size_;
    return true;
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline Value
  Trie<Value, GetKey>::find(const StringRef & key) const
  {
    assert(key.size() >= depth_);

    if (key.size() == depth_ || size_ == 1) {
      if (value_ && GetKey(value_) == key)
        return value_;
      return nullptr;
    }

    if (!childs_ || !childs_[(uint8_t)key[depth_]])
      return nullptr;

    return childs_[(uint8_t)key[depth_]]->find(key);
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::erase(const StringRef & key)
  {
    if ((key.size() == depth_ || size_ == 1) &&
        (value_ && GetKey(value_) == key))
    {
      value_ = nullptr;
      --size_;
      return;
    }

    if (!childs_ || !childs_[(uint8_t)key[depth_]])
      return;

    childs_[(uint8_t)key[depth_]]->erase(key);
    --size_;

    if (childs_[(uint8_t)key[depth_]]->empty()) {
      delete childs_[(uint8_t)key[depth_]];
      childs_[(uint8_t)key[depth_]] = nullptr;
    }
  }

  template <typename Value, StringRef (*GetKey)(Value value)>
  inline void
  Trie<Value, GetKey>::foreach(const std::function<void (Value)> & callback) const
  {
    if (value_)
      callback(value_);

    if (childs_)
      for (int i = 0; i < 256; ++i)
        if (childs_[i])
          childs_[i]->foreach(callback);
  }
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/Referenced>
#include <osg/Notify>
#include <typeinfo>

namespace osg
{

static std::auto_ptr<DeleteHandler> s_deleteHandler(0);

void Referenced::setDeleteHandler(DeleteHandler* handler)
{
//    s_deleteHandler.reset(handler);
}

DeleteHandler* Referenced::getDeleteHandler()
{
    return s_deleteHandler.get();
}

Referenced::~Referenced()
{
    if (_refCount>0)
    {
        notify(WARN)<<"Warning: deleting still referenced object "<<this<<" of type '"<<typeid(this).name()<<"'"<<std::endl;
        notify(WARN)<<"         the final reference count was "<<_refCount<<", memory corruption possible."<<std::endl;
    }
}

}; // end of namespace osg
<commit_msg>Added #include <memory> for Win32 build<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/Referenced>
#include <osg/Notify>

#include <typeinfo>
#include <memory>

namespace osg
{

static std::auto_ptr<DeleteHandler> s_deleteHandler(0);

void Referenced::setDeleteHandler(DeleteHandler* handler)
{
//    s_deleteHandler.reset(handler);
}

DeleteHandler* Referenced::getDeleteHandler()
{
    return s_deleteHandler.get();
}

Referenced::~Referenced()
{
    if (_refCount>0)
    {
        notify(WARN)<<"Warning: deleting still referenced object "<<this<<" of type '"<<typeid(this).name()<<"'"<<std::endl;
        notify(WARN)<<"         the final reference count was "<<_refCount<<", memory corruption possible."<<std::endl;
    }
}

}; // end of namespace osg
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 */
/** @file TransientDirectory.cpp
 * @author Marek Kotewicz <marek@ethdev.com>
 * @date 2015
 */

#include <thread>
#include <boost/filesystem.hpp>
#include "Exceptions.h"
#include "TransientDirectory.h"
#include "CommonIO.h"
using namespace std;
using namespace dev;

TransientDirectory::TransientDirectory():
	TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string())
{}

TransientDirectory::TransientDirectory(std::string const& _path):
	m_path(_path)
{
	// we never ever want to delete a directory (including all its contents) that we did not create ourselves.
	if (boost::filesystem::exists(m_path))
		BOOST_THROW_EXCEPTION(FileError());

	boost::filesystem::create_directories(m_path);
}

TransientDirectory::~TransientDirectory()
{
	for (int i = 0; i < 3; ++i)
	{
		try
		{
			boost::filesystem::remove_all(m_path);
			break;
		}
		catch (...)
		{
			this_thread::sleep_for(chrono::milliseconds(10));
		}
	}
}
<commit_msg>Update TransientDirectory.cpp<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 */
/** @file TransientDirectory.cpp
 * @author Marek Kotewicz <marek@ethdev.com>
 * @date 2015
 */

#include <thread>
#include <boost/filesystem.hpp>
#include "Exceptions.h"
#include "TransientDirectory.h"
#include "CommonIO.h"
#include "Log.h"
using namespace std;
using namespace dev;

TransientDirectory::TransientDirectory():
	TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string())
{}

TransientDirectory::TransientDirectory(std::string const& _path):
	m_path(_path)
{
	// we never ever want to delete a directory (including all its contents) that we did not create ourselves.
	if (boost::filesystem::exists(m_path))
		BOOST_THROW_EXCEPTION(FileError());

	boost::filesystem::create_directories(m_path);
}

TransientDirectory::~TransientDirectory()
{
	boost::system::error_code ec;
	boost::filesystem::remove_all(m_path, ec);
	if (0 == ec)
		return;

	// In some cases, antivirus runnig on Windows will scan all the newly created directories.
	// As a consequence, directory is locked and can not be deleted immediately.
	// Retry after 10 milliseconds usually is successful.
	// This will help our tests run smoothly in such environment.
	this_thread::sleep_for(chrono::milliseconds(10));

	ec.clear();
	boost::filesystem::remove_all(m_path, ec);
	if (ec != 0)
		cwarn << "Failed to delete directory '" << m_path << "': " << ec.message();
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 NorthScale, Inc.
 *
 *   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 "buckets.h"
#include <assert.h>
#include <iostream>
#include <cassert>

using namespace std;

static void testSingleBucket() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "102");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 1);
    assert(buckets[0] == 102);
}

static void testMultipleBuckets() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "102,   \t\n\r 103; 104  ");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 3);
    assert(buckets[0] == 102);
    assert(buckets[1] == 103);
    assert(buckets[2] == 104);
}

static void testBucketRange() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "[102, \t\n\r 105]");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 4);
    assert(buckets[0] == 102);
    assert(buckets[1] == 103);
    assert(buckets[2] == 104);
    assert(buckets[3] == 105);
}

static void testIllegalSyntax() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "[102, 10 2]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[102,,]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[a,12]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[1,a]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,a,2,3");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,,");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1 2 3");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "");
        abort();
    } catch (string& e) {
        /* Success! */
    }
}

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    testSingleBucket();
    testMultipleBuckets();
    testBucketRange();
    testIllegalSyntax();

    return 0;
}
<commit_msg>need <cstdlib> for abort()<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 NorthScale, Inc.
 *
 *   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 "buckets.h"
#include <assert.h>
#include <iostream>
#include <cassert>
#include <cstdlib>

using namespace std;

static void testSingleBucket() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "102");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 1);
    assert(buckets[0] == 102);
}

static void testMultipleBuckets() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "102,   \t\n\r 103; 104  ");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 3);
    assert(buckets[0] == 102);
    assert(buckets[1] == 103);
    assert(buckets[2] == 104);
}

static void testBucketRange() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "[102, \t\n\r 105]");
    } catch (string& e) {
        cerr << e.c_str() << std::endl;
        abort();
    }
    assert(buckets.size() == 4);
    assert(buckets[0] == 102);
    assert(buckets[1] == 103);
    assert(buckets[2] == 104);
    assert(buckets[3] == 105);
}

static void testIllegalSyntax() {
    vector<uint16_t> buckets;

    try {
        parseBuckets(buckets, "[102, 10 2]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[102,,]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[a,12]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "[1,a]");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,a,2,3");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,,");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1,");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "1 2 3");
        abort();
    } catch (string& e) {
        /* Success! */
    }

    try {
        parseBuckets(buckets, "");
        abort();
    } catch (string& e) {
        /* Success! */
    }
}

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    testSingleBucket();
    testMultipleBuckets();
    testBucketRange();
    testIllegalSyntax();

    return 0;
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgUI/ComboBox>
#include <osgText/String>
#include <osgText/Font>
#include <osgText/Text>
#include <osg/Notify>
#include <osg/io_utils>

using namespace osgUI;

ComboBox::ComboBox()
{
}

ComboBox::ComboBox(const osgUI::ComboBox& combobox, const osg::CopyOp& copyop):
    Widget(combobox, copyop),
    _items(combobox._items)
{
}

bool ComboBox::handleImplementation(osgGA::EventVisitor* ev, osgGA::Event* event)
{
    // OSG_NOTICE<<"ComboBox::handleImplementation"<<std::endl;

    osgGA::GUIEventAdapter* ea = event->asGUIEventAdapter();
    if (!ea) return false;

    switch(ea->getEventType())
    {
        case(osgGA::GUIEventAdapter::SCROLL):
            OSG_NOTICE<<"Scroll "<<std::endl;
            if (ea->getScrollingMotion()==osgGA::GUIEventAdapter::SCROLL_DOWN)
            {
                OSG_NOTICE<<"Scroll Down`"<<std::endl;
                if (getCurrentItem()<getNumItems()-1) setCurrentItem(getCurrentItem()+1);
            }
            else if (ea->getScrollingMotion()==osgGA::GUIEventAdapter::SCROLL_UP)
            {
                OSG_NOTICE<<"Scroll Up`"<<std::endl;
                if (getCurrentItem()>0) setCurrentItem(getCurrentItem()-1);
            }
            break;
        case(osgGA::GUIEventAdapter::PUSH):
            OSG_NOTICE<<"Button pressed "<<std::endl;
            break;
        case(osgGA::GUIEventAdapter::RELEASE):
            OSG_NOTICE<<"Button release "<<std::endl;
            break;
        default:
            break;
    }

    return false;
}

void ComboBox::enterImplementation()
{
    OSG_NOTICE<<"ComboBox enter"<<std::endl;
}

void ComboBox::leaveImplementation()
{
    OSG_NOTICE<<"ComboBox leave"<<std::endl;
}

void ComboBox::setCurrentItem(unsigned int i)
{
    OSG_NOTICE << "ComboBox::setCurrentItem("<<i<<")"<<std::endl;
    _currentItem = i;
    if (_switch.valid()) _switch->setSingleChildOn(_currentItem);
}

void ComboBox::createGraphicsImplementation()
{

    if (_switch.valid() && _switch->getNumChildren()==_items.size())
    {
        OSG_NOTICE<<"Need to update existing scene graph"<<std::endl;
        _graphicsInitialized = true;
    }
    else
    {
        OSG_NOTICE<<"ComboBox::createGraphicsImplementation()"<<std::endl;

        Widget::createGraphicsImplementation();

        Style* style = (getStyle()!=0) ? getStyle() : Style::instance().get();

        _switch = new osg::Switch;
        addChild(_switch.get());

        if (!_items.empty())
        {
            for(Items::iterator itr = _items.begin();
                itr != _items.end();
                ++itr)
            {
                Item* item = itr->get();
                OSG_NOTICE<<"Creating item "<<item->getText()<<", "<<item->getColor()<<std::endl;
                osg::ref_ptr<osg::Group> group = new osg::Group;
                if (item->getColor().a()!=0.0f) group->addChild( style->createPanel(_extents, item->getColor()) );
                if (!item->getText().empty()) group->addChild( style->createText(_extents, getAlignmentSettings(), getTextSettings(), item->getText()) );
                _switch->addChild(group.get());
            }
        }
        else
        {
            _switch->addChild( style->createPanel(_extents, osg::Vec4(1.0f,1.0f,1.0f,1.0f)) );
        }

        _switch->setSingleChildOn(_currentItem);
    }
}
<commit_msg>Added handling of up/down key to ComboBox<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgUI/ComboBox>
#include <osgText/String>
#include <osgText/Font>
#include <osgText/Text>
#include <osg/Notify>
#include <osg/io_utils>

using namespace osgUI;

ComboBox::ComboBox()
{
}

ComboBox::ComboBox(const osgUI::ComboBox& combobox, const osg::CopyOp& copyop):
    Widget(combobox, copyop),
    _items(combobox._items)
{
}

bool ComboBox::handleImplementation(osgGA::EventVisitor* ev, osgGA::Event* event)
{
    // OSG_NOTICE<<"ComboBox::handleImplementation"<<std::endl;

    osgGA::GUIEventAdapter* ea = event->asGUIEventAdapter();
    if (!ea) return false;

    switch(ea->getEventType())
    {
        case(osgGA::GUIEventAdapter::SCROLL):
            if (ea->getScrollingMotion()==osgGA::GUIEventAdapter::SCROLL_DOWN)
            {
                if (getCurrentItem()<getNumItems()-1) setCurrentItem(getCurrentItem()+1);
                return true;
            }
            else if (ea->getScrollingMotion()==osgGA::GUIEventAdapter::SCROLL_UP)
            {
                if (getCurrentItem()>0) setCurrentItem(getCurrentItem()-1);
                return true;
            }
            break;
        case(osgGA::GUIEventAdapter::KEYDOWN):
            if (ea->getKey()==osgGA::GUIEventAdapter::KEY_Down)
            {
                if (getCurrentItem()<getNumItems()-1) setCurrentItem(getCurrentItem()+1);
                return true;
            }
            else if (ea->getKey()==osgGA::GUIEventAdapter::KEY_Up)
            {
                if (getCurrentItem()>0) setCurrentItem(getCurrentItem()-1);
                return true;
            }

            break;
        case(osgGA::GUIEventAdapter::PUSH):
            OSG_NOTICE<<"Button pressed "<<std::endl;
            break;
        case(osgGA::GUIEventAdapter::RELEASE):
            OSG_NOTICE<<"Button release "<<std::endl;
            break;
        default:
            break;
    }

    return false;
}

void ComboBox::enterImplementation()
{
    OSG_NOTICE<<"ComboBox enter"<<std::endl;
}

void ComboBox::leaveImplementation()
{
    OSG_NOTICE<<"ComboBox leave"<<std::endl;
}

void ComboBox::setCurrentItem(unsigned int i)
{
    OSG_NOTICE << "ComboBox::setCurrentItem("<<i<<")"<<std::endl;
    _currentItem = i;
    if (_switch.valid()) _switch->setSingleChildOn(_currentItem);
}

void ComboBox::createGraphicsImplementation()
{

    if (_switch.valid() && _switch->getNumChildren()==_items.size())
    {
        OSG_NOTICE<<"Need to update existing scene graph"<<std::endl;
        _graphicsInitialized = true;
    }
    else
    {
        OSG_NOTICE<<"ComboBox::createGraphicsImplementation()"<<std::endl;

        Widget::createGraphicsImplementation();

        Style* style = (getStyle()!=0) ? getStyle() : Style::instance().get();

        _switch = new osg::Switch;
        addChild(_switch.get());

        if (!_items.empty())
        {
            for(Items::iterator itr = _items.begin();
                itr != _items.end();
                ++itr)
            {
                Item* item = itr->get();
                OSG_NOTICE<<"Creating item "<<item->getText()<<", "<<item->getColor()<<std::endl;
                osg::ref_ptr<osg::Group> group = new osg::Group;
                if (item->getColor().a()!=0.0f) group->addChild( style->createPanel(_extents, item->getColor()) );
                if (!item->getText().empty()) group->addChild( style->createText(_extents, getAlignmentSettings(), getTextSettings(), item->getText()) );
                _switch->addChild(group.get());
            }
        }
        else
        {
            _switch->addChild( style->createPanel(_extents, osg::Vec4(1.0f,1.0f,1.0f,1.0f)) );
        }

        _switch->setSingleChildOn(_currentItem);
    }
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>

#include "server.h"
#include "stinger_net/stinger_server_state.h"

//#define LOG_AT_D
#include "stinger_core/stinger_error.h"

typedef struct {
  struct stinger * S;
  int sock;
} handle_stream_args;

void *
handle_stream(void * args)
{
  StingerServerState & server_state = StingerServerState::get_server_state();

  /* should be able to remove these */
  struct stinger *S = ((handle_stream_args *) args)->S;
  int sock = ((handle_stream_args *) args)->sock;
  free(args);

  int nfail = 0;

  LOG_V("Ready to accept messages.");
  while(1)
  {
    StingerBatch * batch = new StingerBatch();
    if (recv_message(sock, *batch)) {
      nfail = 0;

      LOG_V_A("Received message of size %ld", (long)batch->ByteSize());

      if (0 == batch->insertions_size () && 0 == batch->deletions_size ()) {
	LOG_V("Empty batch.");
	if (!batch->keep_alive ()) {
	  delete batch;
	  break;
	} else {
	  delete batch;
	  continue;
	}
      }

      server_state.enqueue_batch(batch);

      if(!batch->keep_alive()) {
	delete batch;
	break;
      }

    } else {
      ++nfail;
      LOG_E("Parsing failed.");
      if (nfail > 2) break;
    }
  }
}

void *
start_tcp_batch_server (void * args)
{
  StingerServerState & server_state = StingerServerState::get_server_state();

  struct stinger * S = server_state.get_stinger();
  int port_streams = server_state.get_port_streams();

  int sock_handle, newsockfd;
  pthread_t garbage_thread_handle;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;
  pid_t pid;

  if (-1 == (sock_handle = socket(AF_INET, SOCK_STREAM, 0))) {
    perror("Socket create failed.\n");
    exit(-1);
  }

  bzero ((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port_streams);

  if (-1 == bind(sock_handle, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
    perror("Socket bind failed.\n");
    exit(-1);
  }

  if (-1 == listen(sock_handle, 5)) {
    perror("Socket listen failed.\n");
    exit(-1);
  }

  clilen = sizeof(cli_addr);

  LOG_V_A("STINGER server listening for input on port %d",
      (int)port_streams);

  pthread_t alg_handling;
  pthread_create(&alg_handling, NULL, start_alg_handling, NULL);

  while (1) {
    newsockfd = accept (sock_handle, (struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) {
      perror("Accept new connection failed.\n");
      exit(-1);
    }

    handle_stream_args * args = (handle_stream_args *)calloc(1, sizeof(handle_stream_args));
    args->S = S;
    args->sock = newsockfd;

    pthread_create(&garbage_thread_handle, NULL, handle_stream, (void *)args);
  }

  close(sock_handle);
}
<commit_msg>Dropping batches when queue reaches 100 and logging it.<commit_after>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>

#include "server.h"
#include "stinger_core/stinger_atomics.h"
#include "stinger_net/stinger_server_state.h"

//#define LOG_AT_D
#include "stinger_core/stinger_error.h"

#define STINGER_MAX_BATCHES 100

typedef struct {
  struct stinger * S;
  int sock;
} handle_stream_args;

void *
handle_stream(void * args)
{
  StingerServerState & server_state = StingerServerState::get_server_state();

  /* should be able to remove these */
  struct stinger *S = ((handle_stream_args *) args)->S;
  int sock = ((handle_stream_args *) args)->sock;
  free(args);

  int nfail = 0;

  LOG_V("Ready to accept messages.");
  while(1)
  {
    StingerBatch * batch = new StingerBatch();
    if (recv_message(sock, *batch)) {
      nfail = 0;

      LOG_V_A("Received message of size %ld", (long)batch->ByteSize());

      if (0 == batch->insertions_size () && 0 == batch->deletions_size ()) {
	LOG_V("Empty batch.");
	if (!batch->keep_alive ()) {
	  delete batch;
	  break;
	} else {
	  delete batch;
	  continue;
	}
      }

      if (server_state.get_queue_size() >= STINGER_MAX_BATCHES) {
	LOG_W("Dropping a batch");
	stinger_uint64_fetch_add(&(S->dropped_batches), 1);
	delete batch;
	continue;
      }
      server_state.enqueue_batch(batch);

      if(!batch->keep_alive()) {
	delete batch;
	break;
      }

    } else {
      ++nfail;
      LOG_E("Parsing failed.");
      if (nfail > 2) break;
    }
  }
}

void *
start_tcp_batch_server (void * args)
{
  StingerServerState & server_state = StingerServerState::get_server_state();

  struct stinger * S = server_state.get_stinger();
  int port_streams = server_state.get_port_streams();

  int sock_handle, newsockfd;
  pthread_t garbage_thread_handle;
  socklen_t clilen;
  struct sockaddr_in serv_addr, cli_addr;
  pid_t pid;

  if (-1 == (sock_handle = socket(AF_INET, SOCK_STREAM, 0))) {
    perror("Socket create failed.\n");
    exit(-1);
  }

  bzero ((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port_streams);

  if (-1 == bind(sock_handle, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
    perror("Socket bind failed.\n");
    exit(-1);
  }

  if (-1 == listen(sock_handle, 5)) {
    perror("Socket listen failed.\n");
    exit(-1);
  }

  clilen = sizeof(cli_addr);

  LOG_V_A("STINGER server listening for input on port %d",
      (int)port_streams);

  pthread_t alg_handling;
  pthread_create(&alg_handling, NULL, start_alg_handling, NULL);

  while (1) {
    newsockfd = accept (sock_handle, (struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) {
      perror("Accept new connection failed.\n");
      exit(-1);
    }

    handle_stream_args * args = (handle_stream_args *)calloc(1, sizeof(handle_stream_args));
    args->S = S;
    args->sock = newsockfd;

    pthread_create(&garbage_thread_handle, NULL, handle_stream, (void *)args);
  }

  close(sock_handle);
}
<|endoftext|>