|
| 1 | +// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL |
| 2 | +// RUN: %vast-front -vast-show-locs -vast-loc-attrs -vast-emit-mlir=hl %s -o - | %vast-opt -vast-hl-to-lazy-regions -o %t.mlir |
| 3 | +// RUN: %vast-detect-parsers -vast-hl-to-parser -vast-parser-reconcile-casts -reconcile-unrealized-casts %t.mlir -o - | %file-check %s -check-prefix=PARSER |
| 4 | + |
| 5 | +#include <stdio.h> |
| 6 | +#include <stdlib.h> |
| 7 | +#include <stdint.h> |
| 8 | + |
| 9 | +// Function to calculate a simple checksum (XOR all bytes) |
| 10 | +// HL: hl.func @calculate_checksum |
| 11 | +// PARSER: hl.func @calculate_checksum |
| 12 | +uint32_t calculate_checksum(uint8_t *data, size_t length) { |
| 13 | + uint32_t checksum = 0; |
| 14 | + for (size_t i = 0; i < length; ++i) { |
| 15 | + checksum ^= data[i]; |
| 16 | + } |
| 17 | + return checksum; |
| 18 | +} |
| 19 | + |
| 20 | +// Function to parse a binary file containing multiple records |
| 21 | +// HL: hl.func @parse_binary_records |
| 22 | +// PARSER: hl.func @parse_binary_records |
| 23 | +void parse_binary_records(const char *filename) { |
| 24 | + FILE *file = fopen(filename, "rb"); |
| 25 | + if (!file) { |
| 26 | + perror("Error opening file"); |
| 27 | + return; |
| 28 | + } |
| 29 | + |
| 30 | + // Go to the end of the file to find the file length |
| 31 | + fseek(file, 0, SEEK_END); |
| 32 | + size_t file_length = ftell(file); |
| 33 | + rewind(file); |
| 34 | + |
| 35 | + // Read the file contents into a buffer |
| 36 | + uint8_t *buffer = (uint8_t *)malloc(file_length); |
| 37 | + fread(buffer, sizeof(uint8_t), file_length, file); |
| 38 | + |
| 39 | + // Close the file after reading |
| 40 | + fclose(file); |
| 41 | + |
| 42 | + size_t idx = 0; |
| 43 | + printf("Parsing records:\n"); |
| 44 | + |
| 45 | + // Parsing Part: Read records until the checksum |
| 46 | + while (idx < file_length - 4) { // Last 4 bytes are the checksum |
| 47 | + // Read record type (2 bytes) |
| 48 | + uint16_t record_type = (buffer[idx] << 8) | buffer[idx + 1]; |
| 49 | + idx += 2; |
| 50 | + |
| 51 | + // Read record length (2 bytes) |
| 52 | + uint16_t record_length = (buffer[idx] << 8) | buffer[idx + 1]; |
| 53 | + idx += 2; |
| 54 | + |
| 55 | + // Read record data based on length |
| 56 | + uint8_t *record_data = &buffer[idx]; |
| 57 | + idx += record_length; |
| 58 | + |
| 59 | + // Print record information |
| 60 | + printf("Record Type: %u, Length: %u, Data: ", record_type, record_length); |
| 61 | + for (uint16_t i = 0; i < record_length; ++i) { |
| 62 | + printf("%02X ", record_data[i]); |
| 63 | + } |
| 64 | + printf("\n"); |
| 65 | + } |
| 66 | + |
| 67 | + // Parsing Part: Read and verify the checksum (last 4 bytes) |
| 68 | + uint32_t checksum = (buffer[idx] << 24) | (buffer[idx + 1] << 16) | (buffer[idx + 2] << 8) | buffer[idx + 3]; |
| 69 | + printf("Read checksum: %08X\n", checksum); |
| 70 | + |
| 71 | + // Non-Parsing Part: Calculate checksum of the data |
| 72 | + uint32_t calculated_checksum = calculate_checksum(buffer, file_length - 4); |
| 73 | + printf("Calculated checksum: %08X\n", calculated_checksum); |
| 74 | + |
| 75 | + // Validate checksum |
| 76 | + if (checksum == calculated_checksum) { |
| 77 | + printf("Checksum verification passed.\n"); |
| 78 | + } else { |
| 79 | + printf("Checksum verification failed.\n"); |
| 80 | + } |
| 81 | + |
| 82 | + // Free memory |
| 83 | + free(buffer); |
| 84 | +} |
| 85 | + |
| 86 | +int main() { |
| 87 | + const char *filename = "records_data.bin"; |
| 88 | + parse_binary_records(filename); |
| 89 | + return 0; |
| 90 | +} |
0 commit comments