Helps reading JSON members from an underlying JsonReader without regard to the order (free) in which they appear. Members are buffered or streamed as needed.
A JsonReader has a stream-oriented interface where the underlying JSON data is tokenized and yielded sequentially. When reading a JSON object, members must be processed in the order in which they are yielded by the underlying reader. If an application requires some members of a JSON object to correctly process the remaining members then those member may need to be read in advance to prepare for further processing. For example, suppose the JSON object { "type": "date", "format": "M/d/yyyy", "value": "5/5/2008" } represents a date encoded in the value member as a JSON string. Suppose further, the type confirms that the entire JSON object indeed describes a date and the format member specifies how to interpret the value member. To correctly create the date, an application would have to assert the type member, then read the format member to determine how to decode the value member value correctly. If the application assumes that the members are always provided in the natural order just described then it can simply use a JsonReader and process them in sequence along with their values. However, if the JSON object instead has members out of order, as in { "value": "5/5/2008", "type": "date", "format": "M/d/yyyy" }, then reading becomes a bit more cumbersome. The application would have to buffer the value and format member values until it has at least seen the type member and asserted its value to be date. Then it has to return to the buffered value of the format member and use it to finally decode the also-buffered value member. This is where FreeJsonMemberReadingHelper can help tremendously. The application can call its ReadMember method to read members in the natural order of processing (e.g., type, format and value) rather than how they have been actually ordered by some source. FreeJsonMemberReadingHelper will buffer or stream from the underlying JsonReader as needed. Once the required members have been processed, the GetTailReader method can be used to read auxillary or optional members in their order of appearance.
        public void BaseReaderInitialization()
        {
            JsonReader reader = JsonText.CreateReader("[]");
            FreeJsonMemberReadingHelper helper = new FreeJsonMemberReadingHelper(reader);

            Assert.AreSame(reader, helper.BaseReader);
        }
        public void ReadingSameMemberMoreThanOnce()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper("{foo:bar}");

            helper.ReadMember("foo").Skip();
            Assert.IsNull(helper.TryReadMember("foo"));
        }
        public void ScopedToCurrentObject()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper("[{},{foo:bar}]");

            helper.BaseReader.ReadToken(JsonTokenClass.Array);
            Assert.IsNull(helper.TryReadMember("foo"));
            Assert.IsNull(helper.TryReadMember("foo"));
        }
        public void OrderedReading()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"{ x: 123, y: 456, z: 789 }");

            Assert.AreEqual(123, helper.ReadMember("x").ReadNumber().ToInt32());
            Assert.AreEqual(456, helper.ReadMember("y").ReadNumber().ToInt32());
            Assert.AreEqual(789, helper.ReadMember("z").ReadNumber().ToInt32());
            Assert.AreEqual(JsonTokenClass.EndObject, helper.BaseReader.TokenClass);
        }
        public void EmptyTailReading()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"{ y: 456, x: 123, z: 789 }");

            Assert.AreEqual(123, helper.ReadMember("x").ReadNumber().ToInt32());
            Assert.AreEqual(456, helper.ReadMember("y").ReadNumber().ToInt32());
            Assert.AreEqual(789, helper.ReadMember("z").ReadNumber().ToInt32());
            JsonReader tail = helper.GetTailReader();

            tail.ReadToken(JsonTokenClass.EndObject);
            Assert.IsFalse(tail.Read());
        }
        public void TailMemberAfterUnorderedReader()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"
                { y: 456, x: 123, z: 789, comment: tail }");

            Assert.AreEqual(123, helper.ReadMember("x").ReadNumber().ToInt32());
            Assert.AreEqual(456, helper.ReadMember("y").ReadNumber().ToInt32());
            Assert.AreEqual(789, helper.ReadMember("z").ReadNumber().ToInt32());
            JsonReader reader = helper.BaseReader;

            Assert.AreEqual("comment", reader.ReadMember());
            Assert.AreEqual("tail", reader.ReadString());
        }
        public void TailReading()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"
                { y: 456, 
                  x: 123, 
                  z: 789, 
                  obj1: { foo: bar }, 
                  comment: null, 
                  arr: [ 123, 456, 789 ],
                  obj2: { a: 1, b: 2, }, }");

            Assert.AreEqual(123, helper.ReadMember("x").ReadNumber().ToInt32());
            helper.ReadMember("comment").ReadNull();
            JsonReader reader = helper.BaseReader;

            Assert.AreEqual(JsonTokenClass.Member, reader.TokenClass);
            Assert.AreEqual("arr", reader.Text);
            JsonReader tail = helper.GetTailReader();

            Assert.AreEqual("y", tail.ReadMember());
            Assert.AreEqual(456, tail.ReadNumber().ToInt32());
            Assert.AreEqual("z", tail.ReadMember());
            Assert.AreEqual(789, tail.ReadNumber().ToInt32());
            Assert.AreEqual("obj1", tail.ReadMember());
            tail.ReadToken(JsonTokenClass.Object);
            Assert.AreEqual("foo", tail.ReadMember());
            Assert.AreEqual("bar", tail.ReadString());
            tail.ReadToken(JsonTokenClass.EndObject);
            Assert.AreEqual("arr", tail.ReadMember());
            tail.ReadToken(JsonTokenClass.Array);
            Assert.AreEqual(123, tail.ReadNumber().ToInt32());
            Assert.AreEqual(456, tail.ReadNumber().ToInt32());
            Assert.AreEqual(789, tail.ReadNumber().ToInt32());
            tail.ReadToken(JsonTokenClass.EndArray);
            Assert.AreEqual("obj2", tail.ReadMember());
            tail.StepOut();
            Assert.IsFalse(reader.Read());
        }
        public void CannotReadNonExistingMember()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"{ y: 456, x: 123, z: 789 }");

            helper.ReadMember("foo");
        }
        public void StringRepresentation()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper("[]");

            Assert.AreEqual(helper.BaseReader.ToString(), helper.ToString());
        }
        public void TryReadMemberCaseSensitivity()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"{ y: 456, x: 123, z: 789 }");

            Assert.IsNull(helper.TryReadMember("X"));
        }
        public void TryReadNonExistingMember()
        {
            FreeJsonMemberReadingHelper helper = CreateHelper(@"{ y: 456, x: 123, z: 789 }");

            Assert.IsNull(helper.TryReadMember("foo"));
        }
 public void BaseReaderInitialization()
 {
     JsonReader reader = JsonText.CreateReader("[]");
     FreeJsonMemberReadingHelper helper = new FreeJsonMemberReadingHelper(reader);
     Assert.AreSame(reader, helper.BaseReader);
 }