| 1 | #pragma once |
| 2 | |
| 3 | #include "basis/seadTypes.h" |
| 4 | #include "prim/seadSafeString.h" |
| 5 | #include "stream/seadBufferStream.h" |
| 6 | |
| 7 | namespace sead |
| 8 | { |
| 9 | class PrintFormatter; |
| 10 | class StreamSrc; |
| 11 | |
| 12 | // region Print outputs |
| 13 | class PrintOutput |
| 14 | { |
| 15 | public: |
| 16 | virtual ~PrintOutput() = default; |
| 17 | virtual void write(const char* string, s32 size) = 0; |
| 18 | void writeLineBreak(); |
| 19 | PrintFormatter& operator<<(PrintFormatter& formatter); |
| 20 | }; |
| 21 | |
| 22 | class StringPrintOutput : public PrintOutput |
| 23 | { |
| 24 | public: |
| 25 | explicit StringPrintOutput(BufferedSafeString* buffer); |
| 26 | ~StringPrintOutput() override = default; |
| 27 | void write(const char* string, s32 size) override; |
| 28 | |
| 29 | protected: |
| 30 | BufferedSafeString* mBuffer; |
| 31 | s32 mPos; |
| 32 | }; |
| 33 | |
| 34 | class StringCutOffPrintOutput : public PrintOutput |
| 35 | { |
| 36 | public: |
| 37 | explicit StringCutOffPrintOutput(BufferedSafeString* buffer); |
| 38 | ~StringCutOffPrintOutput() override = default; |
| 39 | void write(const char* string, s32 size) override; |
| 40 | |
| 41 | protected: |
| 42 | BufferedSafeString* mBuffer; |
| 43 | s32 mPos; |
| 44 | }; |
| 45 | |
| 46 | class StreamPrintOutput : public PrintOutput |
| 47 | { |
| 48 | public: |
| 49 | explicit StreamPrintOutput(StreamSrc* src); |
| 50 | ~StreamPrintOutput() override; |
| 51 | void write(const char* string, s32 size) override; |
| 52 | |
| 53 | protected: |
| 54 | StreamSrc* mSrc; |
| 55 | }; |
| 56 | |
| 57 | class BufferingPrintOutput : public PrintOutput |
| 58 | { |
| 59 | public: |
| 60 | BufferingPrintOutput(char* buffer, u32 buffer_size); |
| 61 | ~BufferingPrintOutput() override; |
| 62 | void write(const char* string, s32 size) override; |
| 63 | |
| 64 | protected: |
| 65 | BufferMultiByteNullTerminatedTextWriteStreamSrc mSrc; |
| 66 | }; |
| 67 | // endregion |
| 68 | |
| 69 | // region Print formatters |
| 70 | |
| 71 | class PrintFormatter |
| 72 | { |
| 73 | public: |
| 74 | template <typename T, template <typename> class Class> |
| 75 | class OutImpl |
| 76 | { |
| 77 | public: |
| 78 | static void out(const Class<T>&, const char*, PrintOutput* output); |
| 79 | }; |
| 80 | |
| 81 | PrintFormatter(const char*, PrintOutput* output); |
| 82 | |
| 83 | void setPrintOutput(PrintOutput* output); |
| 84 | |
| 85 | void flush(); |
| 86 | void flushWithLineBreak(); |
| 87 | |
| 88 | PrintFormatter& operator,(s8); |
| 89 | PrintFormatter& operator,(u8); |
| 90 | PrintFormatter& operator,(s16); |
| 91 | PrintFormatter& operator,(u16); |
| 92 | PrintFormatter& operator,(s32); |
| 93 | PrintFormatter& operator,(u32); |
| 94 | PrintFormatter& operator<<(char*); |
| 95 | PrintFormatter& operator<<(const char*); |
| 96 | |
| 97 | PrintFormatter& operator<<(PrintFormatter& (&fn)(PrintFormatter&)) { return fn(*this); } |
| 98 | |
| 99 | template <typename T> |
| 100 | PrintFormatter& operator,(const T&); |
| 101 | |
| 102 | template <typename T> |
| 103 | void out(const T&, const char*, PrintOutput* output); |
| 104 | |
| 105 | protected: |
| 106 | bool proceedToFormatMark_(char*); |
| 107 | static void outputString_(const char*, PrintOutput*, const char*, s32); |
| 108 | static void outputPtr_(const char*, PrintOutput*, uintptr_t); |
| 109 | |
| 110 | const char* mFormatStr; |
| 111 | class PrintOutput* mPrintOutput; |
| 112 | s32 mPos; |
| 113 | s32 mFormatStrLength; |
| 114 | bool mX; |
| 115 | }; |
| 116 | |
| 117 | inline PrintFormatter& flush(PrintFormatter& formatter) |
| 118 | { |
| 119 | formatter.flush(); |
| 120 | return formatter; |
| 121 | } |
| 122 | |
| 123 | class StringPrintFormatter : public PrintFormatter |
| 124 | { |
| 125 | public: |
| 126 | explicit StringPrintFormatter(BufferedSafeString* string); |
| 127 | StringPrintFormatter(BufferedSafeString* string, const char*); |
| 128 | |
| 129 | protected: |
| 130 | StringPrintOutput mOutput; |
| 131 | }; |
| 132 | |
| 133 | class StringCutOffPrintFormatter : public PrintFormatter |
| 134 | { |
| 135 | public: |
| 136 | explicit StringCutOffPrintFormatter(BufferedSafeString* string); |
| 137 | StringCutOffPrintFormatter(BufferedSafeString* string, const char*); |
| 138 | |
| 139 | protected: |
| 140 | StringCutOffPrintOutput mOutput; |
| 141 | }; |
| 142 | |
| 143 | class StreamPrintFormatter : public PrintFormatter |
| 144 | { |
| 145 | public: |
| 146 | explicit StreamPrintFormatter(StreamSrc* src); |
| 147 | StreamPrintFormatter(StreamSrc* src, const char*); |
| 148 | void flushAndWriteNullChar(); |
| 149 | |
| 150 | protected: |
| 151 | StreamPrintOutput mOutput; |
| 152 | }; |
| 153 | |
| 154 | class BufferingPrintFormatter : public PrintFormatter |
| 155 | { |
| 156 | public: |
| 157 | BufferingPrintFormatter(); |
| 158 | explicit BufferingPrintFormatter(const char*); |
| 159 | |
| 160 | protected: |
| 161 | BufferingPrintOutput mOutput; |
| 162 | char mBuffer[128]; |
| 163 | }; |
| 164 | // endregion |
| 165 | } // namespace sead |
| 166 | |