1 package org.robolectric.res.android; 2 3 // transliterated from 4 // https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/ResourceUtils.h 5 // and 6 // https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceUtils.cpp 7 class ResourceUtils { 8 // Extracts the package, type, and name from a string of the format: [[package:]type/]name 9 // Validation must be performed on each extracted piece. 10 // Returns false if there was a syntax error. 11 // boolean ExtractResourceName(String& str, String* out_package, String* out_type, 12 // String* out_entry); 13 fix_package_id(int resid, int package_id)14 static int fix_package_id(int resid, int package_id) { 15 return (resid & 0x00ffffff) | (package_id << 24); 16 } 17 get_package_id(int resid)18 static int get_package_id(int resid) { 19 // return static_cast<int>((resid >> 24) & 0x000000ff); 20 return resid >>> 24; 21 } 22 23 // The type ID is 1-based, so if the returned value is 0 it is invalid. get_type_id(int resid)24 static int get_type_id(int resid) { 25 // return static_cast<int>((resid >> 16) & 0x000000ff); 26 return (resid & 0x00FF0000) >>> 16; 27 } 28 get_entry_id(int resid)29 static int get_entry_id(int resid) { 30 // return static_cast<uint16_t>(resid & 0x0000ffff); 31 return (short) (resid & 0x0000FFFF); 32 } 33 is_internal_resid(int resid)34 static boolean is_internal_resid(int resid) { 35 return (resid & 0xffff0000) != 0 && (resid & 0x00ff0000) == 0; 36 } 37 is_valid_resid(int resid)38 static boolean is_valid_resid(int resid) { 39 return (resid & 0x00ff0000) != 0 && (resid & 0xff000000) != 0; 40 } 41 make_resid(byte package_id, byte type_id, short entry_id)42 static int make_resid(byte package_id, byte type_id, short entry_id) { 43 // return (static_cast<int>(package_id) << 24) | (static_cast<int>(type_id) << 16) | 44 // entry_id; 45 return package_id << 24 | type_id << 16 | entry_id; 46 } 47 48 // bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, StringPiece* 49 // out_type, 50 // StringPiece* out_entry) { 51 // *out_package = ""; 52 // *out_type = ""; 53 // bool has_package_separator = false; 54 // bool has_type_separator = false; 55 // const char* start = str.data(); 56 // const char* end = start + str.size(); 57 // const char* current = start; 58 // while (current != end) { 59 // if (out_type->size() == 0 && *current == '/') { 60 // has_type_separator = true; 61 // out_type->assign(start, current - start); 62 // start = current + 1; 63 // } else if (out_package->size() == 0 && *current == ':') { 64 // has_package_separator = true; 65 // out_package->assign(start, current - start); 66 // start = current + 1; 67 // } 68 // current++; 69 // } 70 // out_entry->assign(start, end - start); 71 // 72 // return !(has_package_separator && out_package->empty()) && 73 // !(has_type_separator && out_type->empty()); 74 // } 75 ExtractResourceName( String str, Ref<String> out_package, Ref<String> out_type, final Ref<String> out_entry)76 static boolean ExtractResourceName( 77 String str, Ref<String> out_package, Ref<String> out_type, final Ref<String> out_entry) { 78 out_package.set(""); 79 out_type.set(""); 80 boolean has_package_separator = false; 81 boolean has_type_separator = false; 82 int start = 0; 83 int end = start + str.length(); 84 int current = start; 85 while (current != end) { 86 if (out_type.get().length() == 0 && str.charAt(current) == '/') { 87 has_type_separator = true; 88 out_type.set(str.substring(start, current)); 89 start = current + 1; 90 } else if (out_package.get().length() == 0 && str.charAt(current) == ':') { 91 has_package_separator = true; 92 out_package.set(str.substring(start, current)); 93 start = current + 1; 94 } 95 current++; 96 } 97 out_entry.set(str.substring(start, end)); 98 99 return !(has_package_separator && out_package.get().isEmpty()) 100 && !(has_type_separator && out_type.get().isEmpty()); 101 } 102 } 103