140 int rd = fread(&rec,
sizeof(rec), 1, f);
147 printf(
"HIST_RECORD:\n");
149 printf(
" Event ID: %d\n", rec.
event_id);
150 printf(
" Time: %d\n", rec.
time);
158 printf(
"Unexpected record type: 0x%08x, trying to recover by skipping bad data.\n", rec.
record_type);
180 printf(
"Maybe recovered - see what looks like valid history record header.\n");
182 ((
char*)(&rec))[0] = 0x48;
183 ((
char*)(&rec))[1] = 0x53;
184 ((
char*)(&rec))[2] = 0x44;
186 int rd = fread(((
char*)(&rec))+3,
sizeof(rec)-3, 1, f);
202 int ntags = size/
sizeof(
TAG);
205 printf(
"Event %d, \"%s\", size %d, %d tags.\n", rec.
event_id, event_name, size, ntags);
208 assert(size < 1*1024*1024);
209 assert(size == ntags*(
int)
sizeof(
TAG));
211 TAG *tags =
new TAG[ntags];
212 rd = fread(tags, 1, size, f);
222 e->printAllTags =
true;
226 if (
e->printAllTags) {
228 e->tagIndexes.clear();
236 for (
int itag=0; itag<ntags; itag++)
243 int size = tags[itag].n_data * tsize;
245 if (tags[itag].
type == 12) {
248 fprintf(stderr,
"Error: Event %d, \"%s\", has a tag \"%s\" of type TID_STRING, which is forbidden and cannot be decoded, all data after this tag will be gibberish\n", rec.
event_id, event_name, tags[itag].name);
255 assert(
offset%tsize == 0);
259 t->
name = tags[itag].name;
265 e->tags[t->
name] = t;
269 e->tagNames.push_back(t->
name);
270 e->tagIndexes.push_back(-1);
274 printf(
" Tag %d: \"%s\"[%d], type \"%s\" (%d), type size %d, offset %d+%d\n", itag, tags[itag].
name, tags[itag].n_data,
tid_name[tags[itag].
type], tags[itag].
type,
tid_size[tags[itag].
type],
offset, size);
293 printf(
"Data record, size %d.\n", size);
295 if (size <= 1 || size > 1*1024*1024)
297 fprintf(stderr,
"Error: Invalid data record: event %d, size %d is invalid\n", rec.
event_id, rec.
data_size);
301 char *buf =
new char[size];
302 int rd = fread(buf, 1, size, f);
305 time_t t = (time_t)rec.
time;
312 fprintf(stderr,
"Error: event %d, size mismatch should be %d, got %d bytes\n", rec.
event_id,
e->size, size);
317 int n =
e->tagNames.size();
322 for (
int i=0;
i<
n;
i++)
324 Tag*t =
e->tags[
e->tagNames[
i]];
332 void* ptr = (
void*)(buf+
offset);
337 printf(
" %s=", t->
name.c_str());
339 printf(
" %s[%d]=", t->
name.c_str(),
index);
350 printf(
"unknownType%d ",t->
typeCode);
353 printf(
"%u ",((uint8_t*)ptr)[
j]);
356 printf(
"%d ",((int8_t*)ptr)[
j]);
359 printf(
"\'%c\' ",((
char*)ptr)[
j]);
362 printf(
"%u ",((uint16_t*)ptr)[
j]);
365 printf(
"%d ",((int16_t*)ptr)[
j]);
368 printf(
"%u ",((uint32_t*)ptr)[
j]);
371 printf(
"%d ",((int32_t*)ptr)[
j]);
374 printf(
"%u ",((uint32_t*)ptr)[
j]);
377 printf(
"%.8g ",((
float*)ptr)[
j]);
380 printf(
"%.16g ",((
double*)ptr)[
j]);
394 printf(
" %s",
ctime(&t));
453 printf(
"event name: [%s], time [%s]\n", event_name.c_str(), time.c_str());
457 if (strncmp(s.c_str(),
"tag:", 4) != 0)
459 printf(
"tag: %s\n", s.c_str());
461 std::string s_record_size =
tagValue(
"record_size:", s);
463 size_t record_size = atoi(s_record_size.c_str());
464 size_t data_offset = atoi(s_data_offset.c_str());
466 printf(
"record size: %zu, data offset: %zu\n", record_size, data_offset);
467 int status = fseek(f, data_offset, SEEK_SET);
469 fprintf(stderr,
"%s: cannot seek to %zu, fseek() returned %d, errno %d (%s)\n", filename, data_offset,
status, errno, strerror(errno));
472 char buf[record_size];
476 size_t rd = fread(buf, 1, record_size, f);
481 }
else if (rd != record_size) {
483 fprintf(stderr,
"%s: short read at the end of file, last data record is truncated from %zu to %zu bytes\n", filename, record_size, rd);
486 const uint32_t t = *(uint32_t*)&buf[0];
487 printf(
"record %d, time %lu, incr %lu\n",
count, (
long unsigned int)t, (
long unsigned int)(t-
last_time));
490 printf(
"duplicate time %lu -> %lu\n", (
long unsigned int)
last_time, (
long unsigned int)t);
492 printf(
"non-monotonic time %lu -> %lu\n", (
long unsigned int)
last_time, (
long unsigned int)t);
496 fprintf(stderr,
"%s: read %d records\n", filename,
count);