parse static method

Map<String, String> parse(
  1. String data, {
  2. bool backslash = true,
  3. String defaultValue = "",
})

Parses the given string into a map.

  • The format of data is the same as HTML: = is optional, and
  • the value must be enclosed with ' or ".
    • backslash specifies whether to handle backslash, such \n and \.
    • defaultValue specifies the value to use if it is not specified
  • (i.e., no equal sign).

Implementation

static Map<String, String> parse(String data,
    {bool backslash = true, String defaultValue = ""}) {
  final map = LinkedHashMap<String, String>();
  for (int i = 0, len = data.length; i < len;) {
    i = StringUtil.skipWhitespaces(data, i);
    if (i >= len)
      break; //no more

    final j = i;
    for (; i < len; ++i) {
      final cc = data.codeUnitAt(i);
      if (cc == $equal || $whitespaces.contains(cc))
        break;
      if (cc == $single_quote || cc == $double_quote)
        throw FormatException("Quotation marks not allowed in key, $data");
    }

    final key = data.substring(j, i);
    if (key.isEmpty)
      throw FormatException("Key required, $data");

    i = StringUtil.skipWhitespaces(data, i);
    if (i >= len || data.codeUnitAt(i) != $equal) {
      map[key] = defaultValue;
      if (i >= len)
        break; //done
      continue;
    }

    final val = StringBuffer();
    i = StringUtil.skipWhitespaces(data, i + 1);
    if (i < len) {
      final sep = data.codeUnitAt(i);
      if (sep != $double_quote &&  sep != $single_quote)
        throw FormatException("Quatation marks required for a value, $data");

      for (;;) {
        if (++i >= len)
          throw FormatException("Unclosed string, $data");

        final cc = data.codeUnitAt(i);
        if (cc == sep) {
          ++i;
          break; //done
        }
        if (backslash && cc == $backslash) {
          if (++i >= len)
            throw FormatException("Illegal backslash, $data");
          switch (data.codeUnitAt(i)) {
            case $n: val.write('\n'); continue;
            case $t: val.write('\t'); continue;
            case $b: val.write('\b'); continue;
            case $r: val.write('\r'); continue;
            default: val.writeCharCode(data.codeUnitAt(i)); continue;
          }
        }
        val.writeCharCode(cc);
      }
    } //if i >= 0
    map[key] = val.toString();
  }
  return map;
}