1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/android/java/java_type.h" 6 7 #include "base/logging.h" 8 #include "base/strings/string_util.h" // For ReplaceSubstringsAfterOffset 9 10 namespace content { 11 namespace { 12 13 // Array component type names are similar to JNI type names, except for using 14 // dots as namespace separators in class names. CreateFromArrayComponentTypeName(const std::string & type_name)15scoped_ptr<JavaType> CreateFromArrayComponentTypeName( 16 const std::string& type_name) { 17 scoped_ptr<JavaType> result(new JavaType()); 18 DCHECK(!type_name.empty()); 19 switch (type_name[0]) { 20 case 'Z': 21 result->type = JavaType::TypeBoolean; 22 break; 23 case 'B': 24 result->type = JavaType::TypeByte; 25 break; 26 case 'C': 27 result->type = JavaType::TypeChar; 28 break; 29 case 'S': 30 result->type = JavaType::TypeShort; 31 break; 32 case 'I': 33 result->type = JavaType::TypeInt; 34 break; 35 case 'J': 36 result->type = JavaType::TypeLong; 37 break; 38 case 'F': 39 result->type = JavaType::TypeFloat; 40 break; 41 case 'D': 42 result->type = JavaType::TypeDouble; 43 break; 44 case '[': 45 result->type = JavaType::TypeArray; 46 result->inner_type = 47 CreateFromArrayComponentTypeName(type_name.substr(1)); 48 break; 49 case 'L': 50 if (type_name == "Ljava.lang.String;") { 51 result->type = JavaType::TypeString; 52 result->class_jni_name = "java/lang/String"; 53 } else { 54 result->type = JavaType::TypeObject; 55 result->class_jni_name = type_name.substr(1, type_name.length() - 2); 56 ReplaceSubstringsAfterOffset(&result->class_jni_name, 0, ".", "/"); 57 } 58 break; 59 default: 60 // Includes void (V). 61 NOTREACHED(); 62 } 63 return result.Pass(); 64 } 65 66 } // namespace 67 JavaType()68JavaType::JavaType() { 69 } 70 JavaType(const JavaType & other)71JavaType::JavaType(const JavaType& other) { 72 *this = other; 73 } 74 ~JavaType()75JavaType::~JavaType() { 76 } 77 operator =(const JavaType & other)78JavaType& JavaType::operator=(const JavaType& other) { 79 if (this == &other) 80 return *this; 81 type = other.type; 82 if (other.inner_type) { 83 DCHECK_EQ(JavaType::TypeArray, type); 84 inner_type.reset(new JavaType(*other.inner_type)); 85 } else { 86 inner_type.reset(); 87 } 88 class_jni_name = other.class_jni_name; 89 return *this; 90 } 91 92 // static CreateFromBinaryName(const std::string & binary_name)93JavaType JavaType::CreateFromBinaryName(const std::string& binary_name) { 94 JavaType result; 95 DCHECK(!binary_name.empty()); 96 if (binary_name == "boolean") { 97 result.type = JavaType::TypeBoolean; 98 } else if (binary_name == "byte") { 99 result.type = JavaType::TypeByte; 100 } else if (binary_name == "char") { 101 result.type = JavaType::TypeChar; 102 } else if (binary_name == "short") { 103 result.type = JavaType::TypeShort; 104 } else if (binary_name == "int") { 105 result.type = JavaType::TypeInt; 106 } else if (binary_name == "long") { 107 result.type = JavaType::TypeLong; 108 } else if (binary_name == "float") { 109 result.type = JavaType::TypeFloat; 110 } else if (binary_name == "double") { 111 result.type = JavaType::TypeDouble; 112 } else if (binary_name == "void") { 113 result.type = JavaType::TypeVoid; 114 } else if (binary_name[0] == '[') { 115 result.type = JavaType::TypeArray; 116 result.inner_type = CreateFromArrayComponentTypeName(binary_name.substr(1)); 117 } else if (binary_name == "java.lang.String") { 118 result.type = JavaType::TypeString; 119 result.class_jni_name = "java/lang/String"; 120 } else { 121 result.type = JavaType::TypeObject; 122 result.class_jni_name = binary_name; 123 ReplaceSubstringsAfterOffset(&result.class_jni_name, 0, ".", "/"); 124 } 125 return result; 126 } 127 JNIName() const128std::string JavaType::JNIName() const { 129 switch (type) { 130 case JavaType::TypeBoolean: 131 return "Z"; 132 case JavaType::TypeByte: 133 return "B"; 134 case JavaType::TypeChar: 135 return "C"; 136 case JavaType::TypeShort: 137 return "S"; 138 case JavaType::TypeInt: 139 return "I"; 140 case JavaType::TypeLong: 141 return "J"; 142 case JavaType::TypeFloat: 143 return "F"; 144 case JavaType::TypeDouble: 145 return "D"; 146 case JavaType::TypeVoid: 147 return "V"; 148 case JavaType::TypeArray: 149 return "[" + inner_type->JNISignature(); 150 case JavaType::TypeString: 151 case JavaType::TypeObject: 152 return class_jni_name; 153 } 154 NOTREACHED(); 155 return std::string(); 156 } 157 JNISignature() const158std::string JavaType::JNISignature() const { 159 if (type == JavaType::TypeString || type == JavaType::TypeObject) 160 return "L" + JNIName() + ";"; 161 else 162 return JNIName(); 163 } 164 165 } // namespace content 166