FileDocCategorySizeDatePackage
VParser.javaAPI DocAndroid 1.5 API18856Wed May 06 22:41:56 BST 2009android.syncml.pim

VParser

public abstract class VParser extends Object
This interface is used to parse the V format files, such as VCard & VCal

Fields Summary
protected String
mBuffer
The buffer used to store input stream
protected VBuilder
mBuilder
The builder to build parsed data
protected String
mEncoding
The encoding type
protected final int
PARSE_ERROR
protected final String
mDefaultEncoding
Constructors Summary
Methods Summary
protected java.lang.StringgetWord(int offset)
Get a word from current position.

        StringBuilder word = new StringBuilder();
        try {
            for (;;) {
                char ch = mBuffer.charAt(offset);
                if (isLetterOrDigit(ch) || ch == '-") {
                    word.append(ch);
                    offset++;
                } else {
                    break;
                }
            }
        } catch (IndexOutOfBoundsException e) {
            ;
        }
        return word.toString();
    
protected booleanisLetter(char ch)
If it is a letter.

        if ((ch >= 'a" && ch <= 'z") || (ch >= 'A" && ch <= 'Z")) {
            return true;
        }
        return false;
    
protected booleanisLetterOrDigit(char ch)
If it is a letter or digit.

        if (ch >= '0" && ch <= '9")
            return true;
        if (ch >= 'a" && ch <= 'z")
            return true;
        if (ch >= 'A" && ch <= 'Z")
            return true;
        return false;
    
protected booleanisPrintable(char ch)
If it is printable in ASCII

        if (ch >= ' " && ch <= '~")
            return true;
        return false;
    
public booleanparse(java.io.InputStream is, java.lang.String encoding, VBuilder builder)
Parse the given stream

param
is The source to parse.
param
encoding The encoding type.
param
builder The v builder which used to construct data.
return
Return true for success, otherwise false.
throws
IOException

        setInputStream(is, encoding);
        mBuilder = builder;
        int ret = 0, offset = 0, sum = 0;

        if (mBuilder != null) {
            mBuilder.start();
        }
        for (;;) {
            ret = parseVFile(offset); // for next property length
            if (PARSE_ERROR == ret) {
                break;
            } else {
                offset += ret;
                sum += ret;
            }
        }
        if (mBuilder != null) {
            mBuilder.end();
        }
        return (mBuffer.length() == sum);
    
protected intparse8bit(int offset)
Refer to RFC 1521, 8bit text

        int index = 0;

        index = mBuffer.substring(offset).indexOf("\r\n");

        if (index == -1)
            return PARSE_ERROR;
        else
            return index;

    
protected intparseBase64(int offset)
Refer to RFC 1521, base64 text The end of the text is marked with two CRLF sequences

        int sum = 0;
        try {
            for (;;) {
                char ch;
                ch = mBuffer.charAt(offset);

                if (ch == '\r") {
                    int ret = parseString(offset, "\r\n\r\n", false);
                    sum += ret;
                    break;
                } else {
                    /* ignore none base64 character */
                    sum++;
                    offset++;
                }
            }
        } catch (IndexOutOfBoundsException e) {
            return PARSE_ERROR;
        }
        sum -= 2;/* leave one CRLF to parse the end of this property */
        return sum;
    
protected intparseCharsetVal(int offset)
Refer to RFC1521, section 7.1
If is: "us-ascii" / "iso-8859-xxx" / "X-" word

        int ret = 0, sum = 0;

        ret = parseString(offset, "us-ascii", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-1", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-2", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-3", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-4", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-5", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-6", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-7", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-8", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "iso-8859-9", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseXWord(offset);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        return PARSE_ERROR;
    
protected intparseCrlf(int offset)
If offset reach '\r\n' return 2. Else return PARSE_ERROR.


                  
        
        if (offset >= mBuffer.length())
            return PARSE_ERROR;
        char ch = mBuffer.charAt(offset);
        if (ch == '\r") {
            offset++;
            ch = mBuffer.charAt(offset);
            if (ch == '\n") {
                return 2;
            }
        }
        return PARSE_ERROR;
    
protected intparseLangVal(int offset)
Refer to RFC 1766
like: XXX(sequence letters)-XXX(sequence letters)

        int ret = 0, sum = 0;

        ret = parseTag(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;

        for (;;) {
            ret = parseString(offset, "-", false);
            if (PARSE_ERROR == ret) {
                break;
            }
            offset += ret;
            sum += ret;

            ret = parseTag(offset);
            if (PARSE_ERROR == ret) {
                break;
            }
            offset += ret;
            sum += ret;
        }
        return sum;
    
protected intparseOctet(int offset)
start with "=" two of (DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
So maybe return 3.

        int ret = 0, sum = 0;

        ret = parseString(offset, "=", false);
        if (PARSE_ERROR == ret)
            return PARSE_ERROR;
        offset += ret;
        sum += ret;

        try {
            int ch = mBuffer.charAt(offset);
            if (ch == ' " || ch == '\t")
                return ++sum;
            if ((ch >= '0" && ch <= '9") || (ch >= 'A" && ch <= 'F")) {
                offset++;
                sum++;
                ch = mBuffer.charAt(offset);
                if ((ch >= '0" && ch <= '9") || (ch >= 'A" && ch <= 'F")) {
                    sum++;
                    return sum;
                }
            }
        } catch (IndexOutOfBoundsException e) {
            ;
        }
        return PARSE_ERROR;
    
protected intparsePEncodingVal(int offset)
If is: "7BIT" / "8BIT" / "QUOTED-PRINTABLE" / "BASE64" / "X-" word and set mEncoding.

        int ret = 0, sum = 0;

        ret = parseString(offset, "7BIT", true);
        if (ret != PARSE_ERROR) {
            mEncoding = "7BIT";
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "8BIT", true);
        if (ret != PARSE_ERROR) {
            mEncoding = "8BIT";
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "QUOTED-PRINTABLE", true);
        if (ret != PARSE_ERROR) {
            mEncoding = "QUOTED-PRINTABLE";
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "BASE64", true);
        if (ret != PARSE_ERROR) {
            mEncoding = "BASE64";
            sum += ret;
            return sum;
        }

        ret = parseXWord(offset);
        if (ret != PARSE_ERROR) {
            mEncoding = mBuffer.substring(offset).substring(0, ret);
            sum += ret;
            return sum;
        }

        return PARSE_ERROR;
    
protected intparsePValueVal(int offset)
If is: "INLINE" / "URL" / "CONTENT-ID" / "CID" / "X-" word

        int ret = 0, sum = 0;

        ret = parseString(offset, "INLINE", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "URL", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "CONTENT-ID", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "CID", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseString(offset, "INLINE", true);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        ret = parseXWord(offset);
        if (ret != PARSE_ERROR) {
            sum += ret;
            return sum;
        }

        return PARSE_ERROR;
    
protected intparsePtext(int offset)
return 1 or 3
protected intparseQuotedPrintable(int offset)
Refer to RFC 1521, quoted printable text ([*(ptext / SPACE / TAB) ptext] ["="] CRLF)

        int ret = 0, sum = 0;

        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        for (;;) {
            ret = parsePtext(offset);
            if (PARSE_ERROR == ret)
                break;
            offset += ret;
            sum += ret;

            ret = removeWs(offset);
            offset += ret;
            sum += ret;
        }

        ret = parseString(offset, "=", false);
        if (ret != PARSE_ERROR) {
            // offset += ret;
            sum += ret;
        }

        return sum;
    
protected intparseString(int offset, java.lang.String tar, boolean ignoreCase)
To determine if the given string equals to the start of the current string.

param
offset The offset in buffer of current string
param
tar The given string.
param
ignoreCase To determine case sensitive or not.
return
The consumed characters, otherwise return PARSE_ERROR.

        int sum = 0;
        if (tar == null) {
            return PARSE_ERROR;
        }

        if (ignoreCase) {
            int len = tar.length();
            try {
                if (mBuffer.substring(offset, offset + len).equalsIgnoreCase(
                        tar)) {
                    sum = len;
                } else {
                    return PARSE_ERROR;
                }
            } catch (IndexOutOfBoundsException e) {
                return PARSE_ERROR;
            }

        } else { /* case sensitive */
            if (mBuffer.startsWith(tar, offset)) {
                sum = tar.length();
            } else {
                return PARSE_ERROR;
            }
        }
        return sum;
    
protected intparseTag(int offset)
From first 8 position, is sequence LETTER.

        int sum = 0, i = 0;

        try {
            for (i = 0; i < 8; i++) {
                char ch = mBuffer.charAt(offset);
                if (!isLetter(ch)) {
                    break;
                }
                sum++;
                offset++;
            }
        } catch (IndexOutOfBoundsException e) {
            ;
        }
        if (i == 0) {
            return PARSE_ERROR;
        }
        return sum;
    
protected abstract intparseVFile(int offset)
abstract function, waiting implement.
analyse from offset, return the length of consumed property.

protected intparseValue(int offset)
From offset, parse as :mEncoding ?= 7bit / 8bit / quoted-printable / base64

        int ret = 0;

        if (mEncoding == null || mEncoding.equalsIgnoreCase("7BIT")
                || mEncoding.equalsIgnoreCase("8BIT")
                || mEncoding.toUpperCase().startsWith("X-")) {
            ret = parse8bit(offset);
            if (ret != PARSE_ERROR) {
                return ret;
            }
            return PARSE_ERROR;
        }

        if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
            ret = parseQuotedPrintable(offset);
            if (ret != PARSE_ERROR) {
                return ret;
            }
            return PARSE_ERROR;
        }

        if (mEncoding.equalsIgnoreCase("BASE64")) {
            ret = parseBase64(offset);
            if (ret != PARSE_ERROR) {
                return ret;
            }
            return PARSE_ERROR;
        }
        return PARSE_ERROR;
    
protected intparseWord(int offset)
Any printable ASCII sequence except [ ]=:.,;

        int sum = 0;
        try {
            for (;;) {
                char ch = mBuffer.charAt(offset);
                if (!isPrintable(ch))
                    break;
                if (ch == ' " || ch == '=" || ch == ':" || ch == '."
                        || ch == '," || ch == ';")
                    break;
                if (ch == '\\") {
                    ch = mBuffer.charAt(offset + 1);
                    if (ch == ';") {
                        offset++;
                        sum++;
                    }
                }
                offset++;
                sum++;
            }
        } catch (IndexOutOfBoundsException e) {
            ;
        }
        if (sum == 0)
            return PARSE_ERROR;
        return sum;
    
protected intparseWsls(int offset)
From offset, jump ' ', '\t', '\r\n' sequence, return the length of jump.
1 * (SPACE / HTAB / CRLF)

        int ret = 0, sum = 0;

        try {
            char ch = mBuffer.charAt(offset);
            if (ch == ' " || ch == '\t") {
                sum++;
                offset++;
            } else if ((ret = parseCrlf(offset)) != PARSE_ERROR) {
                offset += ret;
                sum += ret;
            } else {
                return PARSE_ERROR;
            }
            for (;;) {
                ch = mBuffer.charAt(offset);
                if (ch == ' " || ch == '\t") {
                    sum++;
                    offset++;
                } else if ((ret = parseCrlf(offset)) != PARSE_ERROR) {
                    offset += ret;
                    sum += ret;
                } else {
                    break;
                }
            }
        } catch (IndexOutOfBoundsException e) {
            ;
        }
        if (sum > 0)
            return sum;
        return PARSE_ERROR;
    
protected intparseXWord(int offset)
"X-" word, and its value. Return consumed length.

        int ret = 0, sum = 0;
        ret = parseString(offset, "X-", true);
        if (PARSE_ERROR == ret)
            return PARSE_ERROR;
        offset += ret;
        sum += ret;

        ret = parseWord(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        sum += ret;
        return sum;
    
protected intremoveWs(int offset)
Skip the white space in string.

        if (offset >= mBuffer.length())
            return PARSE_ERROR;
        int sum = 0;
        char ch;
        while ((ch = mBuffer.charAt(offset)) == ' " || ch == '\t") {
            offset++;
            sum++;
        }
        return sum;
    
protected voidsetInputStream(java.io.InputStream is, java.lang.String encoding)
Copy the content of input stream and filter the "folding"

        InputStreamReader reader = new InputStreamReader(is, encoding);
        StringBuilder b = new StringBuilder();

        int ch;
        try {
            while ((ch = reader.read()) != -1) {
                if (ch == '\r") {
                    ch = reader.read();
                    if (ch == '\n") {
                        ch = reader.read();
                        if (ch == ' " || ch == '\t") {
                            b.append((char) ch);
                            continue;
                        }
                        b.append("\r\n");
                        if (ch == -1) {
                            break;
                        }
                    } else {
                        b.append("\r");
                    }
                }
                b.append((char) ch);
            }
            mBuffer = b.toString();
        } catch (Exception e) {
            return;
        }
        return;