File indexing completed on 2024-11-24 04:54:36

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 TEST_EXAMPLE_DATA_H_
0011 #define TEST_EXAMPLE_DATA_H_
0012 
0013 #include <math.h>
0014 #include <string.h>
0015 #include "../hashFn.h"
0016 
0017 static HashFn h(19);
0018 
0019 class ExampleData {
0020  public:
0021   uint64_t GetHash() const {
0022     return h(data_, data_len_);
0023   }
0024 
0025   ~ExampleData() {
0026     if (data_ && !borrowed_memory_) {
0027       delete[] data_;
0028     }
0029   }
0030   explicit ExampleData(const char *data) {
0031     data_len_ = static_cast<uint32_t>(strlen(data)) + 1;
0032     data_ = new char[data_len_];
0033     memcpy(data_, data, data_len_);
0034     borrowed_memory_ = false;
0035     extra_data_ = 0;
0036   }
0037 
0038   ExampleData(const char *data, int data_len) {
0039     data_len_ = data_len;
0040     data_ = new char[data_len];
0041     memcpy(data_, data, data_len);
0042     borrowed_memory_ = false;
0043     extra_data_ = 0;
0044   }
0045 
0046   ExampleData(const ExampleData &rhs) {
0047     data_len_ = rhs.data_len_;
0048     data_ = new char[data_len_];
0049     memcpy(data_, rhs.data_, data_len_);
0050     borrowed_memory_ = rhs.borrowed_memory_;
0051     extra_data_ = rhs.extra_data_;
0052   }
0053 
0054   ExampleData() : extra_data_(0), data_(nullptr), data_len_(0),
0055     borrowed_memory_(false) {
0056   }
0057 
0058   bool operator==(const ExampleData &rhs) const {
0059     if (data_len_ != rhs.data_len_) {
0060       return false;
0061     }
0062 
0063     return !memcmp(data_, rhs.data_, data_len_);
0064   }
0065 
0066   bool operator!=(const ExampleData &rhs) const {
0067     return !(*this == rhs);
0068   }
0069 
0070   void Update(const ExampleData &other) {
0071     extra_data_ = extra_data_ | other.extra_data_;
0072   }
0073 
0074   uint32_t Serialize(char *buffer) {
0075     uint32_t total_size = 0;
0076     char sz[32];
0077     uint32_t data_len_size = 1 + snprintf(sz, sizeof(sz), "%x", data_len_);
0078     if (buffer) {
0079       memcpy(buffer + total_size, sz, data_len_size);
0080     }
0081     total_size += data_len_size;
0082     if (buffer) {
0083       memcpy(buffer + total_size, data_, data_len_);
0084     }
0085     total_size += data_len_;
0086 
0087     if (buffer) {
0088       buffer[total_size] = extra_data_;
0089     }
0090     total_size++;
0091 
0092     return total_size;
0093   }
0094 
0095   uint32_t Deserialize(char *buffer, uint32_t buffer_size) {
0096     data_len_ = 0;
0097     if (!HasNewlineBefore(buffer, buffer_size)) {
0098       return 0;
0099     }
0100     sscanf(buffer, "%x", &data_len_);
0101     uint32_t consumed = static_cast<uint32_t>(strlen(buffer)) + 1;
0102     if (consumed + data_len_ >= buffer_size) {
0103       return 0;
0104     }
0105     data_ = buffer + consumed;
0106     borrowed_memory_ = true;
0107     memcpy(data_, buffer + consumed, data_len_);
0108     consumed += data_len_;
0109 
0110     extra_data_ = buffer[consumed];
0111     consumed++;
0112 
0113     return consumed;
0114   }
0115 
0116   // Just an example which is not used in comparisons but
0117   // is used for serializing / deserializing, showing the
0118   // need for find vs exists.
0119   char extra_data_;
0120 
0121  private:
0122   bool HasNewlineBefore(char *buffer, uint32_t buffer_size) {
0123     char *p = buffer;
0124     for (uint32_t i = 0; i < buffer_size; ++i) {
0125       if (*p == '\0')
0126         return true;
0127       p++;
0128     }
0129     return false;
0130   }
0131 
0132   char *data_;
0133   uint32_t data_len_;
0134   bool borrowed_memory_;
0135 };
0136 
0137 #endif  // TEST_EXAMPLE_DATA_H_