1045 String valStr = value.getAsString();
1046
1047 if (valStr == null) {
1048
1049 // rfc1779 specifies that attribute values associated
1050 // with non-standard keyword attributes may be represented
1051 // using the hex format below. This will be used only
1052 // when the value is not a string type
1053
1054 byte data [] = value.toByteArray();
1055
1056 retval.append('#');
1057 for (int i = 0; i < data.length; i++) {
1058 retval.append(hexDigits.charAt((data [i] >> 4) & 0x0f));
1059 retval.append(hexDigits.charAt(data [i] & 0x0f));
1060 }
1061
1062 } else {
1063
1064 boolean quoteNeeded = false;
1065 StringBuilder sbuffer = new StringBuilder();
1066 boolean previousWhite = false;
1067 final String escapees = ",+=\n<>#;\\\"";
1068
1069 /*
1070 * Special characters (e.g. AVA list separators) cause strings
1071 * to need quoting, or at least escaping. So do leading or
1072 * trailing spaces, and multiple internal spaces.
1073 */
1074 int length = valStr.length();
1075 boolean alreadyQuoted =
1076 (length > 1 && valStr.charAt(0) == '\"'
1077 && valStr.charAt(length - 1) == '\"');
1078
1079 for (int i = 0; i < length; i++) {
1080 char c = valStr.charAt(i);
1081 if (alreadyQuoted && (i == 0 || i == length - 1)) {
1082 sbuffer.append(c);
1083 continue;
1084 }
1085 if (DerValue.isPrintableStringChar(c) ||
1086 escapees.indexOf(c) >= 0) {
1087
1088 // quote if leading whitespace or special chars
1089 if (!quoteNeeded &&
1090 ((i == 0 && (c == ' ' || c == '\n')) ||
1091 escapees.indexOf(c) >= 0)) {
1092 quoteNeeded = true;
1093 }
1094
1095 // quote if multiple internal whitespace
1096 if (!(c == ' ' || c == '\n')) {
1097 // escape '"' and '\'
1098 if (c == '"' || c == '\\') {
1099 sbuffer.append('\\');
1100 }
1101 previousWhite = false;
1102 } else {
1103 if (!quoteNeeded && previousWhite) {
1104 quoteNeeded = true;
1105 }
1106 previousWhite = true;
1107 }
1108
1109 sbuffer.append(c);
1110
1111 } else if (debug != null && Debug.isOn("ava")) {
1112
1113 // embed non-printable/non-escaped char
1114 // as escaped hex pairs for debugging
1115
1116 previousWhite = false;
1117
1118 // embed escaped hex pairs
1119 byte[] valueBytes =
1120 Character.toString(c).getBytes("UTF8");
1121 for (int j = 0; j < valueBytes.length; j++) {
1122 sbuffer.append('\\');
1123 char hexChar = Character.forDigit
1124 (0xF & (valueBytes[j] >>> 4), 16);
1125 sbuffer.append(Character.toUpperCase(hexChar));
1126 hexChar = Character.forDigit
1127 (0xF & (valueBytes[j]), 16);
1128 sbuffer.append(Character.toUpperCase(hexChar));
1129 }
1130 } else {
1131
1132 // append non-printable/non-escaped char
1133
1134 previousWhite = false;
1135 sbuffer.append(c);
1136 }
1137 }
1138
1139 // quote if trailing whitespace
1140 if (sbuffer.length() > 0) {
1141 char trailChar = sbuffer.charAt(sbuffer.length() - 1);
1142 if (trailChar == ' ' || trailChar == '\n') {
1143 quoteNeeded = true;
1144 }
1145 }
1146
1147 // Emit the string ... quote it if needed
1148 // if string is already quoted, don't re-quote
1149 if (!alreadyQuoted && quoteNeeded) {
1150 retval.append("\"" + sbuffer.toString() + "\"");
1151 } else {
1152 retval.append(sbuffer.toString());
1153 }
1154 }
1155 } catch (IOException e) {
1156 throw new IllegalArgumentException("DER Value conversion");
1157 }
1158
1159 return retval.toString();
1160 }
1161
1162 }
1163
1164 /**
1165 * Helper class that allows conversion from String to ObjectIdentifier and
1166 * vice versa according to RFC1779, RFC2253, and an augmented version of
1167 * those standards.
1168 */
1169 class AVAKeyword {
1170
1171 private static final Map<ObjectIdentifier,AVAKeyword> oidMap;
1172 private static final Map<String,AVAKeyword> keywordMap;
|
1045 String valStr = value.getAsString();
1046
1047 if (valStr == null) {
1048
1049 // rfc1779 specifies that attribute values associated
1050 // with non-standard keyword attributes may be represented
1051 // using the hex format below. This will be used only
1052 // when the value is not a string type
1053
1054 byte data [] = value.toByteArray();
1055
1056 retval.append('#');
1057 for (int i = 0; i < data.length; i++) {
1058 retval.append(hexDigits.charAt((data [i] >> 4) & 0x0f));
1059 retval.append(hexDigits.charAt(data [i] & 0x0f));
1060 }
1061
1062 } else {
1063
1064 boolean quoteNeeded = false;
1065 StringBuilder sb = new StringBuilder();
1066 boolean previousWhite = false;
1067 final String escapees = ",+=\n<>#;\\\"";
1068
1069 /*
1070 * Special characters (e.g. AVA list separators) cause strings
1071 * to need quoting, or at least escaping. So do leading or
1072 * trailing spaces, and multiple internal spaces.
1073 */
1074 int length = valStr.length();
1075 boolean alreadyQuoted =
1076 (length > 1 && valStr.charAt(0) == '\"'
1077 && valStr.charAt(length - 1) == '\"');
1078
1079 for (int i = 0; i < length; i++) {
1080 char c = valStr.charAt(i);
1081 if (alreadyQuoted && (i == 0 || i == length - 1)) {
1082 sb.append(c);
1083 continue;
1084 }
1085 if (DerValue.isPrintableStringChar(c) ||
1086 escapees.indexOf(c) >= 0) {
1087
1088 // quote if leading whitespace or special chars
1089 if (!quoteNeeded &&
1090 ((i == 0 && (c == ' ' || c == '\n')) ||
1091 escapees.indexOf(c) >= 0)) {
1092 quoteNeeded = true;
1093 }
1094
1095 // quote if multiple internal whitespace
1096 if (!(c == ' ' || c == '\n')) {
1097 // escape '"' and '\'
1098 if (c == '"' || c == '\\') {
1099 sb.append('\\');
1100 }
1101 previousWhite = false;
1102 } else {
1103 if (!quoteNeeded && previousWhite) {
1104 quoteNeeded = true;
1105 }
1106 previousWhite = true;
1107 }
1108
1109 sb.append(c);
1110
1111 } else if (debug != null && Debug.isOn("ava")) {
1112
1113 // embed non-printable/non-escaped char
1114 // as escaped hex pairs for debugging
1115
1116 previousWhite = false;
1117
1118 // embed escaped hex pairs
1119 byte[] valueBytes =
1120 Character.toString(c).getBytes("UTF8");
1121 for (int j = 0; j < valueBytes.length; j++) {
1122 sb.append('\\');
1123 char hexChar = Character.forDigit
1124 (0xF & (valueBytes[j] >>> 4), 16);
1125 sb.append(Character.toUpperCase(hexChar));
1126 hexChar = Character.forDigit
1127 (0xF & (valueBytes[j]), 16);
1128 sb.append(Character.toUpperCase(hexChar));
1129 }
1130 } else {
1131
1132 // append non-printable/non-escaped char
1133
1134 previousWhite = false;
1135 sb.append(c);
1136 }
1137 }
1138
1139 // quote if trailing whitespace
1140 if (sb.length() > 0) {
1141 char trailChar = sb.charAt(sb.length() - 1);
1142 if (trailChar == ' ' || trailChar == '\n') {
1143 quoteNeeded = true;
1144 }
1145 }
1146
1147 // Emit the string ... quote it if needed
1148 // if string is already quoted, don't re-quote
1149 if (!alreadyQuoted && quoteNeeded) {
1150 retval.append('"').append(sb).append('"');
1151 } else {
1152 retval.append(sb);
1153 }
1154 }
1155 } catch (IOException e) {
1156 throw new IllegalArgumentException("DER Value conversion");
1157 }
1158
1159 return retval.toString();
1160 }
1161
1162 }
1163
1164 /**
1165 * Helper class that allows conversion from String to ObjectIdentifier and
1166 * vice versa according to RFC1779, RFC2253, and an augmented version of
1167 * those standards.
1168 */
1169 class AVAKeyword {
1170
1171 private static final Map<ObjectIdentifier,AVAKeyword> oidMap;
1172 private static final Map<String,AVAKeyword> keywordMap;
|