Skip to content

Commit

Permalink
[19_3] Move hex related routines to lolly::data
Browse files Browse the repository at this point in the history
+ Rename as_hexadecimal to to_Hex
+ Add routine: to_hex
+ Fix INT32_MIN bug of to_hex
  • Loading branch information
da-liii authored Dec 27, 2023
1 parent 2236462 commit e75585a
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 126 deletions.
50 changes: 2 additions & 48 deletions Kernel/Types/analyze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
******************************************************************************/

#include "analyze.hpp"
#include "lolly/data/numeral.hpp"
#include "ntuple.hpp"

/******************************************************************************
Expand Down Expand Up @@ -520,53 +521,6 @@ fnsymbol_nr (int nr) {
return r;
}

/******************************************************************************
* Conversions to and from hexadecimal
******************************************************************************/

static const char* hex_string= "0123456789ABCDEF";

string
as_hex (uint8_t i) {
uint8_t i_low = i & 15;
uint8_t i_high= i >> 4;
return locase_all (string (hex_string[i_high]) * string (hex_string[i_low]));
}

string
as_hexadecimal (int i) {
if (i < 0) return "-" * as_hexadecimal (-i);
if (i < 16) return hex_string[i & 15];
return as_hexadecimal (i >> 4) * hex_string[i & 15];
}

string
as_hexadecimal (pointer ptr) {
intptr_t i= (intptr_t) ptr;
if (i < 0) return "-" * as_hexadecimal (-i);
if (i < 16) return hex_string[i & 15];
return as_hexadecimal (i >> 4) * hex_string[i & 15];
}

string
as_hexadecimal (int i, int len) {
if (len == 1) return hex_string[i & 15];
else return as_hexadecimal (i >> 4, len - 1) * hex_string[i & 15];
}

int
from_hexadecimal (string s) {
int i, n= N (s), res= 0;
if ((n > 0) && (s[0] == '-')) return -from_hexadecimal (s (1, n));
for (i= 0; i < n; i++) {
res= res << 4;
if (is_digit (s[i])) res+= (int) (s[i] - '0');
if ((s[i] >= 'A') && (s[i] <= 'F')) res+= (int) (s[i] + 10 - 'A');
if ((s[i] >= 'a') && (s[i] <= 'f')) res+= (int) (s[i] + 10 - 'a');
}
return res;
}

