162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include "print_binary.h"
362306a36Sopenharmony_ci#include <linux/log2.h>
462306a36Sopenharmony_ci#include <linux/ctype.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ciint binary__fprintf(unsigned char *data, size_t len,
762306a36Sopenharmony_ci		    size_t bytes_per_line, binary__fprintf_t printer,
862306a36Sopenharmony_ci		    void *extra, FILE *fp)
962306a36Sopenharmony_ci{
1062306a36Sopenharmony_ci	size_t i, j, mask;
1162306a36Sopenharmony_ci	int printed = 0;
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci	if (!printer)
1462306a36Sopenharmony_ci		return 0;
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	bytes_per_line = roundup_pow_of_two(bytes_per_line);
1762306a36Sopenharmony_ci	mask = bytes_per_line - 1;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	printed += printer(BINARY_PRINT_DATA_BEGIN, 0, extra, fp);
2062306a36Sopenharmony_ci	for (i = 0; i < len; i++) {
2162306a36Sopenharmony_ci		if ((i & mask) == 0) {
2262306a36Sopenharmony_ci			printed += printer(BINARY_PRINT_LINE_BEGIN, -1, extra, fp);
2362306a36Sopenharmony_ci			printed += printer(BINARY_PRINT_ADDR, i, extra, fp);
2462306a36Sopenharmony_ci		}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci		printed += printer(BINARY_PRINT_NUM_DATA, data[i], extra, fp);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci		if (((i & mask) == mask) || i == len - 1) {
2962306a36Sopenharmony_ci			for (j = 0; j < mask-(i & mask); j++)
3062306a36Sopenharmony_ci				printed += printer(BINARY_PRINT_NUM_PAD, -1, extra, fp);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci			printer(BINARY_PRINT_SEP, i, extra, fp);
3362306a36Sopenharmony_ci			for (j = i & ~mask; j <= i; j++)
3462306a36Sopenharmony_ci				printed += printer(BINARY_PRINT_CHAR_DATA, data[j], extra, fp);
3562306a36Sopenharmony_ci			for (j = 0; j < mask-(i & mask); j++)
3662306a36Sopenharmony_ci				printed += printer(BINARY_PRINT_CHAR_PAD, i, extra, fp);
3762306a36Sopenharmony_ci			printed += printer(BINARY_PRINT_LINE_END, -1, extra, fp);
3862306a36Sopenharmony_ci		}
3962306a36Sopenharmony_ci	}
4062306a36Sopenharmony_ci	printed += printer(BINARY_PRINT_DATA_END, -1, extra, fp);
4162306a36Sopenharmony_ci	return printed;
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciint is_printable_array(char *p, unsigned int len)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	unsigned int i;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	if (!p || !len || p[len - 1] != 0)
4962306a36Sopenharmony_ci		return 0;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	len--;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	for (i = 0; i < len && p[i]; i++) {
5462306a36Sopenharmony_ci		if (!isprint(p[i]) && !isspace(p[i]))
5562306a36Sopenharmony_ci			return 0;
5662306a36Sopenharmony_ci	}
5762306a36Sopenharmony_ci	return 1;
5862306a36Sopenharmony_ci}
59