blob: faf919cd2302b2bbcbbd1961a68ab77110a24de1 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <fbl/alloc_checker.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/string.h>
#include <fbl/unique_ptr.h>
namespace fuzzing {
// |fuzzing::StringList| is a small wrapper class used to make C-style strings easy to store and
// manipulate in a |fbl::DoublyLinkedList|.
class StringList final {
public:
StringList();
StringList(const char* const* elements, size_t num_elements);
~StringList();
// Identical to |fbl::DoublyLinkedList<fbl::unique_ptr<StringElement>>::is_empty|.
bool is_empty() const;
// Identical to |fbl::DoublyLinkedList<fbl::unique_ptr<StringElement>>::size_slow|.
size_t length() const;
// These methods are similar to |fbl::DoublyLinkedList|'s, except that take raw C strings and
// abstract away the process of wrapping them in the |StringElement| structure defined below.
void push_front(const char* str);
void push_back(const char* str);
void push_front(const fbl::String& str) { return push_front(str.c_str()); }
void push_back(const fbl::String& str) { return push_back(str.c_str()); }
// These methods are similar to |fbl::DoublyLinkedList|'s, except that they apply a simple
// substring pattern match instead of taking a functor. Empty strings match everything, while
// null inputs leave the list unchanged.
// Keeps elements if they **CONTAIN** |substr|. Null strings leave the list unchanged.
void keep_if(const char* substr);
void keep_if(const fbl::String& substr) { return keep_if(substr.c_str()); }
// Keeps elements if they contain at least one element of |substrs|.
void keep_if_any(StringList* substrs);
// Keeps elements if they contain every element of |substrs|.
void keep_if_all(StringList* substrs);
// Removes elements if they exactly **MATCH** |match|. Null strings leave the list unchanged.
void erase_if(const char* match);
void erase_if(const fbl::String& match) { return erase_if(match.c_str()); }
// In place of iterators, this class provides |first| and |next| methods. The former resets the
// internal iterator to the beginning of the list, while the latter returns successive elements
// with each successive call until it reaches the end of the list and returns null. The list
// can be simply iterated by:
// for(const char *s = list.first(); s; s = list.next()) { ... }
const char* first();
const char* next();
// Like|fbl::DoublyLinkedList<fbl::unique_ptr<StringElement>>::clear|, but also resets the
// internal iterator.
void clear();
private:
DISALLOW_COPY_ASSIGN_AND_MOVE(StringList);
// |fuzzing::StringList::StringElement| is an internal intrusive container used to back the
// strings in the list.
struct StringElement final : public fbl::DoublyLinkedListable<fbl::unique_ptr<StringElement>> {
fbl::String str_;
};
// Implements |push_front| and |push_back| above, depending on the value of |front|.
void push(const char* str, bool front);
// The actual list elements, and an iterator to return the |next| one.
using List = fbl::DoublyLinkedList<fbl::unique_ptr<StringElement>>;
List elements_;
List::iterator iterator_;
};
} // namespace fuzzing