/// <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));
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
	    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;
        }
Beispiel #10
0
        /// <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);
        }
Beispiel #11
0
        /// <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;
        }
Beispiel #13
0
        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);
        }