1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "libzfs_jni_util.h" 30 #include <strings.h> 31 32 /* 33 * Package-private functions 34 */ 35 36 /*PRINTFLIKE2*/ 37 void 38 zjni_throw_exception(JNIEnv *env, const char *fmt, ...) 39 { 40 char error[1024]; 41 va_list ap; 42 jclass class_UnsupportedOperationException; 43 44 va_start(ap, fmt); 45 (void) vsnprintf(error, sizeof (error), fmt, ap); 46 va_end(ap); 47 48 class_UnsupportedOperationException = 49 (*env)->FindClass(env, "java/lang/UnsupportedOperationException"); 50 51 (*env)->ThrowNew(env, class_UnsupportedOperationException, error); 52 } 53 54 jstring 55 zjni_get_matched_string(JNIEnv *env, char *name, regmatch_t *match) 56 { 57 jstring stringUTF = NULL; 58 if (match->rm_so != -1 && match->rm_eo != -1) { 59 char *end = name + match->rm_eo; 60 char tmp = *end; 61 *end = '\0'; 62 stringUTF = (*env)->NewStringUTF(env, name + match->rm_so); 63 *end = tmp; 64 } 65 return (stringUTF); 66 } 67 68 void 69 zjni_get_dataset_from_snapshot(const char *snapshot, char *dataset, 70 size_t len) 71 { 72 char *at; 73 (void) strncpy(dataset, snapshot, len); 74 at = strchr(dataset, '@'); 75 if (at != NULL) { 76 *at = '\0'; 77 } 78 } 79 80 /* Convert a zjni_Collection to a (Java) array */ 81 jobjectArray 82 zjni_Collection_to_array(JNIEnv *env, zjni_Collection_t *list, char *class) 83 { 84 /* Get size of zjni_Collection */ 85 jint length = (*env)->CallIntMethod( 86 env, ((zjni_Object_t *)list)->object, 87 ((zjni_Collection_t *)list)->method_size); 88 89 /* Create array to hold elements of list */ 90 jobjectArray array = (*env)->NewObjectArray( 91 env, length, (*env)->FindClass(env, class), NULL); 92 93 /* Copy list elements to array */ 94 return (*env)->CallObjectMethod(env, ((zjni_Object_t *)list)->object, 95 ((zjni_Collection_t *)list)->method_toArray, array); 96 } 97 98 /* Create a zjni_Collection */ 99 void 100 new_Collection(JNIEnv *env, zjni_Collection_t *collection) 101 { 102 zjni_Object_t *object = (zjni_Object_t *)collection; 103 104 collection->method_add = (*env)->GetMethodID( 105 env, object->class, "add", "(Ljava/lang/Object;)Z"); 106 107 collection->method_size = 108 (*env)->GetMethodID(env, object->class, "size", "()I"); 109 110 collection->method_toArray = 111 (*env)->GetMethodID(env, object->class, "toArray", 112 "([Ljava/lang/Object;)[Ljava/lang/Object;"); 113 } 114 115 /* Create an zjni_ArrayList */ 116 void 117 zjni_new_ArrayList(JNIEnv *env, zjni_ArrayList_t *list) 118 { 119 zjni_Object_t *object = (zjni_Object_t *)list; 120 121 if (object->object == NULL) { 122 object->class = (*env)->FindClass(env, "java/util/ArrayList"); 123 124 object->constructor = 125 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 126 127 object->object = (*env)->NewObject( 128 env, object->class, object->constructor); 129 } 130 131 new_Collection(env, (zjni_Collection_t *)list); 132 } 133 134 /* Create an zjni_DatasetSet */ 135 void 136 zjni_new_DatasetSet(JNIEnv *env, zjni_DatasetSet_t *list) 137 { 138 zjni_Object_t *object = (zjni_Object_t *)list; 139 140 if (object->object == NULL) { 141 object->class = (*env)->FindClass( 142 env, "com/sun/zfs/common/util/DatasetSet"); 143 144 object->constructor = 145 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 146 147 object->object = (*env)->NewObject( 148 env, object->class, object->constructor); 149 } 150 151 new_Collection(env, (zjni_Collection_t *)list); 152 } 153 154 jobject 155 zjni_int_to_boolean(JNIEnv *env, uint64_t value) 156 { 157 jclass class_Boolean = (*env)->FindClass( 158 env, "java/lang/Boolean"); 159 160 jfieldID id = (*env)->GetStaticFieldID(env, class_Boolean, 161 value ? "TRUE" : "FALSE", "Ljava/lang/Boolean;"); 162 163 return (*env)->GetStaticObjectField(env, class_Boolean, id); 164 } 165 166 jobject 167 zjni_str_to_long(JNIEnv *env, char *str) 168 { 169 jobject value = NULL; 170 jclass class_Long = (*env)->FindClass(env, "java/lang/Long"); 171 172 jmethodID method_valueOf = (*env)->GetStaticMethodID(env, 173 class_Long, "valueOf", "(Ljava/lang/String;)Ljava/lang/Long;"); 174 175 jstring utf = (*env)->NewStringUTF(env, str); 176 177 /* May throw a NumberFormatException */ 178 value = (*env)->CallStaticObjectMethod( 179 env, class_Long, method_valueOf, utf); 180 181 return (value); 182 } 183 184 jobject 185 zjni_long_to_Long(JNIEnv *env, uint64_t value) 186 { 187 jclass class_Long = (*env)->FindClass(env, "java/lang/Long"); 188 189 jmethodID constructor_Long = (*env)->GetMethodID( 190 env, class_Long, "<init>", "(J)V"); 191 192 jobject obj = (*env)->NewObject( 193 env, class_Long, constructor_Long, value); 194 195 return (obj); 196 } 197 198 jobject 199 zjni_str_to_date(JNIEnv *env, char *str) 200 { 201 jobject date = NULL; 202 jclass class_Long = (*env)->FindClass(env, "java/lang/Long"); 203 204 jmethodID method_parseLong = (*env)->GetStaticMethodID(env, 205 class_Long, "parseLong", "(Ljava/lang/String;)J"); 206 207 jstring utf = (*env)->NewStringUTF(env, str); 208 if (utf != NULL) { 209 210 /* May throw a NumberFormatException */ 211 jlong time = (*env)->CallStaticLongMethod( 212 env, class_Long, method_parseLong, utf); 213 214 if ((*env)->ExceptionOccurred(env) == NULL) { 215 216 jclass class_Date = (*env)->FindClass(env, 217 "java/util/Date"); 218 219 jmethodID constructor_Date = (*env)->GetMethodID( 220 env, class_Date, "<init>", "(J)V"); 221 222 /* Date constructor takes epoch milliseconds */ 223 time *= 1000; 224 225 date = (*env)->NewObject( 226 env, class_Date, constructor_Date, time); 227 } 228 } 229 230 return (date); 231 } 232 233 jobjectArray 234 zjni_string_array_to_String_array(JNIEnv *env, char **array, int n) 235 { 236 int i; 237 jclass class_String = (*env)->FindClass(env, "java/lang/String"); 238 jobjectArray jarray = 239 (*env)->NewObjectArray(env, n, class_String, NULL); 240 241 for (i = 0; i < n; i++) { 242 jstring elementUTF = (*env)->NewStringUTF(env, array[i]); 243 (void) (*env)->SetObjectArrayElement(env, jarray, i, 244 elementUTF); 245 } 246 247 return (jarray); 248 } 249 250 /* 251 * Counts the number of elements in the given NULL-terminated array. 252 * Does not include the terminating NULL in the count. 253 */ 254 int 255 zjni_count_elements(void **array) 256 { 257 int i = 0; 258 if (array != NULL) { 259 for (; array[i] != NULL; i++); 260 } 261 return (i); 262 } 263 264 /* 265 * Get a handle to the next nvpair with the specified name and data 266 * type in the list following the given nvpair. 267 * 268 * This function is needed because the nvlist_lookup_* routines can 269 * only be used with nvlists allocated with NV_UNIQUE_NAME or 270 * NV_UNIQUE_NAME_TYPE, ie. lists of unique name/value pairs. 271 * 272 * Some variation of this function will likely appear in the libnvpair 273 * library per 4981923. 274 * 275 * @param nvl 276 * the nvlist_t to search 277 * 278 * @param name 279 * the string key for the pair to find in the list, or 280 * NULL to match any name 281 * 282 * @param type 283 * the data type for the pair to find in the list, or 284 * DATA_TYPE_UNKNOWN to match any type 285 * 286 * @param nvp 287 * the pair to search from in the list, or NULL to search 288 * from the beginning of the list 289 * 290 * @return the next nvpair in the list matching the given 291 * criteria, or NULL if no matching nvpair is found 292 */ 293 nvpair_t * 294 zjni_nvlist_walk_nvpair(nvlist_t *nvl, const char *name, data_type_t type, 295 nvpair_t *nvp) 296 { 297 /* For each nvpair in the list following nvp... */ 298 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 299 300 /* Does this pair's name match the given name? */ 301 if ((name == NULL || strcmp(nvpair_name(nvp), name) == 0) && 302 303 /* Does this pair's type match the given type? */ 304 (type == DATA_TYPE_UNKNOWN || type == nvpair_type(nvp))) { 305 return (nvp); 306 } 307 } 308 309 return (NULL); 310 } 311