- 将 1346 行的单文件拆分为 7 个职责单一的模块 - authHelper: 认证和登录检查 - userInfoHelper: 用户信息管理 - conversationHelper: 会话历史加载 - vcdHelper: VCD 文件处理 - contextHelper: 上下文管理 - fileHelper: 文件操作 - messageRouter: 消息路由分发 - 主组件精简至 157 行,提升可维护性
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
/**
|
||
* VCD 文件处理模块
|
||
* 功能:VCD 文件信息获取和信号解析
|
||
* 依赖:vscode, fs
|
||
* 使用场景:波形查看器相关功能
|
||
*/
|
||
import * as vscode from "vscode";
|
||
|
||
export async function getVCDFileInfo(
|
||
panel: vscode.WebviewPanel,
|
||
vcdFilePath: string,
|
||
containerId: string,
|
||
) {
|
||
try {
|
||
const fs = require("fs");
|
||
|
||
if (!fs.existsSync(vcdFilePath)) {
|
||
panel.webview.postMessage({
|
||
command: "vcdInfo",
|
||
containerId: containerId,
|
||
vcdInfo: {
|
||
signalCount: "N/A",
|
||
timeRange: "N/A",
|
||
fileSize: "N/A",
|
||
error: "文件不存在",
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
const stats = fs.statSync(vcdFilePath);
|
||
const fileSizeKB = stats.size / 1024;
|
||
const fileSize =
|
||
fileSizeKB < 1024
|
||
? `${fileSizeKB.toFixed(2)} KB`
|
||
: `${(fileSizeKB / 1024).toFixed(2)} MB`;
|
||
|
||
const content = fs.readFileSync(vcdFilePath, "utf-8");
|
||
const varMatches = content.match(/\$var/g);
|
||
const signalCount = varMatches ? varMatches.length : 0;
|
||
|
||
let timeRange = "N/A";
|
||
const timeMatch = content.match(/#(\d+)/g);
|
||
if (timeMatch && timeMatch.length > 0) {
|
||
const times = timeMatch.map((t: string) => parseInt(t.substring(1)));
|
||
const minTime = Math.min(...times);
|
||
const maxTime = Math.max(...times);
|
||
timeRange = `${minTime} - ${maxTime}`;
|
||
}
|
||
|
||
const signals = parseVCDSignals(content, 3);
|
||
|
||
panel.webview.postMessage({
|
||
command: "vcdInfo",
|
||
containerId: containerId,
|
||
vcdInfo: {
|
||
signalCount: signalCount.toString(),
|
||
timeRange: timeRange,
|
||
fileSize: fileSize,
|
||
signals: signals,
|
||
},
|
||
});
|
||
} catch (error) {
|
||
console.error("获取 VCD 文件信息失败:", error);
|
||
panel.webview.postMessage({
|
||
command: "vcdInfo",
|
||
containerId: containerId,
|
||
vcdInfo: {
|
||
signalCount: "N/A",
|
||
timeRange: "N/A",
|
||
fileSize: "N/A",
|
||
error: error instanceof Error ? error.message : "未知错误",
|
||
},
|
||
});
|
||
}
|
||
}
|
||
|
||
function parseVCDSignals(content: string, maxSignals: number = 3) {
|
||
const signals: Array<{
|
||
name: string;
|
||
identifier: string;
|
||
width: number;
|
||
values: Array<{ time: number; value: string }>;
|
||
}> = [];
|
||
|
||
try {
|
||
const varRegex = /\$var\s+(\w+)\s+(\d+)\s+(\S+)\s+([^\$]+?)\s+\$end/g;
|
||
let match;
|
||
const signalDefs: Array<{
|
||
name: string;
|
||
identifier: string;
|
||
width: number;
|
||
}> = [];
|
||
|
||
while (
|
||
(match = varRegex.exec(content)) !== null &&
|
||
signalDefs.length < maxSignals
|
||
) {
|
||
const width = parseInt(match[2]);
|
||
const identifier = match[3];
|
||
const name = match[4].trim();
|
||
signalDefs.push({ name, identifier, width });
|
||
}
|
||
|
||
const dumpvarsIndex = content.indexOf("$dumpvars");
|
||
if (dumpvarsIndex === -1) {
|
||
return signals;
|
||
}
|
||
|
||
const dataSection = content.substring(dumpvarsIndex);
|
||
|
||
for (const signalDef of signalDefs) {
|
||
const values: Array<{ time: number; value: string }> = [];
|
||
let currentTime = 0;
|
||
const lines = dataSection.split("\n");
|
||
|
||
for (const line of lines) {
|
||
const trimmedLine = line.trim();
|
||
|
||
if (trimmedLine.startsWith("#")) {
|
||
currentTime = parseInt(trimmedLine.substring(1));
|
||
continue;
|
||
}
|
||
|
||
if (signalDef.width === 1) {
|
||
const singleBitMatch = trimmedLine.match(
|
||
new RegExp(`^([01xz])${signalDef.identifier}$`),
|
||
);
|
||
if (singleBitMatch) {
|
||
values.push({ time: currentTime, value: singleBitMatch[1] });
|
||
}
|
||
} else {
|
||
const multiBitMatch = trimmedLine.match(
|
||
new RegExp(`^b([01xz]+)\\s+${signalDef.identifier}$`),
|
||
);
|
||
if (multiBitMatch) {
|
||
values.push({ time: currentTime, value: multiBitMatch[1] });
|
||
}
|
||
}
|
||
|
||
if (values.length >= 50) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
signals.push({
|
||
name: signalDef.name,
|
||
identifier: signalDef.identifier,
|
||
width: signalDef.width,
|
||
values: values,
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error("解析 VCD 信号数据失败:", error);
|
||
}
|
||
|
||
return signals;
|
||
}
|