@@ -9,7 +9,9 @@ package bsoncore
99import (
1010 "bytes"
1111 "fmt"
12- "math"
12+ "strings"
13+
14+ "go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil"
1315)
1416
1517// MalformedElementError represents a class of errors that RawElement methods return.
@@ -115,35 +117,78 @@ func (e Element) ValueErr() (Value, error) {
115117
116118// String implements the fmt.String interface. The output will be in extended JSON format.
117119func (e Element ) String () string {
118- return e .StringN (math .MaxInt )
120+ str , _ := e .stringN (0 )
121+ return str
119122}
120123
121124// StringN implements the fmt.String interface for upto N bytes. The output will be in extended JSON format.
122125func (e Element ) StringN (n int ) string {
123- if len ( e ) = = 0 {
126+ if n < = 0 {
124127 return ""
125128 }
129+ str , _ := e .stringN (n )
130+ return str
131+ }
132+
133+ // stringN stringify an element. If N is larger than 0, it will truncate the string to N bytes.
134+ func (e Element ) stringN (n int ) (string , bool ) {
135+ if len (e ) == 0 {
136+ return "" , false
137+ }
138+ if n == 1 {
139+ return `"` , true
140+ }
141+
126142 t := Type (e [0 ])
127143 idx := bytes .IndexByte (e [1 :], 0x00 )
128- if idx == - 1 {
129- return ""
130- }
131- key , valBytes := []byte (e [1 :idx + 1 ]), []byte (e [idx + 2 :])
132- val , _ , valid := ReadValue (valBytes , t )
144+ if idx <= 0 {
145+ return "" , false
146+ }
147+ key := e [1 : idx + 1 ]
148+
149+ var buf strings.Builder
150+ buf .WriteByte ('"' )
151+ const postfix = `": `
152+ switch {
153+ case n <= 0 || idx <= n - 4 :
154+ buf .Write (key )
155+ buf .WriteString (postfix )
156+ case idx < n :
157+ buf .Write (key )
158+ buf .WriteString (postfix [:n - idx ])
159+ default :
160+ buf .WriteString (bsoncoreutil .Truncate (string (key ), n - 1 ))
161+ }
162+
163+ l := 0
164+ if n > 0 {
165+ if buf .Len () >= n {
166+ return buf .String (), true
167+ }
168+ l = n - buf .Len ()
169+ }
170+
171+ val , _ , valid := ReadValue (e [idx + 2 :], t )
133172 if ! valid {
134- return ""
173+ return "" , false
135174 }
136175
137176 var str string
177+ var truncated bool
138178 if _ , ok := val .StringValueOK (); ok {
139- str = val .StringN ( n )
179+ str , truncated = val .stringN ( l )
140180 } else if arr , ok := val .ArrayOK (); ok {
141- str = arr .StringN ( n )
181+ str , truncated = arr .stringN ( l )
142182 } else {
143183 str = val .String ()
184+ if l > 0 && len (str ) > l {
185+ truncated = true
186+ str = bsoncoreutil .Truncate (str , l )
187+ }
144188 }
145189
146- return "\" " + string (key ) + "\" : " + str
190+ buf .WriteString (str )
191+ return buf .String (), truncated
147192}
148193
149194// DebugString outputs a human readable version of RawElement. It will attempt to stringify the
0 commit comments