Skip to content

Commit ebce059

Browse files
committed
fix: feature DETECT_STDOUT_ENCODING fixes #1 fixes #2
1 parent f7e0d48 commit ebce059

File tree

3 files changed

+73
-42
lines changed

3 files changed

+73
-42
lines changed

Editor/ConsoleUtils.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,16 @@ public static string ScanColorLog(string input, ColorMarkVisitor visitor)
8787
/// </summary>
8888
/// <param name="bytes"></param>
8989
/// <returns></returns>
90-
public unsafe static bool IsUTF8InsteadOf16(byte[] bytes)
90+
public unsafe static bool IsValidUTF8(byte[] bytes, int index, int count)
9191
{
92-
if (bytes.Length % 2 != 0) return true; // distinguish from utf-16 only
93-
if (!bytes.Any(b => b == 0))
94-
{
95-
_ = 0;
96-
}
92+
// if (bytes.Length % 2 != 0) return true; // distinguish from utf-16 only
9793
var c = 0;
98-
foreach (var b in bytes)
94+
for (int i = index; i < index + count; i++)
9995
{
96+
var b = bytes[i];
97+
if (b == 0)
98+
return false;
99+
100100
if (c != 0)
101101
{
102102
c--;

Editor/Shell.cs

+66-27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using System.Threading;
1010
using System.Collections.Concurrent;
1111
using System.Runtime.InteropServices;
12+
using System.Buffers;
13+
using System.Linq;
1214

1315
namespace com.bbbirder.unityeditor
1416
{
@@ -55,6 +57,7 @@ public struct ShellSettings
5557

5658
public static class Shell
5759
{
60+
readonly static Encoding DEFAULT_WINDOWS_CONSOLE_ENCODING = Encoding.GetEncoding("gbk");
5861
public static Dictionary<string, string> DefaultEnvironment = new();
5962
internal static ConcurrentQueue<(ShellRequest req, LogEventType type, object arg)> queue = new();
6063
public static Dictionary<ShellRequest, StringBuilder> lineBuilders = new();
@@ -135,14 +138,14 @@ static Process CreateProcess(string cmd, string workDirectory = ".", Dictionary<
135138
start.RedirectStandardError =
136139
start.RedirectStandardInput = true;
137140

138-
// start.StandardInputEncoding =
139-
// start.StandardOutputEncoding =
140-
// start.StandardErrorEncoding =
141-
// #if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
142-
// Encoding.Unicode;
143-
// #else
144-
// Encoding.UTF8;
145-
// #endif
141+
start.StandardInputEncoding =
142+
start.StandardOutputEncoding =
143+
start.StandardErrorEncoding =
144+
#if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
145+
Encoding.Unicode;
146+
#else
147+
Encoding.UTF8;
148+
#endif
146149

147150
start.ArgumentList.Clear();
148151
foreach (var arg in args)
@@ -179,7 +182,7 @@ public static ShellRequest RunCommand(string cmd, ShellSettings? settings = defa
179182
"@echo off>nul\n" +
180183
#endif
181184
#if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
182-
"@chcp 65001>nul\n"
185+
"@chcp 65001>nul\n" +
183186
#endif
184187
cmd;
185188

@@ -222,6 +225,56 @@ public static ShellRequest RunCommandLine(string executable, params object[] arg
222225
return RunCommandLine(executable, ShellSettings.Default, args);
223226
}
224227

228+
static IEnumerable<string> GetConsoleOutput(StreamReader console)
229+
{
230+
const int BUFFER_SIZE = 40960;
231+
var buffer = ArrayPool<byte>.Shared.Rent(BUFFER_SIZE);
232+
while (!console.EndOfStream)
233+
{
234+
var index = 0;
235+
var wchar = console.CurrentEncoding == Encoding.Unicode;
236+
while (console.Peek() != -1)
237+
{
238+
var b = console.Read();
239+
if (wchar)
240+
{
241+
if (index + 2 < buffer.Length)
242+
{
243+
if (BitConverter.IsLittleEndian)
244+
{
245+
buffer[index++] = (byte)(b & 0xff);
246+
buffer[index++] = (byte)(b >> 8);
247+
}
248+
else
249+
{
250+
buffer[index++] = (byte)(b >> 8);
251+
buffer[index++] = (byte)(b & 0xff);
252+
}
253+
}
254+
}
255+
else
256+
{
257+
if (index + 1 < buffer.Length)
258+
{
259+
buffer[index++] = (byte)b;
260+
}
261+
}
262+
}
263+
264+
var encoding = Encoding.UTF8;
265+
#if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
266+
UnityEngine.Debug.Log(string.Join(',', buffer.Select(b => b.ToString("x2")).ToArray(), 0, index));
267+
UnityEngine.Debug.Log(ConsoleUtils.IsValidUTF8(buffer, 0, index) + " " + index);
268+
if (!ConsoleUtils.IsValidUTF8(buffer, 0, index))
269+
{
270+
encoding = DEFAULT_WINDOWS_CONSOLE_ENCODING;
271+
}
272+
#endif
273+
var output = encoding.GetString(buffer, 0, index);
274+
yield return output;
275+
}
276+
ArrayPool<byte>.Shared.Return(buffer);
277+
}
225278

226279
static ShellRequest QueueUpProcess(Process p, string cmd, ShellSettings settings)
227280
{
@@ -232,32 +285,18 @@ static ShellRequest QueueUpProcess(Process p, string cmd, ShellSettings settings
232285
{
233286
try
234287
{
235-
var builder = new StringBuilder();
236-
237-
while (!p.StandardOutput.EndOfStream)
288+
foreach (var output in GetConsoleOutput(p.StandardOutput))
238289
{
239-
while (p.StandardOutput.Peek() > -1)
240-
{
241-
builder.Append((char)p.StandardOutput.Read());
242-
}
243-
var output = builder.ToString();
244-
builder.Clear();
245290
queue.Enqueue((req, LogEventType.InfoLog, output));
246291
}
247292

248-
while (!p.StandardError.EndOfStream)
293+
foreach (var output in GetConsoleOutput(p.StandardError))
249294
{
250-
string error = p.StandardError.ReadLine();
251-
252-
if (!string.IsNullOrEmpty(error))
253-
{
254-
if (!string.IsNullOrEmpty(error))
255-
queue.Enqueue((req, LogEventType.ErrorLog, error));
256-
}
295+
if (!string.IsNullOrEmpty(output))
296+
queue.Enqueue((req, LogEventType.ErrorLog, output));
257297
}
258298

259299
queue.Enqueue((req, LogEventType.EndStream, p.ExitCode));
260-
261300
}
262301
catch (Exception e)
263302
{

Editor/ShellRequest.cs

-8
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,6 @@ void OnLog(LogEventType type, string log)
149149
{
150150
result.AppendLine(type, log);
151151

152-
#if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
153-
var bytes = Encoding.Unicode.GetBytes(log);
154-
if (ConsoleUtils.IsUTF8InsteadOf16(bytes))
155-
{
156-
log = Encoding.UTF8.GetString(bytes);
157-
}
158-
#endif
159-
160152
onLog?.Invoke(type, log);
161153

162154
if (!settings.quiet)

0 commit comments

Comments
 (0)