go-tg-screenshot-bot

Форк
0
817 строк · 15.3 Кб
1
package dbus
2

3
import (
4
	"bytes"
5
	"errors"
6
	"fmt"
7
	"io"
8
	"reflect"
9
	"strconv"
10
	"strings"
11
	"unicode/utf8"
12
)
13

14
type varParser struct {
15
	tokens []varToken
16
	i      int
17
}
18

19
func (p *varParser) backup() {
20
	p.i--
21
}
22

23
func (p *varParser) next() varToken {
24
	if p.i < len(p.tokens) {
25
		t := p.tokens[p.i]
26
		p.i++
27
		return t
28
	}
29
	return varToken{typ: tokEOF}
30
}
31

32
type varNode interface {
33
	Infer() (Signature, error)
34
	String() string
35
	Sigs() sigSet
36
	Value(Signature) (interface{}, error)
37
}
38

39
func varMakeNode(p *varParser) (varNode, error) {
40
	var sig Signature
41

42
	for {
43
		t := p.next()
44
		switch t.typ {
45
		case tokEOF:
46
			return nil, io.ErrUnexpectedEOF
47
		case tokError:
48
			return nil, errors.New(t.val)
49
		case tokNumber:
50
			return varMakeNumNode(t, sig)
51
		case tokString:
52
			return varMakeStringNode(t, sig)
53
		case tokBool:
54
			if sig.str != "" && sig.str != "b" {
55
				return nil, varTypeError{t.val, sig}
56
			}
57
			b, err := strconv.ParseBool(t.val)
58
			if err != nil {
59
				return nil, err
60
			}
61
			return boolNode(b), nil
62
		case tokArrayStart:
63
			return varMakeArrayNode(p, sig)
64
		case tokVariantStart:
65
			return varMakeVariantNode(p, sig)
66
		case tokDictStart:
67
			return varMakeDictNode(p, sig)
68
		case tokType:
69
			if sig.str != "" {
70
				return nil, errors.New("unexpected type annotation")
71
			}
72
			if t.val[0] == '@' {
73
				sig.str = t.val[1:]
74
			} else {
75
				sig.str = varTypeMap[t.val]
76
			}
77
		case tokByteString:
78
			if sig.str != "" && sig.str != "ay" {
79
				return nil, varTypeError{t.val, sig}
80
			}
81
			b, err := varParseByteString(t.val)
82
			if err != nil {
83
				return nil, err
84
			}
85
			return byteStringNode(b), nil
86
		default:
87
			return nil, fmt.Errorf("unexpected %q", t.val)
88
		}
89
	}
90
}
91

92
type varTypeError struct {
93
	val string
94
	sig Signature
95
}
96

97
func (e varTypeError) Error() string {
98
	return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
99
}
100

101
type sigSet map[Signature]bool
102

103
func (s sigSet) Empty() bool {
104
	return len(s) == 0
105
}
106

107
func (s sigSet) Intersect(s2 sigSet) sigSet {
108
	r := make(sigSet)
109
	for k := range s {
110
		if s2[k] {
111
			r[k] = true
112
		}
113
	}
114
	return r
115
}
116

117
func (s sigSet) Single() (Signature, bool) {
118
	if len(s) == 1 {
119
		for k := range s {
120
			return k, true
121
		}
122
	}
123
	return Signature{}, false
124
}
125

126
func (s sigSet) ToArray() sigSet {
127
	r := make(sigSet, len(s))
128
	for k := range s {
129
		r[Signature{"a" + k.str}] = true
130
	}
131
	return r
132
}
133

134
type numNode struct {
135
	sig Signature
136
	str string
137
	val interface{}
138
}
139

140
var numSigSet = sigSet{
141
	Signature{"y"}: true,
142
	Signature{"n"}: true,
143
	Signature{"q"}: true,
144
	Signature{"i"}: true,
145
	Signature{"u"}: true,
146
	Signature{"x"}: true,
147
	Signature{"t"}: true,
148
	Signature{"d"}: true,
149
}
150

151
func (n numNode) Infer() (Signature, error) {
152
	if strings.ContainsAny(n.str, ".e") {
153
		return Signature{"d"}, nil
154
	}
155
	return Signature{"i"}, nil
156
}
157

158
func (n numNode) String() string {
159
	return n.str
160
}
161

162
func (n numNode) Sigs() sigSet {
163
	if n.sig.str != "" {
164
		return sigSet{n.sig: true}
165
	}
166
	if strings.ContainsAny(n.str, ".e") {
167
		return sigSet{Signature{"d"}: true}
168
	}
169
	return numSigSet
170
}
171

