output.h (2916B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Output extension hooks for the Format library. 16 // `internal::InvokeFlush` calls the appropriate flush function for the 17 // specified output argument. 18 // `BufferRawSink` is a simple output sink for a char buffer. Used by SnprintF. 19 // `FILERawSink` is a std::FILE* based sink. Used by PrintF and FprintF. 20 21 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ 22 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ 23 24 #include <cstdio> 25 #include <ios> 26 #include <ostream> 27 #include <string> 28 29 #include "absl/base/port.h" 30 #include "absl/strings/string_view.h" 31 32 namespace absl { 33 ABSL_NAMESPACE_BEGIN 34 namespace str_format_internal { 35 36 // RawSink implementation that writes into a char* buffer. 37 // It will not overflow the buffer, but will keep the total count of chars 38 // that would have been written. 39 class BufferRawSink { 40 public: 41 BufferRawSink(char* buffer, size_t size) : buffer_(buffer), size_(size) {} 42 43 size_t total_written() const { return total_written_; } 44 void Write(string_view v); 45 46 private: 47 char* buffer_; 48 size_t size_; 49 size_t total_written_ = 0; 50 }; 51 52 // RawSink implementation that writes into a FILE*. 53 // It keeps track of the total number of bytes written and any error encountered 54 // during the writes. 55 class FILERawSink { 56 public: 57 explicit FILERawSink(std::FILE* output) : output_(output) {} 58 59 void Write(string_view v); 60 61 size_t count() const { return count_; } 62 int error() const { return error_; } 63 64 private: 65 std::FILE* output_; 66 int error_ = 0; 67 size_t count_ = 0; 68 }; 69 70 // Provide RawSink integration with common types from the STL. 71 inline void AbslFormatFlush(std::string* out, string_view s) { 72 out->append(s.data(), s.size()); 73 } 74 inline void AbslFormatFlush(std::ostream* out, string_view s) { 75 out->write(s.data(), static_cast<std::streamsize>(s.size())); 76 } 77 78 inline void AbslFormatFlush(FILERawSink* sink, string_view v) { 79 sink->Write(v); 80 } 81 82 inline void AbslFormatFlush(BufferRawSink* sink, string_view v) { 83 sink->Write(v); 84 } 85 86 // This is a SFINAE to get a better compiler error message when the type 87 // is not supported. 88 template <typename T> 89 auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) { 90 AbslFormatFlush(out, s); 91 } 92 93 } // namespace str_format_internal 94 ABSL_NAMESPACE_END 95 } // namespace absl 96 97 #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_