Example #1
0
  /**
   * Parses the next line of the vCard file.
   *
   * @return the next line or null if there are no more lines
   * @throws InvalidVersionException if a VERSION property with an invalid value is encountered
   * @throws VCardParseException if a line cannot be parsed
   * @throws IOException if there's a problem reading from the input stream
   */
  public VCardRawLine readLine() throws IOException {
    String line = reader.readLine();
    if (line == null) {
      return null;
    }

    String group = null;
    String propertyName = null;
    VCardParameters parameters = new VCardParameters();
    String value = null;

    char escapeChar = 0; // is the next char escaped?
    boolean inQuotes = false; // are we inside of double quotes?
    StringBuilder buffer = new StringBuilder();
    String curParamName = null;
    for (int i = 0; i < line.length(); i++) {
      char ch = line.charAt(i);

      if (escapeChar != 0) {
        // this character was escaped
        if (escapeChar == '\\') {
          if (ch == '\\') {
            buffer.append(ch);
          } else if (ch == 'n' || ch == 'N') {
            // newlines appear as "\n" or "\N" (see RFC 2426 p.7)
            buffer.append(NEWLINE);
          } else if (ch == '"' && version != VCardVersion.V2_1) {
            // double quotes don't need to be escaped in 2.1 parameter values because they have no
            // special meaning
            buffer.append(ch);
          } else if (ch == ';' && version == VCardVersion.V2_1) {
            // semi-colons can only be escaped in 2.1 parameter values (see section 2 of specs)
            // if a 3.0/4.0 param value has semi-colons, the value should be surrounded in double
            // quotes
            buffer.append(ch);
          } else {
            // treat the escape character as a normal character because it's not a valid escape
            // sequence
            buffer.append(escapeChar).append(ch);
          }
        } else if (escapeChar == '^') {
          if (ch == '^') {
            buffer.append(ch);
          } else if (ch == 'n') {
            buffer.append(NEWLINE);
          } else if (ch == '\'') {
            buffer.append('"');
          } else {
            // treat the escape character as a normal character because it's not a valid escape
            // sequence
            buffer.append(escapeChar).append(ch);
          }
        }
        escapeChar = 0;
        continue;
      }

      if (ch == '\\' || (ch == '^' && version != VCardVersion.V2_1 && caretDecodingEnabled)) {
        // an escape character was read
        escapeChar = ch;
        continue;
      }

      if (ch == '.' && group == null && propertyName == null) {
        // set the group
        group = buffer.toString();
        buffer.setLength(0);
        continue;
      }

      if ((ch == ';' || ch == ':') && !inQuotes) {
        if (propertyName == null) {
          // property name
          propertyName = buffer.toString();
        } else {
          // parameter value
          String paramValue = buffer.toString();
          if (version == VCardVersion.V2_1) {
            // 2.1 allows whitespace to surround the "=", so remove it
            paramValue = StringUtils.ltrim(paramValue);
          }
          parameters.put(curParamName, paramValue);
          curParamName = null;
        }
        buffer.setLength(0);

        if (ch == ':') {
          // the rest of the line is the property value
          if (i < line.length() - 1) {
            value = line.substring(i + 1);
          } else {
            value = "";
          }
          break;
        }
        continue;
      }

      if (ch == ',' && !inQuotes && version != VCardVersion.V2_1) {
        // multi-valued parameter
        parameters.put(curParamName, buffer.toString());
        buffer.setLength(0);
        continue;
      }

      if (ch == '=' && curParamName == null) {
        // parameter name
        String paramName = buffer.toString();
        if (version == VCardVersion.V2_1) {
          // 2.1 allows whitespace to surround the "=", so remove it
          paramName = StringUtils.rtrim(paramName);
        }
        curParamName = paramName;
        buffer.setLength(0);
        continue;
      }

      if (ch == '"' && version != VCardVersion.V2_1) {
        // 2.1 doesn't use the quoting mechanism
        inQuotes = !inQuotes;
        continue;
      }

      buffer.append(ch);
    }

    if (propertyName == null || value == null) {
      throw new VCardParseException(line);
    }

    if ("VERSION".equalsIgnoreCase(propertyName)) {
      VCardVersion version = VCardVersion.valueOfByStr(value);
      if (version == null) {
        throw new InvalidVersionException(value, line);
      }
      this.version = version;
    }

    return new VCardRawLine(group, propertyName, parameters, value);
  }
Example #2
0
 /** Closes the underlying {@link Reader} object. */
 public void close() throws IOException {
   reader.close();
 }
Example #3
0
 /**
  * Gets the line number of the last line that was read.
  *
  * @return the line number
  */
 public int getLineNum() {
   return reader.getLineNum();
 }
Example #4
0
 /**
  * Gets the character encoding of the reader.
  *
  * @return the character encoding or null if none is defined
  */
 public Charset getEncoding() {
   return reader.getEncoding();
 }