xref: /llvm-project/flang/lib/Parser/char-buffer.cpp (revision cc575dd2cefce3170655a026dbf058a42e1a4330)
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 klausler char *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)3064ab3302SCarolineConcatto void 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)3764ab3302SCarolineConcatto std::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)4864ab3302SCarolineConcatto std::size_t CharBuffer::Put(const std::string &str) {
4964ab3302SCarolineConcatto   return Put(str.data(), str.size());
5064ab3302SCarolineConcatto }
5164ab3302SCarolineConcatto 
Marshal() const5264ab3302SCarolineConcatto std::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