@@ -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,74 @@ 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+ return e .stringN ( 0 )
119121}
120122
121123// StringN implements the fmt.String interface for upto N bytes. The output will be in extended JSON format.
122124func (e Element ) StringN (n int ) string {
125+ if n <= 0 {
126+ return ""
127+ }
128+ return e .stringN (n )
129+ }
130+
131+ // stringN stringify an element. If N is larger than 0, it will truncate the string to N bytes.
132+ func (e Element ) stringN (n int ) string {
123133 if len (e ) == 0 {
124134 return ""
125135 }
136+ if n == 1 {
137+ return `"`
138+ }
139+
126140 t := Type (e [0 ])
127141 idx := bytes .IndexByte (e [1 :], 0x00 )
128- if idx == - 1 {
142+ if idx <= 0 {
129143 return ""
130144 }
131- key , valBytes := []byte (e [1 :idx + 1 ]), []byte (e [idx + 2 :])
132- val , _ , valid := ReadValue (valBytes , t )
145+ key := e [1 : idx + 1 ]
146+
147+ var buf strings.Builder
148+ buf .WriteByte ('"' )
149+ const postfix = `": `
150+ switch {
151+ case n <= 0 || idx <= n - 4 :
152+ buf .Write (key )
153+ buf .WriteString (postfix )
154+ case idx < n :
155+ buf .Write (key )
156+ buf .WriteString (postfix [:n - idx ])
157+ default :
158+ buf .WriteString (bsoncoreutil .Truncate (string (key ), n - 1 ))
159+ }
160+
161+ l := 0
162+ if n > 0 {
163+ if buf .Len () >= n {
164+ return buf .String ()
165+ }
166+ l = n - buf .Len ()
167+ }
168+
169+ val , _ , valid := ReadValue (e [idx + 2 :], t )
133170 if ! valid {
134171 return ""
135172 }
136173
137174 var str string
138175 if _ , ok := val .StringValueOK (); ok {
139- str = val .StringN ( n )
176+ str = val .stringN ( l )
140177 } else if arr , ok := val .ArrayOK (); ok {
141- str = arr .StringN ( n )
178+ str = arr .stringN ( l )
142179 } else {
143180 str = val .String ()
181+ if l > 0 && len (str ) > l {
182+ str = bsoncoreutil .Truncate (str , l )
183+ }
144184 }
145185
146- return "\" " + string (key ) + "\" : " + str
186+ buf .WriteString (str )
187+ return buf .String ()
147188}
148189
149190// DebugString outputs a human readable version of RawElement. It will attempt to stringify the
0 commit comments