Beispiel #1
0
CstrBuffer::CstrBuffer(const char *filename)
  : m_buffer(nullptr), m_len(0) {
  struct stat sb;
  if (stat(filename, &sb) == 0) {
    if (sb.st_size > kMaxCap - 1) {
      auto const str = folly::to<std::string>(
        "file ", filename, " is too large"
      );
      throw StringBufferLimitException(kMaxCap, String(str.c_str()));
    }
    m_cap = sb.st_size;
    m_buffer = (char *)safe_malloc(m_cap + 1);

    int fd = ::open(filename, O_RDONLY);
    if (fd != -1) {
      while (m_len < m_cap) {
        int buffer_size = m_cap - m_len;
        int len = ::read(fd, m_buffer + m_len, buffer_size);
        if (len == -1 && errno == EINTR) continue;
        if (len <= 0) break;
        m_len += len;
      }
      ::close(fd);
    }
  }
}
Beispiel #2
0
void StringBuffer::growBy(int spaceRequired) {
  /*
   * The default initial size is a power-of-two minus 1.
   * This doubling scheme keeps the total block size a
   * power of two, which should be good for memory allocators.
   * But note there is no guarantee either that the initial size
   * is power-of-two minus 1, or that it stays that way
   * (new_size < minSize below).
   */
  auto new_size = m_cap * 2 + 1;
  auto const minSize = static_cast<unsigned>(m_cap) + spaceRequired;
  if (new_size < minSize) {
    new_size = minSize;
  }

  if (new_size > m_maxBytes) {
    if (minSize > m_maxBytes) {
      throw StringBufferLimitException(m_maxBytes, detach());
    } else {
      new_size = m_maxBytes;
    }
  }

  m_buffer[m_len] = 0;
  m_str->setSize(m_len);
  auto const tmp = m_str->reserve(new_size);
  if (UNLIKELY(tmp != m_str)) {
    assert(m_str->hasExactlyOneRef());
    m_str->release();
    m_str = tmp;
  }
  auto const s = m_str->bufferSlice();
  m_buffer = s.ptr;
  m_cap = s.len;
}
Beispiel #3
0
void StringBuffer::growBy(int spaceRequired) {
  /*
   * The default initial size is a power-of-two minus 1.
   * This doubling scheme keeps the total block size a
   * power of two, which should be good for memory allocators.
   * But note there is no guarantee either that the initial size
   * is power-of-two minus 1, or that it stays that way
   * (new_size < minSize below).
   */
  long new_size = m_cap * 2L + 1;
  long minSize = m_cap + (long)spaceRequired;
  if (new_size < minSize) {
    new_size = minSize;
  }

  if (m_maxBytes > 0 && new_size > m_maxBytes) {
    if (minSize > m_maxBytes) {
      throw StringBufferLimitException(m_maxBytes, detach());
    } else {
      new_size = m_maxBytes;
    }
  }

  m_buffer[m_len] = 0;
  m_str->setSize(m_len);
  MutableSlice s = m_str->reserve(new_size);
  m_buffer = s.ptr;
  m_cap = s.len;
}
Beispiel #4
0
CstrBuffer::CstrBuffer(const char *filename)
  : m_buffer(NULL), m_len(0) {
  struct stat sb;
  if (stat(filename, &sb) == 0) {
    if (sb.st_size > kMaxCap - 1) {
      std::ostringstream out;
      out << "file " << filename << " is too large";
      throw StringBufferLimitException(kMaxCap,
                                       String(out.str().c_str()));
    }
    m_cap = sb.st_size;
    m_buffer = (char *)Util::safe_malloc(m_cap + 1);

    int fd = ::open(filename, O_RDONLY);
    if (fd != -1) {
      while (m_len < m_cap) {
        int buffer_size = m_cap - m_len;
        int len = ::read(fd, m_buffer + m_len, buffer_size);
        if (len == -1 && errno == EINTR) continue;
        if (len <= 0) break;
        m_len += len;
      }
      ::close(fd);
    }
  }
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
Beispiel #5
0
void CstrBuffer::append(const char* data, int len) {
  ASSERT(m_buffer && len >= 0);
  unsigned newlen = m_len + len;
  if (newlen + 1 > m_cap) {
    if (newlen + 1 > kMaxCap) {
      throw StringBufferLimitException(kMaxCap, detach());
    }
    unsigned newcap = Util::nextPower2(newlen + 1);
    m_buffer = (char*)Util::safe_realloc(m_buffer, newcap);
    m_cap = newcap - 1;
    ASSERT(newlen + 1 <= m_cap);
  }
  memcpy(m_buffer + m_len, data, len);
  m_buffer[m_len = newlen] = 0;
}
void StringBuffer::grow(int minSize) {
  int new_size = m_size;
  new_size <<= 1;
  if (new_size < minSize) {
    new_size = minSize;
  }

  if (m_maxBytes > 0 && new_size > m_maxBytes) {
    throw StringBufferLimitException(m_maxBytes, detach());
  }

  char *new_buffer;
  new_buffer = (char *)Util::safe_realloc(m_buffer, new_size + 1);

  m_size = new_size;
  m_buffer = new_buffer;
}
Beispiel #7
0
void CstrBuffer::append(StringSlice slice) {
  auto const data = slice.ptr;
  auto const len = slice.len;

  assert(m_buffer && len >= 0);

  unsigned newlen = m_len + len;
  if (newlen + 1 > m_cap) {
    if (newlen + 1 > kMaxCap) {
      throw StringBufferLimitException(kMaxCap, detach());
    }
    unsigned newcap = Util::nextPower2(newlen + 1);
    m_buffer = (char*)Util::safe_realloc(m_buffer, newcap);
    m_cap = newcap - 1;
    assert(newlen + 1 <= m_cap);
  }
  memcpy(m_buffer + m_len, data, len);
  m_buffer[m_len = newlen] = 0;
}
Beispiel #8
0
void CstrBuffer::append(StringSlice slice) {
  auto const data = slice.ptr;
  auto const len = slice.len;

  static_assert(std::is_unsigned<decltype(len)>::value,
                "len is supposed to be unsigned");
  assert(m_buffer);

  unsigned newlen = m_len + len;
  if (newlen + 1 > m_cap) {
    if (newlen + 1 > kMaxCap) {
      throw StringBufferLimitException(kMaxCap, detach());
    }
    unsigned newcap = folly::nextPowTwo(newlen + 1);
    m_buffer = (char*)safe_realloc(m_buffer, newcap);
    m_cap = newcap - 1;
    assert(newlen + 1 <= m_cap);
  }
  memcpy(m_buffer + m_len, data, len);
  m_buffer[m_len = newlen] = 0;
}