02751c1998-09-02Niels Möller /* IMAP.types * */
8b19a01998-09-07Niels Möller string imap_format(mixed x) { if (!x)
d6137d1999-03-04Henrik Grubbström (Grubba)  return "NIL";
8b19a01998-09-07Niels Möller  else if (stringp(x)) return x; else return x->format(); } string imap_format_array(array a) {
9c37b11999-02-23Henrik Grubbström (Grubba) #if 0
d2bc011999-02-23Henrik Grubbström (Grubba)  if (!sizeof(a)) { return(""); } a = Array.map(a, imap_format); string res = a[0]; for(int i=1; i < sizeof(a); i++) { if (sizeof(res) && (res[-1] == '\n')) { // Special case - No space needed. res += a[i]; } else { res += " " + a[i]; } } return res;
9c37b11999-02-23Henrik Grubbström (Grubba) #else /* !0 */ return Array.map(a, imap_format) * " "; #endif /* 0 */
8b19a01998-09-07Niels Möller }
83f18c1999-03-02Henrik Grubbström (Grubba) array imap_check_array(array a) {
d716671999-03-02Henrik Grubbström (Grubba)  return(Array.filter(a, lambda(mixed item, array index) { index[0]++;
83f18c1999-03-02Henrik Grubbström (Grubba)  if (!item || stringp(item) || objectp(item)) { return 1; }
b996a51999-03-02Henrik Grubbström (Grubba)  werror(describe_backtrace( ({
deeec51999-03-02Henrik Grubbström (Grubba)  sprintf("Bad array element %O (%d)\n",
d716671999-03-02Henrik Grubbström (Grubba)  item, index[0]),
b996a51999-03-02Henrik Grubbström (Grubba)  backtrace() }) ));
83f18c1999-03-02Henrik Grubbström (Grubba)  return 0;
d716671999-03-02Henrik Grubbström (Grubba)  }, ({ -1 }) ));
83f18c1999-03-02Henrik Grubbström (Grubba) }
02751c1998-09-02Niels Möller /* Output types */ class imap_atom { string name; void create(string s) { name = s; } string format() { return name; } }
ac64841998-11-16Niels Möller class imap_atom_options { string name; array options; array range;
b75ef31999-03-22Henrik Grubbström (Grubba)  void create(string s, string sec, array o, array r)
ac64841998-11-16Niels Möller  { name = s;
b75ef31999-03-22Henrik Grubbström (Grubba)  options = (sec && ({ sec })) + (o && ({ imap_list(imap_check_array(Array.map(o[0]->list->atom,
e8d8a81999-03-22Henrik Grubbström (Grubba)  imap_string))) }));
ac64841998-11-16Niels Möller  range = r; } string format() {
633a911999-03-08Henrik Grubbström (Grubba)  return upper_case(name + "[" + Array.map(options, imap_format)*" " + "]")
ac64841998-11-16Niels Möller  // NOTE: Only the start index is sent + (range ? sprintf("<%d>", range[0]) : ""); } }
02751c1998-09-02Niels Möller class imap_string { string data; void create(string s) { data = s; } string format() {
8b19a01998-09-07Niels Möller  if (!sizeof(array_sscanf(data, "%*[^\0-\037\177-\377]%s")[0]))
02751c1998-09-02Niels Möller  return "\"" + replace(data, ({ "\"", "\\" }), ({ "\\\"", "\\\\" }) ) + "\""; else return sprintf("{%d}\r\n%s", strlen(data), data); } } class imap_list { array data;
83f18c1999-03-02Henrik Grubbström (Grubba)  void create(array a) { data = imap_check_array(a); }
02751c1998-09-02Niels Möller 
8b19a01998-09-07Niels Möller  string format() { return "(" + imap_format_array(data) + ")"; }
02751c1998-09-02Niels Möller } class imap_prefix { array data;
83f18c1999-03-02Henrik Grubbström (Grubba)  void create(array a) { data = imap_check_array(a); }
02751c1998-09-02Niels Möller 
8b19a01998-09-07Niels Möller  string format() { return "[" + imap_format_array(data) + "]"; }
02751c1998-09-02Niels Möller } class imap_number { int value; void create(int n) { value = n; } string format() { return sprintf("%d", value); } }
2b3c571998-09-23Niels Möller  /* Input types */ // Returns -1 on error. int string_to_number(string s) { if (!strlen(s) || (strlen(s) > 9)) return -1; if (sizeof(values(s) - ({ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }))) return -1; return array_sscanf(s, "%d")[0]; } class imap_set { /* Each element is either an integer, the string "*", or an * array ({ start, end }) */ array items; void create(array|void a) { items = a; } int|string string_to_number_star(string s) { return (s == "*") ? s : string_to_number(s); } int|string|array string_to_subset(string s) { int i = search(s, ":"); if (i<0) return string_to_number_star(s); int|string start = string_to_number_star(s[..i-1]); if (start < 0) return -1; int end = string_to_number_star(s[i+1..]); if (intp(end) && (end < 0)) return -1; if (end == start) return start; return ({ start, end }); } object init(string s) { items = s/","; for(int i = 0; i<sizeof(items); i++) { items[i] = string_to_subset(items[i]); if (intp(items[i]) && (items[i]<0)) return 0; } return this_object(); } int replace_number(int|string i, int largest) { return (i == "*") ? largest : i; } array(int) expand_item(int|string|array item, int largest) { if (arrayp(item)) { int start = replace_number(item[0], largest); int end = replace_number(item[1], largest); if (end > largest) end = largest; if (end < start) return ({ }); array res = allocate(end - start + 1); for(int i = start; i<= end; i++) res[i-start] = i; return res; } int i = replace_number(item, largest); return (i > largest) ? ({ }) : ({ i }); } /* Return a plain array of integers. LARGEST is the number to be * substituted for "*". Handles empty intervals, and cuts away * elements larger than LARGEST. Does not attempt to handle * overlapping intervals intelligently. */ array(int) expand(int largest) { return `+( ({}), @Array.map(items, expand_item, largest)); } }