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