protected void init(IRI uri) throws IOException, MalformedURLException {
        if (!uri.getScheme().equals("data")) {
            throw new IllegalArgumentException("The input did not start with data:.");
        }

        if (uri.getRawFragment() != null) {
            throw new MalformedURLException("Fragment is not allowed for data: URIs according to RFC 2397. But if strictly comply with RFC 3986, ignore this error.");
        }

        InputStream is = new PercentDecodingReaderInputStream(new StringReader(uri.getRawPath()));
        StringBuilder sb = new StringBuilder();
        State state = State.AT_START;
        int i = 0; // string counter
        for (;;i++) {
            int b = is.read();
            if (b == -1) {
                throw new MalformedURLException("Premature end of URI.");
            }
            if (b >= 0x80) {
                throw new MalformedURLException("Non-ASCII character in MIME type part of the data URI.");                
            }
            char c = (char) b;
            sb.append(c);
            switch (state) {
                case AT_START:
                    if (isTokenChar(c)) {
                        state = State.IN_SUPERTYPE;
                        continue;
                    } else if (c == ';') {
                        sb.setLength(0);
                        sb.append("text/plain;");
                        state = State.SEMICOLON_SEEN;
                        continue;
                    } else if (c == ',') {
                        contentType = "text/plain;charset=US-ASCII";
                        inputStream = is;
                        return;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a token character or a semicolon but saw ",
                                        c, " instead.");
                    }
                case IN_SUPERTYPE:
                    if (isTokenChar(c)) {
                        continue;
                    } else if (c == '/') {
                        state = State.AT_SUBTYPE_START;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a token character or \u201C/\u201D but saw ",
                                        c, " instead.");
                    }
                case AT_SUBTYPE_START:
                    if (isTokenChar(c)) {
                        state = State.IN_SUBTYPE;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a token character but saw ",
                                        c, " instead.");
                    }
                case IN_SUBTYPE:
                    if (isTokenChar(c)) {
                        continue;
                    } else if (c == ';') {
                        state = State.SEMICOLON_SEEN;
                        continue;
                    } else if (isWhitespace(c)) {
                        state = State.WS_BEFORE_SEMICOLON;
                        continue;
                    } else if (c == ',') {
                        contentType = sb.substring(0, sb.length() - 1);
                        inputStream = is;
                        return;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a token character, whitespace, a semicolon or a comma but saw ",
                                        c, " instead.");
                    }
                case WS_BEFORE_SEMICOLON:
                    if (isWhitespace(c)) {
                        continue;
                    } else if (c == ';') {
                        state = State.SEMICOLON_SEEN;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected whitespace or a semicolon but saw ",
                                        c, " instead.");
                    }
                case SEMICOLON_SEEN:
                    if (isWhitespace(c)) {
                        continue;
                    } else if (isTokenChar(c)) {
                        state = State.IN_PARAM_NAME;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected whitespace or a token character but saw ",
                                        c, " instead.");
                    }
                case IN_PARAM_NAME:
                    if (isTokenChar(c)) {
                        continue;
                    } else if (c == '=') {
                        state = State.EQUALS_SEEN;
                        continue;
                    } else if (c == ',') {
                        // let's see if we had ;base64,
                        int baseFirst = sb.length() - 8;
                        if (baseFirst >= 0 && ";base64,".equals(sb.substring(baseFirst, sb.length()))) {
                            contentType = sb.substring(0, baseFirst);
                            inputStream = new Base64InputStream(is);
                            return;
                        }
                    } else {
                        throw newDatatypeException(i, 
                                "Expected an equals sign, a comma or a token character but saw ",
                                        c, " instead.");
                    }
                case EQUALS_SEEN:
                    if (c == '\"') {
                        state = State.IN_QUOTED_STRING;
                        continue;
                    } else if (isTokenChar(c)) {
                        state = State.IN_UNQUOTED_STRING;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a double quote or a token character but saw ",
                                        c, " instead.");
                    }
                case IN_QUOTED_STRING:
                    if (c == '\\') {
                        state = State.IN_QUOTED_PAIR;
                        continue;
                    } else if (c == '\"') {
                        state = State.CLOSE_QUOTE_SEEN;
                        continue;
                    } else if (isQDTextChar(c)) {
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a non-control ASCII character but saw ",
                                        c, " instead.");
                    }
                case IN_QUOTED_PAIR:
                    if (c <= 127) {
                        state = State.IN_QUOTED_STRING;
                        continue;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected an ASCII character but saw ",
                                        c, " instead.");
                    }
                case CLOSE_QUOTE_SEEN:
                    if (c == ';') {
                        state = State.SEMICOLON_SEEN;
                        continue;
                    } else if (isWhitespace(c)) {
                        state = State.WS_BEFORE_SEMICOLON;
                        continue;
                    } else if (c == ',') {
                        contentType = sb.substring(0, sb.length() - 1);
                        inputStream = is;
                        return;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected an ASCII character but saw ",
                                        c, " instead.");
                    }
                case IN_UNQUOTED_STRING:
                    if (isTokenChar(c)) {
                        continue;
                    } else if (c == ';') {
                        state = State.SEMICOLON_SEEN;
                        continue;
                    } else if (isWhitespace(c)) {
                        state = State.WS_BEFORE_SEMICOLON;
                        continue;
                    } else if (c == ',') {
                        contentType = sb.substring(0, sb.length() - 1);
                        inputStream = is;
                        return;
                    } else {
                        throw newDatatypeException(i, 
                                "Expected a token character, whitespace, a semicolon, or a comma but saw ",
                                        c, " instead.");
                    }
            }
        }

    }