172
func (n numNode) Value(sig Signature) (interface{}, error) {
173
	if n.sig.str != "" && n.sig != sig {
174
		return nil, varTypeError{n.str, sig}
175
	}
176
	if n.val != nil {
177
		return n.val, nil
178
	}
179
	return varNumAs(n.str, sig)
180
}
181

182
func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
183
	if sig.str == "" {
184
		return numNode{str: tok.val}, nil
185
	}
186
	num, err := varNumAs(tok.val, sig)
187
	if err != nil {
188
		return nil, err
189
	}
190
	return numNode{sig: sig, val: num}, nil
191
}
192

193
func varNumAs(s string, sig Signature) (interface{}, error) {
194
	isUnsigned := false
195
	size := 32
196
	switch sig.str {
197
	case "n":
198
		size = 16
199
	case "i":
200
	case "x":
201
		size = 64
202
	case "y":
203
		size = 8
204
		isUnsigned = true
205
	case "q":
206
		size = 16
207
		isUnsigned = true
208
	case "u":
209
		isUnsigned = true
210
	case "t":
211
		size = 64
212
		isUnsigned = true
213
	case "d":
214
		d, err := strconv.ParseFloat(s, 64)
215
		if err != nil {
216
			return nil, err
217
		}
218
		return d, nil
219
	default:
220
		return nil, varTypeError{s, sig}
221
	}
222
	base := 10
223
	if strings.HasPrefix(s, "0x") {
224
		base = 16
225
		s = s[2:]
226
	}
227
	if strings.HasPrefix(s, "0") && len(s) != 1 {
228
		base = 8
229
		s = s[1:]
230
	}
231
	if isUnsigned {
232
		i, err := strconv.ParseUint(s, base, size)
233
		if err != nil {
234
			return nil, err
235
		}
236
		var v interface{} = i
237
		switch sig.str {
238
		case "y":
239
			v = byte(i)
240
		case "q":
241
			v = uint16(i)
242
		case "u":
243
			v = uint32(i)
244
		}
245
		return v, nil
246
	}
247
	i, err := strconv.ParseInt(s, base, size)
248
	if err != nil {
249
		return nil, err
250
	}
251
	var v interface{} = i
252
	switch sig.str {
253
	case "n":
254
		v = int16(i)
255
	case "i":
256
		v = int32(i)
257
	}
258
	return v, nil
259
}
260

261
type stringNode struct {
262
	sig Signature
263
	str string      // parsed
264
	val interface{} // has correct type
265
}
266

267
var stringSigSet = sigSet{
268
	Signature{"s"}: true,
269
	Signature{"g"}: true,
270
	Signature{"o"}: true,
271
}
272

273
func (n stringNode) Infer() (Signature, error) {
274
	return Signature{"s"}, nil
275
}
276

277
func (n stringNode) String() string {
278
	return n.str
279
}
280

281
func (n stringNode) Sigs() sigSet {
282
	if n.sig.str != "" {
283
		return sigSet{n.sig: true}
284
	}
285
	return stringSigSet
286
}
287

288
func (n stringNode) Value(sig Signature) (interface{}, error) {
289
	if n.sig.str != "" && n.sig != sig {
290
		return nil, varTypeError{n.str, sig}
291
	}
292
	if n.val != nil {
293
		return n.val, nil
294
	}
295
	switch {
296
	case sig.str == "g":
297
		return Signature{n.str}, nil
298
	case sig.str == "o":
299
		return ObjectPath(n.str), nil
300
	case sig.str == "s":
301
		return n.str, nil
302
	default:
303
		return nil, varTypeError{n.str, sig}
304
	}
305
}
306

307
func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
308
	if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
309
		return nil, fmt.Errorf("invalid type %q for string", sig.str)
310
	}
311
	s, err := varParseString(tok.val)
312
	if err != nil {
313
		return nil, err
314
	}
315
	n := stringNode{str: s}
316
	if sig.str == "" {
317
		return stringNode{str: s}, nil
318
	}
319
	n.sig = sig
320
	switch sig.str {
321
	case "o":
322
		n.val = ObjectPath(s)
323
	case "g":
324
		n.val = Signature{s}
325
	case "s":
326
		n.val = s
327
	}
328
	return n, nil
329
}
330

