@@ -56,7 +56,7 @@ type ErrParseFailed struct {
56
56
Err error
57
57
StartPos int
58
58
EndPos int
59
- Context [] byte
59
+ Context * ParseContext
60
60
Breadcrumbs []Breadcrumb
61
61
}
62
62
@@ -65,10 +65,9 @@ func (e *ErrParseFailed) Error() string {
65
65
sb .WriteString (e .Err .Error ())
66
66
sb .WriteString (fmt .Sprintf (", start position: %d, end position: %d" , e .StartPos , e .EndPos ))
67
67
68
- if len (e .Context ) > 0 {
69
- sb .WriteString (", context: '" )
70
- _ , _ = sb .Write (e .Context )
71
- sb .WriteByte ('\'' )
68
+ if e .Context != nil {
69
+ sb .WriteString (", context: " )
70
+ sb .WriteString (e .Context .String ())
72
71
}
73
72
74
73
if len (e .Breadcrumbs ) > 0 {
@@ -91,45 +90,31 @@ func (e *ErrParseFailed) Unwrap() error {
91
90
}
92
91
93
92
func (e * ErrParseFailed ) CopyContext (ctx context.Context , p Plate , startPos , endPos , chunkLen int ) {
94
- var ctxLen = endPos - startPos
93
+ e .Context = new (ParseContext )
94
+
95
+ var (
96
+ ctxLen = endPos - startPos
97
+ buf []byte
98
+ )
95
99
if ctxLen <= chunkLen {
96
- if buf , err : = p .ByteSlice (ctx , startPos , endPos ); err == nil {
97
- e .Context = make ([]byte , ctxLen )
98
- copy (e .Context , buf )
100
+ if buf , e . Context . HeadErr = p .ByteSlice (ctx , startPos , endPos ); e . Context . HeadErr == nil {
101
+ e .Context . Head = make ([]byte , len ( buf ) )
102
+ copy (e .Context . Head , buf )
99
103
}
100
104
} else {
101
- var leftLen = ctxLen / 2
102
- leftBuf , leftErr := p .ByteSlice (ctx , startPos , startPos + leftLen )
103
-
104
- var rightLen = ctxLen - leftLen
105
- rightBuf , rightErr := p .ByteSlice (ctx , endPos - rightLen , endPos )
106
-
107
- if leftErr == nil && rightErr == nil {
108
- var (
109
- bytesRemain = ctxLen - chunkLen
110
- remainMsg = []byte (fmt .Sprintf ("..[%d bytes].." , bytesRemain ))
111
- msgLen = len (remainMsg )
112
- )
113
- e .Context = make ([]byte , ctxLen + msgLen )
114
- copy (e .Context [:leftLen ], leftBuf )
115
- copy (e .Context [leftLen :leftLen + msgLen ], remainMsg )
116
- copy (e .Context [leftLen + msgLen :], rightBuf )
117
- } else if leftErr == nil {
118
- var (
119
- remainMsg = []byte ("..[more bytes]" )
120
- msgLen = len (remainMsg )
121
- )
122
- e .Context = make ([]byte , leftLen + msgLen )
123
- copy (e .Context [:leftLen ], leftBuf )
124
- copy (e .Context [leftLen :leftLen + msgLen ], remainMsg )
125
- } else if rightErr == nil {
126
- var (
127
- remainMsg = []byte ("[more bytes].." )
128
- msgLen = len (remainMsg )
129
- )
130
- e .Context = make ([]byte , rightLen + msgLen )
131
- copy (e .Context [:msgLen ], remainMsg )
132
- copy (e .Context [msgLen :], rightBuf )
105
+ e .Context .Parted = true
106
+ e .Context .BytesRemain = ctxLen - chunkLen
107
+
108
+ var leftLen = chunkLen / 2
109
+ if buf , e .Context .HeadErr = p .ByteSlice (ctx , startPos , startPos + leftLen ); e .Context .HeadErr == nil {
110
+ e .Context .Head = make ([]byte , len (buf ))
111
+ copy (e .Context .Head , buf )
112
+ }
113
+
114
+ var rightLen = chunkLen - leftLen
115
+ if buf , e .Context .TailErr = p .ByteSlice (ctx , endPos - rightLen , endPos ); e .Context .TailErr == nil {
116
+ e .Context .Tail = make ([]byte , len (buf ))
117
+ copy (e .Context .Tail , buf )
133
118
}
134
119
}
135
120
}
@@ -183,6 +168,55 @@ func ExtendBreadcrumb(err error, startPos, endPos int) error {
183
168
return err
184
169
}
185
170
171
+ type ParseContext struct {
172
+ Head []byte
173
+ HeadErr error
174
+ Tail []byte
175
+ TailErr error
176
+ BytesRemain int
177
+ Parted bool
178
+ }
179
+
180
+ func (pc ParseContext ) String () string {
181
+ var sb strings.Builder
182
+
183
+ if pc .Parted {
184
+ if pc .HeadErr == nil && pc .TailErr == nil {
185
+ sb .WriteByte ('\'' )
186
+ _ , _ = sb .Write (pc .Head )
187
+ if pc .BytesRemain > 0 {
188
+ sb .WriteString ("..[" )
189
+ sb .WriteString (strconv .Itoa (pc .BytesRemain ))
190
+ sb .WriteString (" bytes].." )
191
+ }
192
+ _ , _ = sb .Write (pc .Tail )
193
+ sb .WriteByte ('\'' )
194
+ } else if pc .HeadErr == nil {
195
+ sb .WriteByte ('\'' )
196
+ _ , _ = sb .Write (pc .Head )
197
+ sb .WriteString ("..[more bytes]'" )
198
+ } else if pc .TailErr == nil {
199
+ sb .WriteString ("'[more bytes].." )
200
+ _ , _ = sb .Write (pc .Tail )
201
+ sb .WriteByte ('\'' )
202
+ } else {
203
+ sb .WriteByte ('!' )
204
+ sb .WriteString (pc .HeadErr .Error ())
205
+ }
206
+ } else {
207
+ if pc .HeadErr == nil {
208
+ sb .WriteByte ('\'' )
209
+ _ , _ = sb .Write (pc .Head )
210
+ sb .WriteByte ('\'' )
211
+ } else {
212
+ sb .WriteByte ('!' )
213
+ sb .WriteString (pc .HeadErr .Error ())
214
+ }
215
+ }
216
+
217
+ return sb .String ()
218
+ }
219
+
186
220
type Breadcrumb struct {
187
221
Name string
188
222
Index int
0 commit comments