/*
 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
   Hierarchical storage layout:

   <dict>
     <key>/</key>
     <dict>
       <key>foo</key>
       <string>/foo's value</string>
       <key>foo/</key>
       <dict>
         <key>bar</key>
         <string>/foo/bar's value</string>
       </dict>
     </dict>
   </dict>

   Java pref nodes are stored in several different files. Pref nodes
   with at least three components in the node name (e.g. /com/MyCompany/MyApp/)
   are stored in a CF prefs file with the first three components as the name.
   This way, all preferences for MyApp end up in com.MyCompany.MyApp.plist .
   Pref nodes with shorter names are stored in com.apple.java.util.prefs.plist

   The filesystem is assumed to be case-insensitive (like HFS+).
   Java pref node names are case-sensitive. If two pref node names differ
   only in case, they may end up in the same pref file. This is ok
   because the CF keys identifying the node span the entire absolute path
   to the node and are case-sensitive.

   Java node names may contain '.' . When mapping to the CF file name,
   these dots are left as-is, even though '/' is mapped to '.' .
   This is ok because the CF key contains the correct node name.
*/



#include <CoreFoundation/CoreFoundation.h>

#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"


// Throw an OutOfMemoryError with the given message.
static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
{
    static jclass exceptionClass = NULL;
    jclass c;

    (*env)->ExceptionClear(env);  // If an exception is pending, clear it before
                                  // calling FindClass() and/or ThrowNew().
    if (exceptionClass) {
        c = exceptionClass;
    } else {
        c = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
        if ((*env)->ExceptionOccurred(env)) return;
        exceptionClass = (*env)->NewGlobalRef(env, c);
    }

    (*env)->ThrowNew(env, c, msg);
}


// throwIfNull macro
// If var is NULL, throw an OutOfMemoryError and goto badvar.
// var must be a variable. env must be the current JNIEnv.
// fixme throw BackingStoreExceptions sometimes?
#define throwIfNull(var, msg) \
    do { \
        if (var == NULL) { \
            throwOutOfMemoryError(env, msg); \
            goto bad##var; \
        } \
    } while (0)


// Converts CFNumber, CFBoolean, CFString to CFString
// returns NULL if value is of some other type
// throws and returns NULL on memory error
// result must be released (even if value was already a CFStringRef)
// value must not be null
static CFStringRef copyToCFString(JNIEnv *env, CFTypeRef value)
{
    CFStringRef result;
    CFTypeID type;

    type = CFGetTypeID(value);

    if (type == CFStringGetTypeID()) {
        result = (CFStringRef)CFRetain(value);
    }
    else if (type == CFBooleanGetTypeID()) {
        // Java Preferences API expects "true" and "false" for boolean values.
        result = CFStringCreateCopy(NULL, (value == kCFBooleanTrue) ? CFSTR("true") : CFSTR("false"));
        throwIfNull(result, "copyToCFString failed");
    }
    else if (type == CFNumberGetTypeID()) {
        CFNumberRef number = (CFNumberRef) value;
        if (CFNumberIsFloatType(number)) {
            double d;
            CFNumberGetValue(number, kCFNumberDoubleType, &d);
            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%g"), d);
            throwIfNull(result, "copyToCFString failed");
        }
        else {
            long l;
            CFNumberGetValue(number, kCFNumberLongType, &l);
            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), l);
            throwIfNull(result, "copyToCFString failed");
        }
    }
    else {
        // unknown type - return NULL
        result = NULL;
    }

 badresult:
    return result;
}


// Create a Java string from the given CF string.
// returns NULL if cfString is NULL
// throws and returns NULL on memory error
static jstring toJavaString(JNIEnv *env, CFStringRef cfString)
{
    if (cfString == NULL) {
        return NULL;
    } else {
        jstring javaString = NULL;

        CFIndex length = CFStringGetLength(cfString);
        const UniChar *constchars = CFStringGetCharactersPtr(cfString);
        if (constchars) {
            javaString = (*env)->NewString(env, constchars, length);
        } else {
            UniChar *chars = malloc(length * sizeof(UniChar));
            throwIfNull(chars, "toJavaString failed");
            CFStringGetCharacters(cfString, CFRangeMake(0, length), chars);
            javaString = (*env)->NewString(env, chars, length);
            free(chars);
        }
    badchars:
        return javaString;
    }
}



