File indexing completed on 2024-11-17 04:55:17

0001 /*
0002     SPDX-License-Identifier: MPL-2.0
0003 */
0004 
0005 /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license.
0006  * This Source Code Form is subject to the terms of the Mozilla Public
0007  * License, v. 2.0. If a copy of the MPL was not distributed with this
0008  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
0009 
0010 #ifndef COSMETIC_FILTER_H_
0011 #define COSMETIC_FILTER_H_
0012 #define UNUSED(x) ( (void)(x) )
0013 
0014 #include <math.h>
0015 #include <string.h>
0016 #include "./hash_set.h"
0017 
0018 class CosmeticFilter {
0019  public:
0020   uint64_t hash() const;
0021   uint64_t GetHash() const {
0022     return hash();
0023   }
0024 
0025   ~CosmeticFilter() {
0026     if (data) {
0027       delete[] data;
0028     }
0029   }
0030   explicit CosmeticFilter(const char *data) {
0031     size_t len = strlen(data) + 1;
0032     this->data = new char[len];
0033     snprintf(this->data, len, "%s", data);
0034   }
0035 
0036   CosmeticFilter(const CosmeticFilter &rhs) {
0037     data = new char[strlen(rhs.data) + 1];
0038     memcpy(data, rhs.data, strlen(rhs.data) + 1);
0039   }
0040 
0041   CosmeticFilter() : data(nullptr) {
0042   }
0043 
0044   bool operator==(const CosmeticFilter &rhs) const {
0045     return !strcmp(data, rhs.data);
0046   }
0047 
0048   bool operator!=(const CosmeticFilter &rhs) const {
0049     return !(*this == rhs);
0050   }
0051 
0052   // Nothing needs to be updated for multiple adds
0053   void Update(const CosmeticFilter &) {}
0054 
0055   uint32_t Serialize(char *buffer) {
0056     if (buffer) {
0057       memcpy(buffer, data, strlen(data) + 1);
0058     }
0059     return static_cast<uint32_t>(strlen(data)) + 1;
0060   }
0061 
0062   uint32_t Deserialize(char *buffer, uint32_t bufferSize) {
0063     UNUSED(bufferSize);
0064     int len = static_cast<int>(strlen(buffer));
0065     data = new char[len + 1];
0066     memcpy(data, buffer, len + 1);
0067     return len + 1;
0068   }
0069 
0070   char *data;
0071 };
0072 
0073 class CosmeticFilterHashSet : public HashSet<CosmeticFilter> {
0074  public:
0075   CosmeticFilterHashSet() : HashSet<CosmeticFilter>(1000, false) {
0076   }
0077   char * toStylesheet(uint32_t *len) {
0078     *len = fillStylesheetBuffer(nullptr);
0079     char *buffer = new char[*len];
0080     memset(buffer, 0, *len);
0081     fillStylesheetBuffer(buffer);
0082     return buffer;
0083   }
0084 
0085  private:
0086   uint32_t fillStylesheetBuffer(char *buffer) {
0087     uint32_t len = 0;
0088     for (uint32_t bucketIndex = 0; bucketIndex < bucket_count_; bucketIndex++) {
0089       HashItem<CosmeticFilter> *hashItem = buckets_[bucketIndex];
0090       len = 0;
0091       while (hashItem) {
0092         CosmeticFilter *cosmeticFilter = hashItem->hash_item_storage_;
0093         // [cosmeticFilter],[space]
0094         int cosmeticFilterLen =
0095           static_cast<int>(strlen(cosmeticFilter->data));
0096         if (buffer) {
0097           memcpy(buffer + len, cosmeticFilter->data, cosmeticFilterLen);
0098         }
0099         len += cosmeticFilterLen;
0100         if (hashItem->next_) {
0101           if (buffer) {
0102             memcpy(buffer + len, ", ", 2);
0103           }
0104           len += 2;
0105         }
0106         hashItem = hashItem->next_;
0107       }
0108     }
0109     return len;
0110   }
0111 };
0112 
0113 #endif  // COSMETIC_FILTER_H_