FLAG_EXTRA_NONE = 0, //!< no extra meaning, should be invalid
FLAG_KEY_FIELD, //!< this is a key field for a subsequent struct
FLAG_BIT_FIELD, //!< bit field inside of a struct
+ FLAG_LENGTH_UINT8, //!< string / octets type is prefixed by uint8 of length
FLAG_LENGTH_UINT16, //!< string / octets type is prefixed by uint16 of length
};
#define fr_dict_attr_is_key_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_KEY_FIELD))
#define da_is_bit_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_BIT_FIELD))
-#define da_is_length_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_LENGTH_UINT16))
+#define da_is_length_field(_da) ((_da)->flags.extra && (((_da)->flags.subtype == FLAG_LENGTH_UINT16) || ((_da)->flags.subtype == FLAG_LENGTH_UINT16)))
/** Extension identifier
FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "key,");
break;
- case FLAG_LENGTH_UINT16:
+ case FLAG_BIT_FIELD:
FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint16,");
break;
- case FLAG_BIT_FIELD:
+ case FLAG_LENGTH_UINT8:
+ FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint8,");
+ break;
+
+ case FLAG_LENGTH_UINT16:
FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint16,");
break;
flags->subtype = FLAG_KEY_FIELD;
} else if (strcmp(key, "length") == 0) {
- if (!value || (strcmp(value, "uint16") != 0)) {
- fr_strerror_const("The 'length' flag can only be used with value 'uint16'");
+ if (!value) {
+ fr_strerror_const("The 'length' flag requires a value");
+ return -1;
}
- flags->extra = 1;
- flags->subtype = FLAG_LENGTH_UINT16;
+ if (strcmp(value, "uint8") == 0) {
+ flags->extra = 1;
+ flags->subtype = FLAG_LENGTH_UINT8;
+
+ } else if (strcmp(value, "uint16") == 0) {
+ flags->extra = 1;
+ flags->subtype = FLAG_LENGTH_UINT16;
+
+ } else {
+ fr_strerror_const("Invalid value given for the 'length' flag");
+ return -1;
+ }
} else if ((type == FR_TYPE_DATE) || (type == FR_TYPE_TIME_DELTA)) {
/*
*/
memset(&flags, 0, sizeof(flags));
+ /*
+ * Structs can be prefixed with 16-bit lengths, but not
+ * with any other type of length.
+ */
if (argc == 4) {
if (strcmp(argv[3], "length=uint16") != 0) {
fr_strerror_printf("Unknown option '%s'", argv[3]);
* the data type.
*/
if (flags->extra) {
- if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_LENGTH_UINT16) &&
- (flags->subtype != FLAG_BIT_FIELD)) {
+ if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_BIT_FIELD) &&
+ (flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) {
fr_strerror_const("The 'key' and 'length' flags cannot be used with any other flags.");
return false;
}
if (flags->array) {
ALLOW_FLAG(array);
- if (flags->subtype != FLAG_LENGTH_UINT16) goto invalid_extra;
+ if ((flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) goto invalid_extra;
} else if (flags->subtype) {
invalid_extra:
fr_strerror_const("Invalid type for extra flag.");
return false;
}
- if ((flags->subtype == FLAG_LENGTH_UINT16) &&
+ if (((flags->subtype == FLAG_LENGTH_UINT8) || (flags->subtype == FLAG_LENGTH_UINT16)) &&
((type != FR_TYPE_STRING) && (type != FR_TYPE_OCTETS) && (type != FR_TYPE_STRUCT))) {
fr_strerror_printf("The 'length' flag cannot be used used with type %s",
fr_type_to_str(type));