68 lines · cpp
1//===-- lib/Parser/char-buffer.cpp ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Parser/char-buffer.h"10#include "flang/Common/idioms.h"11#include <algorithm>12#include <cstddef>13#include <cstring>14 15namespace Fortran::parser {16 17char *CharBuffer::FreeSpace(std::size_t &n) {18 int offset{LastBlockOffset()};19 if (blocks_.empty()) {20 blocks_.emplace_front();21 lastBlockEmpty_ = true;22 } else if (offset == 0 && !lastBlockEmpty_) {23 blocks_.emplace_back();24 lastBlockEmpty_ = true;25 }26 n = Block::capacity - offset;27 return blocks_.back().data + offset;28}29 30void CharBuffer::Claim(std::size_t n) {31 if (n > 0) {32 bytes_ += n;33 lastBlockEmpty_ = false;34 }35}36 37std::size_t CharBuffer::Put(const char *data, std::size_t n) {38 std::size_t chunk;39 for (std::size_t at{0}; at < n; at += chunk) {40 char *to{FreeSpace(chunk)};41 chunk = std::min(n - at, chunk);42 Claim(chunk);43 std::memcpy(to, data + at, chunk);44 }45 return bytes_ - n;46}47 48std::size_t CharBuffer::Put(const std::string &str) {49 return Put(str.data(), str.size());50}51 52std::string CharBuffer::Marshal() const {53 std::string result;54 std::size_t bytes{bytes_};55 result.reserve(bytes);56 for (const Block &block : blocks_) {57 std::size_t chunk{std::min(bytes, Block::capacity)};58 for (std::size_t j{0}; j < chunk; ++j) {59 result += block.data[j];60 }61 bytes -= chunk;62 }63 result.shrink_to_fit();64 CHECK(result.size() == bytes_);65 return result;66}67} // namespace Fortran::parser68