// Create a CF string from the given Java string.
// returns NULL if javaString is NULL
// throws and returns NULL on memory error
static CFStringRef toCF(JNIEnv *env, jstring javaString)
{
    if (javaString == NULL) {
        return NULL;
    } else {
        CFStringRef result = NULL;
        jsize length = (*env)->GetStringLength(env, javaString);
        const jchar *chars = (*env)->GetStringChars(env, javaString, NULL);
        throwIfNull(chars, "toCF failed");
        result =
            CFStringCreateWithCharacters(NULL, (const UniChar *)chars, length);
        (*env)->ReleaseStringChars(env, javaString, chars);
        throwIfNull(result, "toCF failed");
    badchars:
    badresult:
        return result;
    }
}


// Create an empty Java string array of the given size.
// Throws and returns NULL on error.
static jarray createJavaStringArray(JNIEnv *env, CFIndex count)
{
    static jclass stringClass = NULL;
    jclass c;

    if (stringClass) {
        c = stringClass;
    } else {
        c = (*env)->FindClass(env, "java/lang/String");
        if ((*env)->ExceptionOccurred(env)) return NULL;
        stringClass = (*env)->NewGlobalRef(env, c);
    }

    return (*env)->NewObjectArray(env, count, c, NULL); // AWT_THREADING Safe (known object)
}


// Java accessors for CF constants.
JNIEXPORT jlong JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_currentUser(JNIEnv *env,
                                                       jobject klass)
{
    return ptr_to_jlong(kCFPreferencesCurrentUser);
}

JNIEXPORT jlong JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_anyUser(JNIEnv *env, jobject klass)
{
    return ptr_to_jlong(kCFPreferencesAnyUser);
}

JNIEXPORT jlong JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_currentHost(JNIEnv *env,
                                                       jobject klass)
{
    return ptr_to_jlong(kCFPreferencesCurrentHost);
}

JNIEXPORT jlong JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_anyHost(JNIEnv *env, jobject klass)
{
    return ptr_to_jlong(kCFPreferencesAnyHost);
}


// Create an empty node.
// Does not store the node in any prefs file.
// returns NULL on memory error
static CFMutableDictionaryRef createEmptyNode(void)
{
    return CFDictionaryCreateMutable(NULL, 0,
                                     &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);
}


// Create a string that consists of path minus its last component.
// path must end with '/'
// The result will end in '/' (unless path itself is '/')
static CFStringRef copyParentOf(CFStringRef path)
{
    CFRange searchRange;
    CFRange slashRange;
    CFRange parentRange;
    Boolean found;

    searchRange = CFRangeMake(0, CFStringGetLength(path) - 1);
    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
                                    kCFCompareBackwards, &slashRange);
    if (!found) return CFSTR("");
    parentRange = CFRangeMake(0, slashRange.location + 1); // include '/'
    return CFStringCreateWithSubstring(NULL, path, parentRange);
}


// Create a string that consists of path's last component.
// path must end with '/'
// The result will end in '/'.
// The result will not start with '/' (unless path itself is '/')
static CFStringRef copyChildOf(CFStringRef path)
{
    CFRange searchRange;
    CFRange slashRange;
    CFRange childRange;
    Boolean found;
    CFIndex length = CFStringGetLength(path);

    searchRange = CFRangeMake(0, length - 1);
    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
                                    kCFCompareBackwards, &slashRange);
    if (!found) return CFSTR("");
    childRange = CFRangeMake(slashRange.location + 1,
                             length - slashRange.location - 1); // skip '/'
    return CFStringCreateWithSubstring(NULL, path, childRange);
}


