/// <summary> /// 15.4.4.15 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance LastIndexOfImpl(JsObject target, JsInstance[] parameters) { if (parameters.Length == 0) { return(Global.NumberClass.New(-1)); } int len = target.Length; if (len == 0) { return(Global.NumberClass.New(-1)); } int n = len; if (parameters.Length > 1) { n = Convert.ToInt32(parameters[1].ToNumber()); } int k; JsInstance searchParameter = parameters[0]; if (n >= 0) { k = Math.Min(n, len - 1); } else { k = len - Math.Abs(n - 1); } while (k >= 0) { JsInstance result = null; if (target.TryGetProperty(k.ToString(), out result)) { if (result == searchParameter) { return(Global.NumberClass.New(k)); } } k--; } return(Global.NumberClass.New(-1)); }
public JsArray concat(IGlobal global, JsInstance[] args) { var newData = new SortedList <int, JsInstance>(m_data); int offset = length; foreach (var item in args) { if (item is JsArray) { foreach (var pair in ((JsArray)item).m_data) { newData.Add(pair.Key + offset, pair.Value); } offset += ((JsArray)item).Length; } else if (global.ArrayClass.HasInstance(item as JsObject)) { // Array subclass JsObject obj = (JsObject)item; for (int i = 0; i < obj.Length; i++) { JsInstance value; if (obj.TryGetProperty(i.ToString(), out value)) { newData.Add(offset + i, value); } } } else { newData.Add(offset, item); offset++; } } return(new JsArray(newData, offset, global.ArrayClass.PrototypeProperty)); }
private void PutDocument(string key, JsObject doc, JsObject meta) { if (doc == null) { throw new InvalidOperationException( string.Format("Created document cannot be null or empty. Document key: '{0}'", key)); } var newDocument = new JsonDocument { Key = key, DataAsJson = ToRavenJObject(doc) }; if (meta == null) { RavenJToken value; if (newDocument.DataAsJson.TryGetValue("@metadata", out value)) { newDocument.DataAsJson.Remove("@metadata"); newDocument.Metadata = (RavenJObject) value; } } else { foreach (var etagKeyName in EtagKeyNames) { JsInstance result; if (!meta.TryGetProperty(etagKeyName, out result)) continue; string etag = result.ToString(); meta.Delete(etagKeyName); if (string.IsNullOrEmpty(etag)) continue; Etag newDocumentEtag; if (Etag.TryParse(etag, out newDocumentEtag) == false) { throw new InvalidOperationException(string.Format("Invalid ETag value '{0}' for document '{1}'", etag, key)); } newDocument.Etag = newDocumentEtag; } newDocument.Metadata = ToRavenJObject(meta); } ValidateDocument(newDocument); if(key == null || key.EndsWith("/")) createdDocIdentity.Add(newDocument); else createdDocDict[key] = newDocument; }
/// <summary> /// 15.4.4.12 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance Splice(JsObject target, JsInstance[] parameters) { JsArray array = Global.ArrayClass.New(); int relativeStart = Convert.ToInt32(parameters[0].ToNumber()); int actualStart = relativeStart < 0 ? Math.Max(target.Length + relativeStart, 0) : Math.Min(relativeStart, target.Length); int actualDeleteCount = Math.Min(Math.Max(Convert.ToInt32(parameters[1].ToNumber()), 0), target.Length - actualStart); int len = target.Length; for (int k = 0; k < actualDeleteCount; k++) { string from = (relativeStart + k).ToString(); JsInstance result = null; if (target.TryGetProperty(from, out result)) { array.DefineOwnProperty(k.ToString(), new ValueDescriptor(target, k.ToString(), result)); } } List <JsInstance> items = new List <JsInstance>(); items.AddRange(parameters); items.RemoveAt(0); items.RemoveAt(0); if (items.Count < actualDeleteCount) { for (int k = actualStart; k < len - actualDeleteCount; k++) { JsInstance result = null; string from = (k + actualDeleteCount).ToString(); string to = (k + items.Count).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } for (int k = target.Length; k > len - actualDeleteCount + items.Count; k--) { target.Delete((k - 1).ToString()); } } else { for (int k = len - actualDeleteCount; k > actualStart; k--) { JsInstance result = null; string from = (k + actualDeleteCount - 1).ToString(); string to = (k + items.Count - 1).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } if (target.length != int.MinValue && target.Prototype != Prototype) { target.length += len - actualDeleteCount + items.Count; } for (int k = 0; items.Count > 0; k++) { JsInstance e = items[0]; items.RemoveAt(0); target[k.ToString()] = e; } } return(array); }
/// <summary> /// 15.4.4.15 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance IndexOfImpl(JsObject target, JsInstance[] parameters) { if (parameters.Length == 0) { return Global.NumberClass.New(-1); } int len = (int)target["length"].ToNumber(); if (len == 0) return Global.NumberClass.New(-1); int n = 0; if (parameters.Length > 1) n = Convert.ToInt32(parameters[1].ToNumber()); int k; if (n >= len) return Global.NumberClass.New(-1); JsInstance searchParameter = parameters[0]; if (n >= 0) k = n; else k = len - Math.Abs(n); while (k < len) { JsInstance result = null; if (target.TryGetProperty(k.ToString(), out result)) { if (JsInstance.StrictlyEquals(Global, result, searchParameter) == Global.BooleanClass.True) { return Global.NumberClass.New(k); } } k++; } return Global.NumberClass.New(-1); }
/// <summary> /// 15.4.4.15 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance LastIndexOfImpl(JsObject target, JsInstance[] parameters) { if (parameters.Length == 0) { return Global.NumberClass.New(-1); } int len = target.Length; if (len == 0) return Global.NumberClass.New(-1); int n = len; if (parameters.Length > 1) n = Convert.ToInt32(parameters[1].ToNumber()); int k; JsInstance searchParameter = parameters[0]; if (n >= 0) k = Math.Min(n, len - 1); else k = len - Math.Abs(n - 1); while (k >= 0) { JsInstance result = null; if (target.TryGetProperty(k.ToString(), out result)) { if (result == searchParameter) { return Global.NumberClass.New(k); } } k--; } return Global.NumberClass.New(-1); }
/// <summary> /// 15.4.4.13 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance UnShift(JsObject target, JsInstance[] parameters) { for (int k = target.Length; k > 0; k--) { JsInstance result = null; string from = (k - 1).ToString(); string to = (k + parameters.Length - 1).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } List<JsInstance> items = new List<JsInstance>(parameters); for (int j = 0; items.Count > 0; j++) { JsInstance e = items[0]; items.RemoveAt(0); target[j.ToString()] = e; } return Global.NumberClass.New(target.Length); }
/// <summary> /// 15.4.4.12 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance Splice(JsObject target, JsInstance[] parameters) { JsArray array = Global.ArrayClass.New(); int relativeStart = Convert.ToInt32(parameters[0].ToNumber()); int actualStart = relativeStart < 0 ? Math.Max(target.Length + relativeStart, 0) : Math.Min(relativeStart, target.Length); int actualDeleteCount = Math.Min(Math.Max(Convert.ToInt32(parameters[1].ToNumber()), 0), target.Length - actualStart); int len = target.Length; for (int k = 0; k < actualDeleteCount; k++) { string from = (relativeStart + k).ToString(); JsInstance result = null; if (target.TryGetProperty(from, out result)) { array.put(k, result); } } List<JsInstance> items = new List<JsInstance>(); items.AddRange(parameters); items.RemoveAt(0); items.RemoveAt(0); // use non-distructional copy, determine direction if (items.Count < actualDeleteCount) { for (int k = actualStart; k < len - actualDeleteCount; k++) { JsInstance result = null; string from = (k + actualDeleteCount).ToString(); string to = (k + items.Count).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } for (int k = target.Length; k > len - actualDeleteCount + items.Count; k--) { target.Delete((k - 1).ToString()); } target.Length = len - actualDeleteCount + items.Count; } else { for (int k = len - actualDeleteCount; k > actualStart; k--) { JsInstance result = null; string from = (k + actualDeleteCount - 1).ToString(); string to = (k + items.Count - 1).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } } for (int k = 0; k < items.Count; k++) target[k.ToString()] = items[k]; return array; }
/// <summary> /// 15.4.4.8 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance Reverse(JsObject target, JsInstance[] parameters) { int len = target.Length; int middle = len / 2; for (int lower = 0; lower != middle; lower++) { int upper = len - lower - 1; string upperP = upper.ToString(); string lowerP = lower.ToString(); JsInstance lowerValue = null; JsInstance upperValue = null; bool lowerExists = target.TryGetProperty(lowerP, out lowerValue); bool upperExists = target.TryGetProperty(upperP, out upperValue); if (lowerExists) { target[upperP] = lowerValue; } else { target.Delete(upperP); } if (upperExists) { target[lowerP] = upperValue; } else { target.Delete(lowerP); } } return target; }
/// <summary> /// 15.4.4.12 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance Splice(JsObject target, JsInstance[] parameters) { JsArray array = Global.ArrayClass.New(); int relativeStart = Convert.ToInt32(parameters[0].ToNumber()); int actualStart = relativeStart < 0 ? Math.Max(target.Length + relativeStart, 0) : Math.Min(relativeStart, target.Length); int actualDeleteCount = Math.Min(Math.Max(Convert.ToInt32(parameters[1].ToNumber()), 0), target.Length - actualStart); int len = target.Length; for (int k = 0; k < actualDeleteCount; k++) { string from = (relativeStart + k).ToString(); JsInstance result = null; if (target.TryGetProperty(from, out result)) { array.put(k, result); } } List <JsInstance> items = new List <JsInstance>(); items.AddRange(parameters); items.RemoveAt(0); items.RemoveAt(0); // use non-distructional copy, determine direction if (items.Count < actualDeleteCount) { for (int k = actualStart; k < len - actualDeleteCount; k++) { JsInstance result = null; string from = (k + actualDeleteCount).ToString(); string to = (k + items.Count).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } for (int k = target.Length; k > len - actualDeleteCount + items.Count; k--) { target.Delete((k - 1).ToString()); } target.Length = len - actualDeleteCount + items.Count; } else { for (int k = len - actualDeleteCount; k > actualStart; k--) { JsInstance result = null; string from = (k + actualDeleteCount - 1).ToString(); string to = (k + items.Count - 1).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } } for (int k = 0; k < items.Count; k++) { target[k.ToString()] = items[k]; } return(array); }
/// <summary> /// 8.10.5 /// </summary> /// <param name="global"></param> /// <param name="obj"></param> /// <returns></returns> internal static Descriptor ToPropertyDesciptor(IGlobal global, JsDictionaryObject owner, string name, JsInstance jsInstance) { if (jsInstance.Class != JsInstance.CLASS_OBJECT) { throw new JsException(global.TypeErrorClass.New("The target object has to be an instance of an object")); } JsObject obj = (JsObject)jsInstance; if ((obj.HasProperty("value") || obj.HasProperty("writable")) && (obj.HasProperty("set") || obj.HasProperty("get"))) { throw new JsException(global.TypeErrorClass.New("The property cannot be both writable and have get/set accessors or cannot have both a value and an accessor defined")); } Descriptor desc; JsInstance result = null; if (obj.HasProperty("value")) { desc = new ValueDescriptor(owner, name, obj["value"]); } else { desc = new PropertyDescriptor(global, owner, name); } if (obj.TryGetProperty("enumerable", out result)) { desc.Enumerable = result.ToBoolean(); } if (obj.TryGetProperty("configurable", out result)) { desc.Configurable = result.ToBoolean(); } if (obj.TryGetProperty("writable", out result)) { desc.Writable = result.ToBoolean(); } if (obj.TryGetProperty("get", out result)) { if (!(result is JsFunction)) { throw new JsException(global.TypeErrorClass.New("The getter has to be a function")); } ((PropertyDescriptor)desc).GetFunction = (JsFunction)result; } if (obj.TryGetProperty("set", out result)) { if (!(result is JsFunction)) { throw new JsException(global.TypeErrorClass.New("The setter has to be a function")); } ((PropertyDescriptor)desc).SetFunction = (JsFunction)result; } return(desc); }
/// <summary> /// 15.4.4.12 /// </summary> /// <param name="target"></param> /// <param name="parameters"></param> /// <returns></returns> public JsInstance Splice(JsObject target, JsInstance[] parameters) { JsArray array = Global.ArrayClass.New(); int relativeStart = Convert.ToInt32(parameters[0].ToNumber()); int actualStart = relativeStart < 0 ? Math.Max(target.Length + relativeStart, 0) : Math.Min(relativeStart, target.Length); int actualDeleteCount = Math.Min(Math.Max(Convert.ToInt32(parameters[1].ToNumber()), 0), target.Length - actualStart); int len = target.Length; for (int k = 0; k < actualDeleteCount; k++) { string from = (relativeStart + k).ToString(); JsInstance result = null; if (target.TryGetProperty(from, out result)) { array.DefineOwnProperty(k.ToString(), new ValueDescriptor(target, k.ToString(), result)); } } List<JsInstance> items = new List<JsInstance>(); items.AddRange(parameters); items.RemoveAt(0); items.RemoveAt(0); if (items.Count < actualDeleteCount) { for (int k = actualStart; k < len - actualDeleteCount; k++) { JsInstance result = null; string from = (k + actualDeleteCount).ToString(); string to = (k + items.Count).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } for (int k = target.Length; k > len - actualDeleteCount + items.Count; k--) { target.Delete((k - 1).ToString()); } } else { for (int k = len - actualDeleteCount; k > actualStart; k--) { JsInstance result = null; string from = (k + actualDeleteCount - 1).ToString(); string to = (k + items.Count - 1).ToString(); if (target.TryGetProperty(from, out result)) { target[to] = result; } else { target.Delete(to); } } if (target.length != int.MinValue && target.Prototype != Prototype) target.length += len - actualDeleteCount + items.Count; for (int k = 0; items.Count > 0; k++) { JsInstance e = items[0]; items.RemoveAt(0); target[k.ToString()] = e; } } return array; }
public JsInstance Splice(JsObject target, JsInstance[] parameters) { JsArray jsArray = this.Global.ArrayClass.New(); int int32 = Convert.ToInt32(parameters[0].ToNumber()); int num1 = int32 < 0 ? Math.Max(target.Length + int32, 0) : Math.Min(int32, target.Length); int num2 = Math.Min(Math.Max(Convert.ToInt32(parameters[1].ToNumber()), 0), target.Length - num1); int length1 = target.Length; int num3; for (int i = 0; i < num2; ++i) { num3 = int32 + i; string index = num3.ToString(); JsInstance result = (JsInstance)null; if (target.TryGetProperty(index, out result)) { jsArray.put(i, result); } } List <JsInstance> jsInstanceList = new List <JsInstance>(); jsInstanceList.AddRange((IEnumerable <JsInstance>)parameters); jsInstanceList.RemoveAt(0); jsInstanceList.RemoveAt(0); if (jsInstanceList.Count < num2) { for (int index1 = num1; index1 < length1 - num2; ++index1) { JsInstance result = (JsInstance)null; num3 = index1 + num2; string index2 = num3.ToString(); num3 = index1 + jsInstanceList.Count; string index3 = num3.ToString(); if (target.TryGetProperty(index2, out result)) { target[index3] = result; } else { target.Delete(index3); } } for (int length2 = target.Length; length2 > length1 - num2 + jsInstanceList.Count; --length2) { JsObject jsObject = target; num3 = length2 - 1; string index = num3.ToString(); jsObject.Delete(index); } target.Length = length1 - num2 + jsInstanceList.Count; } else { for (int index1 = length1 - num2; index1 > num1; --index1) { JsInstance result = (JsInstance)null; num3 = index1 + num2 - 1; string index2 = num3.ToString(); num3 = index1 + jsInstanceList.Count - 1; string index3 = num3.ToString(); if (target.TryGetProperty(index2, out result)) { target[index3] = result; } else { target.Delete(index3); } } } for (int index = 0; index < jsInstanceList.Count; ++index) { target[index.ToString()] = jsInstanceList[index]; } return((JsInstance)jsArray); }