nmeasim::core::log¶
namespace nmeasim::core::log · Library API
Recorded sentence logs, part of the Qt-free nmeasim::core library: the format the simulator writes when recording and the third-party variants it reads back for replay.
A log is a text file with one sentence per line. The recorder (nmeasim::io::LogTransport) writes kHeaderLine, # key: value header lines made by format_header_line, and one ISO-8601-UTC-time sentence line per sentence made by format_log_line. parse_log and load_log read that format and also plain NMEA logs, Unix-time prefixes and IEC 61162-450 TAG block times, mixed freely, for simulation::ReplaySource. The format is described in docs/reference/log-format.md and chosen in ADR 0012.
Types¶
| Type | Description |
|---|---|
LogEntry |
One sentence of a log, with the time at which a replay sends it. |
Log |
A parsed log: its sentences in file order with their offsets, and the header metadata. |
LogParseOptions |
Options for parse_log and load_log. |
Summary¶
Enumerations
| Name | Description |
|---|---|
TimingSource |
How the entry offsets of a log were derived, in parse_log's order of preference. |
Functions
| Name | Description |
|---|---|
to_string() |
Returns the lower-case display name of a timing source, such as sentence times. |
parse_log() |
Parses the text of a log into its sentences and their replay offsets. |
load_log() |
Reads a log file from disk and parses it with parse_log. |
format_log_line() |
Formats one log line as the recorder writes it, without line terminator. |
format_header_line() |
Formats a # key: value header line, without line terminator. |
Variables
| Name | Description |
|---|---|
kHeaderLine |
First line written by the recorder; the trailing number is the format version. |
Enumerations¶
TimingSource¶
enum class TimingSource
How the entry offsets of a log were derived, in parse_log's order of preference.
| Enumerator | Value | Description |
|---|---|---|
Timestamps |
At least one line carried an absolute time (prefix or TAG block); offsets come from those times. Display name timestamps. |
|
SentenceTimes |
No line carried an absolute time, but at least one sentence carried a UTC time field; offsets come from those fields. Display name sentence times. |
|
FixedInterval |
The log had no time information; entries are spaced by LogParseOptions::fixed_interval. Display name fixed interval. |
Declared in src/core/include/nmeasim/core/log/log_file.hpp:56
Functions¶
to_string()¶
const char* to_string(TimingSource source) noexcept
Returns the lower-case display name of a timing source, such as sentence times.
Parameters
| Name | Type | Description |
|---|---|---|
source |
TimingSource |
The timing source to name. |
Returns const char*: A static string, valid for the lifetime of the program: timestamps, sentence times or fixed interval, and unknown for a value outside the enumeration.
Declared in src/core/include/nmeasim/core/log/log_file.hpp:74 · defined in src/core/src/log/log_file.cpp:174
parse_log()¶
std::optional<Log> parse_log(
std::string_view text,
const LogParseOptions& options,
std::string* error)
Parses the text of a log into its sentences and their replay offsets.
The text is split into lines at line feeds and each line is trimmed, so <CR><LF> and <LF> endings both work. Each line is then handled on its own:
- a blank line is ignored;
- a line starting with
#is a comment.# key: value, with a non-empty key without spaces, becomes aLog::headerentry, andkHeaderLinesetsformat; other comments are ignored. Comments are not counted as skipped; - a line starting with
\\endiskiphas an IEC 61162-450 TAG block up to the next\\endiskip; its firstc:parameter, a positive Unix time in seconds (with optional fraction) or in milliseconds, gives the line's time. A*hhchecksum at the end of the block must match, as for a sentence, and a block without one is accepted. A line whose block is not closed or has a checksum that does not match is skipped and counted inLog::skipped_lines; - the sentence starts at the first
$or!and must passnmea0183::parse_sentence: a checksum, when present, must match, and a sentence without one is accepted. A line without$or!, or with a rejected sentence, is skipped and counted inLog::skipped_lines; - when the TAG block gave no time, the text before the sentence is read as a time: an ISO 8601 time (
Tor space separator, optional fraction and offset, UTC when there is none) or a Unix time in seconds or milliseconds (a number above 1e11 is taken as milliseconds), optionally followed by,,;,:, tabs or spaces, either as the whole prefix or as its last whitespace-separated word. Any other prefix, such as[10:00:00], is ignored and the line has no time.
The offsets are then derived in this order of preference, recorded in Log::timing:
TimingSource::Timestamps, when any line has an absolute time. The first time in the file is the origin; each timed entry is at its time minus the origin, and an untimed entry shares the previous entry's offset (zero before the first timed line). An offset is never lower than the previous one, so a clock stepping back holds the replay instead of reversing it.TimingSource::SentenceTimes, when any sentence carries a valid UTC time of day (RMC, GGA, GLL, ZDA, GNS, GST, GBS, GRS; seenmea0183::sentence_time). Each such sentence advances the offset by its time minus the latest sentence time seen so far; a step back of more than 12 hours is taken as crossing midnight and gets 24 hours added. Any other step back leaves the offset unchanged and does not lower the latest time, so the replay holds until the times have caught up and no time is counted twice. Dates are ignored. Sentences without a time share the offset of the previous entry.TimingSource::FixedIntervalotherwise: entryiis atitimesoptions.fixed_interval.
Parameters
| Name | Type | Description |
|---|---|---|
text |
std::string_view |
The complete log text. |
options |
const LogParseOptions& |
Parsing options; only the fixed interval, which must not be negative. |
error |
std::string* |
Receives the reason when the log is rejected; left unchanged on success. May be null. It is The fixed interval must not be negative for a negative options.fixed_interval, The log is empty when no line was counted as skipped (the text holds only blank and comment lines, or nothing), and No valid NMEA sentence found in the log when lines were skipped. |
Returns std::optional<Log>: The log, with at least one entry, or std::nullopt when no sentence could be read or the options are invalid. Malformed lines never reject the log on their own.
See also
- IEC 61162-450, TAG block parameter "c" and checksum.
- docs/reference/log-format.md
Declared in src/core/include/nmeasim/core/log/log_file.hpp:163 · defined in src/core/src/log/log_file.cpp:191
load_log()¶
std::optional<Log> load_log(
const std::string& path,
const LogParseOptions& options,
std::string* error)
Reads a log file from disk and parses it with parse_log.
The whole file is read into memory first (ADR 0012 puts multi-gigabyte logs out of scope).
Parameters
| Name | Type | Description |
|---|---|---|
path |
const std::string& |
Path of the file, in the encoding std::ifstream expects. |
options |
const LogParseOptions& |
Parsing options passed on to parse_log. |
error |
std::string* |
Receives the reason on failure; left unchanged on success. May be null. It is Cannot read PATH when the file cannot be opened, and PATH: REASON with the reason from parse_log when no sentence could be read. |
Returns std::optional<Log>: The log, or std::nullopt on failure.
Declared in src/core/include/nmeasim/core/log/log_file.hpp:177 · defined in src/core/src/log/log_file.cpp:320
format_log_line()¶
std::string format_log_line(
std::chrono::system_clock::time_point recorded_at,
std::string_view sentence)
Formats one log line as the recorder writes it, without line terminator.
Parameters
| Name | Type | Description |
|---|---|---|
recorded_at |
std::chrono::system_clock::time_point |
The UTC wall-clock time at which the sentence was written; it is written with millisecond resolution as YYYY-MM-DDThh:mm:ss.mmmZ. |
sentence |
std::string_view |
The sentence as sent, without line terminator; copied unchanged. |
Returns std::string: The time, one space and the sentence, a line that parse_log reads back with recorded_at as its time.
Declared in src/core/include/nmeasim/core/log/log_file.hpp:187 · defined in src/core/src/log/log_file.cpp:340
format_header_line()¶
std::string format_header_line(std::string_view key, std::string_view value)
Formats a # key: value header line, without line terminator.
Parameters
| Name | Type | Description |
|---|---|---|
key |
std::string_view |
The metadata key, such as profile. |
value |
std::string_view |
The metadata value. |
Returns std::string: #, the key, : and the value. parse_log reads the pair back into Log::header when key is non-empty and contains no space or :; it trims whitespace from both ends of value.
Declared in src/core/include/nmeasim/core/log/log_file.hpp:197 · defined in src/core/src/log/log_file.cpp:348
Variables¶
kHeaderLine¶
std::string_view kHeaderLine{"# NMEA Simulator X log 1"}
First line written by the recorder; the trailing number is the format version.
parse_log stores the text after NMEA Simulator X log as the format header entry.
Declared in src/core/include/nmeasim/core/log/log_file.hpp:39