Add timestamp snprintf. Fix bacapp snprintf to account for string size zero behavior of snprintf.

This commit is contained in:
Steve Karg
2024-04-23 10:04:46 -05:00
parent 8729c00dbd
commit e73520a974
7 changed files with 299 additions and 142 deletions
+164 -139
View File
@@ -1865,15 +1865,20 @@ int bacapp_data_len(
}
#if defined(BACAPP_DATE)
/* 135.1-4.4 Notational Rules for Parameter Values
(j)
dates are represented enclosed in parenthesis:
(Monday, 24-January-1998).
Any "wild card" or unspecified field is shown by an asterisk (X'2A'):
(Monday, *-January-1998).
The omission of day of week implies that the day is unspecified:
(24-January-1998);
*/
/**
* @brief Print a date value to a string for EPICS
* @param str - destination string, or NULL for length only
* @param str_len - length of the destination string, or 0 for length only
* @param bdate - date value to print
* @return number of characters written
* @note 135.1-4.4 Notational Rules for Parameter Values
* (j) dates are represented enclosed in parenthesis:
* (Monday, 24-January-1998).
* Any "wild card" or unspecified field is shown by an asterisk (X'2A'):
* (Monday, *-January-1998).
* The omission of day of week implies that the day is unspecified:
* (24-January-1998);
*/
static int bacapp_snprintf_date(char *str, size_t str_len, BACNET_DATE *bdate)
{
int ret_val = 0;
@@ -1888,11 +1893,11 @@ static int bacapp_snprintf_date(char *str, size_t str_len, BACNET_DATE *bdate)
slen = snprintf(str, str_len, "%s, %s", weekday_text, month_text);
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (bdate->day == 255) {
@@ -1902,11 +1907,11 @@ static int bacapp_snprintf_date(char *str, size_t str_len, BACNET_DATE *bdate)
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (bdate->year == 2155) {
@@ -1921,11 +1926,17 @@ static int bacapp_snprintf_date(char *str, size_t str_len, BACNET_DATE *bdate)
#endif
#if defined(BACAPP_TIME)
/* 135.1-4.4 Notational Rules for Parameter Values
(k)
times are represented as hours, minutes, seconds, hundredths in the format
hh:mm:ss.xx: 2:05:44.00, 16:54:59.99. Any "wild card" field is shown by an
asterisk (X'2A'): 16:54:*.*; */
/**
* @brief Print a time value to a string for EPICS
* @param str - destination string, or NULL for length only
* @param str_len - length of the destination string, or 0 for length only
* @param btime - date value to print
* @return number of characters written
* @note 135.1-4.4 Notational Rules for Parameter Values
* (k) times are represented as hours, minutes, seconds, hundredths
* in the format hh:mm:ss.xx: 2:05:44.00, 16:54:59.99.
* Any "wild card" field is shown by an asterisk (X'2A'): 16:54:*.*;
*/
static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
{
int ret_val = 0;
@@ -1940,11 +1951,11 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (btime->min == 255) {
@@ -1954,11 +1965,11 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (btime->sec == 255) {
@@ -1968,11 +1979,11 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (btime->hundredths == 255) {
@@ -1987,6 +1998,14 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
#endif
#if defined(BACAPP_WEEKLY_SCHEDULE)
/**
* @brief Print a weekly schedule value to a string for EPICS
* @param str - destination string, or NULL for length only
* @param str_len - length of the destination string, or 0 for length only
* @param ws - weekly schedule value to print
* @param arrayIndex - index of the weekly schedule to print
* @return number of characters written
*/
static int bacapp_snprintf_weeklyschedule(char *str,
size_t str_len,
BACNET_WEEKLY_SCHEDULE *ws,
@@ -2027,11 +2046,11 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
for (wi = 0; wi < loopend; wi++) {
@@ -2047,11 +2066,11 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
for (ti = 0; ti < ds->TV_Count; ti++) {
@@ -2071,13 +2090,12 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
bacnet_primitive_to_application_data_value(
&dummyDataValue, &ds->Time_Values[ti].Value);
dummyPropValue.value = &dummyDataValue;
@@ -2088,11 +2106,11 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
if (ti < ds->TV_Count - 1) {
@@ -2100,11 +2118,11 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
}
@@ -2114,11 +2132,11 @@ static int bacapp_snprintf_weeklyschedule(char *str,
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
}
@@ -2131,7 +2149,7 @@ static int bacapp_snprintf_weeklyschedule(char *str,
/**
* @brief Extract the value into a text string
* @param str - the buffer to store the extracted value, or NULL for length
* @param str_len - the size of the buffer
* @param str_len - the size of the buffer, or 0 for length only
* @param object_value - ptr to BACnet object value from which to extract str
* @return number of bytes (excluding terminating NULL byte) that were stored
* to the output string.
@@ -2204,11 +2222,11 @@ int bacapp_snprintf_value(
octet_str++;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
}
@@ -2222,11 +2240,11 @@ int bacapp_snprintf_value(
slen = snprintf(str, str_len, "\"");
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
@@ -2250,11 +2268,11 @@ int bacapp_snprintf_value(
slen = snprintf(str, str_len, "%lc", (wint_t)wc);
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (len > wclen) {
@@ -2275,11 +2293,11 @@ int bacapp_snprintf_value(
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
char_str++;
@@ -2295,11 +2313,11 @@ int bacapp_snprintf_value(
slen = snprintf(str, str_len, "{");
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
for (i = 0; i < len; i++) {
@@ -2308,22 +2326,22 @@ int bacapp_snprintf_value(
slen = snprintf(str, str_len, "%s", bit ? "true" : "false");
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (i < (len - 1)) {
slen = snprintf(str, str_len, ",");
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
}
@@ -2448,11 +2466,11 @@ int bacapp_snprintf_value(
slen = snprintf(str, str_len, "(");
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
if (value->type.Object_Id.type <= BACNET_OBJECT_TYPE_LAST) {
@@ -2468,11 +2486,11 @@ int bacapp_snprintf_value(
}
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
ret_val += slen;
slen = snprintf(str, str_len, "%lu)",
@@ -2487,16 +2505,22 @@ int bacapp_snprintf_value(
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
slen = snprintf(str, str_len, "..");
ret_val += slen;
if (str) {
str += slen;
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
slen = bacapp_snprintf_date(
str, str_len, &value->type.Date_Range.enddate);
ret_val += slen;
@@ -2504,17 +2528,8 @@ int bacapp_snprintf_value(
#endif
#if defined(BACAPP_TIMESTAMP)
case BACNET_APPLICATION_TAG_TIMESTAMP:
/*ISO 8601 format */
slen = snprintf(str, str_len,
"%04u-%02u-%02uT%02u:%02u:%02u.%03u",
(unsigned)value->type.Time_Stamp.value.dateTime.date.year,
(unsigned)value->type.Time_Stamp.value.dateTime.date.month,
(unsigned)value->type.Time_Stamp.value.dateTime.date.day,
(unsigned)value->type.Time_Stamp.value.dateTime.time.hour,
(unsigned)value->type.Time_Stamp.value.dateTime.time.min,
(unsigned)value->type.Time_Stamp.value.dateTime.time.sec,
(unsigned)
value->type.Time_Stamp.value.dateTime.time.hundredths);
slen = bacapp_timestamp_to_ascii(str, str_len,
&value->type.Time_Stamp);
ret_val += slen;
break;
#endif
@@ -2525,11 +2540,21 @@ int bacapp_snprintf_value(
ret_val += slen;
if (str) {
str += slen;
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
slen = snprintf(str, str_len, "-");
ret_val += slen;
if (str) {
str += slen;
}
if (str_len >= slen) {
str_len -= slen;
} else {
str_len = 0;
}
slen = bacapp_snprintf_time(
str, str_len, &value->type.Date_Time.time);