CreateStringArray() private method

private CreateStringArray ( NativeV8EngineProxy engine, char items, Int32 length ) : HandleProxy*
engine NativeV8EngineProxy
items char
length System.Int32
return HandleProxy*
Ejemplo n.º 1
0
        /// <summary>
        /// Calls the native V8 proxy library to create the value instance for use within the V8 JavaScript environment.
        /// <para>This overload provides a *quick way* to construct an array of strings.
        /// One big memory block is created to marshal the given strings at one time, which is many times faster than having to create an array of individual native strings.</para>
        /// </summary>
        public InternalHandle CreateValue(IEnumerable <string> items)
        {
            if (items == null)
            {
                return(V8NetProxy.CreateArray(_NativeV8EngineProxy, null, 0));
            }

            var itemsEnum  = items.GetEnumerator();
            int strBufSize = 0; // (size needed for the string chars portion of the memory block)
            int itemsCount = 0;

            while (itemsEnum.MoveNext())
            {
                // get length of all strings together
                strBufSize += itemsEnum.Current.Length + 1; // (+1 for null char)
                itemsCount++;
            }

            itemsEnum.Reset();

            int    strPtrBufSize     = Marshal.SizeOf(typeof(IntPtr)) * itemsCount; // start buffer size with size needed for all string pointers.
            char **oneBigStringBlock = (char **)Utilities.AllocNativeMemory(strPtrBufSize + Marshal.SystemDefaultCharSize * strBufSize);
            char **ptrWritePtr       = oneBigStringBlock;
            char * strWritePtr       = (char *)(((byte *)oneBigStringBlock) + strPtrBufSize);
            int    itemLength;

            while (itemsEnum.MoveNext())
            {
                itemLength = itemsEnum.Current.Length;
                Marshal.Copy(itemsEnum.Current.ToCharArray(), 0, (IntPtr)strWritePtr, itemLength);
                Marshal.WriteInt16((IntPtr)(strWritePtr + itemLength), 0);
                Marshal.WriteIntPtr((IntPtr)ptrWritePtr++, (IntPtr)strWritePtr);
                strWritePtr += itemLength + 1;
            }

            InternalHandle handle = V8NetProxy.CreateStringArray(_NativeV8EngineProxy, oneBigStringBlock, itemsCount);

            Utilities.FreeNativeMemory((IntPtr)oneBigStringBlock);

            return(handle);
        }