Word Unperfect
public
Read
Owner: themaster
Branch: main
Commits: 0
Git CLI clone URL
git clone https://www.xt-emporium.com/git/word-unperfect.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
word-unperfect
/
rev
/
wp_record_dump.c
File editor
#include "wp_record_dump.h" #include "wp_document_analyzer.h" #include "wp_fixed_codes.h" #include "wp_record_parser.h" #include "wp_variable_codes.h" #include <ctype.h> #include <string.h> static const char *wp_record_dump_type_name(const WpRecord *rec) { if (rec == NULL) { return "null"; } switch (rec->type) { case WP_CODE_CHAR: return "char"; case WP_CODE_SINGLE_BYTE: return "single"; case WP_CODE_FIXED_LENGTH: return "fixed"; case WP_CODE_VARIABLE_LENGTH: return "var"; default: return "unknown"; } } static char wp_record_dump_printable_char(uint8_t ch) { return (ch >= 0x20U && ch < 0x7FU) ? (char)ch : '.'; } static void wp_record_dump_print_char_literal(FILE *out, uint8_t ch) { if (out == NULL) { return; } if (ch == '\\' || ch == '\'') { fprintf(out, " ch='\\%c'", (int)ch); } else if (ch >= 0x20U && ch < 0x7FU) { fprintf(out, " ch='%c'", (int)ch); } else { fprintf(out, " ch=0x%02X", (unsigned)ch); } } static void wp_record_dump_print_payload(FILE *out, const WpRecord *rec, const WpRecordDumpOptions *options) { size_t i; size_t shown; if (out == NULL || rec == NULL || rec->data == NULL || rec->data_length == 0U || options == NULL || options->max_payload_bytes == 0U) { return; } shown = rec->data_length; if (shown > options->max_payload_bytes) { shown = options->max_payload_bytes; } fprintf(out, " payload="); for (i = 0; i < shown; ++i) { fprintf(out, "%s%02X", i == 0U ? "" : " ", (unsigned)rec->data[i]); } if (shown < rec->data_length) { fprintf(out, " ...(+%lu)", (unsigned long)(rec->data_length - shown)); } if (options->include_payload_ascii) { fprintf(out, " ascii=\""); for (i = 0; i < shown; ++i) { fputc(wp_record_dump_printable_char(rec->data[i]), out); } if (shown < rec->data_length) { fputs("...", out); } fputc('"', out); } } void wp_record_dump_default_options(WpRecordDumpOptions *options) { if (options == NULL) { return; } options->max_records = 0U; options->max_payload_bytes = 16U; options->include_payload_ascii = true; } void wp_record_dump_clear_stats(WpRecordDumpStats *stats) { if (stats != NULL) { memset(stats, 0, sizeof(*stats)); } } bool wp_record_dump_stream(WpLayoutGlobals *wl, FILE *out, const WpRecordDumpOptions *options, WpRecordDumpStats *stats) { WpLayoutGlobals cursor; WpRecordDumpOptions local_options; WpRecordDumpStats local_stats; if (wl == NULL || out == NULL) { return false; } if (options == NULL) { wp_record_dump_default_options(&local_options); options = &local_options; } wp_record_dump_clear_stats(&local_stats); cursor = *wl; fprintf(out, "offset type code label details\n"); fprintf(out, "-------- ----- --------- -------------------------------- -------\n"); while (cursor.record_used_bytes > 0) { WpRecord rec; size_t offset = local_stats.bytes_consumed; if (options->max_records != 0U && local_stats.records_seen >= options->max_records) { local_stats.hit_record_limit = true; break; } wp_parser_consume_record(&cursor, &rec); if (rec.length == 0U) { wp_record_free(&rec); break; } fprintf(out, "%08lX %-5s code=0x%02X %-32s len=%u", (unsigned long)offset, wp_record_dump_type_name(&rec), (unsigned)rec.code, wp_document_code_label(rec.code, rec.sub_code), (unsigned)rec.length); if (rec.type == WP_CODE_CHAR) { wp_record_dump_print_char_literal(out, rec.code); } else if (rec.type == WP_CODE_FIXED_LENGTH) { fprintf(out, " declared=%u copied=%u trailer=%s complete=%s", (unsigned)rec.declared_length, (unsigned)rec.data_length, rec.trailer_present ? (rec.trailer_matches ? "ok" : "bad") : "n/a", rec.is_complete ? "yes" : "no"); { char fixed_detail[128]; if (wp_fixed_code_describe_payload(rec.code, rec.data, rec.data_length, fixed_detail, sizeof(fixed_detail))) { fprintf(out, " %s", fixed_detail); } } wp_record_dump_print_payload(out, &rec, options); } else if (rec.type == WP_CODE_VARIABLE_LENGTH) { fprintf(out, " sub=0x%02X declared=%u copied=%u trailer=%s complete=%s", (unsigned)rec.sub_code, (unsigned)rec.declared_length, (unsigned)rec.data_length, rec.trailer_present ? (rec.trailer_matches ? "ok" : "bad") : "missing", rec.is_complete ? "yes" : "no"); { char variable_detail[256]; if (wp_variable_describe_payload(&rec, variable_detail, sizeof(variable_detail))) { fprintf(out, " %s", variable_detail); } } wp_record_dump_print_payload(out, &rec, options); } fputc('\n', out); local_stats.records_seen++; local_stats.bytes_consumed += rec.length; wp_record_free(&rec); } if (stats != NULL) { *stats = local_stats; } return true; } bool wp_record_dump_loaded_file(WpLoadedFile *file, FILE *out, const WpRecordDumpOptions *options, WpRecordDumpStats *stats) { WpLayoutGlobals wl; if (file == NULL || out == NULL) { return false; } memset(&wl, 0, sizeof(wl)); if (!wp_file_bind_primary_stream(file, &wl, 4096U)) { return false; } return wp_record_dump_stream(&wl, out, options, stats); } bool wp_record_dump_file(const char *filename, FILE *out, const WpRecordDumpOptions *options, WpRecordDumpStats *stats) { WpLoadedFile file; bool ok; if (filename == NULL || out == NULL) { return false; } if (!wp_file_load_body(filename, &file)) { return false; } ok = wp_record_dump_loaded_file(&file, out, options, stats); wp_file_free(&file); return ok; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
main
Visibility
public
Your access
Read
Remote
None
File activity
View file history