FileDocCategorySizeDatePackage
VCalParser_V10.javaAPI DocAndroid 1.5 API40568Wed May 06 22:41:56 BST 2009android.syncml.pim.vcalendar

VCalParser_V10

public class VCalParser_V10 extends android.syncml.pim.VParser

Fields Summary
private static final HashSet
mEvtPropNameGroup1
private static final HashSet
mEvtPropNameGroup2
private static final HashSet
mValueCAT
private static final HashSet
mValueCLASS
private static final HashSet
mValueRES
private static final HashSet
mValueSTAT
private static final HashSet
mEscAllowedProps
private static final HashMap
mSpecialValueSetMap
Constructors Summary
public VCalParser_V10()


     
        mSpecialValueSetMap.put("CATEGORIES", mValueCAT);
        mSpecialValueSetMap.put("CLASS", mValueCLASS);
        mSpecialValueSetMap.put("RESOURCES", mValueRES);
        mSpecialValueSetMap.put("STATUS", mValueSTAT);
    
    
Methods Summary
private java.lang.StringexportEntpropValue(java.lang.String propName, java.lang.String str)
Translate escape characters("\\", "\;") which define in vcalendar1.0 spec. But for fault tolerance, we will translate "\:" and "\,", which isn't define in vcalendar1.0 explicitly, as the same behavior as other client. Though vcalendar1.0 spec does not defined the value of property "description", "summary", "aalarm", "dalarm", "malarm" and "palarm" could contain escape characters, we do support escape characters in these properties.

param
str: the value string will be translated.
return
the string which do not contain any escape character in vcalendar1.0

        if (null == propName || null == str)
            return null;
        if ("".equals(propName) || "".equals(str))
            return "";

        if (!mEscAllowedProps.contains(propName))
            return str;

        String tmp = str.replace("\\\\", "\n\r\n");
        tmp = tmp.replace("\\;", ";");
        tmp = tmp.replace("\\:", ":");
        tmp = tmp.replace("\\,", ",");
        tmp = tmp.replace("\n\r\n", "\\");
        return tmp;
    
private intparseCalentities(int offset)
calentities *CRLF calentity / calentity

        int ret = 0, sum = 0;

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

        for (;;) {
            /* *CRLF */
            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
                offset += ret;
                sum += ret;
            }

            ret = parseCalentity(offset);
            if (PARSE_ERROR == ret) {
                break;
            }
            offset += ret;
            sum += ret;
        }

        return sum;
    
