├── .gitignore
├── .hgignore
├── Examples
├── Client
│ ├── AuthenticationExamples.cs
│ └── CommunicationExamples.cs
├── Examples.csproj
└── Values
│ ├── HaystackDictionaryExamples.cs
│ └── HaystackGridExamples.cs
├── GitVersion.yml
├── LICENSE.txt
├── ProjectHaystack.BackCompat
├── Client
│ ├── HttpAsyncClient.cs
│ ├── IHAsyncClient.cs
│ └── IHClient.cs
├── Mapping
│ └── HaystackValueMapper.cs
├── ProjectHaystack - Backup (1).BackCompat.csproj
├── ProjectHaystack - Backup.BackCompat.csproj
├── ProjectHaystack.BackCompat.csproj
├── ProjectHaystack.BackCompat.nuspec
└── Values
│ ├── CHaystackTZDB.cs
│ ├── HBin.cs
│ ├── HBool.cs
│ ├── HCol.cs
│ ├── HCoord.cs
│ ├── HDate.cs
│ ├── HDateTime.cs
│ ├── HDateTimeRange.cs
│ ├── HDef.cs
│ ├── HDict.cs
│ ├── HDictBuilder.cs
│ ├── HGrid.cs
│ ├── HGridBuilder.cs
│ ├── HHisItem.cs
│ ├── HList.cs
│ ├── HMarker.cs
│ ├── HNA.cs
│ ├── HNum.cs
│ ├── HRef.cs
│ ├── HRemove.cs
│ ├── HRow.cs
│ ├── HStr.cs
│ ├── HTime.cs
│ ├── HTimeZone.cs
│ ├── HUri.cs
│ ├── HVal.cs
│ ├── HXStr.cs
│ └── IHProj.cs
├── ProjectHaystack.sln
├── ProjectHaystack
├── Auth
│ ├── AutodetectAuthenticator.cs
│ ├── BasicAuthenticator.cs
│ ├── IAuthenticator.cs
│ ├── NonHaystackBasicAuthenticator.cs
│ ├── ScramAuthenticator.cs
│ └── Util
│ │ ├── Base64.cs
│ │ └── Pbkdf2.cs
├── Builders
│ └── HaystackDateTimeRangeBuilder.cs
├── Client
│ ├── HaystackClient.cs
│ └── IHaystackClient.cs
├── Constants
│ └── HaystackTimeZoneDatabase.cs
├── Exceptions
│ ├── HaystackAuthException.cs
│ ├── HaystackException.cs
│ └── HaystackUnknownNameException.cs
├── Extensions
│ ├── HaystackDictionaryExtensions.cs
│ ├── IHaystackClientExtensions.cs
│ └── UriExtensions.cs
├── OSS_TimeZoneConverter.txt
├── Program.cs
├── ProjectHaystack.csproj
├── ProjectHaystack.nuspec
├── Properties
│ └── launchSettings.json
├── Validation
│ └── HaystackValidator.cs
├── Values
│ ├── HaystackBinary.cs
│ ├── HaystackBoolean.cs
│ ├── HaystackCaretSymbol.cs
│ ├── HaystackColumn.cs
│ ├── HaystackCoordinate.cs
│ ├── HaystackDate.cs
│ ├── HaystackDateTime.cs
│ ├── HaystackDateTimeRange.cs
│ ├── HaystackDefinition.cs
│ ├── HaystackDictionary.cs
│ ├── HaystackGrid.cs
│ ├── HaystackHistoryItem.cs
│ ├── HaystackList.cs
│ ├── HaystackMarker.cs
│ ├── HaystackNotAvailable.cs
│ ├── HaystackNumber.cs
│ ├── HaystackReference.cs
│ ├── HaystackRemove.cs
│ ├── HaystackRow.cs
│ ├── HaystackString.cs
│ ├── HaystackTime.cs
│ ├── HaystackTimeZone.cs
│ ├── HaystackUri.cs
│ ├── HaystackValue.cs
│ └── HaystackXString.cs
├── app.config
└── io
│ ├── HaysonWriter.cs
│ ├── HaystackToken.cs
│ ├── HaystackTokenizer.cs
│ ├── TrioReader.cs
│ ├── TrioWriter.cs
│ ├── ZincReader.cs
│ └── ZincWriter.cs
├── ProjectHaystackTest
├── Auth
│ └── Util
│ │ ├── Base64Test.cs
│ │ └── Pbkdf2Test.cs
├── BackCompat
│ ├── HBinTest.cs
│ ├── HBoolTest.cs
│ ├── HCoordTest.cs
│ ├── HDateTest.cs
│ ├── HDateTimeRangeTest.cs
│ ├── HDateTimeTest.cs
│ ├── HDefTest.cs
│ ├── HDictTest.cs
│ ├── HGridTest.cs
│ ├── HHisItemTest.cs
│ ├── HListTest.cs
│ ├── HMarkerTest.cs
│ ├── HNumTest.cs
│ ├── HRefTest.cs
│ ├── HRowTest.cs
│ ├── HStrTest.cs
│ ├── HTimeTest.cs
│ ├── HTimeZoneTest.cs
│ ├── HTzTest.cs
│ ├── HUriTest.cs
│ ├── HValTest.cs
│ ├── HXStrTest.cs
│ ├── HaystackTest.cs
│ ├── ProjectHaystackTest.csproj
│ ├── Util
│ │ └── UtilTest.cs
│ ├── packages.config
│ └── playlistBaseLibTests.playlist
├── Builders
│ └── HaystackDateTimeRangeBuilderTests.cs
├── Client
│ └── HaystackClientTest.cs
├── Mocks
│ └── HttpClientMockBuilder.cs
├── Obsolete
│ └── HFilterTest.cs
├── ProjectHaystackTest.csproj
├── Validation
│ └── HaystackValidatorTests.cs
├── Values
│ ├── HaystackBinaryTests.cs
│ ├── HaystackBooleanTests.cs
│ ├── HaystackCoordinateTests.cs
│ ├── HaystackDateTests.cs
│ ├── HaystackDateTimeTests.cs
│ ├── HaystackDefinitionTests.cs
│ ├── HaystackDictionaryTests.cs
│ ├── HaystackGridTests.cs
│ ├── HaystackListTests.cs
│ ├── HaystackMarkerTests.cs
│ ├── HaystackNumberTests.cs
│ ├── HaystackReferenceTests.cs
│ ├── HaystackRowTests.cs
│ ├── HaystackStringTests.cs
│ ├── HaystackTimeTests.cs
│ ├── HaystackTimeZoneTests.cs
│ ├── HaystackUriTests.cs
│ └── HaystackXStringTests.cs
├── io
│ ├── HZincReaderTests.cs
│ ├── HaysonWriterTests.cs
│ ├── TokenizerTests.cs
│ ├── TrioReaderTests.cs
│ ├── TrioWriterTests.cs
│ └── ZincWriterTests.cs
├── packages.config
└── playlistBaseLibTests.playlist
├── README.md
├── build-system
└── unix-pr-validation.yml
└── global.json
/.hgignore:
--------------------------------------------------------------------------------
1 | # ignore files
2 |
3 | # globs in any directory
4 | syntax: glob
5 |
6 | .DS_Store
7 | Thumbs.db
8 | temp/
9 | doc/
10 | staging/
11 | haystack.jar
12 |
13 | # Visual Studio
14 | .vs/
15 | bin/
16 | obj/
17 | packages/
18 | *.csproj.user
19 |
20 | # Nuget
21 | *.nupkg
22 |
--------------------------------------------------------------------------------
/Examples/Client/AuthenticationExamples.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Threading.Tasks;
4 | using ProjectHaystack.Auth;
5 | using ProjectHaystack.Client;
6 |
7 | namespace ProjectHaystack.Examples.Client
8 | {
9 | ///
10 | /// Examples on how to set up an authenticated connection.
11 | /// If your system does not support any of the known authenticators,
12 | /// you can write your own by implementing IAuthenticator.
13 | /// Please be so kind to share your implementation with the world by adding it to this library.
14 | ///
15 | public class AuthenticationExamples
16 | {
17 | ///
18 | /// Connect using scram authentication.
19 | /// This will set a cookie on the HttpClient.
20 | ///
21 | public async Task ConnectUsingScramAuthentication()
22 | {
23 | var user = "someuser";
24 | var pass = "somepassword";
25 | var uri = new Uri("https://someserver/api/");
26 | var auth = new ScramAuthenticator(user, pass);
27 | // When authentications fails in certain legacy systems, set this value to true.
28 | auth.AddLegacySpaceToProof = true;
29 | var client = new HaystackClient(auth, uri);
30 | await client.OpenAsync();
31 | }
32 |
33 | ///
34 | /// Connect using basic authentication.
35 | /// This will usually set a cookie on the HttpClient.
36 | ///
37 | public async Task ConnectUsingBasicAuthentication()
38 | {
39 | var user = "someuser";
40 | var pass = "somepassword";
41 | var uri = new Uri("https://someserver/api/");
42 | var auth = new BasicAuthenticator(user, pass);
43 | var client = new HaystackClient(auth, uri);
44 | await client.OpenAsync();
45 | }
46 |
47 | ///
48 | /// Auto-detect authentication scheme.
49 | ///
50 | public async Task ConnectUsingAutodetectAuthentication()
51 | {
52 | var user = "someuser";
53 | var pass = "somepassword";
54 | var uri = new Uri("https://someserver/api/");
55 | var auth = new AutodetectAuthenticator(user, pass);
56 | var client = new HaystackClient(auth, uri);
57 | await client.OpenAsync();
58 | }
59 |
60 | ///
61 | /// Provide your own HttpClient to get more control over the connection.
62 | ///
63 | public async Task ConnectUsingSharedHttpClient()
64 | {
65 | var user = "someuser";
66 | var pass = "somepassword";
67 | var uri = new Uri("https://someserver/api/");
68 | var auth = new AutodetectAuthenticator(user, pass);
69 | var httpClientHandler = new HttpClientHandler { UseCookies = false, AllowAutoRedirect = false };
70 | var httpClient = new HttpClient(httpClientHandler);
71 | var client = new HaystackClient(httpClient, auth, uri);
72 | await client.OpenAsync();
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/Examples/Client/CommunicationExamples.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Threading.Tasks;
3 | using ProjectHaystack.Client;
4 |
5 | namespace ProjectHaystack.Examples.Client
6 | {
7 | ///
8 | /// Examples on how to communicate with the Haystack server.
9 | ///
10 | public class CommunicationExamples
11 | {
12 | private readonly IHaystackClient _haystackClient;
13 |
14 | public CommunicationExamples(IHaystackClient haystackClient)
15 | {
16 | _haystackClient = haystackClient;
17 | }
18 |
19 | ///
20 | /// Get the about page and read its version.
21 | ///
22 | public async Task About()
23 | {
24 | var about = await _haystackClient.AboutAsync();
25 | var version = about.GetString("haystackVersion");
26 | }
27 |
28 | ///
29 | /// Get the ops page and read its capabilities.
30 | ///
31 | public async Task Ops()
32 | {
33 | var ops = await _haystackClient.OpsAsync();
34 | var capabilities = ops.ToDictionary(row => row.GetString("name"), row => row.GetString("summary"));
35 | }
36 |
37 | ///
38 | /// Do a raw call that will not be parsed.
39 | /// This is useful if you mainly want to use the authentication mechanism,
40 | /// but not the data conversion and do conversion elsewhere.
41 | /// You can use this to get specific data types from the server, like json.
42 | ///
43 | public async Task Raw()
44 | {
45 | string aboutAsJson = await _haystackClient.PostStringAsync("about", string.Empty, "text/zinc", "application/json");
46 | }
47 |
48 | ///
49 | /// When sending more complex requests, like an Axon query in SkySpark
50 | /// you can build and send a grid with a specific operation.
51 | ///
52 | public async Task GridQuery()
53 | {
54 | var axon = "someaxon";
55 | var grid = new HaystackGrid()
56 | .AddColumn("expr")
57 | .AddRow(new HaystackString(axon));
58 | HaystackGrid[] result = await _haystackClient.EvalAllAsync(grid);
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/Examples/Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | ProjectHaystack.$(MSBuildProjectName.Replace(" ", "_"))
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Examples/Values/HaystackDictionaryExamples.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using ProjectHaystack.Client;
3 |
4 | namespace ProjectHaystack.Examples.Values
5 | {
6 |
7 | ///
8 | /// Examples on how to use a HaystackDictionary.
9 | /// Note that the values inherit HaystackValue,
10 | /// so they should be cast to the expected type to access their values.
11 | /// The ProjectHaystack namespace contains various convenience extension methods
12 | /// for common operations, like reading a string value.
13 | ///
14 | public class HaystackDictionaryExamples
15 | {
16 | private readonly IHaystackClient _haystackClient;
17 |
18 | public HaystackDictionaryExamples(IHaystackClient haystackClient)
19 | {
20 | _haystackClient = haystackClient;
21 | }
22 |
23 | ///
24 | /// Various ways to get values from the dictionary.
25 | ///
26 | public async Task GetValues()
27 | {
28 | var about = await _haystackClient.AboutAsync();
29 |
30 | // Getting values using the indexer or Get methods.
31 | var value0 = about["key0"];
32 | var value1 = about.Get("key1");
33 | var value2 = about.Get("key2");
34 | // Accessing any key that does not exist will throw an exception,
35 | // so make sure to check if it exists when you are not sure.
36 | var value3 = about.ContainsKey("key3") ? about.Get("key3") : null;
37 |
38 | // GetString is a convenience method that expects the value
39 | // to be a HaystackString, casts it and gets its value.
40 | var value4 = about.GetString("key4");
41 |
42 | // All *Unchecked convenience methods will not throw an exception
43 | // when the key does not exist, but will return the default value instead.
44 | var value5 = about.GetStringUnchecked("key5");
45 | }
46 |
47 | ///
48 | /// Various ways to build up a new dictionary.
49 | ///
50 | public void BuildDictionary()
51 | {
52 | // Build a dictionary and add values as you would a normal Dictionary.
53 | var dictionary0 = new HaystackDictionary();
54 | dictionary0.Add("key", new HaystackString("value"));
55 | dictionary0.AddMarker("someMarker");
56 | dictionary0.AddNumber("someNumber", 10, "m");
57 |
58 | // Build a dictionary and remove values as you would a normal Dictionary.
59 | var dictionary1 = new HaystackDictionary
60 | {
61 | ["key"] = new HaystackString("value"),
62 | ["someMarker"] = new HaystackMarker(),
63 | };
64 | dictionary1.Remove("someMarker");
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/Examples/Values/HaystackGridExamples.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using ProjectHaystack.Client;
3 |
4 | namespace ProjectHaystack.Examples.Values
5 | {
6 | ///
7 | /// Examples on how to use a HaystackGrid.
8 | /// Note that the rows and metadata inherit HaystackDictionary and can be used as such.
9 | ///
10 | public class HaystackGridExamples
11 | {
12 | private readonly IHaystackClient _haystackClient;
13 |
14 | public HaystackGridExamples(IHaystackClient haystackClient)
15 | {
16 | _haystackClient = haystackClient;
17 | }
18 |
19 | ///
20 | /// Iterate over the grid rows.
21 | ///
22 | public async Task IterateRows()
23 | {
24 | var ops = await _haystackClient.OpsAsync();
25 | foreach (var row in ops)
26 | {
27 | var allKeys = row.Keys;
28 | var hasVersion = row.ContainsKey("haystackVersion");
29 | var version = row["haystackVersion"];
30 | var versionString = (version as HaystackString).Value;
31 | }
32 | }
33 |
34 | ///
35 | /// Select specific grid rows.
36 | ///
37 | public async Task SelectRows()
38 | {
39 | var ops = await _haystackClient.OpsAsync();
40 | var numRows = ops.RowCount;
41 | var tenthRow = ops[9];
42 | var secondRow = ops.Row(1);
43 | }
44 |
45 | ///
46 | /// Get the grid meta data.
47 | ///
48 | public async Task GetMeta()
49 | {
50 | var ops = await _haystackClient.OpsAsync();
51 | var meta = ops.Meta;
52 | var hasKey = meta.ContainsKey("key");
53 | }
54 |
55 | ///
56 | /// Build a new grid.
57 | ///
58 | public void BuildGrid()
59 | {
60 | // Create the grid.
61 | var grid = new HaystackGrid();
62 |
63 | // Add columns before adding rows.
64 |
65 | // Add a simple column.
66 | grid.AddColumn("key");
67 | // Add a column with meta data.
68 | grid.AddColumn("value", new HaystackDictionary { ["meta"] = new HaystackString("value") });
69 | // Add a column with a configuration method.
70 | grid.AddColumn("details", col => col.Meta.AddMarker("isDetails"));
71 |
72 | // Add a row, make sure it has the same number of parameters as there are columns.
73 | grid.AddRow(new HaystackString("someKey"), new HaystackString("someValue"), new HaystackMarker());
74 | // Add a row using an array.
75 | grid.AddRow(new HaystackValue[] { new HaystackString("anotherKey"), new HaystackString("anotherValue"), new HaystackNumber(10, "m") });
76 |
77 | // Add meta data using the default HaystackDictionary functions.
78 | grid.Meta.AddMarker("marker");
79 | // Add meta data using the AddMeta helper method.
80 | grid.AddMeta("key", new HaystackString("value"));
81 | }
82 |
83 | ///
84 | /// Build a new grid using chaining.
85 | ///
86 | public void BuildGridChained()
87 | {
88 | // Create the grid.
89 | var grid = new HaystackGrid()
90 | .AddColumn("key")
91 | .AddColumn("value", new HaystackDictionary { ["meta"] = new HaystackString("value") })
92 | .AddColumn("details", col => col.Meta.AddMarker("isDetails"))
93 | .AddRow(new HaystackString("someKey"), new HaystackString("someValue"), new HaystackMarker())
94 | .AddRow(new HaystackValue[] { new HaystackString("anotherKey"), new HaystackString("anotherValue"), new HaystackNumber(10, "m") })
95 | .AddMeta("marker", new HaystackMarker())
96 | .AddMeta("key", new HaystackString("value"));
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/GitVersion.yml:
--------------------------------------------------------------------------------
1 | mode: Mainline
2 |
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Client/IHAsyncClient.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 |
4 | namespace ProjectHaystack.Client
5 | {
6 | public interface IHAsyncClient : IHClient, IHProj
7 | {
8 | Task EvalAllAsync(HGrid req, bool bChecked);
9 | Task GetStringAsync(string op, Dictionary @params, string mimeRequest = "text/zinc", string mimeResponse = "text/zinc");
10 | Task PostStringAsync(string op, string req, string mimeRequest = "text/zinc", string mimeResponse = "text/zinc");
11 | Task readAllAsync(string filter, int limit);
12 | Task readAsync(string filter, bool bChecked);
13 | Task hisWriteAsync(HRef id, HHisItem[] items);
14 | Task HisWriteAsync(HRef id, HHisItem[] items, HDict metaData = null);
15 | Task HisWriteNoWarnAsync(HRef id, HHisItem[] items);
16 | }
17 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Client/IHClient.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack.Client
2 | {
3 | public interface IHClient
4 | {
5 | HDict about();
6 | HGrid call(string op, HGrid req);
7 | HGrid call(string op, HGrid req, string mimeType);
8 | HGrid eval(string expr);
9 | HGrid[] evalAll(HGrid req, bool bChecked);
10 | HGrid[] evalAll(string[] exprs);
11 | HGrid[] evalAll(string[] exprs, bool bChecked);
12 | HGrid formats();
13 | HGrid hisRead(HRef id, object range);
14 | void hisWrite(HRef id, HHisItem[] items);
15 | HGrid invokeAction(HRef id, string action, HDict args);
16 | HGrid invokeAction(HRef id, string action, HDict args, string mimetype);
17 | HGrid ops();
18 | HGrid pointWrite(HRef id, int level, string who, HVal val, HNum dur);
19 | HGrid pointWriteArray(HRef id);
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/ProjectHaystack - Backup (1).BackCompat.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | ProjectHaystack
6 | ProjectHaystack.Client.BackCompat
7 | true
8 | 2.0.14
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/ProjectHaystack - Backup.BackCompat.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0;netstandard2.1;netstandard2.0
5 | ProjectHaystack
6 | ProjectHaystack.Client.BackCompat
7 | true
8 | 2.0.2
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/ProjectHaystack.BackCompat.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net6.0;net5.0;netstandard2.1;netstandard2.0
5 | ProjectHaystack
6 | ProjectHaystack.Client.BackCompat
7 | true
8 | 2.0.2
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/ProjectHaystack.BackCompat.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $authors$
8 | $author$
9 | AFL-3.0
10 | https://github.com/Strukton-Worksphere/haystack-csharp
11 | false
12 | $description$
13 |
14 | Copyright 2017
15 | haystack backward compatibility
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/CHaystackTZDB.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | [Obsolete("Use HaystackTimeZoneDatabase")]
6 | public class CHaystackTZDB
7 | {
8 | public static string[] tzdb = HaystackTimeZoneDatabase.TimeZones;
9 | }
10 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HBin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackBinary")]
8 | public class HBin : HVal
9 | {
10 | public HBin(HaystackBinary source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackBinary Source { get; }
15 | public string mime => Source.Mime;
16 | public static HBin make(string strMime) => M.Map(new HaystackBinary(strMime));
17 | public override int GetHashCode() => mime.GetHashCode();
18 | public override bool Equals(object that) => that != null && that is HBin dict && Source.Equals(M.Map(dict));
19 | public override string toZinc() => ZincWriter.ToZinc(Source);
20 | public override string toJson() => HaysonWriter.ToHayson(Source);
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HBool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackBoolean")]
8 | public class HBool : HVal
9 | {
10 | public static readonly HBool TRUE = new HBool(true);
11 | public static readonly HBool FALSE = new HBool(false);
12 | public HBool(HaystackBoolean source)
13 | {
14 | Source = source;
15 | }
16 | private HBool(bool val)
17 | {
18 | Source = new HaystackBoolean(val);
19 | }
20 | public HaystackBoolean Source { get; }
21 | public static HBool make(bool bVal) => new HBool(new HaystackBoolean(bVal));
22 | public override int GetHashCode() => Source.GetHashCode();
23 | public override bool Equals(object that) => that != null && that is HBool @bool && Source.Equals(M.Map(@bool));
24 | public bool val => Source.Value;
25 | public override string ToString() => Source.Value.ToString();
26 | public override string toJson() => HaysonWriter.ToHayson(Source);
27 | public override string toZinc() => ZincWriter.ToZinc(Source);
28 | }
29 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HCol.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using M = ProjectHaystack.HaystackValueMapper;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackColumn")]
7 | public class HCol
8 | {
9 | public HCol(HaystackColumn source)
10 | {
11 | Source = source;
12 | }
13 | public HCol(int iIndex, string name, HDict meta)
14 | {
15 | Source = new HaystackColumn(iIndex, name, M.Map(meta));
16 | }
17 | public HaystackColumn Source { get; }
18 | public string Name => Source.Name;
19 | public string dis() => Source.Display;
20 | public HDict meta => M.Map(Source.Meta);
21 | public int Index => Source.Index;
22 | public override int GetHashCode() => Name.GetHashCode() ^ meta.GetHashCode();
23 | public bool hequals(object that) => Equals(that);
24 | public override bool Equals(object that) => that != null && that is HCol col && Source.Equals(M.Map(col));
25 | }
26 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HCoord.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using ProjectHaystack.Validation;
4 | using M = ProjectHaystack.HaystackValueMapper;
5 |
6 | namespace ProjectHaystack
7 | {
8 | [Obsolete("Use HaystackCoordinate")]
9 | public class HCoord : HVal
10 | {
11 | public HCoord(HaystackCoordinate source)
12 | {
13 | Source = source;
14 | }
15 | public HaystackCoordinate Source { get; }
16 | public static HCoord make(string s) => M.Map(ZincReader.ReadValue(s));
17 | public static HCoord make(double dblLat, double dblLng) => M.Map(new HaystackCoordinate((decimal)dblLat, (decimal)dblLng));
18 | public static bool isLat(double lat) => HaystackValidator.IsLatitude((decimal)lat);
19 | public static bool isLng(double lng) => HaystackValidator.IsLongitude((decimal)lng);
20 | public double lat => (double)Source.Latitude;
21 | public double lng => (double)Source.Longitude;
22 | public int ulat => (int)(Source.Latitude * 1000000);
23 | public int ulng => (int)(Source.Longitude * 1000000);
24 | public override int GetHashCode() => Source.GetHashCode();
25 | public override bool Equals(object that) => that != null && that is HCoord coord && Source.Equals(M.Map(coord));
26 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
27 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
28 | }
29 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using ProjectHaystack.io;
4 | using M = ProjectHaystack.HaystackValueMapper;
5 |
6 | namespace ProjectHaystack
7 | {
8 | [Obsolete("Use HaystackDate")]
9 | public class HDate : HVal
10 | {
11 | public HDate(HaystackDate source)
12 | {
13 | Source = source;
14 | }
15 | private HDate(int year, int month, int day)
16 | {
17 | Source = new HaystackDate(year, month, day);
18 | }
19 | public HaystackDate Source { get; }
20 | public int Year => Source.Value.Year;
21 | public int Month => Source.Value.Month;
22 | public int Day => Source.Value.Day;
23 | public static HDate make(int year, int month, int day) => M.Map(new HaystackDate(year, month, day));
24 | public static HDate make(DateTime dt) => M.Map(new HaystackDate(dt));
25 | public static HDate make(string s)
26 | {
27 | DateTime dtParsed = DateTime.Now;
28 | if (!DateTime.TryParseExact(s, "yyyy'-'MM'-'dd",
29 | CultureInfo.InvariantCulture,
30 | DateTimeStyles.None,
31 | out dtParsed))
32 | {
33 | throw new FormatException("Invalid date string: " + s);
34 | }
35 | return new HDate(dtParsed.Year, dtParsed.Month, dtParsed.Day);
36 | }
37 | public static HDate today() => M.Map(new HaystackDate(DateTime.Today));
38 | public HDateTime midnight(HTimeZone tz) => M.Map(new HaystackDateTime(Source.Value, M.Map(tz)));
39 | public override int GetHashCode() => Source.GetHashCode();
40 | public override bool Equals(object that) => that != null && that is HDate date && Source.Equals(M.Map(date));
41 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
42 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
43 | public HDate plusDays(int numDays) => M.Map(new HaystackDate(Source.Value.AddDays(numDays)));
44 | public HDate minusDays(int numDays) => M.Map(new HaystackDate(Source.Value.AddDays(-numDays)));
45 | public static bool isLeapYear(int year) => DateTime.IsLeapYear(year);
46 | public DayOfWeek weekday() => Source.Value.DayOfWeek;
47 | public DateTime ToDateTime() => Source.Value;
48 | }
49 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDateTime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackDateTime")]
8 | public class HDateTime : HVal
9 | {
10 | public HDateTime(HaystackDateTime source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackDateTime Source { get; }
15 | public HDate date => HDate.make(Source.Value.DateTime.Date);
16 | public HTime time => new HTime(Source.Value.DateTime.TimeOfDay);
17 | public TimeSpan Offset => Source.Value.Offset;
18 | public HTimeZone TimeZone => M.Map(Source.TimeZone);
19 | public long Ticks => Source.Value.Ticks;
20 | public DateTimeOffset CopyOfDTO => Source.Value;
21 | public static HDateTime make(HDate date, HTime time, HTimeZone tz) => M.Map(new HaystackDateTime(M.Map(date), M.Map(time), M.Map(tz)));
22 | public static HDateTime make(int year, int month, int day, int hour, int min, int sec, HTimeZone tz)
23 | => M.Map(new HaystackDateTime(new DateTime(year, month, day, hour, min, sec), M.Map(tz)));
24 | public static HDateTime make(int year, int month, int day, int hour, int min, HTimeZone tz)
25 | => M.Map(new HaystackDateTime(new DateTime(year, month, day, hour, min, 0), M.Map(tz)));
26 | public static HDateTime make(long ticks)
27 | => M.Map(new HaystackDateTime(new DateTime(ticks), HaystackTimeZone.UTC));
28 | public static HDateTime make(long ticks, HTimeZone tz)
29 | => M.Map(new HaystackDateTime(new DateTime(ticks), M.Map(tz)));
30 | public static HDateTime make(string s, bool bException)
31 | => M.Checked(() => M.Map(ZincReader.ReadValue(s)), bException);
32 | public static HDateTime now(HTimeZone tz) => M.Map(new HaystackDateTime(DateTime.Now, M.Map(tz)));
33 | public static HDateTime now() => M.Map(new HaystackDateTime(DateTime.Now, HaystackTimeZone.UTC));
34 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
35 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
36 | public override int GetHashCode() => Source.GetHashCode();
37 | public override bool Equals(object that) => that != null && that is HDateTime dateTime && Source.Equals(M.Map(dateTime));
38 | public override string ToString() => ZincWriter.ToZinc(M.Map(this));
39 | public int CompareTo(HDateTime that) => Source.Value.ToUniversalTime().CompareTo(that.Source.Value.ToUniversalTime());
40 | }
41 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDateTimeRange.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackDateTimeRange")]
8 | public class HDateTimeRange
9 | {
10 | public HDateTimeRange(HaystackDateTimeRange source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackDateTimeRange Source { get; }
15 | public HDateTime Start => M.Map(Source.Start);
16 | public HDateTime End => M.Map(Source.End);
17 | public static HDateTimeRange make(HDate date, HTimeZone tz)
18 | => M.Map(new HaystackDateTimeRange(new HaystackDateTime(date.Source.Value, M.Map(tz)), new HaystackDateTime(date.Source.Value.AddDays(1), M.Map(tz))));
19 | public static HDateTimeRange make(HDate start, HDate end, HTimeZone tz)
20 | => M.Map(new HaystackDateTimeRange(new HaystackDateTime(start.Source.Value, M.Map(tz)), new HaystackDateTime(end.Source.Value, M.Map(tz))));
21 | public static HDateTimeRange make(HDateTime start, HDateTime end)
22 | => M.Map(new HaystackDateTimeRange(M.Map(start), M.Map(end)));
23 | public static HDateTimeRange thisWeek(HTimeZone tz)
24 | {
25 | var firstOfWeek = DateTime.Today.AddDays(DayOfWeek.Sunday - DateTime.Today.DayOfWeek);
26 | return M.Map(new HaystackDateTimeRange(
27 | new HaystackDateTime(firstOfWeek, M.Map(tz)),
28 | new HaystackDateTime(firstOfWeek.AddDays(7), M.Map(tz))));
29 | }
30 | public static HDateTimeRange thisMonth(HTimeZone tz)
31 | {
32 | var firstOfMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
33 | return M.Map(new HaystackDateTimeRange(
34 | new HaystackDateTime(firstOfMonth, M.Map(tz)),
35 | new HaystackDateTime(firstOfMonth.AddMonths(1), M.Map(tz))));
36 | }
37 | public static HDateTimeRange thisYear(HTimeZone tz)
38 | {
39 | var firstOfYear = new DateTime(DateTime.Today.Year, 1, 1);
40 | return M.Map(new HaystackDateTimeRange(
41 | new HaystackDateTime(firstOfYear, M.Map(tz)),
42 | new HaystackDateTime(firstOfYear.AddYears(1), M.Map(tz))));
43 | }
44 | public static HDateTimeRange lastWeek(HTimeZone tz)
45 | {
46 | var firstOfWeek = DateTime.Today.AddDays(DayOfWeek.Sunday - DateTime.Today.DayOfWeek).AddDays(-7);
47 | return M.Map(new HaystackDateTimeRange(
48 | new HaystackDateTime(firstOfWeek, M.Map(tz)),
49 | new HaystackDateTime(firstOfWeek.AddDays(7), M.Map(tz))));
50 | }
51 | public static HDateTimeRange lastMonth(HTimeZone tz)
52 | {
53 | var firstOfMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1);
54 | return M.Map(new HaystackDateTimeRange(
55 | new HaystackDateTime(firstOfMonth, M.Map(tz)),
56 | new HaystackDateTime(firstOfMonth.AddMonths(1), M.Map(tz))));
57 | }
58 | public static HDateTimeRange lastYear(HTimeZone tz)
59 | {
60 | var firstOfYear = new DateTime(DateTime.Today.Year, 1, 1).AddYears(-1);
61 | return M.Map(new HaystackDateTimeRange(
62 | new HaystackDateTime(firstOfYear, M.Map(tz)),
63 | new HaystackDateTime(firstOfYear.AddYears(1), M.Map(tz))));
64 | }
65 | public override string ToString() => ZincWriter.ToZinc(Source.Start) + "," + ZincWriter.ToZinc(Source.End);
66 | }
67 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackDefinition")]
8 | public class HDef : HVal
9 | {
10 | public HDef(HaystackDefinition source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackDefinition Source { get; }
15 | public static HDef make(string val) => M.Map(ZincReader.ReadValue(val));
16 | public override int GetHashCode() => Source.GetHashCode();
17 | public override bool Equals(object that) => that != null && that is HDef date && Source.Equals(M.Map(date));
18 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
19 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDict.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using ProjectHaystack.io;
6 | using ProjectHaystack.Validation;
7 | using M = ProjectHaystack.HaystackValueMapper;
8 |
9 | namespace ProjectHaystack
10 | {
11 | [Obsolete("Use HaystackDictionary")]
12 | public class HDict : HVal, IDictionary
13 | {
14 | public HDict(Dictionary map)
15 | {
16 | Source = new HaystackDictionary(map.ToDictionary(kv => kv.Key, kv => M.Map(kv.Value)));
17 | }
18 | public HDict(IDictionary map)
19 | {
20 | Source = new HaystackDictionary(map.ToDictionary(kv => kv.Key, kv => M.Map(kv.Value)));
21 | }
22 | public HDict(HaystackDictionary source)
23 | {
24 | Source = source;
25 | }
26 | public HaystackDictionary Source { get; }
27 |
28 | public static HDict Empty => new HDict(new HaystackDictionary());
29 | public virtual int Size => Source.Count;
30 | public ICollection Keys => Source.Keys;
31 | public ICollection Values => Source.Values.Select(M.Map).ToArray();
32 | public int Count => Source.Count;
33 | public virtual bool IsReadOnly => Source.IsReadOnly;
34 | public HVal this[string key] { get => M.Map(Source[key]); set => Source[key] = M.Map(value); }
35 | public virtual int size() => Source.Count;
36 | public bool isEmpty() => Source.IsEmpty();
37 | public bool has(string name) => Source.ContainsKey(name);
38 | public bool missing(string name) => !Source.ContainsKey(name);
39 | public virtual HVal get(string name) => M.Map(Source.Get(name));
40 | public virtual HVal get(HCol col, bool bChecked) => M.Checked(() => M.Map(Source.Get(col.Name)), bChecked);
41 | public virtual HVal get(string strName, bool bChecked) => M.Checked(() => M.Map(Source.Get(strName)), bChecked);
42 | // TODO
43 | public HVal getVal(int iIndex, bool bChecked) => M.Checked(() => M.Map(Source.Get(Source.Keys.Skip(iIndex).First())), bChecked);
44 | public virtual string getKeyAt(int iIndex, bool bChecked) => M.Checked(() => Source.Keys.Skip(iIndex).First(), bChecked);
45 | public HRef id() => M.Map(Source.GetReference("id"));
46 | public string dis() => Source.Display;
47 | public bool getBool(string name) => Source.GetBoolean(name);
48 | public string getStr(string name) => Source.GetString(name);
49 | public HRef getRef(string name) => M.Map(Source.GetReference(name));
50 | public int getInt(string name) => (int)Source.GetDouble(name);
51 | public double getDouble(string name) => Source.GetDouble(name);
52 | public HDef getDef(string name) => M.Map(Source.Get(name));
53 | public string toString() => ZincWriter.ToZinc(Source);
54 | public override int GetHashCode() => Source.GetHashCode();
55 | public override bool Equals(object that) => that != null && that is HDict dict && Source.Equals(M.Map(dict));
56 | public static bool isTagName(string n) => HaystackValidator.IsTagName(n);
57 | public override string toZinc() => ZincWriter.ToZinc(Source);
58 | public override string toJson() => HaysonWriter.ToHayson(Source);
59 | public virtual void Add(string key, HVal value) => Source.Add(key, M.Map(value));
60 | public bool ContainsKey(string key) => Source.ContainsKey(key);
61 | public virtual bool Remove(string key) => Source.Remove(key);
62 | public bool TryGetValue(string key, out HVal value)
63 | {
64 | if (Source.TryGetValue(key, out var val))
65 | {
66 | value = M.Map(val);
67 | return true;
68 | }
69 | value = null;
70 | return false;
71 | }
72 | public void Add(KeyValuePair item) => Source.Add(item.Key, M.Map(item.Value));
73 | public void Clear() => Source.Clear();
74 | public bool Contains(KeyValuePair item) => Source.Contains(new KeyValuePair(item.Key, M.Map(item.Value)));
75 | public void CopyTo(KeyValuePair[] array, int arrayIndex)
76 | => Source.Select(kv => new KeyValuePair(kv.Key, M.Map(kv.Value))).ToArray().CopyTo(array, arrayIndex);
77 | public bool Remove(KeyValuePair item) => Source.Remove(new KeyValuePair(item.Key, M.Map(item.Value)));
78 | public IEnumerator> GetEnumerator() => Source.Select(kv => new KeyValuePair(kv.Key, M.Map(kv.Value))).GetEnumerator();
79 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
80 | }
81 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HDictBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackDict")]
7 | public class HDictBuilder
8 | {
9 | private Dictionary m_map;
10 |
11 | public HDictBuilder ()
12 | {
13 | m_map = null;
14 | }
15 | public bool isEmpty() { return size() == 0; }
16 | public int size() { return m_map.Count; }
17 | public bool has(string name) { return get(name, false) != null; }
18 | public bool missing(string name) { return get(name, false) == null; }
19 | public HVal get(string name) { return get(name, true); }
20 | public HVal get(string name, bool bchecked)
21 | {
22 | HVal val = null;
23 | if (m_map.ContainsKey(name))
24 | val = m_map[name];
25 | if (val != null) return val;
26 | if (!bchecked) return null;
27 | throw new HaystackUnknownNameException(name);
28 | }
29 | public HDictBuilder add(string name)
30 | {
31 | return add(name, HMarker.VAL);
32 | }
33 | public HDictBuilder add(string name, bool val)
34 | {
35 | return add(name, HBool.make(val));
36 | }
37 | public HDictBuilder add(string name, long val)
38 | {
39 | return add(name, HNum.make(val));
40 | }
41 | public HDictBuilder add(string name, long val, String unit)
42 | {
43 | return add(name, HNum.make(val, unit));
44 | }
45 | public HDictBuilder add(string name, double val)
46 | {
47 | return add(name, HNum.make(val));
48 | }
49 | public HDictBuilder add(string name, double val, string unit)
50 | {
51 | return add(name, HNum.make(val, unit));
52 | }
53 | public HDictBuilder add(string name, string val)
54 | {
55 | return add(name, HStr.make(val));
56 | }
57 | public HDictBuilder add(HDict dict)
58 | {
59 | for (int it = 0; it < dict.size(); it++)
60 | {
61 | string strKey = dict.getKeyAt(it, false);
62 | if (strKey != null)
63 | add(strKey, (HVal)dict.get(strKey,false));
64 | }
65 | return this;
66 | }
67 | public HDictBuilder add(string name, HVal val)
68 | {
69 | if (!HDict.isTagName(name))
70 | throw new InvalidOperationException("Invalid tag name: " + name);
71 | if (m_map == null) m_map = new Dictionary();
72 | m_map.Add(name, val);
73 | return this;
74 | }
75 | public HDict toDict()
76 | {
77 | if (m_map == null || m_map.Count == 0) return HDict.Empty;
78 | HDict dict = new HDict(m_map);
79 | m_map = null;
80 | return dict;
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HGrid.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using ProjectHaystack.io;
7 | using M = ProjectHaystack.HaystackValueMapper;
8 |
9 | namespace ProjectHaystack
10 | {
11 | [Obsolete("Use HaystackGrid")]
12 | public class HGrid : HVal, IEnumerable
13 | {
14 | public HGrid(HaystackGrid source)
15 | {
16 | Source = source;
17 | }
18 | public HaystackGrid Source { get; }
19 |
20 | internal HGrid(HDict meta, List cols, List> rowLists)
21 | {
22 | Source = new HaystackGrid(cols.Select(M.Map).ToList(), rowLists.Select(l => l.Select(M.Map).ToArray()).ToList(), M.Map(meta));
23 | }
24 | public static HGrid InstanceEmpty { get; } = M.Map(new HaystackGrid());
25 |
26 | public HDict meta => M.Map(Source.Meta);
27 | public bool isErr() => Source.IsError();
28 | public bool isEmpty() => Source.IsEmpty();
29 | public int numRows => Source.RowCount;
30 | public HRow row(int row) => M.Map(Source.Row(row));
31 | public int numCols => Source.ColumnCount;
32 | public HCol col(int index) => M.Map(Source.Column(index));
33 | public HCol col(string name) => M.Map(Source.Column(name));
34 | public HCol col(string name, bool bchecked) => M.Checked(() => M.Map(Source.Column(name)), bchecked);
35 | public override string toZinc() => ZincWriter.ToZinc(Source);
36 | public override string toJson() => HaysonWriter.ToHayson(Source);
37 | public override int GetHashCode() => Source.GetHashCode();
38 | public override bool Equals(object that) => that != null && that is HGrid grid && Source.Equals(M.Map(grid));
39 | public void dump()
40 | {
41 | Debug.WriteLine(ZincWriter.ToZinc(Source));
42 | Debug.Flush();
43 | }
44 | public void dumpToConsole()
45 | {
46 | Console.WriteLine(ZincWriter.ToZinc(Source));
47 | }
48 | public string dumpAsString() => ZincWriter.ToZinc(Source);
49 | public IEnumerable Cols => Source.Columns.Select(M.Map);
50 | public IEnumerable Rows => Source.Rows.Select(M.Map);
51 | public IEnumerator GetEnumerator() => Source.Select(M.Map).GetEnumerator();
52 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
53 | }
54 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HHisItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackHistoryItem")]
8 | public class HHisItem : HDict
9 | {
10 | public HHisItem(HaystackHistoryItem source)
11 | : base(ToDictionary(source))
12 | {
13 | Source = source;
14 | }
15 |
16 | public HaystackHistoryItem Source { get; }
17 | public HDateTime TimeStamp => M.Map(Source.TimeStamp);
18 | public HVal hsVal => M.Map(Source.Value);
19 | public int hsize() { return 2; }
20 | public static HHisItem[] gridToItems(HGrid grid) => HaystackHistoryItem.ReadGrid(M.Map(grid)).Select(M.Map).ToArray();
21 | public static HHisItem make(HDateTime ts, HVal val) => M.Map(new HaystackHistoryItem(M.Map(ts), M.Map(val)));
22 | public override HVal get(string name, bool bchecked)
23 | {
24 | if (name.CompareTo("ts") == 0) return TimeStamp;
25 | if (name.CompareTo("val") == 0) return hsVal;
26 | if (!bchecked) return null;
27 | throw new HaystackUnknownNameException("Name not known: " + name);
28 | }
29 |
30 | private static HaystackDictionary ToDictionary(HaystackHistoryItem source)
31 | {
32 | var dict = new HaystackDictionary();
33 | dict.Add("ts", source.TimeStamp);
34 | dict.Add("val", source.Value);
35 | return dict;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using ProjectHaystack.io;
6 | using M = ProjectHaystack.HaystackValueMapper;
7 |
8 | namespace ProjectHaystack
9 | {
10 | [Obsolete("Use HaystackList")]
11 | public class HList : HVal, IEnumerable
12 | {
13 | public HList(HaystackList source)
14 | {
15 | Source = source;
16 | }
17 | public HaystackList Source { get; }
18 | public static HList EMPTY = M.Map(new HaystackList());
19 | public static HList make(params HVal[] items) => M.Map(new HaystackList(items.Select(M.Map).ToArray()));
20 | public static HList make(List items) => M.Map(new HaystackList(items.Select(M.Map).ToArray()));
21 | public int size() => Source.Count;
22 | public HVal get(int i) => M.Map(Source[i]);
23 | public HVal this[int i] => M.Map(Source[i]);
24 | public bool CompareItems(List items)
25 | {
26 | if (items.Count != Source.Count) return false;
27 | bool bRet = true;
28 | for (int i = 0; i < items.Count; i++)
29 | {
30 | if (!items[i].hequals(M.Map(Source[i])))
31 | bRet = false;
32 | }
33 | return bRet;
34 | }
35 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
36 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
37 | public override int GetHashCode() => Source.GetHashCode();
38 | public override bool Equals(object that) => that != null && that is HList list && Source.Equals(M.Map(list));
39 | public IEnumerator GetEnumerator() => Source.Select(M.Map).GetEnumerator();
40 | IEnumerator IEnumerable.GetEnumerator() => Source.Select(M.Map).GetEnumerator();
41 | }
42 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HMarker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using M = ProjectHaystack.HaystackValueMapper;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackMarker")]
7 | public class HMarker : HVal
8 | {
9 | public HMarker(HaystackMarker source)
10 | {
11 | Source = source;
12 | }
13 | public HaystackMarker Source { get; }
14 | public static readonly HMarker VAL = M.Map(new HaystackMarker());
15 |
16 | public override int GetHashCode() => Source.GetHashCode();
17 | public override bool Equals(object that) => that != null && that is HMarker;
18 | public override string ToString() { return "marker"; }
19 | public override string toJson() { return "m:"; }
20 | public override string toZinc() { return "M"; }
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HNA.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using M = ProjectHaystack.HaystackValueMapper;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackNotAvailable")]
7 | public class HNA : HVal
8 | {
9 | public HNA(HaystackNotAvailable source)
10 | {
11 | Source = source;
12 | }
13 | public HaystackNotAvailable Source { get; }
14 | public static HNA VAL = M.Map(new HaystackNotAvailable());
15 |
16 | public override int GetHashCode() => Source.GetHashCode();
17 | public override bool Equals(object that) => that != null && that is HNA;
18 | public override string ToString() { return "na"; }
19 | public override string toJson() { return "z:"; }
20 | public override string toZinc() { return "NA"; }
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HNum.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using ProjectHaystack.Validation;
4 | using M = ProjectHaystack.HaystackValueMapper;
5 |
6 | namespace ProjectHaystack
7 | {
8 | [Obsolete("Use HaystackNumber")]
9 | public class HNum : HVal
10 | {
11 | public HNum(HaystackNumber source)
12 | {
13 | Source = source;
14 | }
15 | public HaystackNumber Source { get; }
16 | public double doubleval => Source.Value;
17 | public string unit => Source.Unit;
18 | public static HNum make(int val) => M.Map(new HaystackNumber(val));
19 | public static HNum make(int val, string unit) => M.Map(new HaystackNumber(val, unit));
20 | public static HNum make(long val) => M.Map(new HaystackNumber(val));
21 | public static HNum make(long val, string unit) => M.Map(new HaystackNumber(val, unit));
22 | public static HNum make(double val) => M.Map(new HaystackNumber(val));
23 | public static HNum make(double val, string unit) => M.Map(new HaystackNumber(val, unit));
24 | public static HNum ZERO = M.Map(HaystackNumber.ZERO);
25 | public static HNum POS_INF = M.Map(HaystackNumber.POS_INF);
26 | public static HNum NEG_INF = M.Map(HaystackNumber.NEG_INF);
27 | public static HNum NaN = M.Map(HaystackNumber.NaN);
28 | public override int GetHashCode() => Source.GetHashCode();
29 | public override bool Equals(object that) => that != null && that is HNum num && Source.Equals(M.Map(num));
30 | public int compareTo(object that) => that is HNum num ? Source.CompareTo(M.Map(num)) : 1;
31 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
32 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
33 | public long millis()
34 | {
35 | string u = Source.Unit;
36 | if (u == null) u = "null";
37 | if ((u.Trim() == "ms") || (u.Trim() == "millisecond")) return (long)doubleval;
38 | if ((u.Trim() == "s") || (u.Trim() == "sec")) return (long)(doubleval * 1000.0); // NOTE: A case was taken out of the Java here - it represented an unreachable test
39 | if ((u.Trim() == "min") || (u.Trim() == "minute")) return (long)(doubleval * 1000.0 * 60.0);
40 | if ((u.Trim() == "h") || (u.Trim() == "hr")) return (long)(doubleval * 1000.0 * 3600.0); // NOTE: A case was taken out of the Java here - it represented an unreachable test
41 | throw new InvalidOperationException("Invalid duration unit: " + u);
42 | }
43 | public static bool isUnitName(string strUnit) => HaystackValidator.IsUnitName(strUnit);
44 | }
45 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HRef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using ProjectHaystack.Validation;
4 | using M = ProjectHaystack.HaystackValueMapper;
5 |
6 | namespace ProjectHaystack
7 | {
8 | [Obsolete("Use HaystackReference")]
9 | public class HRef : HVal
10 | {
11 | public HRef(HaystackReference source)
12 | {
13 | Source = source;
14 | }
15 | public HaystackReference Source { get; }
16 | public string val => Source.Value;
17 | public bool disSet => Source.Display != null;
18 | public static HRef make(string val, string dis) => M.Map(new HaystackReference(val, dis));
19 | public static HRef make(string val) => M.Map(new HaystackReference(val));
20 | public override int GetHashCode() => Source.GetHashCode();
21 | public override bool Equals(object that) => that != null && that is HRef str && Source.Equals(M.Map(str));
22 | public string display() => Source.Display;
23 | public string toCode() => "@" + Source.Value;
24 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
25 | public override string ToString() => Source.Value;
26 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
27 | public static bool isId(string id) => HaystackValidator.IsReferenceId(id);
28 | public static bool isIdChar(int ch) => HaystackValidator.IsReferenceIdChar((char)ch);
29 | public static HRef nullRef = M.Map(new HaystackReference(null));
30 | }
31 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HRemove.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackRemove")]
8 | public class HRemove : HVal
9 | {
10 | public HRemove(HaystackRemove source)
11 | {
12 | Source = source;
13 | }
14 | public static HRemove VAL = M.Map(new HaystackRemove());
15 | public HaystackRemove Source { get; }
16 | public override int GetHashCode() => Source.GetHashCode();
17 | public override bool Equals(object that) => that != null && that is HRemove;
18 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
19 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HRow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using M = ProjectHaystack.HaystackValueMapper;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackRow")]
7 | public class HRow : HDict
8 | {
9 | public HRow(HaystackRow source)
10 | : base(source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackRow Source { get; }
15 | public HGrid Grid => M.Map(Source.Grid);
16 | public HDict ToDict() => M.Map(Source);
17 | public override void Add(string key, HVal value) => Source.Add(key, M.Map(value));
18 | public override bool Remove(string key) => Source.Remove(key);
19 | }
20 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HStr.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackString")]
8 | public class HStr : HVal
9 | {
10 | public HStr(HaystackString source)
11 | {
12 | Source = source;
13 | }
14 | protected HStr(string val)
15 | {
16 | Source = new HaystackString(val);
17 | }
18 | public HaystackString Source { get; }
19 | public static HStr InstanceEmpty => M.Map(HaystackString.Empty);
20 | public static HStr make(string val) => M.Map(new HaystackString(val));
21 | public string Value => Source.Value;
22 |
23 | public override int GetHashCode() => Source.GetHashCode();
24 | public override bool Equals(object that) => that != null && that is HStr str && Source.Equals(M.Map(str));
25 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
26 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
27 | public static string toCode(string val) => ZincWriter.ToZinc(new HaystackString(val));
28 | public static string[] customSplitWithTrim(string str, char[] cSeps, bool bEmpty)
29 | {
30 | string[] strARet;
31 | if (bEmpty)
32 | strARet = str.Split(cSeps, StringSplitOptions.RemoveEmptyEntries);
33 | else
34 | strARet = str.Split(cSeps);
35 | for (int i = 0; i < strARet.Length; i++)
36 | strARet[i] = strARet[i].Trim();
37 | return strARet;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HTime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackTime")]
8 | public class HTime : HVal
9 | {
10 | public HTime(HaystackTime source)
11 | {
12 | Source = source;
13 | }
14 | public HTime(TimeSpan time)
15 | {
16 | Source = new HaystackTime(time);
17 | }
18 | public HaystackTime Source { get; }
19 | public int Hour => Source.Value.Hours;
20 | public int Minute => Source.Value.Minutes;
21 | public int Second => Source.Value.Seconds;
22 | public int Millisecond => Source.Value.Milliseconds;
23 |
24 | public static HTime make(int hour, int min, int sec, int ms)
25 | {
26 | if (hour < 0 || hour > 23) throw new ArgumentException("Invalid hour", "hour");
27 | if (min < 0 || min > 59) throw new ArgumentException("Invalid min", "min");
28 | if (sec < 0 || sec > 59) throw new ArgumentException("Invalid sec", "sec");
29 | if (ms < 0 || ms > 999) throw new ArgumentException("Invalid ms", "ms");
30 | return new HTime(new TimeSpan(0, hour, min, sec, ms));
31 | }
32 | public static HTime make(int hour, int min, int sec)
33 | {
34 | return make(hour, min, sec, 0);
35 | }
36 | public static HTime make(int hour, int min)
37 | {
38 | return make(hour, min, 0, 0);
39 | }
40 | public static HTime make(DateTime dt) => M.Map(new HaystackTime(dt.TimeOfDay));
41 | public static HTime make(string s) => M.Map(ZincReader.ReadValue(s));
42 | public static readonly HTime MIDNIGHT = new HTime(TimeSpan.Zero);
43 | public override int GetHashCode() => Source.GetHashCode();
44 | public override bool Equals(object that) => that != null && that is HTime time && Source.Equals(M.Map(time));
45 | public override int CompareTo(object obj) => obj is HTime time ? Source.CompareTo(M.Map(time)) : -1;
46 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
47 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
48 | public override bool hequals(object that) => Equals(that);
49 | }
50 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HTimeZone.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using M = ProjectHaystack.HaystackValueMapper;
3 |
4 | namespace ProjectHaystack
5 | {
6 | [Obsolete("Use HaystackTimeZone")]
7 | public class HTimeZone
8 | {
9 | public HTimeZone(HaystackTimeZone source)
10 | {
11 | Source = source;
12 | }
13 | public HaystackTimeZone Source { get; }
14 | public static HTimeZone make(string name, bool bChecked) => M.Checked(() => M.Map(new HaystackTimeZone(name)), bChecked);
15 | public static HTimeZone make(TimeZoneInfo dntzi, bool bChecked) => M.Checked(() => M.Map(new HaystackTimeZone(dntzi)), bChecked);
16 | public bool hequals(object that) => that != null && that is HTimeZone tz && Source.Equals(M.Map(tz));
17 | public TimeZoneInfo dntz => Source.TimeZoneInfo;
18 | public static HTimeZone UTC => M.Map(HaystackTimeZone.UTC);
19 | public static HTimeZone REL => M.Map(HaystackTimeZone.REL);
20 | public static HTimeZone Default => M.Map(new HaystackTimeZone(TimeZoneInfo.Local.Id));
21 | public override string ToString() => Source.Name;
22 | }
23 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HUri.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using M = ProjectHaystack.HaystackValueMapper;
4 |
5 | namespace ProjectHaystack
6 | {
7 | [Obsolete("Use HaystackUri")]
8 | public class HUri : HVal
9 | {
10 | public HUri(HaystackUri source)
11 | {
12 | Source = source;
13 | }
14 | public HaystackUri Source { get; }
15 | public string UriVal => Source.Value;
16 | public static HUri make(string val) => M.Map(new HaystackUri(val));
17 | public override int GetHashCode() => Source.GetHashCode();
18 | public override bool Equals(object that) => that != null && that is HUri uri && Source.Equals(M.Map(uri));
19 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
20 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HVal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | [Obsolete("Use HaystackValue")]
6 | public abstract class HVal : IComparable
7 | {
8 | public HVal() { }
9 | public override string ToString() { return toZinc(); }
10 | public abstract string toZinc();
11 | public abstract string toJson();
12 | public virtual bool hequals(object that) => Equals(that);
13 | public virtual int hashCode() => GetHashCode();
14 | public virtual int CompareTo(object obj)
15 | {
16 | return ToString().CompareTo(obj.ToString());
17 | }
18 |
19 | public static bool operator ==(HVal left, HVal right) => Equals(left, null) ? Equals(right, null) : left.Equals(right);
20 | public static bool operator !=(HVal left, HVal right) => !(left == right);
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/HXStr.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.io;
3 | using ProjectHaystack.Validation;
4 | using M = ProjectHaystack.HaystackValueMapper;
5 |
6 | namespace ProjectHaystack
7 | {
8 | [Obsolete("Use HaystackXString")]
9 | public class HXStr : HVal
10 | {
11 | public HXStr(HaystackXString source)
12 | {
13 | Source = source;
14 | }
15 |
16 | public HaystackXString Source { get; }
17 | public string Type => Source.Type;
18 | public string Val => Source.Value;
19 | public static HVal decode(string type, string val)
20 | {
21 | if ("Bin".CompareTo(type) == 0) return HBin.make(val);
22 | return M.Map(new HaystackXString(val, type));
23 | }
24 | public static HXStr encode(object val)
25 | {
26 | return M.Map(new HaystackXString(nameof(val), val.ToString()));
27 | }
28 | private static bool isValidType(string t) => HaystackValidator.IsTypeName(t);
29 | public override string toZinc() => ZincWriter.ToZinc(M.Map(this));
30 | public override string toJson() => HaysonWriter.ToHayson(M.Map(this));
31 | public override int GetHashCode() => Source.GetHashCode();
32 | public override bool Equals(object that) => that != null && that is HXStr str && Source.Equals(M.Map(str));
33 | }
34 | }
--------------------------------------------------------------------------------
/ProjectHaystack.BackCompat/Values/IHProj.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | public interface IHProj
4 | {
5 | HDict about();
6 | HGrid hisRead(HRef id, object range);
7 | void hisWrite(HRef id, HHisItem[] items);
8 | HGrid readAll(string filter, int limit);
9 | HDict readById(HRef id, bool bChecked);
10 | HGrid readByIds(HRef[] ids, bool bChecked);
11 | }
12 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Auth/AutodetectAuthenticator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Net.Http.Headers;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace ProjectHaystack.Auth
9 | {
10 | ///
11 | /// Authentication mechanism that tries to auto-detect the Haystack authentication mechanism.
12 | ///
13 | public class AutodetectAuthenticator : IAuthenticator
14 | {
15 | private readonly string _username;
16 | private readonly string _password;
17 | private const string _wwwAuthenticateHeader = "WWW-Authenticate";
18 |
19 | public AutodetectAuthenticator(string username, string password)
20 | {
21 | _username = username;
22 | _password = password;
23 | }
24 |
25 | public async Task Authenticate(HttpClient client, Uri authUrl)
26 | {
27 | var authenticator = await SendHello(client, authUrl).ConfigureAwait(false);
28 | await authenticator.Authenticate(client, authUrl);
29 | }
30 |
31 | private async Task SendHello(HttpClient client, Uri authUrl)
32 | {
33 | var message = new HttpRequestMessage(HttpMethod.Get, authUrl);
34 | message.Headers.Authorization = new AuthenticationHeaderValue("HELLO",
35 | "username=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(_username)).Trim('='));
36 | using (var response = await client.SendAsync(message))
37 | {
38 | string auth = null;
39 | try
40 | {
41 | auth = response.Headers.GetValues(_wwwAuthenticateHeader).First();
42 | }
43 | catch (InvalidOperationException)
44 | {
45 | throw new InvalidOperationException($"Cannot get authentication header, server response was: {(int)response.StatusCode}");
46 | }
47 |
48 | var authLower = auth.ToLower();
49 |
50 | if (authLower.StartsWith("basic"))
51 | return new BasicAuthenticator(_username, _password);
52 |
53 | if (authLower.StartsWith("scram"))
54 | return new ScramAuthenticator(_username, _password);
55 |
56 | throw new InvalidOperationException($"Autodetect cannot determine authentication type from authentication header: {auth}");
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Auth/BasicAuthenticator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Http;
6 | using System.Net.Http.Headers;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace ProjectHaystack.Auth
11 | {
12 | ///
13 | /// Authentication method using HayStack Basic authentication.
14 | ///
15 | public class BasicAuthenticator : IAuthenticator
16 | {
17 | private readonly string _username;
18 | private readonly string _password;
19 | private const string _wwwAuthenticateHeader = "WWW-Authenticate";
20 |
21 | public BasicAuthenticator(string username, string password)
22 | {
23 | _username = username;
24 | _password = password;
25 | }
26 |
27 | public async Task Authenticate(HttpClient client, Uri authUrl)
28 | {
29 | await SendHello(client, authUrl).ConfigureAwait(false);
30 | await SendFinal(client, authUrl).ConfigureAwait(false);
31 | }
32 |
33 | private async Task SendHello(HttpClient client, Uri authUrl)
34 | {
35 | var message = new HttpRequestMessage(HttpMethod.Get, authUrl);
36 | message.Headers.Authorization = new AuthenticationHeaderValue("HELLO",
37 | "username=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(_username)).Trim('='));
38 | using (var response = await client.SendAsync(message))
39 | {
40 | // https://project-haystack.org/doc/docHaystack/Auth
41 | // If multiple authentication mechanisms are supported, the server SHOULD specify them in order of most preferred to least preferred.
42 | // So, we need to check all of them.
43 | // Header example: SCRAM hash=SHA-256, handshakeToken=aabbcc, PLAINTEXT, BASIC
44 | IEnumerable auth = null;
45 | try
46 | {
47 | auth = response.Headers.GetValues(_wwwAuthenticateHeader);
48 | }
49 | catch (InvalidOperationException)
50 | {
51 | throw new InvalidOperationException($"Cannot get authentication header, server response was: {(int)response.StatusCode}");
52 | }
53 | if (auth.Any(x => x.StartsWith("basic", StringComparison.OrdinalIgnoreCase)))
54 | return;
55 |
56 | string server = response.Headers.Contains("Server") ? (response.Headers.GetValues("Server").FirstOrDefault()?.ToLower() ?? string.Empty) : string.Empty;
57 | // fallback to basic if server says it's Niagara; Niagara 4.6 return empry WWW-Authenticate and Server headers
58 | if (server.StartsWith("niagara", StringComparison.Ordinal) || (response.StatusCode == HttpStatusCode.Unauthorized && (auth.Count() == 0 || auth.All(x => string.IsNullOrEmpty(x))) && string.IsNullOrEmpty(server)))
59 | return;
60 |
61 | // detect N4 by their bug - lolol
62 | var content = await response.Content.ReadAsStringAsync();
63 | if (response.StatusCode == HttpStatusCode.InternalServerError && content != null && content.Contains("wrong 4-byte ending"))
64 | return;
65 |
66 | throw new InvalidOperationException("Invalid reponse on basic authentication request");
67 | }
68 | }
69 |
70 | private async Task SendFinal(HttpClient client, Uri authUrl)
71 | {
72 | try
73 | {
74 | var message = new HttpRequestMessage(HttpMethod.Get, authUrl);
75 | message.Headers.Authorization = new AuthenticationHeaderValue("Basic",
76 | Convert.ToBase64String(Encoding.UTF8.GetBytes(_username + ":" + _password)).Trim('='));
77 | using (var response = await client.SendAsync(message))
78 | {
79 | if ((int)response.StatusCode != 200)
80 | {
81 | throw new HaystackAuthException("Basic auth failed: " + response.StatusCode + " " + (await response.Content.ReadAsStringAsync()));
82 | }
83 | }
84 |
85 | // Set default Authorization header for following requests
86 | client.DefaultRequestHeaders.Authorization = message.Headers.Authorization;
87 | }
88 | catch (Exception e)
89 | {
90 | throw new HaystackAuthException("basic authentication failed", e);
91 | }
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Auth/IAuthenticator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Threading.Tasks;
4 |
5 | namespace ProjectHaystack.Auth
6 | {
7 | ///
8 | /// Defines an authentication mechanism using a HttpClient.
9 | ///
10 | public interface IAuthenticator
11 | {
12 | Task Authenticate(HttpClient client, Uri authUrl);
13 | }
14 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Auth/NonHaystackBasicAuthenticator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Net.Http.Headers;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ProjectHaystack.Auth
8 | {
9 | ///
10 | /// Authentication mechanism using non-Haystack simple Basic authentication.
11 | ///
12 | public class NonHaystackBasicAuthenticator : IAuthenticator
13 | {
14 | private readonly string _username;
15 | private readonly string _password;
16 |
17 | public NonHaystackBasicAuthenticator(string username, string password)
18 | {
19 | _username = username;
20 | _password = password;
21 | }
22 |
23 | public async Task Authenticate(HttpClient client, Uri authUrl)
24 | {
25 | client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
26 | Convert.ToBase64String(Encoding.UTF8.GetBytes(_username + ":" + _password)).Trim('='));
27 | try
28 | {
29 | using (var response = await client.GetAsync(authUrl))
30 | {
31 | if ((int)response.StatusCode != 200)
32 | {
33 | throw new HaystackAuthException("Basic auth failed: " + response.StatusCode + " " + (await response.Content.ReadAsStringAsync()));
34 | }
35 | }
36 | }
37 | catch (Exception e)
38 | {
39 | throw new HaystackAuthException("basic authentication failed", e);
40 | }
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Builders/HaystackDateTimeRangeBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace ProjectHaystack.Builders
5 | {
6 | public class HaystackDateTimeRangeBuilder
7 | {
8 | private readonly HaystackTimeZone _timeZone;
9 | private readonly Func _currentTimeProvider;
10 | private readonly CultureInfo _cultureInfo;
11 |
12 | public HaystackDateTimeRangeBuilder(HaystackTimeZone timeZone, Func currentTimeProvider, CultureInfo cultureInfo)
13 | {
14 | _timeZone = timeZone;
15 | _currentTimeProvider = currentTimeProvider;
16 | _cultureInfo = cultureInfo;
17 | }
18 |
19 | public HaystackDateTimeRangeBuilder(HaystackTimeZone timeZone) : this(timeZone, () => DateTime.Now, CultureInfo.InvariantCulture)
20 | {
21 | }
22 |
23 | public HaystackDateTimeRange Today()
24 | {
25 | var currentTime = _currentTimeProvider();
26 | var start = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day);
27 | return new HaystackDateTimeRange(
28 | new HaystackDateTime(start, _timeZone),
29 | new HaystackDateTime(start.AddDays(1), _timeZone));
30 | }
31 |
32 | public HaystackDateTimeRange Yesterday()
33 | {
34 | var currentTime = _currentTimeProvider();
35 | var start = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day).AddDays(-1);
36 | return new HaystackDateTimeRange(
37 | new HaystackDateTime(start, _timeZone),
38 | new HaystackDateTime(start.AddDays(1), _timeZone));
39 | }
40 |
41 | public HaystackDateTimeRange ThisWeek()
42 | {
43 | var currentTime = _currentTimeProvider();
44 | int diff = (7 + (currentTime.DayOfWeek - _cultureInfo.DateTimeFormat.FirstDayOfWeek)) % 7;
45 | var start = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day).AddDays(-1 * diff);
46 | return new HaystackDateTimeRange(
47 | new HaystackDateTime(start, _timeZone),
48 | new HaystackDateTime(start.AddDays(7), _timeZone));
49 | }
50 |
51 | public HaystackDateTimeRange LastWeek()
52 | {
53 | var currentTime = _currentTimeProvider();
54 | int diff = (7 + (currentTime.DayOfWeek - _cultureInfo.DateTimeFormat.FirstDayOfWeek)) % 7;
55 | var start = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day).AddDays(-1 * diff - 7);
56 | return new HaystackDateTimeRange(
57 | new HaystackDateTime(start, _timeZone),
58 | new HaystackDateTime(start.AddDays(7), _timeZone));
59 | }
60 | public HaystackDateTimeRange ThisMonth()
61 | {
62 | var currentTime = _currentTimeProvider();
63 | var start = new DateTime(currentTime.Year, currentTime.Month, 1);
64 | return new HaystackDateTimeRange(
65 | new HaystackDateTime(start, _timeZone),
66 | new HaystackDateTime(start.AddMonths(1), _timeZone));
67 | }
68 |
69 | public HaystackDateTimeRange LastMonth()
70 | {
71 | var currentTime = _currentTimeProvider();
72 | var start = new DateTime(currentTime.Year, currentTime.Month, 1).AddMonths(-1);
73 | return new HaystackDateTimeRange(
74 | new HaystackDateTime(start, _timeZone),
75 | new HaystackDateTime(start.AddMonths(1), _timeZone));
76 | }
77 |
78 | public HaystackDateTimeRange ThisYear()
79 | {
80 | var currentTime = _currentTimeProvider();
81 | var start = new DateTime(currentTime.Year, 1, 1);
82 | return new HaystackDateTimeRange(
83 | new HaystackDateTime(start, _timeZone),
84 | new HaystackDateTime(start.AddYears(1), _timeZone));
85 | }
86 |
87 | public HaystackDateTimeRange LastYear()
88 | {
89 | var currentTime = _currentTimeProvider();
90 | var start = new DateTime(currentTime.Year, 1, 1).AddYears(-1);
91 | return new HaystackDateTimeRange(
92 | new HaystackDateTime(start, _timeZone),
93 | new HaystackDateTime(start.AddYears(1), _timeZone));
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Exceptions/HaystackAuthException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Exception which is thrown by the authentication framework if an error occurs while trying
7 | /// to authenticat a user.
8 | ///
9 | public class HaystackAuthException : Exception
10 | {
11 | public HaystackAuthException(string s)
12 | : base(s) { }
13 |
14 | public HaystackAuthException(string s, Exception throwable)
15 | : base(s, throwable) { }
16 | }
17 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Exceptions/HaystackException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Exception thrown when a grid is returned with the err marker tag
7 | /// indicating a server side error.
8 | ///
9 | public class HaystackException : Exception
10 | {
11 | public HaystackGrid Grid { get; private set; }
12 |
13 | public HaystackException(HaystackGrid grid)
14 | : base(ReadStringOrNull(grid, "dis") ?? "server side error")
15 | {
16 | Grid = grid;
17 | }
18 |
19 | public string ReadMessage => ReadStringOrNull(Grid, "dis");
20 |
21 | ///
22 | /// Read server side stack trace.
23 | ///
24 | /// Stack trace or null.
25 | public string ReadTrace() => ReadStringOrNull(Grid, "errTrace");
26 |
27 |
28 | private static string ReadStringOrNull(HaystackGrid grid, string tagName)
29 | {
30 | if (!grid.Meta.ContainsKey(tagName))
31 | {
32 | return null;
33 | }
34 | var dis = grid.Meta[tagName];
35 | return dis is HaystackString str ? str.Value : null;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Exceptions/HaystackUnknownNameException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Exception thrown when a checked lookup for a name in a dict or grid finds no such tag.
7 | ///
8 | public class HaystackUnknownNameException : Exception
9 | {
10 | public HaystackUnknownNameException(string message) : base(message)
11 | {
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Extensions/HaystackDictionaryExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | public static class HaystackDictionaryExtensions
4 | {
5 | public static TValue GetUnchecked(this HaystackDictionary dict, string name)
6 | where TValue : HaystackValue
7 | {
8 | if (dict.ContainsKey(name))
9 | return dict.Get(name);
10 | return null;
11 | }
12 |
13 | public static string GetString(this HaystackDictionary dict, string name)
14 | {
15 | return dict.Get(name).Value;
16 | }
17 |
18 | public static string GetStringUnchecked(this HaystackDictionary dict, string name)
19 | {
20 | return dict.GetUnchecked(name)?.Value;
21 | }
22 |
23 | public static bool GetBoolean(this HaystackDictionary dict, string name)
24 | {
25 | return dict.Get(name).Value;
26 | }
27 |
28 | public static bool GetBooleanUnchecked(this HaystackDictionary dict, string name)
29 | {
30 | return dict.GetNullableBoolean(name) ?? false;
31 | }
32 |
33 | public static bool? GetNullableBoolean(this HaystackDictionary dict, string name)
34 | {
35 | return dict.GetUnchecked(name)?.Value;
36 | }
37 |
38 | public static HaystackReference GetReference(this HaystackDictionary dict, string name)
39 | {
40 | return dict.Get(name);
41 | }
42 |
43 | public static HaystackReference GetReferenceUnchecked(this HaystackDictionary dict, string name)
44 | {
45 | return dict.GetUnchecked(name);
46 | }
47 |
48 | public static double GetDouble(this HaystackDictionary dict, string name)
49 | {
50 | return dict.Get(name).Value;
51 | }
52 |
53 | public static double GetDoubleUnchecked(this HaystackDictionary dict, string name)
54 | {
55 | return dict.GetNullableDouble(name) ?? 0;
56 | }
57 |
58 | public static double? GetNullableDouble(this HaystackDictionary dict, string name)
59 | {
60 | return dict.GetUnchecked(name)?.Value;
61 | }
62 |
63 | public static int GetInt(this HaystackDictionary dict, string name)
64 | {
65 | return (int)dict.Get(name).Value;
66 | }
67 |
68 | public static int GetIntUnchecked(this HaystackDictionary dict, string name)
69 | {
70 | return dict.GetNullableInt(name) ?? 0;
71 | }
72 |
73 | public static int? GetNullableInt(this HaystackDictionary dict, string name)
74 | {
75 | return (int?)dict.GetUnchecked(name)?.Value;
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Extensions/IHaystackClientExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 |
4 | namespace ProjectHaystack.Client
5 | {
6 | public static class IHaystackClientExtensions
7 | {
8 | ///
9 | /// Convenience method to call HisWriteNoWarnAsync with a "noWarn" marker to
10 | /// prevent warnings when writing out-of-order data.
11 | /// Record ID.
12 | /// Time-series data.
13 | public static Task HisWriteNoWarnAsync(this IHaystackClient client, HaystackReference id, HaystackHistoryItem[] items)
14 | => HisWriteNoWarnAsync(client, id, items, CancellationToken.None);
15 |
16 | ///
17 | /// Convenience method to call HisWriteNoWarnAsync with a "noWarn" marker to
18 | /// prevent warnings when writing out-of-order data.
19 | /// Record ID.
20 | /// Time-series data.
21 | public static Task HisWriteNoWarnAsync(this IHaystackClient client, HaystackReference id, HaystackHistoryItem[] items, CancellationToken cancellationToken)
22 | {
23 | var meta = new HaystackDictionary();
24 | meta.Add("noWarn", new HaystackMarker());
25 | return client.HisWriteAsync(id, items, cancellationToken, meta);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Extensions/UriExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack.Util
4 | {
5 | public static class UriExtensions
6 | {
7 | ///
8 | /// Ensure a URI ending with a slash.
9 | ///
10 | public static Uri EndWithSlash(this Uri uri)
11 | {
12 | if (uri.AbsolutePath.EndsWith("/"))
13 | {
14 | return uri;
15 | }
16 |
17 | var builder = new UriBuilder(uri);
18 | builder.Path += "/";
19 | return builder.Uri;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack/OSS_TimeZoneConverter.txt:
--------------------------------------------------------------------------------
1 | TimeZoneConverter
2 | Copyright (c) 2017 Matt Johnson
3 | https://github.com/mj1856/TimeZoneConverter
4 |
5 | While we certainly hope this software is useful, none of the authors or
6 | contributors place any guarantees as to the accuracy of the data or the
7 | results returned by using this library.
8 |
9 | This library is distributed under the terms of the MIT License:
10 |
11 | -----------------------------------------------------------------------------
12 | The MIT License (MIT)
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy of
15 | this software and associated documentation files (the "Software"), to deal in
16 | the Software without restriction, including without limitation the rights to
17 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
18 | the Software, and to permit persons to whom the Software is furnished to do so,
19 | subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included in all
22 | copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
26 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
28 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 | -----------------------------------------------------------------------------
--------------------------------------------------------------------------------
/ProjectHaystack/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using ProjectHaystack.Client;
5 |
6 | namespace ProjectHaystack
7 | {
8 | public static class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | if (args.Length != 3)
13 | {
14 | Console.WriteLine("usage: HClient ");
15 | Environment.Exit(0);
16 | }
17 |
18 | RunAsync(args[0], args[1], args[2]).Wait();
19 | }
20 |
21 | public static async Task RunAsync(string uri, string user, string pass)
22 | {
23 | var client = new HaystackClient(user, pass, new Uri(uri));
24 | await client.OpenAsync();
25 | Console.WriteLine(await client.GetStringAsync("about", new Dictionary(), "text/zinc"));
26 | Console.ReadKey();
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/ProjectHaystack/ProjectHaystack.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net6.0;net5.0;netstandard2.1;netstandard2.0
5 | 2.0.0
6 | SkyFoundry and Project Haystack Community
7 | SkyFoundry
8 |
9 | A library for working with the Project Haystack data model for semantic tagging of data. Includes a client for invoking Haystack Ops on compliant servers.
10 | 2017
11 | ProjectHaystack.Client
12 | true
13 | ProjectHaystack.Client
14 | true
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ProjectHaystack/ProjectHaystack.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $authors$
8 | $author$
9 | AFL-3.0
10 | https://github.com/Strukton-Worksphere/haystack-csharp
11 | false
12 | $description$
13 |
14 | Copyright 2017
15 | haystack SCRAM client SkySpark
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ProjectHaystack/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:52378/",
7 | "sslPort": 44390
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "ProjectHaystack": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackBinary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | ///
7 | /// Binary data with mime type.
8 | ///
9 | public class HaystackBinary : HaystackValue
10 | {
11 | public string Mime { get; }
12 |
13 | public HaystackBinary(string mimeType)
14 | {
15 | Mime = HaystackValidator.IsMimeType(mimeType)
16 | ? mimeType
17 | : throw new ArgumentException($"Invalid mime type: {mimeType}", "mimeType");
18 | }
19 |
20 | public override int GetHashCode() => Mime.GetHashCode();
21 |
22 | public override bool Equals(object other) => other != null && other is HaystackBinary bin && Mime.Equals(bin.Mime);
23 | }
24 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackBoolean.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Boolean value.
5 | ///
6 | public class HaystackBoolean : HaystackValue
7 | {
8 | private static readonly HaystackBoolean _true = new HaystackBoolean(true);
9 | private static readonly HaystackBoolean _false = new HaystackBoolean(false);
10 |
11 | public HaystackBoolean(bool value)
12 | {
13 | Value = value;
14 | }
15 |
16 | public static HaystackBoolean True => _true;
17 | public static HaystackBoolean False => _false;
18 |
19 | public bool Value { get; }
20 |
21 | public override int GetHashCode() => Value.GetHashCode();
22 |
23 | public override bool Equals(object other) => other != null && other is HaystackBoolean boolean && boolean.Value == Value;
24 | }
25 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackCaretSymbol.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | public class HaystackCaretSymbol : HaystackValue
7 | {
8 | public HaystackCaretSymbol(string value)
9 | {
10 | Value = value == null || HaystackValidator.IsReferenceId(value)
11 | ? value
12 | : throw new ArgumentException($"Invalid id val: {value}", "value");
13 | }
14 |
15 | public string Value { get; }
16 | public string Code => "^" + Value;
17 |
18 | public override int GetHashCode() => Value.GetHashCode();
19 |
20 | public override bool Equals(object other) => other != null && other is HaystackCaretSymbol caretSymbol && (caretSymbol.Value?.Equals(Value) ?? false);
21 | }
22 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackColumn.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Haystack column information.
5 | ///
6 | public class HaystackColumn
7 | {
8 | public HaystackColumn(int index, string name, HaystackDictionary meta = null)
9 | {
10 | Index = index;
11 | Name = name;
12 | Meta = meta ?? new HaystackDictionary();
13 | }
14 |
15 | public int Index { get; }
16 | public string Name { get; }
17 | public HaystackDictionary Meta { get; }
18 |
19 | public string Display
20 | {
21 | get
22 | {
23 | HaystackValue dis = Meta.ContainsKey("dis") ? Meta["dis"] : null;
24 | return dis is HaystackString str ? str.Value : Name;
25 | }
26 | }
27 |
28 | public override int GetHashCode() => Name.GetHashCode() ^ Meta.GetHashCode();
29 |
30 | public override bool Equals(object other) => other != null && other is HaystackColumn col && Name.Equals(col.Name) && Meta.Equals(col.Meta);
31 | }
32 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackCoordinate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | ///
7 | /// Haystack world coordinate.
8 | ///
9 | public class HaystackCoordinate : HaystackValue
10 | {
11 | public HaystackCoordinate(decimal latitude, decimal longitude)
12 | {
13 | if (!HaystackValidator.IsLatitude(latitude)) throw new ArgumentException("Invalid latitude > +/- 90", "latitude");
14 | if (!HaystackValidator.IsLongitude(longitude)) throw new ArgumentException("Invalid longitude > +/- 180", "longitude");
15 |
16 | Latitude = latitude;
17 | Longitude = longitude;
18 | }
19 |
20 | public decimal Latitude { get; set; }
21 |
22 | public decimal Longitude { get; set; }
23 |
24 | public override int GetHashCode() => Latitude.GetHashCode() ^ Longitude.GetHashCode();
25 |
26 | public override bool Equals(object other)
27 | {
28 | return other != null
29 | && other is HaystackCoordinate coordinate
30 | && Latitude == coordinate.Latitude
31 | && Longitude == coordinate.Longitude;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackDate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Haystack date value.
7 | ///
8 | public class HaystackDate : HaystackValue, IComparable
9 | {
10 | public HaystackDate(DateTime date)
11 | {
12 | Value = date.Date;
13 | }
14 |
15 | public HaystackDate(int year, int month, int day)
16 | {
17 | Value = new DateTime(year, month, day);
18 | }
19 |
20 | public DateTime Value { get; }
21 |
22 | public static HaystackDate Today => new HaystackDate(DateTime.Today);
23 |
24 | public override int GetHashCode() => Value.GetHashCode();
25 |
26 | public override bool Equals(object other) => other != null && other is HaystackDate date && date.Value == Value;
27 |
28 | public int CompareTo(object obj)
29 | {
30 | #if NETSTANDARD2_0 || NETSTANDARD2_1
31 | if (obj == null || !(obj is HaystackDate date))
32 | {
33 | return 1;
34 | }
35 | #else
36 | if (obj == null || obj is not HaystackDate date)
37 | {
38 | return 1;
39 | }
40 | #endif
41 |
42 | return Value.CompareTo(date.Value);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackDateTime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Haystack date and time value including timezone.
7 | ///
8 | public class HaystackDateTime : HaystackValue
9 | {
10 | public HaystackDateTime(DateTimeOffset dateTime, HaystackTimeZone timeZone)
11 | {
12 | Value = dateTime;
13 | TimeZone = timeZone;
14 | }
15 |
16 | public HaystackDateTime(DateTime dateTime, HaystackTimeZone timeZone)
17 | {
18 | Value = new DateTimeOffset(dateTime.Ticks, timeZone.TimeZoneInfo.GetUtcOffset(dateTime));
19 | TimeZone = timeZone;
20 | }
21 |
22 | public HaystackDateTime(HaystackDate date, HaystackTime time, HaystackTimeZone timeZone)
23 | : this(date.Value + time.Value, timeZone)
24 | {
25 | }
26 |
27 | public DateTimeOffset Value { get; private set; }
28 |
29 | public HaystackTimeZone TimeZone { get; private set; }
30 |
31 | public static HaystackDateTime Now(HaystackTimeZone tz) => new HaystackDateTime(System.DateTime.Now, tz);
32 |
33 | public static HaystackDateTime Now() => new HaystackDateTime(System.DateTime.Now, HaystackTimeZone.UTC);
34 |
35 | public override int GetHashCode() => Value.GetHashCode() ^ TimeZone.GetHashCode();
36 |
37 | public override bool Equals(object other)
38 | {
39 | return other != null
40 | && other is HaystackDateTime dateTime
41 | && dateTime.Value.Equals(Value)
42 | && dateTime.TimeZone.Equals(TimeZone);
43 | }
44 |
45 | public int CompareTo(HaystackDateTime other) => Value.ToUniversalTime().CompareTo(other.Value.ToUniversalTime());
46 | }
47 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackDateTimeRange.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Haystack date and time range.
5 | /// Inclusive start, exclusive end.
6 | ///
7 | public class HaystackDateTimeRange
8 | {
9 | public HaystackDateTimeRange(HaystackDateTime start, HaystackDateTime end)
10 | {
11 | Start = start;
12 | End = end;
13 | }
14 |
15 | public HaystackDateTime Start { get; }
16 | public HaystackDateTime End { get; }
17 | }
18 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackDefinition.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | public class HaystackDefinition : HaystackValue
7 | {
8 | public HaystackDefinition(string value)
9 | {
10 | Value = value != null && value.StartsWith("^") && HaystackValidator.IsTagName(value)
11 | ? value
12 | : throw new ArgumentException($"Invalid definition value: {value}");
13 | }
14 |
15 | public string Value { get; }
16 |
17 | public override int GetHashCode() => Value.GetHashCode();
18 |
19 | public override bool Equals(object other) => other != null && other is HaystackDefinition def && Value.Equals(def.Value);
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackHistoryItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace ProjectHaystack
6 | {
7 | ///
8 | /// Haystack history item containing a timestamp and a value.
9 | ///
10 | public class HaystackHistoryItem : HaystackValue
11 | {
12 | public HaystackHistoryItem(HaystackDateTime timeStamp, HaystackValue Value)
13 | {
14 | TimeStamp = timeStamp ?? throw new ArgumentNullException(nameof(timeStamp));
15 | this.Value = Value ?? throw new ArgumentNullException(nameof(Value));
16 | }
17 |
18 | public HaystackHistoryItem(HaystackDictionary dictionary)
19 | {
20 | if (dictionary is null)
21 | {
22 | throw new ArgumentNullException(nameof(dictionary));
23 | }
24 |
25 | TimeStamp = (HaystackDateTime)dictionary["ts"];
26 | Value = dictionary.ContainsKey("val") ? dictionary["val"] : null;
27 | }
28 |
29 | public HaystackDateTime TimeStamp { get; }
30 |
31 | public HaystackValue Value { get; }
32 |
33 | ///
34 | /// Read a grid of "ts" and "val" data.
35 | ///
36 | /// Grid to read.
37 | /// List of history items.
38 | public static IEnumerable ReadGrid(HaystackGrid grid)
39 | {
40 | var ts = grid.Column("ts");
41 | var val = grid.Column("val");
42 | return grid.Rows
43 | .Select(row => new HaystackHistoryItem(row));
44 | }
45 |
46 | public override int GetHashCode() => TimeStamp.GetHashCode();
47 |
48 | public override bool Equals(object other)
49 | {
50 | return other != null
51 | && other is HaystackHistoryItem historyItem
52 | && historyItem.TimeStamp.Equals(TimeStamp)
53 | && historyItem.Value.Equals(Value);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackList.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace ProjectHaystack
6 | {
7 | ///
8 | /// List of Haystack values.
9 | ///
10 | public class HaystackList : HaystackValue, IList
11 | {
12 | private readonly List _list;
13 |
14 | public HaystackList(List list)
15 | {
16 | _list = list;
17 | }
18 |
19 | public HaystackList(params HaystackValue[] list)
20 | {
21 | _list = list.ToList();
22 | }
23 |
24 | public int Count => _list.Count;
25 |
26 | public bool IsReadOnly => false;
27 |
28 | public HaystackValue this[int index] { get => _list[index]; set => _list[index] = value; }
29 |
30 | public override int GetHashCode() => _list.GetHashCode();
31 |
32 | public override bool Equals(object other)
33 | {
34 | return other != null
35 | && other is HaystackList list
36 | && list._list.Count == _list.Count
37 | && Enumerable.Range(0, list._list.Count).All(idx => list._list[idx].Equals(_list[idx]));
38 | }
39 |
40 | public int IndexOf(HaystackValue item) => _list.IndexOf(item);
41 |
42 | public void Insert(int index, HaystackValue item) => _list.Insert(index, item);
43 |
44 | public void RemoveAt(int index) => _list.RemoveAt(index);
45 |
46 | public void Add(HaystackValue item) => _list.Add(item);
47 |
48 | public void Clear() => _list.Clear();
49 |
50 | public bool Contains(HaystackValue item) => _list.Contains(item);
51 |
52 | public void CopyTo(HaystackValue[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
53 |
54 | public bool Remove(HaystackValue item) => _list.Remove(item);
55 |
56 | public IEnumerator GetEnumerator() => _list.GetEnumerator();
57 |
58 | IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
59 | }
60 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackMarker.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Haystack marker value.
5 | ///
6 | public class HaystackMarker : HaystackValue
7 | {
8 | public static readonly HaystackMarker Instance = new HaystackMarker();
9 |
10 | public override int GetHashCode() { return 0; }
11 |
12 | public override bool Equals(object other) => other != null && other is HaystackMarker;
13 | }
14 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackNotAvailable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Haystack not available (NA) marker value.
7 | ///
8 | public class HaystackNotAvailable : HaystackValue
9 | {
10 | public static HaystackNotAvailable Instance = new HaystackNotAvailable();
11 |
12 | public override int GetHashCode() => 0;
13 |
14 | public override bool Equals(object other) => other != null && other is HaystackNotAvailable;
15 |
16 | public override string ToString()
17 | {
18 | throw new NotImplementedException("ToString is not implemented to prevent inconsistent results.");
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackNumber.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | ///
7 | /// Haystack number with optional unit.
8 | ///
9 | public class HaystackNumber : HaystackValue
10 | {
11 | public HaystackNumber(double value, string unit = null)
12 | {
13 | if (!HaystackValidator.IsUnitName(unit))
14 | {
15 | throw new ArgumentException($"Invalid unit name: {unit}", nameof(unit));
16 | }
17 |
18 | Value = value;
19 | Unit = unit;
20 | }
21 |
22 | public double Value { get; }
23 | public string Unit { get; }
24 |
25 | public static HaystackNumber ZERO = new HaystackNumber(0.0, null);
26 | public static HaystackNumber POS_INF = new HaystackNumber(double.PositiveInfinity, null);
27 | public static HaystackNumber NEG_INF = new HaystackNumber(double.NegativeInfinity, null);
28 | public static HaystackNumber NaN = new HaystackNumber(double.NaN, null);
29 |
30 | public override int GetHashCode()
31 | {
32 | var unsigned = Convert.ToUInt64(BitConverter.DoubleToInt64Bits(Value));
33 | int hash = (int)(unsigned ^ (unsigned >> 32));
34 | if (Unit != null)
35 | hash ^= Unit.GetHashCode();
36 | return hash;
37 | }
38 |
39 | public override bool Equals(object other) => other != null && other is HaystackNumber number && number.Value.Equals(Value) && number.Unit == Unit;
40 |
41 | public int CompareTo(object other)
42 | {
43 | #if NETSTANDARD2_0 || NETSTANDARD2_1
44 | if (other == null || !(other is HaystackNumber number))
45 | {
46 | return 1;
47 | }
48 | #else
49 | if (other == null || other is not HaystackNumber number)
50 | {
51 | return 1;
52 | }
53 | #endif
54 |
55 | return Value.CompareTo(number.Value);
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackReference.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | public class HaystackReference : HaystackValue
7 | {
8 | public HaystackReference(string value, string dis = null)
9 | {
10 | Value = value == null || HaystackValidator.IsReferenceId(value)
11 | ? value
12 | : throw new ArgumentException($"Invalid id val: {value}", "value");
13 | Display = dis;
14 | }
15 |
16 | public static HaystackReference nullRef = new HaystackReference(null, null);
17 |
18 | public string Value { get; }
19 | public string Display { get; }
20 | public string Code => "@" + Value;
21 |
22 | public override int GetHashCode() => Value.GetHashCode();
23 |
24 | public override bool Equals(object other) => other != null && other is HaystackReference reference && (reference.Value?.Equals(Value) ?? false);
25 | }
26 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackRemove.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Haystack remove marker value.
5 | ///
6 | public class HaystackRemove : HaystackValue
7 | {
8 | public static HaystackRemove Instance = new HaystackRemove();
9 |
10 | public override int GetHashCode() { return 0; }
11 |
12 | public override bool Equals(object other) => other != null && other is HaystackRemove;
13 | }
14 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackRow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace ProjectHaystack
6 | {
7 | ///
8 | /// Row in a Haystack grid.
9 | ///
10 | public class HaystackRow : HaystackDictionary
11 | {
12 | public HaystackRow(HaystackGrid grid, params HaystackValue[] values)
13 | : base(new Lazy>(() => ToDictionary(grid, values)))
14 | {
15 | Grid = grid;
16 | }
17 |
18 | public HaystackGrid Grid { get; }
19 |
20 | public override ICollection Values => _source.Value.Values;
21 |
22 | public override void Add(string key, HaystackValue value)
23 | {
24 | throw new InvalidOperationException("Cannot add values to a row as it will affect the entire grid");
25 | }
26 |
27 | public override bool Remove(string key)
28 | {
29 | throw new InvalidOperationException("Cannot remove values from a row as it will affect the entire grid");
30 | }
31 |
32 | public HaystackValue this[int index]
33 | {
34 | get => Get(Grid.Column(index).Name);
35 | set
36 | {
37 | var key = Grid.Column(index).Name;
38 | _source.Value[key] = value;
39 | }
40 | }
41 |
42 | public override HaystackValue this[string key]
43 | {
44 | get => Get(key);
45 | set
46 | {
47 | if (!_source.Value.ContainsKey(key))
48 | throw new HaystackUnknownNameException("Cannot add values to a row as it will affect the entire grid");
49 | _source.Value[key] = value;
50 | }
51 | }
52 |
53 | private static IDictionary ToDictionary(HaystackGrid grid, HaystackValue[] values)
54 | {
55 | if (values == null || grid.ColumnCount != values.Length)
56 | {
57 | throw new ArgumentException($"Row count {values.Length} does not match col count {grid.ColumnCount}", "values");
58 | }
59 |
60 | #if NETSTANDARD2_0 || NETSTANDARD2_1
61 | return grid.Columns
62 | .Select((col, idx) => new KeyValuePair(col.Name, values[idx]))
63 | .ToDictionary(kv => kv.Key, kv => kv.Value);
64 | #else
65 | return new Dictionary(grid.Columns
66 | .Select((col, idx) => new KeyValuePair(col.Name, values[idx])));
67 | #endif
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackString.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | public class HaystackString : HaystackValue, IComparable
6 | {
7 | private static HaystackString _empty = new HaystackString(string.Empty);
8 |
9 | public HaystackString(string value)
10 | {
11 | Value = value;
12 | }
13 |
14 | public static HaystackString Empty => _empty;
15 |
16 | public string Value { get; }
17 |
18 | public override int GetHashCode() => Value.GetHashCode();
19 |
20 | public override bool Equals(object other) => other != null && other is HaystackString str && str.Value == Value;
21 |
22 | public int CompareTo(object obj)
23 | {
24 | #if NETSTANDARD2_0 || NETSTANDARD2_1
25 | if (obj != null && obj is HaystackString str)
26 | {
27 | return Value.CompareTo(str.Value);
28 | }
29 | return 1;
30 | #else
31 | if (obj == null || obj is not HaystackString str)
32 | {
33 | return 1;
34 | }
35 | return Value.CompareTo(str.Value);
36 | #endif
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackTime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Haystack time of day value.
7 | ///
8 | public class HaystackTime : HaystackValue, IComparable
9 | {
10 | public HaystackTime(TimeSpan time)
11 | {
12 | Value = time;
13 | }
14 |
15 | public HaystackTime(int hours, int minutes, int seconds)
16 | : this(new TimeSpan(hours, minutes, seconds))
17 | {
18 | }
19 |
20 | public TimeSpan Value { get; private set; }
21 |
22 | public override int GetHashCode() => Value.GetHashCode();
23 |
24 | public override bool Equals(object other) => other != null && other is HaystackTime time && Value.Equals(time.Value);
25 |
26 | public int CompareTo(object obj)
27 | {
28 | #if NETSTANDARD2_0 || NETSTANDARD2_1
29 | if (obj == null || !(obj is HaystackTime time))
30 | {
31 | return 1;
32 | }
33 | #else
34 | if (obj == null || obj is not HaystackTime time)
35 | {
36 | return 1;
37 | }
38 | #endif
39 |
40 | return Value.CompareTo(time.Value);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackTimeZone.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using TimeZoneConverter;
4 |
5 | namespace ProjectHaystack
6 | {
7 | ///
8 | /// Haystack time zone information.
9 | ///
10 | ///
11 | /// Handles mapping between Haystack timezone names and dotnet timezones.
12 | ///
13 | public class HaystackTimeZone
14 | {
15 | public HaystackTimeZone(string name, TimeZoneInfo timeZoneInfo)
16 | {
17 | Name = name;
18 | TimeZoneInfo = timeZoneInfo;
19 | }
20 |
21 | public HaystackTimeZone(string name)
22 | {
23 | Name = name;
24 | TimeZoneInfo = LocateTimeZoneByName(name);
25 | }
26 |
27 | public HaystackTimeZone(TimeZoneInfo timeZoneInfo)
28 | {
29 | TimeZoneInfo = timeZoneInfo;
30 | Name = LocateTimeZoneName(timeZoneInfo);
31 | }
32 |
33 | public string Name { get; }
34 | public TimeZoneInfo TimeZoneInfo { get; }
35 |
36 | public static HaystackTimeZone UTC => new HaystackTimeZone("UTC");
37 |
38 | public static HaystackTimeZone REL => new HaystackTimeZone("Rel");
39 |
40 | public static HaystackTimeZone Default => new HaystackTimeZone(TimeZoneInfo.Local.Id);
41 |
42 | public override int GetHashCode() => Name.GetHashCode();
43 |
44 | public override bool Equals(object other) => other != null && other is HaystackTimeZone timeZone && timeZone.Name.Equals(Name);
45 |
46 | private static TimeZoneInfo LocateTimeZoneByName(string name)
47 | {
48 | if (string.IsNullOrWhiteSpace(name))
49 | {
50 | throw new ArgumentException("Value must not be empty", nameof(name));
51 | }
52 |
53 | string nameToSearch = name?.ToUpper().Trim();
54 |
55 | // For "Rel" timezone, use "GMT"
56 | if (nameToSearch == "REL")
57 | {
58 | nameToSearch = "GMT";
59 | }
60 |
61 | TimeZoneInfo tziFound = null;
62 | var bestMatch = TZConvert.KnownIanaTimeZoneNames
63 | .Where(tzName => tzName.ToUpper().Contains(nameToSearch))
64 | .OrderBy(tzName => tzName.Length)
65 | .FirstOrDefault();
66 | if (bestMatch == null)
67 | {
68 | throw new ArgumentException($"Could not find IANA timezone with name {name}", nameof(name));
69 | }
70 | if (!TZConvert.TryGetTimeZoneInfo(bestMatch, out tziFound))
71 | {
72 | throw new ArgumentException($"An exception occurred when trying to convert from IANA to Windows Time Zone for value {tziFound}", nameof(name));
73 | }
74 | return tziFound;
75 | }
76 |
77 | private static string LocateTimeZoneName(TimeZoneInfo dntzi)
78 | {
79 | if (dntzi == null)
80 | {
81 | throw new ArgumentException("Value must not be empty", nameof(dntzi));
82 | }
83 |
84 | if (!TZConvert.TryWindowsToIana(dntzi.Id, out var iana))
85 | {
86 | if (!TZConvert.TryWindowsToIana(dntzi.Id.Replace("Etc/", ""), out iana))
87 | {
88 | throw new ArgumentException($"Windows time zone id {dntzi.Id} could not be converted to IANA tz id", nameof(dntzi));
89 | }
90 | }
91 |
92 | var nameToSearch = iana.ToUpper();
93 | var bestMatch = HaystackTimeZoneDatabase.TimeZones
94 | .Where(tzName => nameToSearch.Contains(tzName.ToUpper()))
95 | .OrderByDescending(tzName => tzName.Length)
96 | .FirstOrDefault();
97 | if (bestMatch == null)
98 | {
99 | throw new ArgumentException($"Windows time zone id {dntzi.Id} converted to IANA id {iana} could not be found in known Haystack ids", nameof(dntzi));
100 | }
101 | return bestMatch;
102 | }
103 | }
104 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackUri.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProjectHaystack
4 | {
5 | ///
6 | /// Haystack URI value.
7 | ///
8 | public class HaystackUri : HaystackValue
9 | {
10 | public HaystackUri(string value)
11 | {
12 | Value = value ?? throw new ArgumentException("Uri cannot be null", nameof(value));
13 | }
14 |
15 | public string Value { get; }
16 |
17 | // Hash code is based on string value
18 | public override int GetHashCode() => Value.GetHashCode();
19 |
20 | // Equals is based on string value
21 | public override bool Equals(object other) => other != null && other is HaystackUri uri && uri.Value.Equals(Value);
22 | }
23 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackValue.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack
2 | {
3 | ///
4 | /// Base class for Haystack values.
5 | ///
6 | public abstract class HaystackValue
7 | {
8 | public abstract override bool Equals(object other);
9 | public abstract override int GetHashCode();
10 |
11 | public static bool operator ==(HaystackValue left, HaystackValue right) => Equals(left, null) ? Equals(right, null) : left.Equals(right);
12 | public static bool operator !=(HaystackValue left, HaystackValue right) => !(left == right);
13 | }
14 | }
--------------------------------------------------------------------------------
/ProjectHaystack/Values/HaystackXString.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystack
5 | {
6 | ///
7 | /// Haystack extended string containing a type and value encoded as a string.
8 | /// It is used as a generic value when no predefined type is used.
9 | ///
10 | public class HaystackXString : HaystackValue
11 | {
12 | public HaystackXString(string value, string type = null)
13 | {
14 | Value = value;
15 | Type = HaystackValidator.IsTypeName(type)
16 | ? type
17 | : throw new ArgumentException($"Invalid type name: {type}", nameof(type));
18 | }
19 |
20 | public string Value { get; }
21 |
22 | public string Type { get; }
23 |
24 | public override int GetHashCode() => Type.GetHashCode() * 31 + Value.GetHashCode();
25 |
26 | public override bool Equals(object other) => other != null && other is HaystackXString xstr && xstr.Value == Value && xstr.Type == Type;
27 | }
28 | }
--------------------------------------------------------------------------------
/ProjectHaystack/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ProjectHaystack/io/HaystackToken.cs:
--------------------------------------------------------------------------------
1 | namespace ProjectHaystack.io
2 | {
3 | public class HaystackToken
4 | {
5 | public string Symbol { get; private set; }
6 | public bool Literal { get; private set; }
7 |
8 | public static HaystackToken eof = new HaystackToken("eof");
9 |
10 | public static HaystackToken id = new HaystackToken("identifier");
11 | public static HaystackToken num = new HaystackToken("Number", true);
12 | public static HaystackToken str = new HaystackToken("Str", true);
13 | public static HaystackToken @ref = new HaystackToken("Ref", true);
14 | public static HaystackToken caretSymbol = new HaystackToken("Symbol", true);
15 | public static HaystackToken uri = new HaystackToken("Uri", true);
16 | public static HaystackToken date = new HaystackToken("Date", true);
17 | public static HaystackToken time = new HaystackToken("Time", true);
18 | public static HaystackToken dateTime = new HaystackToken("DateTime", true);
19 |
20 | public static HaystackToken colon = new HaystackToken(":");
21 | public static HaystackToken comma = new HaystackToken(",");
22 | public static HaystackToken semicolon = new HaystackToken(";");
23 | public static HaystackToken minus = new HaystackToken("-");
24 | public static HaystackToken eq = new HaystackToken("==");
25 | public static HaystackToken notEq = new HaystackToken("!=");
26 | public static HaystackToken lt = new HaystackToken("<");
27 | public static HaystackToken lt2 = new HaystackToken("<<");
28 | public static HaystackToken ltEq = new HaystackToken("<=");
29 | public static HaystackToken gt = new HaystackToken(">");
30 | public static HaystackToken gt2 = new HaystackToken(">>");
31 | public static HaystackToken gtEq = new HaystackToken(">=");
32 | public static HaystackToken lbracket = new HaystackToken("[");
33 | public static HaystackToken rbracket = new HaystackToken("]");
34 | public static HaystackToken lbrace = new HaystackToken("{");
35 | public static HaystackToken rbrace = new HaystackToken("}");
36 | public static HaystackToken lparen = new HaystackToken("(");
37 | public static HaystackToken rparen = new HaystackToken(")");
38 | public static HaystackToken arrow = new HaystackToken("->");
39 | public static HaystackToken slash = new HaystackToken("/");
40 | public static HaystackToken assign = new HaystackToken("=");
41 | public static HaystackToken bang = new HaystackToken("!");
42 | public static HaystackToken nl = new HaystackToken("newline");
43 |
44 | public HaystackToken(string symbol)
45 | {
46 | Symbol = symbol;
47 | Literal = false;
48 | }
49 |
50 | public HaystackToken(string symbol, bool literal)
51 | {
52 | Symbol = symbol;
53 | Literal = literal;
54 | }
55 |
56 | public override bool Equals(object o)
57 | {
58 | if (this == o) return true; // reference check
59 | if (o == null || (!(o is HaystackToken))) return false; // null and type check
60 |
61 | HaystackToken that = (HaystackToken)o;
62 | // Value compare
63 | if (Literal != that.Literal) return false;
64 | return (Symbol.CompareTo(that.Symbol) == 0);
65 | }
66 |
67 | public override int GetHashCode()
68 | {
69 | int result = Symbol.GetHashCode();
70 | result = 31 * result + (Literal ? 1 : 0);
71 | return result;
72 | }
73 |
74 | public override string ToString()
75 | {
76 | return Symbol;
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/ProjectHaystack/io/TrioWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text.RegularExpressions;
4 |
5 | namespace ProjectHaystack.io
6 | {
7 | public class TrioWriter : IDisposable
8 | {
9 | // Strings can be left unquoted if they begin with any of these "safe" chars:
10 | // Any non-ASCII Unicode character, A-Z, a-z, underbar, dash, or space.
11 | private Regex _safeCharsRegex = new Regex(@"^[^\x00-\x7F]|^[A-Za-z0-9_\ ]+$", RegexOptions.Compiled);
12 | private readonly TextWriter _trioWriter;
13 | private bool isFirst = true;
14 |
15 | public TrioWriter(TextWriter writer)
16 | {
17 | _trioWriter = writer;
18 | }
19 |
20 | public TrioWriter(Stream trioStream)
21 | {
22 | _trioWriter = new StreamWriter(trioStream, null, 1024, true);
23 | }
24 |
25 | public void WriteGrid(HaystackGrid grid)
26 | {
27 | foreach (var row in grid.Rows)
28 | WriteEntity(row);
29 | }
30 |
31 |
32 | public void WriteEntity(HaystackDictionary entity)
33 | {
34 | if (isFirst)
35 | isFirst = false;
36 | else
37 | _trioWriter.WriteLine("---");
38 |
39 | foreach (var kv in entity)
40 | {
41 | if (kv.Value == null)
42 | continue;
43 | _trioWriter.Write(kv.Key);
44 | if (kv.Value is HaystackMarker)
45 | {
46 | _trioWriter.WriteLine();
47 | continue;
48 | }
49 | _trioWriter.Write(":");
50 | if (kv.Value is HaystackGrid)
51 | {
52 | _trioWriter.Write("Zinc:");
53 | _trioWriter.WriteLine();
54 | var val = ZincWriter.ToZinc(kv.Value);
55 | foreach (var line in val.TrimEnd().Split(new[] { "\n" }, StringSplitOptions.None))
56 | {
57 | _trioWriter.Write(" ");
58 | _trioWriter.WriteLine(line.TrimEnd());
59 | }
60 | }
61 | else if (kv.Value is HaystackString stringValue && stringValue.Value.Contains("\n"))
62 | {
63 | var val = stringValue.Value;
64 | _trioWriter.WriteLine();
65 | foreach (var line in val.TrimEnd().Split(new[] { "\n" }, StringSplitOptions.None))
66 | {
67 | _trioWriter.Write(" ");
68 | _trioWriter.WriteLine(line.TrimEnd());
69 | }
70 | }
71 | else
72 | {
73 | var val = ZincWriter.ToZinc(kv.Value);
74 | if (val.Contains("\\n"))
75 | val = val.Replace("\\n", "\n");
76 | if (val.StartsWith("\"") && val.EndsWith("\"") && _safeCharsRegex.IsMatch(val.Substring(1, val.Length - 2)))
77 | val = val.Substring(1, val.Length - 2);
78 | _trioWriter.WriteLine(val.TrimEnd());
79 | }
80 | }
81 | }
82 |
83 | public void WriteComment(string comment)
84 | {
85 | foreach (var line in comment.Split(new[] { "\n" }, StringSplitOptions.None))
86 | {
87 | _trioWriter.Write("// ");
88 | _trioWriter.WriteLine(line.TrimEnd());
89 | }
90 | }
91 |
92 | public void Dispose()
93 | {
94 | _trioWriter.Dispose();
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Auth/Util/Base64Test.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 |
4 | namespace ProjectHaystackTest.Util
5 | {
6 | using Base64 = ProjectHaystack.Util.Base64;
7 |
8 | [TestClass]
9 | public class Base64Test
10 | {
11 | private static string RandomString()
12 | {
13 | Guid g = Guid.NewGuid();
14 | string GuidString = Convert.ToBase64String(g.ToByteArray());
15 | GuidString = GuidString.Replace("=", "");
16 | GuidString = GuidString.Replace("+", "");
17 | return GuidString;
18 | }
19 |
20 | [TestMethod]
21 | public void StandardEncodeDecode()
22 | {
23 | for (var i = 0; i < 1000; i++)
24 | {
25 | var s1 = RandomString();
26 | var enc = Base64.STANDARD.Encode(s1);
27 | var s2 = Base64.STANDARD.Decode(enc);
28 | Assert.AreEqual(s1, s2);
29 | }
30 | }
31 |
32 | [TestMethod]
33 | public void StandardUtf8EncodeDecode()
34 | {
35 | for (int i = 0; i < 1000; i++)
36 | {
37 | var s1 = RandomString();
38 | var enc = Base64.STANDARD.EncodeUtf8(s1);
39 | var s2 = Base64.STANDARD.decodeUTF8(enc);
40 | Assert.AreEqual(s1, s2);
41 | }
42 | }
43 |
44 | [TestMethod]
45 | public void UriEncodeDecode()
46 | {
47 | for (int i = 0; i < 1000; i++)
48 | {
49 | var s1 = RandomString();
50 | var enc = Base64.URI.Encode(s1);
51 | var s2 = Base64.URI.Decode(enc);
52 | Assert.AreEqual(s1, s2);
53 | }
54 | }
55 |
56 | [TestMethod]
57 | public void UriUtf8EncodeDecode()
58 | {
59 | for (int i = 0; i < 1000; i++)
60 | {
61 | var s1 = RandomString();
62 | var enc = Base64.URI.EncodeUtf8(s1);
63 | var s2 = Base64.URI.decodeUTF8(enc);
64 | Assert.AreEqual(s1, s2);
65 | }
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Auth/Util/Pbkdf2Test.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using Microsoft.VisualStudio.TestTools.UnitTesting;
4 |
5 | namespace ProjectHaystackTest.Util
6 | {
7 | using Pbkdf2 = ProjectHaystack.Util.Pbkdf2;
8 |
9 | [TestClass]
10 | public class Pbkdf2Test
11 | {
12 | public void DoPbkTest(string password, string salt, int iterations, int dkLen, string expected)
13 | {
14 | using (var hmac = new HMACSHA256())
15 | {
16 | var mine = new Pbkdf2(hmac, System.Text.Encoding.UTF8.GetBytes(password), System.Text.Encoding.UTF8.GetBytes(salt), iterations);
17 | var result = mine.GetBytes(dkLen);
18 | var usResult = (byte[])(Array)result;
19 | var hex = BitConverter.ToString(usResult);
20 | Assert.AreEqual(hex, expected);
21 | }
22 | }
23 |
24 | [TestMethod]
25 | public void PbkTest()
26 | {
27 | DoPbkTest("password", "salt", 1, 32, "12-0F-B6-CF-FC-F8-B3-2C-43-E7-22-52-56-C4-F8-37-A8-65-48-C9-2C-CC-35-48-08-05-98-7C-B7-0B-E1-7B");
28 | DoPbkTest("password", "salt", 2, 32, "AE-4D-0C-95-AF-6B-46-D3-2D-0A-DF-F9-28-F0-6D-D0-2A-30-3F-8E-F3-C2-51-DF-D6-E2-D8-5A-95-47-4C-43");
29 | DoPbkTest("password", "salt", 4096, 32, "C5-E4-78-D5-92-88-C8-41-AA-53-0D-B6-84-5C-4C-8D-96-28-93-A0-01-CE-4E-11-A4-96-38-73-AA-98-13-4A");
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HBinTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using Microsoft.VisualStudio.TestTools.UnitTesting;
9 | using ProjectHaystack;
10 |
11 | namespace ProjectHaystackTest
12 | {
13 | [TestClass]
14 | public class HBinTest : HValTest
15 | {
16 | [TestMethod]
17 | public void testEquality()
18 | {
19 | HBin bin1 = HBin.make("text/plain");
20 | HBin bin2 = HBin.make("text/plain");
21 | HBin bin3 = HBin.make("text/xml");
22 | // Can't user AreEqual or AreNotEqual as these are objects and that is doing
23 | // a reference check not a logical value test because HBin does not implement
24 | // IComparable Interface - Haystack equals determines equality for this library purpose
25 | //e.g this will fail = Assert.AreEqual(HBin.make("text/plain"), HBin.make("text/plain"));
26 | Assert.IsTrue(bin1.hequals(bin2));
27 | Assert.IsFalse(bin1.hequals(bin3));
28 | }
29 | // TODO:FIXIT
30 | // // encoding
31 | // verifyZinc(HBin.make("text/plain"), "Bin(\"text/plain\")");
32 | // verifyZinc(HBin.make("text/plain; charset=utf-8"), "Bin(\"text/plain; charset=utf-8\")");
33 | //
34 | // // verify bad bins are caught on encoding
35 | // try { HBin.make("text/plain; f()").toZinc(); fail(); } catch (Exception e) { verifyException(e); }
36 | // try { read("Bin()"); fail(); } catch (Exception e) { verifyException(e); }
37 | // try { read("Bin(\"text\")"); fail(); } catch (Exception e) { verifyException(e); }
38 | }
39 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HBoolTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using Microsoft.VisualStudio.TestTools.UnitTesting;
9 | using ProjectHaystack;
10 |
11 | namespace ProjectHaystackTest
12 | {
13 | [TestClass]
14 | public class HBoolTest : HValTest
15 | {
16 | [TestMethod]
17 | public void testEquality()
18 | {
19 | Assert.IsTrue(HBool.TRUE.hequals(HBool.TRUE));
20 | Assert.IsFalse(HBool.TRUE.hequals(HBool.FALSE));
21 | Assert.IsTrue(HBool.make(true).hequals(HBool.TRUE));
22 | Assert.IsTrue(HBool.make(false).hequals(HBool.FALSE));
23 | }
24 |
25 | [TestMethod]
26 | public void testCompare()
27 | {
28 | Assert.IsTrue(HBool.FALSE.CompareTo(HBool.TRUE) < 0);
29 | Assert.AreEqual(HBool.TRUE.CompareTo(HBool.TRUE), 0);
30 | }
31 |
32 | [TestMethod]
33 | public void testZinc()
34 | {
35 | verifyZinc(HBool.TRUE, "T");
36 | verifyZinc(HBool.FALSE, "F");
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HCoordTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HCoordTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testLatBoundaries()
19 | {
20 | verifyCoord(90, 123, "C(90,123)");
21 | verifyCoord(-90, 123, "C(-90,123)");
22 | verifyCoord(89.888999, 123, "C(89.888999,123)");
23 | verifyCoord(-89.888999, 123, "C(-89.888999,123)");
24 | }
25 |
26 | [TestMethod]
27 | public void testLonBoundaries()
28 | {
29 | verifyCoord(45, 180, "C(45,180)");
30 | verifyCoord(45, -180, "C(45,-180)");
31 | verifyCoord(45, 179.999129, "C(45,179.999129)");
32 | verifyCoord(45, -179.999129, "C(45,-179.999129)");
33 | }
34 |
35 | [TestMethod]
36 | public void testDecimalPlaces()
37 | {
38 | verifyCoord(9.1, -8.1, "C(9.1,-8.1)");
39 | verifyCoord(9.12, -8.13, "C(9.12,-8.13)");
40 | verifyCoord(9.123, -8.134, "C(9.123,-8.134)");
41 | verifyCoord(9.1234, -8.1346, "C(9.1234,-8.1346)");
42 | verifyCoord(9.12345, -8.13456, "C(9.12345,-8.13456)");
43 | verifyCoord(9.123452, -8.134567, "C(9.123452,-8.134567)");
44 | }
45 |
46 | [TestMethod]
47 | public void testZeroBoundaries()
48 | {
49 | verifyCoord(0, 0, "C(0,0)");
50 | verifyCoord(0.3, -0.3, "C(0.3,-0.3)");
51 | verifyCoord(0.03, -0.03, "C(0.03,-0.03)");
52 | verifyCoord(0.003, -0.003, "C(0.003,-0.003)");
53 | verifyCoord(0.0003, -0.0003, "C(0.0003,-0.0003)");
54 | verifyCoord(0.02003, -0.02003, "C(0.02003,-0.02003)");
55 | verifyCoord(0.020003, -0.020003, "C(0.020003,-0.020003)");
56 | verifyCoord(0.000123, -0.000123, "C(0.000123,-0.000123)");
57 | verifyCoord(7.000123, -7.000123, "C(7.000123,-7.000123)");
58 | }
59 |
60 | [TestMethod]
61 | public void testIsLat()
62 | {
63 | Assert.IsFalse(HCoord.isLat(-91.0));
64 | Assert.IsTrue(HCoord.isLat(-90.0));
65 | Assert.IsTrue(HCoord.isLat(-89.0));
66 | Assert.IsTrue(HCoord.isLat(90.0));
67 | Assert.IsFalse(HCoord.isLat(91.0));
68 | }
69 |
70 | [TestMethod]
71 | public void testIsLng()
72 | {
73 | Assert.IsFalse(HCoord.isLng(-181.0));
74 | Assert.IsTrue(HCoord.isLng(-179.99));
75 | Assert.IsTrue(HCoord.isLng(180.0));
76 | Assert.IsFalse(HCoord.isLng(181.0));
77 | }
78 |
79 | [TestMethod]
80 | public void testMakeErrors()
81 | {
82 | try { HCoord.make(91, 12); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
83 | try { HCoord.make(-90.2, 12); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
84 | try { HCoord.make(13, 180.009); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
85 | try { HCoord.make(13, -181); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
86 | }
87 |
88 | private void verifyCoord(double lat, double lng, string s)
89 | {
90 | HCoord c = HCoord.make(lat, lng);
91 | Assert.AreEqual(c.lat, lat);
92 | Assert.AreEqual(c.lng, lng);
93 | Assert.AreEqual(c.ToString(), s);
94 | HCoord strCoord = HCoord.make(s);
95 | Assert.IsTrue(strCoord.hequals(c));
96 | }
97 |
98 | [TestMethod]
99 | [ExpectedException(typeof(FormatException))] // In Java this was parse exception
100 | public void RunBadZincProviderTest ()
101 | {
102 | string[] badZincs =
103 | { "C(0.123,-.789)",
104 | "1,2",
105 | "(1,2)",
106 | "C(1,2",
107 | "C1,2)",
108 | "C(x,9)" };
109 | foreach (string strCurZinc in badZincs)
110 | HCoord.make(strCurZinc);
111 | }
112 |
113 | }
114 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HDateTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HDateTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testEquality()
19 | {
20 | Assert.IsTrue(HDate.make(2011, 6, 7).hequals(HDate.make(2011, 6, 7)));
21 | Assert.IsFalse(HDate.make(2011, 6, 7).hequals(HDate.make(2011, 6, 8)));
22 | Assert.IsFalse(HDate.make(2011, 6, 7).hequals(HDate.make(2011, 2, 7)));
23 | Assert.IsFalse(HDate.make(2011, 6, 7).hequals(HDate.make(2009, 6, 7)));
24 | }
25 |
26 | [TestMethod]
27 | public void testCompare()
28 | {
29 | Assert.IsTrue(HDate.make(2011, 6, 9).CompareTo(HDate.make(2011, 6, 21)) < 0);
30 | Assert.IsTrue(HDate.make(2011, 10, 9).CompareTo(HDate.make(2011, 3, 21)) > 0);
31 | Assert.IsTrue(HDate.make(2010, 6, 9).CompareTo(HDate.make(2000, 9, 30)) > 0);
32 | Assert.AreEqual(HDate.make(2010, 6, 9).CompareTo(HDate.make(2010, 6, 9)), 0);
33 | }
34 |
35 | [TestMethod]
36 | public void testPlusMinus()
37 | {
38 | Assert.IsTrue(HDate.make(2011, 12, 1).minusDays(0).hequals(HDate.make(2011, 12, 1)));
39 | Assert.IsTrue(HDate.make(2011, 12, 1).minusDays(1).hequals(HDate.make(2011, 11, 30)));
40 | Assert.IsTrue(HDate.make(2011, 12, 1).minusDays(-2).hequals(HDate.make(2011, 12, 3)));
41 | Assert.IsTrue(HDate.make(2011, 12, 1).plusDays(2).hequals(HDate.make(2011, 12, 3)));
42 | Assert.IsTrue(HDate.make(2011, 12, 1).plusDays(31).hequals(HDate.make(2012, 1, 1)));
43 | Assert.IsTrue(HDate.make(2008, 3, 3).minusDays(3).hequals(HDate.make(2008, 2, 29)));
44 | Assert.IsTrue(HDate.make(2008, 3, 3).minusDays(4).hequals(HDate.make(2008, 2, 28)));
45 | }
46 |
47 | [TestMethod]
48 | public void testLeapYear()
49 | {
50 | for (int y = 1900; y <= 2100; y++)
51 | {
52 | if (((y % 4) == 0) && (y != 1900) && (y != 2100))
53 | Assert.IsTrue(HDate.isLeapYear(y));
54 | else
55 | Assert.IsFalse(HDate.isLeapYear(y));
56 | }
57 | }
58 |
59 | [TestMethod]
60 | public void testMidnight()
61 | {
62 | verifyMidnight(HDate.make(2011, 11, 3), "UTC", "2011-11-03T00:00:00Z UTC");
63 | verifyMidnight(HDate.make(2011, 11, 3), "New_York", "2011-11-03T00:00:00-04:00 New_York");
64 | verifyMidnight(HDate.make(2011, 12, 15), "Chicago", "2011-12-15T00:00:00-06:00 Chicago");
65 | verifyMidnight(HDate.make(2008, 2, 29), "Phoenix", "2008-02-29T00:00:00-07:00 Phoenix");
66 | }
67 |
68 | private void verifyMidnight(HDate date, string tzName, string str)
69 | {
70 | var tz = HTimeZone.make(tzName, false);
71 | // Ignore issues with locally installed timezones.
72 | if (tz == null)
73 | return;
74 | HDateTime ts = date.midnight(tz);
75 | Assert.AreEqual(ts.date, date);
76 | Assert.AreEqual(ts.time.Hour, 0);
77 | Assert.AreEqual(ts.time.Minute, 0);
78 | Assert.AreEqual(ts.time.Second, 0);
79 | Assert.AreEqual(ts.ToString(), str);
80 | Assert.IsTrue(ts.hequals(read(ts.toZinc())));
81 | Assert.AreEqual(ts.Ticks, ((HDateTime)read(str)).Ticks);
82 | }
83 |
84 | [TestMethod]
85 | public void testZinc()
86 | {
87 | verifyZinc(HDate.make(2011, 6, 7), "2011-06-07");
88 | verifyZinc(HDate.make(2011, 10, 10), "2011-10-10");
89 | verifyZinc(HDate.make(2011, 12, 31), "2011-12-31");
90 | }
91 |
92 | [TestMethod]
93 | [ExpectedException(typeof(FormatException))]
94 | public void testBadZinc()
95 | {
96 | string[] badDateZinc =
97 | {
98 | "2003-xx-02",
99 | "2003-02",
100 | "2003-02-xx"
101 | };
102 | foreach (string strCurZinc in badDateZinc)
103 | read(strCurZinc);
104 | }
105 |
106 | }
107 | }
108 |
109 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HDateTimeRangeTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HDateTimeRangeTest
16 | {
17 | [TestMethod]
18 | public void testRange()
19 | {
20 | HTimeZone ny = HTimeZone.make("New_York", false);
21 | // Ignore issues with locally installed timezones.
22 | if (ny == null)
23 | return;
24 | HDate today = HDate.today();
25 | HDate yesterday = today.minusDays(1);
26 | HDate x = HDate.make(2011, 7, 4);
27 | HDate y = HDate.make(2011, 11, 4);
28 | HDateTime xa = HDateTime.make(x, HTime.make(2, 30), ny);
29 | HDateTime xb = HDateTime.make(x, HTime.make(22, 5), ny);
30 |
31 | // this week
32 | HDate sun = today;
33 | HDate sat = today;
34 | while (sun.weekday() > DayOfWeek.Sunday) sun = sun.minusDays(1);
35 | while (sat.weekday() < DayOfWeek.Saturday) sat = sat.plusDays(1);
36 | verifyRange(HDateTimeRange.thisWeek(ny), sun, sat);
37 |
38 | // this month
39 | HDate first = today;
40 | HDate last = today;
41 | while (first.Day > 1) first = first.minusDays(1);
42 | while (last.Day < DateTime.DaysInMonth(today.Year, today.Month)) last = last.plusDays(1);
43 | verifyRange(HDateTimeRange.thisMonth(ny), first, last);
44 |
45 | // this year
46 | first = HDate.make(today.Year, 1, 1);
47 | last = HDate.make(today.Year, 12, 31);
48 | verifyRange(HDateTimeRange.thisYear(ny), first, last);
49 |
50 | // last week
51 | HDate prev = today.minusDays(7);
52 | sun = prev;
53 | sat = prev;
54 | while (sun.weekday() > DayOfWeek.Sunday) sun = sun.minusDays(1);
55 | while (sat.weekday() < DayOfWeek.Saturday) sat = sat.plusDays(1);
56 | verifyRange(HDateTimeRange.lastWeek(ny), sun, sat);
57 |
58 | // last month
59 | last = today;
60 | while (last.Month == today.Month) last = last.minusDays(1);
61 | first = HDate.make(last.Year, last.Month, 1);
62 | verifyRange(HDateTimeRange.lastMonth(ny), first, last);
63 |
64 | // last year
65 | first = HDate.make(today.Year - 1, 1, 1);
66 | last = HDate.make(today.Year - 1, 12, 31);
67 | verifyRange(HDateTimeRange.lastYear(ny), first, last);
68 | }
69 |
70 | private void verifyRange(HDateTimeRange r, HDate start, HDate end)
71 | {
72 | Assert.IsTrue(r.Start.date.hequals(start));
73 | Assert.IsTrue(r.Start.time.hequals(HTime.MIDNIGHT));
74 | Assert.AreEqual(r.Start.TimeZone.ToString(), "New_York");
75 | Assert.IsTrue(r.End.date.hequals(end.plusDays(1)));
76 | Assert.IsTrue(r.End.time.hequals( HTime.MIDNIGHT));
77 | Assert.AreEqual(r.End.TimeZone.ToString(), "New_York");
78 | }
79 |
80 | private void verifyRange(HDateTimeRange r, HDateTime start, HDateTime end)
81 | {
82 | Assert.IsTrue(r.Start.hequals(start));
83 | Assert.IsTrue(r.End.hequals(end));
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HDefTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HDefTest : HValTest
9 | {
10 | [TestMethod]
11 | public void testEquality()
12 | {
13 | Assert.IsTrue(HDef.make("^foo").hequals(HDef.make("^foo")));
14 | }
15 |
16 | [TestMethod]
17 | public void testZinc()
18 | {
19 | verifyZinc(HDef.make("^testDef"), "^testDef");
20 | }
21 |
22 | [TestMethod]
23 | [ExpectedException(typeof(ArgumentException))]
24 | public void testBadDefConstruction()
25 | {
26 | string[] badDefs = new string[]
27 | {
28 | "^@a",
29 | "^a b",
30 | "^a\n",
31 | "^@",
32 | "a",
33 | "bcd",
34 | };
35 | foreach (string strID in badDefs)
36 | HDef.make(strID);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HHisItemTest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest.BackCompat
5 | {
6 | [TestClass]
7 | public class HHisItemTest : HValTest
8 | {
9 | [TestMethod]
10 | public void gridToItems()
11 | {
12 | // Arrange.
13 | var gridBuilder = new HGridBuilder();
14 | gridBuilder.addCol("ts");
15 | gridBuilder.addCol("val");
16 | gridBuilder.addRow(HDateTime.make(2020, 1, 1, 0, 0, 0, HTimeZone.UTC), HNum.make(10));
17 | var grid = gridBuilder.toGrid();
18 |
19 | // Act.
20 | var hisItems = HHisItem.gridToItems(grid);
21 |
22 | // Assert.
23 | Assert.AreEqual(1, hisItems.Length);
24 | Assert.AreEqual(HDateTime.make(2020, 1, 1, 0, 0, 0, HTimeZone.UTC), hisItems[0].TimeStamp);
25 | Assert.AreEqual(HNum.make(10), hisItems[0].hsVal);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HListTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using System.Collections.Generic;
10 | using Microsoft.VisualStudio.TestTools.UnitTesting;
11 | using ProjectHaystack;
12 |
13 | namespace ProjectHaystackTest
14 | {
15 | [TestClass]
16 | public class HListTest : HValTest
17 | {
18 | [TestMethod]
19 | public void testEmpty()
20 | {
21 | Assert.IsTrue(HList.EMPTY.hequals(HList.make(new List())));
22 | Assert.IsTrue(HList.EMPTY.hequals(HList.make(new HVal[0])));
23 | Assert.AreEqual(HList.EMPTY.size(), 0);
24 | try
25 | {
26 | HList.EMPTY.get(0);
27 | Assert.Fail();
28 | }
29 | catch (Exception)
30 | {
31 | Assert.IsTrue(true);
32 | }
33 | }
34 |
35 | [TestMethod]
36 | public void testBasics()
37 | {
38 | HRef hrefTest = HRef.make("a");
39 | HStr str = HStr.make("string");
40 | List items = new List();
41 | items.Add(hrefTest);
42 | items.Add(str);
43 |
44 | HList list = HList.make(items);
45 | Assert.AreEqual(list.size(), 2);
46 | Assert.AreEqual(list.get(0), hrefTest);
47 | Assert.AreEqual(list.get(1), str);
48 | }
49 |
50 | [TestMethod]
51 | public void testZinc()
52 | {
53 | verifyZinc(HList.EMPTY, "[]");
54 | // TODO: more tests
55 | }
56 |
57 | [TestMethod]
58 | public void testJson()
59 | {
60 | // Arrange.
61 | HRef hrefTest = HRef.make("a");
62 | HStr str = HStr.make("string");
63 | List items = new List();
64 | items.Add(hrefTest);
65 | items.Add(str);
66 | HList list = HList.make(items);
67 |
68 | // Act.
69 | var json = list.toJson();
70 |
71 | // Assert.
72 | Assert.AreEqual("[{\"_kind\":\"ref\",\"val\":\"a\",\"dis\":null},\"string\"]", json);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HMarkerTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 | using ProjectHaystack.io;
12 |
13 | namespace ProjectHaystackTest
14 | {
15 | [TestClass]
16 | public class HMarkerTest : HValTest
17 | {
18 | [TestMethod]
19 | public void testEquality()
20 | {
21 | Assert.IsTrue(HMarker.VAL.hequals(HMarker.VAL));
22 | }
23 |
24 | [TestMethod]
25 | public void testToString()
26 | {
27 | Assert.AreEqual(HMarker.VAL.ToString(), "marker");
28 | }
29 |
30 | [TestMethod]
31 | public void testZinc()
32 | {
33 | verifyZinc(HMarker.VAL, "M");
34 | }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HNumTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using System.Globalization;
10 | using System.Threading;
11 | using Microsoft.VisualStudio.TestTools.UnitTesting;
12 | using ProjectHaystack;
13 |
14 | namespace ProjectHaystackTest
15 | {
16 | [TestClass]
17 | public class HNumTest : HValTest
18 | {
19 | [TestMethod]
20 | public void testEquality()
21 | {
22 | Assert.IsTrue(HNum.make(2).hequals(HNum.make(2.0, null)));
23 | Assert.IsFalse(HNum.make(2).hequals(HNum.make(2, "%")));
24 | Assert.IsFalse(HNum.make(2, "%").hequals(HNum.make(2)));
25 | Assert.IsTrue(HNum.make(0).hequals(HNum.make(0.0)));
26 | }
27 |
28 | [TestMethod]
29 | public void testCompare()
30 | {
31 | Assert.IsTrue(HNum.make(9).compareTo(HNum.make(11)) < 0);
32 | Assert.IsTrue(HNum.make(-3).compareTo(HNum.make(-4)) > 0);
33 | Assert.AreEqual(HNum.make(-23).compareTo(HNum.make(-23)), 0);
34 | }
35 |
36 | [TestMethod]
37 | public void testZinc()
38 | {
39 | verifyZinc(HNum.make(123), "123");
40 | verifyZinc(HNum.make(123.4, "m/s"), "123.4m/s");
41 | verifyZinc(HNum.make(9.6, "m/s"), "9.6m/s");
42 | verifyZinc(HNum.make(-5.2, "\u00b0F"), "-5.2\u00b0F");
43 | verifyZinc(HNum.make(23, "%"), "23%");
44 | verifyZinc(HNum.make(2.4e-3, "fl_oz"), "0.0024fl_oz");
45 | verifyZinc(HNum.make(2.4e5, "$"), "240000$");
46 | Assert.IsTrue(read("1234.56fl_oz").hequals(HNum.make(1234.56, "fl_oz")));
47 | Assert.IsTrue(read("0.000028fl_oz").hequals(HNum.make(0.000028, "fl_oz")));
48 |
49 | // specials
50 | verifyZinc(HNum.make(double.NegativeInfinity), "-INF");
51 | verifyZinc(HNum.make(double.PositiveInfinity), "INF");
52 | verifyZinc(HNum.make(double.NaN), "NaN");
53 |
54 | // verify units never serialized for special values
55 | Assert.AreEqual(HNum.make(double.NaN, "ignore").toZinc(), "NaN");
56 | Assert.AreEqual(HNum.make(double.PositiveInfinity, "%").toZinc(), "INF");
57 | Assert.AreEqual(HNum.make(double.NegativeInfinity, "%").toZinc(), "-INF");
58 | }
59 |
60 | [TestMethod]
61 | public void verifyUnitNames()
62 | {
63 | Assert.IsTrue(HNum.isUnitName(null));
64 | Assert.IsFalse(HNum.isUnitName(""));
65 | Assert.IsTrue(HNum.isUnitName("x_z"));
66 | Assert.IsFalse(HNum.isUnitName("x z"));
67 | }
68 |
69 | [TestMethod]
70 | public void testFormatDecimalWithDot()
71 | {
72 | string defaultLanguage = CultureInfo.InvariantCulture.ToString();
73 | Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
74 | verifyZinc(HNum.make(2.4), "2.4");
75 | Thread.CurrentThread.CurrentCulture = new CultureInfo(defaultLanguage);
76 | }
77 |
78 | [TestMethod]
79 | [ExpectedException(typeof(ArgumentException))]
80 | public void testBadUnitConstruction()
81 | {
82 | string[] badunitNames = new string[]
83 | {
84 | "foo bar",
85 | "foo,bar"
86 | };
87 | foreach (string curUnit in badunitNames)
88 | HNum.make(123.4, curUnit);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HRefTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HRefTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testEquality()
19 | {
20 | Assert.IsTrue(HRef.make("foo").hequals(HRef.make("foo")));
21 | Assert.IsTrue(HRef.make("foo").hequals(HRef.make("foo", "Foo")));
22 | Assert.IsFalse(HRef.make("foo").hequals(HRef.make("Foo")));
23 | Assert.IsFalse(HRef.nullRef.hequals(HRef.nullRef));
24 | }
25 |
26 | [TestMethod]
27 | public void testZinc()
28 | {
29 | verifyZinc(HRef.make("1234-5678.foo:bar"), "@1234-5678.foo:bar");
30 | verifyZinc(HRef.make("1234-5678", "Foo Bar"), "@1234-5678 \"Foo Bar\"");
31 | verifyZinc(HRef.make("1234-5678", "Foo \"Bar\""), "@1234-5678 \"Foo \\\"Bar\\\"\"");
32 | }
33 |
34 | [TestMethod]
35 | public void testIsId()
36 | {
37 | Assert.IsFalse(HRef.isId(""));
38 | Assert.IsFalse(HRef.isId("%"));
39 | Assert.IsTrue(HRef.isId("a"));
40 | Assert.IsTrue(HRef.isId("a-b:c"));
41 | Assert.IsFalse(HRef.isId("a b"));
42 | Assert.IsFalse(HRef.isId("a\u0129b"));
43 | }
44 |
45 | [TestMethod]
46 | [ExpectedException(typeof(ArgumentException))]
47 | public void testBadRefConstruction()
48 | {
49 | string[] badRefs = new string[]
50 | {
51 | "@a",
52 | "a b",
53 | "a\n",
54 | "@"
55 | };
56 | foreach (string strID in badRefs)
57 | HRef.make(strID);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HStrTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HStrTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testEquality()
19 | {
20 | Assert.IsTrue(HStr.make("a").hequals(HStr.make("a")));
21 | Assert.IsFalse(HStr.make("a").hequals( HStr.make("b")));
22 | Assert.IsTrue(HStr.make("").hequals(HStr.make("")));
23 | }
24 |
25 | [TestMethod]
26 | public void testCompare()
27 | {
28 | Assert.IsTrue(HStr.make("abc").CompareTo(HStr.make("z")) < 0);
29 | Assert.AreEqual(HStr.make("Foo").CompareTo(HStr.make("Foo")), 0);
30 | }
31 |
32 | [TestMethod]
33 | public void testZinc()
34 | {
35 | verifyZinc(HStr.make("hello"), "\"hello\"");
36 | verifyZinc(HStr.make("_ \\ \" \n \r \t \u0011 _"), "\"_ \\\\ \\\" \\n \\r \\t \\u0011 _\"");
37 | verifyZinc(HStr.make("\u0abc"), "\"\u0abc\"");
38 | }
39 |
40 | [TestMethod]
41 | public void testHex()
42 | {
43 | // Changed test - unicode code must be valid not random like original test. - this is "NA"
44 | Assert.IsTrue(read("\"[\\u004e \\u0041]\"").hequals(HStr.make("[\u004e \u0041]")));
45 | Assert.IsTrue(read("\"[\\u004E \\u0041]\"").hequals(HStr.make("[\u004E \u0041]")));
46 | }
47 |
48 | [TestMethod]
49 | [ExpectedException(typeof(FormatException))]
50 | public void testNoEndQuote()
51 | {
52 | read("\"end...");
53 | }
54 |
55 | [TestMethod]
56 | [ExpectedException(typeof(ArgumentException))]
57 | public void testBadUnicodeEsc()
58 | {
59 | read("\"\\u1x34\"");
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HTimeTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HTimeTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testEquality()
19 | {
20 | Assert.IsTrue(HTime.make(1, 2, 3, 4).hequals(HTime.make(1, 2, 3, 4)));
21 | Assert.IsFalse(HTime.make(1, 2, 3, 4).hequals(HTime.make(9, 2, 3, 4)));
22 | Assert.IsFalse(HTime.make(1, 2, 3, 4).hequals( HTime.make(1, 9, 3, 4)));
23 | Assert.IsFalse(HTime.make(1, 2, 3, 4).hequals(HTime.make(1, 2, 9, 9)));
24 | }
25 |
26 | [TestMethod]
27 | public void testCompare()
28 | {
29 | Assert.IsTrue(HTime.make(0, 0, 0, 0).CompareTo(HTime.make(0, 0, 0, 9)) < 0);
30 | Assert.IsTrue(HTime.make(0, 0, 0, 0).CompareTo(HTime.make(0, 0, 1, 0)) < 0);
31 | Assert.IsTrue(HTime.make(0, 1, 0, 0).CompareTo(HTime.make(0, 0, 0, 0)) > 0);
32 | Assert.IsTrue(HTime.make(0, 0, 0, 0).CompareTo(HTime.make(2, 0, 0, 0)) < 0);
33 | Assert.AreEqual(HTime.make(2, 0, 0, 0).CompareTo(HTime.make(2, 0, 0, 0)), 0);
34 | }
35 |
36 | [TestMethod]
37 | public void testZinc()
38 | {
39 | verifyZinc(HTime.make(2, 3), "02:03:00");
40 | verifyZinc(HTime.make(2, 3, 4), "02:03:04");
41 | verifyZinc(HTime.make(2, 3, 4, 5), "02:03:04.005");
42 | verifyZinc(HTime.make(2, 3, 4, 56), "02:03:04.056");
43 | verifyZinc(HTime.make(2, 3, 4, 109), "02:03:04.109");
44 | verifyZinc(HTime.make(2, 3, 10, 109), "02:03:10.109");
45 | verifyZinc(HTime.make(2, 10, 59), "02:10:59");
46 | verifyZinc(HTime.make(10, 59, 30), "10:59:30");
47 | verifyZinc(HTime.make(23, 59, 59, 999), "23:59:59.999");
48 | verifyZinc(HTime.make(3, 20, 0), "03:20:00");
49 | Assert.IsTrue(HTime.make("10:04:19.181511").hequals( HTime.make(10, 04, 19, 181)));
50 | }
51 |
52 | [TestMethod]
53 | [ExpectedException(typeof(Exception))]
54 | public void testBadZinc()
55 | {
56 | string[] badZincs = new string[]
57 | {
58 | "13:xx:00",
59 | "13:45:0x",
60 | "13:45:00.",
61 | "13:45:00.x"
62 | };
63 | foreach (string zinc in badZincs)
64 | read(zinc);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HTimeZoneTest.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HTimeZoneTest : HaystackTest
9 | {
10 | [TestMethod]
11 | public void make_utc()
12 | {
13 | var tz = HTimeZone.make("UTC", false);
14 | Assert.IsTrue(new[] { "UTC", "Etc/UTC" }.Contains(tz.dntz.Id));
15 | }
16 |
17 | [TestMethod]
18 | public void make_sidney()
19 | {
20 | var tz = HTimeZone.make("Sydney", false);
21 | Assert.IsTrue(new[] { "AUS Eastern Standard Time", "Australia/Sydney" }.Contains(tz.dntz.Id));
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HTzTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using System.Linq;
10 | using Microsoft.VisualStudio.TestTools.UnitTesting;
11 | using ProjectHaystack;
12 |
13 | namespace ProjectHaystackTest
14 | {
15 | [TestClass]
16 | public class HTzTest
17 | {
18 | [TestMethod]
19 | public void testTz_NewYork()
20 | {
21 | verifyTz("New_York", "Eastern Standard Time", "America/New_York");
22 | }
23 |
24 | [TestMethod]
25 | public void testTz_Chicago()
26 | {
27 | verifyTz("Chicago", "Central Standard Time", "America/Chicago");
28 | }
29 |
30 | [TestMethod]
31 | public void testTz_Phoenix()
32 | {
33 | verifyTz("Phoenix", "US Mountain Standard Time", "America/Phoenix");
34 | }
35 |
36 | [TestMethod]
37 | public void testTz_London()
38 | {
39 | verifyTz("London", "GMT Standard Time", "Europe/London");
40 | }
41 |
42 | [TestMethod]
43 | public void testTz_UTC()
44 | {
45 | verifyTz("UTC", "UTC", "Etc/UTC");
46 | }
47 |
48 | [TestMethod]
49 | public void testTz_GMT()
50 | {
51 | verifyTz("GMT", "UTC", "GMT");
52 | }
53 |
54 | [TestMethod]
55 | public void testTz_Rel()
56 | {
57 | verifyTz("Rel", "UTC", "GMT"); // GMT
58 | }
59 |
60 | private void verifyTz(string name, params string[] dntzIds)
61 | {
62 | HTimeZone tz = HTimeZone.make(name, false);
63 | // Ignore issues with locally installed timezones.
64 | if (tz == null)
65 | return;
66 | TimeZoneInfo dntz = tz.dntz;
67 | Assert.AreEqual(tz.ToString(), name);
68 | Assert.IsTrue(dntzIds.Contains(dntz.Id), $"{dntz.Id} not in [{string.Join(", ", dntzIds)}]");
69 | // TODO: What is this testing? Move into another test?
70 | //TimeZoneInfo dntzByID = TimeZoneConverter.TZConvert.GetTimeZoneInfo(dntz.Id);
71 | //Assert.IsTrue(tz.hequals(HTimeZone.make(dntzByID, false)), $"{tz} does not equal {dntzByID}");
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HUriTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using ProjectHaystack;
11 |
12 | namespace ProjectHaystackTest
13 | {
14 | [TestClass]
15 | public class HUriTest : HValTest
16 | {
17 | [TestMethod]
18 | public void testEquality()
19 | {
20 | Assert.IsTrue(HUri.make("a").hequals(HUri.make("a")));
21 | Assert.IsFalse(HUri.make("a").hequals(HUri.make("b")));
22 | Assert.IsTrue(HUri.make("") == HUri.make(""));
23 | }
24 |
25 | [TestMethod]
26 | public void testCompare()
27 | {
28 | Assert.IsTrue(HUri.make("abc").CompareTo(HUri.make("z")) < 0);
29 | Assert.AreEqual(HUri.make("Foo").CompareTo(HUri.make("Foo")), 0);
30 | }
31 |
32 | [TestMethod]
33 | public void testZinc()
34 | {
35 | verifyZinc(HUri.make("http://foo.com/f?q"), "`http://foo.com/f?q`");
36 | verifyZinc(HUri.make("a$b"), "`a$b`");
37 | verifyZinc(HUri.make("a`b"), "`a\\`b`");
38 | verifyZinc(HUri.make("http\\:a\\?b"), "`http\\:a\\?b`");
39 | verifyZinc(HUri.make("\u01ab.txt"), "`\u01ab.txt`");
40 | }
41 |
42 | [TestMethod]
43 | [ExpectedException(typeof(FormatException))]
44 | public void testBadZinc()
45 | {
46 | string[] badZincs = new string[]
47 | {
48 | "`no end",
49 | "`new\nline`"
50 | };
51 | foreach (string zinc in badZincs)
52 | read(zinc);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HValTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using Microsoft.VisualStudio.TestTools.UnitTesting;
9 | using ProjectHaystack;
10 | using ProjectHaystack.io;
11 | using M = ProjectHaystack.HaystackValueMapper;
12 |
13 | namespace ProjectHaystackTest
14 | {
15 | [TestClass]
16 | public abstract class HValTest : HaystackTest
17 | {
18 | protected void verifyZinc(HVal val, string s)
19 | {
20 | Assert.AreEqual(val.toZinc(), s);
21 | Assert.IsTrue(read(s).hequals(val));
22 | }
23 |
24 | protected HVal read(string s)
25 | {
26 | return M.Map(ZincReader.ReadValue(s));
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HXStrTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HXStrTest : HValTest
9 | {
10 | [TestMethod]
11 | public void testTypeStartsWithUpper()
12 | {
13 | HXStr.decode("Type", "a");
14 | Assert.ThrowsException(() => HXStr.decode("type", "a"));
15 | }
16 |
17 | [TestMethod]
18 | public void testTypeContainsValidCharacters()
19 | {
20 | HXStr.decode("TyP0_s", "a");
21 | Assert.ThrowsException(() => HXStr.decode("T.", "a"));
22 | Assert.ThrowsException(() => HXStr.decode("T,", "a"));
23 | }
24 |
25 | [TestMethod]
26 | public void testEquality()
27 | {
28 | Assert.IsTrue(HXStr.decode("Type", "a").hequals(HXStr.decode("Type", "a")));
29 | Assert.IsFalse(HXStr.decode("X", "a").hequals(HXStr.decode("X", "b")));
30 | Assert.IsTrue(HXStr.decode("X", "").hequals(HXStr.decode("X", "")));
31 | }
32 |
33 | [TestMethod]
34 | public void testCompare()
35 | {
36 | Assert.IsTrue(HXStr.decode("Type", "abc").CompareTo(HXStr.decode("Type", "z")) < 0);
37 | Assert.AreEqual(HXStr.decode("Type", "Foo").CompareTo(HXStr.decode("Type", "Foo")), 0);
38 | }
39 |
40 | [TestMethod]
41 | public void testZinc()
42 | {
43 | verifyZinc(HXStr.decode("Type", "hello"), "Type(\"hello\")");
44 | verifyZinc(HXStr.decode("Type", "\u0abc"), "Type(\"\u0abc\")");
45 | }
46 |
47 | [TestMethod]
48 | public void testHex()
49 | {
50 | // Changed test - unicode code must be valid not random like original test. - this is "NA"
51 | Assert.IsTrue(read("Type(\"[\\u004e \\u0041]\")").hequals(HXStr.decode("Type", "[\u004e \u0041]")));
52 | Assert.IsTrue(read("Type(\"[\\u004E \\u0041]\")").hequals(HXStr.decode("Type", "[\u004E \u0041]")));
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/HaystackTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 16 August 2018 Ian Davies Creation based on Java Toolkit at same time from project-haystack.org downloads
7 | //
8 | using System;
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
10 | using System.Collections.Generic;
11 | using System.Linq;
12 | using System.Text;
13 | using System.Threading.Tasks;
14 | using ProjectHaystack;
15 |
16 | namespace ProjectHaystackTest
17 | {
18 | public abstract class HaystackTest
19 | {
20 | protected virtual HNum n(long val) { return HNum.make(val); }
21 | protected virtual HNum n(double val) { return HNum.make(val); }
22 | protected virtual HNum n(double val, string unit) { return HNum.make(val, unit); }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/ProjectHaystackTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 | 2.1.19
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/Util/UtilTest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017, SkyFoundry LLC
3 | // Licensed under the Academic Free License version 3.0
4 | //
5 | // History:
6 | // 26 Jun 2017 Hank Weber Creation
7 | //
8 |
9 | using System;
10 | using Microsoft.VisualStudio.TestTools.UnitTesting;
11 | using System.Security.Cryptography;
12 |
13 | namespace ProjectHaystackTest.Util
14 | {
15 | using Base64 = ProjectHaystack.Util.Base64;
16 | using Pbkdf2 = ProjectHaystack.Util.Pbkdf2;
17 |
18 | [TestClass]
19 | public class UtilTest
20 | {
21 | private static string RandomString()
22 | {
23 | Guid g = Guid.NewGuid();
24 | string GuidString = Convert.ToBase64String(g.ToByteArray());
25 | GuidString = GuidString.Replace("=", "");
26 | GuidString = GuidString.Replace("+", "");
27 | return GuidString;
28 | }
29 |
30 | [TestMethod]
31 | public void Base64Test()
32 | {
33 | for (int i = 0; i < 1000; i++)
34 | {
35 | string s1 = RandomString();
36 | string enc = Base64.STANDARD.EncodeUtf8(s1);
37 | string s2 = Base64.STANDARD.decodeUTF8(enc);
38 | Assert.AreEqual(s1, s2);
39 |
40 | enc = Base64.STANDARD.Encode(s1);
41 | s2 = Base64.STANDARD.Decode(enc);
42 | Assert.AreEqual(s1, s2);
43 |
44 | enc = Base64.URI.EncodeUtf8(s1);
45 | s2 = Base64.URI.decodeUTF8(enc);
46 | Assert.AreEqual(s1, s2);
47 |
48 | enc = Base64.URI.Encode(s1);
49 | s2 = Base64.URI.Decode(enc);
50 | Assert.AreEqual(s1, s2);
51 | }
52 | }
53 |
54 |
55 | public void DoPbkTest(string password, string salt, int iterations, int dkLen, string expected)
56 | {
57 | using (var hmac = new HMACSHA256())
58 | {
59 | var mine = new Pbkdf2(hmac, System.Text.Encoding.UTF8.GetBytes(password), System.Text.Encoding.UTF8.GetBytes(salt), iterations);
60 | sbyte[] result = mine.GetBytes(dkLen);
61 | byte[] usResult = (byte[])(Array)result;
62 | String hex = BitConverter.ToString(usResult);
63 | Assert.AreEqual(hex, expected);
64 | }
65 | }
66 |
67 | [TestMethod]
68 | public void PbkTest()
69 | {
70 | DoPbkTest("password", "salt", 1, 32, "12-0F-B6-CF-FC-F8-B3-2C-43-E7-22-52-56-C4-F8-37-A8-65-48-C9-2C-CC-35-48-08-05-98-7C-B7-0B-E1-7B");
71 | DoPbkTest("password", "salt", 2, 32, "AE-4D-0C-95-AF-6B-46-D3-2D-0A-DF-F9-28-F0-6D-D0-2A-30-3F-8E-F3-C2-51-DF-D6-E2-D8-5A-95-47-4C-43");
72 | DoPbkTest("password", "salt", 4096, 32, "C5-E4-78-D5-92-88-C8-41-AA-53-0D-B6-84-5C-4C-8D-96-28-93-A0-01-CE-4E-11-A4-96-38-73-AA-98-13-4A");
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/BackCompat/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/Mocks/HttpClientMockBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Http;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using Moq;
10 | using Moq.Protected;
11 | using ProjectHaystack;
12 | using ProjectHaystack.io;
13 |
14 | namespace ProjectHaystackTest.Mocks
15 | {
16 | public class HttpClientMockBuilder
17 | {
18 | private readonly Uri _baseUri;
19 | private readonly Mock _httpMessageHanderMock = new Mock();
20 | private readonly List>> _requestHandlers = new List>>();
21 |
22 | public HttpClientMockBuilder(Uri baseUri)
23 | {
24 | _baseUri = baseUri;
25 | }
26 |
27 | public HttpClient Build()
28 | {
29 | _httpMessageHanderMock
30 | .Protected()
31 | .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny())
32 | .Returns((request, _) =>
33 | {
34 | foreach (var requestHandler in _requestHandlers)
35 | {
36 | var response = requestHandler(request);
37 | if (response != null)
38 | {
39 | return response;
40 | }
41 | }
42 | throw new Exception("Unexpected request");
43 | });
44 | return new HttpClient(_httpMessageHanderMock.Object);
45 | }
46 |
47 | public HttpClientMockBuilder WithBasicAuthentication(string allowedBasicAuth)
48 | {
49 | _requestHandlers.Add(request =>
50 | {
51 | if (request.Headers.Authorization == null)
52 | {
53 | return null;
54 | }
55 | if (request.Headers.Authorization.Scheme == "HELLO")
56 | {
57 | var response = new HttpResponseMessage();
58 | response.Headers.Add("WWW-Authenticate", "basic");
59 | return Task.FromResult(response);
60 | }
61 | if (request.Headers.Authorization.Scheme == "Basic" && request.RequestUri == new Uri(_baseUri, "about"))
62 | {
63 | if (request.Headers.Authorization.Parameter == allowedBasicAuth)
64 | {
65 | return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
66 | }
67 | return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));
68 | }
69 | return null;
70 | });
71 |
72 | return this;
73 | }
74 |
75 | public HttpClientMockBuilder WithReadAsync(string expectedFilter, HaystackGrid response)
76 | {
77 | _requestHandlers.Add(async request =>
78 | {
79 | var relativeUri = _baseUri.MakeRelativeUri(request.RequestUri);
80 | if (relativeUri.OriginalString != "read")
81 | {
82 | return null;
83 | }
84 | var reader = new ZincReader(await request.Content.ReadAsStringAsync());
85 | var grid = reader.ReadValue();
86 | var filter = grid.Rows.First().Get("filter").Value;
87 | if (filter != expectedFilter)
88 | {
89 | return null;
90 | }
91 | using (var stream = new MemoryStream())
92 | using (var streamWriter = new StreamWriter(stream))
93 | {
94 | var writer = new ZincWriter(streamWriter);
95 | writer.WriteValue(response);
96 | streamWriter.Flush();
97 | stream.Position = 0;
98 | return new HttpResponseMessage
99 | {
100 | Content = new StringContent(await new StreamReader(stream).ReadToEndAsync()),
101 | };
102 | }
103 | });
104 |
105 | return this;
106 | }
107 |
108 | public HttpClientMockBuilder WithRequestHandler(Func> handleRequest)
109 | {
110 | _requestHandlers.Add(handleRequest);
111 |
112 | return this;
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/ProjectHaystackTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ProjectHaystackTest/Validation/HaystackValidatorTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack.Validation;
3 |
4 | namespace ProjectHaystackTest.Validation
5 | {
6 | [TestClass]
7 | public class HaystackValidatorTests
8 | {
9 | [TestMethod]
10 | public void TestIsTagName()
11 | {
12 | Assert.IsFalse(HaystackValidator.IsTagName(""));
13 | Assert.IsFalse(HaystackValidator.IsTagName("A"));
14 | Assert.IsFalse(HaystackValidator.IsTagName(" "));
15 | Assert.IsTrue(HaystackValidator.IsTagName("a"));
16 | Assert.IsTrue(HaystackValidator.IsTagName("a_B_19"));
17 | Assert.IsFalse(HaystackValidator.IsTagName("a b"));
18 | Assert.IsFalse(HaystackValidator.IsTagName("a\u0128"));
19 | Assert.IsFalse(HaystackValidator.IsTagName("a\u0129x"));
20 | Assert.IsFalse(HaystackValidator.IsTagName("a\uabcdx"));
21 | Assert.IsTrue(HaystackValidator.IsTagName("^tag"));
22 | }
23 |
24 | [TestMethod]
25 | public void TestIsId()
26 | {
27 | Assert.IsFalse(HaystackValidator.IsReferenceId(""));
28 | Assert.IsFalse(HaystackValidator.IsReferenceId("%"));
29 | Assert.IsTrue(HaystackValidator.IsReferenceId("a"));
30 | Assert.IsTrue(HaystackValidator.IsReferenceId("a-b:c"));
31 | Assert.IsFalse(HaystackValidator.IsReferenceId("a b"));
32 | Assert.IsFalse(HaystackValidator.IsReferenceId("a\u0129b"));
33 | }
34 |
35 | [TestMethod]
36 | public void VerifyUnitNames()
37 | {
38 | Assert.IsTrue(HaystackValidator.IsUnitName(null));
39 | Assert.IsFalse(HaystackValidator.IsUnitName(""));
40 | Assert.IsTrue(HaystackValidator.IsUnitName("x_z"));
41 | Assert.IsFalse(HaystackValidator.IsUnitName("x z"));
42 | Assert.IsTrue(HaystackValidator.IsUnitName("ft²"));
43 | }
44 |
45 | [TestMethod]
46 | public void TestIsLatitude()
47 | {
48 | Assert.IsFalse(HaystackValidator.IsLatitude(-91m));
49 | Assert.IsTrue(HaystackValidator.IsLatitude(-90m));
50 | Assert.IsTrue(HaystackValidator.IsLatitude(-89m));
51 | Assert.IsTrue(HaystackValidator.IsLatitude(90m));
52 | Assert.IsFalse(HaystackValidator.IsLatitude(91m));
53 | }
54 |
55 | [TestMethod]
56 | public void TestIsLongitude()
57 | {
58 | Assert.IsFalse(HaystackValidator.IsLongitude(-181m));
59 | Assert.IsTrue(HaystackValidator.IsLongitude(-179.99m));
60 | Assert.IsTrue(HaystackValidator.IsLongitude(180m));
61 | Assert.IsFalse(HaystackValidator.IsLongitude(181m));
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackBinaryTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackBinaryTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | var bin1 = new HaystackBinary("text/plain");
13 | var bin2 = new HaystackBinary("text/plain");
14 | var bin3 = new HaystackBinary("text/xml");
15 |
16 | Assert.AreEqual(bin1, bin2);
17 | Assert.AreNotEqual(bin1, bin3);
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackBooleanTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackBooleanTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | Assert.IsTrue(new HaystackBoolean(true).Equals(new HaystackBoolean(true)));
13 | Assert.IsFalse(new HaystackBoolean(true).Equals(new HaystackBoolean(false)));
14 | Assert.IsTrue(new HaystackBoolean(true).Equals(new HaystackBoolean(true)));
15 | Assert.IsTrue(new HaystackBoolean(false).Equals(new HaystackBoolean(false)));
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackCoordinateTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 | using ProjectHaystack.io;
5 |
6 | namespace ProjectHaystackTest
7 | {
8 | [TestClass]
9 | public class HaystackCoordinateTest
10 | {
11 | [TestMethod]
12 | public void TestLatBoundaries()
13 | {
14 | VerifyCoord(90, 123, "C(90,123)");
15 | VerifyCoord(-90, 123, "C(-90,123)");
16 | VerifyCoord(89.888999m, 123, "C(89.888999,123)");
17 | VerifyCoord(-89.888999m, 123, "C(-89.888999,123)");
18 | }
19 |
20 | [TestMethod]
21 | public void TestLonBoundaries()
22 | {
23 | VerifyCoord(45, 180, "C(45,180)");
24 | VerifyCoord(45, -180, "C(45,-180)");
25 | VerifyCoord(45, 179.999129m, "C(45,179.999129)");
26 | VerifyCoord(45, -179.999129m, "C(45,-179.999129)");
27 | }
28 |
29 | [TestMethod]
30 | public void TestDecimalPlaces()
31 | {
32 | VerifyCoord(9.1m, -8.1m, "C(9.1,-8.1)");
33 | VerifyCoord(9.12m, -8.13m, "C(9.12,-8.13)");
34 | VerifyCoord(9.123m, -8.134m, "C(9.123,-8.134)");
35 | VerifyCoord(9.1234m, -8.1346m, "C(9.1234,-8.1346)");
36 | VerifyCoord(9.12345m, -8.13456m, "C(9.12345,-8.13456)");
37 | VerifyCoord(9.123452m, -8.134567m, "C(9.123452,-8.134567)");
38 | }
39 |
40 | [TestMethod]
41 | public void TestZeroBoundaries()
42 | {
43 | VerifyCoord(0, 0, "C(0,0)");
44 | VerifyCoord(0.3m, -0.3m, "C(0.3,-0.3)");
45 | VerifyCoord(0.03m, -0.03m, "C(0.03,-0.03)");
46 | VerifyCoord(0.003m, -0.003m, "C(0.003,-0.003)");
47 | VerifyCoord(0.0003m, -0.0003m, "C(0.0003,-0.0003)");
48 | VerifyCoord(0.02003m, -0.02003m, "C(0.02003,-0.02003)");
49 | VerifyCoord(0.020003m, -0.020003m, "C(0.020003,-0.020003)");
50 | VerifyCoord(0.000123m, -0.000123m, "C(0.000123,-0.000123)");
51 | VerifyCoord(7.000123m, -7.000123m, "C(7.000123,-7.000123)");
52 | }
53 |
54 | [TestMethod]
55 | public void TestMakeErrors()
56 | {
57 | try { new HaystackCoordinate(91, 12); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
58 | try { new HaystackCoordinate(-90.2m, 12); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
59 | try { new HaystackCoordinate(13, 180.009m); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
60 | try { new HaystackCoordinate(13, -181); Assert.Fail(); } catch (ArgumentException) { Assert.IsTrue(true); }
61 | }
62 |
63 | private void VerifyCoord(decimal latitude, decimal longitude, string s)
64 | {
65 | var coordinate = new HaystackCoordinate(latitude, longitude);
66 | Assert.AreEqual(latitude, coordinate.Latitude);
67 | Assert.AreEqual(longitude, coordinate.Longitude);
68 | Assert.AreEqual(s, ZincWriter.ToZinc(coordinate));
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackDateTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackDateTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | Assert.IsTrue(new HaystackDate(2011, 6, 7).Equals(new HaystackDate(2011, 6, 7)));
13 | Assert.IsFalse(new HaystackDate(2011, 6, 7).Equals(new HaystackDate(2011, 6, 8)));
14 | Assert.IsFalse(new HaystackDate(2011, 6, 7).Equals(new HaystackDate(2011, 2, 7)));
15 | Assert.IsFalse(new HaystackDate(2011, 6, 7).Equals(new HaystackDate(2009, 6, 7)));
16 | }
17 |
18 | [TestMethod]
19 | public void TestCompare()
20 | {
21 | Assert.IsTrue(new HaystackDate(2011, 6, 9).CompareTo(new HaystackDate(2011, 6, 21)) < 0);
22 | Assert.IsTrue(new HaystackDate(2011, 10, 9).CompareTo(new HaystackDate(2011, 3, 21)) > 0);
23 | Assert.IsTrue(new HaystackDate(2010, 6, 9).CompareTo(new HaystackDate(2000, 9, 30)) > 0);
24 | Assert.AreEqual(new HaystackDate(2010, 6, 9).CompareTo(new HaystackDate(2010, 6, 9)), 0);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackDateTimeTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackDateTimeTests
9 | {
10 | public static HaystackTimeZone utc = HaystackTimeZone.UTC;
11 | public static HaystackTimeZone london = new HaystackTimeZone("London");
12 |
13 | [TestMethod]
14 | public void TestEquality()
15 | {
16 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc)));
17 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2009, 1, 2, 3, 4, 5), utc)));
18 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 9, 2, 3, 4, 5), utc)));
19 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 9, 3, 4, 5), utc)));
20 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 2, 9, 4, 5), utc)));
21 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 9, 5), utc)));
22 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 9), utc)));
23 | Assert.IsFalse(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).Equals(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), london)));
24 | }
25 |
26 | [TestMethod]
27 | public void TestCompare()
28 | {
29 | Assert.AreEqual(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc)), 0);
30 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 6), utc)) < 0);
31 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 5, 5), utc)) < 0);
32 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 2, 4, 4, 5), utc)) < 0);
33 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 3, 3, 4, 5), utc)) < 0);
34 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 2, 2, 3, 4, 5), utc)) < 0);
35 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2012, 1, 2, 3, 4, 5), utc)) < 0);
36 | Assert.IsTrue(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), utc).CompareTo(new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 0), utc)) > 0);
37 | }
38 |
39 | [TestMethod]
40 | public void TestTimeZoneOffset()
41 | {
42 | Assert.AreEqual(TimeSpan.FromHours(0), new HaystackDateTime(new DateTime(2011, 1, 2, 3, 4, 5), london).Value.Offset);
43 | Assert.AreEqual(TimeSpan.FromHours(1), new HaystackDateTime(new DateTime(2011, 7, 2, 3, 4, 5), london).Value.Offset);
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackDefinitionTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackDefinitionTests
9 | {
10 | [TestMethod]
11 | public void TestEquality()
12 | {
13 | Assert.IsTrue(new HaystackDefinition("^foo").Equals(new HaystackDefinition("^foo")));
14 | Assert.IsFalse(new HaystackDefinition("^foo").Equals(new HaystackDefinition("^Foo")));
15 | }
16 |
17 | [TestMethod]
18 | [ExpectedException(typeof(ArgumentException))]
19 | public void TestBadDefConstruction()
20 | {
21 | string[] badDefs = new string[]
22 | {
23 | "^@a",
24 | "^a b",
25 | "^a\n",
26 | "^@",
27 | "a",
28 | "bcd",
29 | };
30 | foreach (string strID in badDefs)
31 | {
32 | new HaystackDefinition(strID);
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackListTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.VisualStudio.TestTools.UnitTesting;
4 | using ProjectHaystack;
5 |
6 | namespace ProjectHaystackTest
7 | {
8 | [TestClass]
9 | public class HaystackListTests
10 | {
11 | [TestMethod]
12 | public void TestEmpty()
13 | {
14 | Assert.IsTrue(new HaystackList().Equals(new HaystackList(new List())));
15 | Assert.IsTrue(new HaystackList().Equals(new HaystackList(new HaystackValue[0])));
16 | Assert.AreEqual(new HaystackList().Count, 0);
17 | Assert.ThrowsException(() => new HaystackList()[0]);
18 | }
19 |
20 | [TestMethod]
21 | public void TestBasics()
22 | {
23 | var hrefTest = new HaystackReference("a");
24 | var str = new HaystackString("string");
25 | List items = new List();
26 | items.Add(hrefTest);
27 | items.Add(str);
28 |
29 | var list = new HaystackList(items);
30 | Assert.AreEqual(list.Count, 2);
31 | Assert.AreEqual(list[0], hrefTest);
32 | Assert.AreEqual(list[1], str);
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackMarkerTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackMarkerTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | Assert.IsTrue(new HaystackMarker().Equals(new HaystackMarker()));
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackNumberTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackNumberTests
9 | {
10 | [TestMethod]
11 | public void TestEquality()
12 | {
13 | Assert.IsTrue(new HaystackNumber(2).Equals(new HaystackNumber(2.0, null)));
14 | Assert.IsFalse(new HaystackNumber(2).Equals(new HaystackNumber(2, "%")));
15 | Assert.IsFalse(new HaystackNumber(2, "%").Equals(new HaystackNumber(2)));
16 | Assert.IsTrue(new HaystackNumber(0).Equals(new HaystackNumber(0.0)));
17 | }
18 |
19 | [TestMethod]
20 | public void TestCompare()
21 | {
22 | Assert.IsTrue(new HaystackNumber(9).CompareTo(new HaystackNumber(11)) < 0);
23 | Assert.IsTrue(new HaystackNumber(-3).CompareTo(new HaystackNumber(-4)) > 0);
24 | Assert.AreEqual(new HaystackNumber(-23).CompareTo(new HaystackNumber(-23)), 0);
25 | }
26 |
27 | [TestMethod]
28 | [ExpectedException(typeof(ArgumentException))]
29 | public void TestBadUnitConstruction()
30 | {
31 | string[] badunitNames = new string[]
32 | {
33 | "foo bar",
34 | "foo,bar"
35 | };
36 | foreach (string curUnit in badunitNames)
37 | {
38 | new HaystackNumber(123.4, curUnit);
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackReferenceTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackReferenceTests
9 | {
10 | [TestMethod]
11 | public void TestEquality()
12 | {
13 | Assert.IsTrue(new HaystackReference("foo").Equals(new HaystackReference("foo")));
14 | Assert.IsTrue(new HaystackReference("foo").Equals(new HaystackReference("foo", "Foo")));
15 | Assert.IsFalse(new HaystackReference("foo").Equals(new HaystackReference("Foo")));
16 | }
17 |
18 | [TestMethod]
19 | [ExpectedException(typeof(ArgumentException))]
20 | public void TestBadRefConstruction()
21 | {
22 | string[] badRefs = new string[]
23 | {
24 | "@a",
25 | "a b",
26 | "a\n",
27 | "@"
28 | };
29 | foreach (string strID in badRefs)
30 | {
31 | new HaystackReference(strID);
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackRowTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using ProjectHaystack;
6 |
7 | namespace ProjectHaystackTest
8 | {
9 | [TestClass]
10 | public class HaystackRowTests
11 | {
12 | [TestMethod]
13 | public void TestEmpty()
14 | {
15 | var row = BuildRows(Array.Empty(), Array.Empty()).First();
16 | Assert.IsTrue(row.IsEmpty());
17 | Assert.AreEqual(row.Count, 0);
18 | Assert.IsFalse(row.ContainsKey("foo"));
19 | }
20 |
21 | [TestMethod]
22 | public void TestCheckedImplicitMissing()
23 | {
24 | var row = BuildRows(Array.Empty(), Array.Empty()).First();
25 | Assert.ThrowsException(() => row["foo"]);
26 | }
27 |
28 | [TestMethod]
29 | public void TestBasics()
30 | {
31 | var row = BuildRows(
32 | new[] { "id", "site", "geoAddr", "area", "date", "null" },
33 | new HaystackValue[] { new HaystackReference("aaaa-bbbb"), new HaystackMarker(), new HaystackString("Richmond, Va"), new HaystackNumber(1200, "ft"), new HaystackDate(2000, 12, 3), null })
34 | .First();
35 |
36 | // size
37 | Assert.AreEqual(row.Count, 5);
38 | Assert.IsFalse(row.IsEmpty());
39 |
40 | // configured tags
41 | Assert.IsTrue(row["id"].Equals(new HaystackReference("aaaa-bbbb")));
42 | Assert.IsTrue(row["site"].Equals(new HaystackMarker()));
43 | Assert.IsTrue(row["geoAddr"].Equals(new HaystackString("Richmond, Va")));
44 | Assert.IsTrue(row.Get("area").Equals(new HaystackNumber(1200, "ft")));
45 | Assert.IsTrue(row.Get("date").Equals(new HaystackDate(2000, 12, 3)));
46 | Assert.ThrowsException(() => row.Get("null"));
47 |
48 | // missing tag
49 | Assert.IsFalse(row.ContainsKey("foo"));
50 | Assert.ThrowsException(() => row.Get("foo"));
51 | }
52 |
53 | [TestMethod]
54 | public void TestToArray()
55 | {
56 | var row = BuildRows(new[] { "x", "y" }, new HaystackValue[] { new HaystackMarker(), new HaystackString("str") }).First();
57 | var array = row.ToArray();
58 | Assert.AreEqual(2, array.Length);
59 | Assert.AreEqual("x", array[0].Key);
60 | Assert.AreEqual(new HaystackMarker(), array[0].Value);
61 | Assert.AreEqual("y", array[1].Key);
62 | Assert.AreEqual(new HaystackString("str"), array[1].Value);
63 | }
64 |
65 | [TestMethod]
66 | public void TestAdd()
67 | {
68 | var row = BuildRows(new[] { "x", "y" }, new HaystackValue[] { new HaystackMarker(), new HaystackString("y") }).First();
69 | Assert.ThrowsException(() => row.Add("z", new HaystackMarker()));
70 | }
71 |
72 | [TestMethod]
73 | public void TestRemove()
74 | {
75 | var row = BuildRows(new[] { "x", "y" }, new HaystackValue[] { new HaystackMarker(), new HaystackString("y") }).First();
76 | Assert.ThrowsException(() => row.Remove("y"));
77 | }
78 |
79 | public static IEnumerable BuildRows(ICollection cols, params HaystackValue[][] rows)
80 | {
81 | var grid = new HaystackGrid();
82 | foreach (var col in cols)
83 | {
84 | grid.AddColumn(col);
85 | }
86 | foreach (var row in rows)
87 | {
88 | grid.AddRow(row);
89 | }
90 | return grid.Rows;
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackStringTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackStringTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | Assert.IsTrue(new HaystackString("a").Equals(new HaystackString("a")));
13 | Assert.IsFalse(new HaystackString("a").Equals(new HaystackString("b")));
14 | Assert.IsTrue(new HaystackString("").Equals(new HaystackString("")));
15 | }
16 |
17 | [TestMethod]
18 | public void TestCompare()
19 | {
20 | Assert.IsTrue(new HaystackString("abc").CompareTo(new HaystackString("z")) < 0);
21 | Assert.AreEqual(new HaystackString("Foo").CompareTo(new HaystackString("Foo")), 0);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackTimeTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackTimeTests
9 | {
10 | [TestMethod]
11 | public void TestEquality()
12 | {
13 | Assert.IsTrue(new HaystackTime(new TimeSpan(0, 1, 2, 3, 4)).Equals(new HaystackTime(new TimeSpan(0, 1, 2, 3, 4))));
14 | Assert.IsFalse(new HaystackTime(new TimeSpan(0, 1, 2, 3, 4)).Equals(new HaystackTime(new TimeSpan(0, 9, 2, 3, 4))));
15 | Assert.IsFalse(new HaystackTime(new TimeSpan(0, 1, 2, 3, 4)).Equals(new HaystackTime(new TimeSpan(0, 1, 9, 3, 4))));
16 | Assert.IsFalse(new HaystackTime(new TimeSpan(0, 1, 2, 3, 4)).Equals(new HaystackTime(new TimeSpan(0, 1, 2, 9, 9))));
17 | }
18 |
19 | [TestMethod]
20 | public void TestCompare()
21 | {
22 | Assert.IsTrue(new HaystackTime(new TimeSpan(0, 0, 0, 0, 0)).CompareTo(new HaystackTime(new TimeSpan(0, 0, 0, 0, 9))) < 0);
23 | Assert.IsTrue(new HaystackTime(new TimeSpan(0, 0, 0, 0, 0)).CompareTo(new HaystackTime(new TimeSpan(0, 0, 0, 1, 0))) < 0);
24 | Assert.IsTrue(new HaystackTime(new TimeSpan(0, 0, 1, 0, 0)).CompareTo(new HaystackTime(new TimeSpan(0, 0, 0, 0, 0))) > 0);
25 | Assert.IsTrue(new HaystackTime(new TimeSpan(0, 0, 0, 0, 0)).CompareTo(new HaystackTime(new TimeSpan(0, 2, 0, 0, 0))) < 0);
26 | Assert.AreEqual(new HaystackTime(new TimeSpan(0, 2, 0, 0, 0)).CompareTo(new HaystackTime(new TimeSpan(0, 2, 0, 0, 0))), 0);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackTimeZoneTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackTimeZoneTests
9 | {
10 | [TestMethod]
11 | public void Make_utc()
12 | {
13 | var tz = new HaystackTimeZone("UTC");
14 | Assert.IsTrue(new[] { "UTC", "Etc/UTC" }.Contains(tz.TimeZoneInfo.Id));
15 | }
16 |
17 | [TestMethod]
18 | public void Make_sidney()
19 | {
20 | var tz = new HaystackTimeZone("Sydney");
21 | Assert.IsTrue(new[] { "AUS Eastern Standard Time", "Australia/Sydney" }.Contains(tz.TimeZoneInfo.Id));
22 | }
23 |
24 | [TestMethod]
25 | public void TestTz_NewYork()
26 | {
27 | VerifyTz("New_York", "Eastern Standard Time", "America/New_York");
28 | }
29 |
30 | [TestMethod]
31 | public void TestTz_Chicago()
32 | {
33 | VerifyTz("Chicago", "Central Standard Time", "America/Chicago");
34 | }
35 |
36 | [TestMethod]
37 | public void TestTz_Phoenix()
38 | {
39 | VerifyTz("Phoenix", "US Mountain Standard Time", "America/Phoenix");
40 | }
41 |
42 | [TestMethod]
43 | public void TestTz_London()
44 | {
45 | VerifyTz("London", "GMT Standard Time", "Europe/London");
46 | }
47 |
48 | [TestMethod]
49 | public void TestTz_UTC()
50 | {
51 | VerifyTz("UTC", "UTC", "Etc/UTC");
52 | }
53 |
54 | [TestMethod]
55 | public void TestTz_GMT()
56 | {
57 | VerifyTz("GMT", "UTC", "GMT");
58 | }
59 |
60 | [TestMethod]
61 | public void TestTz_Rel()
62 | {
63 | VerifyTz("Rel", "UTC", "GMT"); // GMT
64 | }
65 |
66 | private void VerifyTz(string name, params string[] dntzIds)
67 | {
68 | var tz = new HaystackTimeZone(name);
69 | // Ignore issues with locally installed timezones.
70 | if (tz == null)
71 | {
72 | return;
73 | }
74 | var dntz = tz.TimeZoneInfo;
75 | Assert.AreEqual(tz.Name, name);
76 | Assert.IsTrue(dntzIds.Contains(dntz.Id), $"{dntz.Id} not in [{string.Join(", ", dntzIds)}]");
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackUriTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 |
4 | namespace ProjectHaystackTest
5 | {
6 | [TestClass]
7 | public class HaystackUriTests
8 | {
9 | [TestMethod]
10 | public void TestEquality()
11 | {
12 | Assert.IsTrue(new HaystackUri("a").Equals(new HaystackUri("a")));
13 | Assert.IsFalse(new HaystackUri("a").Equals(new HaystackUri("b")));
14 | Assert.IsTrue(new HaystackUri("") == new HaystackUri(""));
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/Values/HaystackXStringTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 |
5 | namespace ProjectHaystackTest
6 | {
7 | [TestClass]
8 | public class HaystackXStringTests
9 | {
10 | [TestMethod]
11 | public void TestTypeStartsWithUpper()
12 | {
13 | new HaystackXString("a", "Type");
14 | Assert.ThrowsException(() => new HaystackXString("a", "type"));
15 | }
16 |
17 | [TestMethod]
18 | public void TestTypeContainsValidCharacters()
19 | {
20 | new HaystackXString("a", "TyP0_s");
21 | Assert.ThrowsException(() => new HaystackXString("a", "T."));
22 | Assert.ThrowsException(() => new HaystackXString("a", "T,"));
23 | }
24 |
25 | [TestMethod]
26 | public void TestEquality()
27 | {
28 | Assert.IsTrue(new HaystackXString("a", "Type").Equals(new HaystackXString("a", "Type")));
29 | Assert.IsFalse(new HaystackXString("a", "X").Equals(new HaystackXString("b", "X")));
30 | Assert.IsTrue(new HaystackXString("", "X").Equals(new HaystackXString("", "X")));
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/io/HZincReaderTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using ProjectHaystack;
3 | using ProjectHaystack.io;
4 |
5 | namespace ProjectHaystackTest.io
6 | {
7 | [TestClass]
8 | public class HZincReaderTests
9 | {
10 | [TestMethod]
11 | public void readGrid_withTagDef()
12 | {
13 | var reader = new ZincReader(
14 | @"ver:""3.0""
15 | id,def,doc,mod
16 | @p:struktonLibrary:r:25b81501-75003ad2 ""struktonActivePointOnly"",^struktonActivePointOnly,""Import only active points"",2020-01-20T07:36:33.162Z");
17 | var grid = reader.ReadValue();
18 | Assert.IsTrue(grid.Row(0).Get("def") is HaystackDefinition);
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/io/TrioReaderTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using ProjectHaystack;
4 | using ProjectHaystack.io;
5 |
6 | namespace ProjectHaystackTest.io
7 | {
8 | [TestClass]
9 | public class TrioReaderTests
10 | {
11 | [TestMethod]
12 | public void ReadEntities_TwoEntities_IsValid()
13 | {
14 | // Arrange.
15 | var trio = @"dis: ""Site 1""
16 | site
17 | area: 3702ft²
18 | geoAddr: ""100 Main St, Richmond, VA""
19 | geoCoord: C(37.5458,-77.4491)
20 | strTag: OK if unquoted if only safe chars
21 | summary:
22 | This is a string value which spans multiple
23 | lines with two or more space characters
24 | ---
25 | name: ""Site 2""
26 | site
27 | summary:
28 | Entities are separated by one or more dashes";
29 | var reader = new TrioReader(trio);
30 |
31 | // Act.
32 | var entities = reader.ReadEntities().ToArray();
33 |
34 | // Assert.
35 | Assert.AreEqual(2, entities.Length);
36 | Assert.AreEqual(new HaystackMarker(), entities[0]["site"]);
37 | Assert.AreEqual(new HaystackString("Entities are separated by one or more dashes"), entities[1]["summary"]);
38 | }
39 |
40 | [TestMethod]
41 | public void ReadEntities_NestedZincGrid_IsValid()
42 | {
43 | // Arrange.
44 | var trio = @"// Trio
45 | type:list
46 | val:[1,2,3]
47 | ---
48 | type:dict
49 | val:{ dis:""Dict!"" foo}
50 | ---
51 | type:grid
52 | val:Zinc:
53 | ver:""3.0""
54 | b,a
55 | 20,10";
56 | var reader = new TrioReader(trio);
57 |
58 | // Act.
59 | var entities = reader.ReadEntities().ToArray();
60 |
61 | // Assert.
62 | Assert.AreEqual(3, entities.Length);
63 | Assert.AreEqual(new HaystackString("list"), entities[0]["type"]);
64 | Assert.IsTrue(entities[1]["val"] is HaystackDictionary);
65 | Assert.IsTrue(entities[2]["val"] is HaystackGrid);
66 | Assert.AreEqual(10, (((HaystackGrid)entities[2]["val"]).Row(0).Get("a") as HaystackNumber).Value);
67 | }
68 |
69 | [TestMethod]
70 | public void ReadEntities_NestedTrioGrid_IsValid()
71 | {
72 | // Arrange.
73 | var trio = @"// Trio
74 | type:list
75 | val:[1,2,3]
76 | ---
77 | type:dict
78 | val:{ dis:""Dict!"" foo}
79 | ---
80 | type:list
81 | val: Trio:
82 | b: 20
83 | a: 10";
84 | var reader = new TrioReader(trio);
85 |
86 | // Act.
87 | var entities = reader.ReadEntities().ToArray();
88 |
89 | // Assert.
90 | Assert.AreEqual(3, entities.Length);
91 | Assert.AreEqual(new HaystackString("list"), entities[0]["type"]);
92 | Assert.IsTrue(entities[1]["val"] is HaystackDictionary);
93 | Assert.IsTrue(entities[2]["val"] is HaystackDictionary);
94 | Assert.AreEqual(10, ((HaystackNumber)((HaystackDictionary)entities[2]["val"])["a"]).Value);
95 | }
96 |
97 | [TestMethod]
98 | public void ToGrid_TwoEntities_IsValid()
99 | {
100 | // Arrange.
101 | var trio = @"dis: ""Site 1""
102 | site
103 | area: 3702ft²
104 | geoAddr: ""100 Main St, Richmond, VA""
105 | geoCoord: C(37.5458,-77.4491)
106 | strTag: OK if unquoted if only safe chars
107 | summary:
108 | This is a string value which spans multiple
109 | lines with two or more space characters
110 | ---
111 | name: ""Site 2""
112 | site
113 | summary:
114 | Entities are separated by one or more dashes";
115 | var reader = new TrioReader(trio);
116 |
117 | // Act.
118 | var grid = reader.ToGrid();
119 |
120 | // Assert.
121 | Assert.AreEqual(2, grid.Rows.Count());
122 | Assert.AreEqual(8, grid.Columns.Count());
123 | Assert.AreEqual(new HaystackMarker(), grid.Row(0).Get("site"));
124 | Assert.AreEqual(new HaystackString("Entities are separated by one or more dashes"), grid.Row(1).Get("summary"));
125 | }
126 | }
127 | }
--------------------------------------------------------------------------------
/ProjectHaystackTest/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build-system/unix-pr-validation.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | branches:
3 | include:
4 | - master
5 |
6 | name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
7 |
8 | stages:
9 | - stage: Build
10 | displayName: "Build and test libraries"
11 | jobs:
12 | - job: BuildTestPublish
13 | pool:
14 | vmImage: 'ubuntu-latest'
15 | workspace:
16 | clean: all
17 | steps:
18 | - checkout: self
19 | displayName: "Clean source checkout"
20 | clean: true
21 | - task: UseDotNet@2
22 | displayName: "Use .NET Core sdk"
23 | inputs:
24 | packageType: sdk
25 | installationPath: $(Agent.ToolsDirectory)/dotnet
26 | useGlobalJson: true
27 |
28 | - task: gittools.gittools.setup-gitversion-task.gitversion/setup@0
29 | displayName: "GitVersion: Setup"
30 | inputs:
31 | versionSpec: '5.x'
32 |
33 | - task: gittools.gittools.execute-gitversion-task.gitversion/execute@0
34 | displayName: "GitVersion: Determine version information"
35 | inputs:
36 | useConfigFile: true
37 | configFilePath: 'GitVersion.yml'
38 |
39 | - task: bleddynrichards.Assembly-Info-Task.Assembly-Info-NetCore.Assembly-Info-NetCore@2
40 | displayName: "Set Assembly Manifest Data"
41 | inputs:
42 | InsertAttributes: true
43 | Company: Strukton Worksphere
44 | Copyright: "Copyright © $(date:YYYY) Strukton Worksphere"
45 | VersionNumber: "$(GitVersion.AssemblySemVer)"
46 | FileVersionNumber: "$(GitVersion.AssemblySemFileVer)"
47 | InformationalVersion: "$(GitVersion.InformationalVersion)"
48 | PackageVersion: "$(GitVersion.NuGetVersion)"
49 |
50 | - task: DotNetCoreCLI@2
51 | displayName: "Restore dependencies for all projects"
52 | inputs:
53 | command: restore
54 | projects: "**/*.csproj"
55 | noCache: true
56 |
57 | - task: DotNetCoreCLI@2
58 | displayName: "Pack the package ProjectHaystack"
59 | continueOnError: false
60 | inputs:
61 | command: custom
62 | custom: pack
63 | arguments: "--configuration Release --no-restore --output $(Build.ArtifactStagingDirectory)/ProjectHaystack"
64 | projects: "**/ProjectHaystack.csproj"
65 |
66 | - task: DotNetCoreCLI@2
67 | displayName: "Run tests"
68 | continueOnError: false
69 | inputs:
70 | command: test
71 | arguments: "--configuration Release --no-restore --output $(Build.ArtifactStagingDirectory)/ProjectHaystack"
72 | projects: "**/ProjectHaystack.csproj"
73 |
74 | - task: PublishBuildArtifacts@1
75 | condition: ne(variables['Build.Reason'], 'PullRequest')
76 | displayName: "Publish Artifact: ProjectHaystack"
77 | continueOnError: false
78 | inputs:
79 | PathtoPublish: "$(Build.ArtifactStagingDirectory)/ProjectHaystack"
80 | ArtifactName: "ProjectHaystack"
81 |
82 | - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
83 | - stage: PushToFeed
84 | displayName: "Push to feed"
85 | condition: succeeded()
86 | jobs:
87 | - deployment: PublishToFeed
88 | displayName: "Publish libraries to feed"
89 | environment: "NuGetFeed"
90 | pool:
91 | vmImage: 'ubuntu-latest'
92 | workspace:
93 | clean: all
94 | strategy:
95 | runOnce:
96 | deploy:
97 | steps:
98 | - download: current
99 | - task: NuGetToolInstaller@0
100 | displayName: "Use latest NuGet"
101 | continueOnError: false
102 | - task: NuGetCommand@2
103 | displayName: "Release to feed"
104 | inputs:
105 | command: push
106 | packagesToPush: "$(Pipeline.Workspace)/ProjectHaystack/*.nupkg"
107 | NuGetFeedType: "external"
108 | publishFeedCredentials: "NuGet.org"
109 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.300",
4 | "rollForward": "latestPatch"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------