/******************************************************************************
* Routines for the TeXmacs encoding
******************************************************************************/
Expand Down Expand Up @@ -955,7 +909,7 @@ unescape_guile (string s) {
else if (i + 3 < n && s[i + 1] == 'x' && is_hex_digit (s[i + 2]) &&
is_hex_digit (s[i + 3])) {
string e= s (i + 2, i + 4);
r << (unsigned char) from_hexadecimal (e);
r << (unsigned char) lolly::data::from_hex (e);
i+= 3;
}
else r << s[i];
Expand Down
46 changes: 0 additions & 46 deletions Kernel/Types/analyze.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,52 +301,6 @@ string Alpha_nr (int nr);
*/
string fnsymbol_nr (int nr);

/**
* @brief Converts an 8-bit unsigned integer to a fixed-length (2) hex string.
*
* @param i The integer to be converted to a fixed-length hex string.
* @return The fixed-length (2) hexadecimal string representation of the input
* integer.
*/
string as_hex (uint8_t i);

/**
* @brief Converts an integer to a hexadecimal string.
*
* @param i The integer to be converted to a hexadecimal string.
* @return The hexadecimal string representation of the input integer.
*/
string as_hexadecimal (int i);

/**
* @brief Converts a pointer to a hexadecimal string.
*
* @param ptr The pointer to be converted to a hexadecimal string.
* @return The hexadecimal string representation of the input pointer.
*/
string as_hexadecimal (pointer ptr);

/**
* @brief Converts an integer to a hexadecimal string with a fixed length.
*
* @param i The integer to be converted to a hexadecimal string.
* @param len The length of the output hexadecimal string.
* @return The fixed-length hexadecimal string representation of the input
* integer.
*/
string as_hexadecimal (int i, int length);

/**
* @brief Converts a hexadecimal string to an integer.
*
* This function takes a hexadecimal string as input and converts it into its
* integer representation.
*
* @param s The hexadecimal string to be converted to an integer.
* @return The integer representation of the input hexadecimal string.
*/
int from_hexadecimal (string s);

/**
* @brief Encodes a string by converting special characters to TeXmacs encoding.
*
Expand Down
85 changes: 72 additions & 13 deletions lolly/data/numeral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@

namespace lolly {
namespace data {
static string roman_ones[10] = {"", "i", "ii", "iii", "iv",
"v", "vi", "vii", "viii", "ix"};
static string roman_tens[10] = {"", "x", "xx", "xxx", "xl",
"l", "lx", "lxx", "lxxx", "xc"};
static string roman_hundreds[10]= {"", "c", "cc", "ccc", "cd",
"d", "dc", "dcc", "dccc", "cm"};
static string roman_thousands[4]= {"", "m", "mm", "mmm"};
static const string roman_ones[10] = {"", "i", "ii", "iii", "iv",
"v", "vi", "vii", "viii", "ix"};
static const string roman_tens[10] = {"", "x", "xx", "xxx", "xl",
"l", "lx", "lxx", "lxxx", "xc"};
static const string roman_hundreds[10]= {"", "c", "cc", "ccc", "cd",
"d", "dc", "dcc", "dccc", "cm"};
static const string roman_thousands[4]= {"", "m", "mm", "mmm"};

// 0 should not be used as index of this array, or bug occurs. because digit 0
// is handled specially according to position of digit.
static const string chars_han[10]= {"?", "", "", "", "",
"", "", "", "", ""};

static const char* hex_string= "0123456789ABCDEF";

string
to_roman (int32_t nr) {
Expand All @@ -37,11 +44,6 @@ to_Roman (int32_t nr) {
return upcase_all (to_roman (nr));
}

// 0 should not be used as index of this array, or bug occurs. because digit 0
// is handled specially according to position of digit.
static string chars_han[10]= {
"<unspecified>", "", "", "", "", "", "", "", "", ""};

string
hanzi_sub (int16_t nr, bool leading_zero) {
short thousand= (nr % 10000) / 1000, hundred= (nr % 1000) / 100,
Expand Down Expand Up @@ -120,7 +122,7 @@ hanzi_sub (int16_t nr, bool leading_zero) {
case 0x1F:
return "";
default:
return "<unspecified>" * as_string (cases);
return "?" * as_string (cases);
}
}

Expand All @@ -140,5 +142,62 @@ to_hanzi (int32_t nr) {
return hanzi_sub (nr, false);
}

string
to_padded_Hex (uint8_t i) {
uint8_t i_low = i & 15;
uint8_t i_high= i >> 4;
return string (hex_string[i_high]) * string (hex_string[i_low]);
}

string
to_padded_hex (uint8_t i) {
return locase_all (to_padded_Hex (i));
}

string
to_Hex (int32_t i) {
if (i == INT32_MIN) return "-80000000";
if (i < 0) return "-" * to_Hex (-i);
if (i < 16) return hex_string[i & 15];
return to_Hex (i >> 4) * hex_string[i & 15];
}

string
to_hex (int32_t i) {
return locase_all (to_Hex (i));
}

string
to_Hex (pointer ptr) {
intptr_t i= (intptr_t) ptr;
if (i < 0) return "-" * to_Hex (-i);
if (i < 16) return hex_string[i & 15];
return to_Hex (i >> 4) * hex_string[i & 15];
}

string
to_hex (pointer ptr) {
return locase_all (to_Hex (ptr));
}

int
from_hex (string s) {
int i, n= N (s), res= 0;
if ((n > 0) && (s[0] == '-')) return -from_hex (s (1, n));
for (i= 0; i < n; i++) {
res= res << 4;
if (is_digit (s[i])) res+= (int) (s[i] - '0');
if ((s[i] >= 'A') && (s[i] <= 'F')) res+= (int) (s[i] + 10 - 'A');
if ((s[i] >= 'a') && (s[i] <= 'f')) res+= (int) (s[i] + 10 - 'a');
}
return res;
}

string
as_hexadecimal (int i, int len) {
if (len == 1) return hex_string[i & 15];
else return as_hexadecimal (i >> 4, len - 1) * hex_string[i & 15];
}

} // namespace data
} // namespace lolly
51 changes: 51 additions & 0 deletions lolly/data/numeral.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,56 @@ string to_Roman (int32_t nr);
* @return A string representing the Chinese numeral.
*/
string to_hanzi (int32_t nr);

/**
* @brief Converts an 8-bit unsigned integer to a fixed-length (2) hex string.
*
* @param i The integer to be converted to a fixed-length hex string.
* @return The fixed-length (2) hexadecimal string representation of the input
* integer.
*/
string to_padded_hex (uint8_t i);

/**
* @brief Converts an integer to a hexadecimal string.
*
* @param i The integer to be converted to a hexadecimal string.
* @return The hexadecimal string representation of the input integer.
*/
string to_hex (int i);

string to_Hex (int i);

/**
* @brief Converts a pointer to a hexadecimal string.
*
* @param ptr The pointer to be converted to a hexadecimal string.
* @return The hexadecimal string representation of the input pointer.
*/
string to_hex (pointer ptr);

string to_Hex (pointer ptr);

/**
* @brief Converts a hexadecimal string to an integer.
*
* This function takes a hexadecimal string as input and converts it into its
* integer representation.
*
* @param s The hexadecimal string to be converted to an integer.
* @return The integer representation of the input hexadecimal string.
*/
int from_hex (string s);

/**
* @brief Converts an integer to a hexadecimal string with a fixed length.
*
* @param i The integer to be converted to a hexadecimal string.
* @param len The length of the output hexadecimal string.
* @return The fixed-length hexadecimal string representation of the input
* integer.
*/
string as_hexadecimal (int i, int length);

} // namespace data
} // namespace lolly
3 changes: 2 additions & 1 deletion lolly/hash/md5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "md5.hpp"
#include "analyze.hpp"
#include "file.hpp"
#include "lolly/data/numeral.hpp"

