164ab3302SCarolineConcatto //===-- lib/Parser/char-buffer.cpp ----------------------------------------===// 264ab3302SCarolineConcatto // 364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information. 564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664ab3302SCarolineConcatto // 764ab3302SCarolineConcatto //===----------------------------------------------------------------------===// 864ab3302SCarolineConcatto 964ab3302SCarolineConcatto #include "flang/Parser/char-buffer.h" 1064ab3302SCarolineConcatto #include "flang/Common/idioms.h" 1164ab3302SCarolineConcatto #include <algorithm> 1264ab3302SCarolineConcatto #include <cstddef> 1364ab3302SCarolineConcatto #include <cstring> 1464ab3302SCarolineConcatto 1564ab3302SCarolineConcatto namespace Fortran::parser { 1664ab3302SCarolineConcatto FreeSpace(std::size_t & n)173b635714Speter klauslerchar *CharBuffer::FreeSpace(std::size_t &n) { 1864ab3302SCarolineConcatto int offset{LastBlockOffset()}; 1964ab3302SCarolineConcatto if (blocks_.empty()) { 2064ab3302SCarolineConcatto blocks_.emplace_front(); 2164ab3302SCarolineConcatto lastBlockEmpty_ = true; 2264ab3302SCarolineConcatto } else if (offset == 0 && !lastBlockEmpty_) { 23*cc575dd2Speter klausler blocks_.emplace_back(); 2464ab3302SCarolineConcatto lastBlockEmpty_ = true; 2564ab3302SCarolineConcatto } 263b635714Speter klausler n = Block::capacity - offset; 27*cc575dd2Speter klausler return blocks_.back().data + offset; 2864ab3302SCarolineConcatto } 2964ab3302SCarolineConcatto Claim(std::size_t n)3064ab3302SCarolineConcattovoid CharBuffer::Claim(std::size_t n) { 3164ab3302SCarolineConcatto if (n > 0) { 3264ab3302SCarolineConcatto bytes_ += n; 3364ab3302SCarolineConcatto lastBlockEmpty_ = false; 3464ab3302SCarolineConcatto } 3564ab3302SCarolineConcatto } 3664ab3302SCarolineConcatto Put(const char * data,std::size_t n)3764ab3302SCarolineConcattostd::size_t CharBuffer::Put(const char *data, std::size_t n) { 3864ab3302SCarolineConcatto std::size_t chunk; 3964ab3302SCarolineConcatto for (std::size_t at{0}; at < n; at += chunk) { 403b635714Speter klausler char *to{FreeSpace(chunk)}; 4164ab3302SCarolineConcatto chunk = std::min(n - at, chunk); 4264ab3302SCarolineConcatto Claim(chunk); 4364ab3302SCarolineConcatto std::memcpy(to, data + at, chunk); 4464ab3302SCarolineConcatto } 4564ab3302SCarolineConcatto return bytes_ - n; 4664ab3302SCarolineConcatto } 4764ab3302SCarolineConcatto Put(const std::string & str)4864ab3302SCarolineConcattostd::size_t CharBuffer::Put(const std::string &str) { 4964ab3302SCarolineConcatto return Put(str.data(), str.size()); 5064ab3302SCarolineConcatto } 5164ab3302SCarolineConcatto Marshal() const5264ab3302SCarolineConcattostd::string CharBuffer::Marshal() const { 5364ab3302SCarolineConcatto std::string result; 5464ab3302SCarolineConcatto std::size_t bytes{bytes_}; 5564ab3302SCarolineConcatto result.reserve(bytes); 5664ab3302SCarolineConcatto for (const Block &block : blocks_) { 5764ab3302SCarolineConcatto std::size_t chunk{std::min(bytes, Block::capacity)}; 5864ab3302SCarolineConcatto for (std::size_t j{0}; j < chunk; ++j) { 5964ab3302SCarolineConcatto result += block.data[j]; 6064ab3302SCarolineConcatto } 6164ab3302SCarolineConcatto bytes -= chunk; 6264ab3302SCarolineConcatto } 6364ab3302SCarolineConcatto result.shrink_to_fit(); 6464ab3302SCarolineConcatto CHECK(result.size() == bytes_); 6564ab3302SCarolineConcatto return result; 6664ab3302SCarolineConcatto } 671f879005STim Keith } // namespace Fortran::parser 68