1#pragma once
2
3#include "basis/seadTypes.h"
4#include "prim/seadSafeString.h"
5#include "stream/seadBufferStream.h"
6
7namespace sead
8{
9class PrintFormatter;
10class StreamSrc;
11
12// region Print outputs
13class PrintOutput
14{
15public:
16 virtual ~PrintOutput() = default;
17 virtual void write(const char* string, s32 size) = 0;
18 void writeLineBreak();
19 PrintFormatter& operator<<(PrintFormatter& formatter);
20};
21
22class StringPrintOutput : public PrintOutput
23{
24public:
25 explicit StringPrintOutput(BufferedSafeString* buffer);
26 ~StringPrintOutput() override = default;
27 void write(const char* string, s32 size) override;
28
29protected:
30 BufferedSafeString* mBuffer;
31 s32 mPos;
32};
33
34class StringCutOffPrintOutput : public PrintOutput
35{
36public:
37 explicit StringCutOffPrintOutput(BufferedSafeString* buffer);
38 ~StringCutOffPrintOutput() override = default;
39 void write(const char* string, s32 size) override;
40
41protected:
42 BufferedSafeString* mBuffer;
43 s32 mPos;
44};
45
46class StreamPrintOutput : public PrintOutput
47{
48public:
49 explicit StreamPrintOutput(StreamSrc* src);
50 ~StreamPrintOutput() override;
51 void write(const char* string, s32 size) override;
52
53protected:
54 StreamSrc* mSrc;
55};
56
57class BufferingPrintOutput : public PrintOutput
58{
59public:
60 BufferingPrintOutput(char* buffer, u32 buffer_size);
61 ~BufferingPrintOutput() override;
62 void write(const char* string, s32 size) override;
63
64protected:
65 BufferMultiByteNullTerminatedTextWriteStreamSrc mSrc;
66};
67// endregion
68
69// region Print formatters
70
71class PrintFormatter
72{
73public:
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
105protected:
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
117inline PrintFormatter& flush(PrintFormatter& formatter)
118{
119 formatter.flush();
120 return formatter;
121}
122
123class StringPrintFormatter : public PrintFormatter
124{
125public:
126 explicit StringPrintFormatter(BufferedSafeString* string);
127 StringPrintFormatter(BufferedSafeString* string, const char*);
128
129protected:
130 StringPrintOutput mOutput;
131};
132
133class StringCutOffPrintFormatter : public PrintFormatter
134{
135public:
136 explicit StringCutOffPrintFormatter(BufferedSafeString* string);
137 StringCutOffPrintFormatter(BufferedSafeString* string, const char*);
138
139protected:
140 StringCutOffPrintOutput mOutput;
141};
142
143class StreamPrintFormatter : public PrintFormatter
144{
145public:
146 explicit StreamPrintFormatter(StreamSrc* src);
147 StreamPrintFormatter(StreamSrc* src, const char*);
148 void flushAndWriteNullChar();
149
150protected:
151 StreamPrintOutput mOutput;
152};
153
154class BufferingPrintFormatter : public PrintFormatter
155{
156public:
157 BufferingPrintFormatter();
158 explicit BufferingPrintFormatter(const char*);
159
160protected:
161 BufferingPrintOutput mOutput;
162 char mBuffer[128];
163};
164// endregion
165} // namespace sead
166