/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id: TokenTests.scala 18387 2009-07-24 15:28:37Z odersky $ package scala.xml package parsing; /** * Helper functions for parsing XML fragments */ trait TokenTests { /** (#x20 | #x9 | #xD | #xA) */ final def isSpace( ch:Char ): Boolean = ch match { case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true case _ => false; } /** (#x20 | #x9 | #xD | #xA)+ */ final def isSpace(cs: Seq[Char]): Boolean = { val it = cs.iterator; it.hasNext && it.forall { isSpace }; } /** NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' * | CombiningChar | Extender * * see [4] and Appendix B of XML 1.0 specification */ def isNameChar(ch: Char) = isNameStart(ch) || (ch match { case '.' | '-' | ':' => true; case _ => java.lang.Character.getType( ch ).asInstanceOf[Byte] match { case java.lang.Character.COMBINING_SPACING_MARK => true; // Mc case java.lang.Character.ENCLOSING_MARK => true; // Me case java.lang.Character.NON_SPACING_MARK => true; // Mn case java.lang.Character.MODIFIER_LETTER => true; // Lm case java.lang.Character.DECIMAL_DIGIT_NUMBER => true; // Nd case _ => false; } }); /** NameStart ::= ( Letter | '_' ) * where Letter means in one of the Unicode general * categories { Ll, Lu, Lo, Lt, Nl } * * We do not allow a name to start with ':'. * see [3] and Appendix B of XML 1.0 specification */ def isNameStart(ch: Char) = java.lang.Character.getType(ch).asInstanceOf[Byte] match { case java.lang.Character.LOWERCASE_LETTER => true; case java.lang.Character.UPPERCASE_LETTER => true; case java.lang.Character.OTHER_LETTER => true; case java.lang.Character.TITLECASE_LETTER => true; case java.lang.Character.LETTER_NUMBER => true; case _ => ch match { case '_' => true case _ => false; } } /** Name ::= ( Letter | '_' ) (NameChar)* * * see [5] of XML 1.0 specification */ def isName(s: String): Boolean = { if( s.length() > 0 ) { val y = s.iterator; if (isNameStart(y.next)) { while (y.hasNext && isNameChar(y.next)) {}; !y.hasNext } else false; } else false; } def isPubIDChar(ch: Char): Boolean = { //Console.println("char: '" + ch + "'"); ch match { case '\u0020' | '\u000D' | '\u000A' => true; case _ if (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) => true; case '-' | '\''| '(' | ')' | '+' | ',' | '.' | '/' | ':' | '=' | '?' | ';' | '!' | '*' | '#' | '@' | '$' | '_' | '%' => true case _ => //Console.println("false: '" + ch + "'"); false; } } /** * Returns true if the encoding name is a valid IANA encoding. * This method does not verify that there is a decoder available * for this encoding, only that the characters are valid for an * IANA encoding name. * * @param ianaEncoding The IANA encoding name. */ def isValidIANAEncoding(ianaEncoding: Seq[Char]): Boolean = { val it = ianaEncoding.iterator; if (!it.hasNext) return false; var c = it.next; if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { while (it.hasNext) { c = it.next; if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '.' && c != '_' && c != '-') { return false; } } return true; } else return false; } // isValidIANAEncoding(String): Boolean def checkSysID( s:String ): Boolean = { s.indexOf('"'.asInstanceOf[Int]) == -1 || s.indexOf('\''.asInstanceOf[Int]) == -1 } def checkPubID(s: String): Boolean = { //Console.println("checkPubID of \""+s+"\""); if (s.length() > 0) { val y = s.iterator; var c = ' '; while (y.hasNext && isPubIDChar(c)) { //Console.println(c); c = y.next }; !y.hasNext } else true } }