int MIValue::ParseArray(String const &s, int i) { Clear(); type = MIArray; // drop opening delimiter if(!expect("ParseArray", '[', i, s)) return s.GetCount(); i++; while(s[i] && isspace(s[i])) i++; while(s[i] && s[i] != ']') { while(s[i] && isspace(s[i])) i++; String name; MIValue val; if(s[i] == '[') i = val.ParseArray(s, i); else if(s[i] == '{') i = val.ParseTuple(s, i); else if(s[i] == '"') i = val.ParseString(s, i); else if(s[i] == '<') i = val.ParseAngle(s, i); else i = ParsePair(name, val, s, i); array.Add() = pick(val); while(s[i] && isspace(s[i])) i++; if(s[i] == ']') break; if(!expect("ParseArray", ',', i, s)) return s.GetCount(); i++; } return i + 1; }
int MIValue::ParsePair(String &name, MIValue &val, String const &s, int i) { name.Clear(); val.Clear(); while(s[i] && isspace(s[i])) i++; if(!s[i]) { SetError("ParsePair:Unexpected end of string"); return i; } // is starting wirh '[' or '{' take it as a value with empty name if(s[i] == '{' || s[i] == '[') { name = "<UNNAMED>"; return val.ParseTuple(s, i); } else { int aCount = 0; while(s[i] && ((s[i] != '=' && s[i] != '}' && s[i] != ']' && s[i] != ',') || aCount)) { if(s[i] == '<') aCount++; else if(s[i] == '>') aCount--; if(s[i] == '\\') name.Cat(backslash(s, i)); else name.Cat(s[i]); i++; // skip blanks if not inside <> /* if(!aCount) while(s[i] && isspace(s[i])) i++; */ } while(s[i] && isspace(s[i])) i++; if(s[i] != '=') { // we take the data without = as the value part // of keyless tuple... val.Set(name); name = "<UNNAMED>"; return i; } i++; while(s[i] && isspace(s[i])) i++; } // skip address part before a tuple start, if any... it's useless and confuses the parser if(s[i] == '@') { int j = i; while(s[j] && s[j] != ':') j++; if(s[j] == ':') j++; while(s[j] && IsSpace(s[j])) j++; if(s[j] == '{') i = j; } switch(s[i]) { case '"': i = val.ParseString(s, i); break; break; case '[': i = val.ParseArray(s, i); break; case '{': i = val.ParseTuple(s, i); break; default: i = val.ParseUnquotedString(s, i); break; } return i; }