• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)15 scoped_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()68 JavaType::JavaType() {
69 }
70 
JavaType(const JavaType & other)71 JavaType::JavaType(const JavaType& other) {
72   *this = other;
73 }
74 
~JavaType()75 JavaType::~JavaType() {
76 }
77 
operator =(const JavaType & other)78 JavaType& 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)93 JavaType 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() const128 std::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() const158 std::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