/// <summary> /// parses unix timestamp <paramref name="metadataJToken"/>. /// </summary> /// <seealso cref="JsonUtils.GetPropertyValue{T}(JToken, string)"/> /// <param name="metadataJToken"></param> /// <returns> /// unix timestamp parsed from <paramref name="metadataJToken"/> /// </returns> /// <exception cref="ArgumentNullException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// </exception> /// <exception cref="JsonPropertyParseException> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// <seealso cref="JsonUtils.GetPropertyValue{T}(JToken, string)"/> /// </exception> private static long parseUnixTimestamp(JToken metadataJToken) { JsonUtils.AssertExist(metadataJToken, "timestamp"); long unixTimestamp = JsonUtils.GetPropertyValue <int>(metadataJToken, "timestamp"); return(unixTimestamp); }
/// <summary> /// parses <see cref="CoinTicker"/> having <paramref name="unixTimestamp"/> from /// <paramref name="coinTickerDataJToken"/>. /// </summary> /// <param name="coinTickerDataJToken"></param> /// <param name="unixTimestamp"></param> /// <returns> /// <see cref="CoinTicker"/> parsed from <paramref name="coinTickerDataJToken"/>, /// having <paramref name="unixTimestamp"/> /// </returns> /// <exception cref="ArgumentNullException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// <seealso cref="JsonUtils.GetPropertyValue{T}(JToken, string)"/> /// </exception> /// <exception cref="JsonPropertyParseException"> /// <seealso cref="JsonUtils.GetPropertyValue{T}(JToken, string)"/> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// </exception> /// <exception cref="JsonReaderException"> /// <seealso cref="JToken.Value{T}(object)"/> /// </exception> /// <exception cref="InvalidCastException"> /// <seealso cref="JToken.Value{T}(object)"/> /// </exception> /// <exception cref="InvalidOperationException"> /// <seealso cref="JToken.Value{T}(object)"/> /// </exception> private static CoinTicker parse(JToken coinTickerDataJToken, long unixTimestamp) { // fetch coin ticker fields // handle "data" fields JsonUtils.AssertExist( coinTickerDataJToken, "id", "name", "symbol", "rank", "circulating_supply", "total_supply", "max_supply"); int id = JsonUtils.GetPropertyValue <int>(coinTickerDataJToken, "id"); string name = JsonUtils.GetPropertyValue <string>(coinTickerDataJToken, "name"); string symbol = JsonUtils.GetPropertyValue <string>(coinTickerDataJToken, "symbol"); int rank = JsonUtils.GetPropertyValue <int>(coinTickerDataJToken, "rank"); double?circulatingSupply = JsonUtils.GetPropertyValue <double?>(coinTickerDataJToken, "circulating_supply"); double?totalSupply = JsonUtils.GetPropertyValue <double?>(coinTickerDataJToken, "total_supply"); double?maxSupply = JsonUtils.GetPropertyValue <double?>(coinTickerDataJToken, "max_supply"); // handle "data.quotes" fields JsonUtils.AssertExist(coinTickerDataJToken, "quotes"); JToken CoinTickerDataQuotesJToken = coinTickerDataJToken["quotes"]; JsonUtils.AssertExist(CoinTickerDataQuotesJToken, "USD"); JToken CoinTickerDataQuotesUsdJToken = CoinTickerDataQuotesJToken["USD"]; // handle data.quotes.USD fields JsonUtils.AssertExist(CoinTickerDataQuotesUsdJToken, "price", "volume_24h", "market_cap", "percent_change_24h"); double priceUsd = JsonUtils.GetPropertyValue <double>(CoinTickerDataQuotesUsdJToken, "price"); double?volume24hUsd = JsonUtils.GetPropertyValue <double?>(CoinTickerDataQuotesUsdJToken, "volume_24h"); double?marketCapUsd = JsonUtils.GetPropertyValue <double?>(CoinTickerDataQuotesUsdJToken, "market_cap"); double percentChange24hUsd = JsonUtils.GetPropertyValue <double>( CoinTickerDataQuotesUsdJToken, "percent_change_24h"); // init a new coin ticker CoinTicker CoinTicker = new CoinTicker( id, name, symbol, rank, circulatingSupply, totalSupply, maxSupply, priceUsd, volume24hUsd, marketCapUsd, percentChange24hUsd, unixTimestamp); return(CoinTicker); }
/// <summary> /// parses a <see cref="CoinListing"/> array from <paramref name="ListingJsonString"/>. /// </summary> /// <seealso cref="JsonConvert.DeserializeObject(string)"/> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// <seealso cref="JToken.Value{T}(object)"/> /// <param name="ListingJSONString"></param> /// <returns> /// <see cref="CoinListing"/> array parsed from <paramref name="ListingJsonString"/> /// </returns> /// <exception cref="CoinListingJsonParseException"> /// thrown if <paramref name="ListingJsonString"/> is invalid. /// </exception> internal static CoinListing[] ParseCoinListingArray(string ListingJsonString) { try { CoinListing[] coinListingArray; // deserialize json string to get a JToken JToken coinListingJToken = (JToken)JsonConvert.DeserializeObject(ListingJsonString); // handle matadata JsonUtils.AssertExist(coinListingJToken, "metadata", "data"); JToken coinListingMetadataJToken = coinListingJToken["metadata"]; // get length of coin listing array JsonUtils.AssertExist(coinListingMetadataJToken, "num_cryptocurrencies"); int coinListingArrayLength = JsonUtils.GetPropertyValue <int>( coinListingMetadataJToken, "num_cryptocurrencies"); if (coinListingArrayLength <= 0) // invalid coin listing array length { throw new JsonPropertyParseException("data.num_cryptocurrencies"); } // init coin listing array coinListingArray = new CoinListing[coinListingArrayLength]; // get coin listing array JToken JToken CoinListingsArrayJToken = coinListingJToken["data"]; // fill coin listing array with data from JToken fillCoinListingArray(coinListingArray, CoinListingsArrayJToken); return(coinListingArray); } catch (Exception exception) { if ( exception is JsonReaderException || exception is JsonPropertyParseException || exception is InvalidCastException) { throw new CoinListingJsonParseException(exception); } else // unhandled exception { throw exception; } } }
/// <summary> /// parses array of <see cref="CoinTicker"/>s from <paramref name="tickerArrayJSONString"/>, /// starting at <paramref name="startingCoinIndex"/>, /// and having a maximum length of <paramref name="CoinTickerArrayMaxSize"/>. /// </summary> /// <param name="tickerArrayJSONString"></param> /// <param name="startingCoinIndex"> /// index of first coin in <paramref name="tickerArrayJSONString"/> /// </param> /// <param name="CoinTickerArrayMaxSize"> /// maximum length of parsed array /// </param> /// <returns> /// array of <see cref="CoinTicker"/>s parsed from <paramref name="tickerArrayJSONString"/>, /// starting at <paramref name="startingCoinIndex"/>, /// and having a maximum length of <paramref name="CoinTickerArrayMaxSize"/> /// </returns> /// <exception cref="CoinTickerJsonParseException"> /// thrown if <paramref name="tickerArrayJSONString"/> was invalid. /// </exception> /// <exception cref="CoinIndexNotFoundException"> /// thrown if specified <paramref name="startingCoinIndex"/> does not exist in server. /// </exception> public static CoinTicker[] ParseArray( string tickerArrayJSONString, int startingCoinIndex, int coinTickerArrayMaxLength) { try { List <CoinTicker> coinTickerList = new List <CoinTicker>(); JToken coinTickerArrayJToken = (JToken)JsonConvert.DeserializeObject(tickerArrayJSONString); // handle metadata fields JsonUtils.AssertExist(coinTickerArrayJToken, "metadata"); JToken coinTickerArrayMetadataJToken = coinTickerArrayJToken["metadata"]; long unixTimestamp = parseUnixTimestamp(coinTickerArrayMetadataJToken); // assert that (valid) server response did not specify an error. assertNoErrorSpecifiedInResponse(coinTickerArrayMetadataJToken, startingCoinIndex); // fetch ticker array JToken, located in data field JsonUtils.AssertExist(coinTickerArrayJToken, "data"); JArray coinTickerJArray = (JArray)coinTickerArrayJToken["data"]; // fill coinTickerList with data from ticker JArray fillCoinTickerList( coinTickerList, coinTickerJArray, unixTimestamp); int coinTickerArrayLength = Math.Min(coinTickerArrayMaxLength, coinTickerList.Count); return(coinTickerList.GetRange(0, coinTickerArrayLength).ToArray()); } catch (Exception exception) { if ( exception is JsonReaderException || exception is JsonPropertyParseException || exception is InvalidCastException) { throw new CoinTickerJsonParseException("Invalid JSON string.", exception); } else // unhandled exception { throw exception; } } }
/// <summary> /// fills <paramref name="CoinTickerList"/> with <see cref="CoinTicker"/>s parsed from /// <paramref name="coinTickerJArray"/>, each having <paramref name="unixTimestamp"/>. /// </summary> /// <seealso cref="parse(JToken, long)"/> /// <param name="CoinTickerList"></param> /// <param name="coinTickerJArray"></param> /// <param name="unixTimestamp"></param> /// <exception cref="ArgumentNullException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// </exception> /// <exception cref="ArgumentNullException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// </exception> /// <exception cref="JsonPropertyParseException"> /// <seealso cref="parse(JToken, long)"/> /// </exception> /// <exception cref="JsonReaderException"> /// <seealso cref="JToken.Value{T}(object)"/> /// <seealso cref="parse(JToken, long)"/> /// </exception> /// <exception cref="InvalidCastException"> /// <seealso cref="parse(JToken, long)"/> /// <seealso cref="JToken.Value{T}(object)"/> /// </exception> /// <exception cref="InvalidOperationException"> /// <seealso cref="parse(JToken, long)"/> /// <seealso cref="JToken.Value{T}(object)"/> /// </exception> private static void fillCoinTickerList( List <CoinTicker> CoinTickerList, JArray coinTickerJArray, long unixTimestamp) { for (int i = 0; i < coinTickerJArray.Count; i++) { // get JToken of the i'th item in coin tickre array JsonUtils.AssertExist(coinTickerJArray, i); JToken currentCoinTickerJToken = coinTickerJArray[i]; // parse i'th coin ticker from corresponding JToken CoinTicker currentCoinTicker = parse(currentCoinTickerJToken, unixTimestamp); // add coin ticker to list CoinTickerList.Add(currentCoinTicker); } }
/// <summary> /// asserts that server has not specified in <paramref name="metadataJToken"/> that an error occurred /// while processing request. /// </summary> /// <param name="metadataJToken"></param> /// <param name="coinIndex"> /// index of first (or only) <see cref="CoinTicker"/> requested from server. /// </param> /// <exception cref="ArgumentNullException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// </exception> /// <exception cref="JsonPropertyParseException"> /// <seealso cref="JsonUtils.AssertExist(JToken, object[])"/> /// <seealso cref="JsonUtils.GetPropertyValue{T}(JToken, string)"/> /// </exception> /// <exception cref="CoinIndexNotFoundException"> /// thrown if server specified that <paramref name="startingCoinIndex"/> does not exist in server /// </exception> /// <exception cref="CoinTickerJsonParseException"> /// thrown if server specified an unhandled error /// </exception> private static void assertNoErrorSpecifiedInResponse(JToken metadataJToken, int startingCoinIndex) { // assert that error field exists in meta data JsonUtils.AssertExist(metadataJToken, "error"); // error field value is not null - server reported an error in its response if (!JsonUtils.IsPropertyNull(metadataJToken, "error")) { // get error field value string errorFieldValue = JsonUtils.GetPropertyValue <string>(metadataJToken, "error"); // coin id does not exist in server if (errorFieldValue == RESPONSE_COIN_INDEX_NOT_FOUND_ERROR_FIELD_VALUE) { throw new CoinIndexNotFoundException(startingCoinIndex); } else // unhandled error { throw new CoinTickerJsonParseException(errorFieldValue); } } }
/// <summary> /// parses a single <see cref="CoinTicker"/> with <paramref name="coinId"/> /// from <paramref name="tickerJSONString"/>. /// </summary> /// <param name="tickerJSONString"></param> /// <param name="coinId"></param> /// <returns> /// <see cref="CoinTicker"/> having <paramref name="coinId"/> /// parsed from <paramref name="tickerJSONString"/> /// </returns> /// <exception cref="CoinIndexNotFoundException"> /// <seealso cref="assertNoErrorSpecifiedInResponse(JToken, int)"/> /// </exception> /// <exception cref="CoinTickerJsonParseException"> /// thrown if <paramref name="tickerJSONString"/> is invalid /// </exception> public static CoinTicker Parse(string tickerJSONString, int coinId) { try { JToken coinTickerJToken = (JToken)JsonConvert.DeserializeObject(tickerJSONString); // handle metadata fields JsonUtils.AssertExist(coinTickerJToken, "metadata"); JToken coinTickerMetadataJToken = coinTickerJToken["metadata"]; long unixTimestamp = parseUnixTimestamp(coinTickerMetadataJToken); assertNoErrorSpecifiedInResponse(coinTickerMetadataJToken, coinId); // handle data fields JsonUtils.AssertExist(coinTickerJToken, "data"); JToken coinTickerDataJToken = coinTickerJToken["data"]; // parse coin ticker using coinTickerDataJToken CoinTicker CoinTicker = parse(coinTickerDataJToken, unixTimestamp); return(CoinTicker); } catch (Exception exception) { if ( exception is JsonReaderException || exception is JsonPropertyParseException || exception is InvalidCastException || exception is InvalidOperationException) { throw new CoinTickerJsonParseException("Invalid JSON string.", exception); } else { throw exception; } } }