OSDN Git Service

Merge \\"Remove duplicate the from AppBar documentation.\\" into mnc-io-docs am:...
[android-x86/frameworks-base.git] / libs / androidfw / TypeWrappers.cpp
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 #include <androidfw/TypeWrappers.h>
18
19 namespace android {
20
21 TypeVariant::iterator& TypeVariant::iterator::operator++() {
22     mIndex++;
23     if (mIndex > dtohl(mTypeVariant->data->entryCount)) {
24         mIndex = dtohl(mTypeVariant->data->entryCount);
25     }
26     return *this;
27 }
28
29 const ResTable_entry* TypeVariant::iterator::operator*() const {
30     const ResTable_type* type = mTypeVariant->data;
31     const uint32_t entryCount = dtohl(type->entryCount);
32     if (mIndex >= entryCount) {
33         return NULL;
34     }
35
36     const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(type)
37             + dtohl(type->header.size);
38     const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(
39             reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));
40     if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount) > containerEnd) {
41         ALOGE("Type's entry indices extend beyond its boundaries");
42         return NULL;
43     }
44
45     const uint32_t entryOffset = dtohl(entryIndices[mIndex]);
46     if (entryOffset == ResTable_type::NO_ENTRY) {
47         return NULL;
48     }
49
50     if ((entryOffset & 0x3) != 0) {
51         ALOGE("Index %u points to entry with unaligned offset 0x%08x", mIndex, entryOffset);
52         return NULL;
53     }
54
55     const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>(
56             reinterpret_cast<uintptr_t>(type) + dtohl(type->entriesStart) + entryOffset);
57     if (reinterpret_cast<uintptr_t>(entry) > containerEnd - sizeof(*entry)) {
58         ALOGE("Entry offset at index %u points outside the Type's boundaries", mIndex);
59         return NULL;
60     } else if (reinterpret_cast<uintptr_t>(entry) + dtohs(entry->size) > containerEnd) {
61         ALOGE("Entry at index %u extends beyond Type's boundaries", mIndex);
62         return NULL;
63     } else if (dtohs(entry->size) < sizeof(*entry)) {
64         ALOGE("Entry at index %u is too small (%u)", mIndex, dtohs(entry->size));
65         return NULL;
66     }
67     return entry;
68 }
69
70 } // namespace android