331
func varParseString(s string) (string, error) {
332
	// quotes are guaranteed to be there
333
	s = s[1 : len(s)-1]
334
	buf := new(bytes.Buffer)
335
	for len(s) != 0 {
336
		r, size := utf8.DecodeRuneInString(s)
337
		if r == utf8.RuneError && size == 1 {
338
			return "", errors.New("invalid UTF-8")
339
		}
340
		s = s[size:]
341
		if r != '\\' {
342
			buf.WriteRune(r)
343
			continue
344
		}
345
		r, size = utf8.DecodeRuneInString(s)
346
		if r == utf8.RuneError && size == 1 {
347
			return "", errors.New("invalid UTF-8")
348
		}
349
		s = s[size:]
350
		switch r {
351
		case 'a':
352
			buf.WriteRune(0x7)
353
		case 'b':
354
			buf.WriteRune(0x8)
355
		case 'f':
356
			buf.WriteRune(0xc)
357
		case 'n':
358
			buf.WriteRune('\n')
359
		case 'r':
360
			buf.WriteRune('\r')
361
		case 't':
362
			buf.WriteRune('\t')
363
		case '\n':
364
		case 'u':
365
			if len(s) < 4 {
366
				return "", errors.New("short unicode escape")
367
			}
368
			r, err := strconv.ParseUint(s[:4], 16, 32)
369
			if err != nil {
370
				return "", err
371
			}
372
			buf.WriteRune(rune(r))
373
			s = s[4:]
374
		case 'U':
375
			if len(s) < 8 {
376
				return "", errors.New("short unicode escape")
377
			}
378
			r, err := strconv.ParseUint(s[:8], 16, 32)
379
			if err != nil {
380
				return "", err
381
			}
382
			buf.WriteRune(rune(r))
383
			s = s[8:]
384
		default:
385
			buf.WriteRune(r)
386
		}
387
	}
388
	return buf.String(), nil
389
}
390

391
var boolSigSet = sigSet{Signature{"b"}: true}
392

393
type boolNode bool
394

395
func (boolNode) Infer() (Signature, error) {
396
	return Signature{"b"}, nil
397
}
398

399
func (b boolNode) String() string {
400
	if b {
401
		return "true"
402
	}
403
	return "false"
404
}
405

406
func (boolNode) Sigs() sigSet {
407
	return boolSigSet
408
}
409

410
func (b boolNode) Value(sig Signature) (interface{}, error) {
411
	if sig.str != "b" {
412
		return nil, varTypeError{b.String(), sig}
413
	}
414
	return bool(b), nil
415
}
416

417
type arrayNode struct {
418
	set      sigSet
419
	children []varNode
420
	val      interface{}
421
}
422

423
func (n arrayNode) Infer() (Signature, error) {
424
	for _, v := range n.children {
425
		csig, err := varInfer(v)
426
		if err != nil {
427
			continue
428
		}
429
		return Signature{"a" + csig.str}, nil
430
	}
431
	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
432
}
433

434
func (n arrayNode) String() string {
435
	s := "["
436
	for i, v := range n.children {
437
		s += v.String()
438
		if i != len(n.children)-1 {
439
			s += ", "
440
		}
441
	}
442
	return s + "]"
443
}
444

445
func (n arrayNode) Sigs() sigSet {
446
	return n.set
447
}
448

449
func (n arrayNode) Value(sig Signature) (interface{}, error) {
450
	if n.set.Empty() {
451
		// no type information whatsoever, so this must be an empty slice
452
		return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
453
	}
454
	if !n.set[sig] {
455
		return nil, varTypeError{n.String(), sig}
456
	}
457
	s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
458
	for i, v := range n.children {
459
		rv, err := v.Value(Signature{sig.str[1:]})
460
		if err != nil {
461
			return nil, err
462
		}
463
		s.Index(i).Set(reflect.ValueOf(rv))
464
	}
465
	return s.Interface(), nil
466
}
467

468
func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
469
	var n arrayNode
470
	if sig.str != "" {
471
		n.set = sigSet{sig: true}
472
	}
473
	if t := p.next(); t.typ == tokArrayEnd {
474
		return n, nil
475
	} else {
476
		p.backup()
477
	}
478
Loop:
479
	for {
480
		t := p.next()
481
		switch t.typ {
482
		case tokEOF:
483
			return nil, io.ErrUnexpectedEOF
484
		case tokError:
485
			return nil, errors.New(t.val)
486
		}
487
		p.backup()
488
		cn, err := varMakeNode(p)
489
		if err != nil {
490
			return nil, err
491
		}
492
		if cset := cn.Sigs(); !cset.Empty() {
493
			if n.set.Empty() {
494
				n.set = cset.ToArray()
495
			} else {
496
				nset := cset.ToArray().Intersect(n.set)
497
				if nset.Empty() {
498
					return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
499
				}
500
				n.set = nset
501
			}
502
		}
503
		n.children = append(n.children, cn)
504
		switch t := p.next(); t.typ {
505
		case tokEOF:
506
			return nil, io.ErrUnexpectedEOF
507
		case tokError:
508
			return nil, errors.New(t.val)
509
		case tokArrayEnd:
510
			break Loop
511
		case tokComma:
512
			continue
513
		default:
514
			return nil, fmt.Errorf("unexpected %q", t.val)
515
		}
516
	}
