private static CBORObject RemoveOperation( CBORObject o, string valueOpStr, string path) { if (path == null) { throw new ArgumentException("Patch " + valueOpStr); } if (path.Length == 0) { return(o); } else { JSONPointer pointer = JSONPointer.FromPointer(o, path); if (!pointer.Exists()) { throw new KeyNotFoundException("Patch " + valueOpStr + " " + path); } o = pointer.GetValue(); if (pointer.GetParent().Type == CBORType.Array) { ((CBORObject)pointer.GetParent()).RemoveAt(pointer.GetIndex()); } else if (pointer.GetParent().Type == CBORType.Map) { ((CBORObject)pointer.GetParent()).Remove( CBORObject.FromObject(pointer.GetKey())); } return(o); } }
/// <summary>Gets the JSON object referred to by a JSON Pointer /// according to RFC6901. The syntax for pointers is: /// <pre>'/' KEY '/' KEY [...]</pre> where KEY represents a key into /// the JSON object or its sub-objects in the hierarchy. For example, /// <pre>/foo/2/bar</pre> means the same as /// <pre>obj['foo'][2]['bar']</pre> in JavaScript. If "~" and/or "/" /// occurs in a key, it must be escaped with "~0" or "~1", /// respectively, in a JSON pointer.</summary> /// <param name='obj'>A CBOR object.</param> /// <param name='pointer'>A JSON pointer according to RFC 6901.</param> /// <returns>An object within the specified JSON object, or <paramref /// name='obj'/> if pointer is the empty string, if the pointer is /// null, if the pointer is invalid , if there is no JSON object at the /// given pointer, or if <paramref name='obj'/> is not of type /// CBORObject, unless pointer is the empty string.</returns> /// <exception cref='ArgumentNullException'>The parameter <paramref /// name='pointer'/> is null.</exception> public static Object GetObject(CBORObject obj, string pointer) { if (pointer == null) { throw new ArgumentNullException(nameof(pointer)); } return((pointer.Length == 0) ? obj : JSONPointer.FromPointer(obj, pointer).GetValue()); }
private static CBORObject ReplaceOperation( CBORObject o, string valueOpStr, string path, CBORObject value) { if (path == null) { throw new ArgumentException("Patch " + valueOpStr); } if (path.Length == 0) { o = value; } else { JSONPointer pointer = JSONPointer.FromPointer(o, path); if (!pointer.Exists()) { throw new KeyNotFoundException("Patch " + valueOpStr + " " + path); } if (pointer.GetParent().Type == CBORType.Array) { int index = pointer.GetIndex(); if (index < 0) { throw new ArgumentException("Patch " + valueOpStr + " path"); } ((CBORObject)pointer.GetParent()).Set(index, value); } else if (pointer.GetParent().Type == CBORType.Map) { string key = pointer.GetKey(); ((CBORObject)pointer.GetParent()).Set(key, value); } else { throw new ArgumentException("Patch " + valueOpStr + " path"); } } return(o); }
public static CBORObject Patch(CBORObject o, CBORObject ptch) { // clone the object in case of failure if (o == null) { throw new ArgumentNullException(nameof(o)); } o = CloneCbor(o); if (ptch == null) { throw new ArgumentNullException(nameof(ptch)); } for (int i = 0; i < ptch.Count; ++i) { CBORObject patchOp = ptch[i]; // NOTE: This algorithm requires "op" to exist // only once; the CBORObject, however, does not // allow duplicates string valueOpStr = GetString(patchOp, "op"); if (valueOpStr == null) { throw new ArgumentException("Patch"); } if ("add".Equals(valueOpStr, StringComparison.Ordinal)) { // operation CBORObject value = null; if (!patchOp.ContainsKey("value")) { throw new ArgumentException("Patch " + valueOpStr + " value"); } value = patchOp["value"]; o = AddOperation(o, valueOpStr, GetString(patchOp, "path"), value); } else if ("replace".Equals(valueOpStr, StringComparison.Ordinal)) { // operation CBORObject value = null; if (!patchOp.ContainsKey("value")) { throw new ArgumentException("Patch " + valueOpStr + " value"); } value = patchOp["value"]; o = ReplaceOperation( o, valueOpStr, GetString(patchOp, "path"), value); } else if ("remove".Equals(valueOpStr, StringComparison.Ordinal)) { // Remove operation string path = patchOp["path"].AsString(); if (path == null) { throw new ArgumentException("Patch " + valueOpStr + " path"); } if (path.Length == 0) { o = null; } else { RemoveOperation(o, valueOpStr, GetString(patchOp, "path")); } } else if ("move".Equals(valueOpStr, StringComparison.Ordinal)) { string path = patchOp["path"].AsString(); if (path == null) { throw new ArgumentException("Patch " + valueOpStr + " path"); } string fromPath = patchOp["from"].AsString(); if (fromPath == null) { throw new ArgumentException("Patch " + valueOpStr + " from"); } if (path.StartsWith(fromPath, StringComparison.Ordinal)) { throw new ArgumentException("Patch " + valueOpStr); } CBORObject movedObj = RemoveOperation(o, valueOpStr, fromPath); o = AddOperation(o, valueOpStr, path, CloneCbor(movedObj)); } else if ("copy".Equals(valueOpStr, StringComparison.Ordinal)) { string path = patchOp["path"].AsString(); string fromPath = patchOp["from"].AsString(); if (path == null) { throw new ArgumentException("Patch " + valueOpStr + " path"); } if (fromPath == null) { throw new ArgumentException("Patch " + valueOpStr + " from"); } JSONPointer pointer = JSONPointer.FromPointer(o, path); if (!pointer.Exists()) { throw new KeyNotFoundException("Patch " + valueOpStr + " " + fromPath); } CBORObject copiedObj = pointer.GetValue(); o = AddOperation( o, valueOpStr, path, CloneCbor(copiedObj)); } else if ("test".Equals(valueOpStr, StringComparison.Ordinal)) { string path = patchOp["path"].AsString(); if (path == null) { throw new ArgumentException("Patch " + valueOpStr + " path"); } CBORObject value = null; if (!patchOp.ContainsKey("value")) { throw new ArgumentException("Patch " + valueOpStr + " value"); } value = patchOp["value"]; JSONPointer pointer = JSONPointer.FromPointer(o, path); if (!pointer.Exists()) { throw new ArgumentException("Patch " + valueOpStr + " " + path); } Object testedObj = pointer.GetValue(); if ((testedObj == null) ? (value != null) : !testedObj.Equals(value)) { throw new InvalidOperationException("Patch " + valueOpStr); } } } return((o == null) ? CBORObject.Null : o); }