1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <fbl/intrusive_wavl_tree.h> 8 #include <fbl/string.h> 9 #include <fbl/unique_ptr.h> 10 11 namespace fuzzing { 12 13 // |fuzzing::StringMap| is a small wrapper class used to make C-style strings easy to store and 14 // manipulate in a |fbl::WAVLTree|. 15 class StringMap final { 16 public: 17 StringMap(); 18 ~StringMap(); 19 20 // Identical to |fbl::WAVLTree<fbl::unique_ptr<StringElement>>::is_empty|. 21 bool is_empty() const; 22 23 // Identical to |fbl::WAVLTree<fbl::unique_ptr<StringElement>>::size|. 24 size_t size() const; 25 26 // In place of iterators, this class provides |first| and |next| methods. The former resets the 27 // internal iterator to the beginning of the map, while the latter returns successive key-value 28 // pairs via |out_key| and |out_value| with each successive call until it reaches the end of the 29 // map and returns null. The map can be simply iterated by: 30 // const char *key; 31 // const char *value; 32 // map.begin(); 33 // while(map.next(&key, &value)) { ... } 34 void begin(); 35 bool next(const char** out_key, const char** out_val); 36 bool next(fbl::String* out_key, fbl::String* out_val); 37 38 // Returns the value for the given |key|, or null if the key isn't found. 39 const char* get(const char* key) const; get(const fbl::String & key)40 const char* get(const fbl::String& key) const { return get(key.c_str()); } 41 42 // Associates the given |value| with the given |key|. |key| and |value| must not be null. 43 void set(const char* key, const char* val); set(const fbl::String & key,const fbl::String & val)44 void set(const fbl::String& key, const fbl::String& val) { set(key.c_str(), val.c_str()); } 45 46 // Removes any value associated with the given |key| and removes it from the map. 47 void erase(const char* key); erase(const fbl::String & key)48 void erase(const fbl::String& key) { erase(key.c_str()); }; 49 50 // Erases all keys. 51 void clear(); 52 53 private: 54 DISALLOW_COPY_ASSIGN_AND_MOVE(StringMap); 55 56 // |fuzzing::StringMap::StringElement| is an internal intrusive container used to back the 57 // strings in the list. 58 struct StringElement final : public fbl::WAVLTreeContainable<fbl::unique_ptr<StringElement>> { 59 fbl::String key; 60 fbl::String val; 61 }; 62 63 // |fuzzing::StringMap::KeyTraits| is used to sort keys lexicographically. 64 struct KeyTraits { GetKeyKeyTraits65 static const char* GetKey(const StringElement& element) { return element.key.c_str(); } LessThanKeyTraits66 static bool LessThan(const char* key1, const char* key2) { return strcmp(key1, key2) < 0; } EqualToKeyTraits67 static bool EqualTo(const char* key1, const char* key2) { return strcmp(key1, key2) == 0; } 68 }; 69 70 // The actual map pairs, and an iterator to return the |next| one. 71 using Map = fbl::WAVLTree<const char*, fbl::unique_ptr<StringElement>, KeyTraits>; 72 Map elements_; 73 Map::iterator iterator_; 74 }; 75 76 } // namespace fuzzing 77