Kaynağa Gözat

read object cb

Tao Wen 9 yıl önce
ebeveyn
işleme
80c86e63b1
2 değiştirilmiş dosya ile 55 ekleme ve 31 silme
  1. 39 17
      feature_iter_object.go
  2. 16 14
      jsoniter_object_test.go

+ 39 - 17
feature_iter_object.go

@@ -1,33 +1,22 @@
 package jsoniter
 
-// ReadObject is a implemented iterator for json
 func (iter *Iterator) ReadObject() (ret string) {
 	c := iter.nextToken()
-	if iter.Error != nil {
-		return
-	}
 	switch c {
 	case 'n':
 		iter.skipFixedBytes(3)
-		if iter.Error != nil {
-			return
-		}
 		return "" // null
 	case '{':
 		c = iter.nextToken()
-		if iter.Error != nil {
-			return
-		}
-		switch c {
-		case '}':
-			return "" // end of object
-		case '"':
+		if c == '"' {
 			iter.unreadByte()
 			return string(iter.readObjectFieldAsBytes())
-		default:
-			iter.reportError("ReadObject", `expect " after {`)
-			return
 		}
+		if c == '}' {
+			return "" // end of object
+		}
+		iter.reportError("ReadObject", `expect " after {`)
+		return
 	case ',':
 		return string(iter.readObjectFieldAsBytes())
 	case '}':
@@ -38,6 +27,39 @@ func (iter *Iterator) ReadObject() (ret string) {
 	}
 }
 
+func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
+	c := iter.nextToken()
+	if c == '{' {
+		c = iter.nextToken()
+		if c == '"' {
+			iter.unreadByte()
+			field := string(iter.readObjectFieldAsBytes())
+			if !callback(iter, field) {
+				return false
+			}
+			c = iter.nextToken()
+			for c == ',' {
+				field := string(iter.readObjectFieldAsBytes())
+				if !callback(iter, field) {
+					return false
+				}
+			}
+			return true
+		}
+		if c == '}' {
+			return true
+		}
+		iter.reportError("ReadObjectCB", `expect " after }`)
+		return false
+	}
+	if c == 'n' {
+		iter.skipFixedBytes(3)
+		return true // null
+	}
+	iter.reportError("ReadObjectCB", `expect { or n`)
+	return false
+}
+
 func (iter *Iterator) readObjectStart() bool {
 	c := iter.nextToken()
 	if c == '{' {

+ 16 - 14
jsoniter_object_test.go

@@ -2,35 +2,37 @@ package jsoniter
 
 import (
 	"encoding/json"
-	"fmt"
 	"testing"
 	"github.com/json-iterator/go/require"
 	"bytes"
 )
 
 func Test_empty_object(t *testing.T) {
+	should := require.New(t)
 	iter := ParseString(`{}`)
 	field := iter.ReadObject()
-	if field != "" {
-		t.Fatal(field)
-	}
+	should.Equal("", field)
+	iter = ParseString(`{}`)
+	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		should.FailNow("should not call")
+		return true
+	})
 }
 
 func Test_one_field(t *testing.T) {
+	should := require.New(t)
 	iter := ParseString(`{"a": "b"}`)
 	field := iter.ReadObject()
-	if field != "a" {
-		fmt.Println(iter.Error)
-		t.Fatal(field)
-	}
+	should.Equal("a", field)
 	value := iter.ReadString()
-	if value != "b" {
-		t.Fatal(field)
-	}
+	should.Equal("b", value)
 	field = iter.ReadObject()
-	if field != "" {
-		t.Fatal(field)
-	}
+	should.Equal("", field)
+	iter = ParseString(`{"a": "b"}`)
+	should.True(iter.ReadObjectCB(func(iter *Iterator, field string) bool {
+		should.Equal("a", field)
+		return true
+	}))
 }
 
 func Test_two_field(t *testing.T) {