import React from 'react'; import './BinaryString.css'; export type BinaryStringViewProps = { allowFlipBits?: boolean; binaryString: string; onBitClicked?: (input: FlipBitEventArg) => void; emphasizeBytes?: boolean; className?: string; disableHighlight?: boolean, signBitIndex?: number, valueBitSize?: number }; export type FlipBitEventArg = { bitIndex: number; binaryStringLength: number; $event: any; newBinaryString: any; isExtraBit: boolean }; export default class BinaryStringView extends React.Component { render() { return {this.getChildren()} } onBitClick(index: number, isExtra: boolean, e: any) { if (!this.props.allowFlipBits || !this.props.onBitClicked) { return; } const arr = this.props.binaryString.split(''); arr[index] = arr[index] == '0' ? '1' : '0'; const newBinaryString = arr.join(''); this.props.onBitClicked({ bitIndex: index, binaryStringLength: this.props.binaryString.length, newBinaryString: newBinaryString, $event: e, isExtraBit: isExtra }); } getChildren() { var bits = this.createBits(this.props.binaryString.split('')); if (this.props.emphasizeBytes) { return this.splitIntoBytes(bits); } return bits; } createBits(bitChars: string[]): JSX.Element[] { const allowFlipBits = this.props.allowFlipBits || false; const css = allowFlipBits ? ' flipable' : '' const disableHighlight = this.props.disableHighlight || false; const firstBitIndex = this.props.valueBitSize != null ? bitChars.length - this.props.valueBitSize : -1; return bitChars.map((c, i) => { var className = c == '1' ? `one${css}` : `zero${css}`; var tooltip = ''; const isExtra = i < firstBitIndex; if (isExtra) className += ' extra-bit'; if (i === this.props.signBitIndex) { className += ' accent1'; tooltip = 'Signature bit. 0 means a positive number and 1 means a negative.' } if (disableHighlight) className = css; return this.onBitClick(i, isExtra, e)}>{c} }); } splitIntoBytes(bits: JSX.Element[]) { const bytes = []; var key = 0; while (bits.length > 0) { bytes.push({bits.splice(0, 8)}); } return bytes; } }