private intparseCalentity(int offset)
evententity / todoentity

        int ret = 0;

        ret = parseEvententity(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseTodoentity(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        return PARSE_ERROR;

    
private intparseCalprop(int offset)
calprop = DAYLIGHT/ GEO/ PRODID/ TZ/ VERSION

        int ret = 0;

        ret = parseCalprop0(offset, "DAYLIGHT");
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseCalprop0(offset, "GEO");
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseCalprop0(offset, "PRODID");
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseCalprop0(offset, "TZ");
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseCalprop1(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        return PARSE_ERROR;
    
private intparseCalprop0(int offset, java.lang.String propName)
propName [params] ":" value CRLF

        int ret = 0, sum = 0, start = 0;

        ret = parseString(offset, propName, true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyName(propName);
        }

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

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

        start = offset;
        ret = parseValue(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            ArrayList<String> v = new ArrayList<String>();
            v.add(mBuffer.substring(start, offset));
            mBuilder.propertyValues(v);
        }

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

        return sum;
    
private intparseCalprop1(int offset)
"VERSION" [params] ":" "1.0" CRLF

        int ret = 0, sum = 0;

        ret = parseString(offset, "VERSION", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyName("VERSION");
        }

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

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

        ret = parseString(offset, "1.0", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            ArrayList<String> v = new ArrayList<String>();
            v.add("1.0");
            mBuilder.propertyValues(v);
        }
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        sum += ret;

        return sum;
    
private intparseCalprops(int offset)
calprops * CRLF calprop / calprop

        int ret = 0, sum = 0;

        if (mBuilder != null) {
            mBuilder.startProperty();
        }
        ret = parseCalprop(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.endProperty();
        }

        for (;;) {
            /* *CRLF */
            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
                offset += ret;
                sum += ret;
            }
            // follow VEVENT ,it wont reach endProperty
            if (mBuilder != null) {
                mBuilder.startProperty();
            }
            ret = parseCalprop(offset);
            if (PARSE_ERROR == ret) {
                break;
            }
            offset += ret;
            sum += ret;
            if (mBuilder != null) {
                mBuilder.endProperty();
            }
        }

        return sum;
    
private intparseEntprop(int offset)
for VEVENT,VTODO prop. entprop0 / entprop1

        int ret = 0;
        ret = parseEntprop0(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseEntprop1(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        return PARSE_ERROR;
    
private intparseEntprop0(int offset)
simprop AND "CLASS" AND "STATUS" The value of these properties are not seperated by ";" [ws] simprop [params] ":" value CRLF

        int ret = 0, sum = 0, start = 0;

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

        String propName = getWord(offset).toUpperCase();
        if (!mEvtPropNameGroup1.contains(propName)) {
            if (PARSE_ERROR == parseXWord(offset))
                return PARSE_ERROR;
        }
        ret = propName.length();
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyName(propName);
        }

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

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

        start = offset;
        ret = parseValue(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            ArrayList<String> v = new ArrayList<String>();
            v.add(exportEntpropValue(propName, mBuffer.substring(start,
                            offset)));
            mBuilder.propertyValues(v);
            // Filter value,match string, REFER:RFC
            if (PARSE_ERROR == valueFilter(propName, v))
                return PARSE_ERROR;
        }

        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        sum += ret;
        return sum;
    
private intparseEntprop1(int offset)
other event prop names except simprop AND "CLASS" AND "STATUS" The value of these properties are seperated by ";" [ws] proper name [params] ":" value CRLF

        int ret = 0, sum = 0;

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

        String propName = getWord(offset).toUpperCase();
        if (!mEvtPropNameGroup2.contains(propName)) {
            return PARSE_ERROR;
        }
        ret = propName.length();
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyName(propName);
        }

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

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

        int start = offset;
        ret = parseValue(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        // mutil-values
        if (mBuilder != null) {
            int end = 0;
            ArrayList<String> v = new ArrayList<String>();
            Pattern p = Pattern
                    .compile("([^;\\\\]*(\\\\[\\\\;:,])*[^;\\\\]*)(;?)");
            Matcher m = p.matcher(mBuffer.substring(start, offset));
            while (m.find()) {
                String s = exportEntpropValue(propName, m.group(1));
                v.add(s);
                end = m.end();
                if (offset == start + end) {
                    String endValue = m.group(3);
                    if (";".equals(endValue)) {
                        v.add("");
                    }
                    break;
                }
            }
            mBuilder.propertyValues(v);
            // Filter value,match string, REFER:RFC
            if (PARSE_ERROR == valueFilter(propName, v))
                return PARSE_ERROR;
        }

        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        sum += ret;
        return sum;
    
private intparseEntprops(int offset)
entprops *CRLF entprop / entprop

        int ret = 0, sum = 0;
        if (mBuilder != null) {
            mBuilder.startProperty();
        }

        ret = parseEntprop(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.endProperty();
        }

        for (;;) {
            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
                offset += ret;
                sum += ret;
            }
            if (mBuilder != null) {
                mBuilder.startProperty();
            }

            ret = parseEntprop(offset);
            if (PARSE_ERROR == ret) {
                break;
            }
            offset += ret;
            sum += ret;
            if (mBuilder != null) {
                mBuilder.endProperty();
            }
        }
        return sum;
    
private intparseEvententity(int offset)
"BEGIN" [ws] ":" [ws] "VEVENT" [ws] 1*CRLF entprops [ws] *CRLF "END" [ws] ":" [ws] "VEVENT" [ws] 1*CRLF

        int ret = 0, sum = 0;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VEVNET"
        ret = parseString(offset, "VEVENT", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.startRecord("VEVENT");
        }

        /* [ws] */
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // 1*CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // *CRLF
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VEVENT"
        ret = parseString(offset, "VEVENT", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.endRecord();
        }

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // 1 * CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

        return sum;
    
private intparseKnownType(int offset)

        int ret = 0;

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

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

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

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

        return PARSE_ERROR;
    
private intparseParam(int offset)
param0 - param7 / knowntype

        int ret = 0;

        ret = parseParam0(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam1(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam2(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam3(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam4(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam5(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam6(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseParam7(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        int start = offset;
        ret = parseKnownType(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(null);
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return ret;
    
private intparseParam0(int offset)
"TYPE" [ws] = [ws] ptypeval

        int ret = 0, sum = 0, start = offset;

        ret = parseString(offset, "TYPE", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parsePtypeval(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }
        return sum;
    
private intparseParam1(int offset)
["VALUE" [ws] "=" [ws]] pvalueval

        int ret = 0, sum = 0, start = offset;
        boolean flag = false;

        ret = parseString(offset, "VALUE", true);
        if (PARSE_ERROR != ret) {
            offset += ret;
            sum += ret;
            flag = true;
        }
        if (flag == true && mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

        ret = parseString(offset, "=", true);
        if (PARSE_ERROR != ret) {
            if (flag == false) { // "VALUE" does not exist
                return PARSE_ERROR;
            }
            offset += ret;
            sum += ret;
        } else {
            if (flag == true) { // "VALUE" exists
                return PARSE_ERROR;
            }
        }

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

        start = offset;
        ret = parsePValueVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;
    
private intparseParam2(int offset)
["ENCODING" [ws] "=" [ws]] pencodingval

        int ret = 0, sum = 0, start = offset;
        boolean flag = false;

        ret = parseString(offset, "ENCODING", true);
        if (PARSE_ERROR != ret) {
            offset += ret;
            sum += ret;
            flag = true;
        }
        if (flag == true && mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

        ret = parseString(offset, "=", true);
        if (PARSE_ERROR != ret) {
            if (flag == false) { // "VALUE" does not exist
                return PARSE_ERROR;
            }
            offset += ret;
            sum += ret;
        } else {
            if (flag == true) { // "VALUE" exists
                return PARSE_ERROR;
            }
        }

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

        start = offset;
        ret = parsePEncodingVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;
    
private intparseParam3(int offset)
"CHARSET" [WS] "=" [WS] charsetval

        int ret = 0, sum = 0, start = offset;

        ret = parseString(offset, "CHARSET", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parseCharsetVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;
    
private intparseParam4(int offset)
"LANGUAGE" [ws] "=" [ws] langval

        int ret = 0, sum = 0, start = offset;

        ret = parseString(offset, "LANGUAGE", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parseLangVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;
    
private intparseParam5(int offset)
"ROLE" [ws] "=" [ws] roleval

        int ret = 0, sum = 0, start = offset;

        ret = parseString(offset, "ROLE", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parseRoleVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;
    
private intparseParam6(int offset)
"STATUS" [ws] = [ws] statuval

        int ret = 0, sum = 0, start = offset;

        ret = parseString(offset, "STATUS", true);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parseStatuVal(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;

    
private intparseParam7(int offset)
XWord [ws] "=" [ws] word

        int ret = 0, sum = 0, start = offset;

        ret = parseXWord(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamType(mBuffer.substring(start, offset));
        }

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

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

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

        start = offset;
        ret = parseWord(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
        }

        return sum;

    
private intparseParamlist(int offset)
Same with card. paramlist [ws] ";" [ws] param / param

        int ret = 0, sum = 0;

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

        int offsetTemp = offset;
        int sumTemp = sum;
        for (;;) {
            ret = removeWs(offsetTemp);
            offsetTemp += ret;
            sumTemp += ret;

            ret = parseString(offsetTemp, ";", false);
            if (PARSE_ERROR == ret) {
                return sum;
            }
            offsetTemp += ret;
            sumTemp += ret;

            ret = removeWs(offsetTemp);
            offsetTemp += ret;
            sumTemp += ret;

            ret = parseParam(offsetTemp);
            if (PARSE_ERROR == ret) {
                break;
            }
            offsetTemp += ret;
            sumTemp += ret;

            // offset = offsetTemp;
            sum = sumTemp;
        }
        return sum;
    
private intparseParams(int offset)
Same with card. ";" [ws] paramlist

        int ret = 0, sum = 0;

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

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

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

        return sum;
    
private intparsePtypeval(int offset)

        int ret = 0;

        ret = parseKnownType(offset);
        if (PARSE_ERROR != ret) {
            return ret;
        }

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

        return PARSE_ERROR;
    
private intparseRoleVal(int offset)
"ATTENDEE" / "ORGANIZER" / "OWNER" / XWORD

        int ret = 0;

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

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

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

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

        return PARSE_ERROR;
    
private intparseStatuVal(int offset)
"ACCEPTED" / "NEED ACTION" / "SENT" / "TENTATIVE" / "CONFIRMED" / "DECLINED" / "COMPLETED" / "DELEGATED / XWORD

        int ret = 0;

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

        ret = parseString(offset, "NEED ACTION", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }

        ret = parseString(offset, "TENTATIVE", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        ret = parseString(offset, "CONFIRMED", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        ret = parseString(offset, "DECLINED", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        ret = parseString(offset, "COMPLETED", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }
        ret = parseString(offset, "DELEGATED", true);
        if (PARSE_ERROR != ret) {
            return ret;
        }

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

        return PARSE_ERROR;
    
private intparseTodoentity(int offset)
"BEGIN" [ws] ":" [ws] "VTODO" [ws] 1*CRLF entprops [ws] *CRLF "END" [ws] ":" [ws] "VTODO" [ws] 1*CRLF

        int ret = 0, sum = 0;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VTODO"
        ret = parseString(offset, "VTODO", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.startRecord("VTODO");
        }

        // 1*CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // *CRLF
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VTODO"
        ret = parseString(offset, "VTODO", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.endRecord();
        }

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // 1 * CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

        return sum;
    
private intparseVCal(int offset)
"BEGIN" [ws] ":" [ws] "VCALENDAR" [ws] 1*crlf calprop calentities [ws] *crlf "END" [ws] ":" [ws] "VCALENDAR" [ws] 1*CRLF

        int ret = 0, sum = 0;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VCALENDAR
        ret = parseString(offset, "VCALENDAR", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.startRecord("VCALENDAR");
        }

        /* [ws] */
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // 1*CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

        // calprop
        ret = parseCalprops(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;

        // calentities
        ret = parseCalentities(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // *CRLF
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

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

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // "VCALENDAR"
        ret = parseString(offset, "VCALENDAR", false);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        if (mBuilder != null) {
            mBuilder.endRecord();
        }

        // [ws]
        ret = removeWs(offset);
        offset += ret;
        sum += ret;

        // 1 * CRLF
        ret = parseCrlf(offset);
        if (PARSE_ERROR == ret) {
            return PARSE_ERROR;
        }
        offset += ret;
        sum += ret;
        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
            offset += ret;
            sum += ret;
        }

        return sum;
    
private intparseVCalFile(int offset)

        int ret = 0, sum = 0;

        /* remove wsls */
        while (PARSE_ERROR != (ret = parseWsls(offset))) {
            offset += ret;
            sum += ret;
        }

        ret = parseVCal(offset); // BEGIN:VCAL ... END:VCAL
        if (PARSE_ERROR != ret) {
            offset += ret;
            sum += ret;
        } else {
            return PARSE_ERROR;
        }

        /* remove wsls */
        while (PARSE_ERROR != (ret = parseWsls(offset))) {
            offset += ret;
            sum += ret;
        }
        return sum;
    
protected intparseVFile(int offset)

        return parseVCalFile(offset);
    
private intvalueFilter(java.lang.String propName, java.util.ArrayList values)
Check 4 special propName and it's value to match Hash.

return
PARSE_ERROR:value not match. 1:go on,like nothing happen.

        if (propName == null || propName.equals("") || values == null
                || values.isEmpty())
            return 1; // go on, like nothing happen.

        if (mSpecialValueSetMap.containsKey(propName)) {
            for (String value : values) {
                if (!mSpecialValueSetMap.get(propName).contains(value)) {
                    if (!value.startsWith("X-"))
                        return PARSE_ERROR;
                }
            }
        }

        return 1;