You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.7 KiB

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CoreAgent.ProtocolClient.Enums;
using CoreAgent.ProtocolClient.Models;
using Microsoft.Extensions.Logging;
namespace CoreAgent.ProtocolClient.Context.UeStateManager
{
/// <summary>
/// UeIdentifierManager 协议解析部分
/// </summary>
public partial class UeIdentifierManager
{
#region 协议解析方法
/// <summary>
/// 解析提示信息
/// </summary>
/// <param name="log">协议日志</param>
/// <param name="config">解析配置</param>
public void ParseHints(BuildProtocolLog log, Dictionary<string, object> config)
{
if (log?.Info != (int)LogChannelId.ID_HINTS)
{
_logger?.LogDebug("跳过非提示信息日志: Info={Info}", log?.Info);
return;
}
try
{
var hints = ParseArguments(log.Message, config);
_logger?.LogDebug("解析提示信息成功,共解析 {Count} 个参数", hints.Count);
// TODO: 处理解析后的提示信息
}
catch (Exception ex)
{
_logger?.LogError(ex, "解析提示信息失败: {Message}", log.Message);
throw new ParsingException("Hints", log?.Message ?? "", $"解析提示信息失败: {ex.Message}", ex);
}
}
/// <summary>
/// 解析参数字符串为字典
/// 性能优化:使用编译后的正则表达式
/// </summary>
/// <param name="arguments">参数字符串,格式如 "a=1 b=2 c=hello"</param>
/// <param name="config">
/// 配置字典,key为参数名,value为类型(Type)或处理函数(Func&lt;string, object&gt;)
/// 例如:{ "a", typeof(int) }, { "b", (Func&lt;string, object&gt;)(s =&gt; s.ToUpper()) }
/// </param>
/// <returns>解析后的参数字典</returns>
private Dictionary<string, object> ParseArguments(string arguments, Dictionary<string, object> config)
{
if (string.IsNullOrEmpty(arguments))
{
return new Dictionary<string, object>();
}
var result = new Dictionary<string, object>();
// 使用编译后的正则表达式提高性能
var whitespaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
try
{
foreach (var argument in whitespaceRegex.Split(arguments))
{
if (string.IsNullOrWhiteSpace(argument))
continue;
var keyValuePair = argument.Split('=', 2);
if (keyValuePair.Length != 2)
{
_logger?.LogWarning("跳过格式无效的参数: {Argument}", argument);
continue;
}
var key = keyValuePair[0];
var value = keyValuePair[1];
result[key] = ParseValue(value, key, config);
}
return result;
}
catch (Exception ex)
{
_logger?.LogError(ex, "解析参数字符串失败: {Arguments}", arguments);
throw new ParsingException("Arguments", arguments, $"解析参数字符串失败: {ex.Message}", ex);
}
}
/// <summary>
/// 根据配置解析参数值
/// </summary>
/// <param name="value">原始值字符串</param>
/// <param name="key">参数键</param>
/// <param name="config">解析配置</param>
/// <returns>解析后的值</returns>
private object ParseValue(string value, string key, Dictionary<string, object> config)
{
if (!config.TryGetValue(key, out var typeOrFunc))
return value;
try
{
return typeOrFunc switch
{
Type type when type == typeof(int) => int.TryParse(value, out var intValue) ? intValue : 0,
Type type when type == typeof(double) => double.TryParse(value, out var doubleValue) ? doubleValue : 0.0,
Func<string, object> func => func(value),
_ => value
};
}
catch (Exception ex)
{
_logger?.LogError(ex, "解析参数值失败: Key={Key}, Value={Value}", key, value);
return value; // 返回原始值作为回退
}
}
/// <summary>
/// 批量解析参数
/// 性能优化:批量处理减少重复计算
/// </summary>
/// <param name="argumentsList">参数字符串列表</param>
/// <param name="config">解析配置</param>
/// <returns>解析结果列表</returns>
public List<Dictionary<string, object>> ParseArgumentsBatch(
IEnumerable<string> argumentsList,
Dictionary<string, object> config)
{
if (argumentsList == null)
{
throw new ArgumentNullException(nameof(argumentsList));
}
var results = new List<Dictionary<string, object>>();
foreach (var arguments in argumentsList)
{
results.Add(ParseArguments(arguments, config));
}
_logger?.LogDebug("批量解析参数完成,共处理 {Count} 个参数字符串", results.Count);
return results;
}
#endregion
}
}