...
1
2
3
4
5 package message
6
7 import (
8 "bytes"
9 "strconv"
10 "unicode/utf8"
11
12 "golang.org/x/text/internal/format"
13 )
14
15 const (
16 ldigits = "0123456789abcdefx"
17 udigits = "0123456789ABCDEFX"
18 )
19
20 const (
21 signed = true
22 unsigned = false
23 )
24
25
26
27 type formatInfo struct {
28 buf *bytes.Buffer
29
30 format.Parser
31
32
33
34 intbuf [68]byte
35 }
36
37 func (f *formatInfo) init(buf *bytes.Buffer) {
38 f.ClearFlags()
39 f.buf = buf
40 }
41
42
43 func (f *formatInfo) writePadding(n int) {
44 if n <= 0 {
45 return
46 }
47 f.buf.Grow(n)
48
49 padByte := byte(' ')
50 if f.Zero {
51 padByte = byte('0')
52 }
53
54 for i := 0; i < n; i++ {
55 f.buf.WriteByte(padByte)
56 }
57 }
58
59
60 func (f *formatInfo) pad(b []byte) {
61 if !f.WidthPresent || f.Width == 0 {
62 f.buf.Write(b)
63 return
64 }
65 width := f.Width - utf8.RuneCount(b)
66 if !f.Minus {
67
68 f.writePadding(width)
69 f.buf.Write(b)
70 } else {
71
72 f.buf.Write(b)
73 f.writePadding(width)
74 }
75 }
76
77
78 func (f *formatInfo) padString(s string) {
79 if !f.WidthPresent || f.Width == 0 {
80 f.buf.WriteString(s)
81 return
82 }
83 width := f.Width - utf8.RuneCountInString(s)
84 if !f.Minus {
85
86 f.writePadding(width)
87 f.buf.WriteString(s)
88 } else {
89
90 f.buf.WriteString(s)
91 f.writePadding(width)
92 }
93 }
94
95
96 func (f *formatInfo) fmt_boolean(v bool) {
97 if v {
98 f.padString("true")
99 } else {
100 f.padString("false")
101 }
102 }
103
104
105 func (f *formatInfo) fmt_unicode(u uint64) {
106 buf := f.intbuf[0:]
107
108
109
110
111 prec := 4
112 if f.PrecPresent && f.Prec > 4 {
113 prec = f.Prec
114
115 width := 2 + prec + 2 + utf8.UTFMax + 1
116 if width > len(buf) {
117 buf = make([]byte, width)
118 }
119 }
120
121
122 i := len(buf)
123
124
125 if f.Sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
126 i--
127 buf[i] = '\''
128 i -= utf8.RuneLen(rune(u))
129 utf8.EncodeRune(buf[i:], rune(u))
130 i--
131 buf[i] = '\''
132 i--
133 buf[i] = ' '
134 }
135
136 for u >= 16 {
137 i--
138 buf[i] = udigits[u&0xF]
139 prec--
140 u >>= 4
141 }
142 i--
143 buf[i] = udigits[u]
144 prec--
145
146 for prec > 0 {
147 i--
148 buf[i] = '0'
149 prec--
150 }
151
152 i--
153 buf[i] = '+'
154 i--
155 buf[i] = 'U'
156
157 oldZero := f.Zero
158 f.Zero = false
159 f.pad(buf[i:])
160 f.Zero = oldZero
161 }
162
163
164 func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits string) {
165 negative := isSigned && int64(u) < 0
166 if negative {
167 u = -u
168 }
169
170 buf := f.intbuf[0:]
171
172
173 if f.WidthPresent || f.PrecPresent {
174
175 width := 3 + f.Width + f.Prec
176 if width > len(buf) {
177
178 buf = make([]byte, width)
179 }
180 }
181
182
183
184
185 prec := 0
186 if f.PrecPresent {
187 prec = f.Prec
188
189 if prec == 0 && u == 0 {
190 oldZero := f.Zero
191 f.Zero = false
192 f.writePadding(f.Width)
193 f.Zero = oldZero
194 return
195 }
196 } else if f.Zero && f.WidthPresent {
197 prec = f.Width
198 if negative || f.Plus || f.Space {
199 prec--
200 }
201 }
202
203
204
205
206 i := len(buf)
207
208
209 switch base {
210 case 10:
211 for u >= 10 {
212 i--
213 next := u / 10
214 buf[i] = byte('0' + u - next*10)
215 u = next
216 }
217 case 16:
218 for u >= 16 {
219 i--
220 buf[i] = digits[u&0xF]
221 u >>= 4
222 }
223 case 8:
224 for u >= 8 {
225 i--
226 buf[i] = byte('0' + u&7)
227 u >>= 3
228 }
229 case 2:
230 for u >= 2 {
231 i--
232 buf[i] = byte('0' + u&1)
233 u >>= 1
234 }
235 default:
236 panic("fmt: unknown base; can't happen")
237 }
238 i--
239 buf[i] = digits[u]
240 for i > 0 && prec > len(buf)-i {
241 i--
242 buf[i] = '0'
243 }
244
245
246 if f.Sharp {
247 switch base {
248 case 8:
249 if buf[i] != '0' {
250 i--
251 buf[i] = '0'
252 }
253 case 16:
254
255 i--
256 buf[i] = digits[16]
257 i--
258 buf[i] = '0'
259 }
260 }
261
262 if negative {
263 i--
264 buf[i] = '-'
265 } else if f.Plus {
266 i--
267 buf[i] = '+'
268 } else if f.Space {
269 i--
270 buf[i] = ' '
271 }
272
273
274
275 oldZero := f.Zero
276 f.Zero = false
277 f.pad(buf[i:])
278 f.Zero = oldZero
279 }
280
281
282 func (f *formatInfo) truncate(s string) string {
283 if f.PrecPresent {
284 n := f.Prec
285 for i := range s {
286 n--
287 if n < 0 {
288 return s[:i]
289 }
290 }
291 }
292 return s
293 }
294
295
296 func (f *formatInfo) fmt_s(s string) {
297 s = f.truncate(s)
298 f.padString(s)
299 }
300
301
302 func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) {
303 length := len(b)
304 if b == nil {
305
306 length = len(s)
307 }
308
309 if f.PrecPresent && f.Prec < length {
310 length = f.Prec
311 }
312
313 width := 2 * length
314 if width > 0 {
315 if f.Space {
316
317 if f.Sharp {
318 width *= 2
319 }
320
321 width += length - 1
322 } else if f.Sharp {
323
324 width += 2
325 }
326 } else {
327 if f.WidthPresent {
328 f.writePadding(f.Width)
329 }
330 return
331 }
332
333 if f.WidthPresent && f.Width > width && !f.Minus {
334 f.writePadding(f.Width - width)
335 }
336
337 buf := f.buf
338 if f.Sharp {
339
340 buf.WriteByte('0')
341 buf.WriteByte(digits[16])
342 }
343 var c byte
344 for i := 0; i < length; i++ {
345 if f.Space && i > 0 {
346
347 buf.WriteByte(' ')
348 if f.Sharp {
349
350 buf.WriteByte('0')
351 buf.WriteByte(digits[16])
352 }
353 }
354 if b != nil {
355 c = b[i]
356 } else {
357 c = s[i]
358 }
359
360 buf.WriteByte(digits[c>>4])
361 buf.WriteByte(digits[c&0xF])
362 }
363
364 if f.WidthPresent && f.Width > width && f.Minus {
365 f.writePadding(f.Width - width)
366 }
367 }
368
369
370 func (f *formatInfo) fmt_sx(s, digits string) {
371 f.fmt_sbx(s, nil, digits)
372 }
373
374
375 func (f *formatInfo) fmt_bx(b []byte, digits string) {
376 f.fmt_sbx("", b, digits)
377 }
378
379
380
381
382 func (f *formatInfo) fmt_q(s string) {
383 s = f.truncate(s)
384 if f.Sharp && strconv.CanBackquote(s) {
385 f.padString("`" + s + "`")
386 return
387 }
388 buf := f.intbuf[:0]
389 if f.Plus {
390 f.pad(strconv.AppendQuoteToASCII(buf, s))
391 } else {
392 f.pad(strconv.AppendQuote(buf, s))
393 }
394 }
395
396
397
398 func (f *formatInfo) fmt_c(c uint64) {
399 r := rune(c)
400 if c > utf8.MaxRune {
401 r = utf8.RuneError
402 }
403 buf := f.intbuf[:0]
404 w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
405 f.pad(buf[:w])
406 }
407
408
409
410 func (f *formatInfo) fmt_qc(c uint64) {
411 r := rune(c)
412 if c > utf8.MaxRune {
413 r = utf8.RuneError
414 }
415 buf := f.intbuf[:0]
416 if f.Plus {
417 f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
418 } else {
419 f.pad(strconv.AppendQuoteRune(buf, r))
420 }
421 }
422
423
424
425 func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) {
426
427 if f.PrecPresent {
428 prec = f.Prec
429 }
430
431 num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
432 if num[1] == '-' || num[1] == '+' {
433 num = num[1:]
434 } else {
435 num[0] = '+'
436 }
437
438
439 if f.Space && num[0] == '+' && !f.Plus {
440 num[0] = ' '
441 }
442
443
444 if num[1] == 'I' || num[1] == 'N' {
445 oldZero := f.Zero
446 f.Zero = false
447
448 if num[1] == 'N' && !f.Space && !f.Plus {
449 num = num[1:]
450 }
451 f.pad(num)
452 f.Zero = oldZero
453 return
454 }
455
456
457 if f.Sharp && verb != 'b' {
458 digits := 0
459 switch verb {
460 case 'v', 'g', 'G':
461 digits = prec
462
463 if digits == -1 {
464 digits = 6
465 }
466 }
467
468
469
470 var tailBuf [5]byte
471 tail := tailBuf[:0]
472
473 hasDecimalPoint := false
474
475 for i := 1; i < len(num); i++ {
476 switch num[i] {
477 case '.':
478 hasDecimalPoint = true
479 case 'e', 'E':
480 tail = append(tail, num[i:]...)
481 num = num[:i]
482 default:
483 digits--
484 }
485 }
486 if !hasDecimalPoint {
487 num = append(num, '.')
488 }
489 for digits > 0 {
490 num = append(num, '0')
491 digits--
492 }
493 num = append(num, tail...)
494 }
495
496 if f.Plus || num[0] != '+' {
497
498
499 if f.Zero && f.WidthPresent && f.Width > len(num) {
500 f.buf.WriteByte(num[0])
501 f.writePadding(f.Width - len(num))
502 f.buf.Write(num[1:])
503 return
504 }
505 f.pad(num)
506 return
507 }
508
509 f.pad(num[1:])
510 }
511
View as plain text