// Return the first three components of path, with leading and trailing '/'.
// If path does not have three components, return NULL.
// path must begin and end in '/'
static CFStringRef copyFirstThreeComponentsOf(CFStringRef path)
{
    CFRange searchRange;
    CFRange slashRange;
    CFRange prefixRange;
    CFStringRef prefix;
    Boolean found;
    CFIndex length = CFStringGetLength(path);

    searchRange = CFRangeMake(1, length - 1);  // skip leading '/'
    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
                                    &slashRange);
    if (!found) return NULL;  // no second slash!

    searchRange = CFRangeMake(slashRange.location + 1,
                              length - slashRange.location - 1);
    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
                                    &slashRange);
    if (!found) return NULL;  // no third slash!

    searchRange = CFRangeMake(slashRange.location + 1,
                              length - slashRange.location - 1);
    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
                                    &slashRange);
    if (!found) return NULL;  // no fourth slash!

    prefixRange = CFRangeMake(0, slashRange.location + 1); // keep last '/'
    prefix = CFStringCreateWithSubstring(NULL, path, prefixRange);

    return prefix;
}


// Copy the CFPreferences key and value at the base of path's tree.
// path must end in '/'
// topKey or topValue may be NULL
// Returns NULL on error or if there is no tree for path in this file.
static void copyTreeForPath(CFStringRef path, CFStringRef name,
                            CFStringRef user, CFStringRef host,
                            CFStringRef *topKey, CFDictionaryRef *topValue)
{
    CFStringRef key;
    CFPropertyListRef value;

    if (topKey) *topKey = NULL;
    if (topValue) *topValue = NULL;

    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
        // Top-level file. Only key "/" is an acceptable root.
        key = (CFStringRef) CFRetain(CFSTR("/"));
    } else {
        // Second-level file. Key must be the first three components of path.
        key = copyFirstThreeComponentsOf(path);
        if (!key) return;
    }

    value = CFPreferencesCopyValue(key, name, user, host);
    if (value) {
        if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
            // (key, value) is acceptable
            if (topKey) *topKey = (CFStringRef)CFRetain(key);
            if (topValue) *topValue = (CFDictionaryRef)CFRetain(value);
        }
        CFRelease(value);
    }
    CFRelease(key);
}


// Find the node for path in the given tree.
// Returns NULL on error or if path doesn't have a node in this tree.
// path must end in '/'
static CFDictionaryRef copyNodeInTree(CFStringRef path, CFStringRef topKey,
                                      CFDictionaryRef topValue)
{
    CFMutableStringRef p;
    CFDictionaryRef result = NULL;

    p = CFStringCreateMutableCopy(NULL, 0, path);
    if (!p) return NULL;
    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
    result = topValue;

    while (CFStringGetLength(p) > 0) {
        CFDictionaryRef child;
        CFStringRef part = NULL;
        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
        // guaranteed to succeed because path must end in '/'
        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
        part = CFStringCreateWithSubstring(NULL, p, partRange);
        if (!part) { result = NULL; break; }
        CFStringDelete(p, partRange);

        child = CFDictionaryGetValue(result, part);
        CFRelease(part);
        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
            // continue search
            result = child;
        } else {
            // didn't find target node
            result = NULL;
            break;
        }
    }

    CFRelease(p);
    if (result) return (CFDictionaryRef)CFRetain(result);
    else return NULL;
}


// Return a retained copy of the node at path from the given file.
// path must end in '/'
// returns NULL if node doesn't exist.
// returns NULL if the value for key "path" isn't a valid node.
static CFDictionaryRef copyNodeIfPresent(CFStringRef path, CFStringRef name,
                                         CFStringRef user, CFStringRef host)
{
    CFStringRef topKey;
    CFDictionaryRef topValue;
    CFDictionaryRef result;

    copyTreeForPath(path, name, user, host, &topKey, &topValue);
    if (!topKey) return NULL;

    result = copyNodeInTree(path, topKey, topValue);

    CFRelease(topKey);
    if (topValue) CFRelease(topValue);
    return result;
}


