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