CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
std_stream_wrappers.h
1
2#pragma once
3
4#include <iostream>
5#include <vector>
6#include "system/io/stream.h"
7#include "system/bit_converter.h"
8#include "system/details/is_template_base_of.h"
9
10namespace System { namespace IO {
11
12using System::Details::IsTemplateBaseOf;
13
16{
19 Binary,
23};
24
28{
30 Zero,
35};
36
42template <typename T, typename = std::enable_if_t<IsTemplateBaseOf<std::basic_ios, T>::value>>
44{
45public:
48 using ThisTypeBaseTypesInfo = BaseTypesInfo<BaseType>;
51
52public:
53 using char_type = typename T::char_type;
54 using traits_type = typename T::traits_type;
55
56 using int_type = typename T::int_type;
57 using pos_type = typename T::pos_type;
58 using off_type = typename T::off_type;
59
62
65
70 virtual int64_t Seek(int64_t offset, SeekOrigin origin) override
71 {
72 Check();
73
74 if (origin < SeekOrigin::Begin || origin > SeekOrigin::End)
75 throw ArgumentException(u"Invalid SeekOrigin enum value", u"origin");
76
77 if (!get_CanSeek())
78 throw NotSupportedException(u"Can't seek stream.");
79
80 int64_t new_pos;
82 {
83 if (origin == SeekOrigin::Begin)
84 {
85 new_pos = offset;
86 }
87 else if (origin == SeekOrigin::Current)
88 {
89 new_pos = m_elem_pos + offset;
90 }
91 else
92 {
93 new_pos = m_length + offset;
94 }
95
96 if (new_pos < 0)
97 throw ArgumentOutOfRangeException(u"Seeking is attempted before the beginning of the stream.");
98
99 if (new_pos == m_elem_pos)
100 return m_elem_pos;
101
102 Pubseekpos(new_pos);
103 }
104 else
105 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
106 if (origin == SeekOrigin::Begin)
107 {
108 new_pos = offset;
109 }
110 else if (origin == SeekOrigin::Current)
111 {
112 new_pos = m_byte_pos + offset;
113 }
114 else
115 {
116 new_pos = m_length * m_elem_size + offset;
117 }
118
119 if (new_pos < 0)
120 throw ArgumentOutOfRangeException(u"Seeking is attempted before the beginning of the stream.");
121
122 if (new_pos == m_byte_pos)
123 return m_byte_pos;
124
125 bool has_new_byte_pos_shift = new_pos % m_elem_size != 0;
126 int64_t new_elem_pos = Pubseekpos(new_pos / m_elem_size + int(has_new_byte_pos_shift));
127 if (new_elem_pos != -1)
128 {
129 m_byte_pos = new_pos;
130 if (has_new_byte_pos_shift)
131 {
132 Pubseekpos(new_elem_pos - 1);
133 }
134
135 DecodeElem(m_stream.rdbuf()->sgetc());
136 }
137 }
138
139 Sync();
140 return new_pos;
141 }
142
145 virtual void set_Position(int64_t value) override
146 {
147 Check();
148
149 if (!get_CanSeek())
150 throw NotSupportedException(u"Can't seek stream.");
151
152 if (value < 0)
153 throw ArgumentOutOfRangeException(u"value must be non-negative");
154
156 {
157 if (value == m_elem_pos)
158 return;
159
160 Pubseekpos(value);
161 }
162 else
163 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
164 if (value == m_byte_pos)
165 return;
166
167 int64_t new_byte_pos = value;
168 bool has_new_byte_pos_shift = new_byte_pos % m_elem_size != 0;
169 int64_t new_elem_pos = Pubseekpos(new_byte_pos / m_elem_size + int(has_new_byte_pos_shift));
170 if (new_elem_pos != -1)
171 {
172 m_byte_pos = new_byte_pos;
173 if (has_new_byte_pos_shift)
174 {
175 Pubseekpos(new_elem_pos - 1);
176 }
177
178 DecodeElem(m_stream.rdbuf()->sgetc());
179 }
180 }
181
182 Sync();
183 }
184
186 virtual int64_t get_Position() const override
187 {
188 Check();
189
190 if (!get_CanSeek())
191 throw NotSupportedException(u"Can't seek stream.");
192
194 {
195 return m_elem_pos;
196 }
197 else
198 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
199 return m_byte_pos;
200 }
201 }
202
204 virtual int64_t get_Length() const override
205 {
206 Check();
207
208 if (!get_CanSeek())
209 throw NotSupportedException(u"Can't seek stream.");
210
212 {
213 return m_length;
214 }
215 else
216 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
217 return m_length * m_elem_size;
218 }
219 }
220
222 virtual bool get_CanRead() const override
223 {
224 return m_can_read && !m_stream.fail();
225 }
226
228 virtual bool get_CanSeek() const override
229 {
230 return m_can_seek && !m_stream.fail();
231 }
232
234 virtual bool get_CanWrite() const override
235 {
236 return m_can_write && !m_stream.fail();
237 }
238
239protected:
247 STDIOStreamWrapperBase(std::basic_ios<char_type, traits_type>& str,
248 STDIOStreamWrappingMode mode = STDIOStreamWrappingMode::Binary, bool can_read = false,
249 bool can_write = false, bool can_seek = false,
251 : m_stream(str), m_wrapping_mode(mode), m_can_read(can_read), m_can_write(can_write), m_can_seek(can_seek)
252 {
254 can_read ? int64_t(m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)) : int64_t(0);
256 can_write ? int64_t(m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out)) : int64_t(0);
257 if (!m_can_seek)
258 {
259 m_elem_pos = 0;
260 m_byte_pos = 0;
261 m_length = 0;
262 }
263 else
264 {
266 {
267 switch (pref_pos)
268 {
272 m_elem_pos = 0;
273 break;
277 break;
281 break;
282 default:
283 // nothing to do
284 break;
285 }
286
287 int64_t end = m_stream.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios_base::in);
288 int64_t beg = m_stream.rdbuf()->pubseekoff(0, std::ios_base::beg, std::ios_base::in);
289 m_length = end - beg;
290 m_stream.rdbuf()->pubseekpos(m_elem_pos, std::ios_base::in);
291 }
292 else if (m_can_read)
293 {
295
296 int64_t end = m_stream.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios_base::in);
297 int64_t beg = m_stream.rdbuf()->pubseekoff(0, std::ios_base::beg, std::ios_base::in);
298 m_length = end - beg;
299 m_stream.rdbuf()->pubseekpos(m_elem_pos, std::ios_base::in);
300 }
301 else
302 {
304
305 int64_t end = m_stream.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios_base::out);
306 int64_t beg = m_stream.rdbuf()->pubseekoff(0, std::ios_base::beg, std::ios_base::out);
307 m_length = end - beg;
308 m_stream.rdbuf()->pubseekpos(m_elem_pos, std::ios_base::out);
309 }
310
312 {
314 }
315 }
316 }
317
321 virtual int64_t Pubseekpos(int64_t value) = 0;
322
324 virtual void Check() const
325 {
326 if (m_wrapping_mode < STDIOStreamWrappingMode::Binary || m_wrapping_mode > STDIOStreamWrappingMode::Conversion)
327 throw NotSupportedException(u"Wrapper does not support current wrapping mode.");
328 };
329
331 virtual void Sync() = 0;
332
336 {
338 }
339
343 void DecodeElem(int_type meta, ArrayPtr<uint8_t>& destination)
344 {
345 if (traits_type::eq_int_type(meta, traits_type::eof()))
346 {
347 destination.reset();
348 }
349 else
350 {
351 destination = BitConverter::GetBytes(meta);
352 }
353 }
354
358 {
359 return EncodeElem(m_decoded_elem->data_ptr());
360 }
361
365 char_type EncodeElem(uint8_t* source)
366 {
367 char_type result;
368 EncodeElem(source, &result);
369 return result;
370 }
371
375 void EncodeElem(uint8_t* source, char_type* destination)
376 {
377 auto dst = (uint8_t*)destination;
379 {
380 std::copy(source, source + m_elem_size, dst);
381 }
382 else
383 {
384 std::reverse_copy(source, source + m_elem_size, dst);
385 }
386 }
387
389 std::basic_ios<char_type, traits_type>& m_stream;
393 const bool m_can_read;
395 const bool m_can_write;
397 const bool m_can_seek;
399 static constexpr uint8_t m_elem_size = sizeof(char_type);
405 int64_t m_elem_pos;
407 int64_t m_byte_pos;
409 int64_t m_length;
410
413};
414
420template <typename T, typename = std::enable_if_t<IsTemplateBaseOf<std::basic_istream, T>::value>>
422{
423public:
426 using ThisTypeBaseTypesInfo = BaseTypesInfo<BaseType>;
429
430public:
433
437 BasicSTDIStreamWrapper(std::basic_istream<char_type, traits_type>& str,
439 : BaseType(str, mode, true, false, (std::ios_base*)&str != &std::cin && (std::ios_base*)&str != &std::wcin)
440 {}
441
444
447
451 virtual int ReadByte() override
452 {
453 Check();
454
455 if (!get_CanRead())
456 throw NotSupportedException(u"Can't read from stream.");
457
459 {
460 auto meta = m_stream.rdbuf()->sbumpc();
461 if (traits_type::eq_int_type(meta, traits_type::eof()))
462 {
463 return -1;
464 }
465 else
466 {
467 Sync();
468 return uint8_t(meta);
469 }
470 }
471 else
472 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
473 if (m_decoded_elem == nullptr)
474 {
475 auto meta = m_stream.rdbuf()->sgetc();
476 if (traits_type::eq_int_type(meta, traits_type::eof()))
477 {
478 return -1;
479 }
480 else
481 {
482 DecodeElem(meta);
483 }
484 }
485
486 int64_t byte_pos_shift = m_byte_pos % m_elem_size;
487 auto result = int(m_decoded_elem[byte_pos_shift]);
488
489 ++m_byte_pos;
490 ++byte_pos_shift %= m_elem_size;
491 if (byte_pos_shift == 0)
492 { // Decode element at new byte position.
493 DecodeElem(m_stream.rdbuf()->snextc());
494 }
495
496 Sync();
497 return result;
498 }
499 }
500
504 virtual void WriteByte(uint8_t value) override
505 {
506 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
507 }
508
516 virtual int32_t Read(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
517 {
518 return Read(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
519 }
520
527 virtual void Write(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
528 {
529 Write(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
530 }
531
537 virtual int32_t Read(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
538 {
539 Check();
540
541 if (!get_CanRead())
542 throw NotSupportedException(u"Can't read from stream.");
543 if (buffer == nullptr)
544 throw ArgumentNullException(u"buffer");
545 if (offset < 0)
546 throw ArgumentOutOfRangeException(u"offset", u"Value is less than zero");
547 if (count < 0)
548 throw ArgumentOutOfRangeException(u"count", u"Value is less than zero");
549 if (buffer.get_Length() - offset < count)
550 throw ArgumentException(u"Invalid buffer length");
551
552 if (count == 0)
553 return 0;
554
555 if (m_elem_size == 1)
556 {
557 int readed_count = int(m_stream.rdbuf()->sgetn((char_type*)&buffer[offset], count));
559 {
560 m_byte_pos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
561 }
562
563 Sync();
564 return readed_count;
565 }
566
568 {
569 std::vector<char_type> tempbuff(count, 0);
570 int readed_count = int(m_stream.rdbuf()->sgetn(tempbuff.data(), count));
571 auto dst = &buffer[offset];
572 std::for_each(tempbuff.begin(), tempbuff.end(),
573 [&dst, this](char_type& elem) { *(dst++) = uint8_t(elem); });
574
575 Sync();
576 return readed_count;
577 }
578 else
579 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
580 uint8_t byte_pos_shift = m_byte_pos % m_elem_size;
581 int new_byte_count = byte_pos_shift + count;
582 bool has_new_byte_pos_shift = new_byte_count % m_elem_size != 0;
583 int elem_count = new_byte_count / m_elem_size + int(has_new_byte_pos_shift);
584
585 std::vector<char_type> tempbuff(elem_count, 0);
586 int readed_elem_count = int(m_stream.rdbuf()->sgetn(tempbuff.data(), elem_count));
587 int readed_byte_count;
588 if (readed_elem_count != elem_count)
589 {
590 readed_byte_count = readed_elem_count * m_elem_size - byte_pos_shift;
591 }
592 else
593 {
594 readed_byte_count = count;
595 if (has_new_byte_pos_shift)
596 {
597 m_stream.rdbuf()->pubseekoff(-1, std::ios_base::cur, std::ios_base::in);
598 }
599 }
600
601 m_byte_pos += readed_byte_count;
602
603 const char_type* source = &tempbuff[byte_pos_shift];
604 uint8_t* destination = &buffer[offset];
605 for (int i = 0; i < readed_byte_count; i += m_elem_size, ++source, destination += m_elem_size)
606 {
607 DecodeElem(traits_type::to_int_type(*source));
608 std::strncpy((char*)destination, (const char*)m_decoded_elem->data_ptr(), m_elem_size);
609 }
610
611 Sync();
612 return readed_byte_count;
613 }
614 }
615
620 virtual void Write(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
621 {
622 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
623 }
624
627 virtual void SetLength(int64_t value) override
628 {
629 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
630 }
631
633 virtual void Flush() override
634 {
635 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
636 }
637
638protected:
642 virtual int64_t Pubseekpos(int64_t value) override
643 {
644 return m_stream.rdbuf()->pubseekpos(value, std::ios_base::in);
645 }
646
648 virtual void Check() const override
649 {
651 auto elem_gpos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
652 if (m_stream.fail() || m_last_elem_gpos != elem_gpos)
653 {
654 if (!m_stream.fail())
655 {
656 m_stream.setstate(std::ios_base::failbit);
657 }
658
659 throw IOException(u"The stream has been modified outside the wrapper.");
660 }
661 }
662
664 virtual void Sync() override
665 {
666 auto elem_gpos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
667 if (m_last_elem_gpos != elem_gpos)
668 {
669 m_last_elem_gpos = elem_gpos;
670 m_elem_pos = elem_gpos;
671 }
672 }
673
676
682 using BaseType::m_stream;
684};
685
691template <typename T, typename = std::enable_if_t<IsTemplateBaseOf<std::basic_ostream, T>::value>>
693{
694public:
697 using ThisTypeBaseTypesInfo = BaseTypesInfo<BaseType>;
700
701public:
704
708 BasicSTDOStreamWrapper(std::basic_ostream<char_type, traits_type>& str,
710 : BaseType(str, mode, false, true, (std::ios_base*)&str != &std::cout && (std::ios_base*)&str != &std::wcout)
711 {}
712
715
718
722 virtual int ReadByte() override
723 {
724 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
725 }
726
730 virtual void WriteByte(uint8_t value) override
731 {
732 Check();
733
734 if (!get_CanWrite())
735 throw NotSupportedException(u"Can't write to stream.");
736
738 {
739 m_stream.rdbuf()->sputc(char_type(value));
740 }
741 else
742 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
743 if (m_decoded_elem == nullptr)
744 {
745 m_decoded_elem = MakeArray<uint8_t>(m_elem_size, 0);
746 }
747
748 int64_t byte_pos_shift = m_byte_pos % m_elem_size;
749 m_decoded_elem[byte_pos_shift] = value;
750 ++m_byte_pos;
751 ++byte_pos_shift %= m_elem_size;
752
753 m_stream.rdbuf()->sputc(EncodeElem());
754 if (byte_pos_shift != 0)
755 { // New byte position is previous element position.
756 m_stream.rdbuf()->pubseekoff(-1, std::ios_base::cur, std::ios_base::in);
757 }
758 else
759 { // Decode element at new byte position.
760 DecodeElem(m_stream.rdbuf()->sgetc());
761 }
762 }
763
764 Sync();
765 }
766
774 virtual int32_t Read(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
775 {
776 return Read(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
777 }
778
785 virtual void Write(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
786 {
787 Write(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
788 }
789
795 virtual int32_t Read(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
796 {
797 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
798 }
799
804 virtual void Write(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
805 {
806 Check();
807
808 if (!get_CanWrite())
809 throw NotSupportedException(u"Can't write to stream.");
810 if (buffer == nullptr)
811 throw ArgumentNullException(u"buffer");
812 if (offset < 0)
813 throw ArgumentOutOfRangeException(u"offset", u"Value is less than zero");
814 if (count < 0)
815 throw ArgumentOutOfRangeException(u"count", u"Value is less than zero");
816 if (buffer.get_Length() - offset < count)
817 throw ArgumentException(u"Invalid buffer length");
818
819 if (count == 0)
820 return;
821
822 if (sizeof(char_type) == 1)
823 {
824 m_stream.rdbuf()->sputn((const char_type*)&buffer[offset], count);
826 {
827 m_byte_pos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
828 }
829
830 Sync();
831 return;
832 }
833
835 {
836 std::vector<char_type> tempbuff(count, 0);
837 auto dst = tempbuff.data();
838 std::for_each(buffer.begin() + offset, buffer.begin() + offset + count,
839 [&dst, this](uint8_t& byte) { *(dst++) = char_type(byte); });
840 m_stream.rdbuf()->sputn(tempbuff.data(), count);
841
842 Sync();
843 }
844 else
845 { // m_wrapping_mode == STDIOStreamWrappingMode::Binary
846 if (m_decoded_elem == nullptr)
847 {
848 m_decoded_elem = MakeArray<uint8_t>(m_elem_size, 0);
849 }
850
851 uint8_t* source = &buffer[offset];
852 uint8_t byte_pos_shift = m_byte_pos % m_elem_size;
853 m_byte_pos += count;
854
855 if (byte_pos_shift != 0)
856 {
857 for (; count > 0 && byte_pos_shift != 0; ++source, --count, ++byte_pos_shift %= m_elem_size)
858 { // Append to the remaining memory cells of the decoded_elem.
859 m_decoded_elem[byte_pos_shift] = *source;
860 }
861
862 m_stream.rdbuf()->sputc(EncodeElem());
863
864 if (byte_pos_shift != 0)
865 { // New byte position is previous element position.
866 m_stream.rdbuf()->pubseekoff(-1, std::ios_base::cur, std::ios_base::out);
867
868 Sync();
869 return;
870 }
871 }
872
873 int elem_count = count / m_elem_size;
874 if (elem_count != 0)
875 { // Encode and put elem_count elements into stream.
876 std::vector<char_type> tempbuff(elem_count, 0);
877 char_type* destination = tempbuff.data();
878 for (; count >= m_elem_size; source += m_elem_size, ++destination, count -= m_elem_size)
879 {
880 EncodeElem(source, destination);
881 }
882
883 m_stream.rdbuf()->sputn(tempbuff.data(), elem_count);
884 }
885
886 DecodeElem(m_stream.rdbuf()->sgetc());
887
888 if (count != 0)
889 { // There are unwritten bytes. Write bytes in decoded_elem, encode it and put result in the stream.
890 if (m_decoded_elem == nullptr)
891 {
892 m_decoded_elem = MakeArray<uint8_t>(m_elem_size, 0);
893 }
894
895 for (; count > 0; ++source, --count, ++byte_pos_shift %= m_elem_size)
896 {
897 m_decoded_elem[byte_pos_shift] = *source;
898 }
899
900 m_stream.rdbuf()->sputc(EncodeElem());
901 m_stream.rdbuf()->pubseekoff(-1, std::ios_base::cur, std::ios_base::out);
902 }
903
904 Sync();
905 }
906 }
907
910 virtual void SetLength(int64_t value) override
911 {
912 throw NotSupportedException(ASPOSE_CURRENT_FUNCTION);
913 }
914
916 virtual void Flush() override
917 {
918 Check();
919
920 if (!get_CanWrite())
921 throw NotSupportedException(u"Can't write to stream.");
922
923 m_stream.rdbuf()->pubsync();
924 }
925
926protected:
930 virtual int64_t Pubseekpos(int64_t value) override
931 {
932 return m_stream.rdbuf()->pubseekpos(value, std::ios_base::out);
933 }
934
936 virtual void Check() const override
937 {
939 auto elem_ppos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
940 if (m_stream.fail() || m_last_elem_ppos != elem_ppos)
941 {
942 if (!m_stream.fail())
943 {
944 m_stream.setstate(std::ios_base::failbit);
945 }
946
947 throw IOException(u"The stream has been modified outside the wrapper.");
948 }
949 }
950
952 virtual void Sync() override
953 {
954 auto elem_ppos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
955 if (m_last_elem_ppos != elem_ppos)
956 {
957 m_elem_pos = elem_ppos;
959 if (m_elem_pos > m_length)
960 {
962 }
963 }
964 }
965
969
975 using BaseType::m_length;
976 using BaseType::m_stream;
978};
979
985template <typename T, typename = std::enable_if_t<IsTemplateBaseOf<std::basic_iostream, T>::value>>
987{
988public:
993 using ThisTypeBaseTypesInfo = BaseTypesInfo<BaseIType, BaseOType>;
996
997public:
1000
1005 BasicSTDIOStreamWrapper(std::basic_iostream<char_type, traits_type>& str,
1008 : BaseType(str, mode, true, true, true, pref_pos), BaseIType(str, mode), BaseOType(str, mode)
1009 {}
1010
1013
1016
1020 virtual int ReadByte() override
1021 {
1022 return BaseIType::ReadByte();
1023 }
1024
1028 virtual void WriteByte(uint8_t value) override
1029 {
1030 BaseOType::WriteByte(value);
1031 }
1032
1040 virtual int32_t Read(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
1041 {
1042 return Read(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
1043 }
1044
1051 virtual void Write(const ArrayPtr<uint8_t>& buffer, int32_t offset, int32_t count) override
1052 {
1053 Write(static_cast<System::Details::ArrayView<uint8_t>>(buffer), offset, count);
1054 }
1055
1061 virtual int32_t Read(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
1062 {
1063 return BaseIType::Read(buffer, offset, count);
1064 }
1065
1070 virtual void Write(const System::Details::ArrayView<uint8_t>& buffer, int32_t offset, int32_t count) override
1071 {
1072 BaseOType::Write(buffer, offset, count);
1073 }
1074
1077 virtual void SetLength(int64_t value) override
1078 {
1079 BaseOType::SetLength(value);
1080 }
1081
1083 virtual void Flush() override
1084 {
1086 }
1087
1088protected:
1092 virtual int64_t Pubseekpos(int64_t value)
1093 {
1094 m_stream.rdbuf()->pubseekpos(value, std::ios_base::in);
1095 return m_stream.rdbuf()->pubseekpos(value, std::ios_base::out);
1096 }
1097
1099 virtual void Check() const
1100 {
1102 auto elem_gpos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
1103 auto elem_ppos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
1104 if (m_stream.fail() || m_last_elem_gpos != elem_gpos || m_last_elem_ppos != elem_ppos || elem_gpos != elem_ppos)
1105 {
1106 if (!m_stream.fail())
1107 {
1108 m_stream.setstate(std::ios_base::failbit);
1109 }
1110
1111 throw IOException(u"The stream has been modified outside the wrapper.");
1112 }
1113 }
1114
1116 virtual void Sync()
1117 {
1118 auto elem_gpos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
1119 auto elem_ppos = m_stream.rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
1120 if (m_last_elem_gpos != elem_gpos || m_last_elem_ppos != elem_ppos)
1121 {
1122 if (m_last_elem_gpos != elem_gpos)
1123 {
1124 m_last_elem_gpos = elem_gpos;
1125 if (elem_ppos != elem_gpos)
1126 {
1127 m_last_elem_ppos = m_stream.rdbuf()->pubseekpos(elem_gpos, std::ios_base::out);
1128 }
1129 else
1130 {
1131 m_last_elem_ppos = elem_gpos;
1132 }
1133
1134 m_elem_pos = elem_gpos;
1135 }
1136 else
1137 {
1138 m_last_elem_ppos = elem_ppos;
1139 if (elem_gpos != elem_ppos)
1140 {
1141 m_last_elem_gpos = m_stream.rdbuf()->pubseekpos(elem_ppos, std::ios_base::in);
1142 }
1143 else
1144 {
1145 m_last_elem_gpos = elem_ppos;
1146 }
1147
1148 m_elem_pos = elem_ppos;
1149 }
1150
1151 if (m_elem_pos > m_length)
1152 {
1154 }
1155 }
1156 }
1157
1161 using BaseType::m_length;
1162 using BaseType::m_stream;
1163};
1164
1169template <typename char_type, typename traits_type>
1170SharedPtr<Stream> WrapSTDIOStream(std::basic_istream<char_type, traits_type>& stream,
1172{
1173 return MakeObject<BasicSTDIStreamWrapper<std::basic_istream<char_type, traits_type>>>(stream, mode);
1174}
1175
1180template <typename char_type, typename traits_type>
1181SharedPtr<Stream> WrapSTDIOStream(std::basic_ostream<char_type, traits_type>& stream,
1183{
1184 return MakeObject<BasicSTDOStreamWrapper<std::basic_ostream<char_type, traits_type>>>(stream, mode);
1185}
1186
1192template <typename char_type, typename traits_type>
1193SharedPtr<Stream> WrapSTDIOStream(std::basic_iostream<char_type, traits_type>& stream,
1196{
1197 return MakeObject<BasicSTDIOStreamWrapper<std::basic_iostream<char_type, traits_type>>>(stream, mode);
1198}
1199
1212
1213}} // namespace System::IO
static bool _IsLittleEndian()
Indicates the endianness of the current architecture.
static System::ArrayPtr< uint8_t > GetBytes(bool value)
Converts the specified boolean value into an array of bytes.
Represents a System.IO.Stream-like wrapper for std::basic_iostream and its derived objects....
Definition: std_stream_wrappers.h:987
virtual void Sync()
Syncronize read and write positions.
Definition: std_stream_wrappers.h:1116
virtual int64_t Pubseekpos(int64_t value)
Seeks positions of read or write or both on value.
Definition: std_stream_wrappers.h:1092
BasicSTDIOStreamWrapper & operator=(const BasicSTDIOStreamWrapper &)=delete
Copy assignment operator. Deleted.
virtual void Write(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Writes the specified subrange of bytes from the specified byte array to the stream.
Definition: std_stream_wrappers.h:1070
virtual int32_t Read(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, reads the specified number of bytes from the stream, otherwise read the s...
Definition: std_stream_wrappers.h:1040
virtual void Flush() override
Clears this stream's buffers and writes all buffered data to the underlying storage.
Definition: std_stream_wrappers.h:1083
virtual int ReadByte() override
If wrapping mode is binary, reads a single byte from the last decoded character storage,...
Definition: std_stream_wrappers.h:1020
virtual void Write(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, writes to the stream the specified subrange of bytes from the specified b...
Definition: std_stream_wrappers.h:1051
BasicSTDIOStreamWrapper(const BasicSTDIOStreamWrapper &)=delete
Copy constructor. Deleted.
virtual void WriteByte(uint8_t value) override
If wrapping mode is binary, writes to the stream the specified unsigned 8-bit integer value,...
Definition: std_stream_wrappers.h:1028
BasicSTDIOStreamWrapper(std::basic_iostream< char_type, traits_type > &str, STDIOStreamWrappingMode mode=STDIOStreamWrappingMode::Binary, STDIOStreamPositionPreference pref_pos=STDIOStreamPositionPreference::Zero)
Constructs a new instance of the BasicSTDIOStreamWrapper.
Definition: std_stream_wrappers.h:1005
virtual int32_t Read(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Reads the specified number of bytes from the stream and writes them to the specified byte array.
Definition: std_stream_wrappers.h:1061
virtual void SetLength(int64_t value) override
Sets the length of the stream represented by the current object.
Definition: std_stream_wrappers.h:1077
RTTI_INFO_TEMPLATE_CLASS(ThisType, ThisTypeBaseTypesInfo)
RTTI information.
virtual void Check() const
Check if the stream has been modified outside the wrapper.
Definition: std_stream_wrappers.h:1099
Represents a System.IO.Stream-like wrapper for std::basic_istream and its derived objects....
Definition: std_stream_wrappers.h:422
virtual void Flush() override
Clears this stream's buffers and writes all buffered data to the underlying storage....
Definition: std_stream_wrappers.h:633
virtual void SetLength(int64_t value) override
Sets the length of the stream represented by the current object. Not supported!
Definition: std_stream_wrappers.h:627
virtual void Check() const override
Check if the stream has been modified outside the wrapper.
Definition: std_stream_wrappers.h:648
virtual int32_t Read(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Reads the specified number of bytes from the stream and writes them to the specified byte array.
Definition: std_stream_wrappers.h:537
virtual int32_t Read(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, reads the specified number of bytes from the stream, otherwise read the s...
Definition: std_stream_wrappers.h:516
virtual bool get_CanRead() const=0
Determines if the stream is readable.
virtual void WriteByte(uint8_t value) override
If wrapping mode is binary, writes to the stream the specified unsigned 8-bit integer value,...
Definition: std_stream_wrappers.h:504
BasicSTDIStreamWrapper & operator=(const BasicSTDIStreamWrapper &)=delete
Copy assignment operator. Deleted.
RTTI_INFO_TEMPLATE_CLASS(ThisType, ThisTypeBaseTypesInfo)
RTTI information.
virtual void Write(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Writes the specified subrange of bytes from the specified byte array to the stream.
Definition: std_stream_wrappers.h:620
virtual void Write(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, writes to the stream the specified subrange of bytes from the specified b...
Definition: std_stream_wrappers.h:527
BasicSTDIStreamWrapper(const BasicSTDIStreamWrapper &)=delete
Copy constructor. Deleted.
virtual void Sync() override
Syncronize read position.
Definition: std_stream_wrappers.h:664
virtual int64_t Pubseekpos(int64_t value) override
Seeks positions of read or write or both on value.
Definition: std_stream_wrappers.h:642
BasicSTDIStreamWrapper(std::basic_istream< char_type, traits_type > &str, STDIOStreamWrappingMode mode=STDIOStreamWrappingMode::Binary)
Constructs a new instance of the BasicSTDIStreamWrapper.
Definition: std_stream_wrappers.h:437
virtual int ReadByte() override
If wrapping mode is binary, reads a single byte from the last decoded character storage,...
Definition: std_stream_wrappers.h:451
Represents a System.IO.Stream-like wrapper for std::basic_ostream and its derived objects....
Definition: std_stream_wrappers.h:693
virtual void Write(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, writes to the stream the specified subrange of bytes from the specified b...
Definition: std_stream_wrappers.h:785
RTTI_INFO_TEMPLATE_CLASS(ThisType, ThisTypeBaseTypesInfo)
RTTI information.
virtual int32_t Read(const ArrayPtr< uint8_t > &buffer, int32_t offset, int32_t count) override
If wrapping mode is binary, reads the specified number of bytes from the stream, otherwise read the s...
Definition: std_stream_wrappers.h:774
BasicSTDOStreamWrapper(const BasicSTDOStreamWrapper &)=delete
Copy constructor. Deleted.
virtual void Flush() override
Clears this stream's buffers and writes all buffered data to the underlying storage.
Definition: std_stream_wrappers.h:916
virtual int32_t Read(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Reads the specified number of bytes from the stream and writes them to the specified byte array.
Definition: std_stream_wrappers.h:795
virtual void Check() const override
Check if the stream has been modified outside the wrapper.
Definition: std_stream_wrappers.h:936
virtual void WriteByte(uint8_t value) override
If wrapping mode is binary, writes to the stream the specified unsigned 8-bit integer value,...
Definition: std_stream_wrappers.h:730
virtual bool get_CanWrite() const=0
Determines if the stream is writable.
virtual void Sync() override
Syncronize write position.
Definition: std_stream_wrappers.h:952
typename BaseType::char_type char_type
Definition: std_stream_wrappers.h:702
virtual int64_t Pubseekpos(int64_t value) override
Seeks positions of read or write or both on value.
Definition: std_stream_wrappers.h:930
virtual int ReadByte() override
If wrapping mode is binary, reads a single byte from the last decoded character storage,...
Definition: std_stream_wrappers.h:722
virtual void Write(const System::Details::ArrayView< uint8_t > &buffer, int32_t offset, int32_t count) override
Writes the specified subrange of bytes from the specified byte array to the stream.
Definition: std_stream_wrappers.h:804
BasicSTDOStreamWrapper(std::basic_ostream< char_type, traits_type > &str, STDIOStreamWrappingMode mode=STDIOStreamWrappingMode::Binary)
Constructs a new instance of the BasicSTDOStreamWrapper.
Definition: std_stream_wrappers.h:708
virtual void SetLength(int64_t value) override
Sets the length of the stream represented by the current object.
Definition: std_stream_wrappers.h:910
BasicSTDOStreamWrapper & operator=(const BasicSTDOStreamWrapper &)=delete
Copy assignment operator. Deleted.
Represents a base class for System.IO.Stream-like wrappers. Objects of this class should only be allo...
Definition: std_stream_wrappers.h:44
virtual bool get_CanWrite() const override
Determines if the stream supports writing.
Definition: std_stream_wrappers.h:234
int64_t m_byte_pos
Read/write position in bytes.
Definition: std_stream_wrappers.h:407
typename T::off_type off_type
Definition: std_stream_wrappers.h:58
int64_t m_elem_pos
Read/write position.
Definition: std_stream_wrappers.h:405
STDIOStreamWrapperBase & operator=(const STDIOStreamWrapperBase &)=delete
Copy assignment operator. Deleted.
int64_t m_length
Stream's length.
Definition: std_stream_wrappers.h:409
STDIOStreamWrapperBase(const STDIOStreamWrapperBase &)=delete
Copy constructor. Deleted.
virtual void set_Position(int64_t value) override
Sets the stream's position.
Definition: std_stream_wrappers.h:145
virtual bool get_CanRead() const override
Determines if the stream supports reading.
Definition: std_stream_wrappers.h:222
void DecodeElem(int_type meta, ArrayPtr< uint8_t > &destination)
Decodes meta and store result in the destination.
Definition: std_stream_wrappers.h:343
char_type EncodeElem(uint8_t *source)
Encodes source.
Definition: std_stream_wrappers.h:365
const bool m_can_read
CanRead flag.
Definition: std_stream_wrappers.h:393
RTTI_INFO_TEMPLATE_CLASS(ThisType, ThisTypeBaseTypesInfo)
RTTI information.
ArrayPtr< uint8_t > m_decoded_elem
The last decoded element storage.
Definition: std_stream_wrappers.h:412
std::basic_ios< char_type, traits_type > & m_stream
Reference to the stream.
Definition: std_stream_wrappers.h:389
typename T::pos_type pos_type
Definition: std_stream_wrappers.h:57
virtual bool get_CanSeek() const override
Determines if the stream supports seeking.
Definition: std_stream_wrappers.h:228
virtual void Sync()=0
Synchronizes positions of read or write or both.
typename T::int_type int_type
Definition: std_stream_wrappers.h:56
virtual int64_t get_Position() const override
Returns current position of the stream.
Definition: std_stream_wrappers.h:186
void DecodeElem(int_type meta)
Decodes meta and store result in the last decoded element storage.
Definition: std_stream_wrappers.h:335
int64_t m_last_elem_ppos
Last write position.
Definition: std_stream_wrappers.h:403
const STDIOStreamWrappingMode m_wrapping_mode
Wrapping mode.
Definition: std_stream_wrappers.h:391
STDIOStreamWrapperBase(std::basic_ios< char_type, traits_type > &str, STDIOStreamWrappingMode mode=STDIOStreamWrappingMode::Binary, bool can_read=false, bool can_write=false, bool can_seek=false, STDIOStreamPositionPreference pref_pos=STDIOStreamPositionPreference::Zero)
Constructs a new instance of the STDIOStreamWrapperBase.
Definition: std_stream_wrappers.h:247
virtual int64_t Seek(int64_t offset, SeekOrigin origin) override
Sets the position of the stream represented by the current object.
Definition: std_stream_wrappers.h:70
const bool m_can_write
CanWrite flag.
Definition: std_stream_wrappers.h:395
const bool m_can_seek
CanSeek flag.
Definition: std_stream_wrappers.h:397
static constexpr uint8_t m_elem_size
char_type size = sizeof(char_type).
Definition: std_stream_wrappers.h:399
virtual int64_t get_Length() const override
Returns length of the stream.
Definition: std_stream_wrappers.h:204
BaseTypesInfo< BaseType > ThisTypeBaseTypesInfo
Definition: std_stream_wrappers.h:48
int64_t m_last_elem_gpos
Last read position.
Definition: std_stream_wrappers.h:401
typename T::char_type char_type
Definition: std_stream_wrappers.h:53
typename T::traits_type traits_type
Definition: std_stream_wrappers.h:54
virtual int64_t Pubseekpos(int64_t value)=0
Seeks positions of read or write or both on value.
char_type EncodeElem()
Encodes the last decoded element storage.
Definition: std_stream_wrappers.h:357
virtual void Check() const
Check if the stream has been modified outside the wrapper.
Definition: std_stream_wrappers.h:324
void EncodeElem(uint8_t *source, char_type *destination)
Encodes source to destination.
Definition: std_stream_wrappers.h:375
A base class for a variety of stream implementations. Objects of this class should only be allocated ...
Definition: stream.h:24
Pointer class to wrap types being allocated on heap. Use it to manage memory for classes inheriting O...
Definition: smart_ptr.h:180
void reset(Pointee_ *ptr)
Sets pointed object.
Definition: smart_ptr.h:530
STDIOStreamPositionPreference
Determines which position in the stream is preferable as a common read and write position when std::b...
Definition: std_stream_wrappers.h:28
@ WritePosition
pptr position will sets as a read and write position.
@ ReadPosition
gptr position will sets as a read and write position.
@ Zero
Zero position will sets as a read and write position.
SharedPtr< Stream > WrapSTDIOStream(std::basic_istream< char_type, traits_type > &stream, STDIOStreamWrappingMode mode=STDIOStreamWrappingMode::Binary)
Wrapper function for std::basic_istream-like streams.
Definition: std_stream_wrappers.h:1170
STDIOStreamWrappingMode
Specifies the mode of I/O operations that wrappers will perform on std::iostreams-like streams.
Definition: std_stream_wrappers.h:16
@ Conversion
A mode that allows input operations to convert stream data from char_type type to uint8_t type and vi...
@ Binary
A mode that allows input operations to decode stream data of char_type type into bytes,...
SeekOrigin
Specifies the reference position in the stream relative to which the position to seek to is specified...
Definition: seekorigin.h:11
@ Begin
Beginning of the stream.
@ Current
Current stream position.
@ End
End of the stream.
Definition: db_command.h:9