From b73b69a8ccb8bdd842f330e1885685d9caf7c762 Mon Sep 17 00:00:00 2001 From: Nik Date: Tue, 28 Mar 2023 15:28:44 +0200 Subject: [PATCH] includes: Added documentations for all remaining types and functions --- includes/std/limits.pat | 84 +++++++++++++++++++++++++++++++++++ includes/std/random.pat | 30 ++++++++++--- includes/type/base.pat | 24 ++++++++++ includes/type/bcd.pat | 8 ++++ includes/type/byte.pat | 13 ++++++ includes/type/color.pat | 70 +++++++++++++++++++++-------- includes/type/float16.pat | 7 +++ includes/type/guid.pat | 12 +++++ includes/type/ip.pat | 10 +++++ includes/type/leb128.pat | 23 ++++++++-- includes/type/mac.pat | 7 +++ includes/type/magic.pat | 23 +++++++++- includes/type/path.pat | 37 +++++++++++---- includes/type/size.pat | 23 ++++++++++ includes/type/time.pat | 32 +++++++++++-- includes/type/types/010.pat | 4 ++ includes/type/types/c.pat | 4 ++ includes/type/types/linux.pat | 4 ++ includes/type/types/rust.pat | 4 ++ includes/type/types/win32.pat | 4 ++ 20 files changed, 381 insertions(+), 42 deletions(-) diff --git a/includes/std/limits.pat b/includes/std/limits.pat index f4ec155..eeb4741 100644 --- a/includes/std/limits.pat +++ b/includes/std/limits.pat @@ -1,83 +1,167 @@ #pragma once +/*! + Library to calculate the minimum and maximum values that fit into a given data type +*/ + namespace std::limits { + /** + Returns the minimum value that can be stored in a `u8`. + @return Minimum value + */ fn u8_min() { return u8(0); }; + /** + Returns the maximum value that can be stored in a `u8`. + @return Maximum value + */ fn u8_max() { return u8(-1); }; + /** + Returns the minimum value that can be stored in a `s8`. + @return Minimum value + */ fn s8_min() { return -s8((std::limits::u8_max() / 2)) - 1; }; + /** + Returns the maximum value that can be stored in a `s8`. + @return Maximum value + */ fn s8_max() { return s8((std::limits::u8_max() / 2)); }; + /** + Returns the minimum value that can be stored in a `u16`. + @return Minimum value + */ fn u16_min() { return u16(0); }; + /** + Returns the maximum value that can be stored in a `u16`. + @return Maximum value + */ fn u16_max() { return u16(-1); }; + /** + Returns the minimum value that can be stored in a `s16`. + @return Minimum value + */ fn s16_min() { return -s16((std::limits::u16_max() / 2)) - 1; }; + /** + Returns the maximum value that can be stored in a `s16`. + @return Maximum value + */ fn s16_max() { return s16((std::limits::u16_max() / 2)); }; + /** + Returns the minimum value that can be stored in a `u32`. + @return Minimum value + */ fn u32_min() { return u32(0); }; + /** + Returns the maximum value that can be stored in a `u32`. + @return Maximum value + */ fn u32_max() { return u32(-1); }; + /** + Returns the minimum value that can be stored in a `s32`. + @return Minimum value + */ fn s32_min() { return -s32((std::limits::u32_max() / 2)) - 1; }; + /** + Returns the maximum value that can be stored in a `s32`. + @return Maximum value + */ fn s32_max() { return s32((std::limits::u32_max() / 2)); }; + /** + Returns the minimum value that can be stored in a `u64`. + @return Minimum value + */ fn u64_min() { return u64(0); }; + /** + Returns the maximum value that can be stored in a `u64`. + @return Maximum value + */ fn u64_max() { return u64(-1); }; + /** + Returns the minimum value that can be stored in a `s64`. + @return Minimum value + */ fn s64_min() { return -s64((std::limits::u64_max() / 2)) - 1; }; + /** + Returns the maximum value that can be stored in a `s64`. + @return Maximum value + */ fn s64_max() { return s64((std::limits::u64_max() / 2)); }; + /** + Returns the minimum value that can be stored in a `u128`. + @return Minimum value + */ fn u128_min() { return u128(0); }; + /** + Returns the maximum value that can be stored in a `u128`. + @return Maximum value + */ fn u128_max() { return u128(-1); }; + /** + Returns the minimum value that can be stored in a `s128`. + @return Minimum value + */ fn s128_min() { return -s128((std::limits::u128_max() / 2)) - 1; }; + /** + Returns the maximum value that can be stored in a `s128`. + @return Maximum value + */ fn s128_max() { return s128((std::limits::u128_max() / 2)); }; diff --git a/includes/std/random.pat b/includes/std/random.pat index 5b42716..f371212 100644 --- a/includes/std/random.pat +++ b/includes/std/random.pat @@ -23,12 +23,11 @@ namespace std::random { FisherF = 8, StudentT = 9, LogNormal = 10, - Discrete = 11, - Bernoulli = 12, - Binomial = 13, - NegativeBinomial = 14, - Geometric = 15, - Poisson = 16 + Bernoulli = 11, + Binomial = 12, + NegativeBinomial = 13, + Geometric = 14, + Poisson = 15 }; /** @@ -42,6 +41,25 @@ namespace std::random { /** Generates a random number using the given distribution with the given parameters. The random number generator used internally is C++'s std::mt19937_64 Mersenne Twister implementation. + + > **Distributions** + > - `Uniform(min, max) -> i128` + > - `Normal(mean, stddev) -> double` + > - `Exponential(lambda) -> double` + > - `Gamma(alpha, beta) -> double` + > - `Weibull(a, b) -> double` + > - `ExtremeValue(a, b) -> double` + > - `ChiSquared(n) -> double` + > - `Cauchy(a, b) -> double` + > - `FisherF(m, n) -> double` + > - `StudentT(n) -> double` + > - `LogNormal(m, s) -> double` + > - `Bernoulli(p) -> bool` + > - `Binomial(t, p) -> i128` + > - `NegativeBinomial(k, p) -> i128` + > - `Geometric(p) -> i128` + > - `Poisson(mean) -> i128` + @param distribution Distribution to use @param param1 This parameter depends on the type of distribution used. @param param2 This parameter depends on the type of distribution used. diff --git a/includes/type/base.pat b/includes/type/base.pat index a485431..d24fec4 100644 --- a/includes/type/base.pat +++ b/includes/type/base.pat @@ -3,11 +3,35 @@ #include #include +/*! + Types used to change the base of the displayed integer value. + Used like `type::Hex hexNumber;`, `type::Oct octalNumber;` +*/ + namespace type { + /** + Integer type representing a Hexadecimal value. Displays its value in hexadecimal format. + @tparam T Integer type to use + */ using Hex = T [[format("type::impl::format_hex")]]; + + /** + Integer type representing a Octal value. Displays its value in octal format. + @tparam T Integer type to use + */ using Oct = T [[format("type::impl::format_oct")]]; + + /** + Integer type representing a Decimal value. Displays its value in decimal format. + @tparam T Integer type to use + */ using Dec = T [[format("type::impl::format_dec")]]; + + /** + Integer type representing a Binary value. Displays its value in binary format. + @tparam T Integer type to use + */ using Bin = T [[format("type::impl::format_bin")]]; namespace impl { diff --git a/includes/type/bcd.pat b/includes/type/bcd.pat index f9b20f3..56c72a8 100644 --- a/includes/type/bcd.pat +++ b/includes/type/bcd.pat @@ -2,8 +2,16 @@ #include +/*! + Type to decode a BCD (Binary Coded Decimal) number +*/ + namespace type { + /** + Decodes a BCD value where one byte represents a single digit + @tparam Digits Number of digits + */ struct BCD { u8 bytes[Digits]; } [[sealed, format_read("type::impl::format_bcd")]]; diff --git a/includes/type/byte.pat b/includes/type/byte.pat index 18cae0b..09790e2 100644 --- a/includes/type/byte.pat +++ b/includes/type/byte.pat @@ -2,8 +2,15 @@ #include +/*! + Types to display single bytes using various different representations +*/ + namespace type { + /** + Type visualizing the value of each individual bit + */ bitfield Bits { bit0 : 1; bit1 : 1; @@ -15,11 +22,17 @@ namespace type { bit7 : 1; } [[format("type::impl::format_bits"), right_to_left]]; + /** + Type visualizing the value of the two nibbles + */ bitfield Nibbles { low : 4; high : 4; } [[format("type::impl::format_nibbles")]]; + /** + Type representing a single Byte. Decodes the byte as it's hexadeicmal value, individual bits and nibbles + */ union Byte { u8 value; Bits bits; diff --git a/includes/type/color.pat b/includes/type/color.pat index 22f9a75..922aa83 100644 --- a/includes/type/color.pat +++ b/includes/type/color.pat @@ -3,28 +3,60 @@ #include #include +/*! + Types representing RGB or RGBA colors. The decoded color will be displayed in their color field +*/ + namespace type { - struct RGB8 { - u8 r, g, b; - } [[sealed, format("type::impl::format_color")]]; + /** + Type representing a generic RGBA color with a variable number of bits for each color + @tparam R Number of bits used for the red component + @tparam G Number of bits used for the green component + @tparam B Number of bits used for the blue component + @tparam A Number of bits used for the alpha component + */ + bitfield RGBA { + r : R; + g : G; + b : B; + if (A > 0) a : A; + } [[sealed, format("type::impl::format_color"), color(std::format("{0:02X}{1:02X}{2:02X}FF", r, g, b))]]; + + /** + Type representing a generic RGB color with a variable number of bits for each color + @tparam R Number of bits used for the red component + @tparam G Number of bits used for the green component + @tparam B Number of bits used for the blue component + */ + using RGB = RGBA; + - struct RGBA8 { - u8 r, g, b, a; - } [[sealed, format("type::impl::format_color")]]; + /** + Type representing a RGBA color with 8 bits for the red component, 8 bits for green, 8 bits for blue and 8 bits for alpha + */ + using RGBA8 = RGBA<8,8,8,8>; - bitfield RGB565 { - r : 5; - g : 6; - b : 5; - } [[sealed, format("type::impl::format_color")]]; + /** + Type representing a RGB color with 8 bits for the red component, 8 bits for green and 8 bits for blue + */ + using RGB8 = RGB<8,8,8>; - bitfield RGBA4 { - r : 4; - g : 4; - b : 4; - a : 4; - } [[sealed, format("type::impl::format_color")]]; + /** + Type representing a RGB color with 5 bits for the red component, 6 bits for green and 5 bits for blue + */ + using RGB565 = RGB<5,6,5>; + + /** + Type representing a RGBA color with 4 bits for the red component, 4 bits for green, 4 bits for blue and 4 bits for alpha + */ + using RGB4444 = RGBA<4,4,4,4>; + + /** + Type representing a RGBA color with 5 bits for the red component, 5 bits for green, 5 bits for blue and 1 bits for alpha + */ + using RGBA5551 = RGBA<5,5,5,1>; + namespace impl { @@ -44,5 +76,5 @@ namespace type { }; } - -} + +} \ No newline at end of file diff --git a/includes/type/float16.pat b/includes/type/float16.pat index 7b5a2e4..e9f49e5 100644 --- a/includes/type/float16.pat +++ b/includes/type/float16.pat @@ -4,8 +4,15 @@ #include #include +/*! + Type representing a 16 bit half precision floating point number +*/ + namespace type { + /** + Type representing a 16 bit half precision floating point number + */ using float16 = u16 [[format("type::impl::format_float16")]]; namespace impl { diff --git a/includes/type/guid.pat b/includes/type/guid.pat index 494a7a5..bcc601f 100644 --- a/includes/type/guid.pat +++ b/includes/type/guid.pat @@ -2,8 +2,15 @@ #include +/*! + Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122 +*/ + namespace type { + /** + Type representing a GUID value + */ struct GUID { u32 time_low; u16 time_mid; @@ -13,6 +20,11 @@ namespace type { u8 node[6]; } [[sealed, format("type::impl::format_guid")]]; + /** + Alias name for GUID + */ + using UUID = GUID; + namespace impl { fn format_guid(GUID guid) { diff --git a/includes/type/ip.pat b/includes/type/ip.pat index f8e5b24..f6d2f72 100644 --- a/includes/type/ip.pat +++ b/includes/type/ip.pat @@ -3,12 +3,22 @@ #include #include +/** + Types used to decode IP addresses +*/ + namespace type { + /** + A 4 byte IPv4 Address as described in RFC 791 + */ struct IPv4Address { u8 bytes[4]; } [[sealed, format("type::impl::format_ipv4_address")]]; + /** + A 16 byte IPv6 Address as described in RFC 8200 + */ struct IPv6Address { be u16 words[8]; } [[sealed, format("type::impl::format_ipv6_address")]]; diff --git a/includes/type/leb128.pat b/includes/type/leb128.pat index 7231c19..9fa790b 100644 --- a/includes/type/leb128.pat +++ b/includes/type/leb128.pat @@ -3,15 +3,32 @@ #include #include +/*! + Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible +*/ + namespace type { - struct _LEB128 { + /** + Base LEB128 type. Use `uLEB128` and `sLEB128` instead. + */ + struct LEB128Base { u8 array[while($ == addressof(this) || std::mem::read_unsigned($-1, 1) & 0x80 != 0)] [[hidden]]; } [[sealed]]; - using uLEB128 = _LEB128 [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]]; - using sLEB128 = _LEB128 [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]]; + /** + A unsigned variant of a LEB128 number + */ + using uLEB128 = LEB128Base [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]]; + /** + A signed variant of a LEB128 number + */ + using sLEB128 = LEB128Base [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]]; + + /** + Legacy alias for uLEB128 + */ using LEB128 = uLEB128; namespace impl { diff --git a/includes/type/mac.pat b/includes/type/mac.pat index df1080d..48fe237 100644 --- a/includes/type/mac.pat +++ b/includes/type/mac.pat @@ -2,8 +2,15 @@ #include +/*! + Types used to decode MAC Addresses +*/ + namespace type { + /** + A MAC Address as used in the Internet Protocol + */ struct MACAddress { u8 bytes[6]; } [[sealed, format("type::impl::format_mac_address")]]; diff --git a/includes/type/magic.pat b/includes/type/magic.pat index 22d0392..37be42f 100644 --- a/includes/type/magic.pat +++ b/includes/type/magic.pat @@ -1,8 +1,18 @@ #include #include +#include +#include + +/*! + Types used to parse and enforce specific magic numbers +*/ namespace type { + /** + A Magic number. Throws an error if the magic number does not match the expected value + @tparam ExpectedValue A string representing the expected value + */ struct Magic { char value[std::string::length(ExpectedValue)]; std::assert(value == ExpectedValue, std::format("Invalid magic value! Expected \"{}\", got \"{}\".", ExpectedValue, value)); @@ -11,9 +21,18 @@ namespace type { namespace impl { fn format_magic(ref auto magic) { - return magic.value; + str result; + for (u32 i = 0, i < sizeof(magic.value), i += 1) { + char c = magic.value[i]; + + if (std::ctype::isprint(c)) + result += c; + else + result += std::format("\\x{:02X}", u8(c)); + } + return std::format("\"{}\"", result); }; } -} +} \ No newline at end of file diff --git a/includes/type/path.pat b/includes/type/path.pat index 25a145a..e18a073 100644 --- a/includes/type/path.pat +++ b/includes/type/path.pat @@ -1,29 +1,50 @@ #include +/*! + Types dealing with various kinds of resource paths +*/ + namespace type { - struct UnixPathSegment { - char string[while(std::mem::read_unsigned($, 1) != '/' && std::mem::read_unsigned($, 1) != 0x00)]; + /** + Type representing a single path segment. Use the `Path` type instead of using this on its own + @tparam Delimeter The delimeter sequence used to separate two path segments + */ + struct PathSegment { + char string[while(std::mem::read_string($, std::string::length(Delimeter)) != Delimeter && std::mem::read_unsigned($, 1) != 0x00)]; char separator [[hidden]]; if (separator == 0x00) { $ -= 1; break; } - } [[sealed, format("type::impl::format_unix_path_segment")]]; + } [[sealed, format("type::impl::format_path_segment")]]; - struct UnixPath { - UnixPathSegment segments[while(true)]; - } [[format("type::impl::format_unix_path")]]; + /** + A generic type representing a path with an arbitrary delimeter + @tparam Delimeter The delimeter sequence used to separate two path segments + */ + struct Path { + PathSegment segments[while(true)]; + } [[format("type::impl::format_path")]]; + /** + A type representing a Unix path using a '/' forwardslash as delimeter + */ + using UnixPath = Path<"/">; + + /** + A type representing a DOS path using a '\' backslash as delimeter + */ + using DOSPath = Path<"\\">; namespace impl { - fn format_unix_path_segment(UnixPathSegment segment) { + fn format_path_segment(PathSegment segment) { return segment.string; }; - fn format_unix_path(UnixPath path) { + fn format_path(Path path) { return std::mem::read_string($, sizeof(path)); }; diff --git a/includes/type/size.pat b/includes/type/size.pat index 63027e7..25d0655 100644 --- a/includes/type/size.pat +++ b/includes/type/size.pat @@ -1,13 +1,36 @@ #include +/*! + Types used to pretty print size values +*/ + namespace type { + /** + A generic size type which displays its value in Bytes (or kiB, MiB, GiB, TiB, PiB, EiB if larger) + @tparam T Underlying type + */ using Size = T [[format("type::impl::size_formatter")]]; + /** + A 8 bit size type + */ using Size8 = Size; + /** + A 16 bit size type + */ using Size16 = Size; + /** + A 32 bit size type + */ using Size32 = Size; + /** + A 64 bit size type + */ using Size64 = Size; + /** + A 128 bit size type + */ using Size128 = Size; namespace impl { diff --git a/includes/type/time.pat b/includes/type/time.pat index e981f98..a42beef 100644 --- a/includes/type/time.pat +++ b/includes/type/time.pat @@ -3,12 +3,36 @@ #include #include +/*! + Types used to decode various different time formats +*/ + namespace type { + /** + A 32 bit Unix time value + */ using time32_t = u32 [[format("type::impl::format_time_t")]]; + + /** + Alias name for `time32_t` + */ + using time_t = time32_t; + + /** + A 64 bit Unix time value + */ using time64_t = u64 [[format("type::impl::format_time_t")]]; - using dosdate16_t = u16 [[format("type::impl::format_dosdate16_t")]]; - using dostime16_t = u16 [[format("type::impl::format_dostime16_t")]]; + + /** + A DOS Date value + */ + using DOSDate = u16 [[format("type::impl::format_dosdate")]]; + + /** + A DOS Time value + */ + using DOSTime = u16 [[format("type::impl::format_dostime")]]; namespace impl { @@ -16,11 +40,11 @@ namespace type { return std::time::format(std::time::to_utc(value)); }; - fn format_dosdate16_t(u16 value) { + fn format_dosdate(u16 value) { return std::time::format_dos_date(std::time::to_dos_date(value)); }; - fn format_dostime16_t(u16 value) { + fn format_dostime(u16 value) { return std::time::format_dos_time(std::time::to_dos_time(value)); }; diff --git a/includes/type/types/010.pat b/includes/type/types/010.pat index e473f7d..0aa6c3b 100644 --- a/includes/type/types/010.pat +++ b/includes/type/types/010.pat @@ -1,5 +1,9 @@ #pragma once +/*! + Alias types to make it easier to move template definitions over from 010 Editor to ImHex +*/ + // Explicitly don't add these types to the `type` namespace for usability // namespace type { diff --git a/includes/type/types/c.pat b/includes/type/types/c.pat index 4197200..fbb2dd9 100644 --- a/includes/type/types/c.pat +++ b/includes/type/types/c.pat @@ -1,5 +1,9 @@ #pragma once +/*! + Alias definitions for all C stdint and regular data types +*/ + // Explicitly don't add these types to the `type` namespace for usability // namespace type { diff --git a/includes/type/types/linux.pat b/includes/type/types/linux.pat index 8dd02da..102d836 100644 --- a/includes/type/types/linux.pat +++ b/includes/type/types/linux.pat @@ -1,5 +1,9 @@ #pragma once +/*! + Various data types used in the Linux Kernel +*/ + // Explicitly don't add these types to the `type` namespace for usability // namespace type { diff --git a/includes/type/types/rust.pat b/includes/type/types/rust.pat index a55c056..b91b48e 100644 --- a/includes/type/types/rust.pat +++ b/includes/type/types/rust.pat @@ -1,5 +1,9 @@ #pragma once +/*! + Alias definitions for Rust's data types +*/ + // Explicitly don't add these types to the `type` namespace for usability // namespace type { diff --git a/includes/type/types/win32.pat b/includes/type/types/win32.pat index 892fca2..2646690 100644 --- a/includes/type/types/win32.pat +++ b/includes/type/types/win32.pat @@ -1,5 +1,9 @@ #pragma once +/*! + Alias definitions for various type names used in Windows applications +*/ + // Explicitly don't add these types to the `type` namespace for usability // namespace type {