All files / sportident/src/utils bytes.ts

100% Statements 64/64
100% Branches 21/21
100% Functions 12/12
100% Lines 51/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 8337x 870x           37x 274x 854x     37x 257x 19x       37x 207x 305x     37x 197x 14x       37x 51x 45x 45x 86x 86x   45x     37x       93x 93x 19x 19x 65x     93x 276x 276x 93x 55x   38x 38x 48x 48x 48x 48x   38x     37x 140x 140x 1x   139x 139x 12049x 12049x 12049x 1x   12048x   138x    
export const isByte = (byte: unknown): boolean => (
    Number(byte) === byte &&
    Math.floor(byte) === byte &&
    byte <= 0xFF &&
    byte >= 0x00
);
 
export const isByteArr = (arr: unknown[]): boolean => (
    Array.isArray(arr) &&
    !arr.some((e) => !isByte(e))
);
 
export const assertIsByteArr = (arr: unknown[]): void => {
    if (!isByteArr(arr)) {
        throw new Error(`${arr} is not a byte array`);
    }
};
 
export const isArrOfLengths = (arr: unknown[], lengths: number[]): boolean => {
    const actualLength = arr.length;
    return lengths.some((length) => actualLength === length);
};
 
export const assertArrIsOfLengths = (arr: unknown[], lengths: number[]): void => {
    if (!isArrOfLengths(arr, lengths)) {
        throw new Error(`${arr} is not of lengths ${lengths}`);
    }
};
 
export const arr2big = (arr: number[]): number => {
    assertIsByteArr(arr);
    let outnum = 0;
    for (let i = 0; i < arr.length; i++) {
        const byte = arr[i];
        outnum += byte * Math.pow(0x100, arr.length - i - 1);
    }
    return outnum;
};
 
export const prettyHex = (
    input: string|(number|undefined)[],
    lineLength = 0,
): string => {
    let iterable = input;
    if (typeof input === 'string') {
        iterable = [];
        for (let strIndex = 0; strIndex < input.length; strIndex++) {
            iterable.push(input.charCodeAt(strIndex));
        }
    }
    const prettyBytes = [...(iterable as (number|undefined)[])]
        .map((byte) => (byte !== undefined ? `00${byte.toString(16)}` : '??'))
        .map((paddedStr) => paddedStr.slice(-2).toUpperCase());
    if (lineLength === 0) {
        return prettyBytes.join(' ');
    }
    const lines = [];
    for (let lineIndex = 0; lineIndex < prettyBytes.length / lineLength; lineIndex++) {
        const startIndex = lineIndex * lineLength;
        const endIndex = (lineIndex + 1) * lineLength;
        const line = prettyBytes.slice(startIndex, endIndex).join(' ');
        lines.push(line);
    }
    return lines.join('\n');
};
 
export const unPrettyHex = (input: string): Array<number|undefined> => {
    const hexString = input.replace(/\s/g, '');
    if ((hexString.length % 2) !== 0) {
        throw new Error('Hex String length must be even');
    }
    const byteArray = [];
    for (let byteIndex = 0; byteIndex < hexString.length / 2; byteIndex++) {
        const hexByteString = hexString.substr(byteIndex * 2, 2);
        const byteValue = hexByteString === '??' ? undefined : parseInt(hexByteString, 16);
        if (byteValue !== undefined && (!Number.isInteger(byteValue) || byteValue < 0 || byteValue > 255)) {
            throw new Error(`Invalid hex: ${hexByteString}`);
        }
        byteArray.push(byteValue);
    }
    return byteArray;
};