Created
November 27, 2025 12:36
-
-
Save shortthefomo/ccf5282137a9183e292a46014df27b0e to your computer and use it in GitHub Desktop.
Generate all possible combinations of composable flags
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdint.h> | |
| #include <math.h> | |
| /** | |
| * @brief Generate all possible combinations of composable flags | |
| * | |
| * @param flags Array of flag values to combine | |
| * @param flag_count Number of flags in the input array | |
| * @param output_combinations Pointer to store the resulting combinations array | |
| * @param output_count Pointer to store the number of combinations generated | |
| * @return int 0 on success, -1 on failure | |
| */ | |
| int xrpl_generate_flag_combinations( | |
| const uint32_t* flags, | |
| size_t flag_count, | |
| uint32_t** output_combinations, | |
| size_t* output_count | |
| ) { | |
| if (flags == NULL || output_combinations == NULL || output_count == NULL) { | |
| return -1; | |
| } | |
| // Calculate total combinations: 2^flag_count | |
| size_t total_combinations = (size_t)pow(2, flag_count); | |
| // Allocate memory for output array | |
| *output_combinations = (uint32_t*)malloc(total_combinations * sizeof(uint32_t)); | |
| if (*output_combinations == NULL) { | |
| return -1; | |
| } | |
| // Generate all combinations using bitwise operations | |
| for (size_t i = 0; i < total_combinations; i++) { | |
| uint32_t combination = 0; | |
| // Check each bit position | |
| for (size_t j = 0; j < flag_count; j++) { | |
| // If bit j is set in i, include flag j in the combination | |
| if (i & (1 << j)) { | |
| combination |= flags[j]; | |
| } | |
| } | |
| (*output_combinations)[i] = combination; | |
| } | |
| *output_count = total_combinations; | |
| return 0; | |
| } | |
| /** | |
| * @brief Filter combinations by a specific flag presence | |
| * | |
| * @param combinations Array of all combinations | |
| * @param combination_count Number of combinations | |
| * @param required_flag Flag that must be present | |
| * @param output_filtered Pointer to store filtered combinations | |
| * @param output_filtered_count Pointer to store count of filtered combinations | |
| * @return int 0 on success, -1 on failure | |
| */ | |
| int xrpl_filter_flag_combinations( | |
| const uint32_t* combinations, | |
| size_t combination_count, | |
| uint32_t required_flag, | |
| uint32_t** output_filtered, | |
| size_t* output_filtered_count | |
| ) { | |
| if (combinations == NULL || output_filtered == NULL || output_filtered_count == NULL) { | |
| return -1; | |
| } | |
| // First pass: count matching combinations | |
| size_t match_count = 0; | |
| for (size_t i = 0; i < combination_count; i++) { | |
| if (combinations[i] & required_flag) { | |
| match_count++; | |
| } | |
| } | |
| // Allocate memory for filtered results | |
| *output_filtered = (uint32_t*)malloc(match_count * sizeof(uint32_t)); | |
| if (*output_filtered == NULL && match_count > 0) { | |
| return -1; | |
| } | |
| // Second pass: copy matching combinations | |
| size_t index = 0; | |
| for (size_t i = 0; i < combination_count; i++) { | |
| if (combinations[i] & required_flag) { | |
| (*output_filtered)[index++] = combinations[i]; | |
| } | |
| } | |
| *output_filtered_count = match_count; | |
| return 0; | |
| } | |
| /** | |
| * @brief Check if a combination contains a specific flag | |
| * | |
| * @param combination The combined flag value | |
| * @param flag The flag to check for | |
| * @return int 1 if flag is present, 0 otherwise | |
| */ | |
| int xrpl_has_flag(uint32_t combination, uint32_t flag) { | |
| return (combination & flag) == flag; | |
| } | |
| // Example usage and test function | |
| #ifdef XRPL_FLAG_COMBINATIONS_TEST | |
| int main(void) { | |
| // XRPL Payment flags (excluding deprecated tfFullyCanonicalSig) | |
| uint32_t payment_flags[] = { | |
| 0x00010000, // tfNoDirectRipple (65536) | |
| 0x00020000, // tfPartialPayment (131072) | |
| 0x00040000 // tfLimitQuality (262144) | |
| }; | |
| size_t flag_count = sizeof(payment_flags) / sizeof(payment_flags[0]); | |
| uint32_t* combinations = NULL; | |
| size_t combination_count = 0; | |
| // Generate all combinations | |
| if (xrpl_generate_flag_combinations(payment_flags, flag_count, &combinations, &combination_count) != 0) { | |
| fprintf(stderr, "Error generating flag combinations\n"); | |
| return 1; | |
| } | |
| printf("Generated %zu flag combinations:\n", combination_count); | |
| for (size_t i = 0; i < combination_count; i++) { | |
| printf(" [%zu] = %u (0x%08X)\n", i, combinations[i], combinations[i]); | |
| } | |
| // Filter for combinations that include tfPartialPayment | |
| uint32_t* partial_combinations = NULL; | |
| size_t partial_count = 0; | |
| if (xrpl_filter_flag_combinations(combinations, combination_count, 0x00020000, &partial_combinations, &partial_count) == 0) { | |
| printf("\nCombinations with tfPartialPayment (%zu):\n", partial_count); | |
| for (size_t i = 0; i < partial_count; i++) { | |
| printf(" %u (0x%08X)\n", partial_combinations[i], partial_combinations[i]); | |
| } | |
| free(partial_combinations); | |
| } | |
| free(combinations); | |
| return 0; | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment