blob: 98a4a0f6eb3af9499ec18881404d8a5599c52023 [file] [log] [blame]
Karl Zhang3de5ab12021-05-31 11:45:48 +08001/*
Nik Dewallybacae6c2024-07-30 16:58:14 +01002 * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
Karl Zhang3de5ab12021-05-31 11:45:48 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "string_ops.hpp"
Nik Dewallybacae6c2024-07-30 16:58:14 +01009
10#include <ctype.h>
11#include <stdint.h>
12#include <stdlib.h>
Karl Zhang3de5ab12021-05-31 11:45:48 +080013#include <iostream>
Karl Zhang3de5ab12021-05-31 11:45:48 +080014#include <iomanip>
Nik Dewallybacae6c2024-07-30 16:58:14 +010015#include <stdexcept>
16#include <sstream>
Karl Zhang3de5ab12021-05-31 11:45:48 +080017
18using namespace std;
19
20// Replace first occurrence of find_str within orig of replace_str:
21size_t find_replace_1st (const string &find_str, const string &replace_str,
22 string &orig) {
23 size_t where = 0;
24 where = orig.find(find_str, where);
25 if (where != string::npos) {
26 orig.replace(where, find_str.length(), replace_str);
27 }
28 return where;
29}
30
31// Replace all occurrences of find_str in "this" string, with replace_str:
32size_t find_replace_all (const string &find_str, const string &replace_str,
33 string &orig) {
34 size_t where = 0;
35 do {
36 where = orig.find(find_str, where);
37 if (where != string::npos) {
38 orig.replace(where, find_str.length(), replace_str);
39 }
40 } while (where != string::npos);
41 return where;
42}
43
44
45string formalize (string input, string prefix) {
46 // First capitalize the input string:
47 for (auto cp = input.begin(); cp < input.end(); cp++) {
48 *cp = (char) toupper (*cp);
49 }
50 // If it already begins with the prefix...
51 if (input.substr (0, prefix.length()) == prefix) {
52 // then return it as capitalized:
53 return input;
54 } else {
55 // If not, prefix it with that prefix:
56 return prefix + input;
57 }
58}
59
60/* This implementation assumes ASCII character encoding and no "special characters" --
61 loosely speaking, "English." */
62string string_or_hex (string input, int clump_size) {
63 uint32_t n_alphanum = 0; // the number of alphanumeric characters
64 bool prose = true; // the string is alphanumeric, space, or common punctuation
65 ostringstream hex_stream;
66
67 for (auto cp = input.begin(); cp < input.end(); cp++) {
68 if ((int) *cp < 0) {
69 prose = false;
70 break;
71 }
72 if ( (*cp >= '0' && *cp <= '9')
73 || (*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z')
74 || (*cp == ' ') || (*cp == ',') || (*cp == '.')
75 || (*cp == '?') || (*cp == '!')
76 ) {
77 n_alphanum++;
78 }
79 }
80 if ( prose // so far at least!
81 && ( (input.length() - n_alphanum) // number of chars that are not "English"
82 < (input.length() >> 3) // 1/8 of the length of the string
83 ) ) {
84 return input; // take it at face-value
85 }
86 // It's not run-of-the-mill text, so create a hex string:
87 int i = 0;
88 for (auto cp = input.begin(); cp < input.end(); cp++) {
89 hex_stream << setfill('0') << setw(2) << hex << (((unsigned) *cp) & 0xff);
90 if (++i >= clump_size) {
91 hex_stream << " ";
92 i = 0;
93 }
94 }
95 return hex_stream.str();
96}
97
98string binary_from_hex (string input) {
99 stringstream hex_stream;
100 uint8_t aByte; // each byte as we grab it
101 string result = "";
102 string holder_string = "";
103
104 hex_stream.str(input);
105 hex_stream.width(2);
106 while (!hex_stream.eof()) {
107 hex_stream >> skipws >> setw(2) >> holder_string;
108 try { // TODO: May not catch all bad-chars.
109 aByte = stoi(holder_string, 0, 16);
110 }
111 catch (const invalid_argument &arg_err) {
112 cerr << "Error 2345: Non-hexadecimal character found in binary-data string ("
113 << arg_err.what() << endl;
114 exit (2345);
115 }
116 result += aByte;
117 }
118 return result;
119}