Encodes a token to a valid NCName. @param name token to be encoded @param lax lax encoding (lossy, but better readable) @return valid NCName
(final byte[] name, final boolean lax)
| 290 | * @return valid NCName |
| 291 | */ |
| 292 | public static byte[] encode(final byte[] name, final boolean lax) { |
| 293 | // lax encoding: trim whitespace |
| 294 | final byte[] nm = lax ? trim(name) : name; |
| 295 | final int nl = nm.length; |
| 296 | if(nl == 0) return cpToken('_'); |
| 297 | |
| 298 | for(int n = 0; n < nl; n += cl(nm, n)) { |
| 299 | int cp = cp(nm, n); |
| 300 | if(cp == '_' || (n == 0 ? !isNCStartChar(cp) : !isNCChar(cp))) { |
| 301 | final TokenBuilder tb = new TokenBuilder((long) nl << 1).add(nm, 0, n); |
| 302 | for(int m = n; m < nl; m += cl(nm, m)) { |
| 303 | cp = cp(nm, m); |
| 304 | if(lax) { |
| 305 | final boolean nc = isNCChar(cp); |
| 306 | // prefix invalid start chars (numbers, dashes, dots) with underscore |
| 307 | if(m == 0 && nc && !isNCStartChar(cp)) tb.add('_'); |
| 308 | tb.add(nc ? cp : '_'); |
| 309 | } else if(cp == '_') { |
| 310 | tb.add('_').add('_'); |
| 311 | } else if(m == 0 ? isNCStartChar(cp) : isNCChar(cp)) { |
| 312 | tb.add(cp); |
| 313 | } else if(cp < 0x10000) { |
| 314 | addEsc(tb, cp); |
| 315 | } else { |
| 316 | final int r = cp - 0x10000; |
| 317 | addEsc(tb, (r >>> 10) + 0xD800); |
| 318 | addEsc(tb, (r & 0x3FF) + 0xDC00); |
| 319 | } |
| 320 | } |
| 321 | return tb.finish(); |
| 322 | } |
| 323 | } |
| 324 | return nm; |
| 325 | } |
| 326 | |
| 327 | /** |
| 328 | * Adds the given 16-bit char to the token builder in encoded form. |