case47 就是 name 类型。
{
case 47:
outBuf = new StringBuffer();
this.type = PRTokeniser.TokenType.NAME; // 如果ch是47,/,则说明是name类型的开头
while(true){
ch = this.file.read();
if(delims[ch +1]) { // 对于特殊字符的处理,例如 ch==60,说明name取值完成,跳出循环。
this.backOnePosition(ch);
break;
}
if(ch == 35){ // 如果是 # 号
ch = (getHex(this.file.read()) << 4) + getHex(this.file.read());
}
outBuf.append((char)ch); // 复合name的char,加入到outBuf中输出
}
}
ch==35这个地方,需要回头看一下 PdfName 的对应方法,so,当遇到符号 }
, 或者 c >= ' ' && c <= '~'
的时候
encodeName方法会将其转化为16进制,并在其前面加 #。
所以在上面的解析方法中,如果遇到 # 号,则将其从16进制解析出来。
public static byte[] encodeName(String name) {
int length = name.length();
ByteBuffer buf = new ByteBuffer(length + 20);
buf.append('/');
char[] chars = name.toCharArray();
for(int k = 0; k < length; ++k) {
char c = (char)(chars[k] & 255);
switch(c) {
case ' ':
case '#':
case '%':
case '(':
case ')':
case '/':
case '<':
case '>':
case '[':
case ']':
case '{':
case '}':
buf.append('#');
buf.append(Integer.toString(c, 16));
break;
default:
if (c >= ' ' && c <= '~') {
buf.append(c);
} else {
buf.append('#');
if (c < 16) {
buf.append('0');
}
buf.append(Integer.toString(c, 16));
}
}
}
return buf.toByteArray();
}
分析完 name解析的方法,咱们下一章再了解一下name类型
PdfName 类型
PdfName: /Type /Page /Filter…