Home | History | Annotate | Download | only in libpropertyinfoserializer
      1 //
      2 // Copyright (C) 2017 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef PROPERTY_INFO_SERIALIZER_TRIE_NODE_ARENA_H
     18 #define PROPERTY_INFO_SERIALIZER_TRIE_NODE_ARENA_H
     19 
     20 #include <string>
     21 #include <vector>
     22 
     23 namespace android {
     24 namespace properties {
     25 
     26 template <typename T>
     27 class ArenaObjectPointer {
     28  public:
     29   ArenaObjectPointer(std::string& arena_data, uint32_t offset)
     30       : arena_data_(arena_data), offset_(offset) {}
     31 
     32   T* operator->() { return reinterpret_cast<T*>(arena_data_.data() + offset_); }
     33 
     34  private:
     35   std::string& arena_data_;
     36   uint32_t offset_;
     37 };
     38 
     39 class TrieNodeArena {
     40  public:
     41   TrieNodeArena() : current_data_pointer_(0) {}
     42 
     43   // We can't return pointers to objects since data_ may move when reallocated, thus invalidating
     44   // any pointers.  Therefore we return an ArenaObjectPointer, which always accesses elements via
     45   // data_ + offset.
     46   template <typename T>
     47   ArenaObjectPointer<T> AllocateObject(uint32_t* return_offset) {
     48     uint32_t offset;
     49     AllocateData(sizeof(T), &offset);
     50     if (return_offset) *return_offset = offset;
     51     return ArenaObjectPointer<T>(data_, offset);
     52   }
     53 
     54   uint32_t AllocateUint32Array(int length) {
     55     uint32_t offset;
     56     AllocateData(sizeof(uint32_t) * length, &offset);
     57     return offset;
     58   }
     59 
     60   uint32_t* uint32_array(uint32_t offset) {
     61     return reinterpret_cast<uint32_t*>(data_.data() + offset);
     62   }
     63 
     64   uint32_t AllocateAndWriteString(const std::string& string) {
     65     uint32_t offset;
     66     char* data = static_cast<char*>(AllocateData(string.size() + 1, &offset));
     67     strcpy(data, string.c_str());
     68     return offset;
     69   }
     70 
     71   void AllocateAndWriteUint32(uint32_t value) {
     72     auto location = static_cast<uint32_t*>(AllocateData(sizeof(uint32_t), nullptr));
     73     *location = value;
     74   }
     75 
     76   void* AllocateData(size_t size, uint32_t* offset) {
     77     size_t aligned_size = size + (sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1);
     78 
     79     if (current_data_pointer_ + aligned_size > data_.size()) {
     80       auto new_size = (current_data_pointer_ + aligned_size + data_.size()) * 2;
     81       data_.resize(new_size, '\0');
     82     }
     83     if (offset) *offset = current_data_pointer_;
     84 
     85     uint32_t return_offset = current_data_pointer_;
     86     current_data_pointer_ += aligned_size;
     87     return &data_[0] + return_offset;
     88   }
     89 
     90   uint32_t size() const { return current_data_pointer_; }
     91 
     92   const std::string& data() const { return data_; }
     93 
     94   std::string truncated_data() const {
     95     auto result = data_;
     96     result.resize(current_data_pointer_);
     97     return result;
     98   }
     99 
    100  private:
    101   std::string data_;
    102   uint32_t current_data_pointer_;
    103 };
    104 
    105 }  // namespace properties
    106 }  // namespace android
    107 
    108 #endif
    109