/// <summary> /// Parses a JSON Pointer from a string. /// </summary> /// <param name="source">The source string.</param> /// <param name="pointerKind">(optional) Restricts the kind of pointer. <see cref="JsonPointerKind.Unspecified"/> (default) allows both.</param> /// <returns>A JSON Pointer.</returns> /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception> /// <exception cref="PointerParseException"><paramref name="source"/> does not contain a valid pointer or contains a pointer of the wrong kind.</exception> public static JsonPointer Parse(string source, JsonPointerKind pointerKind = JsonPointerKind.Unspecified) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (source == string.Empty) { return(Empty); } if (source == "#") { return(UrlEmpty); } bool isUriEncoded; var parts = source.Split('/'); var i = 0; if (parts[0] == "#" || parts[0] == string.Empty) { isUriEncoded = parts[0] == "#"; i++; } else { throw new PointerParseException("Pointer must start with either `#` or `/` or be empty"); } switch (pointerKind) { case JsonPointerKind.Unspecified: break; case JsonPointerKind.Plain: if (isUriEncoded) { throw new PointerParseException("Pointer is URI-encoded, but plain was expected."); } break; case JsonPointerKind.UriEncoded: if (!isUriEncoded) { throw new PointerParseException("Pointer is plain, but URI-encoded was expected."); } break; default: throw new ArgumentOutOfRangeException(nameof(pointerKind), pointerKind, null); } var segments = new PointerSegment[parts.Length - i]; for (; i < parts.Length; i++) { segments[i - 1] = PointerSegment.Parse(parts[i], isUriEncoded); } return(new JsonPointer { _source = source, _segments = segments, Kind = isUriEncoded ? JsonPointerKind.UriEncoded : JsonPointerKind.Plain }); }
/// <summary> /// Parses a JSON Pointer from a string. /// </summary> /// <param name="source">The source string.</param> /// <param name="pointer">The resulting pointer.</param> /// <param name="pointerKind">(optional) Restricts the kind of pointer. <see cref="JsonPointerKind.Unspecified"/> (default) allows both.</param> /// <returns><code>true</code> if the parse was successful; <code>false</code> otherwise.</returns> /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception> public static bool TryParse(string source, out JsonPointer pointer, JsonPointerKind pointerKind = JsonPointerKind.Unspecified) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (source == string.Empty) { pointer = Empty; return(true); } if (source == "#") { pointer = UrlEmpty; return(true); } bool isUriEncoded; var parts = source.Split('/'); var i = 0; if (parts[0] == "#" || parts[0] == string.Empty) { isUriEncoded = parts[0] == "#"; i++; } else { pointer = default; return(false); } switch (pointerKind) { case JsonPointerKind.Unspecified: break; case JsonPointerKind.Plain: if (isUriEncoded) { pointer = default; return(false); } break; case JsonPointerKind.UriEncoded: if (!isUriEncoded) { pointer = default; return(false); } break; default: throw new ArgumentOutOfRangeException(nameof(pointerKind), pointerKind, null); } var segments = new PointerSegment[parts.Length - i]; for (; i < parts.Length; i++) { var part = parts[i]; if (!PointerSegment.TryParse(part, isUriEncoded, out var segment)) { pointer = default; return(false); } segments[i - 1] = segment; } pointer = new JsonPointer { _source = source, _segments = segments, Kind = isUriEncoded ? JsonPointerKind.UriEncoded : JsonPointerKind.Plain }; return(true); }