// Create a new tree that would store path in the given file.
// Only the root of the tree is created, not all of the links leading to path.
// returns NULL on error
static void createTreeForPath(CFStringRef path, CFStringRef name,
                              CFStringRef user, CFStringRef host,
                              CFStringRef *outTopKey,
                              CFMutableDictionaryRef *outTopValue)
{
    *outTopKey = NULL;
    *outTopValue = NULL;

    // if name is "com.apple.java.util.prefs" then create tree "/"
    // else create tree "/foo/bar/baz/"
    // "com.apple.java.util.prefs.plist" is also in MacOSXPreferences.java
    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
        *outTopKey = CFSTR("/");
        *outTopValue = createEmptyNode();
    } else {
        CFStringRef prefix = copyFirstThreeComponentsOf(path);
        if (prefix) {
            *outTopKey = prefix;
            *outTopValue = createEmptyNode();
        }
    }
}


// Return a mutable copy of the tree containing path and the dict for
//   path itself. *outTopKey and *outTopValue can be used to write the
//   modified tree back to the prefs file.
// *outTopKey and *outTopValue must be released iff the actual return
//   value is not NULL.
static CFMutableDictionaryRef
copyMutableNode(CFStringRef path, CFStringRef name,
                CFStringRef user, CFStringRef host,
                CFStringRef *outTopKey,
                CFMutableDictionaryRef *outTopValue)
{
    CFStringRef topKey = NULL;
    CFDictionaryRef oldTopValue = NULL;
    CFMutableDictionaryRef topValue;
    CFMutableDictionaryRef result = NULL;
    CFMutableStringRef p;

    if (outTopKey) *outTopKey = NULL;
    if (outTopValue) *outTopValue = NULL;

    copyTreeForPath(path, name, user, host, &topKey, &oldTopValue);
    if (!topKey) {
        createTreeForPath(path, name, user, host, &topKey, &topValue);
    } else {
        topValue = (CFMutableDictionaryRef)
            CFPropertyListCreateDeepCopy(NULL, (CFPropertyListRef)oldTopValue,
                                         kCFPropertyListMutableContainers);
    }
    if (!topValue) goto badtopValue;

    p = CFStringCreateMutableCopy(NULL, 0, path);
    if (!p) goto badp;
    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
    result = topValue;

    while (CFStringGetLength(p) > 0) {
        CFMutableDictionaryRef child;
        CFStringRef part = NULL;
        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
        // guaranteed to succeed because path must end in '/'
        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
        part = CFStringCreateWithSubstring(NULL, p, partRange);
        if (!part) { result = NULL; break; }
        CFStringDelete(p, partRange);

        child = (CFMutableDictionaryRef)CFDictionaryGetValue(result, part);
        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
            // continue search
            result = child;
        } else {
            // didn't find target node - add it and continue
            child = createEmptyNode();
            if (!child) { CFRelease(part); result = NULL; break; }
            CFDictionaryAddValue(result, part, child);
            result = child;
        }
        CFRelease(part);
    }

    if (result) {
        *outTopKey = (CFStringRef)CFRetain(topKey);
        *outTopValue = (CFMutableDictionaryRef)CFRetain(topValue);
        CFRetain(result);
    }

    CFRelease(p);
 badp:
    CFRelease(topValue);
 badtopValue:
    if (topKey) CFRelease(topKey);
    if (oldTopValue) CFRelease(oldTopValue);
    return result;
}


JNIEXPORT jboolean JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_addNode
(JNIEnv *env, jobject klass, jobject jpath,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFDictionaryRef node = NULL;
    jboolean neededNewNode = false;

    if (!path  ||  !name) goto badparams;

    node = copyNodeIfPresent(path, name, user, host);

    if (node) {
        neededNewNode = false;
        CFRelease(node);
    } else {
        CFStringRef topKey = NULL;
        CFMutableDictionaryRef topValue = NULL;

        neededNewNode = true;

        // copyMutableNode creates the node if necessary
        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
        throwIfNull(node, "copyMutableNode failed");

        CFPreferencesSetValue(topKey, topValue, name, user, host);

        CFRelease(node);
        if (topKey) CFRelease(topKey);
        if (topValue) CFRelease(topValue);
    }

 badnode:
 badparams:
    if (path) CFRelease(path);
    if (name) CFRelease(name);

    return neededNewNode;
}


