mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-31 13:25:58 -05:00
Compare commits
27 Commits
ImHex-v1.3
...
ImHex-v1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4299243e95 | ||
|
|
23b3c2b5d0 | ||
|
|
da1c2687e8 | ||
|
|
18f968df5b | ||
|
|
f797c711ca | ||
|
|
5380877da4 | ||
|
|
bb46276bde | ||
|
|
4242869ac1 | ||
|
|
8bdcd814a9 | ||
|
|
d7811ff5e9 | ||
|
|
4d0b3e21bc | ||
|
|
acd6903b21 | ||
|
|
8d2a39f7d4 | ||
|
|
65ef3a7783 | ||
|
|
21a0b99eac | ||
|
|
a33b68921d | ||
|
|
a0bb71be58 | ||
|
|
c7fc39ac19 | ||
|
|
b540ead0ae | ||
|
|
26878548f0 | ||
|
|
e4c9d86755 | ||
|
|
2a3de1b705 | ||
|
|
e02280f9ee | ||
|
|
bbba68cef7 | ||
|
|
28b281b403 | ||
|
|
c807959d75 | ||
|
|
3416d30f2b |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,4 +1,4 @@
|
||||
*.pat linguist-language=Rust
|
||||
*.hexpat linguist-language=Rust
|
||||
|
||||
tests/patterns/test_data/* binary
|
||||
tests/patterns/test_data/** binary
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
|
||||
tests/cmake-build-debug/
|
||||
tests/cmake*/
|
||||
tests/build*/
|
||||
|
||||
.idea/
|
||||
.DS_Store
|
||||
@@ -62,7 +62,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| GGUF | | [`patterns/gguf.hexpat`](patterns/gguf.hexpat) | GGML Inference Models |
|
||||
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
|
||||
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
|
||||
| Halo Bitmap || [`patterns/hinf_bitmap.hexpat`](patterns/hinf_bitmap.hexpat) | Halo Infinite Bitmap tag files |
|
||||
| Halo Tag || [`patterns/hinf_tag.hexpat`](patterns/hinf_tag.hexpat) | Halo Infinite Tag Files |
|
||||
| Halo Module || [`patterns/hinf_module.hexpat`](patterns/hinf_module.hexpat) | Halo Infinite Module Archive Files |
|
||||
| Halo HavokScript || [`patterns/hinf_luas.hexpat`](patterns/hinf_luas.hexpat) | Halo Infinite HavokScript 5.1 Bytecode |
|
||||
| ICO | | [`patterns/ico.hexpat`](patterns/ico.hexpat) | Icon (.ico) or Cursor (.cur) files |
|
||||
| ID3 | `audio/mpeg` | [`patterns/id3.hexpat`](patterns/id3.hexpat) | ID3 tags in MP3 files |
|
||||
@@ -96,6 +97,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
||||
| psafe3 | | [`patterns/psafe3.hexpat`](patterns/psafe3.hexpat`) | Password Safe V3 |
|
||||
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
|
||||
| PYC | | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
|
||||
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
|
||||
@@ -112,6 +114,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| TAR | `application/x-tar` | [`patterns/tar.hexpat`](patterns/tar.hexpat) | Tar file format |
|
||||
| TIFF | `image/tiff` | [`patterns/tiff.hexpat`](patterns/tiff.hexpat) | Tag Image File Format |
|
||||
| TGA | `image/tga` | [`patterns/tga.hexpat`](patterns/tga.hexpat) | Truevision TGA/TARGA image |
|
||||
| TTF | `font/ttf`, `font/otf` | [`patterns/ttf.hexpat`](patterns/ttf.hexpat) | TrueType and OpenType font format |
|
||||
| Ubiquiti | | [`patterns/ubiquiti.hexpat`](patterns/ubiquiti.hexpat) | Ubiquiti Firmware (update) image |
|
||||
| UEFI | | [`patterns/uefi.hexpat`](patterns/uefi.hexpat)` | UEFI structs for parsing efivars |
|
||||
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
|
||||
|
||||
@@ -60,5 +60,16 @@ namespace auto hex::dec {
|
||||
fn zstd_decompress(ref auto pattern, std::mem::Section section) {
|
||||
return builtin::hex::dec::zstd_decompress(pattern, section);
|
||||
};
|
||||
|
||||
/**
|
||||
Decompresses the bytes of a pattern into a section using the lz4 algorithm
|
||||
@param pattern The pattern whose bytes should be decompressed
|
||||
@param section The section to decompress the data into
|
||||
@param frame Whether the data is framed or not
|
||||
@return true if successful, false otherwise
|
||||
*/
|
||||
fn lz4_decompress(ref auto pattern, std::mem::Section section, bool frame = true) {
|
||||
return builtin::hex::dec::lz4_decompress(pattern, section, frame);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -11,20 +11,20 @@ import hex.dec;
|
||||
*/
|
||||
|
||||
namespace auto hex::type {
|
||||
|
||||
|
||||
/**
|
||||
A mangled name string that gets demangled when displayed
|
||||
*/
|
||||
struct MangledName {
|
||||
char value[];
|
||||
} [[sealed, format("hex::type::impl::format_mangled_name")]];
|
||||
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_mangled_name(ref MangledName name) {
|
||||
return hex::dec::demangle(name.value);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
import std.sys;
|
||||
import std.core;
|
||||
|
||||
/*!
|
||||
The array library contains a helper type to make it easier to create multi-dimensional arrays
|
||||
@@ -30,6 +31,16 @@ namespace auto std {
|
||||
std::assert($ - startAddress == NumBytes, "Not enough bytes available to fit a whole number of types");
|
||||
} [[format("std::impl::format_array")]];
|
||||
|
||||
|
||||
/**
|
||||
An interface type for getting the index of the currently processed element in an array. This is a nice wrapper around `std::core::array_index()`
|
||||
|
||||
To use it, inherit from it and use the `this.index` field to get the index of the current element
|
||||
*/
|
||||
struct IIndexed {
|
||||
const u64 index = std::core::array_index();
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_array(ref auto array) {
|
||||
|
||||
@@ -3,61 +3,65 @@
|
||||
import std.limits;
|
||||
|
||||
/*!
|
||||
This library contains various helper functions for common bit operations.
|
||||
This library contains various helper functions for common bit operations.
|
||||
*/
|
||||
|
||||
namespace auto std::bit {
|
||||
|
||||
/**
|
||||
Calculates the number of 1 bits in a given number
|
||||
@param x The number
|
||||
@return The number of bits set to 1 in `x`
|
||||
*/
|
||||
fn popcount(u128 x) {
|
||||
x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3));
|
||||
x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5));
|
||||
x = (x & (std::limits::u128_max() / 17)) + ((x >> 4) & (std::limits::u128_max() / 17));
|
||||
|
||||
return x % 0xFF;
|
||||
};
|
||||
/**
|
||||
Calculates the number of 1 bits in a given number
|
||||
@param x The number
|
||||
@return The number of bits set to 1 in `x`
|
||||
*/
|
||||
fn popcount(u128 x) {
|
||||
const u128 a = 0x55555555555555555555555555555555;
|
||||
const u128 b = 0x33333333333333333333333333333333;
|
||||
const u128 c = 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F;
|
||||
|
||||
/**
|
||||
Checks if only a single bit is set to 1 in a given number
|
||||
@param x The number
|
||||
@return True if there's a single bit set to 1 in `x`, false otherwise
|
||||
*/
|
||||
fn has_single_bit(u128 x) {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Rounds the given number up to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next bigger power of two that can fit `x`
|
||||
*/
|
||||
fn bit_ceil(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((1 << i) < x)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << i;
|
||||
};
|
||||
x = (x & a) + ((x >> 1) & a);
|
||||
x = (x & b) + ((x >> 2) & b);
|
||||
x = (x & c) + ((x >> 4) & c);
|
||||
|
||||
return x % 0xFF;
|
||||
};
|
||||
|
||||
/**
|
||||
Rounds the given number down to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next smaller power of two
|
||||
*/
|
||||
fn bit_floor(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((x >> i) > 0)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << (i - 1);
|
||||
};
|
||||
/**
|
||||
Checks if only a single bit is set to 1 in a given number
|
||||
@param x The number
|
||||
@return True if there's a single bit set to 1 in `x`, false otherwise
|
||||
*/
|
||||
fn has_single_bit(u128 x) {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Rounds the given number up to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next bigger power of two that can fit `x`
|
||||
*/
|
||||
fn bit_ceil(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((1 << i) < x)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << i;
|
||||
};
|
||||
|
||||
/**
|
||||
Rounds the given number down to the next bigger power of two
|
||||
@param x The number
|
||||
@return Next smaller power of two
|
||||
*/
|
||||
fn bit_floor(u128 x) {
|
||||
if (x == 0) return 0;
|
||||
|
||||
u8 i;
|
||||
while ((x >> i) > 0)
|
||||
i = i + 1;
|
||||
|
||||
return 1 << (i - 1);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -164,4 +164,13 @@ namespace auto std::core {
|
||||
fn set_pattern_comment(ref auto pattern, str comment) {
|
||||
builtin::std::core::set_pattern_comment(pattern, name);
|
||||
};
|
||||
|
||||
/**
|
||||
Executes the function with the given name, passing in all given arguments
|
||||
@param function_name The namespace-prefixed name of the function
|
||||
@param args Arguments to pass to the function
|
||||
*/
|
||||
fn execute_function(str function_name, auto ... args) {
|
||||
builtin::std::core::execute_function(function_name, args);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
The File library allows reading and writing from/to external files using
|
||||
a C-like File IO API.
|
||||
The File library allows reading and writing from/to external files using
|
||||
a C-like File IO API.
|
||||
|
||||
**These functions are considered dangerous and require the user to manually permit them**
|
||||
**These functions are considered dangerous and require the user to manually permit them**
|
||||
*/
|
||||
|
||||
namespace auto std::file {
|
||||
|
||||
/**
|
||||
/**
|
||||
A handle representing a file that has been opened
|
||||
*/
|
||||
using Handle = s32;
|
||||
|
||||
/**
|
||||
using Handle = s32;
|
||||
|
||||
/**
|
||||
The mode to open a file in.
|
||||
Read opens the file in read-only mode
|
||||
Write opens the file in read and write mode
|
||||
Create creates a new file if it doesn't exist and overwrites an existing file
|
||||
Read opens the file in read-only mode
|
||||
Write opens the file in read and write mode
|
||||
Create creates a new file if it doesn't exist and overwrites an existing file
|
||||
*/
|
||||
enum Mode : u8 {
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
Create = 3
|
||||
};
|
||||
enum Mode : u8 {
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
Create = 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Opens a file
|
||||
@param path The path to the file to open
|
||||
@param mode File open mode
|
||||
@return Handle to the newly opened file
|
||||
@param path The path to the file to open
|
||||
@param mode File open mode
|
||||
@return Handle to the newly opened file
|
||||
*/
|
||||
fn open(str path, Mode mode) {
|
||||
return builtin::std::file::open(path, u32(mode));
|
||||
};
|
||||
fn open(str path, Mode mode) {
|
||||
return builtin::std::file::open(path, u32(mode));
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
Closes a file handle that has been opened previously
|
||||
@param handle The handle to close
|
||||
@param handle The handle to close
|
||||
*/
|
||||
fn close(Handle handle) {
|
||||
builtin::std::file::close(handle);
|
||||
};
|
||||
fn close(Handle handle) {
|
||||
builtin::std::file::close(handle);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
Reads the content of a file into a string
|
||||
@param handle The file handle to read from
|
||||
@param size Number of bytes to read
|
||||
@return String containing the read data
|
||||
@param handle The file handle to read from
|
||||
@param size Number of bytes to read
|
||||
@return String containing the read data
|
||||
*/
|
||||
fn read(Handle handle, u64 size) {
|
||||
return builtin::std::file::read(handle, size);
|
||||
};
|
||||
fn read(Handle handle, u64 size) {
|
||||
return builtin::std::file::read(handle, size);
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
Writes the content of a string into a file
|
||||
@param handle The file handle to write to
|
||||
@param data String or Pattern to write to the file
|
||||
@param handle The file handle to write to
|
||||
@param data String or Pattern to write to the file
|
||||
*/
|
||||
fn write(Handle handle, auto data) {
|
||||
builtin::std::file::write(handle, data);
|
||||
};
|
||||
fn write(Handle handle, auto data) {
|
||||
builtin::std::file::write(handle, data);
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
Sets the current cursor position in the given file handle
|
||||
@param handle The file handle to set the cursor position in
|
||||
@param offset The offset to move the cursor to
|
||||
@param handle The file handle to set the cursor position in
|
||||
@param offset The offset to move the cursor to
|
||||
*/
|
||||
fn seek(Handle handle, u64 offset) {
|
||||
builtin::std::file::seek(handle, offset);
|
||||
};
|
||||
fn seek(Handle handle, u64 offset) {
|
||||
builtin::std::file::seek(handle, offset);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Queries the size of a file
|
||||
@param handle The handle of the file to get the size of
|
||||
@return The file's size
|
||||
*/
|
||||
fn size(Handle handle) {
|
||||
return builtin::std::file::size(handle);
|
||||
};
|
||||
/**
|
||||
Queries the size of a file
|
||||
@param handle The handle of the file to get the size of
|
||||
@return The file's size
|
||||
*/
|
||||
fn size(Handle handle) {
|
||||
return builtin::std::file::size(handle);
|
||||
};
|
||||
|
||||
/**
|
||||
Resizes a file
|
||||
@param handle The handle of the file to resize
|
||||
*/
|
||||
fn resize(Handle handle, u64 size) {
|
||||
builtin::std::file::resize(handle, size);
|
||||
};
|
||||
/**
|
||||
Resizes a file
|
||||
@param handle The handle of the file to resize
|
||||
*/
|
||||
fn resize(Handle handle, u64 size) {
|
||||
builtin::std::file::resize(handle, size);
|
||||
};
|
||||
|
||||
/**
|
||||
Flushes changes made to a file to disk
|
||||
@param handle The handle of the file to flush
|
||||
*/
|
||||
fn flush(Handle handle) {
|
||||
builtin::std::file::flush(handle);
|
||||
};
|
||||
/**
|
||||
Flushes changes made to a file to disk
|
||||
@param handle The handle of the file to flush
|
||||
*/
|
||||
fn flush(Handle handle) {
|
||||
builtin::std::file::flush(handle);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Deletes a file from disk. This will also automatically close this file
|
||||
@param handle The handle of the file to delete
|
||||
*/
|
||||
fn remove(Handle handle) {
|
||||
builtin::std::file::remove(handle);
|
||||
};
|
||||
/**
|
||||
Deletes a file from disk. This will also automatically close this file
|
||||
@param handle The handle of the file to delete
|
||||
*/
|
||||
fn remove(Handle handle) {
|
||||
builtin::std::file::remove(handle);
|
||||
};
|
||||
|
||||
/**
|
||||
Create all directories for the provided path
|
||||
@param path The path for which all directories should be created
|
||||
*/
|
||||
fn create_directories(str path) {
|
||||
builtin::std::file::create_directories(path);
|
||||
};
|
||||
/**
|
||||
Create all directories for the provided path
|
||||
@param path The path for which all directories should be created
|
||||
*/
|
||||
fn create_directories(str path) {
|
||||
builtin::std::file::create_directories(path);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,89 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
|
||||
Library for doing arithmetic with fixed point numbers and converting them from/to floating point numbers.
|
||||
*/
|
||||
|
||||
namespace auto std::fxpt {
|
||||
|
||||
/**
|
||||
A fixed point value
|
||||
*/
|
||||
using fixed = s128;
|
||||
/**
|
||||
A fixed point value
|
||||
*/
|
||||
using fixed = s128;
|
||||
|
||||
/**
|
||||
Converts a fixed point value into a floating point value
|
||||
@param fxt The fixed point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The floating point representation of fxt
|
||||
*/
|
||||
fn to_float(fixed fxt, u32 precision) {
|
||||
return double(fxt) / double((1 << precision));
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a floating point value into a fixed point value
|
||||
@param flt The floating point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The fixed point representation of flt
|
||||
*/
|
||||
fn to_fixed(double flt, u32 precision) {
|
||||
return s128((flt * (1 << precision)));
|
||||
};
|
||||
/**
|
||||
Converts a fixed point value into a floating point value
|
||||
@param fxt The fixed point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The floating point representation of fxt
|
||||
*/
|
||||
fn to_float(fixed fxt, u32 precision) {
|
||||
return double(fxt) / double((1 << precision));
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a floating point value into a fixed point value
|
||||
@param flt The floating point value to convert
|
||||
@param precision The bits of precision the new value should have
|
||||
@return The fixed point representation of flt
|
||||
*/
|
||||
fn to_fixed(double flt, u32 precision) {
|
||||
return s128((flt * (1 << precision)));
|
||||
};
|
||||
|
||||
/**
|
||||
Changes the number of bits used to represent the decimal part of the given fixed point number
|
||||
@param value The fixed point value to convert
|
||||
@param start_precision The current number of bits used
|
||||
@param end_precision The new number of bits used
|
||||
@return `value` as a new fixed point number with `end_precision` bits of precision
|
||||
*/
|
||||
fn change_precision(fixed value, u32 start_precision, u32 end_precision) {
|
||||
return std::fxpt::to_fixed(std::fxpt::to_float(value, start_precision), end_precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Adds two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the addition of `a` and `b`
|
||||
*/
|
||||
fn add(fixed a, fixed b, u32 precision) {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
/**
|
||||
Subtracts two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the subtraction of `a` and `b`
|
||||
*/
|
||||
fn subtract(fixed a, fixed b, u32 precision) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
/**
|
||||
Multiplies two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the multiplication of `a` and `b`
|
||||
*/
|
||||
fn multiply(fixed a, fixed b, u32 precision) {
|
||||
return (a * b) / (1 << precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Divides two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the division of `a` and `b`
|
||||
*/
|
||||
fn divide(fixed a, fixed b, u32 precision) {
|
||||
return (a << precision) / b;
|
||||
};
|
||||
/**
|
||||
Changes the number of bits used to represent the decimal part of the given fixed point number
|
||||
@param value The fixed point value to convert
|
||||
@param start_precision The current number of bits used
|
||||
@param end_precision The new number of bits used
|
||||
@return `value` as a new fixed point number with `end_precision` bits of precision
|
||||
*/
|
||||
fn change_precision(fixed value, u32 start_precision, u32 end_precision) {
|
||||
return std::fxpt::to_fixed(std::fxpt::to_float(value, start_precision), end_precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Adds two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the addition of `a` and `b`
|
||||
*/
|
||||
fn add(fixed a, fixed b, u32 precision) {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
/**
|
||||
Subtracts two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the subtraction of `a` and `b`
|
||||
*/
|
||||
fn subtract(fixed a, fixed b, u32 precision) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
/**
|
||||
Multiplies two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the multiplication of `a` and `b`
|
||||
*/
|
||||
fn multiply(fixed a, fixed b, u32 precision) {
|
||||
return (a * b) / (1 << precision);
|
||||
};
|
||||
|
||||
/**
|
||||
Divides two fixed point numbers with a given precision together
|
||||
@param a First fixed point number
|
||||
@param b Second fixed point number
|
||||
@param precision The precision of `a` and `b`
|
||||
@return Result of the division of `a` and `b`
|
||||
*/
|
||||
fn divide(fixed a, fixed b, u32 precision) {
|
||||
return (a << precision) / b;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,37 @@
|
||||
|
||||
namespace auto std::hash {
|
||||
|
||||
/**
|
||||
Calculates the CRC8 hash of the bytes inside of a given pattern
|
||||
@param pattern The pattern to calculate the CRC8 hash of
|
||||
@param init The CRC8 init value
|
||||
@param poly The CRC8 polynomial
|
||||
@param xorout The CRC8 XOR-Out value
|
||||
@param reflect_in Whether or not the input bytes should be reflected
|
||||
@param reflect_out Whether or not the output should be reflected
|
||||
@return Calculated CRC8 hash
|
||||
*/
|
||||
fn crc8(ref auto pattern, u8 init, u8 poly, u8 xorout, bool reflect_in, bool reflect_out) {
|
||||
return builtin::std::hash::crc8(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the CRC16 hash of the bytes inside of a given pattern
|
||||
@param pattern The pattern to calculate the CRC16 hash of
|
||||
@param init The CRC16 init value
|
||||
@param poly The CRC16 polynomial
|
||||
@param xorout The CRC16 XOR-Out value
|
||||
@param reflect_in Whether or not the input bytes should be reflected
|
||||
@param reflect_out Whether or not the output should be reflected
|
||||
@return Calculated CRC16 hash
|
||||
*/
|
||||
fn crc16(ref auto pattern, u16 init, u16 poly, u16 xorout, bool reflect_in, bool reflect_out) {
|
||||
return builtin::std::hash::crc16(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the CRC32 hash of the bytes inside of a given pattern
|
||||
@param pattern The pattern to calculate the crc32 hash of
|
||||
@param pattern The pattern to calculate the CRC32 hash of
|
||||
@param init The CRC32 init value
|
||||
@param poly The CRC32 polynomial
|
||||
@param xorout The CRC32 XOR-Out value
|
||||
@@ -20,4 +48,18 @@ namespace auto std::hash {
|
||||
return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the CRC64 hash of the bytes inside of a given pattern
|
||||
@param pattern The pattern to calculate the CRC64 hash of
|
||||
@param init The CRC64 init value
|
||||
@param poly The CRC64 polynomial
|
||||
@param xorout The CRC64 XOR-Out value
|
||||
@param reflect_in Whether or not the input bytes should be reflected
|
||||
@param reflect_out Whether or not the output should be reflected
|
||||
@return Calculated CRC64 hash
|
||||
*/
|
||||
fn crc64(ref auto pattern, u64 init, u64 poly, u64 xorout, bool reflect_in, bool reflect_out) {
|
||||
return builtin::std::hash::crc64(pattern, init, poly, xorout, reflect_in, reflect_out);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,169 +1,169 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
Library to calculate the minimum and maximum values that fit into a given data type
|
||||
Library to calculate the minimum and maximum values that fit into a given data type
|
||||
*/
|
||||
|
||||
namespace auto 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 `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
|
||||
*/
|
||||
/**
|
||||
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));
|
||||
};
|
||||
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));
|
||||
};
|
||||
|
||||
/**
|
||||
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));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -3,338 +3,338 @@
|
||||
import std.mem;
|
||||
|
||||
/*!
|
||||
Library containing more advanced mathematical operations.
|
||||
Library containing more advanced mathematical operations.
|
||||
*/
|
||||
|
||||
namespace auto std::math {
|
||||
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the smaller of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is smaller than `b`, otherwise `b`
|
||||
*/
|
||||
fn min(auto a, auto b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the bigger of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is bigger than `b`, otherwise `b`
|
||||
*/
|
||||
fn max(auto a, auto b) {
|
||||
if (a > b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Clamps the value of `x` between `min` and `max`.
|
||||
@param x Value
|
||||
@param min Minimum value
|
||||
@param max Maximum value
|
||||
@return `min` if `x` is smaller than `min`, `max` if `x` is bigger than `max`, `x` otherwise
|
||||
*/
|
||||
fn clamp(auto x, auto min, auto max) {
|
||||
if (x < min)
|
||||
return min;
|
||||
else if (x > max)
|
||||
return max;
|
||||
else
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the absolute value of `x`.
|
||||
@param x Value
|
||||
@return `x` if `x` is positive, `-x` otherwise
|
||||
*/
|
||||
fn abs(auto x) {
|
||||
if (x < 0)
|
||||
return -x;
|
||||
else
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the sign of `x`.
|
||||
@param x Value
|
||||
@return `1` if `x` is positive, `-1` if `x` is negative, `0` if `x` is zero
|
||||
*/
|
||||
fn sign(auto x) {
|
||||
if (x > 0)
|
||||
return 1;
|
||||
else if (x < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Copies the sign of `y` to `x`.
|
||||
@param x Value
|
||||
@param y Value
|
||||
@return `x` if `y` is positive, `-x` if `y` is negative
|
||||
*/
|
||||
fn copy_sign(auto x, auto y) {
|
||||
if (y >= 0)
|
||||
return std::math::abs(x);
|
||||
else
|
||||
return -std::math::abs(x);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the factorial of `x`.
|
||||
@param x Value
|
||||
@return Factorial of `x`
|
||||
*/
|
||||
fn factorial(u128 x) {
|
||||
u128 result;
|
||||
|
||||
result = x;
|
||||
while (x > 1) {
|
||||
x = x - 1;
|
||||
result = result * x;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the binomial coefficient of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Binomial coefficient of `n` and `k`
|
||||
*/
|
||||
fn comb(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
else
|
||||
return std::math::factorial(n) / (std::math::factorial(k) * std::math::factorial(n - k));
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the permutation of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Permutation of `n` and `k`
|
||||
*/
|
||||
fn perm(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
else
|
||||
return std::math::factorial(n) / std::math::factorial(n - k);
|
||||
};
|
||||
|
||||
/**
|
||||
Floors the value of `value`.
|
||||
@param value Value
|
||||
@return `value` floored
|
||||
*/
|
||||
fn floor(auto value) { return builtin::std::math::floor(value); };
|
||||
|
||||
/**
|
||||
Ceils the value of `value`.
|
||||
@param value Value
|
||||
@return `value` ceiled
|
||||
*/
|
||||
fn ceil(auto value) { return builtin::std::math::ceil(value); };
|
||||
|
||||
/**
|
||||
Rounds the value of `value`.
|
||||
@param value Value
|
||||
@return `value` rounded
|
||||
*/
|
||||
fn round(auto value) { return builtin::std::math::round(value); };
|
||||
|
||||
/**
|
||||
Truncates the value of `value`.
|
||||
@param value Value
|
||||
@return `value` truncated
|
||||
*/
|
||||
fn trunc(auto value) { return builtin::std::math::trunc(value); };
|
||||
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 10.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 10
|
||||
*/
|
||||
fn log10(auto value) { return builtin::std::math::log10(value); };
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 2.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 2
|
||||
*/
|
||||
fn log2(auto value) { return builtin::std::math::log2(value); };
|
||||
|
||||
/**
|
||||
Calculates the natural logarithm of `value`.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base `e`
|
||||
*/
|
||||
fn ln(auto value) { return builtin::std::math::ln(value); };
|
||||
|
||||
/**
|
||||
Calculates the floating point modulus of `value`.
|
||||
@param value Value
|
||||
@return Floating point modulus of `value`
|
||||
*/
|
||||
fn fmod(auto value) { return builtin::std::math::fmod(value); };
|
||||
|
||||
/**
|
||||
Calculates the value of `base` raised to the power of `exp`.
|
||||
@param base Base
|
||||
@param exp Exponent
|
||||
@return `base` raised to the power of `exp`
|
||||
*/
|
||||
fn pow(auto base, auto exp) { return builtin::std::math::pow(base, exp); };
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the smaller of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is smaller than `b`, otherwise `b`
|
||||
*/
|
||||
fn min(auto a, auto b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Compares the values `a` and `b` with each other and returns the bigger of the two
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@return `a` if `a` is bigger than `b`, otherwise `b`
|
||||
*/
|
||||
fn max(auto a, auto b) {
|
||||
if (a > b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the value of the natural number `e` raised to the power of `value`.
|
||||
@param value Exponent
|
||||
@return `e` raised to the power of `value`
|
||||
*/
|
||||
Clamps the value of `x` between `min` and `max`.
|
||||
@param x Value
|
||||
@param min Minimum value
|
||||
@param max Maximum value
|
||||
@return `min` if `x` is smaller than `min`, `max` if `x` is bigger than `max`, `x` otherwise
|
||||
*/
|
||||
fn clamp(auto x, auto min, auto max) {
|
||||
if (x < min)
|
||||
return min;
|
||||
else if (x > max)
|
||||
return max;
|
||||
else
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the absolute value of `x`.
|
||||
@param x Value
|
||||
@return `x` if `x` is positive, `-x` otherwise
|
||||
*/
|
||||
fn abs(auto x) {
|
||||
if (x < 0)
|
||||
return -x;
|
||||
else
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the sign of `x`.
|
||||
@param x Value
|
||||
@return `1` if `x` is positive, `-1` if `x` is negative, `0` if `x` is zero
|
||||
*/
|
||||
fn sign(auto x) {
|
||||
if (x > 0)
|
||||
return 1;
|
||||
else if (x < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Copies the sign of `y` to `x`.
|
||||
@param x Value
|
||||
@param y Value
|
||||
@return `x` if `y` is positive, `-x` if `y` is negative
|
||||
*/
|
||||
fn copy_sign(auto x, auto y) {
|
||||
if (y >= 0)
|
||||
return std::math::abs(x);
|
||||
else
|
||||
return -std::math::abs(x);
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the factorial of `x`.
|
||||
@param x Value
|
||||
@return Factorial of `x`
|
||||
*/
|
||||
fn factorial(u128 x) {
|
||||
u128 result;
|
||||
|
||||
result = x;
|
||||
while (x > 1) {
|
||||
x = x - 1;
|
||||
result = result * x;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the binomial coefficient of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Binomial coefficient of `n` and `k`
|
||||
*/
|
||||
fn comb(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
else
|
||||
return std::math::factorial(n) / (std::math::factorial(k) * std::math::factorial(n - k));
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the permutation of `n` and `k`.
|
||||
@param n Value
|
||||
@param k Value
|
||||
@return Permutation of `n` and `k`
|
||||
*/
|
||||
fn perm(u128 n, u128 k) {
|
||||
if (k > n)
|
||||
return 0;
|
||||
else
|
||||
return std::math::factorial(n) / std::math::factorial(n - k);
|
||||
};
|
||||
|
||||
/**
|
||||
Floors the value of `value`.
|
||||
@param value Value
|
||||
@return `value` floored
|
||||
*/
|
||||
fn floor(auto value) { return builtin::std::math::floor(value); };
|
||||
|
||||
/**
|
||||
Ceils the value of `value`.
|
||||
@param value Value
|
||||
@return `value` ceiled
|
||||
*/
|
||||
fn ceil(auto value) { return builtin::std::math::ceil(value); };
|
||||
|
||||
/**
|
||||
Rounds the value of `value`.
|
||||
@param value Value
|
||||
@return `value` rounded
|
||||
*/
|
||||
fn round(auto value) { return builtin::std::math::round(value); };
|
||||
|
||||
/**
|
||||
Truncates the value of `value`.
|
||||
@param value Value
|
||||
@return `value` truncated
|
||||
*/
|
||||
fn trunc(auto value) { return builtin::std::math::trunc(value); };
|
||||
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 10.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 10
|
||||
*/
|
||||
fn log10(auto value) { return builtin::std::math::log10(value); };
|
||||
|
||||
/**
|
||||
Calculates the logarithm of `value` with base 2.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base 2
|
||||
*/
|
||||
fn log2(auto value) { return builtin::std::math::log2(value); };
|
||||
|
||||
/**
|
||||
Calculates the natural logarithm of `value`.
|
||||
@param value Value
|
||||
@return Logarithm of `value` with base `e`
|
||||
*/
|
||||
fn ln(auto value) { return builtin::std::math::ln(value); };
|
||||
|
||||
/**
|
||||
Calculates the floating point modulus of `value`.
|
||||
@param value Value
|
||||
@return Floating point modulus of `value`
|
||||
*/
|
||||
fn fmod(auto value) { return builtin::std::math::fmod(value); };
|
||||
|
||||
/**
|
||||
Calculates the value of `base` raised to the power of `exp`.
|
||||
@param base Base
|
||||
@param exp Exponent
|
||||
@return `base` raised to the power of `exp`
|
||||
*/
|
||||
fn pow(auto base, auto exp) { return builtin::std::math::pow(base, exp); };
|
||||
|
||||
/**
|
||||
Calculates the value of the natural number `e` raised to the power of `value`.
|
||||
@param value Exponent
|
||||
@return `e` raised to the power of `value`
|
||||
*/
|
||||
fn exp(auto value) { return builtin::std::math::exp(value); };
|
||||
|
||||
/**
|
||||
Calculates the square root of `value`.
|
||||
@param value Value
|
||||
@return Square root of `value`
|
||||
*/
|
||||
fn sqrt(auto value) { return builtin::std::math::sqrt(value); };
|
||||
/**
|
||||
Calculates the square root of `value`.
|
||||
@param value Value
|
||||
@return Square root of `value`
|
||||
*/
|
||||
fn sqrt(auto value) { return builtin::std::math::sqrt(value); };
|
||||
|
||||
/**
|
||||
Calculates the cubic root of `value`.
|
||||
@param value Value
|
||||
@return Cubic root of `value`
|
||||
*/
|
||||
fn cbrt(auto value) { return builtin::std::math::cbrt(value); };
|
||||
/**
|
||||
Calculates the cubic root of `value`.
|
||||
@param value Value
|
||||
@return Cubic root of `value`
|
||||
*/
|
||||
fn cbrt(auto value) { return builtin::std::math::cbrt(value); };
|
||||
|
||||
/**
|
||||
Calculates the sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Sine of `value`
|
||||
*/
|
||||
fn sin(auto value) { return builtin::std::math::sin(value); };
|
||||
/**
|
||||
Calculates the sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Sine of `value`
|
||||
*/
|
||||
fn sin(auto value) { return builtin::std::math::sin(value); };
|
||||
|
||||
/**
|
||||
Calculates the cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Cosine of `value`
|
||||
*/
|
||||
fn cos(auto value) { return builtin::std::math::cos(value); };
|
||||
/**
|
||||
Calculates the cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Cosine of `value`
|
||||
*/
|
||||
fn cos(auto value) { return builtin::std::math::cos(value); };
|
||||
|
||||
/**
|
||||
Calculates the tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Tangent of `value`
|
||||
*/
|
||||
fn tan(auto value) { return builtin::std::math::tan(value); };
|
||||
/**
|
||||
Calculates the tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Tangent of `value`
|
||||
*/
|
||||
fn tan(auto value) { return builtin::std::math::tan(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Arc sine of `value`
|
||||
*/
|
||||
fn asin(auto value) { return builtin::std::math::asin(value); };
|
||||
/**
|
||||
Calculates the arc sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Arc sine of `value`
|
||||
*/
|
||||
fn asin(auto value) { return builtin::std::math::asin(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc cosine of `value` in radians
|
||||
*/
|
||||
fn acos(auto value) { return builtin::std::math::acos(value); };
|
||||
/**
|
||||
Calculates the arc cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc cosine of `value` in radians
|
||||
*/
|
||||
fn acos(auto value) { return builtin::std::math::acos(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc tangent of `value` in radians between `-pi/2` and `pi/2`
|
||||
*/
|
||||
fn atan(auto value) { return builtin::std::math::atan(value); };
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc tangent of `value` in radians between `-pi/2` and `pi/2`
|
||||
*/
|
||||
fn atan(auto value) { return builtin::std::math::atan(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param y Value representing the proportion of the y-coordinate
|
||||
@param x Value representing the proportion of the x-coordinate.
|
||||
@return Arc tangent of `value` in radians between `-pi` and `pi`
|
||||
*/
|
||||
fn atan2(auto y, auto x) { return builtin::std::math::atan2(y, x); };
|
||||
/**
|
||||
Calculates the arc tangent of `value`.
|
||||
@param y Value representing the proportion of the y-coordinate
|
||||
@param x Value representing the proportion of the x-coordinate.
|
||||
@return Arc tangent of `value` in radians between `-pi` and `pi`
|
||||
*/
|
||||
fn atan2(auto y, auto x) { return builtin::std::math::atan2(y, x); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic sine of `value`
|
||||
*/
|
||||
fn sinh(auto value) { return builtin::std::math::sinh(value); };
|
||||
/**
|
||||
Calculates the hyperbolic sine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic sine of `value`
|
||||
*/
|
||||
fn sinh(auto value) { return builtin::std::math::sinh(value); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic cosine of `value`
|
||||
*/
|
||||
fn cosh(auto value) { return builtin::std::math::cosh(value); };
|
||||
/**
|
||||
Calculates the hyperbolic cosine of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic cosine of `value`
|
||||
*/
|
||||
fn cosh(auto value) { return builtin::std::math::cosh(value); };
|
||||
|
||||
/**
|
||||
Calculates the hyperbolic tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic tangent of `value`
|
||||
*/
|
||||
fn tanh(auto value) { return builtin::std::math::tanh(value); };
|
||||
/**
|
||||
Calculates the hyperbolic tangent of `value`.
|
||||
@param value Angle value in radians
|
||||
@return Hyperbolic tangent of `value`
|
||||
*/
|
||||
fn tanh(auto value) { return builtin::std::math::tanh(value); };
|
||||
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic sine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic sine of `value`
|
||||
*/
|
||||
fn asinh(auto value) { return builtin::std::math::asinh(value); };
|
||||
/**
|
||||
Calculates the arc hyperbolic sine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic sine of `value`
|
||||
*/
|
||||
fn asinh(auto value) { return builtin::std::math::asinh(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic cosine of `value`
|
||||
*/
|
||||
fn acosh(auto value) { return builtin::std::math::acosh(value); };
|
||||
/**
|
||||
Calculates the arc hyperbolic cosine of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic cosine of `value`
|
||||
*/
|
||||
fn acosh(auto value) { return builtin::std::math::acosh(value); };
|
||||
|
||||
/**
|
||||
Calculates the arc hyperbolic tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic tangent of `value`
|
||||
*/
|
||||
fn atanh(auto value) { return builtin::std::math::atanh(value); };
|
||||
/**
|
||||
Calculates the arc hyperbolic tangent of `value`.
|
||||
@param value Value
|
||||
@return Arc hyperbolic tangent of `value`
|
||||
*/
|
||||
fn atanh(auto value) { return builtin::std::math::atanh(value); };
|
||||
|
||||
|
||||
/**
|
||||
Options to use with the `std::math::accumulate` function.
|
||||
*/
|
||||
enum AccumulateOperation : u8 {
|
||||
Add = 0,
|
||||
Multiply = 1,
|
||||
Modulo = 2,
|
||||
Min = 3,
|
||||
Max = 4
|
||||
};
|
||||
/**
|
||||
Options to use with the `std::math::accumulate` function.
|
||||
*/
|
||||
enum AccumulateOperation : u8 {
|
||||
Add = 0,
|
||||
Multiply = 1,
|
||||
Modulo = 2,
|
||||
Min = 3,
|
||||
Max = 4
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the sum of all values in the specified memory range.
|
||||
@param start Start address
|
||||
@param end End address
|
||||
@param valueSize Size of each value in bytes
|
||||
@param [section] Section to use
|
||||
@param [operation] Operation to use. Defaults to addition
|
||||
@param [endian] Endianness to use. Defaults to native
|
||||
@return Sum of all values in the specified memory range
|
||||
*/
|
||||
fn accumulate(u128 start, u128 end, u128 valueSize, std::mem::Section section = 0, AccumulateOperation operation = AccumulateOperation::Add, std::mem::Endian endian = std::mem::Endian::Native) {
|
||||
return builtin::std::math::accumulate(start, end, valueSize, section, u128(operation), u128(endian));
|
||||
};
|
||||
|
||||
/**
|
||||
Calculates the sum of all values in the specified memory range.
|
||||
@param start Start address
|
||||
@param end End address
|
||||
@param valueSize Size of each value in bytes
|
||||
@param [section] Section to use
|
||||
@param [operation] Operation to use. Defaults to addition
|
||||
@param [endian] Endianness to use. Defaults to native
|
||||
@return Sum of all values in the specified memory range
|
||||
*/
|
||||
fn accumulate(u128 start, u128 end, u128 valueSize, std::mem::Section section = 0, AccumulateOperation operation = AccumulateOperation::Add, std::mem::Endian endian = std::mem::Endian::Native) {
|
||||
return builtin::std::math::accumulate(start, end, valueSize, section, u128(operation), u128(endian));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,18 +9,15 @@ namespace auto std::mem {
|
||||
namespace impl {
|
||||
|
||||
struct MagicSearchImpl<auto Magic, T> {
|
||||
if ($ < (std::mem::base_address() + std::mem::size() - std::string::length(Magic) - 1)) {
|
||||
char __potentialMagic__[std::string::length(Magic)] [[hidden, no_unique_address]];
|
||||
|
||||
if (__potentialMagic__ == Magic) {
|
||||
T data [[inline]];
|
||||
} else {
|
||||
padding[1];
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
padding[1];
|
||||
continue;
|
||||
s128 address = builtin::std::mem::find_string_in_range(0, $, builtin::std::mem::size(), Magic);
|
||||
if (address < 0)
|
||||
break;
|
||||
|
||||
$ = address;
|
||||
try {
|
||||
T data [[inline]];
|
||||
} catch {
|
||||
T data;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,7 +60,7 @@ namespace auto std::mem {
|
||||
|
||||
|
||||
/**
|
||||
Gets the base address of the memory
|
||||
Gets the base address of the data
|
||||
@return The base address of the memory
|
||||
*/
|
||||
fn base_address() {
|
||||
@@ -71,7 +68,7 @@ namespace auto std::mem {
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the size of the memory
|
||||
Gets the size of the data
|
||||
@return The size of the memory
|
||||
*/
|
||||
fn size() {
|
||||
@@ -79,17 +76,18 @@ namespace auto std::mem {
|
||||
};
|
||||
|
||||
/**
|
||||
Finds a sequence of bytes in the memory
|
||||
Finds a sequence of bytes in the data
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param bytes The bytes to find
|
||||
@return The address of the sequence
|
||||
*/
|
||||
fn find_sequence(u128 occurrence_index, auto ... bytes) {
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, builtin::std::mem::base_address(), builtin::std::mem::size(), bytes);
|
||||
const u128 address = builtin::std::mem::base_address();
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, address, address + builtin::std::mem::size(), bytes);
|
||||
};
|
||||
|
||||
/**
|
||||
Finds a sequence of bytes in a specific region of the memory
|
||||
Finds a sequence of bytes in a specific region of the data
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param offsetFrom The offset from which to start searching
|
||||
@param offsetTo The offset to which to search
|
||||
@@ -100,6 +98,30 @@ namespace auto std::mem {
|
||||
return builtin::std::mem::find_sequence_in_range(occurrence_index, offsetFrom, offsetTo, bytes);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Finds a string in the data
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param string The string to find
|
||||
@return The address of the sequence
|
||||
*/
|
||||
fn find_string(u128 occurrence_index, str string) {
|
||||
const u128 address = builtin::std::mem::base_address();
|
||||
return builtin::std::mem::find_string_in_range(occurrence_index, address, address + builtin::std::mem::size(), string);
|
||||
};
|
||||
|
||||
/**
|
||||
Finds a string in a specific region of the data
|
||||
@param occurrence_index The index of the occurrence to find
|
||||
@param offsetFrom The offset from which to start searching
|
||||
@param offsetTo The offset to which to search
|
||||
@param string The string to find
|
||||
@return The address of the sequence
|
||||
*/
|
||||
fn find_string_in_range(u128 occurrence_index, u128 offsetFrom, u128 offsetTo, str string) {
|
||||
return builtin::std::mem::find_string_in_range(occurrence_index, offsetFrom, offsetTo, string);
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a unsigned value from the memory
|
||||
@param address The address to read from
|
||||
@@ -132,14 +154,6 @@ namespace auto std::mem {
|
||||
return builtin::std::mem::read_string(address, size);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Gets the current bit offset within the current byte that a bitfield will read.
|
||||
*/
|
||||
fn current_bit_offset() {
|
||||
return builtin::std::mem::current_bit_offset();
|
||||
};
|
||||
|
||||
/**
|
||||
Reads a number of bits from the specified bit offset within the specified byte
|
||||
@param byteOffset The byte offset within the data
|
||||
@@ -211,6 +225,14 @@ namespace auto std::mem {
|
||||
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the current bit offset when inside of a bitfield.
|
||||
@return The current bit offset between 0 and 7
|
||||
*/
|
||||
fn current_bit_offset() {
|
||||
return builtin::std::mem::current_bit_offset();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Searches for a sequence of bytes and places the given type at that address
|
||||
|
||||
@@ -1,129 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
import std.io;
|
||||
import std.mem;
|
||||
|
||||
/*!
|
||||
Libray to interact with strings.
|
||||
Libray to interact with strings.
|
||||
*/
|
||||
|
||||
namespace auto std::string {
|
||||
|
||||
/**
|
||||
Base type for sized strings. Represents a string with its size preceeding it.
|
||||
@tparam SizeType The type of the size field.
|
||||
@tparam DataType The type of the characters.
|
||||
*/
|
||||
struct SizedStringBase<SizeType, DataType> {
|
||||
SizeType size;
|
||||
DataType data[size];
|
||||
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
|
||||
/**
|
||||
Base type for sized strings. Represents a string with its size preceeding it.
|
||||
@tparam SizeType The type of the size field.
|
||||
@tparam DataType The type of the characters.
|
||||
*/
|
||||
struct SizedStringBase<SizeType, DataType> {
|
||||
SizeType size;
|
||||
DataType data[size];
|
||||
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
|
||||
|
||||
/**
|
||||
A ASCII string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
|
||||
/**
|
||||
A ASCII string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
|
||||
|
||||
/**
|
||||
A UTF-16 string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
||||
/**
|
||||
A UTF-16 string with a prefixed size.
|
||||
@tparam SizeType The type of the size field.
|
||||
*/
|
||||
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
|
||||
|
||||
namespace impl {
|
||||
/**
|
||||
Base type for null-terminated strings. Represents a string with its size determined by the first 0x00 byte found.
|
||||
@tparam DataType The type of the characters.
|
||||
*/
|
||||
struct NullStringBase<DataType> {
|
||||
DataType string[while(std::mem::read_unsigned($, sizeof(DataType)) != 0x00)];
|
||||
DataType null_terminator;
|
||||
} [[sealed, format("std::string::impl::format_string"), transform("std::string::impl::format_string")]];
|
||||
|
||||
fn format_sized_string(ref auto string) {
|
||||
return string.data;
|
||||
};
|
||||
/**
|
||||
A null-terminated ASCII string.
|
||||
*/
|
||||
using NullString = NullStringBase<char>;
|
||||
|
||||
}
|
||||
/**
|
||||
A null-terminated UTF-16 string.
|
||||
*/
|
||||
using NullString16 = NullStringBase<char16>;
|
||||
|
||||
/**
|
||||
Gets the length of a string.
|
||||
@param string The string to get the length of.
|
||||
@return The length of the string.
|
||||
*/
|
||||
fn length(str string) {
|
||||
return builtin::std::string::length(string);
|
||||
};
|
||||
namespace impl {
|
||||
|
||||
/**
|
||||
Gets the character at a given index.
|
||||
@param string The string to get the character from.
|
||||
@param index The index of the character to get.
|
||||
@return The character at the given index.
|
||||
*/
|
||||
fn at(str string, u32 index) {
|
||||
return builtin::std::string::at(string, index);
|
||||
};
|
||||
fn format_string(ref auto string) {
|
||||
return string.data;
|
||||
};
|
||||
|
||||
/**
|
||||
Gets a substring of a string.
|
||||
@param string The string to get the substring from.
|
||||
@param pos The position of the first character of the substring.
|
||||
@param count The number of characters to get.
|
||||
@return The substring.
|
||||
*/
|
||||
fn substr(str string, u32 pos, u32 count) {
|
||||
return builtin::std::string::substr(string, pos, count);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
Gets the length of a string.
|
||||
@param string The string to get the length of.
|
||||
@return The length of the string.
|
||||
*/
|
||||
fn length(str string) {
|
||||
return builtin::std::string::length(string);
|
||||
};
|
||||
|
||||
/**
|
||||
Gets the character at a given index.
|
||||
@param string The string to get the character from.
|
||||
@param index The index of the character to get.
|
||||
@return The character at the given index.
|
||||
*/
|
||||
fn at(str string, u32 index) {
|
||||
return builtin::std::string::at(string, index);
|
||||
};
|
||||
|
||||
/**
|
||||
Gets a substring of a string.
|
||||
@param string The string to get the substring from.
|
||||
@param pos The position of the first character of the substring.
|
||||
@param count The number of characters to get.
|
||||
@return The substring.
|
||||
*/
|
||||
fn substr(str string, u32 pos, u32 count) {
|
||||
return builtin::std::string::substr(string, pos, count);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts a string to an integer.
|
||||
@param string The string to convert.
|
||||
@param base The base of the number.
|
||||
@return The integer.
|
||||
*/
|
||||
fn parse_int(str string, u8 base) {
|
||||
return builtin::std::string::parse_int(string, base);
|
||||
};
|
||||
/**
|
||||
Converts a string to an integer.
|
||||
@param string The string to convert.
|
||||
@param base The base of the number.
|
||||
@return The integer.
|
||||
*/
|
||||
fn parse_int(str string, u8 base) {
|
||||
return builtin::std::string::parse_int(string, base);
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to a float.
|
||||
@param string The string to convert.
|
||||
@return The float.
|
||||
*/
|
||||
fn parse_float(str string) {
|
||||
return builtin::std::string::parse_float(string);
|
||||
};
|
||||
/**
|
||||
Converts a string to a float.
|
||||
@param string The string to convert.
|
||||
@return The float.
|
||||
*/
|
||||
fn parse_float(str string) {
|
||||
return builtin::std::string::parse_float(string);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Converts any type to a string.
|
||||
@param x The value to convert.
|
||||
@return The string.
|
||||
*/
|
||||
/**
|
||||
Converts any type to a string.
|
||||
@param x The value to convert.
|
||||
@return The string.
|
||||
*/
|
||||
fn to_string(auto x) {
|
||||
return std::format("{}", x);
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if a string starts with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string starts with the substring, false otherwise.
|
||||
*/
|
||||
/**
|
||||
Checks if a string starts with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string starts with the substring, false otherwise.
|
||||
*/
|
||||
fn starts_with(str string, str part) {
|
||||
return std::string::substr(string, 0, std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if a string ends with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string ends with the substring, false otherwise.
|
||||
*/
|
||||
/**
|
||||
Checks if a string ends with a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string ends with the substring, false otherwise.
|
||||
*/
|
||||
fn ends_with(str string, str part) {
|
||||
return std::string::substr(string, std::string::length(string) - std::string::length(part), std::string::length(part)) == part;
|
||||
};
|
||||
|
||||
/**
|
||||
Checks if a string contains a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string contains the substring, false otherwise.
|
||||
*/
|
||||
/**
|
||||
Checks if a string contains a given substring.
|
||||
@param string The string to check.
|
||||
@param part The substring to check for.
|
||||
@return True if the string contains the substring, false otherwise.
|
||||
*/
|
||||
fn contains(str string, str part) {
|
||||
s32 string_len = std::string::length(string);
|
||||
s32 part_len = std::string::length(part);
|
||||
@@ -136,12 +156,12 @@ namespace auto std::string {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
Reverses a string.
|
||||
@param string The string to reverse.
|
||||
@return The reversed string.
|
||||
*/
|
||||
fn reverse(str string) {
|
||||
/**
|
||||
Reverses a string.
|
||||
@param string The string to reverse.
|
||||
@return The reversed string.
|
||||
*/
|
||||
fn reverse(str string) {
|
||||
str result;
|
||||
|
||||
s32 i;
|
||||
@@ -154,82 +174,82 @@ namespace auto std::string {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to upper case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
/**
|
||||
Converts a string to upper case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
fn to_upper(str string) {
|
||||
str result;
|
||||
|
||||
u32 i;
|
||||
char c;
|
||||
while (i < std::string::length(string)) {
|
||||
c = std::string::at(string, i);
|
||||
|
||||
if (c >= 'a' && c <= 'z')
|
||||
result = result + char(c - 0x20);
|
||||
else
|
||||
result = result + c;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to lower case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
fn to_lower(str string) {
|
||||
str result;
|
||||
|
||||
u32 i;
|
||||
char c;
|
||||
while (i < std::string::length(string)) {
|
||||
c = std::string::at(string, i);
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
result = result + char(c + 0x20);
|
||||
else
|
||||
result = result + c;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
str result;
|
||||
|
||||
u32 i;
|
||||
char c;
|
||||
while (i < std::string::length(string)) {
|
||||
c = std::string::at(string, i);
|
||||
|
||||
if (c >= 'a' && c <= 'z')
|
||||
result = result + char(c - 0x20);
|
||||
else
|
||||
result = result + c;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a string to lower case.
|
||||
@param string The string to convert.
|
||||
@return The converted string.
|
||||
*/
|
||||
fn to_lower(str string) {
|
||||
str result;
|
||||
|
||||
u32 i;
|
||||
char c;
|
||||
while (i < std::string::length(string)) {
|
||||
c = std::string::at(string, i);
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
result = result + char(c + 0x20);
|
||||
else
|
||||
result = result + c;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Replaces all occurrences of a substring with another substring.
|
||||
@param string The string to replace in.
|
||||
@param pattern The substring to replace.
|
||||
@param replace The substring to replace with.
|
||||
@return The string with the replacements.
|
||||
*/
|
||||
fn replace(str string, str pattern, str replace) {
|
||||
s32 string_len = std::string::length(string);
|
||||
s32 pattern_len = std::string::length(pattern);
|
||||
/**
|
||||
Replaces all occurrences of a substring with another substring.
|
||||
@param string The string to replace in.
|
||||
@param pattern The substring to replace.
|
||||
@param replace The substring to replace with.
|
||||
@return The string with the replacements.
|
||||
*/
|
||||
fn replace(str string, str pattern, str replace) {
|
||||
s32 string_len = std::string::length(string);
|
||||
s32 pattern_len = std::string::length(pattern);
|
||||
|
||||
if (pattern_len > string_len || pattern_len * string_len == 0 )
|
||||
return string;
|
||||
if (pattern_len > string_len || pattern_len * string_len == 0 )
|
||||
return string;
|
||||
|
||||
str result;
|
||||
s32 string_index;
|
||||
s32 remaining_len = string_len;
|
||||
while (pattern_len <= remaining_len) {
|
||||
if (std::string::substr(string, string_index, pattern_len) == pattern) {
|
||||
result += replace;
|
||||
string_index += pattern_len;
|
||||
} else {
|
||||
result += std::string::at(string, string_index);
|
||||
string_index += 1;
|
||||
}
|
||||
remaining_len = string_len - string_index;
|
||||
}
|
||||
result += std::string::substr(string, string_index, remaining_len );
|
||||
return result;
|
||||
};
|
||||
str result;
|
||||
s32 string_index;
|
||||
s32 remaining_len = string_len;
|
||||
while (pattern_len <= remaining_len) {
|
||||
if (std::string::substr(string, string_index, pattern_len) == pattern) {
|
||||
result += replace;
|
||||
string_index += pattern_len;
|
||||
} else {
|
||||
result += std::string::at(string, string_index);
|
||||
string_index += 1;
|
||||
}
|
||||
remaining_len = string_len - string_index;
|
||||
}
|
||||
result += std::string::substr(string, string_index, remaining_len );
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace auto std {
|
||||
|
||||
/**
|
||||
Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console
|
||||
@param conditoon The condition that is required to be true
|
||||
@param condition The condition that is required to be true
|
||||
@param message The message to print in case the assertion doesn't hold
|
||||
*/
|
||||
fn assert(bool condition, str message) {
|
||||
@@ -21,7 +21,7 @@ namespace auto std {
|
||||
|
||||
/**
|
||||
Asserts that a given value is true. If it's not, print the given message to the console as a warning
|
||||
@param conditoon The condition that is required to be true
|
||||
@param condition The condition that is required to be true
|
||||
@param message The message to print in case the assertion doesn't hold
|
||||
*/
|
||||
fn assert_warn(bool condition, str message) {
|
||||
@@ -49,4 +49,11 @@ namespace auto std {
|
||||
return builtin::std::sizeof_pack(pack);
|
||||
};
|
||||
|
||||
/**
|
||||
Throws an error notifying the developer that the current codepath is not implemented currently.
|
||||
*/
|
||||
fn unimplemented() {
|
||||
std::error("Unimplemented code path reached!");
|
||||
};
|
||||
|
||||
}
|
||||
@@ -3,198 +3,198 @@
|
||||
import std.io;
|
||||
|
||||
/*!
|
||||
Library to handle time and date related operations.
|
||||
Library to handle time and date related operations.
|
||||
*/
|
||||
|
||||
namespace auto std::time {
|
||||
|
||||
/**
|
||||
A structured representation of a time and date.
|
||||
*/
|
||||
struct Time {
|
||||
u8 sec;
|
||||
u8 min;
|
||||
u8 hour;
|
||||
u8 mday;
|
||||
u8 mon;
|
||||
u16 year;
|
||||
u8 wday;
|
||||
u16 yday;
|
||||
bool isdst;
|
||||
} [[sealed]];
|
||||
/**
|
||||
A structured representation of a time and date.
|
||||
*/
|
||||
struct Time {
|
||||
u8 sec;
|
||||
u8 min;
|
||||
u8 hour;
|
||||
u8 mday;
|
||||
u8 mon;
|
||||
u16 year;
|
||||
u8 wday;
|
||||
u16 yday;
|
||||
bool isdst;
|
||||
} [[sealed]];
|
||||
|
||||
/**
|
||||
A helper type to convert between Time and u128.
|
||||
*/
|
||||
union TimeConverter {
|
||||
Time time;
|
||||
u128 value;
|
||||
};
|
||||
/**
|
||||
A helper type to convert between Time and u128.
|
||||
*/
|
||||
union TimeConverter {
|
||||
Time time;
|
||||
u128 value;
|
||||
};
|
||||
|
||||
/**
|
||||
A type to represent a time in seconds since the epoch.
|
||||
*/
|
||||
using EpochTime = u32;
|
||||
/**
|
||||
A type to represent a time in seconds since the epoch.
|
||||
*/
|
||||
using EpochTime = u32;
|
||||
|
||||
/**
|
||||
A type to represent a time zone.
|
||||
*/
|
||||
enum TimeZone : u8 {
|
||||
Local,
|
||||
UTC
|
||||
};
|
||||
/**
|
||||
A type to represent a time zone.
|
||||
*/
|
||||
enum TimeZone : u8 {
|
||||
Local,
|
||||
UTC
|
||||
};
|
||||
|
||||
/**
|
||||
A type to represent a DOS date.
|
||||
*/
|
||||
bitfield DOSDate {
|
||||
day: 5;
|
||||
month: 4;
|
||||
year: 7;
|
||||
} [[sealed]];
|
||||
/**
|
||||
A type to represent a DOS date.
|
||||
*/
|
||||
bitfield DOSDate {
|
||||
day: 5;
|
||||
month: 4;
|
||||
year: 7;
|
||||
} [[sealed]];
|
||||
|
||||
/**
|
||||
A type to represent a DOS time.
|
||||
*/
|
||||
bitfield DOSTime {
|
||||
seconds: 5;
|
||||
minutes: 6;
|
||||
hours: 5;
|
||||
} [[sealed]];
|
||||
/**
|
||||
A type to represent a DOS time.
|
||||
*/
|
||||
bitfield DOSTime {
|
||||
seconds: 5;
|
||||
minutes: 6;
|
||||
hours: 5;
|
||||
} [[sealed]];
|
||||
|
||||
namespace impl {
|
||||
namespace impl {
|
||||
|
||||
union DOSDateConverter {
|
||||
DOSDate date;
|
||||
u16 value;
|
||||
};
|
||||
union DOSDateConverter {
|
||||
DOSDate date;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
union DOSTimeConverter {
|
||||
DOSTime time;
|
||||
u16 value;
|
||||
};
|
||||
union DOSTimeConverter {
|
||||
DOSTime time;
|
||||
u16 value;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the current time in seconds since the epoch.
|
||||
@return The current time in seconds since the epoch.
|
||||
*/
|
||||
fn epoch() {
|
||||
return builtin::std::time::epoch();
|
||||
};
|
||||
/**
|
||||
Returns the current time in seconds since the epoch.
|
||||
@return The current time in seconds since the epoch.
|
||||
*/
|
||||
fn epoch() {
|
||||
return builtin::std::time::epoch();
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a local time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The local time.
|
||||
*/
|
||||
fn to_local(EpochTime epoch_time) {
|
||||
le TimeConverter converter;
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a local time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The local time.
|
||||
*/
|
||||
fn to_local(EpochTime epoch_time) {
|
||||
le TimeConverter converter;
|
||||
|
||||
converter.value = builtin::std::time::to_local(epoch_time);
|
||||
converter.value = builtin::std::time::to_local(epoch_time);
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a UTC time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The UTC time.
|
||||
*/
|
||||
fn to_utc(EpochTime epoch_time) {
|
||||
le TimeConverter converter;
|
||||
/**
|
||||
Converts a time in seconds since the epoch to a UTC time.
|
||||
@param epoch_time The time in seconds since the epoch.
|
||||
@return The UTC time.
|
||||
*/
|
||||
fn to_utc(EpochTime epoch_time) {
|
||||
le TimeConverter converter;
|
||||
|
||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
||||
converter.value = builtin::std::time::to_utc(epoch_time);
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
/**
|
||||
Queries the current time in the specified time zone.
|
||||
@param [time_zone] The time zone to query. Defaults to local.
|
||||
@return The current time in the specified time zone.
|
||||
*/
|
||||
fn now(TimeZone time_zone = TimeZone::Local) {
|
||||
le TimeConverter converter;
|
||||
/**
|
||||
Queries the current time in the specified time zone.
|
||||
@param [time_zone] The time zone to query. Defaults to local.
|
||||
@return The current time in the specified time zone.
|
||||
*/
|
||||
fn now(TimeZone time_zone = TimeZone::Local) {
|
||||
le TimeConverter converter;
|
||||
|
||||
if (time_zone == TimeZone::Local)
|
||||
converter.value = builtin::std::time::to_local(std::time::epoch());
|
||||
else if (time_zone == TimeZone::UTC)
|
||||
converter.value = builtin::std::time::to_utc(std::time::epoch());
|
||||
else
|
||||
converter.value = 0x00;
|
||||
if (time_zone == TimeZone::Local)
|
||||
converter.value = builtin::std::time::to_local(std::time::epoch());
|
||||
else if (time_zone == TimeZone::UTC)
|
||||
converter.value = builtin::std::time::to_utc(std::time::epoch());
|
||||
else
|
||||
converter.value = 0x00;
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a value to a DOS date.
|
||||
@param value The value to convert.
|
||||
@return The DOS date.
|
||||
*/
|
||||
fn to_dos_date(u16 value) {
|
||||
le impl::DOSDateConverter converter;
|
||||
/**
|
||||
Converts a value to a DOS date.
|
||||
@param value The value to convert.
|
||||
@return The DOS date.
|
||||
*/
|
||||
fn to_dos_date(u16 value) {
|
||||
le impl::DOSDateConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
converter.value = value;
|
||||
|
||||
return converter.date;
|
||||
};
|
||||
return converter.date;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a value to a DOS time.
|
||||
@param value The value to convert.
|
||||
@return The DOS time.
|
||||
*/
|
||||
fn to_dos_time(u16 value) {
|
||||
le impl::DOSTimeConverter converter;
|
||||
/**
|
||||
Converts a value to a DOS time.
|
||||
@param value The value to convert.
|
||||
@return The DOS time.
|
||||
*/
|
||||
fn to_dos_time(u16 value) {
|
||||
le impl::DOSTimeConverter converter;
|
||||
|
||||
converter.value = value;
|
||||
converter.value = value;
|
||||
|
||||
return converter.time;
|
||||
};
|
||||
return converter.time;
|
||||
};
|
||||
|
||||
/**
|
||||
Converts a FILETIME to unix time.
|
||||
@param value The value to convert.
|
||||
@return Timestamp formatted as unix time.
|
||||
*/
|
||||
fn filetime_to_unix(u64 value) {
|
||||
return value / 10000000 - 11644473600;
|
||||
};
|
||||
/**
|
||||
Converts a FILETIME to unix time.
|
||||
@param value The value to convert.
|
||||
@return Timestamp formatted as unix time.
|
||||
*/
|
||||
fn filetime_to_unix(u64 value) {
|
||||
return value / 10000000 - 11644473600;
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a time according to the specified format string.
|
||||
@param time The time to format.
|
||||
@param [format_string] The format string to use. Defaults to "%c".
|
||||
@return The formatted time.
|
||||
*/
|
||||
fn format(Time time, str format_string = "%c") {
|
||||
le TimeConverter converter;
|
||||
converter.time = time;
|
||||
/**
|
||||
Formats a time according to the specified format string.
|
||||
@param time The time to format.
|
||||
@param [format_string] The format string to use. Defaults to "%c".
|
||||
@return The formatted time.
|
||||
*/
|
||||
fn format(Time time, str format_string = "%c") {
|
||||
le TimeConverter converter;
|
||||
converter.time = time;
|
||||
|
||||
return builtin::std::time::format(format_string, converter.value);
|
||||
};
|
||||
return builtin::std::time::format(format_string, converter.value);
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a DOS date according to the specified format string.
|
||||
@param date The DOS date to format.
|
||||
@param [format_string] The format string to use. Defaults to "{}/{}/{}".
|
||||
@return The formatted DOS date.
|
||||
*/
|
||||
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
|
||||
return std::format(format_string, date.day, date.month, date.year + 1980);
|
||||
};
|
||||
/**
|
||||
Formats a DOS date according to the specified format string.
|
||||
@param date The DOS date to format.
|
||||
@param [format_string] The format string to use. Defaults to "{}/{}/{}".
|
||||
@return The formatted DOS date.
|
||||
*/
|
||||
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
|
||||
return std::format(format_string, date.day, date.month, date.year + 1980);
|
||||
};
|
||||
|
||||
/**
|
||||
Formats a DOS time according to the specified format string.
|
||||
@param time The DOS time to format.
|
||||
@param [format_string] The format string to use. Defaults to "{:02}:{:02}:{:02}".
|
||||
@return The formatted DOS time.
|
||||
*/
|
||||
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
||||
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
|
||||
};
|
||||
/**
|
||||
Formats a DOS time according to the specified format string.
|
||||
@param time The DOS time to format.
|
||||
@param [format_string] The format string to use. Defaults to "{:02}:{:02}:{:02}".
|
||||
@return The formatted DOS time.
|
||||
*/
|
||||
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
|
||||
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace auto type {
|
||||
*/
|
||||
using Bin<T> = T [[format("type::impl::format_bin")]];
|
||||
|
||||
namespace impl {
|
||||
namespace impl {
|
||||
|
||||
fn format_number(auto value, str fmt) {
|
||||
bool negative = value < 0;
|
||||
@@ -50,6 +50,6 @@ namespace auto type {
|
||||
fn format_dec(auto value) { return type::impl::format_number(value, "{}"); };
|
||||
fn format_bin(auto value) { return type::impl::format_number(value, "0b{:08b}"); };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
import std.io;
|
||||
import std.core;
|
||||
|
||||
/*!
|
||||
Types to display single bytes using various different representations
|
||||
@@ -20,7 +21,7 @@ namespace auto type {
|
||||
bit5 : 1;
|
||||
bit6 : 1;
|
||||
bit7 : 1;
|
||||
} [[format("type::impl::format_bits"), right_to_left]];
|
||||
} [[format("type::impl::format_bits"), bitfield_order(std::core::BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
/**
|
||||
Type visualizing the value of the two nibbles
|
||||
@@ -40,7 +41,7 @@ namespace auto type {
|
||||
} [[format("type::impl::format_byte"), single_color]];
|
||||
|
||||
|
||||
namespace impl {
|
||||
namespace impl {
|
||||
|
||||
fn format_byte(Byte byte) {
|
||||
return std::format("0x{0:02X} (0b{1:08b}) LSB:{2}, MSB:{3}",
|
||||
@@ -66,6 +67,6 @@ namespace auto type {
|
||||
return std::format("{{ {0:0X}, {1:0X} }}", nibbles.high, nibbles.low);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace auto type {
|
||||
float floatValue;
|
||||
};
|
||||
|
||||
fn format_float16(float16 value) {
|
||||
fn format_float16(float16 value) {
|
||||
u32 sign = value >> 15;
|
||||
u32 exponent = (value >> 10) & 0x1F;
|
||||
u32 mantissa = value & 0x3FF;
|
||||
|
||||
42
includes/type/fmt.pat
Normal file
42
includes/type/fmt.pat
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
import std.io;
|
||||
|
||||
/*!
|
||||
Type that allows specifying its format value using a format string.
|
||||
## Usage
|
||||
|
||||
The following code reads a u32 from the data and formats it as an upper case hexadecimal value with
|
||||
a minimum of 8 digits which is prefixed by 0x.
|
||||
|
||||
The format string is the same as passed to `std::format()` and follows the libfmt specification.
|
||||
|
||||
```rust
|
||||
type::Formatted<u32, "0x{:08X}"> hex_formatted_integer @ 0x00;
|
||||
```
|
||||
*/
|
||||
|
||||
namespace auto type {
|
||||
|
||||
/**
|
||||
Arbitrarily formatted type
|
||||
@tparam T Type to format
|
||||
@tparam FormatString libfmt format string to format the value
|
||||
*/
|
||||
struct Formatted<T, auto FormatString> {
|
||||
T value;
|
||||
} [[sealed, format("type::impl::format_formatted"), transform("type::impl::transform_formatted")]];
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_formatted(ref auto formatted) {
|
||||
return std::format(std::format("{{0:{}}}", formatted.FormatString), formatted.value);
|
||||
};
|
||||
|
||||
fn transform_formatted(ref auto formatted) {
|
||||
return formatted.value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,15 +3,15 @@
|
||||
import std.io;
|
||||
|
||||
/*!
|
||||
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
|
||||
Types to deal with UUIDs (Universally Unique Identifiers) / GUIDs (Globally Unique Identifiers) as described in RFC 4122
|
||||
*/
|
||||
|
||||
namespace auto type {
|
||||
|
||||
/**
|
||||
Type representing a GUID value
|
||||
*/
|
||||
struct GUID {
|
||||
/**
|
||||
Type representing a GUID value
|
||||
*/
|
||||
struct GUID {
|
||||
u32 time_low;
|
||||
u16 time_mid;
|
||||
u16 time_high_and_version;
|
||||
@@ -20,31 +20,31 @@ namespace auto type {
|
||||
u8 node[6];
|
||||
} [[sealed, format("type::impl::format_guid")]];
|
||||
|
||||
/**
|
||||
Alias name for GUID
|
||||
*/
|
||||
using UUID = GUID;
|
||||
/**
|
||||
Alias name for GUID
|
||||
*/
|
||||
using UUID = GUID;
|
||||
|
||||
namespace impl {
|
||||
namespace impl {
|
||||
|
||||
fn format_guid(GUID guid) {
|
||||
bool valid = ((le u16(guid.time_high_and_version) >> 12) <= 5) && (((guid.clock_seq_and_reserved >> 4) >= 8) || ((guid.clock_seq_and_reserved >> 4) == 0));
|
||||
|
||||
return std::format("{}{{{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}",
|
||||
valid ? "" : "Invalid ",
|
||||
le u32(guid.time_low),
|
||||
le u16(guid.time_mid),
|
||||
le u16(guid.time_high_and_version),
|
||||
guid.clock_seq_and_reserved,
|
||||
guid.clock_seq_low,
|
||||
guid.node[0],
|
||||
guid.node[1],
|
||||
guid.node[2],
|
||||
guid.node[3],
|
||||
guid.node[4],
|
||||
guid.node[5]);
|
||||
};
|
||||
fn format_guid(GUID guid) {
|
||||
bool valid = ((le u16(guid.time_high_and_version) >> 12) <= 5) && (((guid.clock_seq_and_reserved >> 4) >= 8) || ((guid.clock_seq_and_reserved >> 4) == 0));
|
||||
|
||||
return std::format("{}{{{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}",
|
||||
valid ? "" : "Invalid ",
|
||||
le u32(guid.time_low),
|
||||
le u16(guid.time_mid),
|
||||
le u16(guid.time_high_and_version),
|
||||
guid.clock_seq_and_reserved,
|
||||
guid.clock_seq_low,
|
||||
guid.node[0],
|
||||
guid.node[1],
|
||||
guid.node[2],
|
||||
guid.node[3],
|
||||
guid.node[4],
|
||||
guid.node[5]);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,69 +4,69 @@ import std.io;
|
||||
import std.mem;
|
||||
|
||||
/*!
|
||||
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
|
||||
Types used to decode Little Endian Base 128 numbers used to store large numbers as space efficiently as possible
|
||||
*/
|
||||
|
||||
namespace auto type {
|
||||
|
||||
/**
|
||||
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]];
|
||||
|
||||
/**
|
||||
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]];
|
||||
|
||||
/**
|
||||
A unsigned variant of a LEB128 number
|
||||
*/
|
||||
using uLEB128 = LEB128Base [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]];
|
||||
/**
|
||||
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")]];
|
||||
/**
|
||||
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 {
|
||||
|
||||
fn transform_uleb128_array(ref auto array) {
|
||||
u128 res = array[0] & 0x7f;
|
||||
for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) {
|
||||
res |= u128(array[i] & 0x7f) << 7 * i;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
/**
|
||||
Legacy alias for uLEB128
|
||||
*/
|
||||
using LEB128 = uLEB128;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn transform_uleb128_array(ref auto array) {
|
||||
u128 res = array[0] & 0x7f;
|
||||
for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) {
|
||||
res |= u128(array[i] & 0x7f) << 7 * i;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
fn transform_sleb128_array(ref auto array) {
|
||||
s128 res = type::impl::transform_uleb128_array(array);
|
||||
if (res & 0x40 != 0) {
|
||||
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
fn format_uleb128(ref auto leb128) {
|
||||
u128 res = type::impl::transform_uleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_uleb128(ref auto leb128) {
|
||||
return type::impl::transform_uleb128_array(leb128.array);
|
||||
};
|
||||
fn transform_sleb128_array(ref auto array) {
|
||||
s128 res = type::impl::transform_uleb128_array(array);
|
||||
if (res & 0x40 != 0) {
|
||||
res |= ~0 << (sizeof(array) / sizeof(u8)) * 7;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
fn format_uleb128(ref auto leb128) {
|
||||
u128 res = type::impl::transform_uleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_uleb128(ref auto leb128) {
|
||||
return type::impl::transform_uleb128_array(leb128.array);
|
||||
};
|
||||
|
||||
fn format_sleb128(ref auto leb128) {
|
||||
s128 res = type::impl::transform_sleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_sleb128(ref auto leb128) {
|
||||
return type::impl::transform_sleb128_array(leb128.array);
|
||||
};
|
||||
fn format_sleb128(ref auto leb128) {
|
||||
s128 res = type::impl::transform_sleb128_array(leb128.array);
|
||||
return std::format("{} ({:#x})", res, res);
|
||||
};
|
||||
|
||||
fn transform_sleb128(ref auto leb128) {
|
||||
return type::impl::transform_sleb128_array(leb128.array);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
import std.io;
|
||||
|
||||
/*!
|
||||
Types used to decode MAC Addresses
|
||||
Types used to decode MAC Addresses
|
||||
*/
|
||||
|
||||
namespace auto type {
|
||||
|
||||
/**
|
||||
A MAC Address as used in the Internet Protocol
|
||||
*/
|
||||
struct MACAddress {
|
||||
u8 bytes[6];
|
||||
} [[sealed, format("type::impl::format_mac_address")]];
|
||||
/**
|
||||
A MAC Address as used in the Internet Protocol
|
||||
*/
|
||||
struct MACAddress {
|
||||
u8 bytes[6];
|
||||
} [[sealed, format("type::impl::format_mac_address")]];
|
||||
|
||||
namespace impl {
|
||||
namespace impl {
|
||||
|
||||
fn format_mac_address(MACAddress address) {
|
||||
return std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
|
||||
address.bytes[0],
|
||||
address.bytes[1],
|
||||
address.bytes[2],
|
||||
address.bytes[3],
|
||||
address.bytes[4],
|
||||
address.bytes[5]);
|
||||
};
|
||||
return std::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
|
||||
address.bytes[0],
|
||||
address.bytes[1],
|
||||
address.bytes[2],
|
||||
address.bytes[3],
|
||||
address.bytes[4],
|
||||
address.bytes[5]);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +1,53 @@
|
||||
import std.mem;
|
||||
|
||||
/*!
|
||||
Types dealing with various kinds of resource paths
|
||||
Types dealing with various kinds of resource paths
|
||||
*/
|
||||
|
||||
namespace auto type {
|
||||
|
||||
/**
|
||||
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<auto Delimeter> {
|
||||
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_path_segment")]];
|
||||
|
||||
/**
|
||||
A generic type representing a path with an arbitrary delimeter
|
||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
||||
*/
|
||||
struct Path<auto Delimeter> {
|
||||
PathSegment<Delimeter> segments[while(true)];
|
||||
} [[format("type::impl::format_path")]];
|
||||
|
||||
/**
|
||||
A type representing a Unix path using a '/' forwardslash as delimeter
|
||||
*/
|
||||
using UnixPath = Path<"/">;
|
||||
/**
|
||||
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<auto Delimeter> {
|
||||
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_path_segment")]];
|
||||
|
||||
/**
|
||||
A generic type representing a path with an arbitrary delimeter
|
||||
@tparam Delimeter The delimeter sequence used to separate two path segments
|
||||
*/
|
||||
struct Path<auto Delimeter> {
|
||||
PathSegment<Delimeter> 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_path_segment(ref auto segment) {
|
||||
return segment.string;
|
||||
};
|
||||
|
||||
fn format_path(ref auto path) {
|
||||
return std::mem::read_string($, sizeof(path));
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
A type representing a DOS path using a '\\' backslash as delimeter
|
||||
*/
|
||||
using DOSPath = Path<"\\">;
|
||||
|
||||
namespace impl {
|
||||
|
||||
fn format_path_segment(ref auto segment) {
|
||||
return segment.string;
|
||||
};
|
||||
|
||||
fn format_path(ref auto path) {
|
||||
return std::mem::read_string($, sizeof(path));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -167,16 +167,26 @@ bitfield Caps2Flags {
|
||||
};
|
||||
|
||||
bitfield PixelFormatFlags {
|
||||
alphaPixels : 1;
|
||||
alpha : 1;
|
||||
fourCC : 1;
|
||||
padding : 3;
|
||||
rgb : 1; // 0x40
|
||||
padding : 2;
|
||||
yuv : 1; // 0x200
|
||||
padding : 3;
|
||||
luminance : 1; // 0x20000
|
||||
padding : 17;
|
||||
alphaPixels : 1; // DDPF_ALPHAPIXELS
|
||||
alpha : 1; // DDPF_ALPHA
|
||||
fourCC : 1; // DDPF_FOURCC
|
||||
paletteIndexed4 : 1; // DDPF_PALETTEINDEXED4
|
||||
paletteIndexedTo8 : 1; // DDPF_PALETTEINDEXEDTO8
|
||||
paletteIndexed8 : 1; // DDPF_PALETTEINDEXED8
|
||||
rgb : 1; // DDPF_RGB
|
||||
compressed : 1; // DDPF_COMPRESSED
|
||||
rgbToYuv : 1; // DDPF_RGBTOYUV
|
||||
yuv : 1; // DDPF_YUV
|
||||
zBuffer : 1; // DDPF_ZBUFFER
|
||||
paletteIndexed1 : 1; // DDPF_PALETTEINDEXED1
|
||||
paletteIndexed2 : 1; // DDPF_PALETTEINDEXED2
|
||||
zPixels : 1; // DDPF_ZPIXELS
|
||||
stencilBuffer : 1; // DDPF_STENCILBUFFER
|
||||
alphaResult : 1; // DDPF_ALPHARESULT
|
||||
luminance : 1; // DDPF_LUMINANCE
|
||||
bumpLuminance : 1; // DDPF_BUMPLUMINANCE
|
||||
bumpDudv : 1; // DDPF_BUMPDUDV
|
||||
padding : 13; // Padding bits to complete 32-bit structure
|
||||
};
|
||||
|
||||
enum DX10ResourceDimension : u32 {
|
||||
|
||||
@@ -498,12 +498,12 @@ bitfield SHF {
|
||||
bitfield ELF32_R_INFO {
|
||||
SYM : 8;
|
||||
TYPE : 8;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 16)]];
|
||||
|
||||
bitfield ELF64_R_INFO {
|
||||
SYM : 32;
|
||||
TYPE : 32;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 64)]];
|
||||
|
||||
bitfield PF {
|
||||
X : 1;
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace fat32 {
|
||||
lastLogical : 1;
|
||||
padding : 1;
|
||||
number : 5;
|
||||
} [[left_to_right]];
|
||||
} [[bitfield_order(BitfieldOrder::MostToLeastSignificant, 8)]];
|
||||
|
||||
enum EntryStatus : u8 {
|
||||
Regular = 0x00,
|
||||
@@ -73,7 +73,7 @@ namespace fat32 {
|
||||
subdirectory : 1;
|
||||
archive : 1;
|
||||
padding : 2;
|
||||
} [[right_to_left]];
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 8)]];
|
||||
|
||||
struct DirEntry {
|
||||
char fileName[8];
|
||||
|
||||
@@ -1,538 +0,0 @@
|
||||
#pragma description TODO
|
||||
|
||||
import std.mem;
|
||||
import std.io;
|
||||
import std.string;
|
||||
|
||||
struct Header {
|
||||
u32 magic;
|
||||
u32 version;
|
||||
u64 RootStructAltGUID;
|
||||
u64 AssetChecksum;
|
||||
u32 DependencyCount;
|
||||
s32 DataBlockCount;
|
||||
s32 TagStructCount;
|
||||
s32 DataReferenceCount;
|
||||
s32 TagReferenceCount;
|
||||
u32 StringTableSize;
|
||||
u32 ZoneSetDataSize;
|
||||
u32 Unk_0x34;
|
||||
u32 HeaderSize;
|
||||
u32 DataSize;
|
||||
u32 ResourceDataSize;
|
||||
u32 ActualResoureDataSize;
|
||||
u8 HeaderAlignment;
|
||||
u8 TagDataAlignment;
|
||||
u8 ResourceDataAlignment;
|
||||
u8 ActualResourceDataAlignment;
|
||||
s32 IsResource;
|
||||
};
|
||||
|
||||
enum curve_mode : u8 {
|
||||
choose_best = 0x00,
|
||||
force_FAST = 0x01,
|
||||
force_PRETTY = 0x02,
|
||||
};
|
||||
|
||||
enum BitmapForcedFormat : u16 {
|
||||
Use_Default = 0x00,
|
||||
Best_Compressed_Color_Format = 0x01,
|
||||
Best_Uncompressed_Color_Format = 0x02,
|
||||
Best_Compressed_Bump_Format = 0x03,
|
||||
Best_Uncompressed_Bump_Format = 0x04,
|
||||
Best_Compressed_Monochrome_Format = 0x05,
|
||||
Best_Uncompressed_Monochrome_Format = 0x06,
|
||||
Best_Compressed_Monochrome_Format_Without_Alpha = 0x07,
|
||||
unused2 = 0x08,
|
||||
unused3 = 0x09,
|
||||
unused4 = 0x0A,
|
||||
unused5 = 0x0B,
|
||||
unused6 = 0x0C,
|
||||
Color_And_Alpha_Formats = 0x0D,
|
||||
bc1_unorm_DXT1_Compressed_Color_Key_Alpha = 0x0E,
|
||||
bc2_unorm_DXT3_Compressed_Color_4bit_Alpha = 0x0F,
|
||||
bc3_unorm_DXT5_Compressed_Color_Compressed_8bit_Alpha = 0x10,
|
||||
Color_24bit_Alpha_8bit = 0x11,
|
||||
Monochrome_8bit_Alpha_8bit = 0x12,
|
||||
Channel_Mask_3bit_Color_1bit_Alpha = 0x13,
|
||||
Color_30bit_Alpha_2bit = 0x14,
|
||||
Color_48bit_Alpha_16bit = 0x15,
|
||||
HALF_Color_Alpha = 0x16,
|
||||
FLOAT_Color_Alpha = 0x17,
|
||||
r8_unorm_8bit_Intensity_RGBA = 0x18,
|
||||
DEPRECATED_DXT3A_4bit_Intensity_ARGB = 0x19,
|
||||
bc4_unorm_rrrr_DXT5A_Compressed_Intensity_ARGB = 0x1A,
|
||||
Compressed_Monochrome_Alpha = 0x1B,
|
||||
b4g4r4a4_12bit_Color_4bit_Alpha = 0x1C,
|
||||
Color_Only_Formats = 0x1D,
|
||||
Monochrome_8bit = 0x1E,
|
||||
Compressed_Color_24bit = 0x1F,
|
||||
Color_32bit_R11G11B10 = 0x20,
|
||||
Monochrome_16bit = 0x21,
|
||||
Red_Green_Only_16bit = 0x22,
|
||||
Signed_RGBA_16bit = 0x23,
|
||||
HALF_Red_Only = 0x24,
|
||||
FLOAT_Red_Only = 0x25,
|
||||
HALF_Red_Green_Only = 0x26,
|
||||
FLOAT_Red_Green_Only = 0x27,
|
||||
HALF_Monochrome = 0x28,
|
||||
DEPRECATED_Compressed_Monochrome_4bit = 0x29,
|
||||
Compressed_Interpolated_Monochrome = 0x2A,
|
||||
bc6h_uf16_HDR_RGB_Unsigned_Half_Float = 0x2B,
|
||||
bc6h_sf16_HDR_RGB_Signed_Half_Float = 0x2C,
|
||||
bc7_unorm_High_Quality_bc3 = 0x2D,
|
||||
Alpha_Only_Formats = 0x2E,
|
||||
DEPRECATED_DXT3A_4bit_Alpha = 0x2F,
|
||||
bc4_unorm_000r_DXT5A_8bit_Compressed_Alpha = 0x30,
|
||||
Alpha_8bit = 0x31,
|
||||
unused28 = 0x32,
|
||||
unused29 = 0x33,
|
||||
unused30 = 0x34,
|
||||
Normal_Map_Formats = 0x35,
|
||||
bc5_snorm_DXN_Compressed_Normals_Better = 0x36,
|
||||
DEPRECATED_CTX1_Compressed_Normals_Smaller = 0x37,
|
||||
Normals_16bit = 0x38,
|
||||
Normals_32bit = 0x39,
|
||||
Vector_8bit_4_Channel = 0x3A,
|
||||
};
|
||||
|
||||
enum BitmapDownsampleFilter : u8 {
|
||||
point_sampled = 0x01,
|
||||
box_filter = 0x02,
|
||||
blackman_filter = 0x03,
|
||||
lanczos_filter = 0x04,
|
||||
nuttall_filter = 0x05,
|
||||
blackman_harris_filter = 0x06,
|
||||
blackman_nuttall_filter = 0x07,
|
||||
flat_top_filter = 0x08,
|
||||
extreme_filter = 0x09,
|
||||
min_filter = 0x0A
|
||||
};
|
||||
|
||||
enum BitmapType : u8 {
|
||||
_2D_Texture = 0x00,
|
||||
_3D_Texture = 0x01,
|
||||
CubeMap = 0x02,
|
||||
Array = 0x03,
|
||||
};
|
||||
|
||||
enum BitmapColorSpace : u8 {
|
||||
Automatic = 0x00,
|
||||
Rec709 = 0x01,
|
||||
DCI_P3 = 0x02,
|
||||
Rec2020 = 0x03,
|
||||
};
|
||||
|
||||
enum SignedDistanceFieldMethod : u8 {
|
||||
Neighbors_Multithreaded = 0x00,
|
||||
Neighbors = 0x01,
|
||||
Cached_Euclidean_Multithreaded = 0x02,
|
||||
Cached_Euclidean = 0x03,
|
||||
SSEDT = 0x04,
|
||||
};
|
||||
|
||||
enum BitmapFormat : u16 {
|
||||
a8_unorm = 0x00,
|
||||
r8_unorm_rrr1 = 0x01,
|
||||
r8_unorm_rrrr = 0x02,
|
||||
r8g8_unorm_rrrg = 0x03,
|
||||
unused1 = 0x04,
|
||||
unused2 = 0x05,
|
||||
b5g6r5_unorm = 0x06,
|
||||
unused3 = 0x07,
|
||||
b5g6r5a1_unorm = 0x08,
|
||||
b4g4r4a4_unorm = 0x09,
|
||||
b8g8r8x8_unorm = 0x0A,
|
||||
b8g8r8a8_unorm = 0x0B,
|
||||
unused4 = 0x0C,
|
||||
DEPRECATED_dxt5_bias_alpha = 0x0D,
|
||||
bc1_unorm_dxt1 = 0x0E,
|
||||
bc2_unorm_dxt3 = 0x0F,
|
||||
bc3_unorm_dxt5 = 0x10,
|
||||
DEPRECATED_a4r4g4b4_font = 0x11,
|
||||
unused7 = 0x12,
|
||||
unused8 = 0x13,
|
||||
DEPRECATED_SOFTWARE_rgbfp32 = 0x14,
|
||||
unused9 = 0x15,
|
||||
r8g8_snorm_v8u8 = 0x16,
|
||||
DEPRECATED_g8b8 = 0x17,
|
||||
r32g32b32a32_float_abgrfp32 = 0x18,
|
||||
r16g16b16a16_float_abgrfp16 = 0x19,
|
||||
r16_float_rrr1_16f_mono = 0x1A,
|
||||
r16_float_r000_16f_red = 0x1B,
|
||||
r8g8b8a8_snorm_q8w8v8u8 = 0x1C,
|
||||
r10g10b10a2_unorm_a2r10g10b10 = 0x1D,
|
||||
r16g16b16a16_unorm_a16b16g16r16 = 0x1E,
|
||||
r16g16_snorm_v16u16 = 0x1F,
|
||||
r16_unorm_rrr0_L16 = 0x20,
|
||||
r16g16_unorm_r16g16 = 0x21,
|
||||
r16g16b16a16_snorm_signedr16g16b16a16 = 0x22,
|
||||
DEPRECATED_dxt3a = 0x23,
|
||||
bc4_unorm_rrrr_dxt5a = 0x24,
|
||||
bc4_snorm_rrrr = 0x25,
|
||||
DEPRECATED_dxt3a_1111 = 0x26,
|
||||
bc5_snorm_dxn = 0x27,
|
||||
DEPRECATED_ctx1 = 0x28,
|
||||
DEPRECATED_dxt3a_alpha_only = 0x29,
|
||||
DEPRECATED_dxt3a_monochrome_only = 0x2A,
|
||||
bc4_unorm_000r_dxt5a_alpha = 0x2B,
|
||||
bc4_unorm_rrr1_dxt5a_mono = 0x2C,
|
||||
bc5_unorm_rrrg_dxn_mono_alpha = 0x2D,
|
||||
bc5_snorm_rrrg_dxn_mono_alpha_signed = 0x2E,
|
||||
bc6h_uf16 = 0x2F,
|
||||
bc6h_sf16 = 0x30,
|
||||
bc7_unorm = 0x31,
|
||||
d24_unorm_s8_uint_depth_24 = 0x32,
|
||||
r11g11b10_float = 0x33,
|
||||
r16g16_float = 0x34,
|
||||
};
|
||||
|
||||
enum BitmapCurve : u8 {
|
||||
unknown = 0x00,
|
||||
xRGB = 0x01,
|
||||
gamma_2 = 0x02,
|
||||
linear = 0x03,
|
||||
offset_log = 0x04,
|
||||
sRGB = 0x05,
|
||||
Rec709 = 0x06,
|
||||
};
|
||||
|
||||
enum BitmapUsageFlag : u8 {
|
||||
ignore_curve_override = 0x00,
|
||||
do_not_allow_size_optimization = 0x01,
|
||||
swap_axes = 0x02,
|
||||
pre_filter_cubemaps = 0x03,
|
||||
};
|
||||
|
||||
enum BitmapSlicer : u8 {
|
||||
automatically_determine_slicer = 0x00,
|
||||
no_slicing = 0x01,
|
||||
color_plate_slicer = 0x02,
|
||||
cube_map_slicer = 0x03,
|
||||
color_grading_slicer = 0x04,
|
||||
};
|
||||
|
||||
enum BitmapPacker : u8 {
|
||||
no_packing = 0x00,
|
||||
sprite_packing = 0x01,
|
||||
sprite_packing_if_needed = 0x02,
|
||||
_3d_pack = 0x03,
|
||||
};
|
||||
|
||||
enum BitmapSmallestMip : u8 {
|
||||
_1_pixel = 0x00,
|
||||
_2_pixel = 0x01,
|
||||
_4_pixel = 0x02,
|
||||
_8_pixel = 0x03,
|
||||
_16_pixel = 0x04,
|
||||
_32_pixel = 0x05,
|
||||
_64_pixel = 0x06,
|
||||
_128_pixel = 0x07,
|
||||
_256_pixel = 0x08,
|
||||
_512_pixel = 0x09,
|
||||
_1024_pixel = 0x0A,
|
||||
};
|
||||
|
||||
enum Swizzle : u8 {
|
||||
default = 0x00,
|
||||
source_red_channel = 0x01,
|
||||
source_green_channel = 0x02,
|
||||
source_blue_channel = 0x03,
|
||||
source_alpha_channel = 0x04,
|
||||
set_to_1 = 0x05,
|
||||
set_to_0 = 0x06,
|
||||
set_to_0_5 = 0x07,
|
||||
Random = 0x08,
|
||||
one_minus_source_red_channel = 0x09,
|
||||
one_minus_source_green_channel = 0x0A,
|
||||
one_minus_source_blue_channel = 0x0B,
|
||||
one_minus_source_alpha_channel = 0x0C,
|
||||
negative_source_red_channel = 0x0D,
|
||||
negative_source_green_channel = 0x0E,
|
||||
negative_source_blue_channel = 0x0F,
|
||||
negative_source_alpha_channel = 0x10,
|
||||
};
|
||||
|
||||
bitfield BitmapDicerFlag {
|
||||
convert_plate_color_key_to_alpha_channel : 1;
|
||||
rotate_cube_map_to_match_directX_format : 1;
|
||||
sprites_shrink_elements_to_smallest_non_zero_alpha_region : 1;
|
||||
sprites_shrink_elements_to_smallest_non_zero_color_and_alpha_region : 1;
|
||||
unsigned_signed_scale_and_bias : 1;
|
||||
color_grading_sRGB_correction : 1;
|
||||
color_grading_Rec709_correction : 1;
|
||||
};
|
||||
|
||||
bitfield BitmapDownsampleFlag {
|
||||
sprites : 1;
|
||||
pre_multiply_alpha : 1;
|
||||
post_divide_alpha : 1;
|
||||
height_map : 1;
|
||||
detail_map : 1;
|
||||
_signed : 1;
|
||||
illum_map : 1;
|
||||
zbump_map : 1;
|
||||
cubemap : 1;
|
||||
calculate_spec_power : 1;
|
||||
downsample_bumps_in_angular_space : 1;
|
||||
standard_orientation_of_normals_in_angular_space_and_renormalize : 1;
|
||||
generate_rgb_luminance_into_alpha_channel : 1;
|
||||
};
|
||||
|
||||
bitfield BitmapPackerFlag {
|
||||
shrink_sprite_texture_pages_tightly_to_content : 1;
|
||||
};
|
||||
|
||||
bitfield BitmapDataResourceFlags {
|
||||
Contains_3D_Texture : 1;
|
||||
CPU_Gameplay_Required : 1;
|
||||
Single_Mip_Texture : 1;
|
||||
UI_Texture : 1;
|
||||
};
|
||||
|
||||
|
||||
bitfield BitmapGroupFlags {
|
||||
bitmap_is_tiled : 1;
|
||||
use_less_blurry_bump_map : 1;
|
||||
dither_when_compressing : 1;
|
||||
generate_random_sprites : 1;
|
||||
ignore_alpha_channel : 1;
|
||||
alpha_channel_stores_transparency : 1;
|
||||
preserve_alpha_channel_in_mipmaps : 1;
|
||||
only_use_on_demand : 1;
|
||||
apply_max_resolution_after_slicing :1;
|
||||
pre_filter_cubemaps : 1;
|
||||
has_valid_min_and_max_values : 1;
|
||||
SDF_Only_Store_Inside_values : 1;
|
||||
SDF_Store_Direction : 1;
|
||||
SDF_Store_Initial_Values_In_Alpha_Channel : 1;
|
||||
Has_CUstom_Mipmaps : 1;
|
||||
Validate_Has_Custom_Mipmaps : 1;
|
||||
Is_Light_Probes : 1;
|
||||
pad1 : 1;
|
||||
pad2 : 1;
|
||||
pad3 : 1;
|
||||
pad4 : 1;
|
||||
pad5 : 1;
|
||||
pad6 : 1;
|
||||
pad7 : 1;
|
||||
pad8 : 1;
|
||||
};
|
||||
|
||||
bitfield BitmapFlags {
|
||||
power_of_two_dimension : 1;
|
||||
compressed : 1;
|
||||
swap_axes : 1;
|
||||
mutable_at_runtime : 1;
|
||||
pad1 : 1;
|
||||
pad2 : 1;
|
||||
pad3 : 1;
|
||||
pad4 : 1;
|
||||
pad5 : 1;
|
||||
};
|
||||
|
||||
struct Data_Block {
|
||||
u32 Size;
|
||||
u16 Padding;
|
||||
u16 Section;
|
||||
u64 Offset;
|
||||
};
|
||||
|
||||
struct Tag_Def_Structure {
|
||||
s64 GUID_1;
|
||||
s64 GUID_2;
|
||||
u16 Type;
|
||||
u16 Unk_0x12;
|
||||
s32 TargetIndex;
|
||||
s32 FieldBlock;
|
||||
u32 FieldOffset;
|
||||
};
|
||||
|
||||
struct Tag_Dependency {
|
||||
char GroupTag[4] [[format("std::string::reverse")]];
|
||||
u32 NameOffset;
|
||||
u64 AssetID;
|
||||
u32 GlobalID;
|
||||
u32 Unk_0x14;
|
||||
};
|
||||
|
||||
struct Data_Reference {
|
||||
s32 ParentStructIndex;
|
||||
s32 Unk_0x04;
|
||||
s32 TargetIndex;
|
||||
s32 FieldBlock;
|
||||
u32 FieldOffset;
|
||||
};
|
||||
|
||||
struct TagReference {
|
||||
s64 GlobalHandle;
|
||||
s32 ref_id_int;
|
||||
s32 ref_id_sub;
|
||||
s32 ref_id_center_int;
|
||||
char TagGroupRev[4] [[format("std::string::reverse")]];
|
||||
s32 local_handle;
|
||||
};
|
||||
|
||||
struct Tag_Fixup_Reference {
|
||||
s32 FieldBlock;
|
||||
u32 FieldOffset;
|
||||
u32 NameOffset;
|
||||
s32 DependencyIndex;
|
||||
TagReference tagreference @ header.HeaderSize + datablocks[FieldBlock].Offset + FieldOffset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct RealARgbColor {
|
||||
float A;
|
||||
float R;
|
||||
float G;
|
||||
float B;
|
||||
};
|
||||
|
||||
struct RealRgbColor {
|
||||
float R;
|
||||
float G;
|
||||
float B;
|
||||
};
|
||||
|
||||
struct Bitmap_Resource_Handle {
|
||||
s32 pixels[6]; // sum of these equals pixel count.
|
||||
u32 hardware_format;
|
||||
s8 tileMode;
|
||||
s8 format;
|
||||
BitmapDataResourceFlags bitmap_data_resource_flags;
|
||||
s8 Alignment_Bits;
|
||||
u8 highResMipCountAndFlags;
|
||||
u8 mipCountPerArraySlice;
|
||||
char generated_padff1b[6];
|
||||
s64 runtime_data;
|
||||
char streamingData[20];
|
||||
s32 generated_padb266;
|
||||
};
|
||||
|
||||
struct BitmapBlock {
|
||||
u16 width;
|
||||
u16 height;
|
||||
u16 depth;
|
||||
BitmapType Bitmap_Type;
|
||||
u8 generated_paddca;
|
||||
BitmapFormat bitmap_format;
|
||||
BitmapFlags bitmap_flags;
|
||||
s8 mipmap_count;
|
||||
BitmapCurve bitmap_curve;
|
||||
u16 generated_pad8fee;
|
||||
float streaming_scale;
|
||||
s16 source_width;
|
||||
s16 source_height;
|
||||
char bitmap_resource_handle_size[12];
|
||||
s32 bitmap_resource_handle_count;
|
||||
Bitmap_Resource_Handle bitmap_resource_handle[bitmap_resource_handle_count];
|
||||
};
|
||||
|
||||
struct BitmapUsage {
|
||||
s32 name;
|
||||
s32 editor_group;
|
||||
u32 source_gamma;
|
||||
BitmapCurve bitmap_curve;
|
||||
BitmapUsageFlag bitmap_usage_flag;
|
||||
BitmapSlicer bitmap_slicer;
|
||||
BitmapDicerFlag bitmap_dicer;
|
||||
BitmapPacker bitmap_packer;
|
||||
BitmapPackerFlag bitmap_packer_flags;
|
||||
BitmapType bitmap_type;
|
||||
s8 mipmap_limit;
|
||||
BitmapSmallestMip bitmap_smallest_mip;
|
||||
BitmapDownsampleFilter bitmap_downsample_filter;
|
||||
s8 filter_radius_bias;
|
||||
char generated_pad122e[1];
|
||||
BitmapDownsampleFlag bitmap_downsample_flag;
|
||||
char generated_pad5ee3[2];
|
||||
RealRgbColor sprite_background_color;
|
||||
Swizzle swizzle_red;
|
||||
Swizzle swizzle_green;
|
||||
Swizzle swizzle_blue;
|
||||
Swizzle swizzle_alpha;
|
||||
BitmapFormat bitmap_formats;
|
||||
BitmapColorSpace source_color_space;
|
||||
BitmapColorSpace target_color_space;
|
||||
};
|
||||
|
||||
struct BitmapGroupSprite {
|
||||
u32 bitmap_index;
|
||||
char generated_pad2095[2];
|
||||
s32 left;
|
||||
s32 right;
|
||||
s32 top;
|
||||
s32 bottom;
|
||||
s64 real_point_2D;
|
||||
};
|
||||
|
||||
struct BitmapGroupSequence {
|
||||
char name[32];
|
||||
u32 first_bitmap_index;
|
||||
u32 bitmap_count;
|
||||
char sprites[16];
|
||||
s32 sprite_count;
|
||||
BitmapGroupSprite Sprites[sprite_count];
|
||||
};
|
||||
|
||||
|
||||
struct Bitm {
|
||||
u32 Usage;
|
||||
s32 UsageID;
|
||||
s32 Package;
|
||||
s32 texture_group;
|
||||
BitmapGroupFlags flags;
|
||||
u16 sprite_spacing;
|
||||
u16 mip_sample_count;
|
||||
float bump_map_height;
|
||||
float blur_factor;
|
||||
u32 blur;
|
||||
u32 mipmap_blur;
|
||||
curve_mode curvemode;
|
||||
s8 max_mipmap_level;
|
||||
u16 max_resolution;
|
||||
BitmapForcedFormat force_bitmap_format;
|
||||
SignedDistanceFieldMethod sdfgeneration;
|
||||
s8 target_platform;
|
||||
u16 spread_factor;
|
||||
u16 generated_pad8ed2;
|
||||
char usage_override[16];
|
||||
s32 usage_override_count;
|
||||
BitmapUsage bitmap_usage[usage_override_count];
|
||||
char manual_sequence[16];
|
||||
s32 manual_sequences_count;
|
||||
BitmapGroupSequence manual_sequences[manual_sequences_count];
|
||||
char source_data[24];
|
||||
char source_path[20];
|
||||
u64 source_checksum;
|
||||
RealARgbColor min_color;
|
||||
RealARgbColor max_color;
|
||||
char sequence[16];
|
||||
s32 sequences_count;
|
||||
BitmapGroupSequence sequences[sequences_count];
|
||||
char bitmapstart[16];
|
||||
s32 bitmap_block_count;
|
||||
BitmapBlock bitmap_block[bitmap_block_count];
|
||||
char RawDDSData[header.ActualResoureDataSize];
|
||||
};
|
||||
|
||||
|
||||
struct InternalStruct {
|
||||
s64 vtablespace;
|
||||
u32 global_tag_id;
|
||||
char local_tag_handle[4];
|
||||
};
|
||||
|
||||
|
||||
// TAG LAYOUT
|
||||
Header header @ 0x00;
|
||||
Tag_Dependency Dependencies[header.DependencyCount] @ 0x50;
|
||||
Data_Block datablocks[header.DataBlockCount] @ header.DependencyCount * 0x18 + 0x50;
|
||||
Tag_Def_Structure tagdefstructure[header.TagStructCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10;
|
||||
Data_Reference Data_References[header.DataReferenceCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10 + header.TagStructCount * 0x20;
|
||||
Tag_Fixup_Reference tagfixupreference[header.TagReferenceCount] @ header.DependencyCount * 0x18 + 0x50 + header.DataBlockCount * 0x10 + header.TagStructCount * 0x20 + header.DataReferenceCount * 0x14;
|
||||
char ZoneSet[header.ZoneSetDataSize] @ header.HeaderSize - header.ZoneSetDataSize; // zonesets kinda make no sense
|
||||
InternalStruct internalstruct @ header.HeaderSize;
|
||||
Bitm bitmap @ header.HeaderSize + 16;
|
||||
77
patterns/hinf_module.hexpat
Normal file
77
patterns/hinf_module.hexpat
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma author Surasia
|
||||
#pragma description Halo Infinite Module
|
||||
#pragma array_limit 4294967295
|
||||
#pragma pattern_limit 4294967295
|
||||
|
||||
import std.string;
|
||||
|
||||
struct ModuleHeader
|
||||
{
|
||||
char magic[4];
|
||||
s32 version;
|
||||
s64 moduleId;
|
||||
u32 fileCount;
|
||||
s32 manifest0Count;
|
||||
s32 manifest1Count;
|
||||
s32 manifest2Count;
|
||||
s32 resourceIndex;
|
||||
u32 stringSize;
|
||||
u32 resourceCount;
|
||||
u32 blockCount;
|
||||
u64 buildVersion;
|
||||
s64 hd1Delta;
|
||||
u64 dataSize;
|
||||
};
|
||||
|
||||
|
||||
struct ModuleFile
|
||||
{
|
||||
u32 resourceCount;
|
||||
s32 parentIndex;
|
||||
s16 pad;
|
||||
u16 blockCount;
|
||||
s32 blockIndex;
|
||||
s32 resourceIndex;
|
||||
char class[4] [[format("std::string::reverse")]];
|
||||
u64 dataOffsetBytes;
|
||||
u64 dataOffset = dataOffsetBytes & 0x0000FFFFFFFFFFFF [[export]];
|
||||
u16 dataOffsetFlags = dataOffsetBytes >> 48 [[export]];
|
||||
u32 totalCompressedSize;
|
||||
u32 totalUncompressedSize;
|
||||
u32 globalTagId;
|
||||
u32 uncompressedHeaderSize;
|
||||
u32 uncompressedTagDataSize;
|
||||
u32 uncompressedResourceDataSize;
|
||||
u32 uncompressedActualResourceDataSize;
|
||||
u32 resourceBlockCount;
|
||||
u32 nameOffset;
|
||||
s32 parentResource;
|
||||
u64 assetChecksum;
|
||||
u64 assetId;
|
||||
};
|
||||
|
||||
|
||||
struct ModuleBlock
|
||||
{
|
||||
u32 compressedOffset;
|
||||
u32 compressedSize;
|
||||
u32 decompressedOffset;
|
||||
u32 decompressedSize;
|
||||
bool compressed;
|
||||
s24 pad;
|
||||
};
|
||||
|
||||
|
||||
struct Module
|
||||
{
|
||||
ModuleHeader module_header;
|
||||
ModuleFile files[module_header.fileCount];
|
||||
$ = $ + 8;
|
||||
s32 resources[module_header.resourceCount];
|
||||
ModuleBlock blocks[module_header.blockCount];
|
||||
padding[while($[$] == 0)];
|
||||
std::print("Compressed Tag Data starts at: {}", $);
|
||||
};
|
||||
|
||||
|
||||
Module module_root @ 0x00;
|
||||
168
patterns/hinf_tag.hexpat
Normal file
168
patterns/hinf_tag.hexpat
Normal file
@@ -0,0 +1,168 @@
|
||||
#pragma author Surasia
|
||||
#pragma description Halo Infinite Tag File
|
||||
|
||||
import std.string;
|
||||
import type.guid;
|
||||
|
||||
u32 fileStart = 0;
|
||||
|
||||
enum TagSectionType : u16
|
||||
{
|
||||
header,
|
||||
tagData,
|
||||
resourceData
|
||||
};
|
||||
|
||||
|
||||
enum TagStructType : u16
|
||||
{
|
||||
mainStruct,
|
||||
tagBlock,
|
||||
resource,
|
||||
custom,
|
||||
literal
|
||||
};
|
||||
|
||||
|
||||
struct TagHeader
|
||||
{
|
||||
char magic[4];
|
||||
s32 version;
|
||||
u64 hash;
|
||||
u64 checksum;
|
||||
u32 dependencyCount;
|
||||
u32 dataBlockCount;
|
||||
u32 tagStructCount;
|
||||
u32 dataReferenceCount;
|
||||
u32 tagReferenceCount;
|
||||
u32 stringTableSize;
|
||||
u32 zoneSetDataSize;
|
||||
u32 unknown0;
|
||||
u32 headerSize;
|
||||
fileStart = headerSize;
|
||||
u32 dataSize;
|
||||
u32 resourceDataSize;
|
||||
u32 actualResourceDataSize;
|
||||
u8 headerAlignment;
|
||||
u8 tagDataAlignment;
|
||||
u8 resourceDataAlignment;
|
||||
u8 actualResourceAlignment;
|
||||
u32 unknown1;
|
||||
};
|
||||
|
||||
|
||||
struct TagDependency
|
||||
{
|
||||
char tagGroup[4] [[format("std::string::reverse")]];
|
||||
u32 nameOffset;
|
||||
u64 assetId;
|
||||
u32 globalId;
|
||||
u32 parentTag;
|
||||
};
|
||||
|
||||
|
||||
struct TagDataBlock
|
||||
{
|
||||
u32 entrySize;
|
||||
u16 pad;
|
||||
TagSectionType section;
|
||||
u64 offset;
|
||||
if (section == TagSectionType::tagData)
|
||||
{
|
||||
char dataBlock[entrySize] @ fileStart + offset;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct TagStruct
|
||||
{
|
||||
type::GUID guid;
|
||||
TagStructType type;
|
||||
u16 unknown0;
|
||||
s32 targetIndex;
|
||||
s32 fieldBlockIndex;
|
||||
u32 fieldOffset;
|
||||
};
|
||||
|
||||
|
||||
struct TagDataReference
|
||||
{
|
||||
s32 parentStructIndex;
|
||||
s32 unknown0;
|
||||
s32 targetIndex;
|
||||
s32 fieldBlockIndex;
|
||||
u32 fieldOffset;
|
||||
};
|
||||
|
||||
|
||||
struct TagReference
|
||||
{
|
||||
s32 fieldBlockIndex;
|
||||
u32 fieldOffset;
|
||||
u32 nameOffset;
|
||||
s32 dependencyIndex;
|
||||
};
|
||||
|
||||
|
||||
struct TagZonesetHeader
|
||||
{
|
||||
s32 version;
|
||||
u32 zonesetCount;
|
||||
u32 footerCount;
|
||||
s32 parentCount;
|
||||
};
|
||||
|
||||
|
||||
struct TagZonesetInstanceHeader
|
||||
{
|
||||
s32 stringId;
|
||||
u32 tagCount;
|
||||
u32 parentCount;
|
||||
u32 footerCount;
|
||||
};
|
||||
|
||||
|
||||
struct TagZonesetTag
|
||||
{
|
||||
u32 globalId;
|
||||
s32 stringId;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct TagZonesetInstance
|
||||
{
|
||||
TagZonesetInstanceHeader header;
|
||||
TagZonesetTag tags[header.tagCount];
|
||||
TagZonesetTag footers[header.footerCount];
|
||||
s32 parents[header.parentCount];
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct TagZoneset
|
||||
{
|
||||
TagZonesetHeader zoneset_header;
|
||||
TagZonesetInstance instances[zoneset_header.zonesetCount];
|
||||
};
|
||||
|
||||
|
||||
struct Tag
|
||||
{
|
||||
TagHeader header;
|
||||
TagDependency dependencies[header.dependencyCount];
|
||||
TagDataBlock data_blocks[header.dataBlockCount];
|
||||
TagStruct tag_structs[header.tagStructCount];
|
||||
TagDataReference data_references[header.dataReferenceCount];
|
||||
TagReference tag_references[header.tagReferenceCount];
|
||||
TagZoneset zonesets;
|
||||
if (header.headerSize != $)
|
||||
{
|
||||
std::print("Header size is wrong, additional data in tag");
|
||||
$ = header.headerSize;
|
||||
std::print("Data offset now at: {}", $);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Tag tag_root @ 0x00;
|
||||
@@ -41,7 +41,8 @@ enum Marker : u8 {
|
||||
APP13 = 0xED,
|
||||
APP14 = 0xEE,
|
||||
APP15 = 0xEF,
|
||||
COM = 0xFE
|
||||
COM = 0xFE,
|
||||
UNKNOWN = 0X00
|
||||
};
|
||||
|
||||
enum DensityUnit : u8 {
|
||||
@@ -103,6 +104,15 @@ fn sof0_component_read(SOF0Component c) {
|
||||
return std::format("({}, {}, {})", c.componentId, c.samplingFactors, c.quantizationTableId);
|
||||
};
|
||||
|
||||
fn get_eoi_marker_position() {
|
||||
u32 pos = std::mem::find_sequence_in_range(0, $, std::mem::size(), 0xFF);
|
||||
while (std::mem::read_unsigned(pos + 1, 1) != 0xD9) {
|
||||
pos = std::mem::find_sequence_in_range(0, pos + 1, std::mem::size() + 1, 0xFF);
|
||||
}
|
||||
return pos;
|
||||
|
||||
};
|
||||
|
||||
struct SOF0 {
|
||||
u8 bitsPerSample;
|
||||
u16 imageHeight, imageWidth;
|
||||
@@ -121,30 +131,34 @@ struct SOS {
|
||||
u8 startSpectralSelection;
|
||||
u8 endSpectral;
|
||||
u8 apprBitPos;
|
||||
|
||||
u8 image_data[std::mem::size() - $ - 2] [[sealed]];
|
||||
u8 image_data[get_eoi_marker_position() - $] [[sealed]];
|
||||
};
|
||||
|
||||
struct Segment {
|
||||
type::Magic<"\xff"> magic;
|
||||
Marker marker;
|
||||
|
||||
if (marker == Marker::SOI || marker == Marker::EOI) {
|
||||
|
||||
if (std::mem::read_unsigned($, 1) != 0xFF) {
|
||||
Marker marker = Marker::UNKNOWN;
|
||||
u8 data[get_eoi_marker_position() - $];
|
||||
} else {
|
||||
u16 length;
|
||||
if (marker == Marker::APP0) {
|
||||
APP0 data;
|
||||
} else if (marker == Marker::APP14) {
|
||||
APP14 data;
|
||||
} else if (marker == Marker::COM) {
|
||||
char data[length - sizeof(length)];
|
||||
} else if (marker == Marker::SOF0) {
|
||||
SOF0 data;
|
||||
} else if (marker == Marker::SOS) {
|
||||
SOS data;
|
||||
type::Magic<"\xff"> magic;
|
||||
Marker marker;
|
||||
|
||||
if (marker == Marker::SOI || marker == Marker::EOI) {
|
||||
|
||||
} else {
|
||||
u8 data[length - sizeof(length)] [[sealed]];
|
||||
u16 length;
|
||||
if (marker == Marker::APP0) {
|
||||
APP0 data;
|
||||
} else if (marker == Marker::APP14) {
|
||||
APP14 data;
|
||||
} else if (marker == Marker::COM) {
|
||||
char data[length - sizeof(length)];
|
||||
} else if (marker == Marker::SOF0) {
|
||||
SOF0 data;
|
||||
} else if (marker == Marker::SOS) {
|
||||
SOS data;
|
||||
} else {
|
||||
u8 data[length - sizeof(length)] [[sealed]];
|
||||
}
|
||||
}
|
||||
}
|
||||
} [[format_read("segment_read")]];
|
||||
@@ -153,4 +167,4 @@ fn segment_read(Segment s) {
|
||||
return std::format("{}", s.marker);
|
||||
};
|
||||
|
||||
Segment segments[while(!std::mem::eof())] @ 0x00 [[hex::visualize("image", this)]];
|
||||
Segment segments[while(!std::mem::eof())] @ 0x00 [[hex::visualize("image", this)]];
|
||||
|
||||
@@ -455,6 +455,33 @@ struct ImportsTable {
|
||||
$ = addressof(this)+coffHeader.optionalHeader.directories[1].size;
|
||||
};
|
||||
|
||||
struct DelayedImportsDirectory {
|
||||
u32 attributes;
|
||||
u32 name;
|
||||
u32 moduleHandle;
|
||||
u32 delayImportAddressTable;
|
||||
u32 delayImportNameTable;
|
||||
u32 boundDelayImportTable;
|
||||
u32 unloadDelayImportTable;
|
||||
u32 timeStamp;
|
||||
};
|
||||
|
||||
struct DelayImportsStructure {
|
||||
if (parent.delayImportsDirectoryTable[std::core::array_index()].delayImportNameTable > 0) {
|
||||
ImportsLookup delayedLookupTable[while(std::mem::read_unsigned($, wordsize()) != 0)] @ parent.delayImportsDirectoryTable[std::core::array_index()].delayImportNameTable - relativeVirtualDifference();
|
||||
}
|
||||
if (parent.delayImportsDirectoryTable[std::core::array_index()].name > 0) {
|
||||
char dllName[] @ parent.delayImportsDirectoryTable[std::core::array_index()].name - relativeVirtualDifference() [[format("formatNullTerminatedString")]];
|
||||
}
|
||||
} [[inline]];
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#delay-load-import-tables-image-only
|
||||
struct DelayedImportsTable {
|
||||
DelayedImportsDirectory delayImportsDirectoryTable[while(std::mem::read_unsigned($, 16) != 0)];
|
||||
DelayImportsStructure delayImportsStructures[sizeof(delayImportsDirectoryTable)/sizeof(delayImportsDirectoryTable[0])] [[inline]];
|
||||
$ = addressof(this)+coffHeader.optionalHeader.directories[1].size;
|
||||
};
|
||||
|
||||
// General Resource Table things
|
||||
fn formatNullTerminatedString16(str string) {
|
||||
return "\"" + std::string::substr(string, 0, std::string::length(string)) + "\"";
|
||||
@@ -1063,6 +1090,9 @@ struct Section {
|
||||
if (dataDirectoryInSection[9]) {
|
||||
TLSTable tlsTable @ coffHeader.optionalHeader.directories[9].rva - relativeVirtualDifference();
|
||||
}
|
||||
if (dataDirectoryInSection[13]) {
|
||||
DelayedImportsTable delayedImportTable @ coffHeader.optionalHeader.directories[13].rva - relativeVirtualDifference();
|
||||
}
|
||||
}
|
||||
clearBoolArray();
|
||||
|
||||
|
||||
33
patterns/psafe3.hexpat
Normal file
33
patterns/psafe3.hexpat
Normal file
@@ -0,0 +1,33 @@
|
||||
// Password Safe V3
|
||||
// Only a small part of the file is unencrypted.
|
||||
|
||||
#pragma endian little
|
||||
#pragma description Password Safe V3
|
||||
|
||||
import std.mem;
|
||||
import std.sys;
|
||||
|
||||
struct Prologue {
|
||||
u8 SALT[32];
|
||||
u32 ITER;
|
||||
u8 HPP[32] [[name("H(P')")]];
|
||||
u8 B1[16];
|
||||
u8 B2[16];
|
||||
u8 B3[16];
|
||||
u8 B4[16];
|
||||
u8 IV[16];
|
||||
};
|
||||
|
||||
struct EOF {
|
||||
u8 HMAC[32];
|
||||
};
|
||||
|
||||
char magic[4] @ 0x00;
|
||||
std::assert(magic == "PWS3", "Invalid file: bad tag!");
|
||||
char marker[16] @ std::mem::size() - 48;
|
||||
std::assert(marker == "PWS3-EOFPWS3-EOF", "Invalid file: bad end marker!");
|
||||
|
||||
Prologue prologue @ 0x04;
|
||||
u8 HMAC[32] @ std::mem::size() - 32;
|
||||
|
||||
EOF eof @ std::mem::size() - 48;
|
||||
726
patterns/ttf.hexpat
Normal file
726
patterns/ttf.hexpat
Normal file
@@ -0,0 +1,726 @@
|
||||
#pragma author Shimogawa (aka Rebuild)
|
||||
#pragma description TrueType and OpenType font format
|
||||
#pragma endian big
|
||||
#pragma MIME font/ttf
|
||||
#pragma MIME font/otf
|
||||
|
||||
#pragma pattern_limit 1000000
|
||||
|
||||
import std.mem;
|
||||
import std.string;
|
||||
import std.time;
|
||||
import std.io;
|
||||
|
||||
struct TableDirectory {
|
||||
char tag[4];
|
||||
u32 checkSum;
|
||||
u32 offset;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
fn format_fixed32(auto fp32) {
|
||||
return fp32.integer + fp32.fraction / 65536.0;
|
||||
};
|
||||
|
||||
fn format_f2dot14(auto f) {
|
||||
return f.integer + f.fraction / 16384.0;
|
||||
};
|
||||
|
||||
using FWord = s16;
|
||||
using UFWord = u16;
|
||||
|
||||
struct FixedPoint32 {
|
||||
u16 integer;
|
||||
u16 fraction;
|
||||
} [[format("format_fixed32")]];
|
||||
|
||||
bitfield F2Dot14 {
|
||||
integer : 2;
|
||||
fraction : 14;
|
||||
} [[format("format_f2dot14")]];
|
||||
|
||||
fn format_longdatetime(auto t) {
|
||||
return std::time::format(std::time::to_utc(u32(t.time - 2082844800)));
|
||||
};
|
||||
|
||||
struct LongDatetime {
|
||||
s64 time;
|
||||
} [[format("format_longdatetime")]];
|
||||
|
||||
using HeadTable;
|
||||
|
||||
u64 currentOffset;
|
||||
u64 currentLength;
|
||||
u64 glyfStart;
|
||||
bool hasPostScriptOutlines = false;
|
||||
u16 numHMetrics;
|
||||
u16 gNumGlyphs;
|
||||
HeadTable headTable;
|
||||
|
||||
// begin avar
|
||||
|
||||
struct AxisValueMap {
|
||||
F2Dot14 fromCoord;
|
||||
F2Dot14 toCoord;
|
||||
};
|
||||
|
||||
struct ShortFracSegment {
|
||||
u16 positionMapCount;
|
||||
AxisValueMap axisValueMaps[positionMapCount];
|
||||
};
|
||||
|
||||
struct AvarTable {
|
||||
FixedPoint32 version;
|
||||
s32 axisCount;
|
||||
ShortFracSegment segments[axisCount];
|
||||
};
|
||||
|
||||
// end avar
|
||||
|
||||
// begin cmap
|
||||
|
||||
u64 startOfCmapTable = 0;
|
||||
|
||||
struct BaseCmapSubtable {
|
||||
u64 start = $;
|
||||
u16 format;
|
||||
};
|
||||
|
||||
struct CmapSubtable0 : BaseCmapSubtable {
|
||||
u16 length;
|
||||
u16 language;
|
||||
u8 glyphIndexArr[256];
|
||||
};
|
||||
|
||||
struct CmapSubtable2 : BaseCmapSubtable {
|
||||
u16 length;
|
||||
u16 language;
|
||||
u16 subHeaderKeys[256];
|
||||
u8 data[length - 516];
|
||||
};
|
||||
|
||||
struct CmapSubtable4 : BaseCmapSubtable {
|
||||
u16 length;
|
||||
u64 end = start + length;
|
||||
u16 language;
|
||||
u16 segCountX2;
|
||||
u16 segCount = segCountX2 / 2;
|
||||
u16 searchRange;
|
||||
u16 entrySelector;
|
||||
u16 rangeShift;
|
||||
u16 endCode[segCount];
|
||||
u16 reserved;
|
||||
u16 startCode[segCount];
|
||||
s16 idDelta[segCount];
|
||||
u16 idRangeOffset[segCount];
|
||||
u16 glyphIdArr[(end - $) / sizeof(u16)];
|
||||
};
|
||||
|
||||
struct CmapSubtable6 : BaseCmapSubtable {
|
||||
u16 length;
|
||||
u16 language;
|
||||
u16 firstCode;
|
||||
u16 entryCount;
|
||||
u16 glyphIdArr[entryCount];
|
||||
};
|
||||
|
||||
struct SequentialMapGroup {
|
||||
u32 startCharCode;
|
||||
u32 endCharCode;
|
||||
u32 startGlyphId;
|
||||
};
|
||||
|
||||
struct CmapSubtable8 : BaseCmapSubtable {
|
||||
u16 reserved;
|
||||
u32 length;
|
||||
u32 language;
|
||||
u8 is32[8192];
|
||||
u32 numGroups;
|
||||
SequentialMapGroup groups[numGroups];
|
||||
};
|
||||
|
||||
struct CmapSubtable10 : BaseCmapSubtable {
|
||||
u16 reserved;
|
||||
u32 length;
|
||||
u64 end = start + length;
|
||||
u32 language;
|
||||
u32 startCharCode;
|
||||
u32 numChars;
|
||||
u16 glyphIdArr[(end - $) / sizeof(u16)];
|
||||
};
|
||||
|
||||
struct CmapSubtable12 : BaseCmapSubtable {
|
||||
u16 reserved;
|
||||
u32 length;
|
||||
u32 language;
|
||||
u32 numGroups;
|
||||
SequentialMapGroup groups[numGroups];
|
||||
};
|
||||
|
||||
struct CmapSubtable {
|
||||
u16 format = std::mem::read_unsigned($, 2, std::mem::Endian::Big);
|
||||
|
||||
match (format) {
|
||||
(0): CmapSubtable0 table [[inline]];
|
||||
(2): CmapSubtable2 table [[inline]];
|
||||
(4): CmapSubtable4 table [[inline]];
|
||||
(6): CmapSubtable6 table [[inline]];
|
||||
(8): CmapSubtable8 table [[inline]];
|
||||
(10): CmapSubtable10 table [[inline]];
|
||||
(12): CmapSubtable12 table [[inline]];
|
||||
(_): BaseCmapSubtable table [[inline]];
|
||||
}
|
||||
} [[name(std::format("Subtable Format {}", format))]];
|
||||
|
||||
enum CmapPlatform : u16 {
|
||||
Unicode = 0,
|
||||
Macintosh = 1,
|
||||
ISO = 2,
|
||||
Microsoft = 3,
|
||||
Custom = 4,
|
||||
};
|
||||
|
||||
struct EncodingRecord {
|
||||
CmapPlatform platformId;
|
||||
u16 encodingId;
|
||||
u32 offset;
|
||||
|
||||
u64 endEncodingRecord = $;
|
||||
$ = startOfCmapTable + offset;
|
||||
|
||||
CmapSubtable subtable;
|
||||
|
||||
$ = endEncodingRecord;
|
||||
};
|
||||
|
||||
struct CmapTable {
|
||||
startOfCmapTable = $;
|
||||
u16 version;
|
||||
u16 numSubtables;
|
||||
EncodingRecord encodingRecords[numSubtables];
|
||||
};
|
||||
|
||||
// end cmap
|
||||
|
||||
// begin cvt
|
||||
|
||||
struct CvtTable {
|
||||
u64 size = currentLength / sizeof(FWord);
|
||||
FWord controlValues[size];
|
||||
};
|
||||
|
||||
// end cvt
|
||||
|
||||
// begin gasp
|
||||
|
||||
bitfield RangeGaspBehavior {
|
||||
padding : 12;
|
||||
symmetricSmoothing : 1;
|
||||
symmetricGridfit : 1;
|
||||
doGray : 1;
|
||||
gridFit : 1;
|
||||
};
|
||||
|
||||
struct GaspRange {
|
||||
u16 rangeMaxPPEM;
|
||||
RangeGaspBehavior rangeGaspBehavior;
|
||||
};
|
||||
|
||||
struct GaspTable {
|
||||
u16 version;
|
||||
u16 numRanges;
|
||||
GaspRange gaspRanges[numRanges];
|
||||
};
|
||||
|
||||
// end gasp
|
||||
|
||||
// begin glyf
|
||||
|
||||
struct GlyphTableHeader {
|
||||
u64 startOffset = $;
|
||||
s16 numContours;
|
||||
FWord xMin;
|
||||
FWord yMin;
|
||||
FWord xMax;
|
||||
FWord yMax;
|
||||
};
|
||||
|
||||
bitfield OutlineFlag {
|
||||
padding : 2;
|
||||
ySameOrPositive : 1;
|
||||
xSameOrPositive : 1;
|
||||
repeat : 1;
|
||||
yShort : 1;
|
||||
xShort : 1;
|
||||
onCurve : 1;
|
||||
};
|
||||
|
||||
u32 pIdx = 0;
|
||||
u32 curGlyfSize;
|
||||
|
||||
struct SimpleGlyphFlag {
|
||||
pIdx += 1;
|
||||
OutlineFlag flag;
|
||||
if (flag.repeat) {
|
||||
pIdx += 1;
|
||||
u8 repeatTimes;
|
||||
}
|
||||
};
|
||||
|
||||
struct SimpleGlyphTable : GlyphTableHeader {
|
||||
u16 endPtsOfContours[numContours];
|
||||
u32 numPoints = numContours == 0 ? 0 : endPtsOfContours[numContours - 1];
|
||||
u16 instructionLength;
|
||||
u8 instructions[instructionLength];
|
||||
pIdx = 0;
|
||||
SimpleGlyphFlag flags[while(pIdx < numPoints)] [[single_color]];
|
||||
u8 data[startOffset + curGlyfSize - $];
|
||||
};
|
||||
|
||||
bitfield CompositeGlyphFlag {
|
||||
padding : 3;
|
||||
unscaledComponentOffset : 1;
|
||||
scaledComponentOffset : 1;
|
||||
overlapCompound : 1;
|
||||
useMyMetrics : 1;
|
||||
weHaveInstructions : 1;
|
||||
weHaveA2x2 : 1;
|
||||
weHaveAnXAndYScale : 1;
|
||||
moreComponents : 1;
|
||||
padding : 1;
|
||||
weHaveAScale : 1;
|
||||
roundXYToGrid : 1;
|
||||
argsAreXYValues : 1;
|
||||
arg1And2AreWords : 1;
|
||||
};
|
||||
|
||||
bool componentGlyphHasMoreComponents;
|
||||
bool componentGlyphHasInstruction;
|
||||
|
||||
struct ComponentGlyphRecord {
|
||||
CompositeGlyphFlag flags;
|
||||
u16 glyphIndex;
|
||||
if (flags.arg1And2AreWords) {
|
||||
FWord arg1;
|
||||
FWord arg2;
|
||||
} else {
|
||||
u8 arg1;
|
||||
u8 arg2;
|
||||
}
|
||||
if (flags.weHaveAScale) {
|
||||
F2Dot14 scale;
|
||||
} else if (flags.weHaveAnXAndYScale) {
|
||||
F2Dot14 xScale;
|
||||
F2Dot14 yScale;
|
||||
} else if (flags.weHaveA2x2) {
|
||||
F2Dot14 xScale;
|
||||
F2Dot14 scale01;
|
||||
F2Dot14 scale10;
|
||||
F2Dot14 yScale;
|
||||
}
|
||||
componentGlyphHasMoreComponents = flags.moreComponents;
|
||||
componentGlyphHasInstruction = flags.weHaveInstructions;
|
||||
};
|
||||
|
||||
struct CompositeGlyphTable : GlyphTableHeader {
|
||||
componentGlyphHasMoreComponents = true;
|
||||
componentGlyphHasInstruction = false;
|
||||
ComponentGlyphRecord records[while (componentGlyphHasMoreComponents)];
|
||||
if (componentGlyphHasInstruction) {
|
||||
u16 instructionLength;
|
||||
u8 instructions[instructionLength];
|
||||
}
|
||||
};
|
||||
|
||||
struct GlyfTable {
|
||||
s16 type = std::mem::read_signed($, 2, std::mem::Endian::Big);
|
||||
|
||||
if (type >= 0) {
|
||||
SimpleGlyphTable table [[inline]];
|
||||
} else {
|
||||
CompositeGlyphTable table [[inline]];
|
||||
}
|
||||
} [[name(std::format("glyf ({})", table.numContours < 0 ? "Composite" : "Simple"))]];
|
||||
|
||||
// end glyf
|
||||
|
||||
// begin hdmx
|
||||
|
||||
struct DeviceRecord {
|
||||
u8 pixelSize;
|
||||
u8 maxWidth;
|
||||
u8 widths[gNumGlyphs];
|
||||
};
|
||||
|
||||
struct HdmxTable {
|
||||
u16 version;
|
||||
u16 numRecords;
|
||||
u32 sizeDeviceRecord;
|
||||
DeviceRecord records[numRecords];
|
||||
};
|
||||
|
||||
// end hdmx
|
||||
|
||||
// begin head
|
||||
|
||||
bitfield HeadFlag {
|
||||
padding : 1;
|
||||
lastResort : 1;
|
||||
clearTypeOptimized : 1;
|
||||
converted : 1;
|
||||
lossless : 1;
|
||||
indicStyleRearr : 1;
|
||||
RTLGlyph : 1;
|
||||
AATFont : 1;
|
||||
linguisticRender : 1;
|
||||
padding : 1;
|
||||
verticalLayout : 1;
|
||||
instrMayAlterAW : 1;
|
||||
integerScaling : 1;
|
||||
differentPointSize : 1;
|
||||
xLBlackBitIsLSB : 1;
|
||||
yZeroIsBaseline : 1;
|
||||
};
|
||||
|
||||
bitfield MacStyle {
|
||||
padding : 9;
|
||||
extended : 1;
|
||||
condensed : 1;
|
||||
shadow : 1;
|
||||
outline : 1;
|
||||
underline : 1;
|
||||
italic : 1;
|
||||
bold : 1;
|
||||
};
|
||||
|
||||
struct HeadTable {
|
||||
FixedPoint32 version;
|
||||
FixedPoint32 fontRevision;
|
||||
u32 checksumAdjustment;
|
||||
u32 magic;
|
||||
HeadFlag flags;
|
||||
u16 unitsPerEm;
|
||||
LongDatetime created;
|
||||
LongDatetime modified;
|
||||
FWord xMin;
|
||||
FWord yMin;
|
||||
FWord xMax;
|
||||
FWord yMax;
|
||||
MacStyle macStyle;
|
||||
u16 lowestRecPPEM;
|
||||
s16 fontDirectionHint;
|
||||
s16 indexToLocFormat;
|
||||
s16 glyphDataFormat;
|
||||
};
|
||||
|
||||
// end head
|
||||
|
||||
// begin hhea
|
||||
|
||||
struct HheaTable {
|
||||
FixedPoint32 version;
|
||||
FWord ascent;
|
||||
FWord descent;
|
||||
FWord lineGap;
|
||||
UFWord advanceWidthMax;
|
||||
FWord minLeftSideBearing;
|
||||
FWord minRightSideBearing;
|
||||
FWord xMaxExtent;
|
||||
s16 caretSlopeRise;
|
||||
s16 caretSlopeRun;
|
||||
s16 caretOffset;
|
||||
s16 reserved[4];
|
||||
s16 metricDataFormat;
|
||||
u16 numberOfHMetrics;
|
||||
numHMetrics = numberOfHMetrics;
|
||||
};
|
||||
|
||||
// end hhea
|
||||
|
||||
// begin hmtx
|
||||
|
||||
struct LongHorMetric {
|
||||
UFWord advanceWidth;
|
||||
FWord lsb;
|
||||
};
|
||||
|
||||
struct HmtxTable {
|
||||
LongHorMetric hMetrics[numHMetrics];
|
||||
FWord leftSideBearings[gNumGlyphs - numHMetrics];
|
||||
};
|
||||
|
||||
// end hmtx
|
||||
|
||||
// begin loca
|
||||
|
||||
// loca contains offsets for glyf tables, so
|
||||
// we put glyf arrays here also.
|
||||
|
||||
struct GlyfWithOffset<auto longOffset> {
|
||||
if (longOffset) {
|
||||
u32 offset;
|
||||
u32 realOffset = offset;
|
||||
u32 nextOff = std::mem::read_unsigned($, 4, std::mem::Endian::Big);
|
||||
} else {
|
||||
u16 offset;
|
||||
u32 realOffset = u32(offset) * 2;
|
||||
u32 nextOff = u32(std::mem::read_unsigned($, 2, std::mem::Endian::Big)) * 2;
|
||||
}
|
||||
curGlyfSize = nextOff - realOffset;
|
||||
u64 prev = $;
|
||||
$ = glyfStart + realOffset;
|
||||
if (curGlyfSize != 0) {
|
||||
GlyfTable glyf;
|
||||
}
|
||||
$ = prev;
|
||||
};
|
||||
|
||||
struct LocaTable {
|
||||
if (headTable.indexToLocFormat == 1) {
|
||||
//u32 offsets[gNumGlyphs + 1];
|
||||
GlyfWithOffset<true> glyfs[gNumGlyphs];
|
||||
} else {
|
||||
// u16 offsets[gNumGlyphs + 1];
|
||||
GlyfWithOffset<false> glyfs[gNumGlyphs];
|
||||
}
|
||||
};
|
||||
|
||||
// end loca
|
||||
|
||||
// begin maxp
|
||||
|
||||
struct MaxpTable {
|
||||
FixedPoint32 version;
|
||||
u16 numGlyphs;
|
||||
gNumGlyphs = numGlyphs;
|
||||
if (!hasPostScriptOutlines) {
|
||||
u16 maxPoints;
|
||||
u16 maxContours;
|
||||
u16 maxComponentPoints;
|
||||
u16 maxComponentContours;
|
||||
u16 maxZones;
|
||||
u16 maxTwilightPoints;
|
||||
u16 maxStorage;
|
||||
u16 maxFunctionDefs;
|
||||
u16 maxInstructionDefs;
|
||||
u16 maxStackElements;
|
||||
u16 maxSizeOfElements;
|
||||
u16 maxComponentDepth;
|
||||
}
|
||||
};
|
||||
|
||||
// end maxp
|
||||
|
||||
// begin name
|
||||
|
||||
u64 curStorageOffset;
|
||||
|
||||
struct NameRecord {
|
||||
u16 platformId;
|
||||
u16 encodingId;
|
||||
u16 languageId;
|
||||
u16 nameId;
|
||||
u16 length;
|
||||
u16 stringOffset;
|
||||
u64 cur = $;
|
||||
$ = curStorageOffset + stringOffset;
|
||||
char16 string[length / 2];
|
||||
$ = cur;
|
||||
};
|
||||
|
||||
struct LangTagRecord {
|
||||
u16 length;
|
||||
u16 langTagOffset;
|
||||
u64 cur = $;
|
||||
$ = curStorageOffset + langTagOffset;
|
||||
char16 langTag[length / 2];
|
||||
$ = cur;
|
||||
};
|
||||
|
||||
struct NameTableV0 {
|
||||
u64 startOfNameTable = $;
|
||||
u16 version;
|
||||
u16 count;
|
||||
u16 storageOffset;
|
||||
curStorageOffset = startOfNameTable + storageOffset;
|
||||
NameRecord nameRecords[count];
|
||||
};
|
||||
|
||||
struct NameTableV1 : NameTableV0 {
|
||||
u16 langTagCount;
|
||||
LangTagRecord langTagRecords[langTagCount];
|
||||
};
|
||||
|
||||
struct NameTable {
|
||||
u16 version = std::mem::read_unsigned($, 2, std::mem::Endian::Big);
|
||||
|
||||
match (version) {
|
||||
(0): NameTableV0 table [[inline]];
|
||||
(_): NameTableV1 table [[inline]];
|
||||
}
|
||||
};
|
||||
|
||||
// end name
|
||||
|
||||
// begin OS/2
|
||||
|
||||
struct OS2TableV0 {
|
||||
u16 version;
|
||||
FWord xAvgCharWidth;
|
||||
u16 usWeightClass;
|
||||
u16 usWidthClass;
|
||||
u16 fsType;
|
||||
FWord ySubscriptXSize;
|
||||
FWord ySubscriptYSize;
|
||||
FWord SubscriptXOffset;
|
||||
FWord SubscriptYOffset;
|
||||
FWord ySuperscriptXSize;
|
||||
FWord ySuperscriptYSize;
|
||||
FWord SuperscriptXOffset;
|
||||
FWord SuperscriptYOffset;
|
||||
FWord yStrikeoutSize;
|
||||
FWord yStrikeoutPosition;
|
||||
s16 sFamilyClass;
|
||||
u8 panose[10];
|
||||
u32 ulUnicodeRange[4];
|
||||
u8 achVendID[4];
|
||||
u16 fsSelection;
|
||||
u16 usFirstCharIndex;
|
||||
u16 usLastCharIndex;
|
||||
FWord sTypoAscender;
|
||||
FWord sTypoDescender;
|
||||
FWord sTypoLineGap;
|
||||
UFWord usWinAscent;
|
||||
UFWord usWinDescent;
|
||||
};
|
||||
|
||||
struct OS2TableV1 : OS2TableV0 {
|
||||
u32 ulCodePageRange[2];
|
||||
};
|
||||
|
||||
struct OS2TableV4 : OS2TableV1 {
|
||||
FWord sxHeight;
|
||||
FWord sCapHeight;
|
||||
u16 usDefaultChar;
|
||||
u16 usBreakChar;
|
||||
u16 usMaxContent;
|
||||
};
|
||||
|
||||
struct OS2TableV5 : OS2TableV4 {
|
||||
u16 usLowerOpticalPointSize;
|
||||
u16 usUpperOpticalPointSize;
|
||||
};
|
||||
|
||||
struct OS2Table {
|
||||
u16 version = std::mem::read_unsigned($, 2, std::mem::Endian::Big);
|
||||
|
||||
match (version) {
|
||||
(0): OS2TableV0 table [[inline]];
|
||||
(1): OS2TableV1 table [[inline]];
|
||||
(2 | 3 | 4): OS2TableV4 table [[inline]];
|
||||
(_): OS2TableV5 table [[inline]];
|
||||
}
|
||||
};
|
||||
|
||||
// end OS/2
|
||||
|
||||
// begin post
|
||||
|
||||
struct PostTableV1 {
|
||||
u64 startOfTable = $;
|
||||
FixedPoint32 version;
|
||||
FixedPoint32 italicAngle;
|
||||
FWord underlinePosition;
|
||||
FWord underlineThickness;
|
||||
u32 isFixedPitch;
|
||||
u32 minMemType42;
|
||||
u32 maxMemType42;
|
||||
u32 minMemType1;
|
||||
u32 maxMemType1;
|
||||
};
|
||||
|
||||
struct PostTableV2 : PostTableV1 {
|
||||
u16 numGlyphs;
|
||||
u16 glyphNameIndex[numGlyphs];
|
||||
std::string::SizedString<u8> stringData[while ($ < startOfTable + currentLength)];
|
||||
};
|
||||
|
||||
struct PostTable {
|
||||
u16 major = std::mem::read_unsigned($, 2, std::mem::Endian::Big);
|
||||
u16 minor = std::mem::read_unsigned($ + 2, 2, std::mem::Endian::Big);
|
||||
|
||||
match (major, minor) {
|
||||
(2, 0): PostTableV2 table [[inline]];
|
||||
(_, _): PostTableV1 table [[inline]];
|
||||
}
|
||||
};
|
||||
|
||||
// end post
|
||||
|
||||
struct HiddenForPreprocessing {
|
||||
u64 defStart = $;
|
||||
TableDirectory td;
|
||||
$ = td.offset;
|
||||
currentOffset = td.offset;
|
||||
currentLength = td.length;
|
||||
match (td.tag) {
|
||||
("CFF "): {
|
||||
hasPostScriptOutlines = true;
|
||||
}
|
||||
("maxp"): MaxpTable table;
|
||||
("head"): {
|
||||
HeadTable table;
|
||||
headTable = table;
|
||||
}
|
||||
("glyf"): {
|
||||
glyfStart = $;
|
||||
}
|
||||
}
|
||||
$ = defStart + sizeof(TableDirectory);
|
||||
} [[hidden]];
|
||||
|
||||
struct Table {
|
||||
u64 defStart = $;
|
||||
TableDirectory td [[inline]];
|
||||
$ = td.offset;
|
||||
currentOffset = td.offset;
|
||||
currentLength = td.length;
|
||||
match (td.tag) {
|
||||
("avar"): AvarTable table;
|
||||
("bhed"): HeadTable table;
|
||||
("cmap"): CmapTable table;
|
||||
("cvt "): CvtTable table;
|
||||
("gasp"): GaspTable table;
|
||||
// ("glyf"): GlyfTable table;
|
||||
// glyf will be contained in loca.
|
||||
("glyf"): {}
|
||||
("hdmx"): HdmxTable table;
|
||||
("head"): HeadTable table;
|
||||
("hhea"): HheaTable table;
|
||||
("hmtx"): HmtxTable table;
|
||||
("loca"): LocaTable table;
|
||||
("maxp"): MaxpTable table;
|
||||
("name"): NameTable table;
|
||||
("OS/2"): OS2Table table;
|
||||
("post"): PostTable table;
|
||||
(_): u8 data[td.length];
|
||||
}
|
||||
$ = defStart + sizeof(TableDirectory);
|
||||
} [[name(std::format("Table({})", td.tag))]];
|
||||
|
||||
|
||||
struct TTF {
|
||||
u32 scalarType;
|
||||
u16 numTables;
|
||||
u16 searchRange;
|
||||
u16 entrySelector;
|
||||
u16 rangeShift;
|
||||
|
||||
u64 start = $;
|
||||
HiddenForPreprocessing hidden[numTables] [[hidden]];
|
||||
$ = start;
|
||||
|
||||
Table tables[numTables];
|
||||
};
|
||||
|
||||
TTF ttf @ 0x0;
|
||||
@@ -231,7 +231,7 @@ struct DeviceQualifierDescriptor {
|
||||
bitfield OTGAttributes {
|
||||
SRPSupport : 1;
|
||||
HNPSupport : 1;
|
||||
} [[right_to_left]];
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 2)]];
|
||||
|
||||
struct OTGDescriptor {
|
||||
OTGAttributes bmAttributes;
|
||||
|
||||
@@ -47,11 +47,11 @@ bitfield Header {
|
||||
fn validate_hdr_checksum(Header hdr) {
|
||||
// Reassemble as a 2-byte big endian value
|
||||
u16 value = (
|
||||
(hdr.method << 8) +
|
||||
(u8(hdr.method) << 8) +
|
||||
(hdr.info << 12) +
|
||||
(hdr.fcheck << 0) +
|
||||
(hdr.fdict << 5) +
|
||||
(hdr.flevel << 6)
|
||||
(u8(hdr.flevel) << 6)
|
||||
);
|
||||
|
||||
if (value % 31 == 0) {
|
||||
|
||||
@@ -83,5 +83,11 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return hasDescription ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
if (!hasDescription) {
|
||||
fmt::print("No description pragma found in pattern file\n");
|
||||
fmt::print("Please add a #pragma description <your description> tag to the pattern!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
tests/patterns/test_data/hinf_module.hexpat.module
Normal file
BIN
tests/patterns/test_data/hinf_module.hexpat.module
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/hinf_tag.hexpat.tag
Normal file
BIN
tests/patterns/test_data/hinf_tag.hexpat.tag
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/psafe3.hexpat.psafe3
Normal file
BIN
tests/patterns/test_data/psafe3.hexpat.psafe3
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/ttf.hexpat.ttf
Normal file
BIN
tests/patterns/test_data/ttf.hexpat.ttf
Normal file
Binary file not shown.
Reference in New Issue
Block a user