protected void init ( IRI uri ) throws IOException , MalformedURLException { if ( ! uri . getScheme ( ) . equals ( "data" ) ) { throw new IllegalArgumentException ( "The input did not start with data:." ) ; } if ( uri . getRawFragment ( ) != null ) { throw new MalformedURLException ( "Fragment is not allowed for data: URIs according to RFC 2397. But if strictly comply with RFC 3986, ignore this error." ) ; } InputStream is = new PercentDecodingReaderInputStream ( new StringReader ( uri . getRawPath ( ) ) ) ; StringBuilder sb = new StringBuilder ( ) ; State state = State . AT_START ; int i = 0 ; for ( ; ; i ++ ) { int b = is . read ( ) ; if ( b == - 1 ) { throw new MalformedURLException ( "Premature end of URI." ) ; } if ( b >= 0x80 ) { throw new MalformedURLException ( "Non-ASCII character in MIME type part of the data URI." ) ; } char c = ( char ) b ; sb . append ( c ) ; switch ( state ) { case AT_START : if ( isTokenChar ( c ) ) { state = State . IN_SUPERTYPE ; continue ; } else if ( c == ';' ) { sb . setLength ( 0 ) ; sb . append ( "text/plain;" ) ; state = State . SEMICOLON_SEEN ; continue ; } else if ( c == ',' ) { contentType = "text/plain;charset=US-ASCII" ; inputStream = is ; return ; } else { throw newDatatypeException ( i , "Expected a token character or a semicolon but saw " , c , " instead." ) ; } case IN_SUPERTYPE : if ( isTokenChar ( c ) ) { continue ; } else if ( c == '/' ) { state = State . AT_SUBTYPE_START ; continue ; } else { throw newDatatypeException ( i , "Expected a token character or “/” but saw " , c , " instead." ) ; } case AT_SUBTYPE_START : if ( isTokenChar ( c ) ) { state = State . IN_SUBTYPE ; continue ; } else { throw newDatatypeException ( i , "Expected a token character but saw " , c , " instead." ) ; } case IN_SUBTYPE : if ( isTokenChar ( c ) ) { continue ; } else if ( c == ';' ) { state = State . SEMICOLON_SEEN ; continue ; } else if ( isWhitespace ( c ) ) { state = State . WS_BEFORE_SEMICOLON ; continue ; } else if ( c == ',' ) { contentType = sb . substring ( 0 , sb . length ( ) - 1 ) ; inputStream = is ; return ; } else { throw newDatatypeException ( i , "Expected a token character, whitespace, a semicolon or a comma but saw " , c , " instead." ) ; } case WS_BEFORE_SEMICOLON : if ( isWhitespace ( c ) ) { continue ; } else if ( c == ';' ) { state = State . SEMICOLON_SEEN ; continue ; } else { throw newDatatypeException ( i , "Expected whitespace or a semicolon but saw " , c , " instead." ) ; } case SEMICOLON_SEEN : if ( isWhitespace ( c ) ) { continue ; } else if ( isTokenChar ( c ) ) { state = State . IN_PARAM_NAME ; continue ; } else { throw newDatatypeException ( i , "Expected whitespace or a token character but saw " , c , " instead." ) ; } case IN_PARAM_NAME : if ( isTokenChar ( c ) ) { continue ; } else if ( c == '=' ) { state = State . EQUALS_SEEN ; continue ; } else if ( c == ',' ) { int baseFirst = sb . length ( ) - 8 ; if ( baseFirst >= 0 && ";base64," . equals ( sb . substring ( baseFirst , sb . length ( ) ) ) ) { contentType = sb . substring ( 0 , baseFirst ) ; inputStream = new Base64InputStream ( is ) ; return ; } } else { throw newDatatypeException ( i , "Expected an equals sign, a comma or a token character but saw " , c , " instead." ) ; } case EQUALS_SEEN : if ( c == '\"' ) { state = State . IN_QUOTED_STRING ; continue ; } else if ( isTokenChar ( c ) ) { state = State . IN_UNQUOTED_STRING ; continue ; } else { throw newDatatypeException ( i , "Expected a double quote or a token character but saw " , c , " instead." ) ; } case IN_QUOTED_STRING : if ( c == '\\' ) { state = State . IN_QUOTED_PAIR ; continue ; } else if ( c == '\"' ) { state = State . CLOSE_QUOTE_SEEN ; continue ; } else if ( isQDTextChar ( c ) ) { continue ; } else { throw newDatatypeException ( i , "Expected a non-control ASCII character but saw " , c , " instead." ) ; } case IN_QUOTED_PAIR : if ( c <= 127 ) { state = State . IN_QUOTED_STRING ; continue ; } else { throw newDatatypeException ( i , "Expected an ASCII character but saw " , c , " instead." ) ; } case CLOSE_QUOTE_SEEN : if ( c == ';' ) { state = State . SEMICOLON_SEEN ; continue ; } else if ( isWhitespace ( c ) ) { state = State . WS_BEFORE_SEMICOLON ; continue ; } else if ( c == ',' ) { contentType = sb . substring ( 0 , sb . length ( ) - 1 ) ; inputStream = is ; return ; } else { throw newDatatypeException ( i , "Expected an ASCII character but saw " , c , " instead." ) ; } case IN_UNQUOTED_STRING : if ( isTokenChar ( c ) ) { continue ; } else if ( c == ';' ) { state = State . SEMICOLON_SEEN ; continue ; } else if ( isWhitespace ( c ) ) { state = State . WS_BEFORE_SEMICOLON ; continue ; } else if ( c == ',' ) { contentType = sb . substring ( 0 , sb . length ( ) - 1 ) ; inputStream = is ; return ; } else { throw newDatatypeException ( i , "Expected a token character, whitespace, a semicolon, or a comma but saw " , c , " instead." ) ; } } } }
@throws IOException, MalformedURLException