JNIEXPORT void JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_removeNode
(JNIEnv *env, jobject klass, jobject jpath,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFStringRef parentName;
    CFStringRef childName;
    CFDictionaryRef constParent;

    if (!path  ||  !name) goto badparams;

    parentName = copyParentOf(path);
    throwIfNull(parentName, "copyParentOf failed");
    childName  = copyChildOf(path);
    throwIfNull(childName, "copyChildOf failed");

    // root node is not allowed to be removed, so parentName is never empty

    constParent = copyNodeIfPresent(parentName, name, user, host);
    if (constParent  &&  CFDictionaryContainsKey(constParent, childName)) {
        CFStringRef topKey;
        CFMutableDictionaryRef topValue;
        CFMutableDictionaryRef parent;

        parent = copyMutableNode(parentName, name, user, host,
                                 &topKey, &topValue);
        throwIfNull(parent, "copyMutableNode failed");

        CFDictionaryRemoveValue(parent, childName);
        CFPreferencesSetValue(topKey, topValue, name, user, host);

        CFRelease(parent);
        if (topKey) CFRelease(topKey);
        if (topValue) CFRelease(topValue);
    } else {
        // might be trying to remove the root itself in a non-root file
        CFStringRef topKey;
        CFDictionaryRef topValue;
        copyTreeForPath(path, name, user, host, &topKey, &topValue);
        if (topKey) {
            if (CFEqual(topKey, path)) {
                CFPreferencesSetValue(topKey, NULL, name, user, host);
            }

            if (topKey) CFRelease(topKey);
            if (topValue) CFRelease(topValue);
        }
    }


 badparent:
    if (constParent) CFRelease(constParent);
    CFRelease(childName);
 badchildName:
    CFRelease(parentName);
 badparentName:
 badparams:
    if (path) CFRelease(path);
    if (name) CFRelease(name);
}


// child must end with '/'
JNIEXPORT Boolean JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_addChildToNode
(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
 jobject jname, jlong juser, jlong jhost)
{
    // like addNode, but can put a three-level-deep dict into the root file
    CFStringRef path = NULL;
    CFStringRef child = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        child = toCF(env, jchild);
    }
    if (child != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFMutableDictionaryRef parent;
    CFDictionaryRef node;
    CFStringRef topKey;
    CFMutableDictionaryRef topValue;
    Boolean beforeAdd = false;

    if (!path  ||  !child  ||  !name) goto badparams;

    node = createEmptyNode();
    throwIfNull(node, "createEmptyNode failed");

    // copyMutableNode creates the node if necessary
    parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
    throwIfNull(parent, "copyMutableNode failed");
    beforeAdd = CFDictionaryContainsKey(parent, child);
    CFDictionaryAddValue(parent, child, node);
    if (!beforeAdd)
        beforeAdd = CFDictionaryContainsKey(parent, child);
    else
        beforeAdd = false;
    CFPreferencesSetValue(topKey, topValue, name, user, host);

    CFRelease(parent);
    if (topKey) CFRelease(topKey);
    if (topValue) CFRelease(topValue);
 badparent:
    CFRelease(node);
 badnode:
 badparams:
    if (path) CFRelease(path);
    if (child) CFRelease(child);
    if (name) CFRelease(name);
    return beforeAdd;
}


JNIEXPORT void JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_removeChildFromNode
(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef child = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        child = toCF(env, jchild);
    }
    if (child != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFDictionaryRef constParent;

    if (!path  ||  !child  ||  !name) goto badparams;

    constParent = copyNodeIfPresent(path, name, user, host);
    if (constParent  &&  CFDictionaryContainsKey(constParent, child)) {
        CFStringRef topKey;
        CFMutableDictionaryRef topValue;
        CFMutableDictionaryRef parent;

        parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
        throwIfNull(parent, "copyMutableNode failed");

        CFDictionaryRemoveValue(parent, child);
        CFPreferencesSetValue(topKey, topValue, name, user, host);

        CFRelease(parent);
        if (topKey) CFRelease(topKey);
        if (topValue) CFRelease(topValue);
    }

 badparent:
    if (constParent) CFRelease(constParent);
 badparams:
    if (path) CFRelease(path);
    if (child) CFRelease(child);
    if (name) CFRelease(name);
}