517
	return n, nil
518
}
519

520
type variantNode struct {
521
	n varNode
522
}
523

524
var variantSet = sigSet{
525
	Signature{"v"}: true,
526
}
527

528
func (variantNode) Infer() (Signature, error) {
529
	return Signature{"v"}, nil
530
}
531

532
func (n variantNode) String() string {
533
	return "<" + n.n.String() + ">"
534
}
535

536
func (variantNode) Sigs() sigSet {
537
	return variantSet
538
}
539

540
func (n variantNode) Value(sig Signature) (interface{}, error) {
541
	if sig.str != "v" {
542
		return nil, varTypeError{n.String(), sig}
543
	}
544
	sig, err := varInfer(n.n)
545
	if err != nil {
546
		return nil, err
547
	}
548
	v, err := n.n.Value(sig)
549
	if err != nil {
550
		return nil, err
551
	}
552
	return MakeVariant(v), nil
553
}
554

555
func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
556
	n, err := varMakeNode(p)
557
	if err != nil {
558
		return nil, err
559
	}
560
	if t := p.next(); t.typ != tokVariantEnd {
561
		return nil, fmt.Errorf("unexpected %q", t.val)
562
	}
563
	vn := variantNode{n}
564
	if sig.str != "" && sig.str != "v" {
565
		return nil, varTypeError{vn.String(), sig}
566
	}
567
	return variantNode{n}, nil
568
}
569

570
type dictEntry struct {
571
	key, val varNode
572
}
573

574
type dictNode struct {
575
	kset, vset sigSet
576
	children   []dictEntry
577
	val        interface{}
578
}
579

580
func (n dictNode) Infer() (Signature, error) {
581
	for _, v := range n.children {
582
		ksig, err := varInfer(v.key)
583
		if err != nil {
584
			continue
585
		}
586
		vsig, err := varInfer(v.val)
587
		if err != nil {
588
			continue
589
		}
590
		return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
591
	}
592
	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
593
}
594

595
func (n dictNode) String() string {
596
	s := "{"
597
	for i, v := range n.children {
598
		s += v.key.String() + ": " + v.val.String()
599
		if i != len(n.children)-1 {
600
			s += ", "
601
		}
602
	}
603
	return s + "}"
604
}
605

606
func (n dictNode) Sigs() sigSet {
607
	r := sigSet{}
608
	for k := range n.kset {
609
		for v := range n.vset {
610
			sig := "a{" + k.str + v.str + "}"
611
			r[Signature{sig}] = true
612
		}
613
	}
614
	return r
615
}
616

617
func (n dictNode) Value(sig Signature) (interface{}, error) {
618
	set := n.Sigs()
619
	if set.Empty() {
620
		// no type information -> empty dict
621
		return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
622
	}
623
	if !set[sig] {
624
		return nil, varTypeError{n.String(), sig}
625
	}
626
	m := reflect.MakeMap(typeFor(sig.str))
627
	ksig := Signature{sig.str[2:3]}
628
	vsig := Signature{sig.str[3 : len(sig.str)-1]}
629
	for _, v := range n.children {
630
		kv, err := v.key.Value(ksig)
631
		if err != nil {
632
			return nil, err
633
		}
634
		vv, err := v.val.Value(vsig)
635
		if err != nil {
636
			return nil, err
637
		}
638
		m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
639
	}
640
	return m.Interface(), nil
641
}
642

643
func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
644
	var n dictNode
645

646
	if sig.str != "" {
647
		if len(sig.str) < 5 {
648
			return nil, fmt.Errorf("invalid signature %q for dict type", sig)
649
		}
650
		ksig := Signature{string(sig.str[2])}
651
		vsig := Signature{sig.str[3 : len(sig.str)-1]}
652
		n.kset = sigSet{ksig: true}
653
		n.vset = sigSet{vsig: true}
654
	}
655
	if t := p.next(); t.typ == tokDictEnd {
656
		return n, nil
657
	} else {
658
		p.backup()
659
	}
