function lib_array_version()
{
	return 1
}

BEGIN {
# item open: ASCII "start of text"
	LIB_ARRAY_SOPEN  = "\002"
# item close: ASCII "end of text"
	LIB_ARRAY_SCLOSE = "\003"
# index/value separator: ASCII "unit separator"
	LIB_ARRAY_SSEP   = "\036"
}

# print an array; each element in a new line prefixed by prefix
function lib_array_print(prefix, A       ,n)
{
	for(n in A)
		print prefix "[" n "] = '" A[n] "'"
}

# Pack an array to a single string. Optionally use Sopen/Sclose/Ssep for
# separator characters. Each element of the array is packed in the following
# sequence: Sopen <index> Ssep <value> Sclose; index can not contain Ssep,
# but value may contain a full packed array using the same separators.
# If Sopen/Sclose/Ssep are empty, default separators are used
# (LIB_ARRAY_SOPEN/LIB_ARRAY_SCLOSE/LIB_ARRAY_SSEP).
function lib_array_pack(A,    Sopen, Sclose, Ssep,      n,s)
{
	s=""
	if (Sopen  == "") Sopen  = LIB_ARRAY_SOPEN
	if (Sclose == "") Sclose = LIB_ARRAY_SCLOSE
	if (Ssep   == "") Ssep   = LIB_ARRAY_SSEP

	for(n in A)
		s = s Sopen n Ssep A[n] Sclose

	return s
}

# Unpack string to an array. Separator rules are the same as
# for lib_array_pack(). Returns number of indices found (>=0) or
# -1 on syntax error
function lib_array_unpack(ARRAY, str,   Sopen, Sclose, Ssep,      n,len,lvl,c,idx,val,start,idxs)
{
	if (Sopen  == "") Sopen  = LIB_ARRAY_SOPEN
	if (Sclose == "") Sclose = LIB_ARRAY_SCLOSE
	if (Ssep   == "") Ssep   = LIB_ARRAY_SSEP

	len = length(str);
	lvl = 0
	idxs = 0
	for(n = 1; n <= len; n++) {
		c = substr(str, n, 1);
		if (c == Sopen) {
			lvl++;
			if (lvl == 1) {
				n++
				start = n;
				while((substr(str, n, 1) != Ssep) && (n <= len)) n++;
				idx = substr(str, start, n-start)
				start = n+1;
			}
		}
		else if (c == Sclose) {
			lvl--
			if (lvl == 0) {
				ARRAY[idx] = substr(str, start, n-start)
				idxs++
			}
		}
	}
	if (lvl != 0)
		return -1;
	return idxs
}