JNIEXPORT void JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_addKeyToNode
(JNIEnv *env, jobject klass, jobject jpath, jobject jkey, jobject jvalue,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef key = NULL;
    CFStringRef value = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        value = toCF(env, jvalue);
    }
    if (value != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFMutableDictionaryRef node = NULL;
    CFStringRef topKey;
    CFMutableDictionaryRef topValue;

    if (!path  ||  !key  || !value  ||  !name) goto badparams;

    // fixme optimization: check whether old value and new value are identical
    node = copyMutableNode(path, name, user, host, &topKey, &topValue);
    throwIfNull(node, "copyMutableNode failed");

    CFDictionarySetValue(node, key, value);
    CFPreferencesSetValue(topKey, topValue, name, user, host);

    CFRelease(node);
    if (topKey) CFRelease(topKey);
    if (topValue) CFRelease(topValue);

 badnode:
 badparams:
    if (path) CFRelease(path);
    if (key) CFRelease(key);
    if (value) CFRelease(value);
    if (name) CFRelease(name);
}


JNIEXPORT void JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_removeKeyFromNode
(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef key = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFDictionaryRef constNode;

    if (!path  ||  !key  ||  !name) goto badparams;

    constNode = copyNodeIfPresent(path, name, user, host);
    if (constNode  &&  CFDictionaryContainsKey(constNode, key)) {
        CFStringRef topKey;
        CFMutableDictionaryRef topValue;
        CFMutableDictionaryRef node;

        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
        throwIfNull(node, "copyMutableNode failed");

        CFDictionaryRemoveValue(node, key);
        CFPreferencesSetValue(topKey, topValue, name, user, host);

        CFRelease(node);
        if (topKey) CFRelease(topKey);
        if (topValue) CFRelease(topValue);
    }

 badnode:
    if (constNode) CFRelease(constNode);
 badparams:
    if (path) CFRelease(path);
    if (key) CFRelease(key);
    if (name) CFRelease(name);
}


// path must end in '/'
JNIEXPORT jstring JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_getKeyFromNode
(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
 jobject jname, jlong juser, jlong jhost)
{
    CFStringRef path = NULL;
    CFStringRef key = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFPropertyListRef value;
    CFDictionaryRef node;
    jstring result = NULL;

    if (!path  ||  !key  ||  !name) goto badparams;

    node = copyNodeIfPresent(path, name, user, host);
    if (node) {
        value = (CFPropertyListRef)CFDictionaryGetValue(node, key);
        if (!value) {
            // key doesn't exist, or other error - no Java errors available
            result = NULL;
        } else {
            CFStringRef cfString = copyToCFString(env, value);
            if ((*env)->ExceptionOccurred(env)) {
                // memory error in copyToCFString
                result = NULL;
            } else if (cfString == NULL) {
                // bogus value type in prefs file - no Java errors available
                result = NULL;
            } else {
                // good cfString
                result = toJavaString(env, cfString);
                CFRelease(cfString);
            }
        }
        CFRelease(node);
    }

 badparams:
    if (path) CFRelease(path);
    if (key) CFRelease(key);
    if (name) CFRelease(name);

    return result;
}


typedef struct {
    jarray result;
    JNIEnv *env;
    CFIndex used;
    Boolean allowSlash;
} BuildJavaArrayArgs;

