1 // Copyright 2019 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 "url/android/parsed_android.h"
6 
7 #include <jni.h>
8 
9 #include "base/android/jni_android.h"
10 #include "url/gurl_jni_headers/Parsed_jni.h"
11 
12 using base::android::AttachCurrentThread;
13 using base::android::JavaRef;
14 using base::android::ScopedJavaLocalRef;
15 
16 namespace url {
17 
18 namespace {
19 
CreateJavaParsed(JNIEnv * env,const Parsed & parsed,const JavaRef<jobject> & inner)20 ScopedJavaLocalRef<jobject> CreateJavaParsed(JNIEnv* env,
21                                              const Parsed& parsed,
22                                              const JavaRef<jobject>& inner) {
23   static constexpr bool is_signed =
24       std::is_signed<decltype(parsed.scheme.begin)>::value;
25   static constexpr size_t offset_size = sizeof(parsed.scheme.begin);
26   static_assert((is_signed && sizeof(jint) >= offset_size) ||
27                     (!is_signed && sizeof(jint) > offset_size),
28                 "Java size offsets for Parsed Components must be large enough "
29                 "to store the full C++ offset.");
30   return Java_Parsed_Constructor(
31       env, parsed.scheme.begin, parsed.scheme.len, parsed.username.begin,
32       parsed.username.len, parsed.password.begin, parsed.password.len,
33       parsed.host.begin, parsed.host.len, parsed.port.begin, parsed.port.len,
34       parsed.path.begin, parsed.path.len, parsed.query.begin, parsed.query.len,
35       parsed.ref.begin, parsed.ref.len, parsed.potentially_dangling_markup,
36       inner);
37 }
38 
39 }  // namespace
40 
41 // static
InitFromParsed(JNIEnv * env,const Parsed & parsed)42 ScopedJavaLocalRef<jobject> ParsedAndroid::InitFromParsed(
43     JNIEnv* env,
44     const Parsed& parsed) {
45   ScopedJavaLocalRef<jobject> inner;
46   if (parsed.inner_parsed())
47     inner = CreateJavaParsed(env, *parsed.inner_parsed(), nullptr);
48   return CreateJavaParsed(env, parsed, inner);
49 }
50 
JNI_Parsed_CreateNative(JNIEnv * env,jint scheme_begin,jint scheme_length,jint username_begin,jint username_length,jint password_begin,jint password_length,jint host_begin,jint host_length,jint port_begin,jint port_length,jint path_begin,jint path_length,jint query_begin,jint query_length,jint ref_begin,jint ref_length,jboolean potentially_dangling_markup,jlong inner_parsed)51 static jlong JNI_Parsed_CreateNative(JNIEnv* env,
52                                      jint scheme_begin,
53                                      jint scheme_length,
54                                      jint username_begin,
55                                      jint username_length,
56                                      jint password_begin,
57                                      jint password_length,
58                                      jint host_begin,
59                                      jint host_length,
60                                      jint port_begin,
61                                      jint port_length,
62                                      jint path_begin,
63                                      jint path_length,
64                                      jint query_begin,
65                                      jint query_length,
66                                      jint ref_begin,
67                                      jint ref_length,
68                                      jboolean potentially_dangling_markup,
69                                      jlong inner_parsed) {
70   Parsed* parsed = new Parsed();
71   parsed->scheme.begin = scheme_begin;
72   parsed->scheme.len = scheme_length;
73   parsed->username.begin = username_begin;
74   parsed->username.len = username_length;
75   parsed->password.begin = password_begin;
76   parsed->password.len = password_length;
77   parsed->host.begin = host_begin;
78   parsed->host.len = host_length;
79   parsed->port.begin = port_begin;
80   parsed->port.len = port_length;
81   parsed->path.begin = path_begin;
82   parsed->path.len = path_length;
83   parsed->query.begin = query_begin;
84   parsed->query.len = query_length;
85   parsed->ref.begin = ref_begin;
86   parsed->ref.len = ref_length;
87   parsed->potentially_dangling_markup = potentially_dangling_markup;
88   Parsed* inner = reinterpret_cast<Parsed*>(inner_parsed);
89   if (inner) {
90     parsed->set_inner_parsed(*inner);
91     delete inner;
92   }
93   return reinterpret_cast<intptr_t>(parsed);
94 }
95 
96 }  // namespace url
97