From f09b90fed243ebc9411eafeb80e64a455e7f26d3 Mon Sep 17 00:00:00 2001
From: Ivar Johansson <ivar@webbmaffian.se>
Date: Thu, 16 May 2024 18:45:35 +0200
Subject: [PATCH 1/3] Added `Iterator.ReadStringAsReader`

---
 iter_str_reader.go | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 iter_str_reader.go

diff --git a/iter_str_reader.go b/iter_str_reader.go
new file mode 100644
index 00000000..02951354
--- /dev/null
+++ b/iter_str_reader.go
@@ -0,0 +1,42 @@
+package jsoniter
+
+import "io"
+
+func (iter *Iterator) ReadStringAsReader() (r io.Reader) {
+	c := iter.nextToken()
+	if c == '"' {
+		return iterStrReader{iter}
+	}
+	iter.ReportError("ReadStringAsReader", `expects " or n, but found `+string([]byte{c}))
+	return
+}
+
+var _ io.Reader = iterStrReader{}
+
+type iterStrReader struct {
+	iter *Iterator
+}
+
+func (r iterStrReader) Read(dst []byte) (n int, err error) {
+	for i := r.iter.head; i < r.iter.tail; i++ {
+		// require ascii string and no escape
+		// for: field name, base64, number
+		if r.iter.buf[i] == '"' {
+			n = copy(dst, r.iter.buf[r.iter.head:i])
+			r.iter.head = n + 1
+			err = io.EOF
+			return
+		}
+	}
+
+	n = copy(dst, r.iter.buf[r.iter.head:])
+	r.iter.head = n
+
+	if r.iter.head == r.iter.tail {
+		if !r.iter.loadMore() {
+			err = io.ErrUnexpectedEOF
+		}
+	}
+
+	return
+}

From f482b7023e2fb56cf8a358587f8ee89f06b6c7e4 Mon Sep 17 00:00:00 2001
From: Ivar Johansson <ivar@webbmaffian.se>
Date: Thu, 16 May 2024 19:30:19 +0200
Subject: [PATCH 2/3] Added docs + example for `Iterator.ReadStringAsReader`

---
 .vscode/launch.json     | 15 +++++++++++++++
 iter_str_reader.go      |  7 +++++--
 iter_str_reader_test.go | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 2 deletions(-)
 create mode 100644 .vscode/launch.json
 create mode 100644 iter_str_reader_test.go

diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..e40fcdd8
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,15 @@
+{
+	// Use IntelliSense to learn about possible attributes.
+	// Hover to view descriptions of existing attributes.
+	// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+	"version": "0.2.0",
+	"configurations": [
+		{
+			"name": "Launch Package",
+			"type": "go",
+			"request": "launch",
+			"mode": "auto",
+			"program": "${workspaceFolder}"
+		}
+	]
+}
\ No newline at end of file
diff --git a/iter_str_reader.go b/iter_str_reader.go
index 02951354..f1a8e42b 100644
--- a/iter_str_reader.go
+++ b/iter_str_reader.go
@@ -2,6 +2,9 @@ package jsoniter
 
 import "io"
 
+// Returns a reader that can be used to read the following string until EOF.
+// Using the reader after EOF is undefined behavior, and so is using the reader
+// when when the current token isn't a string.
 func (iter *Iterator) ReadStringAsReader() (r io.Reader) {
 	c := iter.nextToken()
 	if c == '"' {
@@ -23,14 +26,14 @@ func (r iterStrReader) Read(dst []byte) (n int, err error) {
 		// for: field name, base64, number
 		if r.iter.buf[i] == '"' {
 			n = copy(dst, r.iter.buf[r.iter.head:i])
-			r.iter.head = n + 1
+			r.iter.head += n + 1
 			err = io.EOF
 			return
 		}
 	}
 
 	n = copy(dst, r.iter.buf[r.iter.head:])
-	r.iter.head = n
+	r.iter.head += n
 
 	if r.iter.head == r.iter.tail {
 		if !r.iter.loadMore() {
diff --git a/iter_str_reader_test.go b/iter_str_reader_test.go
new file mode 100644
index 00000000..d70d5e8c
--- /dev/null
+++ b/iter_str_reader_test.go
@@ -0,0 +1,35 @@
+package jsoniter
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+)
+
+func ExampleIterator_ReadStringAsReader() {
+	json := bytes.NewBufferString(`{"foo":"abcdefghijklmnopqrstuvwxyz"}`)
+	iter := Parse(ConfigDefault, json, 16)
+
+	_ = iter.ReadObject()
+	r := iter.ReadStringAsReader()
+	buf := make([]byte, 8)
+
+	for {
+		n, err := r.Read(buf)
+		fmt.Println(string(buf[:n]))
+
+		if err != nil {
+			if err != io.EOF {
+				panic(err)
+			}
+			break
+		}
+	}
+
+	// Output:
+	//
+	// abcdefgh
+	// ijklmnop
+	// qrstuvwx
+	// yz
+}

From 85ca0899d8f629e0cb188971a195b24df8cbcdd3 Mon Sep 17 00:00:00 2001
From: Ivar Johansson <ivar@webbmaffian.se>
Date: Thu, 16 May 2024 19:31:43 +0200
Subject: [PATCH 3/3] Clean-up

---
 .vscode/launch.json | 15 ---------------
 1 file changed, 15 deletions(-)
 delete mode 100644 .vscode/launch.json

diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index e40fcdd8..00000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-	// Use IntelliSense to learn about possible attributes.
-	// Hover to view descriptions of existing attributes.
-	// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
-	"version": "0.2.0",
-	"configurations": [
-		{
-			"name": "Launch Package",
-			"type": "go",
-			"request": "launch",
-			"mode": "auto",
-			"program": "${workspaceFolder}"
-		}
-	]
-}
\ No newline at end of file