// CFDictionary applier function that builds an array of Java strings
//   from a CFDictionary of CFPropertyListRefs.
// If args->allowSlash, only strings that end in '/' are added to the array,
//   with the slash removed. Otherwise, only strings that do not end in '/'
//   are added.
// args->result must already exist and be large enough to hold all
//   strings from the dictionary.
// After complete application, args->result may not be full because
//   some of the dictionary values weren't convertible to string. In
//   this case, args->used will be the count of used elements.
static void BuildJavaArrayFn(const void *key, const void *value, void *context)
{
    BuildJavaArrayArgs *args = (BuildJavaArrayArgs *)context;
    CFPropertyListRef propkey = (CFPropertyListRef)key;
    CFStringRef cfString = NULL;
    JNIEnv *env = args->env;

    if ((*env)->ExceptionOccurred(env)) return; // already failed

    cfString = copyToCFString(env, propkey);
    if ((*env)->ExceptionOccurred(env)) {
        // memory error in copyToCFString
    } else if (!cfString) {
        // bogus value type in prefs file - no Java errors available
    } else if (args->allowSlash != CFStringHasSuffix(cfString, CFSTR("/"))) {
        // wrong suffix - ignore
    } else {
        // good cfString
        jstring javaString;
        if (args->allowSlash) {
            CFRange range = CFRangeMake(0, CFStringGetLength(cfString) - 1);
            CFStringRef s = CFStringCreateWithSubstring(NULL, cfString, range);
            CFRelease(cfString);
            cfString = s;
        }
        if (CFStringGetLength(cfString) <= 0) goto bad; // ignore empty
        javaString = toJavaString(env, cfString);
        if ((*env)->ExceptionOccurred(env)) goto bad;
        (*env)->SetObjectArrayElement(env, args->result,args->used,javaString);
        if ((*env)->ExceptionOccurred(env)) goto bad;
        args->used++;
    }

 bad:
    if (cfString) CFRelease(cfString);
}


static jarray getStringsForNode(JNIEnv *env, jobject klass, jobject jpath,
                                jobject jname, jlong juser, jlong jhost,
                                Boolean allowSlash)
{
    CFStringRef path = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        name = toCF(env, jname);
    }
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    CFDictionaryRef node;
    jarray result = NULL;
    CFIndex count;

    if (!path  ||  !name) goto badparams;

    node = copyNodeIfPresent(path, name, user, host);
    if (!node) {
        result = createJavaStringArray(env, 0);
    } else {
        count = CFDictionaryGetCount(node);
        result = createJavaStringArray(env, count);
        if (result) {
            BuildJavaArrayArgs args;
            args.result = result;
            args.env = env;
            args.used = 0;
            args.allowSlash = allowSlash;
            CFDictionaryApplyFunction(node, BuildJavaArrayFn, &args);
            if (!(*env)->ExceptionOccurred(env)) {
                // array construction succeeded
                if (args.used < count) {
                    // finished array is smaller than expected.
                    // Make a new array of precisely the right size.
                    jarray newresult = createJavaStringArray(env, args.used);
                    if (newresult) {
                        JVM_ArrayCopy(env,0, result,0, newresult,0, args.used);
                        result = newresult;
                    }
                }
            }
        }

        CFRelease(node);
    }

 badparams:
    if (path) CFRelease(path);
    if (name) CFRelease(name);

    return result;
}


JNIEXPORT jarray JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_getKeysForNode
(JNIEnv *env, jobject klass, jobject jpath,
 jobject jname, jlong juser, jlong jhost)
{
    return getStringsForNode(env, klass, jpath, jname, juser, jhost, false);
}

JNIEXPORT jarray JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_getChildrenForNode
(JNIEnv *env, jobject klass, jobject jpath,
 jobject jname, jlong juser, jlong jhost)
{
    return getStringsForNode(env, klass, jpath, jname, juser, jhost, true);
}


// Returns false on error instead of throwing.
JNIEXPORT jboolean JNICALL
Java_java_util_prefs_MacOSXPreferencesFile_synchronize
(JNIEnv *env, jobject klass,
 jstring jname, jlong juser, jlong jhost)
{
    CFStringRef name = toCF(env, jname);
    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
    jboolean result = 0;

    if (name) {
        result = CFPreferencesSynchronize(name, user, host);
        CFRelease(name);
    }

    return result;
}
