Esempio n. 1
0
        public KalkNativeBuffer LoadBytes(string path)
        {
            var fullPath = AssertReadFile(path);

            using var stream = Engine.FileService.FileOpen(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            var buffer = new KalkNativeBuffer((int)stream.Length);

            stream.Read(buffer.AsSpan());
            return(buffer);
        }
Esempio n. 2
0
        private static unsafe T BitCastTo <T>(KalkNativeBuffer buffer) where T : unmanaged
        {
            var sizeOfT   = Unsafe.SizeOf <T>();
            T   value     = default;
            var maxLength = Math.Min(buffer.Count, sizeOfT);

            for (int i = 0; i < maxLength; i++)
            {
                ((byte *)(&value))[i] = buffer[i];
            }
            return(value);
        }
Esempio n. 3
0
        public KalkNativeBuffer ByteBuffer(params object[] values)
        {
            if (values == null || values.Length == 0)
            {
                return(new KalkNativeBuffer(0));
            }

            // If we have a single value, try to extract a buffer from it.
            if (values.Length == 1)
            {
                var element = values[0];
                if (element is KalkNativeBuffer nativeBuffer)
                {
                    return(nativeBuffer);
                }

                if (element is string || element is IKalkSpannable)
                {
                    return(AsBytes(element));
                }

                if (element is IEnumerable it)
                {
                    var buffer = new List <byte>();
                    foreach (var item in it)
                    {
                        var b = Engine.ToObject <byte>(0, item);
                        buffer.Add(b);
                    }
                    var result = new KalkNativeBuffer(buffer.Count);
                    var span   = result.AsSpan();
                    for (int i = 0; i < buffer.Count; i++)
                    {
                        span[i] = buffer[i];
                    }

                    return(result);
                }
            }

            var byteBuffer = new KalkNativeBuffer(values.Length);

            for (int i = 0; i < values.Length; i++)
            {
                byteBuffer[i] = (byte)Engine.ToObject <long>(i, values[i]);
            }

            return(byteBuffer);
        }
Esempio n. 4
0
        public ScriptObject WebGet(string url)
        {
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }
            using (var httpClient = new HttpClient())
            {
                HttpResponseMessage result;
                try
                {
                    var task = Task.Run(async() => await httpClient.GetAsync(url));
                    task.Wait();
                    result = task.Result;

                    if (!result.IsSuccessStatusCode)
                    {
                        throw new ArgumentException($"HTTP/{result.Version} {(int)result.StatusCode} {result.ReasonPhrase}", nameof(url));
                    }
                    else
                    {
                        var headers = new ScriptObject();
                        foreach (var headerItem in result.Content.Headers)
                        {
                            var    items     = new ScriptArray(headerItem.Value);
                            object itemValue = items;
                            if (items.Count == 1)
                            {
                                var str = (string)items[0];
                                itemValue = str;
                                if (str == "true")
                                {
                                    itemValue = (KalkBool)true;
                                }
                                else if (str == "false")
                                {
                                    itemValue = (KalkBool)false;
                                }
                                else if (long.TryParse(str, out var longValue))
                                {
                                    if (longValue >= int.MinValue && longValue <= int.MaxValue)
                                    {
                                        itemValue = (int)longValue;
                                    }
                                    else
                                    {
                                        itemValue = longValue;
                                    }
                                }
                                else if (DateTime.TryParse(str, out var time))
                                {
                                    itemValue = time;
                                }
                            }
                            headers[headerItem.Key] = itemValue;
                        }

                        var mediaType = result.Content.Headers.ContentType.MediaType;
                        var resultObj = new ScriptObject()
                        {
                            { "version", result.Version.ToString() },
                            { "code", (int)result.StatusCode },
                            { "reason", result.ReasonPhrase },
                            { "headers", headers }
                        };

                        if (mediaType.StartsWith("text/") || mediaType == "application/json")
                        {
                            var readTask = Task.Run(async() => await result.Content.ReadAsStringAsync());
                            readTask.Wait();
                            var text = readTask.Result;
                            if (mediaType == "application/json" && TryParseJson(text, out var jsonObject))
                            {
                                resultObj["content"] = jsonObject;
                            }
                            else
                            {
                                resultObj["content"] = readTask.Result;
                            }
                        }
                        else
                        {
                            var readTask = Task.Run(async() => await result.Content.ReadAsByteArrayAsync());
                            readTask.Wait();
                            resultObj["content"] = new KalkNativeBuffer(readTask.Result);
                        }

                        return(resultObj);
                    }
                }
                catch (Exception ex)
                {
                    throw new ArgumentException(ex.Message, nameof(url));
                }
            }
        }
