brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · ba628bd Raw
91 lines · c
1//===-- Definition of a class for mbstate_t and conversion -----*-- C++ -*-===//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#ifndef LLVM_LIBC_SRC___SUPPORT_STRING_CONVERTER_H10#define LLVM_LIBC_SRC___SUPPORT_STRING_CONVERTER_H11 12#include "hdr/types/char32_t.h"13#include "hdr/types/char8_t.h"14#include "hdr/types/size_t.h"15#include "src/__support/CPP/type_traits.h"16#include "src/__support/common.h"17#include "src/__support/error_or.h"18#include "src/__support/wchar/character_converter.h"19#include "src/__support/wchar/mbstate.h"20 21namespace LIBC_NAMESPACE_DECL {22namespace internal {23 24template <typename T> class StringConverter {25private:26  CharacterConverter cr;27  const T *src;28  size_t src_len;29  size_t src_idx;30 31  // # of pops we are allowed to perform (essentially size of the dest buffer)32  size_t num_to_write;33 34  ErrorOr<size_t> pushFullCharacter() {35    size_t num_pushed;36    for (num_pushed = 0; !cr.isFull() && src_idx + num_pushed < src_len;37         ++num_pushed) {38      int err = cr.push(src[src_idx + num_pushed]);39      if (err != 0)40        return Error(err);41    }42 43    // if we aren't able to read a full character from the source string44    if (src_idx + num_pushed == src_len && !cr.isFull()) {45      src_idx += num_pushed;46      return Error(-1);47    }48 49    return num_pushed;50  }51 52public:53  StringConverter(const T *s, mbstate *ps, size_t dstlen,54                  size_t srclen = SIZE_MAX)55      : cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {}56 57  template <typename CharType> ErrorOr<CharType> pop() {58    if (num_to_write == 0)59      return Error(-1);60 61    if (cr.isEmpty() || src_idx == 0) {62      auto src_elements_read = pushFullCharacter();63      if (!src_elements_read.has_value())64        return Error(src_elements_read.error());65 66      if (cr.sizeAs<CharType>() > num_to_write) {67        cr.clear();68        return Error(-1);69      }70 71      src_idx += src_elements_read.value();72    }73 74    ErrorOr<CharType> out = cr.pop<CharType>();75    // if out isn't null terminator or an error76    if (out.has_value() && out.value() == 0)77      src_len = src_idx;78 79    num_to_write--;80 81    return out;82  }83 84  size_t getSourceIndex() { return src_idx; }85};86 87} // namespace internal88} // namespace LIBC_NAMESPACE_DECL89 90#endif // LLVM_LIBC_SRC___SUPPORT_STRING_CONVERTER_H91