/// <summary> /// Read a dictionary of tags. /// </summary> public HaystackDictionary ReadDictionary() { var dictionary = new HaystackDictionary(); bool braces = _currentToken == HaystackToken.lbrace; if (braces) { Consume(HaystackToken.lbrace); } while (_currentToken == HaystackToken.id) { // tag name string id = ConsumeTagName(); if (!char.IsLower(id[0])) { throw GetException("Invalid dict tag name: " + id); } // tag value HaystackValue val = HaystackMarker.Instance; if (_currentToken == HaystackToken.colon) { Consume(HaystackToken.colon); val = ParseValue(); } dictionary.Add(id, val); } if (braces) { Consume(HaystackToken.rbrace); } return(dictionary); }
void VerifyRowIterator(HaystackRow it, int iIndex, string name, HaystackValue val) { Assert.IsTrue(it.Count > iIndex); var strKeyValue = it.Keys.Skip(iIndex).First(); Assert.AreEqual(name, strKeyValue); Assert.IsTrue(it[strKeyValue].Equals(val)); }
public static string ToHayson(HaystackValue val) { using (var stream = new MemoryStream()) using (var streamWriter = new StreamWriter(stream)) using (var writer = new HaysonWriter(streamWriter)) { writer.WriteValue(val); streamWriter.Flush(); stream.Position = 0; return(new StreamReader(stream).ReadToEnd()); } }
private HaystackList ParseList() { List <HaystackValue> arr = new List <HaystackValue>(); Consume(HaystackToken.lbracket); while (_currentToken != HaystackToken.rbracket && _currentToken != HaystackToken.eof) { HaystackValue val = ParseValue(); arr.Add(val); if (_currentToken != HaystackToken.comma) { break; } Consume(HaystackToken.comma); } Consume(HaystackToken.rbracket); return(new HaystackList(arr)); }
/// <summary> /// Read a single value. /// </summary> public HaystackValue ReadValue() { HaystackValue val = null; bool bValisVer = false; if (_currentValue is string) { if (((string)_currentValue).CompareTo("ver") == 0) { bValisVer = true; } } if (_currentToken == HaystackToken.id && bValisVer) { val = ReadGrid(); } else { val = ParseValue(); } // Depart from Java - 15.08.2018 after testing with Java Toolkit // It is possible there might be newlines or other non prihtables before eof // only verify it is not a token of interest bool bEnd = false; while (!bEnd) { if (TryVerify(HaystackToken.nl, false)) { Consume(); } else { // This will throw an exception if it is not eof Verify(HaystackToken.eof); bEnd = true; } } return(val); }
private HaystackGrid ReadGrid() { bool nested = _currentToken == HaystackToken.lt2; if (nested) { Consume(HaystackToken.lt2); if (_currentToken == HaystackToken.nl) { Consume(HaystackToken.nl); } } bool bValisVer = false; if (_currentValue is string) { if (((string)_currentValue).CompareTo("ver") == 0) { bValisVer = true; } } // ver:"3.0" if (_currentToken != HaystackToken.id || !bValisVer) { throw GetException("Expecting grid 'ver' identifier, not " + curToStr()); } Consume(); Consume(HaystackToken.colon); _version = CheckVersion(ConsumeStr()); // grid meta var grid = new HaystackGrid(); if (_currentToken == HaystackToken.id) { var dict = ReadDictionary(); foreach (var kv in dict) { grid.AddMeta(kv.Key, kv.Value); } } Consume(HaystackToken.nl); // column definitions int numCols = 0; while (_currentToken == HaystackToken.id) { ++numCols; string name = ConsumeTagName(); var colMeta = new HaystackDictionary(); if (_currentToken == HaystackToken.id) { colMeta = ReadDictionary(); } grid.AddColumn(name, colMeta); if (_currentToken != HaystackToken.comma) { break; } Consume(HaystackToken.comma); } if (numCols == 0) { throw GetException("No columns defined"); } Consume(HaystackToken.nl); // grid rows while (true) { if (_currentToken == HaystackToken.nl) { break; } if (_currentToken == HaystackToken.eof) { break; } if (nested && _currentToken == HaystackToken.gt2) { break; } // read cells HaystackValue[] cells = new HaystackValue[numCols]; for (int i = 0; i < numCols; ++i) { if (_currentToken == HaystackToken.comma || _currentToken == HaystackToken.nl || _currentToken == HaystackToken.eof) { cells[i] = null; } else { cells[i] = ParseValue(); } if (i + 1 < numCols) { Consume(HaystackToken.comma); } } grid.AddRow(cells); // newline or end if (nested && _currentToken == HaystackToken.gt2) { break; } if (_currentToken == HaystackToken.eof) { break; } Consume(HaystackToken.nl); } if (_currentToken == HaystackToken.nl) { Consume(HaystackToken.nl); } if (nested) { Consume(HaystackToken.gt2); } return(grid); }
public void WriteValue(HaystackValue value) { if (value == null) { _haysonWriter.WriteNull(); return; } if (value is HaystackString strValue) { _haysonWriter.WriteValue(strValue.Value); return; } if (value is HaystackNumber numValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("number"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue(numValue.Value); _haysonWriter.WritePropertyName("unit"); _haysonWriter.WriteValue(numValue.Unit); _haysonWriter.WriteEndObject(); return; } if (value is HaystackBoolean boolValue) { _haysonWriter.WriteValue(boolValue.Value); return; } if (value is HaystackList listValue) { _haysonWriter.WriteStartArray(); foreach (var val in listValue) { WriteValue(val); } _haysonWriter.WriteEndArray(); return; } if (value is HaystackDictionary dictValue) { WriteEntity(dictValue); return; } if (value is HaystackGrid gridValue) { WriteGrid(gridValue); return; } if (value is HaystackMarker) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("marker"); _haysonWriter.WriteEndObject(); return; } if (value is HaystackRemove) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("remove"); _haysonWriter.WriteEndObject(); return; } if (value is HaystackNotAvailable) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("na"); _haysonWriter.WriteEndObject(); return; } if (value is HaystackReference refValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("ref"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue(refValue.Value); _haysonWriter.WritePropertyName("dis"); _haysonWriter.WriteValue(refValue.Display); _haysonWriter.WriteEndObject(); return; } if (value is HaystackDate dateValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("date"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue($"{dateValue.Value.Year:d4}-{dateValue.Value.Month:d2}-{dateValue.Value.Day:d2}"); _haysonWriter.WriteEndObject(); return; } if (value is HaystackTime timeValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("time"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue($"{timeValue.Value.Hours:d2}-{timeValue.Value.Minutes:d2}-{timeValue.Value.Seconds:d2}"); _haysonWriter.WriteEndObject(); return; } if (value is HaystackDateTime dateTimeValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("dateTime"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue(dateTimeValue.Value.ToString("o")); _haysonWriter.WritePropertyName("tz"); _haysonWriter.WriteValue(dateTimeValue.TimeZone.Name); _haysonWriter.WriteEndObject(); return; } if (value is HaystackUri uriValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("uri"); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue(uriValue.Value); _haysonWriter.WriteEndObject(); return; } if (value is HaystackCoordinate coordValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("coord"); _haysonWriter.WritePropertyName("lat"); _haysonWriter.WriteValue(coordValue.Latitude); _haysonWriter.WritePropertyName("lng"); _haysonWriter.WriteValue(coordValue.Longitude); _haysonWriter.WriteEndObject(); return; } if (value is HaystackXString xStrValue) { _haysonWriter.WriteStartObject(); _haysonWriter.WritePropertyName("_kind"); _haysonWriter.WriteValue("xStr"); _haysonWriter.WritePropertyName("type"); _haysonWriter.WriteValue(xStrValue.Type); _haysonWriter.WritePropertyName("val"); _haysonWriter.WriteValue(xStrValue.Value); _haysonWriter.WriteEndObject(); return; } }
protected void VerifyZinc(HaystackValue val, string s) { Assert.AreEqual(s, ZincWriter.ToZinc(val)); Assert.IsTrue(ZincReader.ReadValue(s).Equals(val)); }
public ZincWriter WriteValue(HaystackValue value) { if (value == null) { WriteValue('N'); } else if (value is HaystackBinary bin) { WriteValue("Bin(\"").WriteValue(bin.Mime).WriteValue("\")"); } else if (value is HaystackBoolean boolean) { WriteValue(boolean.Value ? "T" : "F"); } else if (value is HaystackCoordinate coordinate) { WriteValue($"C({coordinate.Latitude.ToString(_numberFormat)},{coordinate.Longitude.ToString(_numberFormat)})"); } else if (value is HaystackDate date) { WriteValue(date.Value.ToString("yyyy-MM-dd")); } else if (value is HaystackDateTime dateTime) { var val = dateTime.Value.ToString("yyyy-MM-dd'T'HH:mm:ss.FFF"); if (dateTime.TimeZone.Name == "UTC") { val += "Z UTC"; } else { val += dateTime.Value.Offset.Hours >= 0 ? "+" : "-"; val += dateTime.Value.Offset.ToString(@"hh\:mm"); val += " "; val += dateTime.TimeZone.Name; } WriteValue(val); } else if (value is HaystackDefinition definition) { WriteValue(definition.Value); } else if (value is HaystackDictionary dictionary) { WriteDictionary(dictionary, true); } else if (value is HaystackGrid) { HaystackGrid grid = (HaystackGrid)value; if (_isInGrid) { WriteNestedGrid(grid); } else { _isInGrid = true; WriteGrid(grid); _isInGrid = false; } } else if (value is HaystackHistoryItem historyItem) { throw new NotImplementedException("Cannot write history item"); } else if (value is HaystackList list) { WriteList(list); } else if (value is HaystackMarker) { WriteValue("M"); } else if (value is HaystackNotAvailable) { WriteValue("NA"); } else if (value is HaystackNumber number) { if (number.Value == double.PositiveInfinity) { WriteValue("INF"); } else if (number.Value == double.NegativeInfinity) { WriteValue("-INF"); } else if (double.IsNaN(number.Value)) { WriteValue("NaN"); } else { double abs = Math.Abs(number.Value); WriteValue(number.Value.ToString("#0.####", _numberFormat)); if (number.Unit != null) { WriteValue(number.Unit); } } } else if (value is HaystackReference reference) { WriteValue($"@{reference.Value}"); if (reference.Display != null) { WriteValue(" "); WriteValue(new HaystackString(reference.Display)); } } else if (value is HaystackRemove) { WriteValue("R"); } else if (value is HaystackString str) { if (str.Value == null) { WriteValue(null); } else { var escaped = str.Value .SelectMany(chr => { switch (chr) { case ('\n'): return(@"\n".ToCharArray()); case ('\r'): return(@"\r".ToCharArray()); case ('\t'): return(@"\t".ToCharArray()); case ('"'): return(@"\""".ToCharArray()); case ('\\'): return(@"\\".ToCharArray()); default: if (chr < ' ') { return((@"\u" + Convert.ToByte(chr).ToString("x4")).ToCharArray()); } return(new[] { chr }); } }) .ToArray(); WriteValue($@"""{new string(escaped)}"""); } } else if (value is HaystackTime time) { if (time.Value.Milliseconds == 0) { WriteValue(time.Value.ToString("hh\\:mm\\:ss")); } else { WriteValue(time.Value.ToString("hh\\:mm\\:ss\\.fff")); } } else if (value is HaystackUri uri) { var escaped = uri.Value .SelectMany(chr => { if (chr == '`') { return(@"\`".ToCharArray()); } if (chr < ' ') { throw new ArgumentException($"Invalid URI '{uri.Value}', char='{chr}'", "uri"); } return(new[] { chr }); }) .ToArray(); WriteValue($@"`{new string(escaped)}`"); } else if (value is HaystackXString xstr) { WriteValue(xstr.Type).WriteValue("(\"").WriteValue(xstr.Value).WriteValue("\")"); } else { throw new InvalidOperationException($"Cannot write scalar value of type {value.GetType().Name}"); } return(this); }
/// <summary> /// Write to a given level of a writable point, and return the current status /// of a writable point's priority array <see cref="pointWriteArray"/>. /// </summary> /// <param name="id">Reference of a writable point.</param> /// <param name="level">Number for level to write [1-17].</param> /// <param name="who">Username performing the write, defaults to user dis.</param> /// <param name="val">Value to write or null to auto the level.</param> /// <param name="dur">Number with duration unit if setting level 8.</param> /// <returns>Result grid.</returns> public Task <HaystackGrid> PointWriteAsync(HaystackReference id, int level, string who, HaystackValue val, HaystackNumber dur) { var req = new HaystackGrid() .AddColumn("id") .AddColumn("level") .AddColumn("who") .AddColumn("val") .AddColumn("duration") .AddRow(id, new HaystackNumber(level), new HaystackString(who), val, dur); return(CallAsync("pointWrite", req)); }