Get rid of some places that handled specific timestamp resolutions.
Replace them with tables supporting everything from seconds to nanoseconds, or with code that calculates 10^{resolution}.
This commit is contained in:
parent
e1c5a055f9
commit
151b85c45e
|
@ -972,8 +972,15 @@ get_frame_timestamp_precision(const frame_data *fd)
|
|||
tsprecision = fd->tsprec;
|
||||
else if (tsprecision < 0)
|
||||
ws_assert_not_reached();
|
||||
if (tsprecision > 9)
|
||||
tsprecision = 9;
|
||||
|
||||
/*
|
||||
* Time stamp precision values higher than the maximum
|
||||
* precision we support can't be handled. Just display
|
||||
* those times with the maximum precision we support.
|
||||
*/
|
||||
if (tsprecision > WS_TSPREC_MAX)
|
||||
tsprecision = WS_TSPREC_MAX;
|
||||
|
||||
return tsprecision;
|
||||
}
|
||||
|
||||
|
@ -984,11 +991,18 @@ get_default_timestamp_precision(void)
|
|||
|
||||
tsprecision = timestamp_get_precision();
|
||||
if (tsprecision == TS_PREC_AUTO)
|
||||
tsprecision = 9;
|
||||
tsprecision = WS_TSPREC_MAX; /* default to the maximum precision we support */
|
||||
else if (tsprecision < 0)
|
||||
ws_assert_not_reached();
|
||||
if (tsprecision > 9)
|
||||
tsprecision = 9;
|
||||
|
||||
/*
|
||||
* Time stamp precision values higher than the maximum
|
||||
* precision we support can't be handled. Just display
|
||||
* those times with the maximum precision we support.
|
||||
*/
|
||||
if (tsprecision > WS_TSPREC_MAX)
|
||||
tsprecision = WS_TSPREC_MAX;
|
||||
|
||||
return tsprecision;
|
||||
}
|
||||
|
||||
|
|
261
epan/column.c
261
epan/column.c
|
@ -434,6 +434,97 @@ get_column_format_matches(gboolean *fmt_list, const gint format) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* These tables are indexed by the number of digits of precision for
|
||||
* time stamps; all TS_PREC_FIXED_ types have values equal to the
|
||||
* number of digits of precision, and NUM_WS_TSPREC_VALS is the
|
||||
* total number of such values as there's a one-to-one correspondence
|
||||
* between WS_TSPREC_ values and TS_PREC_FIXED_ values.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Strings for YYYY-MM-DD HH:MM:SS.SSSS dates and times.
|
||||
* (Yes, we know, this has a Y10K problem.)
|
||||
*/
|
||||
static const char *ts_ymd[NUM_WS_TSPREC_VALS] = {
|
||||
"0000-00-00 00:00:00",
|
||||
"0000-00-00 00:00:00.0",
|
||||
"0000-00-00 00:00:00.00",
|
||||
"0000-00-00 00:00:00.000",
|
||||
"0000-00-00 00:00:00.0000",
|
||||
"0000-00-00 00:00:00.00000",
|
||||
"0000-00-00 00:00:00.000000",
|
||||
"0000-00-00 00:00:00.0000000",
|
||||
"0000-00-00 00:00:00.00000000",
|
||||
"0000-00-00 00:00:00.000000000",
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings for YYYY/DOY HH:MM:SS.SSSS dates and times.
|
||||
* (Yes, we know, this also has a Y10K problem.)
|
||||
*/
|
||||
static const char *ts_ydoy[NUM_WS_TSPREC_VALS] = {
|
||||
"0000/000 00:00:00",
|
||||
"0000/000 00:00:00.0",
|
||||
"0000/000 00:00:00.00",
|
||||
"0000/000 00:00:00.000",
|
||||
"0000/000 00:00:00.0000",
|
||||
"0000/000 00:00:00.00000",
|
||||
"0000/000 00:00:00.000000",
|
||||
"0000/000 00:00:00.0000000",
|
||||
"0000/000 00:00:00.00000000",
|
||||
"0000/000 00:00:00.000000000",
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings for HH:MM:SS.SSSS absolute times without dates.
|
||||
*/
|
||||
static const char *ts_abstime[NUM_WS_TSPREC_VALS] = {
|
||||
"00:00:00",
|
||||
"00:00:00.0",
|
||||
"00:00:00.00",
|
||||
"00:00:00.000",
|
||||
"00:00:00.0000",
|
||||
"00:00:00.00000",
|
||||
"00:00:00.000000",
|
||||
"00:00:00.0000000",
|
||||
"00:00:00.00000000",
|
||||
"00:00:00.000000000",
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings for SSSS.S relative and delta times.
|
||||
* (Yes, this has s 10,000-seconds problem.)
|
||||
*/
|
||||
static const char *ts_rel_delta_time[NUM_WS_TSPREC_VALS] = {
|
||||
"0000",
|
||||
"0000.0",
|
||||
"0000.00",
|
||||
"0000.000",
|
||||
"0000.0000",
|
||||
"0000.00000",
|
||||
"0000.000000",
|
||||
"0000.0000000",
|
||||
"0000.00000000",
|
||||
"0000.000000000",
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings for UN*X/POSIX Epoch times.
|
||||
*/
|
||||
static const char *ts_epoch_time[NUM_WS_TSPREC_VALS] = {
|
||||
"0000000000000000000",
|
||||
"0000000000000000000.0",
|
||||
"0000000000000000000.00",
|
||||
"0000000000000000000.000",
|
||||
"0000000000000000000.0000",
|
||||
"0000000000000000000.00000",
|
||||
"0000000000000000000.000000",
|
||||
"0000000000000000000.0000000",
|
||||
"0000000000000000000.00000000",
|
||||
"0000000000000000000.000000000",
|
||||
};
|
||||
|
||||
/* Returns a string representing the longest possible value for
|
||||
a timestamp column type. */
|
||||
static const char *
|
||||
|
@ -443,136 +534,72 @@ get_timestamp_column_longest_string(const gint type, const gint precision)
|
|||
switch(type) {
|
||||
case(TS_ABSOLUTE_WITH_YMD):
|
||||
case(TS_UTC_WITH_YMD):
|
||||
switch(precision) {
|
||||
case(TS_PREC_FIXED_SEC):
|
||||
return "0000-00-00 00:00:00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_DSEC):
|
||||
return "0000-00-00 00:00:00.0";
|
||||
break;
|
||||
case(TS_PREC_FIXED_CSEC):
|
||||
return "0000-00-00 00:00:00.00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_MSEC):
|
||||
return "0000-00-00 00:00:00.000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_USEC):
|
||||
return "0000-00-00 00:00:00.000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_NSEC):
|
||||
case(TS_PREC_AUTO): /* Leave enough room for the maximum */
|
||||
return "0000-00-00 00:00:00.000000000";
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
if(precision == TS_PREC_AUTO) {
|
||||
/*
|
||||
* Return the string for the maximum precision, so that
|
||||
* our caller leaves room for that string.
|
||||
*/
|
||||
return ts_ymd[WS_TSPREC_MAX];
|
||||
} else if(precision >= 0 && precision < NUM_WS_TSPREC_VALS)
|
||||
return ts_ymd[precision];
|
||||
else
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case(TS_ABSOLUTE_WITH_YDOY):
|
||||
case(TS_UTC_WITH_YDOY):
|
||||
switch(precision) {
|
||||
case(TS_PREC_FIXED_SEC):
|
||||
return "0000/000 00:00:00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_DSEC):
|
||||
return "0000/000 00:00:00.0";
|
||||
break;
|
||||
case(TS_PREC_FIXED_CSEC):
|
||||
return "0000/000 00:00:00.00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_MSEC):
|
||||
return "0000/000 00:00:00.000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_USEC):
|
||||
return "0000/000 00:00:00.000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_NSEC):
|
||||
case(TS_PREC_AUTO): /* Leave enough room for the maximum */
|
||||
return "0000/000 00:00:00.000000000";
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
if(precision == TS_PREC_AUTO) {
|
||||
/*
|
||||
* Return the string for the maximum precision, so that
|
||||
* our caller leaves room for that string.
|
||||
*/
|
||||
return ts_ydoy[WS_TSPREC_MAX];
|
||||
} else if(precision >= 0 && precision < NUM_WS_TSPREC_VALS)
|
||||
return ts_ydoy[precision];
|
||||
else
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case(TS_ABSOLUTE):
|
||||
case(TS_UTC):
|
||||
switch(precision) {
|
||||
case(TS_PREC_FIXED_SEC):
|
||||
return "00:00:00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_DSEC):
|
||||
return "00:00:00.0";
|
||||
break;
|
||||
case(TS_PREC_FIXED_CSEC):
|
||||
return "00:00:00.00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_MSEC):
|
||||
return "00:00:00.000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_USEC):
|
||||
return "00:00:00.000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_NSEC):
|
||||
case(TS_PREC_AUTO): /* Leave enough room for the maximum */
|
||||
return "00:00:00.000000000";
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
if(precision == TS_PREC_AUTO) {
|
||||
/*
|
||||
* Return the string for the maximum precision, so that
|
||||
* our caller leaves room for that string.
|
||||
*/
|
||||
return ts_abstime[WS_TSPREC_MAX];
|
||||
} else if(precision >= 0 && precision < NUM_WS_TSPREC_VALS)
|
||||
return ts_abstime[precision];
|
||||
else
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case(TS_RELATIVE): /* fallthrough */
|
||||
case(TS_DELTA):
|
||||
case(TS_DELTA_DIS):
|
||||
switch(precision) {
|
||||
case(TS_PREC_FIXED_SEC):
|
||||
return "0000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_DSEC):
|
||||
return "0000.0";
|
||||
break;
|
||||
case(TS_PREC_FIXED_CSEC):
|
||||
return "0000.00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_MSEC):
|
||||
return "0000.000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_USEC):
|
||||
return "0000.000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_NSEC):
|
||||
case(TS_PREC_AUTO): /* Leave enough room for the maximum */
|
||||
return "0000.000000000";
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
if(precision == TS_PREC_AUTO) {
|
||||
/*
|
||||
* Return the string for the maximum precision, so that
|
||||
* our caller leaves room for that string.
|
||||
*/
|
||||
return ts_rel_delta_time[WS_TSPREC_MAX];
|
||||
} else if(precision >= 0 && precision < NUM_WS_TSPREC_VALS)
|
||||
return ts_rel_delta_time[precision];
|
||||
else
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case(TS_EPOCH):
|
||||
/* This is enough to represent 2^63 (signed 64-bit integer) + fractions */
|
||||
switch(precision) {
|
||||
case(TS_PREC_FIXED_SEC):
|
||||
return "0000000000000000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_DSEC):
|
||||
return "0000000000000000000.0";
|
||||
break;
|
||||
case(TS_PREC_FIXED_CSEC):
|
||||
return "0000000000000000000.00";
|
||||
break;
|
||||
case(TS_PREC_FIXED_MSEC):
|
||||
return "0000000000000000000.000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_USEC):
|
||||
return "0000000000000000000.000000";
|
||||
break;
|
||||
case(TS_PREC_FIXED_NSEC):
|
||||
case(TS_PREC_AUTO): /* Leave enough room for the maximum */
|
||||
return "0000000000000000000.000000000";
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
if(precision == TS_PREC_AUTO) {
|
||||
/*
|
||||
* Return the string for the maximum precision, so that
|
||||
* our caller leaves room for that string.
|
||||
*/
|
||||
return ts_epoch_time[WS_TSPREC_MAX];
|
||||
} else if(precision >= 0 && precision < NUM_WS_TSPREC_VALS)
|
||||
return ts_epoch_time[precision];
|
||||
else
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case(TS_NOT_SET):
|
||||
/* This should not happen. */
|
||||
return "0000.000000";
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1820,46 +1820,34 @@ text_import_pre_open(wtap_dump_params * const params, int file_type_subtype, con
|
|||
} else {
|
||||
wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF, text2pcap", strlen("Fake IF, text2pcap"));
|
||||
}
|
||||
switch (params->tsprec) {
|
||||
if (params->tsprec >= 0 && params->tsprec <= WS_TSPREC_MAX) {
|
||||
/*
|
||||
* This is a valid time precision.
|
||||
*/
|
||||
|
||||
case WTAP_TSPREC_SEC:
|
||||
int_data_mand->time_units_per_second = 1;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 0);
|
||||
break;
|
||||
/*
|
||||
* Compute 10^{params->tsprec}.
|
||||
*/
|
||||
int_data_mand->time_units_per_second = 1;
|
||||
for (int i = 0; i < params->tsprec; i++)
|
||||
int_data_mand->time_units_per_second *= 10;
|
||||
|
||||
case WTAP_TSPREC_DSEC:
|
||||
int_data_mand->time_units_per_second = 10;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 1);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_CSEC:
|
||||
int_data_mand->time_units_per_second = 100;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 2);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_MSEC:
|
||||
int_data_mand->time_units_per_second = 1000;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 3);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_USEC:
|
||||
int_data_mand->time_units_per_second = 1000000;
|
||||
/* This is the default, so no need to add an option */
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_NSEC:
|
||||
int_data_mand->time_units_per_second = 1000000000;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 9);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_PER_PACKET:
|
||||
case WTAP_TSPREC_UNKNOWN:
|
||||
default:
|
||||
if (params->tsprec != WTAP_TSPREC_USEC) {
|
||||
/*
|
||||
* Don't do this.
|
||||
* Microsecond precision is the default, so we only
|
||||
* add an option if the precision isn't microsecond
|
||||
* precision.
|
||||
*/
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, params->tsprec);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Either WTAP_TSPREC_PER_PACKET, WTAP_TSPREC_UNKNOWN,
|
||||
* or not a valid precision.
|
||||
*
|
||||
* Don't do this.
|
||||
*/
|
||||
ws_assert_not_reached();
|
||||
}
|
||||
|
||||
params->idb_inf = g_new(wtapng_iface_descriptions_t,1);
|
||||
|
|
112
wiretap/wtap.c
112
wiretap/wtap.c
|
@ -241,46 +241,31 @@ wtap_generate_idb(int encap, int tsprec, int snaplen)
|
|||
if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(idb);
|
||||
if_descr_mand->wtap_encap = encap;
|
||||
if_descr_mand->tsprecision = tsprec;
|
||||
switch (tsprec) {
|
||||
|
||||
case WTAP_TSPREC_SEC:
|
||||
if_descr_mand->time_units_per_second = 1;
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, 0);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_DSEC:
|
||||
if_descr_mand->time_units_per_second = 10;
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, 1);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_CSEC:
|
||||
if_descr_mand->time_units_per_second = 100;
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, 2);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_MSEC:
|
||||
if_descr_mand->time_units_per_second = 1000;
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, 3);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_USEC:
|
||||
if_descr_mand->time_units_per_second = 1000000;
|
||||
/* This is the default, so no need to add an option */
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_NSEC:
|
||||
if_descr_mand->time_units_per_second = 1000000000;
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, 9);
|
||||
break;
|
||||
|
||||
case WTAP_TSPREC_PER_PACKET:
|
||||
case WTAP_TSPREC_UNKNOWN:
|
||||
default:
|
||||
if (tsprec < 0 || tsprec > WS_TSPREC_MAX) {
|
||||
/*
|
||||
* No timestamp precision.
|
||||
* Either WTAP_TSPREC_PER_PACKET, WTAP_TSPREC_UNKNOWN,
|
||||
* or not a valid WTAP_TSPREC_ value.
|
||||
*
|
||||
* Unknown timestamp precision; use the default of
|
||||
* microsecond resolution.
|
||||
*/
|
||||
if_descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
|
||||
break;
|
||||
tsprec = 6; /* microsecond resolution */
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute 10^{params->tsprec}.
|
||||
*/
|
||||
if_descr_mand->time_units_per_second = 1;
|
||||
for (int i = 0; i < tsprec; i++)
|
||||
if_descr_mand->time_units_per_second *= 10;
|
||||
|
||||
if (tsprec != WTAP_TSPREC_USEC) {
|
||||
/*
|
||||
* Microsecond precision is the default, so we only
|
||||
* add an option if the precision isn't microsecond
|
||||
* precision.
|
||||
*/
|
||||
wtap_block_add_uint8_option(idb, OPT_IDB_TSRESOL, tsprec);
|
||||
}
|
||||
if (snaplen == 0) {
|
||||
/*
|
||||
|
@ -1330,37 +1315,34 @@ wtap_name_to_encap(const char *name)
|
|||
return -1; /* no such encapsulation type */
|
||||
}
|
||||
|
||||
/*
|
||||
* For precision values that correspond to a specific precision.
|
||||
*/
|
||||
static const char *precnames[NUM_WS_TSPREC_VALS] = {
|
||||
"seconds",
|
||||
"100 millisconds (deciseconds)",
|
||||
"10 milliseconds (centiseconds)",
|
||||
"milliseconds",
|
||||
"100 microseconds",
|
||||
"10 microseconds",
|
||||
"microseconds",
|
||||
"100 nanoseconds",
|
||||
"10 nanoseconds",
|
||||
"nanoseconds",
|
||||
};
|
||||
|
||||
const char*
|
||||
wtap_tsprec_string(int tsprec)
|
||||
{
|
||||
const char* s;
|
||||
switch (tsprec) {
|
||||
case WTAP_TSPREC_PER_PACKET:
|
||||
s = "per-packet";
|
||||
break;
|
||||
case WTAP_TSPREC_SEC:
|
||||
s = "seconds";
|
||||
break;
|
||||
case WTAP_TSPREC_DSEC:
|
||||
s = "deciseconds";
|
||||
break;
|
||||
case WTAP_TSPREC_CSEC:
|
||||
s = "centiseconds";
|
||||
break;
|
||||
case WTAP_TSPREC_MSEC:
|
||||
s = "milliseconds";
|
||||
break;
|
||||
case WTAP_TSPREC_USEC:
|
||||
s = "microseconds";
|
||||
break;
|
||||
case WTAP_TSPREC_NSEC:
|
||||
s = "nanoseconds";
|
||||
break;
|
||||
case WTAP_TSPREC_UNKNOWN:
|
||||
default:
|
||||
s = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
if (tsprec == WTAP_TSPREC_PER_PACKET)
|
||||
s = "per-packet";
|
||||
else if (tsprec >= 0 && tsprec < NUM_WS_TSPREC_VALS)
|
||||
s = precnames[tsprec];
|
||||
else if (tsprec == WTAP_TSPREC_UNKNOWN)
|
||||
s = "UNKNOWN";
|
||||
else
|
||||
s = "INVALID";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,19 @@ typedef enum {
|
|||
WS_TSPREC_NSEC = 9
|
||||
} ws_tsprec_e;
|
||||
|
||||
/*
|
||||
* Maximum time stamp precision supported.
|
||||
* Note that going beyond nanosecond precision would require expanding
|
||||
* the fractional part of an nstime_t to 64 bits, and changing code
|
||||
* that currently only handles second to nanosecond precision.
|
||||
*/
|
||||
#define WS_TSPREC_MAX 9
|
||||
|
||||
/*
|
||||
* Total number of valid precision values.
|
||||
*/
|
||||
#define NUM_WS_TSPREC_VALS (WS_TSPREC_MAX + 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
Loading…
Reference in New Issue