diff options
3 files changed, 105 insertions, 12 deletions
diff --git a/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h b/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h index c2114ccff..8c3507e4f 100644 --- a/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h +++ b/property_service/libpropertyinfoparser/include/property_info_parser/property_info_parser.h | |||
@@ -172,6 +172,9 @@ class PropertyInfoArea : private SerializedData { | |||
172 | TrieNode root_node() const { return trie(header()->root_offset); } | 172 | TrieNode root_node() const { return trie(header()->root_offset); } |
173 | 173 | ||
174 | private: | 174 | private: |
175 | void CheckPrefixMatch(const char* remaining_name, const TrieNode& trie_node, | ||
176 | uint32_t* context_index, uint32_t* schema_index) const; | ||
177 | |||
175 | const PropertyInfoAreaHeader* header() const { | 178 | const PropertyInfoAreaHeader* header() const { |
176 | return reinterpret_cast<const PropertyInfoAreaHeader*>(data_base()); | 179 | return reinterpret_cast<const PropertyInfoAreaHeader*>(data_base()); |
177 | } | 180 | } |
diff --git a/property_service/libpropertyinfoparser/property_info_parser.cpp b/property_service/libpropertyinfoparser/property_info_parser.cpp index 84f8c29f8..89864dd78 100644 --- a/property_service/libpropertyinfoparser/property_info_parser.cpp +++ b/property_service/libpropertyinfoparser/property_info_parser.cpp | |||
@@ -87,6 +87,21 @@ bool TrieNode::FindChildForString(const char* name, uint32_t namelen, TrieNode* | |||
87 | return true; | 87 | return true; |
88 | } | 88 | } |
89 | 89 | ||
90 | void PropertyInfoArea::CheckPrefixMatch(const char* remaining_name, const TrieNode& trie_node, | ||
91 | uint32_t* context_index, uint32_t* schema_index) const { | ||
92 | const uint32_t remaining_name_size = strlen(remaining_name); | ||
93 | for (uint32_t i = 0; i < trie_node.num_prefixes(); ++i) { | ||
94 | auto prefix_len = trie_node.prefix(i)->namelen; | ||
95 | if (prefix_len > remaining_name_size) continue; | ||
96 | |||
97 | if (!strncmp(c_string(trie_node.prefix(i)->name_offset), remaining_name, prefix_len)) { | ||
98 | *context_index = trie_node.prefix(i)->context_index; | ||
99 | *schema_index = trie_node.prefix(i)->schema_index; | ||
100 | return; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
90 | void PropertyInfoArea::GetPropertyInfoIndexes(const char* name, uint32_t* context_index, | 105 | void PropertyInfoArea::GetPropertyInfoIndexes(const char* name, uint32_t* context_index, |
91 | uint32_t* schema_index) const { | 106 | uint32_t* schema_index) const { |
92 | uint32_t return_context_index = ~0u; | 107 | uint32_t return_context_index = ~0u; |
@@ -104,6 +119,10 @@ void PropertyInfoArea::GetPropertyInfoIndexes(const char* name, uint32_t* contex | |||
104 | return_schema_index = trie_node.schema_index(); | 119 | return_schema_index = trie_node.schema_index(); |
105 | } | 120 | } |
106 | 121 | ||
122 | // Check prefixes at this node. This comes after the node check since these prefixes are by | ||
123 | // definition longer than the node itself. | ||
124 | CheckPrefixMatch(remaining_name, trie_node, &return_context_index, &return_schema_index); | ||
125 | |||
107 | if (sep == nullptr) { | 126 | if (sep == nullptr) { |
108 | break; | 127 | break; |
109 | } | 128 | } |
@@ -128,18 +147,8 @@ void PropertyInfoArea::GetPropertyInfoIndexes(const char* name, uint32_t* contex | |||
128 | } | 147 | } |
129 | } | 148 | } |
130 | // Check prefix matches for prefixes not deliminated with '.' | 149 | // Check prefix matches for prefixes not deliminated with '.' |
131 | const uint32_t remaining_name_size = strlen(remaining_name); | 150 | CheckPrefixMatch(remaining_name, trie_node, &return_context_index, &return_schema_index); |
132 | for (uint32_t i = 0; i < trie_node.num_prefixes(); ++i) { | 151 | // Return previously found prefix match. |
133 | auto prefix_len = trie_node.prefix(i)->namelen; | ||
134 | if (prefix_len > remaining_name_size) continue; | ||
135 | |||
136 | if (!strncmp(c_string(trie_node.prefix(i)->name_offset), remaining_name, prefix_len)) { | ||
137 | if (context_index != nullptr) *context_index = trie_node.prefix(i)->context_index; | ||
138 | if (schema_index != nullptr) *schema_index = trie_node.prefix(i)->schema_index; | ||
139 | return; | ||
140 | } | ||
141 | } | ||
142 | // Return previously found '.' deliminated prefix match. | ||
143 | if (context_index != nullptr) *context_index = return_context_index; | 152 | if (context_index != nullptr) *context_index = return_context_index; |
144 | if (schema_index != nullptr) *schema_index = return_schema_index; | 153 | if (schema_index != nullptr) *schema_index = return_schema_index; |
145 | return; | 154 | return; |
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp index 5fa3463e1..b3fae268e 100644 --- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp +++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp | |||
@@ -763,5 +763,86 @@ TEST(propertyinfoserializer, RealProperties) { | |||
763 | } | 763 | } |
764 | } | 764 | } |
765 | 765 | ||
766 | TEST(propertyinfoserializer, GetPropertyInfo_prefix_without_dot) { | ||
767 | auto property_info = std::vector<PropertyInfoEntry>{ | ||
768 | {"persist.radio", "1st", "1st", false}, | ||
769 | {"persist.radio.something.else.here", "2nd", "2nd", false}, | ||
770 | }; | ||
771 | |||
772 | auto serialized_trie = std::string(); | ||
773 | auto build_trie_error = std::string(); | ||
774 | ASSERT_TRUE(BuildTrie(property_info, "default", "default", &serialized_trie, &build_trie_error)) | ||
775 | << build_trie_error; | ||
776 | |||
777 | auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data()); | ||
778 | |||
779 | const char* context; | ||
780 | const char* schema; | ||
781 | property_info_area->GetPropertyInfo("persist.radio", &context, &schema); | ||
782 | EXPECT_STREQ("1st", context); | ||
783 | EXPECT_STREQ("1st", schema); | ||
784 | property_info_area->GetPropertyInfo("persist.radio.subproperty", &context, &schema); | ||
785 | EXPECT_STREQ("1st", context); | ||
786 | EXPECT_STREQ("1st", schema); | ||
787 | property_info_area->GetPropertyInfo("persist.radiowords", &context, &schema); | ||
788 | EXPECT_STREQ("1st", context); | ||
789 | EXPECT_STREQ("1st", schema); | ||
790 | property_info_area->GetPropertyInfo("persist.radio.long.long.long.sub.property", &context, | ||
791 | &schema); | ||
792 | EXPECT_STREQ("1st", context); | ||
793 | EXPECT_STREQ("1st", schema); | ||
794 | property_info_area->GetPropertyInfo("persist.radio.something.else.here", &context, &schema); | ||
795 | EXPECT_STREQ("2nd", context); | ||
796 | EXPECT_STREQ("2nd", schema); | ||
797 | property_info_area->GetPropertyInfo("persist.radio.something.else.here2", &context, &schema); | ||
798 | EXPECT_STREQ("2nd", context); | ||
799 | EXPECT_STREQ("2nd", schema); | ||
800 | property_info_area->GetPropertyInfo("persist.radio.something.else.here.after", &context, &schema); | ||
801 | EXPECT_STREQ("2nd", context); | ||
802 | EXPECT_STREQ("2nd", schema); | ||
803 | property_info_area->GetPropertyInfo("persist.radio.something.else.nothere", &context, &schema); | ||
804 | EXPECT_STREQ("1st", context); | ||
805 | EXPECT_STREQ("1st", schema); | ||
806 | property_info_area->GetPropertyInfo("persist.radio.something.else", &context, &schema); | ||
807 | EXPECT_STREQ("1st", context); | ||
808 | EXPECT_STREQ("1st", schema); | ||
809 | } | ||
810 | |||
811 | TEST(propertyinfoserializer, GetPropertyInfo_prefix_with_dot_vs_without) { | ||
812 | auto property_info = std::vector<PropertyInfoEntry>{ | ||
813 | {"persist.", "1st", "1st", false}, | ||
814 | {"persist.radio", "2nd", "2nd", false}, | ||
815 | {"persist.radio.long.property.exact.match", "3rd", "3rd", true}, | ||
816 | }; | ||
817 | |||
818 | auto serialized_trie = std::string(); | ||
819 | auto build_trie_error = std::string(); | ||
820 | ASSERT_TRUE(BuildTrie(property_info, "default", "default", &serialized_trie, &build_trie_error)) | ||
821 | << build_trie_error; | ||
822 | |||
823 | auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data()); | ||
824 | |||
825 | const char* context; | ||
826 | const char* schema; | ||
827 | property_info_area->GetPropertyInfo("persist.notradio", &context, &schema); | ||
828 | EXPECT_STREQ("1st", context); | ||
829 | EXPECT_STREQ("1st", schema); | ||
830 | property_info_area->GetPropertyInfo("persist.radio", &context, &schema); | ||
831 | EXPECT_STREQ("2nd", context); | ||
832 | EXPECT_STREQ("2nd", schema); | ||
833 | property_info_area->GetPropertyInfo("persist.radio.subproperty", &context, &schema); | ||
834 | EXPECT_STREQ("2nd", context); | ||
835 | EXPECT_STREQ("2nd", schema); | ||
836 | property_info_area->GetPropertyInfo("persist.radiowords", &context, &schema); | ||
837 | EXPECT_STREQ("2nd", context); | ||
838 | EXPECT_STREQ("2nd", schema); | ||
839 | property_info_area->GetPropertyInfo("persist.radio.long.property.prefix.match", &context, &schema); | ||
840 | EXPECT_STREQ("2nd", context); | ||
841 | EXPECT_STREQ("2nd", schema); | ||
842 | property_info_area->GetPropertyInfo("persist.radio.long.property.exact.match", &context, &schema); | ||
843 | EXPECT_STREQ("3rd", context); | ||
844 | EXPECT_STREQ("3rd", schema); | ||
845 | } | ||
846 | |||
766 | } // namespace properties | 847 | } // namespace properties |
767 | } // namespace android | 848 | } // namespace android |