public unsafe LazyStringValue GetLazyString(char[] chars, int start, int count)
        {
            LazyStringValue value;

            var state = new JsonParserState();

            state.FindEscapePositionsIn(chars, start, count);
            var maxByteCount = Encoding.GetMaxByteCount(count);
            var memory       = GetMemory(maxByteCount + state.GetEscapePositionsSize());

            try
            {
                fixed(char *pChars = chars)
                {
                    var address    = (byte *)memory.Address;
                    var actualSize = Encoding.GetBytes(pChars + start, count, address, memory.SizeInBytes);

                    state.WriteEscapePositionsTo(address + actualSize);
                    value = new LazyStringValue(null, address, actualSize, this);
                }
            }
            catch (Exception)
            {
                ReturnMemory(memory);
                throw;
            }
            return(value);
        }
        public unsafe LazyStringValue GetLazyString(string field)
        {
            var state = new JsonParserState();

            state.FindEscapePositionsIn(field);
            var maxByteCount = Encoding.GetMaxByteCount(field.Length);
            var memory       = GetMemory(maxByteCount + state.GetEscapePositionsSize());

            try
            {
                fixed(char *pField = field)
                {
                    var address    = (byte *)memory.Address;
                    var actualSize = Encoding.GetBytes(pField, field.Length, address, memory.SizeInBytes);

                    state.WriteEscapePositionsTo(address + actualSize);
                    return(new LazyStringValue(field, address, actualSize, this)
                    {
                        AllocatedMemoryData = memory
                    });
                }
            }
            catch (Exception)
            {
                ReturnMemory(memory);
                throw;
            }
        }
예제 #3
0
        private unsafe LazyStringValue GetLazyString(StringSegment field, bool longLived)
        {
            var state = new JsonParserState();

            state.FindEscapePositionsIn(field);
            var maxByteCount = Encoding.GetMaxByteCount(field.Length);
            var memory       = GetMemory(maxByteCount + state.GetEscapePositionsSize(), longLived: longLived);

            fixed(char *pField = field.String)
            {
                var address    = memory.Address;
                var actualSize = Encoding.GetBytes(pField + field.Start, field.Length, address, memory.SizeInBytes);

                state.WriteEscapePositionsTo(address + actualSize);
                var result = new LazyStringValue(field, address, actualSize, this)
                {
                    AllocatedMemoryData = memory,
                };

                if (state.EscapePositions.Count > 0)
                {
                    result.EscapePositions = state.EscapePositions.ToArray();
                }
                return(result);
            }
        }
예제 #4
0
        public unsafe int WriteValue(string str, out BlittableJsonToken token, UsageMode mode = UsageMode.None)
        {
            if (_intBuffer == null)
            {
                _intBuffer = new List <int>();
            }
            int size = Encoding.UTF8.GetMaxByteCount(str.Length);

            FillBufferWithEscapePositions(str, _intBuffer);
            size += JsonParserState.GetEscapePositionsSize(_intBuffer);
            var buffer = _context.GetNativeTempBuffer(size);

            fixed(char *pChars = str)
            {
                var stringSize = Utf8Encoding.GetBytes(pChars, str.Length, buffer, size);

                return(WriteValue(buffer, stringSize, _intBuffer, out token, mode, null));
            }
        }
예제 #5
0
        public static void GetLowerKeySliceAndStorageKey(JsonOperationContext context, string str, out byte *lowerKey,
                                                         out int lowerSize,
                                                         out byte *key,
                                                         out int keySize)
        {
            // Because we need to also store escape positions for the key when we store it
            // we need to store it as a lazy string value.
            // But lazy string value has two lengths, one is the string length, and the other
            // is the actual data size with the escape positions

            // In order to resolve this, we process the key to find escape positions, then store it
            // in the table using the following format:
            //
            // [var int - string len, string bytes, number of escape positions, escape positions]
            //
            // The total length of the string is stored in the actual table (and include the var int size
            // prefix.

            if (_jsonParserState == null)
            {
                _jsonParserState = new JsonParserState();
            }

            _jsonParserState.Reset();

            keySize = JsonParserState.VariableSizeIntSize(str.Length);
            _jsonParserState.FindEscapePositionsIn(str);
            var escapePositionsSize = _jsonParserState.GetEscapePositionsSize();
            var buffer = context.GetNativeTempBuffer(
                str.Length   // lower key
                + keySize    // the size of var int for the len of the key
                + str.Length // actual key
                + escapePositionsSize);

            for (var i = 0; i < str.Length; i++)
            {
                var ch = str[i];
                if (ch > 127) // not ASCII, use slower mode
                {
                    goto UnlikelyUnicode;
                }
                if ((ch >= 65) && (ch <= 90))
                {
                    buffer[i] = (byte)(ch | 0x20);
                }
                else
                {
                    buffer[i] = (byte)ch;
                }

                buffer[i + keySize + str.Length] = (byte)ch;
            }

            var writePos = buffer + str.Length;

            JsonParserState.WriteVariableSizeInt(ref writePos, str.Length);
            _jsonParserState.WriteEscapePositionsTo(writePos + str.Length);
            keySize   = escapePositionsSize + str.Length + keySize;
            key       = buffer + str.Length;
            lowerKey  = buffer;
            lowerSize = str.Length;
            return;


UnlikelyUnicode:
            UnicodeGetLowerKeySliceAndStorageKey(context, str, out lowerKey, out lowerSize, out key, out keySize);
        }