@@ -233,47 +233,44 @@ std::optional<CHIP_ERROR> TryReadViaAccessInterface(const ConcreteAttributePath
233
233
return encoder.TriedEncode () ? std::make_optional (CHIP_NO_ERROR) : std::nullopt;
234
234
}
235
235
236
- static constexpr uint8_t kEmberStringNullLength = 0xFF ;
237
- static constexpr uint16_t kEmberLongStringNullLength = 0xFFFF ;
238
-
239
- template <class T >
240
- std::optional<T> ExtractEmberShortString (ByteSpan data)
236
+ struct ShortPascalString
241
237
{
242
- uint8_t len = data[0 ];
243
-
244
- if (len == kEmberStringNullLength )
245
- {
246
- return std::nullopt;
247
- }
238
+ using LengthType = uint8_t ;
239
+ static constexpr LengthType kNullLength = 0xFF ;
240
+ };
248
241
249
- VerifyOrDie (static_cast <size_t >(len + 1 ) <= data.size ());
250
- return std::make_optional<T>(reinterpret_cast <typename T::pointer>(data.data () + 1 ), len);
251
- }
242
+ struct LongPascalString
243
+ {
244
+ using LengthType = uint16_t ;
245
+ static constexpr LengthType kNullLength = 0xFFFF ;
246
+ };
252
247
253
- static constexpr size_t kLongStringLengthBytes = 2 ;
248
+ // ember assumptions ... should just work
249
+ static_assert (sizeof (ShortPascalString::LengthType) == 1 );
250
+ static_assert (sizeof (LongPascalString::LengthType) == 2 );
254
251
255
- template <class T >
256
- std::optional<T> ExtractEmberLongString (ByteSpan data)
252
+ template <class OUT , class ENCODING >
253
+ std::optional<OUT> ExtractEmberString (ByteSpan data)
257
254
{
258
- uint16_t len;
259
- static_assert (sizeof (len) == kLongStringLengthBytes );
255
+ typename ENCODING::LengthType len;
260
256
261
- VerifyOrDie (kLongStringLengthBytes <= data.size ());
262
- memcpy (&len, data.data (), kLongStringLengthBytes );
257
+ VerifyOrDie (sizeof (len) <= data.size ());
258
+ memcpy (&len, data.data (), sizeof (len) );
263
259
264
- if (len == kEmberLongStringNullLength )
260
+ if (len == ENCODING:: kNullLength )
265
261
{
266
262
return std::nullopt;
267
263
}
268
264
269
- VerifyOrDie (static_cast <size_t >(len + kLongStringLengthBytes ) <= data.size ());
270
- return std::make_optional<T >(reinterpret_cast <typename T ::pointer>(data.data () + kLongStringLengthBytes ), len);
265
+ VerifyOrDie (static_cast <size_t >(len + sizeof (len) ) <= data.size ());
266
+ return std::make_optional<OUT >(reinterpret_cast <typename OUT ::pointer>(data.data () + sizeof (len) ), len);
271
267
}
272
268
273
- template <typename T>
274
- CHIP_ERROR EncodeStringLike (std::optional<T> data, bool isNullable, AttributeValueEncoder & encoder)
269
+ template <typename T, class ENCODING >
270
+ CHIP_ERROR EncodeStringLike (ByteSpan data, bool isNullable, AttributeValueEncoder & encoder)
275
271
{
276
- if (!data.has_value ())
272
+ std::optional<T> value = ExtractEmberString<T, ENCODING>(data);
273
+ if (!value.has_value ())
277
274
{
278
275
if (isNullable)
279
276
{
@@ -283,7 +280,7 @@ CHIP_ERROR EncodeStringLike(std::optional<T> data, bool isNullable, AttributeVal
283
280
}
284
281
285
282
// encode value as-is
286
- return encoder.Encode (*data );
283
+ return encoder.Encode (*value );
287
284
}
288
285
289
286
template <typename T>
@@ -357,13 +354,13 @@ CHIP_ERROR EncodeEmberValue(ByteSpan data, const EmberAfAttributeMetadata * meta
357
354
case ZCL_DOUBLE_ATTRIBUTE_TYPE: // 64-bit float
358
355
return EncodeFromSpan<double >(data, isNullable, encoder);
359
356
case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string
360
- return EncodeStringLike (ExtractEmberShortString <CharSpan>(data) , isNullable, encoder);
357
+ return EncodeStringLike<CharSpan, ShortPascalString >(data, isNullable, encoder);
361
358
case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE:
362
- return EncodeStringLike (ExtractEmberLongString <CharSpan>(data) , isNullable, encoder);
359
+ return EncodeStringLike<CharSpan, LongPascalString >(data, isNullable, encoder);
363
360
case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string
364
- return EncodeStringLike (ExtractEmberShortString <ByteSpan>(data) , isNullable, encoder);
361
+ return EncodeStringLike<ByteSpan, ShortPascalString >(data, isNullable, encoder);
365
362
case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE:
366
- return EncodeStringLike (ExtractEmberLongString <ByteSpan>(data) , isNullable, encoder);
363
+ return EncodeStringLike<ByteSpan, LongPascalString >(data, isNullable, encoder);
367
364
default :
368
365
ChipLogError (DataManagement, " Attribute type 0x%x not handled" , static_cast <int >(metadata->attributeType ));
369
366
return CHIP_IM_GLOBAL_STATUS (UnsupportedRead);
0 commit comments