VCard format: correctly co/decode escaped values
[jvcard.git] / src / be / nikiroo / jvcard / Data.java
index 63362332004fede408a44ee37d2fc3460fa0a64d..d6ba628d3353fa2f1b22d0f1440790a06c268631 100644 (file)
@@ -1,6 +1,7 @@
 package be.nikiroo.jvcard;
 
 import java.security.InvalidParameterException;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -68,6 +69,15 @@ public class Data extends BaseClass<TypeInfo> {
         * @return the value
         */
        public String getValue() {
+               return unescape(value);
+       }
+       
+       /**
+        * Return the RAW value of this {@link Data}
+        * 
+        * @return the RAW value
+        */
+       public String getRawValue() {
                return value;
        }
 
@@ -78,6 +88,8 @@ public class Data extends BaseClass<TypeInfo> {
         *            the new value
         */
        public void setValue(String value) {
+               value = escape(value);
+
                if ((value == null && this.value != null)
                                || (value != null && !value.equals(this.value))) {
                        this.value = value;
@@ -85,6 +97,45 @@ public class Data extends BaseClass<TypeInfo> {
                }
        }
 
+       /**
+        * Return the {@link List} of comma-listed values from this {@link Data}.
+        * 
+        * @return the {@link List} of values
+        */
+       public List<String> getValues() {
+               return getList(',');
+       }
+
+       /**
+        * Set the {@link List} of comma-listed values from this {@link Data}.
+        * 
+        * @param values
+        *            the {@link List} of values
+        */
+       public void setValues(List<String> values) {
+               setList(values, ',');
+       }
+
+       /**
+        * Return the {@link List} of semi-column-listed fields from this
+        * {@link Data}.
+        * 
+        * @return the {@link List} of values
+        */
+       public List<String> getFields() {
+               return getList(';');
+       }
+
+       /**
+        * Set the {@link List} of comma-listed values from this {@link Data}.
+        * 
+        * @param values
+        *            the {@link List} of values
+        */
+       public void setFields(List<String> values) {
+               setList(values, ';');
+       }
+
        /**
         * Return the group of this {@link Data}
         * 
@@ -117,6 +168,30 @@ public class Data extends BaseClass<TypeInfo> {
                return b64;
        }
 
+       /**
+        * Check if this {@link Data} is binary
+        * 
+        * @return TRUE if it is
+        */
+       public boolean isBinary() {
+               return b64 >= 0;
+       }
+
+       /**
+        * Check if this {@link Data} has the "preferred" flag.
+        * 
+        * @return TRUE if it has
+        */
+       public boolean isPreferred() {
+               for (TypeInfo type : this) {
+                       if (type.getName().equals("TYPE") && type.getValue().equals("pref")) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
        /**
         * Change the bkey of this {@link Data}
         * 
@@ -138,27 +213,60 @@ public class Data extends BaseClass<TypeInfo> {
        }
 
        /**
-        * Check if this {@link Data} is binary
+        * Return the {@link List} of sep-listed values from this {@link String}
+        * data.
         * 
-        * @return TRUE if it is
+        * @param value
+        *            the data
+        * 
+        * @param the
+        *            separator
+        * 
+        * @return the {@link List} of values
         */
-       public boolean isBinary() {
-               return b64 >= 0;
+       private List<String> getList(char sep) {
+               List<String> rep = new LinkedList<String>();
+
+               if (value != null && value.length() > 0) {
+                       int last = 0;
+                       for (int i = 0; i < value.length(); i++) {
+                               if (value.charAt(i) == sep
+                                               && (i == 0 || value.charAt(i - 1) != '\\')) {
+                                       rep.add(value.substring(last, i - last));
+                               }
+                       }
+
+                       rep.add(value.substring(last));
+               }
+
+               return rep;
        }
 
        /**
-        * Check if this {@link Data} has the "preferred" flag.
+        * Create the {@link String}-encoded {@link List} of sep-listed values from
+        * the given values.
         * 
-        * @return TRUE if it has
+        * @param values
+        *            the {@link List} of values
+        * 
+        * @param sep
+        *            the separator
+        * 
+        * @return the {@link String}
         */
-       public boolean isPreferred() {
-               for (TypeInfo type : this) {
-                       if (type.getName().equals("TYPE") && type.getValue().equals("pref")) {
-                               return true;
-                       }
+       private void setList(List<String> values, char sep) {
+               StringBuilder builder = new StringBuilder();
+               boolean first = true;
+               for (String value : values) {
+                       if (!first)
+                               builder.append(sep);
+
+                       builder.append(escape(value));
+
+                       first = false;
                }
 
-               return false;
+               value = builder.toString();
        }
 
        @Override