@@ -613,7 +613,9 @@ - (void)subscribeWithQueue:(dispatch_queue_t)queue
613
613
}
614
614
}
615
615
616
- static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal (id object, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag)
616
+ // writer is allowed to be null to just validate the incoming object without
617
+ // actually encoding.
618
+ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal (id object, chip::TLV::TLVWriter * writer, chip::TLV::Tag tag)
617
619
{
618
620
if (![object isKindOfClass: [NSDictionary class ]]) {
619
621
MTR_LOG_ERROR (" Error: Unsupported object to encode: %@" , [object class ]);
@@ -631,60 +633,62 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T
631
633
MTR_LOG_ERROR (" Error: Object to encode has corrupt signed integer type: %@" , [value class ]);
632
634
return CHIP_ERROR_INVALID_ARGUMENT;
633
635
}
634
- return writer. Put (tag, [value longLongValue ]);
636
+ return writer ? writer-> Put (tag, [value longLongValue ]) : CHIP_NO_ERROR ;
635
637
}
636
638
if ([typeName isEqualToString: MTRUnsignedIntegerValueType]) {
637
639
if (![value isKindOfClass: [NSNumber class ]]) {
638
640
MTR_LOG_ERROR (" Error: Object to encode has corrupt unsigned integer type: %@" , [value class ]);
639
641
return CHIP_ERROR_INVALID_ARGUMENT;
640
642
}
641
- return writer. Put (tag, [value unsignedLongLongValue ]);
643
+ return writer ? writer-> Put (tag, [value unsignedLongLongValue ]) : CHIP_NO_ERROR ;
642
644
}
643
645
if ([typeName isEqualToString: MTRBooleanValueType]) {
644
646
if (![value isKindOfClass: [NSNumber class ]]) {
645
647
MTR_LOG_ERROR (" Error: Object to encode has corrupt boolean type: %@" , [value class ]);
646
648
return CHIP_ERROR_INVALID_ARGUMENT;
647
649
}
648
- return writer. Put (tag, static_cast <bool >([value boolValue ]));
650
+ return writer ? writer-> Put (tag, static_cast <bool >([value boolValue ])) : CHIP_NO_ERROR ;
649
651
}
650
652
if ([typeName isEqualToString: MTRFloatValueType]) {
651
653
if (![value isKindOfClass: [NSNumber class ]]) {
652
654
MTR_LOG_ERROR (" Error: Object to encode has corrupt float type: %@" , [value class ]);
653
655
return CHIP_ERROR_INVALID_ARGUMENT;
654
656
}
655
- return writer. Put (tag, [value floatValue ]);
657
+ return writer ? writer-> Put (tag, [value floatValue ]) : CHIP_NO_ERROR ;
656
658
}
657
659
if ([typeName isEqualToString: MTRDoubleValueType]) {
658
660
if (![value isKindOfClass: [NSNumber class ]]) {
659
661
MTR_LOG_ERROR (" Error: Object to encode has corrupt double type: %@" , [value class ]);
660
662
return CHIP_ERROR_INVALID_ARGUMENT;
661
663
}
662
- return writer. Put (tag, [value doubleValue ]);
664
+ return writer ? writer-> Put (tag, [value doubleValue ]) : CHIP_NO_ERROR ;
663
665
}
664
666
if ([typeName isEqualToString: MTRNullValueType]) {
665
- return writer. PutNull (tag);
667
+ return writer ? writer-> PutNull (tag) : CHIP_NO_ERROR ;
666
668
}
667
669
if ([typeName isEqualToString: MTRUTF8StringValueType]) {
668
670
if (![value isKindOfClass: [NSString class ]]) {
669
671
MTR_LOG_ERROR (" Error: Object to encode has corrupt UTF8 string type: %@" , [value class ]);
670
672
return CHIP_ERROR_INVALID_ARGUMENT;
671
673
}
672
- return writer. PutString (tag, AsCharSpan (value));
674
+ return writer ? writer-> PutString (tag, AsCharSpan (value)) : CHIP_NO_ERROR ;
673
675
}
674
676
if ([typeName isEqualToString: MTROctetStringValueType]) {
675
677
if (![value isKindOfClass: [NSData class ]]) {
676
678
MTR_LOG_ERROR (" Error: Object to encode has corrupt octet string type: %@" , [value class ]);
677
679
return CHIP_ERROR_INVALID_ARGUMENT;
678
680
}
679
- return writer. Put (tag, AsByteSpan (value));
681
+ return writer ? writer-> Put (tag, AsByteSpan (value)) : CHIP_NO_ERROR ;
680
682
}
681
683
if ([typeName isEqualToString: MTRStructureValueType]) {
682
684
if (![value isKindOfClass: [NSArray class ]]) {
683
685
MTR_LOG_ERROR (" Error: Object to encode has corrupt structure type: %@" , [value class ]);
684
686
return CHIP_ERROR_INVALID_ARGUMENT;
685
687
}
686
- TLV::TLVType outer;
687
- ReturnErrorOnFailure (writer.StartContainer (tag, chip::TLV::kTLVType_Structure , outer));
688
+ TLV::TLVType outer = TLV::kTLVType_NotSpecified ;
689
+ if (writer) {
690
+ ReturnErrorOnFailure (writer->StartContainer (tag, chip::TLV::kTLVType_Structure , outer));
691
+ }
688
692
for (id element in value) {
689
693
if (![element isKindOfClass: [NSDictionary class ]]) {
690
694
MTR_LOG_ERROR (" Error: Structure element to encode has corrupt type: %@" , [element class ]);
@@ -713,16 +717,20 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T
713
717
ReturnErrorOnFailure (
714
718
MTREncodeTLVFromDataValueDictionaryInternal (elementValue, writer, tag));
715
719
}
716
- ReturnErrorOnFailure (writer.EndContainer (outer));
720
+ if (writer) {
721
+ ReturnErrorOnFailure (writer->EndContainer (outer));
722
+ }
717
723
return CHIP_NO_ERROR;
718
724
}
719
725
if ([typeName isEqualToString: MTRArrayValueType]) {
720
726
if (![value isKindOfClass: [NSArray class ]]) {
721
727
MTR_LOG_ERROR (" Error: Object to encode has corrupt array type: %@" , [value class ]);
722
728
return CHIP_ERROR_INVALID_ARGUMENT;
723
729
}
724
- TLV::TLVType outer;
725
- ReturnErrorOnFailure (writer.StartContainer (tag, chip::TLV::kTLVType_Array , outer));
730
+ TLV::TLVType outer = TLV::kTLVType_NotSpecified ;
731
+ if (writer) {
732
+ ReturnErrorOnFailure (writer->StartContainer (tag, chip::TLV::kTLVType_Array , outer));
733
+ }
726
734
for (id element in value) {
727
735
if (![element isKindOfClass: [NSDictionary class ]]) {
728
736
MTR_LOG_ERROR (" Error: Array element to encode has corrupt type: %@" , [element class ]);
@@ -735,14 +743,16 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T
735
743
}
736
744
ReturnErrorOnFailure (MTREncodeTLVFromDataValueDictionaryInternal (elementValue, writer, chip::TLV::AnonymousTag ()));
737
745
}
738
- ReturnErrorOnFailure (writer.EndContainer (outer));
746
+ if (writer) {
747
+ ReturnErrorOnFailure (writer->EndContainer (outer));
748
+ }
739
749
return CHIP_NO_ERROR;
740
750
}
741
751
MTR_LOG_ERROR (" Error: Unsupported type to encode: %@" , typeName);
742
752
return CHIP_ERROR_INVALID_ARGUMENT;
743
753
}
744
754
745
- static CHIP_ERROR MTREncodeTLVFromDataValueDictionary (id object, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag)
755
+ static CHIP_ERROR MTREncodeTLVFromDataValueDictionary (id object, chip::TLV::TLVWriter * writer, chip::TLV::Tag tag)
746
756
{
747
757
CHIP_ERROR err = MTREncodeTLVFromDataValueDictionaryInternal (object, writer, tag);
748
758
if (err != CHIP_NO_ERROR) {
@@ -761,7 +771,7 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVW
761
771
TLV::TLVWriter writer;
762
772
writer.Init (buffer);
763
773
764
- CHIP_ERROR err = MTREncodeTLVFromDataValueDictionary (value, writer, TLV::AnonymousTag ());
774
+ CHIP_ERROR err = MTREncodeTLVFromDataValueDictionary (value, & writer, TLV::AnonymousTag ());
765
775
if (err != CHIP_NO_ERROR) {
766
776
if (error) {
767
777
*error = [MTRError errorForCHIPErrorCode: err];
@@ -772,6 +782,11 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVW
772
782
return AsData (ByteSpan (buffer, writer.GetLengthWritten ()));
773
783
}
774
784
785
+ BOOL MTRDataValueDictionaryIsWellFormed (MTRDeviceDataValueDictionary value)
786
+ {
787
+ return MTREncodeTLVFromDataValueDictionary (value, nullptr , TLV::AnonymousTag ()) == CHIP_NO_ERROR;
788
+ }
789
+
775
790
// Callback type to pass data value as an NSObject
776
791
typedef void (*MTRDataValueDictionaryCallback)(void * context, id value);
777
792
@@ -798,7 +813,7 @@ CHIP_ERROR Decode(chip::TLV::TLVReader & data)
798
813
799
814
CHIP_ERROR Encode (chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
800
815
{
801
- return MTREncodeTLVFromDataValueDictionary (decodedObj, writer, tag);
816
+ return MTREncodeTLVFromDataValueDictionary (decodedObj, & writer, tag);
802
817
}
803
818
804
819
static constexpr bool kIsFabricScoped = false ;
@@ -2212,7 +2227,7 @@ + (NSDictionary *)eventReportForHeader:(const chip::app::EventHeader &)header an
2212
2227
// Commands never need chained buffers, since they cannot be chunked.
2213
2228
writer.Init (std::move (buffer), /* useChainedBuffers = */ false );
2214
2229
2215
- CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary (data, writer, TLV::AnonymousTag ());
2230
+ CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary (data, & writer, TLV::AnonymousTag ());
2216
2231
if (errorCode != CHIP_NO_ERROR) {
2217
2232
LogStringAndReturnError (@" Unable to encode data-value to TLV" , errorCode, error);
2218
2233
return System::PacketBufferHandle ();
@@ -3082,7 +3097,7 @@ static bool EncodeDataValueToTLV(System::PacketBufferHandle & buffer, Platform::
3082
3097
System::PacketBufferTLVWriter writer;
3083
3098
writer.Init (std::move (buffer), /* useChainedBuffers = */ true );
3084
3099
3085
- CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary (data, writer, TLV::AnonymousTag ());
3100
+ CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary (data, & writer, TLV::AnonymousTag ());
3086
3101
if (errorCode != CHIP_NO_ERROR) {
3087
3102
LogStringAndReturnError (@" Unable to encode data-value to TLV" , errorCode, error);
3088
3103
return false ;
0 commit comments