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