#include <tbox/tbox.h>

Expand Down Expand Up @@ -49,7 +50,7 @@ md5_hexdigest (url u) {

string md5_hex= string ();
for (int i= 0; i < 16; ++i) {
md5_hex << as_hex (o_buffer[i]);
md5_hex << data::to_padded_hex (o_buffer[i]);
}
return md5_hex;
}
Expand Down
3 changes: 2 additions & 1 deletion lolly/hash/sha.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "sha.hpp"
#include "analyze.hpp"
#include "file.hpp"
#include "lolly/data/numeral.hpp"
#include "string.hpp"
#include "url.hpp"

Expand Down Expand Up @@ -74,7 +75,7 @@ sha_hexdigest (url u, sha_mode mode) {

string ret= string ();
for (int i= 0; i < o_size; ++i) {
ret << as_hex (o_buffer[i]);
ret << data::to_padded_hex (o_buffer[i]);
}
return ret;
}
Expand Down
12 changes: 0 additions & 12 deletions tests/Kernel/Types/analyze_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,6 @@ TEST_CASE ("is_alphanum") {
CHECK (!is_alphanum ("!"));
}

TEST_CASE ("as_hex") {
SUBCASE ("0~255") {
string_eq (as_hex ((uint8_t) 0), "00");
string_eq (as_hex ((uint8_t) 1), "01");
string_eq (as_hex ((uint8_t) 255), "ff");
}
SUBCASE ("overflow") {
string_eq (as_hex ((uint8_t) -1), "ff");
string_eq (as_hex ((uint8_t) 256), "00");
}
}

TEST_CASE ("test locase all") {
CHECK_EQ (locase_all (string ("true")) == string ("true"), true);
CHECK_EQ (locase_all (string ("TRue")) == string ("true"), true);
Expand Down
Loading

0 comments on commit e75585a

Please sign in to comment.