add new target of an executable to unpack binary log data
This commit is contained in:
parent
2d71b4cec2
commit
e07604dc4b
@ -33,14 +33,14 @@ target_compile_options(allcing_config INTERFACE
|
||||
# ---- library header
|
||||
add_library(allcing INTERFACE)
|
||||
target_sources(allcing INTERFACE allcing.h)
|
||||
target_link_libraries(allcing INTERFACE allcing_config)
|
||||
target_include_directories(allcing SYSTEM INTERFACE .)
|
||||
|
||||
|
||||
# ---- test binary
|
||||
if (BUILD_TESTING)
|
||||
add_executable(allcing_test)
|
||||
target_sources(allcing_test PRIVATE test.c)
|
||||
target_link_libraries(allcing_test PRIVATE allcing)
|
||||
target_link_libraries(allcing_test PRIVATE allcing allcing_config)
|
||||
add_test(NAME allcing_test COMMAND $<TARGET_FILE:allcing_test>)
|
||||
endif()
|
||||
|
||||
@ -48,4 +48,8 @@ endif()
|
||||
# ---- example binary
|
||||
add_executable(allcing_example EXCLUDE_FROM_ALL)
|
||||
target_sources(allcing_example PRIVATE example.c)
|
||||
target_link_libraries(allcing_example PRIVATE allcing)
|
||||
target_link_libraries(allcing_example PRIVATE allcing allcing_config)
|
||||
|
||||
|
||||
# ---- tool subdirs
|
||||
add_subdirectory(tool EXCLUDE_FROM_ALL)
|
||||
|
18
example.c
18
example.c
@ -6,10 +6,12 @@
|
||||
|
||||
// ----
|
||||
|
||||
#define ACG_NO_READ_FUNCTIONS
|
||||
#include "allcing.h"
|
||||
|
||||
static inline bool acg_flush(struct acg_stream* s) {
|
||||
static inline bool acg_stream_flush(struct acg_stream* s) {
|
||||
assert(NULL != s);
|
||||
acg_stream_write_chunk_pad(s);
|
||||
if (s->cursor_bits < 8U) {
|
||||
return false;
|
||||
}
|
||||
@ -21,11 +23,19 @@ static inline bool acg_flush(struct acg_stream* s) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (1U != fwrite(s->buffer, s->cursor_bits/8U, 1U, *fp)) {
|
||||
return false;
|
||||
}
|
||||
memset(s->buffer, 0U, (s->cursor_bits+7U)/8U);
|
||||
s->cursor_bits = 0;
|
||||
|
||||
uint8_t frag = 0U;
|
||||
if (s->cursor_bits%8U > 0U) {
|
||||
frag = s->buffer[s->cursor_bits/8U];
|
||||
}
|
||||
|
||||
memset(s->buffer, 0U, s->size_bytes);
|
||||
s->buffer[0] = frag;
|
||||
s->cursor_bits %= 8U;
|
||||
|
||||
if (0U != fflush(*fp)) {
|
||||
return false;
|
||||
@ -35,7 +45,7 @@ static inline bool acg_flush(struct acg_stream* s) {
|
||||
#undef ACG_LOC_FULL
|
||||
#define ACG_LOC_FULL ACG_LOC_SHORT
|
||||
#undef ACG_FLUSH
|
||||
#define ACG_FLUSH(s) acg_flush((s))
|
||||
#define ACG_FLUSH(s) acg_stream_flush((s))
|
||||
|
||||
struct acg_stream logstream = {
|
||||
.buffer = (uint8_t[1024U]) {0U},
|
||||
|
4
tool/CMakeLists.txt
Normal file
4
tool/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# ---- allcing_unpack: converts binary format to human readable text
|
||||
add_executable(allcing_unpack)
|
||||
target_sources(allcing_unpack PRIVATE unpack.c)
|
||||
target_link_libraries(allcing_unpack PRIVATE allcing allcing_config)
|
135
tool/unpack.c
Normal file
135
tool/unpack.c
Normal file
@ -0,0 +1,135 @@
|
||||
// No copyright
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <allcing.h>
|
||||
|
||||
|
||||
#define READ_CHUNK_SIZE 1024U
|
||||
|
||||
static inline bool acg_stream_refill(struct acg_stream* s) {
|
||||
assert(NULL != s);
|
||||
|
||||
FILE* fp = s->udata;
|
||||
assert(NULL != fp);
|
||||
|
||||
uint8_t* const buf = s->buffer;
|
||||
uint64_t* const c = &s->cursor_bits;
|
||||
uint64_t* const size = &s->size_bytes;
|
||||
|
||||
const uint64_t remain = *size - *c/8U;
|
||||
memmove(buf, &buf[*c/8U], remain);
|
||||
*c %= 8U;
|
||||
|
||||
const uint64_t expect_size = READ_CHUNK_SIZE - remain;
|
||||
const uint64_t actual_size = fread(&buf[remain], 1U, expect_size, fp);
|
||||
|
||||
*size = remain + actual_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc != 2U) {
|
||||
fprintf(stderr, "invalid args\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(argv[1], "rb");
|
||||
if (NULL == fp) {
|
||||
fprintf(stderr, "failed to open: %s\n", argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct acg_stream s = {
|
||||
.buffer = (uint8_t[READ_CHUNK_SIZE]) {0U},
|
||||
.udata = fp,
|
||||
};
|
||||
|
||||
uint64_t last_event_chunk_id = 0U;
|
||||
uint32_t indent = 0U;
|
||||
# define INDENT_PRINT(FMT, ...) \
|
||||
printf("%*s" FMT "\n", indent, "" __VA_OPT__(,) __VA_ARGS__)
|
||||
|
||||
while (true) {
|
||||
if (!acg_stream_refill(&s)) {
|
||||
fprintf(stderr, "failed to read: %s\n", argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (0U == s.size_bytes) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t chunk_id;
|
||||
if (!acg_stream_read_uint(&s, &chunk_id, ACG_UNITBITS_CHUNK_ID)) {
|
||||
fprintf(stderr, "failed to read chunk id\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const bool is_event_chunk = chunk_id >= ACG_CHUNK_BEGIN;
|
||||
if (is_event_chunk) {
|
||||
if (ACG_CHUNK_BEGIN == last_event_chunk_id) {
|
||||
++indent;
|
||||
} else if (ACG_CHUNK_END == last_event_chunk_id) {
|
||||
--indent;
|
||||
}
|
||||
last_event_chunk_id = chunk_id;
|
||||
}
|
||||
|
||||
switch (chunk_id) {
|
||||
case ACG_CHUNK_PAD:
|
||||
acg_stream_read_pad(&s);
|
||||
break;
|
||||
case ACG_CHUNK_BLOB: {
|
||||
uint64_t size;
|
||||
uint8_t* buf;
|
||||
if (!acg_stream_read_blob(&s, &size, &buf)) {
|
||||
fprintf(stderr, "failed to read BLOB in BLOB chunk\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INDENT_PRINT("-BLOB: %.*s", (int) size, (const char*) buf);
|
||||
} break;
|
||||
case ACG_CHUNK_CTX: {
|
||||
uint64_t time;
|
||||
if (!acg_stream_read_uint(&s, &time, 64U)) {
|
||||
fprintf(stderr, "failed to read TIME in CTX chunk\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
uint64_t tid;
|
||||
if (!acg_stream_read_uint(&s, &tid, 16U)) {
|
||||
fprintf(stderr, "failed to read TID in CTX chunk\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INDENT_PRINT("-CTX: TIME=%" PRIu64 " / TID=%" PRIx64, time, tid);
|
||||
} break;
|
||||
case ACG_CHUNK_LOC: {
|
||||
uint64_t size;
|
||||
uint8_t* buf;
|
||||
if (!acg_stream_read_blob(&s, &size, &buf)) {
|
||||
fprintf(stderr, "failed to read BLOB in BLOB chunk\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INDENT_PRINT("-LOC: %.*s", (int) size, (const char*) buf);
|
||||
} break;
|
||||
|
||||
case ACG_CHUNK_BEGIN:
|
||||
INDENT_PRINT("BEGIN:");
|
||||
break;
|
||||
case ACG_CHUNK_END:
|
||||
if (0U == indent) {
|
||||
fprintf(stderr, "too many END chunk\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
INDENT_PRINT("END:");
|
||||
break;
|
||||
case ACG_CHUNK_CHECK:
|
||||
INDENT_PRINT("CHECK:");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "unknown chunk id: %" PRIu64 "\n", chunk_id);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user