Initial commit to new repository
This commit is contained in:
275
.decompiledproj/AxCopilot/Services/Agent/EncodingTool.cs
Normal file
275
.decompiledproj/AxCopilot/Services/Agent/EncodingTool.cs
Normal file
@@ -0,0 +1,275 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AxCopilot.Services.Agent;
|
||||
|
||||
public class EncodingTool : IAgentTool
|
||||
{
|
||||
public string Name => "encoding_tool";
|
||||
|
||||
public string Description => "Detect and convert file text encoding. Actions: 'detect' — detect file encoding (UTF-8, EUC-KR, etc.); 'convert' — convert file from one encoding to another; 'list' — list common encoding names.";
|
||||
|
||||
public ToolParameterSchema Parameters
|
||||
{
|
||||
get
|
||||
{
|
||||
ToolParameterSchema toolParameterSchema = new ToolParameterSchema();
|
||||
Dictionary<string, ToolProperty> dictionary = new Dictionary<string, ToolProperty>();
|
||||
ToolProperty obj = new ToolProperty
|
||||
{
|
||||
Type = "string",
|
||||
Description = "Action: detect, convert, list"
|
||||
};
|
||||
int num = 3;
|
||||
List<string> list = new List<string>(num);
|
||||
CollectionsMarshal.SetCount(list, num);
|
||||
Span<string> span = CollectionsMarshal.AsSpan(list);
|
||||
span[0] = "detect";
|
||||
span[1] = "convert";
|
||||
span[2] = "list";
|
||||
obj.Enum = list;
|
||||
dictionary["action"] = obj;
|
||||
dictionary["path"] = new ToolProperty
|
||||
{
|
||||
Type = "string",
|
||||
Description = "File path"
|
||||
};
|
||||
dictionary["from_encoding"] = new ToolProperty
|
||||
{
|
||||
Type = "string",
|
||||
Description = "Source encoding name (e.g. 'euc-kr', 'shift-jis'). Auto-detected if omitted."
|
||||
};
|
||||
dictionary["to_encoding"] = new ToolProperty
|
||||
{
|
||||
Type = "string",
|
||||
Description = "Target encoding name (default: 'utf-8')"
|
||||
};
|
||||
toolParameterSchema.Properties = dictionary;
|
||||
num = 1;
|
||||
List<string> list2 = new List<string>(num);
|
||||
CollectionsMarshal.SetCount(list2, num);
|
||||
CollectionsMarshal.AsSpan(list2)[0] = "action";
|
||||
toolParameterSchema.Required = list2;
|
||||
return toolParameterSchema;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default(CancellationToken))
|
||||
{
|
||||
string action = args.GetProperty("action").GetString() ?? "";
|
||||
if (action == "list")
|
||||
{
|
||||
return ListEncodings();
|
||||
}
|
||||
JsonElement pv;
|
||||
string rawPath = (args.TryGetProperty("path", out pv) ? (pv.GetString() ?? "") : "");
|
||||
if (string.IsNullOrEmpty(rawPath))
|
||||
{
|
||||
return ToolResult.Fail("'path'가 필요합니다.");
|
||||
}
|
||||
string path = (Path.IsPathRooted(rawPath) ? rawPath : Path.Combine(context.WorkFolder, rawPath));
|
||||
if (!context.IsPathAllowed(path))
|
||||
{
|
||||
return ToolResult.Fail("경로 접근 차단: " + path);
|
||||
}
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return ToolResult.Fail("파일 없음: " + path);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
string text = action;
|
||||
ToolResult result = ((text == "detect") ? DetectEncoding(path) : ((!(text == "convert")) ? ToolResult.Fail("Unknown action: " + action) : (await ConvertEncoding(path, args, context))));
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ToolResult.Fail("인코딩 처리 오류: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static ToolResult DetectEncoding(string path)
|
||||
{
|
||||
byte[] array = File.ReadAllBytes(path);
|
||||
Encoding encoding = DetectEncodingFromBytes(array);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
StringBuilder stringBuilder2 = stringBuilder;
|
||||
StringBuilder stringBuilder3 = stringBuilder2;
|
||||
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2);
|
||||
handler.AppendLiteral("File: ");
|
||||
handler.AppendFormatted(Path.GetFileName(path));
|
||||
stringBuilder3.AppendLine(ref handler);
|
||||
stringBuilder2 = stringBuilder;
|
||||
StringBuilder stringBuilder4 = stringBuilder2;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(12, 1, stringBuilder2);
|
||||
handler.AppendLiteral("Size: ");
|
||||
handler.AppendFormatted(array.Length, "N0");
|
||||
handler.AppendLiteral(" bytes");
|
||||
stringBuilder4.AppendLine(ref handler);
|
||||
stringBuilder2 = stringBuilder;
|
||||
StringBuilder stringBuilder5 = stringBuilder2;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(19, 1, stringBuilder2);
|
||||
handler.AppendLiteral("Detected Encoding: ");
|
||||
handler.AppendFormatted(encoding.EncodingName);
|
||||
stringBuilder5.AppendLine(ref handler);
|
||||
stringBuilder2 = stringBuilder;
|
||||
StringBuilder stringBuilder6 = stringBuilder2;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2);
|
||||
handler.AppendLiteral("Code Page: ");
|
||||
handler.AppendFormatted(encoding.CodePage);
|
||||
stringBuilder6.AppendLine(ref handler);
|
||||
stringBuilder2 = stringBuilder;
|
||||
StringBuilder stringBuilder7 = stringBuilder2;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder2);
|
||||
handler.AppendLiteral("BOM Present: ");
|
||||
handler.AppendFormatted(HasBom(array));
|
||||
stringBuilder7.AppendLine(ref handler);
|
||||
return ToolResult.Ok(stringBuilder.ToString());
|
||||
}
|
||||
|
||||
private static async Task<ToolResult> ConvertEncoding(string path, JsonElement args, AgentContext context)
|
||||
{
|
||||
JsonElement te;
|
||||
string toName = (args.TryGetProperty("to_encoding", out te) ? (te.GetString() ?? "utf-8") : "utf-8");
|
||||
if (!(await context.CheckWritePermissionAsync("encoding_tool", path)))
|
||||
{
|
||||
return ToolResult.Fail("파일 쓰기 권한이 거부되었습니다.");
|
||||
}
|
||||
Encoding fromEnc;
|
||||
if (args.TryGetProperty("from_encoding", out var fe) && !string.IsNullOrEmpty(fe.GetString()))
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
fromEnc = Encoding.GetEncoding(fe.GetString());
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] rawBytes = File.ReadAllBytes(path);
|
||||
fromEnc = DetectEncodingFromBytes(rawBytes);
|
||||
}
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
Encoding toEnc = Encoding.GetEncoding(toName);
|
||||
string content = File.ReadAllText(path, fromEnc);
|
||||
File.WriteAllText(path, content, toEnc);
|
||||
return ToolResult.Ok($"변환 완료: {fromEnc.EncodingName} → {toEnc.EncodingName}\nFile: {path}", path);
|
||||
}
|
||||
|
||||
private static ToolResult ListEncodings()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.AppendLine("주요 인코딩 목록:");
|
||||
stringBuilder.AppendLine(" utf-8 — UTF-8 (유니코드, 기본)");
|
||||
stringBuilder.AppendLine(" utf-16 — UTF-16 LE");
|
||||
stringBuilder.AppendLine(" utf-16BE — UTF-16 BE");
|
||||
stringBuilder.AppendLine(" euc-kr — EUC-KR (한국어)");
|
||||
stringBuilder.AppendLine(" ks_c_5601-1987 — 한글 완성형");
|
||||
stringBuilder.AppendLine(" shift_jis — Shift-JIS (일본어)");
|
||||
stringBuilder.AppendLine(" gb2312 — GB2312 (중국어 간체)");
|
||||
stringBuilder.AppendLine(" iso-8859-1 — Latin-1 (서유럽)");
|
||||
stringBuilder.AppendLine(" ascii — US-ASCII");
|
||||
stringBuilder.AppendLine(" utf-32 — UTF-32");
|
||||
return ToolResult.Ok(stringBuilder.ToString());
|
||||
}
|
||||
|
||||
private static Encoding DetectEncodingFromBytes(byte[] bytes)
|
||||
{
|
||||
if (bytes.Length >= 3 && bytes[0] == 239 && bytes[1] == 187 && bytes[2] == 191)
|
||||
{
|
||||
return Encoding.UTF8;
|
||||
}
|
||||
if (bytes.Length >= 2 && bytes[0] == byte.MaxValue && bytes[1] == 254)
|
||||
{
|
||||
return Encoding.Unicode;
|
||||
}
|
||||
if (bytes.Length >= 2 && bytes[0] == 254 && bytes[1] == byte.MaxValue)
|
||||
{
|
||||
return Encoding.BigEndianUnicode;
|
||||
}
|
||||
if (IsValidUtf8(bytes))
|
||||
{
|
||||
return Encoding.UTF8;
|
||||
}
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
try
|
||||
{
|
||||
return Encoding.GetEncoding("euc-kr");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Encoding.Default;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidUtf8(byte[] bytes)
|
||||
{
|
||||
int num = 0;
|
||||
bool flag = false;
|
||||
while (num < bytes.Length)
|
||||
{
|
||||
if (bytes[num] <= 127)
|
||||
{
|
||||
num++;
|
||||
continue;
|
||||
}
|
||||
int num2;
|
||||
if ((bytes[num] & 0xE0) == 192)
|
||||
{
|
||||
num2 = 1;
|
||||
}
|
||||
else if ((bytes[num] & 0xF0) == 224)
|
||||
{
|
||||
num2 = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bytes[num] & 0xF8) != 240)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
num2 = 3;
|
||||
}
|
||||
if (num + num2 >= bytes.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i <= num2; i++)
|
||||
{
|
||||
if ((bytes[num + i] & 0xC0) != 128)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
flag = true;
|
||||
num += num2 + 1;
|
||||
}
|
||||
return flag || bytes.Length < 100;
|
||||
}
|
||||
|
||||
private static bool HasBom(byte[] bytes)
|
||||
{
|
||||
if (bytes.Length >= 3 && bytes[0] == 239 && bytes[1] == 187 && bytes[2] == 191)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (bytes.Length >= 2 && bytes[0] == byte.MaxValue && bytes[1] == 254)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (bytes.Length >= 2 && bytes[0] == 254 && bytes[1] == byte.MaxValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user