static bool equal(const TypeVector& l, const TypeVector& r) { if (&l == &r) return true; if (l.size() != r.size()) return false; TypeVector::const_iterator itl = l.begin(), itr = r.begin(), endl = l.end(); while (itl != endl) { if (!(*itl)->equals(*itr)) return false; ++itl; ++itr; } return true; }
// The scalar cases in llsd_matches() use this helper. In most cases, we can // accept not only the exact type specified in the prototype, but also other // types convertible to the expected type. That implies looping over an array // of such types. If the actual type doesn't match any of them, we want to // provide a list of acceptable conversions as well as the exact type, e.g.: // "Integer (or Boolean, Real, String) required instead of UUID". Both the // implementation and the calling logic are simplified by separating out the // expected type from the convertible types. static std::string match_types(LLSD::Type expect, // prototype.type() const TypeVector& accept, // types convertible to that type LLSD::Type actual, // type we're checking const std::string& pfx) // as for llsd_matches { // Trivial case: if the actual type is exactly what we expect, we're good. if (actual == expect) return ""; // For the rest of the logic, build up a suitable error string as we go so // we only have to make a single pass over the list of acceptable types. // If we detect success along the way, we'll simply discard the partial // error string. std::ostringstream out; out << colon(pfx) << sTypes.lookup(expect); // If there are any convertible types, append that list. if (! accept.empty()) { out << " ("; const char* sep = "or "; for (TypeVector::const_iterator ai(accept.begin()), aend(accept.end()); ai != aend; ++ai, sep = ", ") { // Don't forget to return success if we match any of those types... if (actual == *ai) return ""; out << sep << sTypes.lookup(*ai); } out << ')'; } // If we got this far, it's because 'actual' was not one of the acceptable // types, so we must return an error. 'out' already contains colon(pfx) // and the formatted list of acceptable types, so just append the mismatch // phrase and the actual type. out << op << sTypes.lookup(actual); return out.str(); }
void RenameClassesPass::run_pass(DexClassesVector& dexen, ConfigFiles& cfg) { auto scope = build_class_scope(dexen); std::unordered_set<const DexType*> untouchables; for (const auto& base : m_untouchable_hierarchies) { auto base_type = DexType::get_type(base.c_str()); if (base_type != nullptr) { untouchables.insert(base_type); TypeVector children; get_all_children(base_type, children); untouchables.insert(children.begin(), children.end()); } } rename_classes( scope, m_pre_filter_whitelist, m_post_filter_whitelist, m_path, untouchables, cfg.get_proguard_map(), m_rename_annotations); TRACE(RENAME, 1, "renamed classes: %d anon classes, %d from single char patterns, " "%d from multi char patterns\n", match_inner, match_short, match_long); TRACE(RENAME, 1, "String savings, at least %d bytes \n", base_strings_size - ren_strings_size); }
VVector fill(const Type init_val) { std::fill(x.begin(), x.end(), init_val); return *this; }