/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BaseElement, element } from '../../base-ui/BaseElement.js'; @element('tab-native-data-modal') export class DisassemblingWindow extends BaseElement { private canvas: HTMLCanvasElement | undefined | null; private window: HTMLElement | undefined | null; private loading: HTMLElement | undefined | null; private ctx: CanvasRenderingContext2D | null | undefined; private hintLine = 0; private addrArray = new Array(); private maxBinSize = 0; private close: Function | undefined | null; setCloseListener(callback: Function) { this.close = callback; } removeCloseListener() { this.close = null; } private getMap(content: string, hintAttr: string) { let lines = content.split('\n'); this.addrArray = new Array(); let lineMap = new Map(); let effectLint = 0; this.maxBinSize = 0; for (let line of lines) { let lineContents = line.split(':'); if (lineContents.length === 2) { let addrHex = lineContents[0].trim(); let addr = '0x' + addrHex; let value = lineContents[1].split('\t'); try { let binary = value[0]; let lineStruct = new Disassembling(); if (binary === '') { if (line.includes('Disassembly') || line.includes('file format')) { continue; } else { if (addr.includes(' ')) { let funcs = addr.split(' '); lineStruct.addr = funcs[0]; lineStruct.binary = funcs[1]; } } } else { lineStruct.addr = addr; lineStruct.binary = value[0].trim(); lineStruct.type = value.length > 1 ? value[1] : ''; lineStruct.code = value.length > 2 ? value[2] : ''; } lineMap.set(addrHex, lineStruct); this.maxBinSize = Math.max(this.ctx!.measureText(lineStruct.addr + lineStruct.binary).width, this.maxBinSize); this.addrArray.push(addrHex); if (addrHex === hintAttr) this.hintLine = effectLint; effectLint++; } catch (e) { console.log(e); } } } return lineMap; } public showContent(content: string, hintAddr: string): void { this.loading!.style.display = 'none'; this.window!.style.display = 'block'; if (content.startsWith('error')) { this.window!.innerHTML = `${content}`; return; } let lineMap = this.getMap(content, hintAddr); this.maxBinSize = this.maxBinSize * 1.7; this.window!.innerHTML = ''; for (let addr of this.addrArray) { if (!lineMap.has(addr)) continue; let struct = lineMap.get(addr); if (this.addrArray[this.hintLine] == addr) { this.window!.innerHTML += `
${struct!.addr} : ${struct!.binary} ${struct!.type} ${struct!.code}
`; (this.window!.querySelector('#emphasis') as HTMLElement)!.style.width = this.window!.scrollWidth + 'px'; (this.window!.querySelector('#emphasis') as HTMLElement)!.style.background = '#0A59F7'; } else { this.window!.innerHTML += `
${struct!.addr} : ${struct!.binary} ${struct!.type} ${struct!.code}
`; } } this.window!.scrollTo( 0, (this.hintLine - 1) * this.shadowRoot!.querySelector('#window>.line')!.clientHeight - this.window!.clientHeight / 2 ); } private resetCanvas(styleWidth: number, styleHeight: number, width: number, height: number): void { this.canvas!.style.width = styleWidth + 'px'; this.canvas!.style.height = styleHeight + 'px'; this.canvas!.width = width; this.canvas!.height = height; } public showLoading(): void { this.loading!.style.display = 'block'; this.window!.style.display = 'none'; this.style.display = 'block'; this.style.position = 'absolute'; this.style.left = '0px'; this.style.border = '1px solid #d8d8d8'; } initElements(): void { this.canvas = this.shadowRoot?.querySelector('#canvas'); let close = this.shadowRoot?.querySelector('#close'); this.window = this.shadowRoot?.querySelector('#window'); this.loading = this.shadowRoot?.querySelector('#loading'); this.ctx = this.canvas!.getContext('2d'); this.resetCanvas(0, 0, 0, 0); close!.addEventListener('click', () => { if (this.close) { this.close(); } return true; }); } initHtml(): string { return ` `; } } class Disassembling { addr = ''; binary = ''; type = ''; code = ''; }