Home | History | Annotate | Download | only in androidfw
      1 /*
      2  * Copyright (C) 2014 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 __BYTE_BUCKET_ARRAY_H
     18 #define __BYTE_BUCKET_ARRAY_H
     19 
     20 #include <utils/Log.h>
     21 #include <stdint.h>
     22 #include <string.h>
     23 
     24 namespace android {
     25 
     26 /**
     27  * Stores a sparsely populated array. Has a fixed size of 256
     28  * (number of entries that a byte can represent).
     29  */
     30 template<typename T>
     31 class ByteBucketArray {
     32 public:
     33     ByteBucketArray() : mDefault() {
     34         memset(mBuckets, 0, sizeof(mBuckets));
     35     }
     36 
     37     ~ByteBucketArray() {
     38         for (size_t i = 0; i < NUM_BUCKETS; i++) {
     39             if (mBuckets[i] != NULL) {
     40                 delete [] mBuckets[i];
     41             }
     42         }
     43         memset(mBuckets, 0, sizeof(mBuckets));
     44     }
     45 
     46     inline size_t size() const {
     47         return NUM_BUCKETS * BUCKET_SIZE;
     48     }
     49 
     50     inline const T& get(size_t index) const {
     51         return (*this)[index];
     52     }
     53 
     54     const T& operator[](size_t index) const {
     55         if (index >= size()) {
     56             return mDefault;
     57         }
     58 
     59         uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;
     60         T* bucket = mBuckets[bucketIndex];
     61         if (bucket == NULL) {
     62             return mDefault;
     63         }
     64         return bucket[0x0f & static_cast<uint8_t>(index)];
     65     }
     66 
     67     T& editItemAt(size_t index) {
     68         ALOG_ASSERT(index < size(), "ByteBucketArray.getOrCreate(index=%u) with size=%u",
     69                 (uint32_t) index, (uint32_t) size());
     70 
     71         uint8_t bucketIndex = static_cast<uint8_t>(index) >> 4;
     72         T* bucket = mBuckets[bucketIndex];
     73         if (bucket == NULL) {
     74             bucket = mBuckets[bucketIndex] = new T[BUCKET_SIZE]();
     75         }
     76         return bucket[0x0f & static_cast<uint8_t>(index)];
     77     }
     78 
     79     bool set(size_t index, const T& value) {
     80         if (index >= size()) {
     81             return false;
     82         }
     83 
     84         editItemAt(index) = value;
     85         return true;
     86     }
     87 
     88 private:
     89     enum { NUM_BUCKETS = 16, BUCKET_SIZE = 16 };
     90 
     91     T*  mBuckets[NUM_BUCKETS];
     92     T   mDefault;
     93 };
     94 
     95 } // namespace android
     96 
     97 #endif // __BYTE_BUCKET_ARRAY_H
     98