// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/bitmap.h"

#include "platform/assert.h"
#include "vm/object.h"

namespace dart {

void BitmapBuilder::SetLength(intptr_t new_length) {
  // When this function is used to shorten the length, affected bits in the
  // backing store need to be cleared because the implementation assumes it.
  if (new_length < length_) {
    // Byte offset containing the first bit to be cleared.
    intptr_t byte_offset = new_length >> kBitsPerByteLog2;
    if (byte_offset < data_size_in_bytes_) {
      // First bit index (in the byte) to be cleared.
      intptr_t bit_index = new_length & (kBitsPerByte - 1);
      intptr_t mask = (1 << bit_index) - 1;
      data_[byte_offset] &= mask;
      // Clear the rest.
      ++byte_offset;
      if (byte_offset < data_size_in_bytes_) {
        memset(&data_[byte_offset], 0, data_size_in_bytes_ - byte_offset);
      }
    }
  }
  length_ = new_length;
}


bool BitmapBuilder::Get(intptr_t bit_offset) const {
  if (!InRange(bit_offset)) {
    return false;
  }
  intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
  // Bits not covered by the backing store are implicitly false.
  return (byte_offset < data_size_in_bytes_) && GetBit(bit_offset);
}


void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
  if (!InRange(bit_offset)) {
    length_ = bit_offset + 1;
    // Bits not covered by the backing store are implicitly false.
    if (!value) return;
    // Grow the backing store if necessary.
    intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
    if (byte_offset >= data_size_in_bytes_) {
      uint8_t* old_data = data_;
      intptr_t old_size = data_size_in_bytes_;
      data_size_in_bytes_ =
          Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes);
      ASSERT(data_size_in_bytes_ > 0);
      data_ = Thread::Current()->zone()->Alloc<uint8_t>(data_size_in_bytes_);
      ASSERT(data_ != NULL);
      memmove(data_, old_data, old_size);
      memset(&data_[old_size], 0, (data_size_in_bytes_ - old_size));
    }
  }
  SetBit(bit_offset, value);
}


void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) {
  for (intptr_t i = min; i <= max; i++) {
    Set(i, value);
  }
}


void BitmapBuilder::Print() const {
  for (intptr_t i = 0; i < Length(); i++) {
    if (Get(i)) {
      OS::Print("1");
    } else {
      OS::Print("0");
    }
  }
}


bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
  if (!InRange(bit_offset)) {
    return false;
  }
  intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
  ASSERT(byte_offset < data_size_in_bytes_);
  intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
  uint8_t mask = 1U << bit_remainder;
  ASSERT(data_ != NULL);
  return ((data_[byte_offset] & mask) != 0);
}


void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
  if (!InRange(bit_offset)) {
    FATAL1(
        "Fatal error in BitmapBuilder::SetBit :"
        " invalid bit_offset, %" Pd "\n",
        bit_offset);
  }
  intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
  ASSERT(byte_offset < data_size_in_bytes_);
  intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
  uint8_t mask = 1U << bit_remainder;
  ASSERT(data_ != NULL);
  if (value) {
    data_[byte_offset] |= mask;
  } else {
    data_[byte_offset] &= ~mask;
  }
}

}  // namespace dart