Esempio n. 5
0
        public object ReverseBits(object value)
        {
            if (value == null)
            {
                return(0);
            }

            switch (value)
            {
            case byte vbyte:
                return(ReverseBytes[vbyte]);

            case sbyte vsbyte:
                return(ReverseBytes[(byte)vsbyte]);

            case short vshort:
                return((short)((ReverseBytes[(byte)vshort] << 8) | ReverseBytes[(byte)(vshort >> 8)]));

            case ushort vushort:
                return((short)((ReverseBytes[(byte)vushort] << 8) | ReverseBytes[(byte)(vushort >> 8)]));

            case int vint:
                return((ReverseBytes[(byte)vint] << 24) |
                       (ReverseBytes[(byte)(vint >> 8)] << 16) |
                       (ReverseBytes[(byte)(vint >> 16)] << 8) |
                       ReverseBytes[(byte)(vint >> 24)]);

            case uint vuint:
                return((ReverseBytes[(byte)vuint] << 24) |
                       (ReverseBytes[(byte)(vuint >> 8)] << 16) |
                       (ReverseBytes[(byte)(vuint >> 16)] << 8) |
                       ReverseBytes[(byte)(vuint >> 24)]);

            case long vlong:
                return(((long)ReverseBytes[(byte)vlong] << 56) |
                       ((long)ReverseBytes[(byte)(vlong >> 8)] << 48) |
                       ((long)ReverseBytes[(byte)(vlong >> 16)] << 40) |
                       ((long)ReverseBytes[(byte)(vlong >> 24)] << 32) |
                       ((long)ReverseBytes[(byte)(vlong >> 32)] << 24) |
                       ((long)ReverseBytes[(byte)(vlong >> 40)] << 16) |
                       ((long)ReverseBytes[(byte)(vlong >> 48)] << 8) |
                       (long)ReverseBytes[(byte)(vlong >> 56)]);

            case ulong vulong:
                return(((ulong)ReverseBytes[(byte)vulong] << 56) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 8)] << 48) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 16)] << 40) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 24)] << 32) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 32)] << 24) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 40)] << 16) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 48)] << 8) |
                       (ulong)ReverseBytes[(byte)(vulong >> 56)]);

            case BigInteger bigInt:
            {
                var array = bigInt.ToByteArray();
                int mid   = array.Length / 2;
                for (int i = 0; i < mid; i++)
                {
                    var highIndex = array.Length - i - 1;
                    var high      = ReverseBytes[array[highIndex]];
                    var low       = ReverseBytes[array[i]];
                    array[i]         = high;
                    array[highIndex] = low;
                }

                if ((array.Length & 1) != 0)
                {
                    array[mid] = ReverseBytes[array[mid]];
                }
                return(new BigInteger(array));
            }

            case KalkVector vector:
                var outVector = vector.Clone();
                for (int i = 0; i < vector.Length; i++)
                {
                    var result = ReverseBits(vector.GetComponent(i));
                    outVector.SetComponent(i, result);
                }
                return(outVector);

            case KalkNativeBuffer nativeBuffer:
            {
                var buffer = new KalkNativeBuffer(nativeBuffer.Count);
                int mid    = nativeBuffer.Count / 2;
                for (int i = 0; i < mid; i++)
                {
                    var highIndex = nativeBuffer.Count - i - 1;
                    var high      = ReverseBytes[nativeBuffer[highIndex]];
                    var low       = ReverseBytes[nativeBuffer[i]];
                    buffer[i]         = high;
                    buffer[highIndex] = low;
                }

                if ((buffer.Count & 1) != 0)
                {
                    buffer[mid] = ReverseBytes[nativeBuffer[mid]];
                }

                return(buffer);
            }

            case KalkMatrix matrix:
                var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount);
                for (int y = 0; y < matrix.RowCount; y++)
                {
                    uintMatrix.SetRow(y, (KalkVector <int>)ReverseBits(matrix.GetRow(y)));
                }
                return(uintMatrix);

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value));
            }
        }
Esempio n. 6
0
        public KalkNativeBuffer AsBytes(object value)
        {
            if (value == null)
            {
                return(null);
            }

            switch (value)
            {
            case string str:
            {
                var buffer = Encoding.UTF8.GetBytes(str);
                return(KalkNativeBuffer.AsBytes(buffer.Length, in buffer[0]));
            }

            case byte vbyte:
                return(KalkNativeBuffer.AsBytes(1, vbyte));

            case sbyte vsbyte:
                return(KalkNativeBuffer.AsBytes(1, vsbyte));

            case short vshort:
                return(KalkNativeBuffer.AsBytes(2, vshort));

            case ushort vushort:
                return(KalkNativeBuffer.AsBytes(2, vushort));

            case int vint:
                return(KalkNativeBuffer.AsBytes(4, vint));

            case uint vuint:
                return(KalkNativeBuffer.AsBytes(4, vuint));

            case long vlong:
                return(KalkNativeBuffer.AsBytes(8, vlong));

            case ulong vulong:
                return(KalkNativeBuffer.AsBytes(8, vulong));

            case float vfloat:
            {
                var floatAsInt = BitConverter.SingleToInt32Bits(vfloat);
                return(KalkNativeBuffer.AsBytes(4, floatAsInt));
            }

            case double vdouble:
            {
                var doubleAsLong = BitConverter.DoubleToInt64Bits(vdouble);
                return(KalkNativeBuffer.AsBytes(8, doubleAsLong));
            }

            case BigInteger bigInt:
            {
                var array = bigInt.ToByteArray();
                return(KalkNativeBuffer.AsBytes(array.Length, in array[0]));
            }

            case IKalkSpannable spannable:
            {
                var span = spannable.AsSpan();
                return(KalkNativeBuffer.AsBytes(span.Length, in span[0]));
            }

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported ", nameof(value));
            }
        }
Esempio n. 7
0
        public static void BitCast <T>(ref T dest, int size, KalkNativeBuffer src)
        {
            var maxSize = Math.Min(size, src.Count);

            Unsafe.CopyBlockUnaligned(ref Unsafe.As <T, byte>(ref dest), ref src.AsSpan()[0], (uint)maxSize);
        }