📄 windowspreferences.java
字号:
logger().warning(info); throw new BackingStoreException(info); } int maxKeyLength = result[MAX_KEY_LENGTH]; int subKeysNumber = result[SUBKEYS_NUMBER]; if (subKeysNumber == 0) { closeKey(nativeHandle); return new String[0]; } String[] subkeys = new String[subKeysNumber]; String[] children = new String[subKeysNumber]; // Get children for (int i = 0; i < subKeysNumber; i++) { byte[] windowsName = WindowsRegEnumKeyEx1(nativeHandle, i, maxKeyLength+1); if (windowsName == null) { String info = "Could not enumerate key #" + i + " of windows node " + byteArrayToString(windowsAbsolutePath()) + " at root 0x" + Integer.toHexString(rootNativeHandle()) + ". "; logger().warning(info); throw new BackingStoreException(info); } String javaName = toJavaName(windowsName); children[i] = javaName; } closeKey(nativeHandle); return children; } /** * Implements <tt>Preferences</tt> <tt>flush()</tt> method. * Flushes Windows registry changes to disk. * Throws a BackingStoreException and logs a warning message if Windows * registry is not available. */ public void flush() throws BackingStoreException{ if (isRemoved()) { parent.flush(); return; } if (!isBackingStoreAvailable) { throw new BackingStoreException( "flush(): Backing store not available."); } int nativeHandle = openKey(KEY_READ); if (nativeHandle == NULL_NATIVE_HANDLE) { throw new BackingStoreException("Could not open windows" + "registry node " + byteArrayToString(windowsAbsolutePath()) + " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); } int result = WindowsRegFlushKey1(nativeHandle); if (result != ERROR_SUCCESS) { String info = "Could not flush windows " + "registry node " + byteArrayToString(windowsAbsolutePath()) + " at root 0x" + Integer.toHexString(rootNativeHandle()) + ". Windows RegFlushKey(...) returned error code " + result + "."; logger().warning(info); throw new BackingStoreException(info); } closeKey(nativeHandle); } /** * Implements <tt>Preferences</tt> <tt>sync()</tt> method. * Flushes Windows registry changes to disk. Equivalent to flush(). * @see flush() */ public void sync() throws BackingStoreException{ if (isRemoved()) throw new IllegalStateException("Node has been removed"); flush(); } /** * Implements <tt>AbstractPreferences</tt> <tt>childSpi()</tt> method. * Constructs a child node with a * given name and creates its underlying Windows registry node, * if it does not exist. * Logs a warning message, if Windows Registry is unavailable. */ protected AbstractPreferences childSpi(String name) { return new WindowsPreferences(this, name); } /** * Implements <tt>AbstractPreferences</tt> <tt>removeNodeSpi()</tt> method. * Deletes underlying Windows registry node. * Throws a BackingStoreException and logs a warning, if Windows registry * is not available. */ public void removeNodeSpi() throws BackingStoreException { int parentNativeHandle = ((WindowsPreferences)parent()).openKey(DELETE); if (parentNativeHandle == NULL_NATIVE_HANDLE) { throw new BackingStoreException("Could not open parent windows" + "registry node of " + byteArrayToString(windowsAbsolutePath()) + " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); } int result = WindowsRegDeleteKey(parentNativeHandle, toWindowsName(name())); if (result != ERROR_SUCCESS) { String info = "Could not delete windows " + "registry node " + byteArrayToString(windowsAbsolutePath()) + " at root 0x" + Integer.toHexString(rootNativeHandle()) + ". Windows RegDeleteKeyEx(...) returned error code " + result + "."; logger().warning(info); throw new BackingStoreException(info); } closeKey(parentNativeHandle); } /** * Converts value's or node's name from its byte array representation to * java string. Two encodings, simple and altBase64 are used. See * {@link #toWindowsName(String) toWindowsName()} for a detailed * description of encoding conventions. * @param windowsNameArray Null-terminated byte array. */ private static String toJavaName(byte[] windowsNameArray) { String windowsName = byteArrayToString(windowsNameArray); // check if Alt64 if ((windowsName.length()>1) && (windowsName.substring(0,2).equals("/!"))) { return toJavaAlt64Name(windowsName); } StringBuffer javaName = new StringBuffer(); char ch; // Decode from simple encoding for (int i = 0; i < windowsName.length(); i++){ if ((ch = windowsName.charAt(i)) == '/') { char next = ' '; if ((windowsName.length() > i + 1) && ((next = windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { ch = next; i++; } else if ((windowsName.length() > i + 1) && (next == '/')) { ch = '\\'; i++; } } else if (ch == '\\') { ch = '/'; } javaName.append(ch); } return javaName.toString(); } /** * Converts value's or node's name from its Windows representation to java * string, using altBase64 encoding. See * {@link #toWindowsName(String) toWindowsName()} for a detailed * description of encoding conventions. */ private static String toJavaAlt64Name(String windowsName) { byte[] byteBuffer = Base64.altBase64ToByteArray(windowsName.substring(2)); StringBuffer result = new StringBuffer(); for (int i = 0; i < byteBuffer.length; i++) { int firstbyte = (byteBuffer[i++] & 0xff); int secondbyte = (byteBuffer[i] & 0xff); result.append((char)((firstbyte << 8) + secondbyte)); } return result.toString(); } /** * Converts value's or node's name to its Windows representation * as a byte-encoded string. * Two encodings, simple and altBase64 are used. * <p> * <i>Simple</i> encoding is used, if java string does not contain * any characters less, than 0x0020, or greater, than 0x007f. * Simple encoding adds "/" character to capital letters, i.e. * "A" is encoded as "/A". Character '\' is encoded as '//', * '/' is encoded as '\'. * The constructed string is converted to byte array by truncating the * highest byte and adding the terminating <tt>null</tt> character. * <p> * <i>altBase64</i> encoding is used, if java string does contain at least * one character less, than 0x0020, or greater, than 0x007f. * This encoding is marked by setting first two bytes of the * Windows string to '/!'. The java name is then encoded using * byteArrayToAltBase64() method from * Base64 class. */ private static byte[] toWindowsName(String javaName) { StringBuffer windowsName = new StringBuffer(); for (int i = 0; i < javaName.length(); i++) { char ch =javaName.charAt(i); if ((ch < 0x0020)||(ch > 0x007f)) { // If a non-trivial character encountered, use altBase64 return toWindowsAlt64Name(javaName); } if (ch == '\\') { windowsName.append("//"); } else if (ch == '/') { windowsName.append('\\'); } else if ((ch >= 'A') && (ch <='Z')) { windowsName.append("/" + ch); } else { windowsName.append(ch); } } return stringToByteArray(windowsName.toString()); } /** * Converts value's or node's name to its Windows representation * as a byte-encoded string, using altBase64 encoding. See * {@link #toWindowsName(String) toWindowsName()} for a detailed * description of encoding conventions. */ private static byte[] toWindowsAlt64Name(String javaName) { byte[] javaNameArray = new byte[2*javaName.length()]; // Convert to byte pairs int counter = 0; for (int i = 0; i < javaName.length();i++) { int ch = javaName.charAt(i); javaNameArray[counter++] = (byte)(ch >>> 8); javaNameArray[counter++] = (byte)ch; } return stringToByteArray( "/!" + Base64.byteArrayToAltBase64(javaNameArray)); } /** * Converts value string from its Windows representation * to java string. See * {@link #toWindowsValueString(String) toWindowsValueString()} for the * description of the encoding algorithm. */ private static String toJavaValueString(byte[] windowsNameArray) { // Use modified native2ascii algorithm String windowsName = byteArrayToString(windowsNameArray); StringBuffer javaName = new StringBuffer(); char ch; for (int i = 0; i < windowsName.length(); i++){ if ((ch = windowsName.charAt(i)) == '/') { char next = ' '; if (windowsName.length() > i + 1 && (next = windowsName.charAt(i + 1)) == 'u') { if (windowsName.length() < i + 6){ break; } else { ch = (char)Integer.parseInt (windowsName.substring(i + 2, i + 6), 16); i += 5; } } else if ((windowsName.length() > i + 1) && ((windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { ch = next; i++; } else if ((windowsName.length() > i + 1) && (next == '/')) { ch = '\\'; i++; } } else if (ch == '\\') { ch = '/'; } javaName.append(ch); } return javaName.toString(); } /** * Converts value string to it Windows representation. * as a byte-encoded string. * Encoding algorithm adds "/" character to capital letters, i.e. * "A" is encoded as "/A". Character '\' is encoded as '//', * '/' is encoded as '\'. * Then encoding scheme similar to jdk's native2ascii converter is used * to convert java string to a byte array of ASCII characters. */ private static byte[] toWindowsValueString(String javaName) { StringBuffer windowsName = new StringBuffer(); for (int i = 0; i < javaName.length(); i++) { char ch =javaName.charAt(i); if ((ch < 0x0020)||(ch > 0x007f)){ // write \udddd windowsName.append("/u"); String hex = Integer.toHexString(javaName.charAt(i)); StringBuffer hex4 = new StringBuffer(hex); hex4.reverse(); int len = 4 - hex4.length(); for (int j = 0; j < len; j++){ hex4.append('0'); } for (int j = 0; j < 4; j++){ windowsName.append(hex4.charAt(3 - j)); } } else if (ch == '\\') { windowsName.append("//"); } else if (ch == '/') { windowsName.append('\\'); } else if ((ch >= 'A') && (ch <='Z')) { windowsName.append("/" + ch); } else { windowsName.append(ch); } } return stringToByteArray(windowsName.toString()); } /** * Returns native handle for the top Windows node for this node. */ private int rootNativeHandle() { return (isUserNode()? USER_ROOT_NATIVE_HANDLE : SYSTEM_ROOT_NATIVE_HANDLE); } /** * Returns this java string as a null-terminated byte array */ private static byte[] stringToByteArray(String str) { byte[] result = new byte[str.length()+1]; for (int i = 0; i < str.length(); i++) { result[i] = (byte) str.charAt(i); } result[str.length()] = 0; return result; } /** * Converts a null-terminated byte array to java string */ private static String byteArrayToString(byte[] array) { StringBuffer result = new StringBuffer(); for (int i = 0; i < array.length - 1; i++) { result.append((char)array[i]); } return result.toString(); } /** * Empty, never used implementation of AbstractPreferences.flushSpi(). */ protected void flushSpi() throws BackingStoreException { // assert false; } /** * Empty, never used implementation of AbstractPreferences.flushSpi(). */ protected void syncSpi() throws BackingStoreException { // assert false; } private static synchronized Logger logger() { if (logger == null) { logger = Logger.getLogger("java.util.prefs"); } return logger; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -