1 /* 2 * Copyright 2009-2017 Alibaba Cloud All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 #include <iostream> 19 20 namespace AlibabaCloud 21 { 22 namespace OSS 23 { 24 25 template<class _Elem, class _Traits> 26 class basic_streambuf_proxy : public std::basic_streambuf <_Elem, _Traits> 27 { 28 public: ~basic_streambuf_proxy()29 virtual ~basic_streambuf_proxy() { 30 std::ios_base::iostate state = _Stream->rdstate(); 31 _Stream->rdbuf(_Sbuf); 32 _Stream->setstate(state); 33 } 34 using int_type = typename _Traits::int_type; 35 using pos_type = typename _Traits::pos_type; 36 using off_type = typename _Traits::off_type; 37 38 protected: basic_streambuf_proxy(std::basic_iostream<_Elem,_Traits> & stream)39 basic_streambuf_proxy(std::basic_iostream<_Elem, _Traits>& stream) 40 : _Stream(&stream) 41 , _Sbuf(_Stream->rdbuf(this)) { 42 } 43 44 int_type overflow(int_type _Meta = _Traits::eof()) 45 { // put a character to stream 46 return _Sbuf->sputc(_Meta); 47 } 48 49 int_type pbackfail(int_type _Meta = _Traits::eof()) 50 { // put a character back to stream 51 return _Sbuf->sputbackc(_Meta); 52 } 53 showmanyc()54 std::streamsize showmanyc() 55 { // return count of input characters 56 return _Sbuf->in_avail();; 57 } 58 underflow()59 int_type underflow() 60 { // get a character from stream, but don't point past it 61 return _Sbuf->sgetc(); 62 } 63 uflow()64 int_type uflow() 65 { // get a character from stream, point past it 66 return _Sbuf->sbumpc(); 67 } 68 xsgetn(_Elem * _Ptr,std::streamsize _Count)69 std::streamsize xsgetn(_Elem * _Ptr, std::streamsize _Count) 70 { // get _Count characters from stream 71 return _Sbuf->sgetn(_Ptr, _Count); 72 } 73 xsputn(const _Elem * _Ptr,std::streamsize _Count)74 std::streamsize xsputn(const _Elem *_Ptr, std::streamsize _Count) 75 { // put _Count characters to stream 76 return _Sbuf->sputn(_Ptr, _Count); 77 } 78 79 pos_type seekoff(off_type _Off, std::ios_base::seekdir _Way, std::ios_base::openmode _Mode = std::ios_base::in | std::ios_base::out) 80 { // change position by offset, according to way and mode 81 return _Sbuf->pubseekoff(_Off, _Way, _Mode); 82 } 83 84 pos_type seekpos(pos_type _Pos, std::ios_base::openmode _Mode = std::ios_base::in | std::ios_base::out) 85 { // change to specified position, according to mode 86 return _Sbuf->pubseekpos(_Pos, _Mode); 87 } 88 setbuf(_Elem * _Buffer,std::streamsize _Count)89 std::basic_streambuf<_Elem, _Traits>* setbuf(_Elem *_Buffer, std::streamsize _Count) 90 { // offer buffer to external agent 91 return _Sbuf->pubsetbuf(_Buffer, _Count); 92 } 93 sync()94 int sync() 95 { // synchronize with external agent 96 return _Sbuf->pubsync(); 97 } 98 imbue(const std::locale & _Newlocale)99 void imbue(const std::locale& _Newlocale) 100 { // set locale to argument 101 _Sbuf->pubimbue(_Newlocale); 102 } 103 private: 104 std::basic_iostream<_Elem, _Traits>* _Stream; 105 std::basic_streambuf<_Elem, _Traits>* _Sbuf; 106 }; 107 108 using StreamBufProxy = basic_streambuf_proxy<char, std::char_traits<char>>; 109 110 } 111 } 112