Refactor/snprintf next common shift function (#656)
This commit is contained in:
+54
-267
@@ -1864,6 +1864,31 @@ int bacapp_data_len(
|
||||
return total_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shift the buffer pointer and decrease the size after an snprintf
|
||||
* @param len - number of bytes (excluding terminating NULL byte) from snprintf
|
||||
* @param buf - pointer to the buffer pointer
|
||||
* @param buf_size - pointer to the buffer size
|
||||
* @return number of bytes (excluding terminating NULL byte) from snprintf
|
||||
*/
|
||||
int bacapp_snprintf_shift(int len, char **buf, size_t *buf_size)
|
||||
{
|
||||
if (buf) {
|
||||
if (*buf) {
|
||||
*buf += len;
|
||||
}
|
||||
}
|
||||
if (buf_size) {
|
||||
if ((*buf_size) >= len) {
|
||||
*buf_size -= len;
|
||||
} else {
|
||||
*buf_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if defined(BACAPP_DATE)
|
||||
/**
|
||||
* @brief Print a date value to a string for EPICS
|
||||
@@ -1891,29 +1916,13 @@ static int bacapp_snprintf_date(char *str, size_t str_len, BACNET_DATE *bdate)
|
||||
/* cppcheck-suppress nullPointer */
|
||||
/* cppcheck-suppress ctunullpointer */
|
||||
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;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (bdate->day == 255) {
|
||||
slen = snprintf(str, str_len, " (unspecified), ");
|
||||
} else {
|
||||
slen = snprintf(str, str_len, " %u, ", (unsigned)bdate->day);
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (bdate->year == 2155) {
|
||||
slen = snprintf(str, str_len, "(unspecified)");
|
||||
} else {
|
||||
@@ -1949,43 +1958,19 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime)
|
||||
/* cppcheck-suppress nullPointer */
|
||||
slen = snprintf(str, str_len, "%02u:", (unsigned)btime->hour);
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (btime->min == 255) {
|
||||
slen = snprintf(str, str_len, "**:");
|
||||
} else {
|
||||
slen = snprintf(str, str_len, "%02u:", (unsigned)btime->min);
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (btime->sec == 255) {
|
||||
slen = snprintf(str, str_len, "**.");
|
||||
} else {
|
||||
slen = snprintf(str, str_len, "%02u.", (unsigned)btime->sec);
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (btime->hundredths == 255) {
|
||||
slen = snprintf(str, str_len, "**");
|
||||
} else {
|
||||
@@ -2043,16 +2028,7 @@ static int bacapp_snprintf_weeklyschedule(char *str,
|
||||
slen = snprintf(
|
||||
str, str_len, "(%s; ", bactext_application_tag_name(inner_tag));
|
||||
}
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
for (wi = 0; wi < loopend; wi++) {
|
||||
BACNET_DAILY_SCHEDULE *ds = &ws->weeklySchedule[wi];
|
||||
if (arrayIndex == BACNET_ARRAY_ALL) {
|
||||
@@ -2063,81 +2039,28 @@ static int bacapp_snprintf_weeklyschedule(char *str,
|
||||
? weekdaynames[arrayIndex - 1]
|
||||
: "???");
|
||||
}
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
for (ti = 0; ti < ds->TV_Count; ti++) {
|
||||
slen =
|
||||
bacapp_snprintf_time(str, str_len, &ds->Time_Values[ti].Time);
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = snprintf(str, str_len, " ");
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
bacnet_primitive_to_application_data_value(
|
||||
&dummyDataValue, &ds->Time_Values[ti].Value);
|
||||
dummyPropValue.value = &dummyDataValue;
|
||||
dummyPropValue.object_property = PROP_PRESENT_VALUE;
|
||||
dummyPropValue.object_type = OBJECT_SCHEDULE;
|
||||
|
||||
slen = bacapp_snprintf_value(str, str_len, &dummyPropValue);
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (ti < ds->TV_Count - 1) {
|
||||
slen = snprintf(str, str_len, ", ");
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (wi < loopend - 1) {
|
||||
slen = snprintf(str, str_len, "]; ");
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
}
|
||||
}
|
||||
slen = snprintf(str, str_len, "])");
|
||||
@@ -2219,16 +2142,8 @@ int bacapp_snprintf_value(
|
||||
octet_str = octetstring_value(&value->type.Octet_String);
|
||||
for (i = 0; i < len; i++) {
|
||||
slen = snprintf(str, str_len, "%02X", *octet_str);
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
octet_str++;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2238,15 +2153,7 @@ int bacapp_snprintf_value(
|
||||
len = characterstring_length(&value->type.Character_String);
|
||||
char_str = characterstring_value(&value->type.Character_String);
|
||||
slen = snprintf(str, str_len, "\"");
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
if (characterstring_encoding(&value->type.Character_String) ==
|
||||
CHARACTER_UTF8) {
|
||||
@@ -2266,15 +2173,7 @@ int bacapp_snprintf_value(
|
||||
}
|
||||
/* For portability, cast wchar_t to wint_t */
|
||||
slen = snprintf(str, str_len, "%lc", (wint_t)wc);
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (len > wclen) {
|
||||
len -= wclen;
|
||||
char_str += wclen;
|
||||
@@ -2291,15 +2190,7 @@ int bacapp_snprintf_value(
|
||||
} else {
|
||||
slen = snprintf(str, str_len, "%c", '.');
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
char_str++;
|
||||
}
|
||||
}
|
||||
@@ -2311,39 +2202,15 @@ int bacapp_snprintf_value(
|
||||
case BACNET_APPLICATION_TAG_BIT_STRING:
|
||||
len = bitstring_bits_used(&value->type.Bit_String);
|
||||
slen = snprintf(str, str_len, "{");
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
for (i = 0; i < len; i++) {
|
||||
bool bit;
|
||||
bit = bitstring_bit(&value->type.Bit_String, (uint8_t)i);
|
||||
slen = snprintf(str, str_len, "%s", bit ? "true" : "false");
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (i < (len - 1)) {
|
||||
slen = snprintf(str, str_len, ",");
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
}
|
||||
}
|
||||
slen = snprintf(str, str_len, "}");
|
||||
@@ -2464,15 +2331,7 @@ int bacapp_snprintf_value(
|
||||
#if defined(BACAPP_OBJECT_ID)
|
||||
case BACNET_APPLICATION_TAG_OBJECT_ID:
|
||||
slen = snprintf(str, str_len, "(");
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
if (value->type.Object_Id.type <= BACNET_OBJECT_TYPE_LAST) {
|
||||
slen = snprintf(str, str_len, "%s, ",
|
||||
bactext_object_type_name(value->type.Object_Id.type));
|
||||
@@ -2484,15 +2343,7 @@ int bacapp_snprintf_value(
|
||||
slen = snprintf(str, str_len, "proprietary %u, ",
|
||||
(unsigned)value->type.Object_Id.type);
|
||||
}
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = snprintf(str, str_len, "%lu)",
|
||||
(unsigned long)value->type.Object_Id.instance);
|
||||
ret_val += slen;
|
||||
@@ -2502,25 +2353,9 @@ int bacapp_snprintf_value(
|
||||
case BACNET_APPLICATION_TAG_DATERANGE:
|
||||
slen = bacapp_snprintf_date(
|
||||
str, str_len, &value->type.Date_Range.startdate);
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = snprintf(str, str_len, "..");
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf_date(
|
||||
str, str_len, &value->type.Date_Range.enddate);
|
||||
ret_val += slen;
|
||||
@@ -2537,25 +2372,9 @@ int bacapp_snprintf_value(
|
||||
case BACNET_APPLICATION_TAG_DATETIME:
|
||||
slen = bacapp_snprintf_date(
|
||||
str, str_len, &value->type.Date_Time.date);
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = snprintf(str, str_len, "-");
|
||||
ret_val += slen;
|
||||
if (str) {
|
||||
str += slen;
|
||||
}
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf_time(
|
||||
str, str_len, &value->type.Date_Time.time);
|
||||
ret_val += slen;
|
||||
@@ -2578,27 +2397,11 @@ int bacapp_snprintf_value(
|
||||
case BACNET_APPLICATION_TAG_COLOR_COMMAND:
|
||||
/* BACnetColorCommand */
|
||||
slen = snprintf(str, str_len, "(");
|
||||
if (str) {
|
||||
str += slen;
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = snprintf(str, str_len, "%s",
|
||||
bactext_color_operation_name(
|
||||
value->type.Color_Command.operation));
|
||||
if (str) {
|
||||
str += slen;
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
/* FIXME: add the Lighting Command optional values */
|
||||
slen = snprintf(str, str_len, ")");
|
||||
ret_val += slen;
|
||||
@@ -2641,31 +2444,15 @@ int bacapp_snprintf_value(
|
||||
len = characterstring_length(name);
|
||||
char_str = characterstring_value(name);
|
||||
slen = snprintf(str, str_len, "\"");
|
||||
if (str) {
|
||||
str += slen;
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
}
|
||||
ret_val += slen;
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (isprint(*((unsigned char *)char_str))) {
|
||||
slen = snprintf(str, str_len, "%c", *char_str);
|
||||
} else {
|
||||
slen = snprintf(str, str_len, "%c", '.');
|
||||
}
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
char_str++;
|
||||
if (str) {
|
||||
str += slen;
|
||||
if (str_len >= slen) {
|
||||
str_len -= slen;
|
||||
} else {
|
||||
str_len = 0;
|
||||
}
|
||||
}
|
||||
ret_val += slen;
|
||||
}
|
||||
slen = snprintf(str, str_len, "\"");
|
||||
ret_val += slen;
|
||||
|
||||
@@ -314,6 +314,12 @@ extern "C" {
|
||||
#define BACAPP_PRINT_ENABLED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_snprintf_shift(
|
||||
int len,
|
||||
char **buf,
|
||||
size_t *buf_size);
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_snprintf_value(
|
||||
char *str,
|
||||
|
||||
+174
-145
@@ -71,8 +71,7 @@ void bacnet_destination_default_init(BACNET_DESTINATION *destination)
|
||||
* @param r2 - BACnetRecipient 2 structure
|
||||
* @return true if r1 and r2 are the same
|
||||
*/
|
||||
bool bacnet_recipient_same(
|
||||
BACNET_RECIPIENT *r1, BACNET_RECIPIENT *r2)
|
||||
bool bacnet_recipient_same(BACNET_RECIPIENT *r1, BACNET_RECIPIENT *r2)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
@@ -103,8 +102,7 @@ bool bacnet_recipient_same(
|
||||
* @param src - BACnetRecipient 1 structure
|
||||
* @param dest - BACnetRecipient 2 structure
|
||||
*/
|
||||
void bacnet_recipient_copy(
|
||||
BACNET_RECIPIENT *dest, BACNET_RECIPIENT *src)
|
||||
void bacnet_recipient_copy(BACNET_RECIPIENT *dest, BACNET_RECIPIENT *src)
|
||||
{
|
||||
if (dest && src) {
|
||||
memmove(dest, src, sizeof(BACNET_RECIPIENT));
|
||||
@@ -170,8 +168,7 @@ bool bacnet_destination_same(BACNET_DESTINATION *d1, BACNET_DESTINATION *d2)
|
||||
status = (datetime_compare_time(&d1->ToTime, &d2->ToTime) == 0);
|
||||
}
|
||||
if (status) {
|
||||
status = bacnet_recipient_same(
|
||||
&d1->Recipient, &d2->Recipient);
|
||||
status = bacnet_recipient_same(&d1->Recipient, &d2->Recipient);
|
||||
}
|
||||
if (status) {
|
||||
status = (d1->ProcessIdentifier == d2->ProcessIdentifier);
|
||||
@@ -252,7 +249,8 @@ int bacnet_destination_encode(uint8_t *apdu, BACNET_DESTINATION *destination)
|
||||
apdu += len;
|
||||
}
|
||||
if (destination->Recipient.tag == BACNET_RECIPIENT_TAG_DEVICE) {
|
||||
len = encode_context_object_id(apdu, 0, OBJECT_DEVICE,
|
||||
len = encode_context_object_id(
|
||||
apdu, 0, OBJECT_DEVICE,
|
||||
destination->Recipient.type.device.instance);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
@@ -392,7 +390,8 @@ int bacnet_destination_decode(
|
||||
if (decode_is_context_tag(apdu, BACNET_RECIPIENT_TAG_DEVICE)) {
|
||||
/* device [0] BACnetObjectIdentifier */
|
||||
destination->Recipient.tag = BACNET_RECIPIENT_TAG_DEVICE;
|
||||
len = decode_context_object_id(apdu, BACNET_RECIPIENT_TAG_DEVICE,
|
||||
len = decode_context_object_id(
|
||||
apdu, BACNET_RECIPIENT_TAG_DEVICE,
|
||||
&destination->Recipient.type.device.type,
|
||||
&destination->Recipient.type.device.instance);
|
||||
if (len == BACNET_STATUS_ERROR) {
|
||||
@@ -462,56 +461,52 @@ int bacnet_destination_decode(
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
|
||||
#define LEN_BRANCH(snprintf_expr) \
|
||||
do { \
|
||||
len = snprintf_expr; \
|
||||
output_len += len; \
|
||||
if (buf) { \
|
||||
if (len > buf_size) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
buf += len; \
|
||||
buf_size -= len; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Convert BACnet_Destination to ASCII for printing
|
||||
*
|
||||
* Output format:
|
||||
*
|
||||
* (ValidDays=[1,2,5,6,7];FromTime=0:00:00.0;ToTime=23:59:59.9;Recipient=Device(type=8,instance=15);ProcessIdentifier=0;ConfirmedNotify=false;Transitions=[to-offnormal,to-fault,to-normal])
|
||||
* (
|
||||
* ValidDays=[1,2,5,6,7];
|
||||
* FromTime=0:00:00.0;
|
||||
* ToTime=23:59:59.9;
|
||||
* Recipient=Device(type=8,instance=15);
|
||||
* ProcessIdentifier=0;
|
||||
* ConfirmedNotify=false;
|
||||
* Transitions=[to-offnormal,to-fault,to-normal]
|
||||
* )
|
||||
*
|
||||
* - ValidDays ... array of numbers, 1=Mon through 7=Sun
|
||||
* - FromTime, ToTime ... HH:MM:SS.s
|
||||
* - Recipient ... two variants: Recipient=Device(type=8,instance=15) or Recipient=Address(net=1234,mac=c0:a8:00:0f)
|
||||
* - Recipient ... two variants: Recipient=Device(type=8,instance=15) or
|
||||
* Recipient=Address(net=1234,mac=c0:a8:00:0f)
|
||||
* - type ... bacnet object type enum
|
||||
* - instance ... bacnet object instance
|
||||
* - net ... bacnet network number
|
||||
* - mac ... bacnet MAC address; can be separated by colons or periods.
|
||||
* - ProcessIdentifier ... 32bit unsigned int, process ID
|
||||
* - ConfirmedNotify ... true or false
|
||||
* - Transitions ... array with any of the three items: to-offnormal, to-fault, to-normal
|
||||
* - Transitions ... array with any of the three items: to-offnormal, to-fault,
|
||||
* to-normal
|
||||
*
|
||||
* @param bacdest - Destination struct to convert to ASCII
|
||||
* @param buf - ASCII output buffer
|
||||
* @param buf_size - ASCII output buffer capacity
|
||||
*
|
||||
* @return the number of characters which would be generated for the given
|
||||
* input, excluding the trailing null. negative is returned if the capacity was not sufficient.
|
||||
* input, excluding the trailing null.
|
||||
* @note buf and buf_size may be null and zero to return only the size
|
||||
*/
|
||||
int bacnet_destination_to_ascii(const BACNET_DESTINATION *bacdest, char *buf, size_t buf_size)
|
||||
int bacnet_destination_to_ascii(
|
||||
const BACNET_DESTINATION *bacdest, char *buf, size_t buf_size)
|
||||
{
|
||||
int len = 0;
|
||||
int output_len = 0;
|
||||
int buf_len = 0;
|
||||
bool comma;
|
||||
int i;
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "("));
|
||||
|
||||
len = snprintf(buf, buf_size, "(");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
/*
|
||||
BACnetDaysOfWeek ::= BIT STRING {
|
||||
monday (0),
|
||||
@@ -523,68 +518,80 @@ int bacnet_destination_to_ascii(const BACNET_DESTINATION *bacdest, char *buf, si
|
||||
sunday (6)
|
||||
}
|
||||
*/
|
||||
|
||||
/* Use numbers 1-7 (ISO 8601) */
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "ValidDays=["));
|
||||
len = snprintf(buf, buf_size, "ValidDays=[");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
comma = false;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (bitstring_bit((BACNET_BIT_STRING *) &bacdest->ValidDays, i)) {
|
||||
if (bitstring_bit((BACNET_BIT_STRING *)&bacdest->ValidDays, i)) {
|
||||
if (comma) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ","));
|
||||
len = snprintf(buf, buf_size, ",");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "%d", i + 1));
|
||||
len = snprintf(buf, buf_size, "%d", i + 1);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
comma = true;
|
||||
}
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "];"));
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "FromTime=%d:%02d:%02d.%02d;",
|
||||
bacdest->FromTime.hour,
|
||||
bacdest->FromTime.min,
|
||||
bacdest->FromTime.sec,
|
||||
bacdest->FromTime.hundredths
|
||||
));
|
||||
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "ToTime=%d:%02d:%02d.%02d;",
|
||||
bacdest->ToTime.hour,
|
||||
bacdest->ToTime.min,
|
||||
bacdest->ToTime.sec,
|
||||
bacdest->ToTime.hundredths
|
||||
));
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "Recipient="));
|
||||
len = snprintf(buf, buf_size, "];");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
len = snprintf(
|
||||
buf, buf_size, "FromTime=%d:%02d:%02d.%02d;", bacdest->FromTime.hour,
|
||||
bacdest->FromTime.min, bacdest->FromTime.sec,
|
||||
bacdest->FromTime.hundredths);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
len = snprintf(
|
||||
buf, buf_size, "ToTime=%d:%02d:%02d.%02d;", bacdest->ToTime.hour,
|
||||
bacdest->ToTime.min, bacdest->ToTime.sec, bacdest->ToTime.hundredths);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
len = snprintf(buf, buf_size, "Recipient=");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
if (bacdest->Recipient.tag == BACNET_RECIPIENT_TAG_DEVICE) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "Device(type=%d,instance=%lu)",
|
||||
bacdest->Recipient.type.device.type,
|
||||
(unsigned long)bacdest->Recipient.type.device.instance));
|
||||
len = snprintf(
|
||||
buf, buf_size, "Device(type=%d,instance=%lu)",
|
||||
bacdest->Recipient.type.device.type,
|
||||
(unsigned long)bacdest->Recipient.type.device.instance);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
} else {
|
||||
/*
|
||||
BACnetAddress ::= SEQUENCE {
|
||||
network-number Unsigned16, -- A value of 0 indicates the local network
|
||||
mac-address OCTET STRING -- A string of length 0 indicates a broadcast
|
||||
network-number Unsigned16, -- A value of 0 indicates the local
|
||||
network mac-address OCTET STRING -- A string of length 0 indicates
|
||||
a broadcast
|
||||
}
|
||||
*/
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "Address(net=%d,mac=", bacdest->Recipient.type.address.net));
|
||||
len = snprintf(
|
||||
buf, buf_size,
|
||||
"Address(net=%d,mac=", bacdest->Recipient.type.address.net);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
/* TODO determine if it's IPv4+port or Ethernet mac address and print it nicer - how? Both are 6 bytes long. */
|
||||
/* TODO determine if it's IPv4+port or Ethernet mac address and print it
|
||||
* nicer - how? Both are 6 bytes long. */
|
||||
|
||||
for (i = 0; i < bacdest->Recipient.type.address.mac_len; i++) {
|
||||
if (i > 0) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ":"));
|
||||
len = snprintf(buf, buf_size, ":");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "%02x", bacdest->Recipient.type.address.mac[i]));
|
||||
len = snprintf(
|
||||
buf, buf_size, "%02x", bacdest->Recipient.type.address.mac[i]);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ")"));
|
||||
len = snprintf(buf, buf_size, ")");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ";"));
|
||||
len = snprintf(buf, buf_size, ";");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "ProcessIdentifier=%lu;",
|
||||
(unsigned long)bacdest->ProcessIdentifier));
|
||||
len = snprintf(
|
||||
buf, buf_size, "ProcessIdentifier=%lu;",
|
||||
(unsigned long)bacdest->ProcessIdentifier);
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "ConfirmedNotify=%s;",
|
||||
bacdest->ConfirmedNotify ? "true" : "false"
|
||||
));
|
||||
len = snprintf(
|
||||
buf, buf_size, "ConfirmedNotify=%s;",
|
||||
bacdest->ConfirmedNotify ? "true" : "false");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
/*
|
||||
BACnetEventTransitionBits ::= BIT STRING {
|
||||
@@ -593,36 +600,49 @@ int bacnet_destination_to_ascii(const BACNET_DESTINATION *bacdest, char *buf, si
|
||||
to-normal (2)
|
||||
}
|
||||
*/
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "Transitions=["));
|
||||
len = snprintf(buf, buf_size, "Transitions=[");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
comma = false;
|
||||
/* TODO remove casting when bitstring_bit() has const added - Github issue #320 */
|
||||
if (bitstring_bit((BACNET_BIT_STRING *) &bacdest->Transitions, TRANSITION_TO_OFFNORMAL)) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "to-offnormal"));
|
||||
/* TODO remove casting when bitstring_bit() has const added - Github issue
|
||||
* #320 */
|
||||
if (bitstring_bit(
|
||||
(BACNET_BIT_STRING *)&bacdest->Transitions,
|
||||
TRANSITION_TO_OFFNORMAL)) {
|
||||
len = snprintf(buf, buf_size, "to-offnormal");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
comma = true;
|
||||
}
|
||||
if (bitstring_bit((BACNET_BIT_STRING *) &bacdest->Transitions, TRANSITION_TO_FAULT)) {
|
||||
if (bitstring_bit(
|
||||
(BACNET_BIT_STRING *)&bacdest->Transitions, TRANSITION_TO_FAULT)) {
|
||||
if (comma) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ","));
|
||||
len = snprintf(buf, buf_size, ",");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "to-fault"));
|
||||
len = snprintf(buf, buf_size, "to-fault");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
comma = true;
|
||||
}
|
||||
if (bitstring_bit((BACNET_BIT_STRING *) &bacdest->Transitions, TRANSITION_TO_NORMAL)) {
|
||||
if (bitstring_bit(
|
||||
(BACNET_BIT_STRING *)&bacdest->Transitions, TRANSITION_TO_NORMAL)) {
|
||||
if (comma) {
|
||||
LEN_BRANCH(snprintf(buf, buf_size, ","));
|
||||
len = snprintf(buf, buf_size, ",");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "to-normal"));
|
||||
len = snprintf(buf, buf_size, "to-normal");
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
LEN_BRANCH(snprintf(buf, buf_size, "])")); /* end of the outer paren */
|
||||
len = snprintf(buf, buf_size, "])"); /* end of the outer paren */
|
||||
buf_len += bacapp_snprintf_shift(len, &buf, &buf_size);
|
||||
|
||||
return output_len;
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse BACnet_Destination from ASCII string (as entered by user)
|
||||
*
|
||||
* @param bacdest - Destination struct to pupulate with data from the ASCII string
|
||||
* @param bacdest - Destination struct to pupulate with data from the ASCII
|
||||
* string
|
||||
* @param buf - ASCII string, zero terminated
|
||||
* @return true on success
|
||||
*/
|
||||
@@ -658,14 +678,9 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
enum ParseKeyword kw = 0;
|
||||
BACNET_TIME *ptime;
|
||||
BACNET_MAC_ADDRESS tmpmac;
|
||||
static const char * KW_LOOKUP[] = {
|
||||
"ValidDays",
|
||||
"FromTime",
|
||||
"ToTime",
|
||||
"Recipient",
|
||||
"ProcessIdentifier",
|
||||
"ConfirmedNotify",
|
||||
"Transitions",
|
||||
static const char *KW_LOOKUP[] = {
|
||||
"ValidDays", "FromTime", "ToTime", "Recipient",
|
||||
"ProcessIdentifier", "ConfirmedNotify", "Transitions",
|
||||
};
|
||||
|
||||
if (bacdest == NULL || buf == NULL) {
|
||||
@@ -674,7 +689,6 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
|
||||
bacnet_destination_default_init(bacdest);
|
||||
|
||||
|
||||
/* Helper macros to simplify the parser ... */
|
||||
|
||||
/* true if the character is whitespace */
|
||||
@@ -682,48 +696,49 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
|
||||
/* Discard characters while they match a given test. Goes to parse_end on NUL.
|
||||
* ctest is a boolean expression where c is the tested character */
|
||||
#define DISCARD_WHILE(ctest) \
|
||||
do { \
|
||||
while(1) { \
|
||||
c = buf[pos]; \
|
||||
if (c == 0) { \
|
||||
goto parse_end; \
|
||||
} \
|
||||
if ((ctest)) { \
|
||||
pos++; \
|
||||
continue; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} while(0)
|
||||
#define DISCARD_WHILE(ctest) \
|
||||
do { \
|
||||
while (1) { \
|
||||
c = buf[pos]; \
|
||||
if (c == 0) { \
|
||||
goto parse_end; \
|
||||
} \
|
||||
if ((ctest)) { \
|
||||
pos++; \
|
||||
continue; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Discard all whitespace. Goes to parse_end on NUL. */
|
||||
#define DISCARD_WHITESPACE() DISCARD_WHILE(ISWHITE(c))
|
||||
|
||||
/* Must consume a given word; return false otherwise. */
|
||||
#define MUST_CONSUME(s) \
|
||||
do { \
|
||||
_must_consume_tmplen = strlen(s); \
|
||||
if (0 == strncmp(&buf[pos], s, _must_consume_tmplen)) { \
|
||||
pos += _must_consume_tmplen; \
|
||||
} else { \
|
||||
return false; \
|
||||
} \
|
||||
} while(0)
|
||||
#define MUST_CONSUME(s) \
|
||||
do { \
|
||||
_must_consume_tmplen = strlen(s); \
|
||||
if (0 == strncmp(&buf[pos], s, _must_consume_tmplen)) { \
|
||||
pos += _must_consume_tmplen; \
|
||||
} else { \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Collect a decimal number and store the result into tmp; stop on a non-digit. Clobbers "c" and "tmp". TODO replace with strtol? */
|
||||
#define COLLECT_NUMBER_TMP(maxdigits) \
|
||||
do { \
|
||||
tmp = 0; \
|
||||
for (_number_i = 0; _number_i < (maxdigits); _number_i++) { \
|
||||
c = buf[pos]; \
|
||||
if (c >= '0' && c <= '9') { \
|
||||
tmp = (tmp * 10) + (c - '0'); \
|
||||
pos++; \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
/* Collect a decimal number and store the result into tmp; stop on a non-digit.
|
||||
* Clobbers "c" and "tmp". TODO replace with strtol? */
|
||||
#define COLLECT_NUMBER_TMP(maxdigits) \
|
||||
do { \
|
||||
tmp = 0; \
|
||||
for (_number_i = 0; _number_i < (maxdigits); _number_i++) { \
|
||||
c = buf[pos]; \
|
||||
if (c >= '0' && c <= '9') { \
|
||||
tmp = (tmp * 10) + (c - '0'); \
|
||||
pos++; \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Go through all key=value pieces in the string */
|
||||
@@ -763,7 +778,9 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
}
|
||||
break;
|
||||
|
||||
case PH_VALUE_SPACER: /* Equals between key and value, also consuming opening square bracket if present. */
|
||||
case PH_VALUE_SPACER: /* Equals between key and value, also
|
||||
consuming opening square bracket if
|
||||
present. */
|
||||
DISCARD_WHITESPACE();
|
||||
MUST_CONSUME("=");
|
||||
DISCARD_WHILE(c == '[' || ISWHITE(c));
|
||||
@@ -792,7 +809,8 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
}
|
||||
if (j == 0) {
|
||||
if (c >= '1' && c <= '7') {
|
||||
bitstring_set_bit(&bacdest->ValidDays, c - '1', true);
|
||||
bitstring_set_bit(
|
||||
&bacdest->ValidDays, c - '1', true);
|
||||
pos++;
|
||||
j = 1;
|
||||
} else {
|
||||
@@ -815,7 +833,8 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
ptime = &bacdest->ToTime;
|
||||
}
|
||||
|
||||
/* TODO implemented in bacapp_parse_application_data - extract & reuse? */
|
||||
/* TODO implemented in bacapp_parse_application_data -
|
||||
* extract & reuse? */
|
||||
|
||||
/* Hour */
|
||||
COLLECT_NUMBER_TMP(2);
|
||||
@@ -887,17 +906,20 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
if (j == 0) {
|
||||
if (0 ==
|
||||
strncmp(&buf[pos], "to-offnormal", 12)) {
|
||||
bitstring_set_bit(&bacdest->Transitions,
|
||||
bitstring_set_bit(
|
||||
&bacdest->Transitions,
|
||||
TRANSITION_TO_OFFNORMAL, true);
|
||||
pos += 12;
|
||||
} else if (0 ==
|
||||
strncmp(&buf[pos], "to-fault", 8)) {
|
||||
bitstring_set_bit(&bacdest->Transitions,
|
||||
} else if (
|
||||
0 == strncmp(&buf[pos], "to-fault", 8)) {
|
||||
bitstring_set_bit(
|
||||
&bacdest->Transitions,
|
||||
TRANSITION_TO_FAULT, true);
|
||||
pos += 8;
|
||||
} else if (0 ==
|
||||
strncmp(&buf[pos], "to-normal", 9)) {
|
||||
bitstring_set_bit(&bacdest->Transitions,
|
||||
} else if (
|
||||
0 == strncmp(&buf[pos], "to-normal", 9)) {
|
||||
bitstring_set_bit(
|
||||
&bacdest->Transitions,
|
||||
TRANSITION_TO_NORMAL, true);
|
||||
pos += 9;
|
||||
} else {
|
||||
@@ -914,7 +936,8 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
case KW_Recipient:
|
||||
if (0 == strncmp(&buf[pos], "Device", 6)) {
|
||||
pos += 6;
|
||||
bacdest->Recipient.tag = BACNET_RECIPIENT_TAG_DEVICE;
|
||||
bacdest->Recipient.tag =
|
||||
BACNET_RECIPIENT_TAG_DEVICE;
|
||||
|
||||
DISCARD_WHITESPACE();
|
||||
MUST_CONSUME("(");
|
||||
@@ -943,7 +966,8 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
|
||||
} else if (0 == strncmp(&buf[pos], "Address", 7)) {
|
||||
pos += 7;
|
||||
bacdest->Recipient.tag = BACNET_RECIPIENT_TAG_ADDRESS;
|
||||
bacdest->Recipient.tag =
|
||||
BACNET_RECIPIENT_TAG_ADDRESS;
|
||||
|
||||
DISCARD_WHITESPACE();
|
||||
MUST_CONSUME("(");
|
||||
@@ -964,13 +988,18 @@ bool bacnet_destination_from_ascii(BACNET_DESTINATION *bacdest, const char *buf)
|
||||
MUST_CONSUME("=");
|
||||
DISCARD_WHITESPACE();
|
||||
|
||||
if (!bacnet_address_mac_from_ascii(&tmpmac, &buf[pos])) {
|
||||
if (!bacnet_address_mac_from_ascii(
|
||||
&tmpmac, &buf[pos])) {
|
||||
return false;
|
||||
}
|
||||
bacdest->Recipient.type.address.mac_len = tmpmac.len;
|
||||
memcpy(&bacdest->Recipient.type.address.mac, &tmpmac.adr, MAX_MAC_LEN);
|
||||
bacdest->Recipient.type.address.mac_len =
|
||||
tmpmac.len;
|
||||
memcpy(
|
||||
&bacdest->Recipient.type.address.mac,
|
||||
&tmpmac.adr, MAX_MAC_LEN);
|
||||
|
||||
/* address_mac_from_ascii doesn't return number of digits
|
||||
/* address_mac_from_ascii doesn't return number of
|
||||
* digits
|
||||
* - we have to discard until ) */
|
||||
|
||||
DISCARD_WHILE(c != ')');
|
||||
|
||||
+33
-28
@@ -35,7 +35,10 @@
|
||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||
#include <stdbool.h> /* for the standard bool type. */
|
||||
#include <stdio.h>
|
||||
#include "bacnet/bacenum.h"
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacint.h"
|
||||
#include "bacnet/datalink/bvlc6.h"
|
||||
@@ -641,6 +644,32 @@ bool bvlc6_address_get(BACNET_IP6_ADDRESS *addr,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shift the buffer pointer and decrease the size after an snprintf
|
||||
* @param len - number of bytes (excluding terminating NULL byte) from snprintf
|
||||
* @param buf - pointer to the buffer pointer
|
||||
* @param buf_size - pointer to the buffer size
|
||||
* @return number of bytes (excluding terminating NULL byte) from snprintf
|
||||
*/
|
||||
static int snprintf_shift(int len, char **buf, size_t *buf_size)
|
||||
{
|
||||
if (buf) {
|
||||
if (*buf) {
|
||||
*buf += len;
|
||||
}
|
||||
}
|
||||
if (buf_size) {
|
||||
if ((*buf_size) >= len) {
|
||||
*buf_size -= len;
|
||||
} else {
|
||||
*buf_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/** Convert IPv6 Address from ASCII
|
||||
*
|
||||
* IPv6 addresses are represented as eight groups, separated by colons,
|
||||
@@ -689,41 +718,17 @@ int bvlc6_address_to_ascii(BACNET_IP6_ADDRESS *addr, char *buf, size_t buf_size)
|
||||
if ((a == 0) && (f >= 0)) {
|
||||
if (f++ == 0) {
|
||||
len = snprintf(buf, buf_size, "::");
|
||||
if (buf) {
|
||||
buf += len;
|
||||
}
|
||||
if (len > buf_size) {
|
||||
buf_size = 0;
|
||||
} else {
|
||||
buf_size -= len;
|
||||
}
|
||||
n += len;
|
||||
n += snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
} else {
|
||||
if (f > 0) {
|
||||
f = -1;
|
||||
} else if (i > 0) {
|
||||
len = snprintf(buf, buf_size, ":");
|
||||
if (buf) {
|
||||
buf += len;
|
||||
}
|
||||
if (len > buf_size) {
|
||||
buf_size = 0;
|
||||
} else {
|
||||
buf_size -= len;
|
||||
}
|
||||
n += len;
|
||||
n += snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
len = snprintf(buf, buf_size, "%x", a);
|
||||
if (buf) {
|
||||
buf += len;
|
||||
}
|
||||
if (len > buf_size) {
|
||||
buf_size = 0;
|
||||
} else {
|
||||
buf_size -= len;
|
||||
}
|
||||
n += len;
|
||||
n += snprintf_shift(len, &buf, &buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user