static PgArrayList buildArrayList()

in pgjdbc/src/main/java/org/postgresql/jdbc/ArrayDecoding.java [576:695]


  static PgArrayList buildArrayList(String fieldString, char delim) {

    final PgArrayList arrayList = new PgArrayList();

    if (fieldString == null) {
      return arrayList;
    }

    final char[] chars = fieldString.toCharArray();
    StringBuilder buffer = null;
    boolean insideString = false;

    // needed for checking if NULL value occurred
    boolean wasInsideString = false;

    // array dimension arrays
    final List<PgArrayList> dims = new ArrayList<PgArrayList>();

    // currently processed array
    PgArrayList curArray = arrayList;

    // Starting with 8.0 non-standard (beginning index
    // isn't 1) bounds the dimensions are returned in the
    // data formatted like so "[0:3]={0,1,2,3,4}".
    // Older versions simply do not return the bounds.
    //
    // Right now we ignore these bounds, but we could
    // consider allowing these index values to be used
    // even though the JDBC spec says 1 is the first
    // index. I'm not sure what a client would like
    // to see, so we just retain the old behavior.
    int startOffset = 0;
    {
      if (chars[0] == '[') {
        while (chars[startOffset] != '=') {
          startOffset++;
        }
        startOffset++; // skip =
      }
    }

    for (int i = startOffset; i < chars.length; i++) {

      // escape character that we need to skip
      if (chars[i] == '\\') {
        i++;
      } else if (!insideString && chars[i] == '{') {
        // subarray start
        if (dims.isEmpty()) {
          dims.add(arrayList);
        } else {
          PgArrayList a = new PgArrayList();
          PgArrayList p = dims.get(dims.size() - 1);
          p.add(a);
          dims.add(a);
        }
        curArray = dims.get(dims.size() - 1);

        // number of dimensions
        {
          for (int t = i + 1; t < chars.length; t++) {
            if (Character.isWhitespace(chars[t])) {
              continue;
            } else if (chars[t] == '{') {
              curArray.dimensionsCount++;
            } else {
              break;
            }
          }
        }

        buffer = new StringBuilder();
        continue;
      } else if (chars[i] == '"') {
        // quoted element
        insideString = !insideString;
        wasInsideString = true;
        continue;
      } else if (!insideString && Parser.isArrayWhiteSpace(chars[i])) {
        // white space
        continue;
      } else if ((!insideString && (chars[i] == delim || chars[i] == '}')) || i == chars.length - 1) {
        // array end or element end
        // when character that is a part of array element
        if (chars[i] != '"' && chars[i] != '}' && chars[i] != delim && buffer != null) {
          buffer.append(chars[i]);
        }

        String b = buffer == null ? null : buffer.toString();

        // add element to current array
        if (b != null && (!b.isEmpty() || wasInsideString)) {
          curArray.add(!wasInsideString && b.equals("NULL") ? null : b);
        }

        wasInsideString = false;
        buffer = new StringBuilder();

        // when end of an array
        if (chars[i] == '}') {
          dims.remove(dims.size() - 1);

          // when multi-dimension
          if (!dims.isEmpty()) {
            curArray = dims.get(dims.size() - 1);
          }

          buffer = null;
        }

        continue;
      }

      if (buffer != null) {
        buffer.append(chars[i]);
      }
    }

    return arrayList;
  }