private string ReadObjectKey(ref char *ptr, ref char *end)
        {
            // return ReadString(ref ptr, ref end).Value;
            // check first letter
            Debug.Assert(*ptr == '\"');
            ptr++;

            // reset digger
            _cacheDigger.Initialize();

            var misshit = false;

            for (; !IsEndOfJson(ref ptr, ref end) && *ptr != '\"'; ptr++)
            {
                if (*ptr == '\\')
                {
                    var bp = DecodeEscapedChar(ref ptr, ref end);
                    if (_cacheDigger.DigNextChar(bp))
                    {
                        continue;
                    }
                    goto miss_hit;
                }
                if (_cacheDigger.DigNextChar(*ptr))
                {
                    continue;
                }

miss_hit:
                misshit = true;
                break;
            }
            if (IsEndOfJson(ref ptr, ref end))
            {
                // end in middle of string
                throw CreateException(ptr, "string is not closed.");
            }

            // check cache result and key
            if (!misshit)
            {
                // completed reading string
                // -> read " and direct to next char
                AssertAndReadNext(ref ptr, '\"');
                // completing
                _cacheDigger.Complete();

                var key    = _cacheDigger.PointingItem;
                var length = _cacheDigger.ItemValidLength;
                if (key.Length != length)
                {
                    // add substring item
                    var item = key.Substring(0, length);
                    _cacheTree.Add(item);
                    return(item);
                }
                return(key);
            }
            // offload to original string reader
            var offload = ReadString(ref ptr, ref end, true).Value;
            var newkey  = _cacheDigger.PointingItem?.Substring(0, _cacheDigger.ItemValidLength) + offload;

            _cacheTree.Add(newkey);
            return(newkey);
        }
Example #2
0
        public void KeyCacheTreeDiggingTest()
        {
            _tree.Add("coordinates");
            _tree.Add("favorited");
            _tree.Add("truncated");
            _tree.Add("created_at");
            _tree.Add("id_str");
            _tree.Add("entities");
            _tree.Add("urls");
            _tree.Add("expanded_url");
            _tree.Add("url");
            _tree.Add("indices");
            _tree.Add("display_url");
            _tree.Add("hashtags");
            _tree.Add("user_mentions");
            _tree.Add("in_reply_to_user_id_str");
            _tree.Add("contributors");
            _tree.Add("text");
            _tree.Add("retweet_count");
            _tree.Add("in_reply_to_status_id");
            _tree.Add("id");
            _tree.Add("geo");
            _tree.Add("retweeted");
            _tree.Add("possibly_sensitive");
            _tree.Add("in_reply_to_user_id");
            _tree.Add("place");
            _tree.Add("user");

            _digger.Initialize();
            Assert.IsTrue(_digger.DigNextChar('i'));
            Assert.IsTrue(_digger.DigNextChar('n'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('r'));
            Assert.IsTrue(_digger.DigNextChar('e'));
            Assert.IsTrue(_digger.DigNextChar('p'));
            Assert.IsTrue(_digger.DigNextChar('l'));
            Assert.IsTrue(_digger.DigNextChar('y'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('t'));
            Assert.IsTrue(_digger.DigNextChar('o'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('u'));
            Assert.IsTrue(_digger.DigNextChar('s'));
            Assert.IsTrue(_digger.DigNextChar('e'));
            Assert.IsTrue(_digger.DigNextChar('r'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('i'));
            Assert.IsTrue(_digger.DigNextChar('d'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('s'));
            Assert.IsTrue(_digger.DigNextChar('t'));
            Assert.IsTrue(_digger.DigNextChar('r'));

            Assert.AreEqual(_digger.PointingItem, "in_reply_to_user_id_str");
            Assert.AreEqual(_digger.ItemValidLength, "in_reply_to_user_id_str".Length);

            _digger.Initialize();

            Assert.IsTrue(_digger.DigNextChar('i'));
            Assert.IsTrue(_digger.DigNextChar('n'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('r'));
            Assert.IsTrue(_digger.DigNextChar('e'));
            Assert.IsTrue(_digger.DigNextChar('p'));
            Assert.IsTrue(_digger.DigNextChar('l'));
            Assert.IsTrue(_digger.DigNextChar('y'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('t'));
            Assert.IsTrue(_digger.DigNextChar('o'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('s'));
            Assert.IsTrue(_digger.DigNextChar('t'));
            Assert.IsTrue(_digger.DigNextChar('a'));
            Assert.IsTrue(_digger.DigNextChar('t'));
            Assert.IsTrue(_digger.DigNextChar('u'));
            Assert.IsTrue(_digger.DigNextChar('s'));
            Assert.IsTrue(_digger.DigNextChar('_'));
            Assert.IsTrue(_digger.DigNextChar('i'));
            Assert.IsTrue(_digger.DigNextChar('d'));
            Assert.IsFalse(_digger.DigNextChar('_'));

            Assert.AreEqual(_digger.PointingItem, "in_reply_to_status_id");
            Assert.AreEqual(_digger.ItemValidLength, "in_reply_to_status_id".Length);
        }