660
Loop:
661
	for {
662
		t := p.next()
663
		switch t.typ {
664
		case tokEOF:
665
			return nil, io.ErrUnexpectedEOF
666
		case tokError:
667
			return nil, errors.New(t.val)
668
		}
669
		p.backup()
670
		kn, err := varMakeNode(p)
671
		if err != nil {
672
			return nil, err
673
		}
674
		if kset := kn.Sigs(); !kset.Empty() {
675
			if n.kset.Empty() {
676
				n.kset = kset
677
			} else {
678
				n.kset = kset.Intersect(n.kset)
679
				if n.kset.Empty() {
680
					return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
681
				}
682
			}
683
		}
684
		t = p.next()
685
		switch t.typ {
686
		case tokEOF:
687
			return nil, io.ErrUnexpectedEOF
688
		case tokError:
689
			return nil, errors.New(t.val)
690
		case tokColon:
691
		default:
692
			return nil, fmt.Errorf("unexpected %q", t.val)
693
		}
694
		t = p.next()
695
		switch t.typ {
696
		case tokEOF:
697
			return nil, io.ErrUnexpectedEOF
698
		case tokError:
699
			return nil, errors.New(t.val)
700
		}
701
		p.backup()
702
		vn, err := varMakeNode(p)
703
		if err != nil {
704
			return nil, err
705
		}
706
		if vset := vn.Sigs(); !vset.Empty() {
707
			if n.vset.Empty() {
708
				n.vset = vset
709
			} else {
710
				n.vset = n.vset.Intersect(vset)
711
				if n.vset.Empty() {
712
					return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
713
				}
714
			}
715
		}
716
		n.children = append(n.children, dictEntry{kn, vn})
717
		t = p.next()
718
		switch t.typ {
719
		case tokEOF:
720
			return nil, io.ErrUnexpectedEOF
721
		case tokError:
722
			return nil, errors.New(t.val)
723
		case tokDictEnd:
724
			break Loop
725
		case tokComma:
726
			continue
727
		default:
728
			return nil, fmt.Errorf("unexpected %q", t.val)
729
		}
730
	}
731
	return n, nil
732
}
733

734
type byteStringNode []byte
735

736
var byteStringSet = sigSet{
737
	Signature{"ay"}: true,
738
}
739

740
func (byteStringNode) Infer() (Signature, error) {
741
	return Signature{"ay"}, nil
742
}
743

744
func (b byteStringNode) String() string {
745
	return string(b)
746
}
747

748
func (b byteStringNode) Sigs() sigSet {
749
	return byteStringSet
750
}
751

752
func (b byteStringNode) Value(sig Signature) (interface{}, error) {
753
	if sig.str != "ay" {
754
		return nil, varTypeError{b.String(), sig}
755
	}
756
	return []byte(b), nil
757
}
758

759
func varParseByteString(s string) ([]byte, error) {
760
	// quotes and b at start are guaranteed to be there
761
	b := make([]byte, 0, 1)
762
	s = s[2 : len(s)-1]
763
	for len(s) != 0 {
764
		c := s[0]
765
		s = s[1:]
766
		if c != '\\' {
767
			b = append(b, c)
768
			continue
769
		}
770
		c = s[0]
771
		s = s[1:]
772
		switch c {
773
		case 'a':
774
			b = append(b, 0x7)
775
		case 'b':
776
			b = append(b, 0x8)
777
		case 'f':
778
			b = append(b, 0xc)
779
		case 'n':
780
			b = append(b, '\n')
781
		case 'r':
782
			b = append(b, '\r')
783
		case 't':
784
			b = append(b, '\t')
785
		case 'x':
786
			if len(s) < 2 {
787
				return nil, errors.New("short escape")
788
			}
789
			n, err := strconv.ParseUint(s[:2], 16, 8)
790
			if err != nil {
791
				return nil, err
792
			}
793
			b = append(b, byte(n))
794
			s = s[2:]
795
		case '0':
796
			if len(s) < 3 {
797
				return nil, errors.New("short escape")
798
			}
799
			n, err := strconv.ParseUint(s[:3], 8, 8)
800
			if err != nil {
801
				return nil, err
802
			}
803
			b = append(b, byte(n))
804
			s = s[3:]
805
		default:
806
			b = append(b, c)
807
		}
808
	}
809
	return append(b, 0), nil
810
}
811

812
func varInfer(n varNode) (Signature, error) {
813
	if sig, ok := n.Sigs().Single(); ok {
814
		return sig, nil
815
	}
816
	return n.Infer()
817
}
818

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.