📄 samplelabel.java
字号:
// SampleLabel.java// $Id: SampleLabel.java,v 1.7 2000/08/16 21:37:43 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.pics ;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.LineNumberInputStream;import java.io.PrintStream;import java.io.StringBufferInputStream;// I like writing these silly kind of parsers !// (its probably the X)class LabelParser { File file = null ; LineNumberInputStream in = null ; int ch = -1 ; byte buffer[] = null ; int bufptr = 0 ; /** * Append the given char in the internal buffer */ public void append (int ch) { if ( bufptr + 1 >= buffer.length) { // resize buffer byte nbuf[] = new byte[buffer.length * 2] ; System.arraycopy (buffer, 0, nbuf, 0, bufptr) ; buffer = nbuf ; } buffer[bufptr++] = (byte) ch ; } /** * Get the token from our internale buffer. */ public String getToken (boolean clear) { String tok = new String (buffer, 0, 0, bufptr) ; if ( clear ) bufptr = 0 ; return tok ; } /** * Parser expects given character. */ void expect (int c) throws InvalidLabelException { if ( ch == c ) return ; String msg = ("expected " + (new Character((char) c)).toString() + "[" + c + "]" + " got " + (new Character((char) ch)).toString() + "[" + ch + "]"); if (file == null) throw new InvalidLabelException(in.getLineNumber(), msg) ; else throw new InvalidLabelFileException (file, in.getLineNumber(), msg) ; } String parseVariableName () throws IOException { while ((ch != '=') && (ch != '\n') && (ch != -1)) { append (Character.toLowerCase((char)ch)) ; ch = in.read() ; } return getToken(true) ; } String parseVariableValue() throws IOException { while ( (ch != -1) && (ch != '\n') ) { append (ch) ; ch = in.read() ; } return getToken(true) ; } SampleLabel parse (SampleLabel into) throws InvalidLabelException, InvalidLabelFileException { try { while ( true ) { switch (ch) { case -1: // we are done. return into ; case ' ': case '\t': case '\n': ch = in.read() ; continue ; case '#': while ( ((ch = in.read()) != '\n') && (ch != -1) ) ; continue ; default: String name = parseVariableName() ; expect ('=') ; ch = in.read() ; String value = parseVariableValue() ; if (ch != -1) { // Pb -1 instead of \n expect ('\n') ; ch = in.read() ; } into.addBinding (name, value) ; continue ; } } } catch (IOException e) { if (file == null) throw new InvalidLabelException( "IO exception.") ; else throw new InvalidLabelFileException (file.getAbsolutePath() + ": IO exception.") ; } } LabelParser (File file) throws InvalidLabelFileException { this.file = file ; try { this.in = (new LineNumberInputStream (new BufferedInputStream (new FileInputStream (file)))) ; this.buffer = new byte[32] ; this.ch = in.read() ; } catch (IOException e) { throw new InvalidLabelFileException (file.getAbsolutePath() + ": IO exception.") ; } } LabelParser (String string) throws InvalidLabelException { try { this.in = (new LineNumberInputStream (new BufferedInputStream (new StringBufferInputStream (string)))) ; this.buffer = new byte[32] ; this.ch = in.read() ; } catch (IOException e) { throw new InvalidLabelException( "IO exception.") ; } }}/** * Label internal representation. * The server has to know something about labels. In this implementation, I try * to reduce this knowledge as fas as I could. Here, a label is a set of * assignements to variables (options in PICS terms), and a rating. * The syntax for writing label files is the following: * <variable>=<value>\n * <p>Comments are allowed through the '#' at beginning of line. * With the special variable 'ratings' being mandatory. */public class SampleLabel implements LabelInterface { // Default variables array size private static final int VARSIZE = 8 ; String vars[] = null ; String vals[] = null ; int varptr = 0 ; void addBinding (String var, String val) { if ( varptr + 1 >= vars.length ) { // resize arrays String nvars[] = new String[vars.length*2] ; String nvals[] = new String[vals.length*2] ; System.arraycopy (vars, 0, nvars, 0, vars.length) ; System.arraycopy (vals, 0, nvals, 0, vals.length) ; vars = nvars ; vals = nvals ; } vars[varptr] = var ; vals[varptr] = val ; varptr++ ; } /** * Debugging: print the given options of this label. * @param out The PrintStream to print to. */ public void print (PrintStream out) { for (int i = 0 ; i < varptr ; i++) { System.out.println ("\t" + vars[i] + " = " + vals[i]) ; } } /** * Does this label defines the given option ? * @param option The option to look for. * @return <strong>true</strong> if the label defines the given option. */ public boolean hasOption (String option) { for (int i = 0 ; i < varptr ; i++) { if ( vars[i].equals (option) ) return true ; } return false ; } /** * Get an option index. * This allows for fast acces to label options. There is no guarantee that * the same option will get the same index across labels. * @param option The option to look for. * @return An integer, which is the option index if the option was found * or <strong>-1</strong> if the option isn't defined for this label. */ public int getOptionIndex (String option) { for (int i = 0 ; i < varptr ; i++) { if ( vars[i].equals (option) ) return i; } return -1 ; } /** * Get an option value, by index. * This, along with the <strong>getOptionIndex</strong> method provides * a fast access to option values. * @param idx The index of the option, as gotten from * <strong>getOptionIndex</strong>. * @return A String instance, providing the option value. */ public String getOptionValue (int idx) { if ( (idx < 0) || (idx >= varptr) ) throw new RuntimeException (this.getClass().getName() + "[getOptionValue]: " + " invalid index.") ; return vals[idx] ; } /** * Get an option value, by option name. * @param option The option that you want the value of. * @return A String instance giving the option value, or * <strong>null</strong>, if the option isn't defined for this label. */ public String getOptionValue (String option) { for (int i = 0 ; i < varptr ; i++) { if ( vars[i].equals (option) ) return vals[i] ; } return null ; } /** * Is this label generic ? * @return <strong>true</strong> if the label if generic. */ public boolean isGeneric () { int idx = getOptionIndex ("generic") ; if ( idx >= 0 ) return (new Boolean(getOptionValue (idx))).booleanValue() ; return false ; } /** * Emit the given option to the output. * If the option is not defined for this label, skip it (don't emit). If * possible, and according to the format, emit the short option name. * @param space Should we emit a leading space. * @param option The option name. * @return <strong>true</strong> if the option was successfully emited, * <strong>false</strong> otherwise. */ private boolean emit (boolean space , StringBuffer into , String option, int format) { String value = getOptionValue (option) ; if ( value != null ) { switch (format) { case LabelBureauInterface.FMT_MINIMAL: case LabelBureauInterface.FMT_SHORT: // emit short option name if ( space ) into.append (" ") ; into.append (option+" "+value) ; break ; default: // emit full option name if ( space ) into.append (" ") ; into.append (option+" "+value) ; break ; } return true ; } return false ; } /** * Emit the given option to the output. * If possible, and according to the format, emit the short option name. * @param space Should we emit a leading space. * @param into The StringBuffer to dump this label to. * @param option The option name. */ private void emit (boolean space, StringBuffer into, int idx, int format) { switch (format) { case LabelBureauInterface.FMT_MINIMAL: case LabelBureauInterface.FMT_SHORT: // emit short option name if ( space ) into.append (" ") ; into.append (vars[idx]+" "+vals[idx]) ; break ; default: if ( space ) into.append (" ") ; into.append (vars[idx]+" "+vals[idx]) ; } } /** * Dump this label according to the given format. * The dump should take place <em>after</em> the service has dump itself. * @param into A StringBuffer to dump the labels to. * @param format The format in which the dump should be done. This can * be one of the four format described in the PICS specification. */ public void dump (StringBuffer into, int format) { boolean space = false ; ; switch (format) { case LabelBureauInterface.FMT_MINIMAL: // emit just the ratings, except if generic if ( isGeneric() ) { // emit the generic and for options (FIXME errors ?) emit (space,into,"generic",LabelBureauInterface.FMT_MINIMAL); space = true ; emit (space,into,"for",LabelBureauInterface.FMT_MINIMAL) ; emit (space,into,"ratings",LabelBureauInterface.FMT_MINIMAL); } else { emit (space,into,"ratings",LabelBureauInterface.FMT_MINIMAL); } break ; case LabelBureauInterface.FMT_SHORT: // emit ratings, and full, which I deem appropriate if ( isGeneric() ) { // emit the generic and for options: emit (space,into, "generic", LabelBureauInterface.FMT_SHORT); space = true ; emit (space,into, "for", LabelBureauInterface.FMT_SHORT) ; emit (space,into, "full", LabelBureauInterface.FMT_SHORT) ; emit (space,into, "ratings", LabelBureauInterface.FMT_SHORT); } else { emit (space, into, "full", LabelBureauInterface.FMT_SHORT) ; space = true ; emit (space,into,"ratings",LabelBureauInterface.FMT_SHORT) ; } break ; case LabelBureauInterface.FMT_FULL: // Emit all options, rating at the end for (int i = 0 ; i < varptr ; i++) { if ( vars[i].equals("ratings") ) continue ; emit (space, into, i, LabelBureauInterface.FMT_FULL) ; space = true ; } emit (space, into, "ratings", LabelBureauInterface.FMT_FULL) ; break ; case LabelBureauInterface.FMT_SIGNED: throw new RuntimeException (this.getClass().getName() + "[dump]: " + "SIGNED format unsupported.") ; // not reached default: throw new RuntimeException (this.getClass().getName() + "[dump]: " + " invalid format " + "\"" + format + "\"") ; } } /** * Create a new label from the given stream. * @param file The file inwhich the label options are described. */ SampleLabel (File file) throws InvalidLabelException { try { this.vars = new String[VARSIZE] ; this.vals = new String[VARSIZE] ; this.varptr = 0 ; LabelParser p = new LabelParser (file) ; p.parse (this) ; } catch (InvalidLabelException e) { throw new InvalidLabelFileException(e.getMessage()); } } SampleLabel (String string) throws InvalidLabelException { this.vars = new String[VARSIZE] ; this.vals = new String[VARSIZE] ; this.varptr = 0 ; LabelParser p = new LabelParser (string) ; p.parse (this) ; } /** * Create a new label from a set of options. * This constructor takes two arrays, one of option names, and one * of option values. It builds out of them the internal * representation for this label. * <p>The given arrays are used as is (no copy), and might side-effected * by the new instance. * @param optnames Names of option for this label. * @param optvalues Values of option for this label. */ public SampleLabel (String optnames[], String optvals[]) { if ( optnames.length != optvals.length ) throw new RuntimeException (this.getClass().getName() + " invalid constructor params:" + " bad length.") ; this.vars = optnames ; this.vals = optvals ; this.varptr = optnames.length ; } // Testing only public static void main (String args[]) { if ( args.length != 1 ) { System.out.println ("Label <file>") ; System.exit (1) ; } try { SampleLabel label = new SampleLabel (new File (args[0])) ; StringBuffer sb = new StringBuffer() ; label.dump (sb, LabelBureauInterface.FMT_MINIMAL) ; System.out.println (sb.toString()) ; } catch (InvalidLabelException e) { System.out.println (e.getMessage()) ; System.exit (1) ; } System.exit (0) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -