...

Source file src/github.com/godbus/dbus/v5/decoder.go

Documentation: github.com/godbus/dbus/v5

     1  package dbus
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  	"reflect"
     7  )
     8  
     9  type decoder struct {
    10  	in    io.Reader
    11  	order binary.ByteOrder
    12  	pos   int
    13  	fds   []int
    14  }
    15  
    16  // newDecoder returns a new decoder that reads values from in. The input is
    17  // expected to be in the given byte order.
    18  func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
    19  	dec := new(decoder)
    20  	dec.in = in
    21  	dec.order = order
    22  	dec.fds = fds
    23  	return dec
    24  }
    25  
    26  // align aligns the input to the given boundary and panics on error.
    27  func (dec *decoder) align(n int) {
    28  	if dec.pos%n != 0 {
    29  		newpos := (dec.pos + n - 1) & ^(n - 1)
    30  		empty := make([]byte, newpos-dec.pos)
    31  		if _, err := io.ReadFull(dec.in, empty); err != nil {
    32  			panic(err)
    33  		}
    34  		dec.pos = newpos
    35  	}
    36  }
    37  
    38  // Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
    39  func (dec *decoder) binread(v interface{}) {
    40  	if err := binary.Read(dec.in, dec.order, v); err != nil {
    41  		panic(err)
    42  	}
    43  }
    44  
    45  func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
    46  	defer func() {
    47  		var ok bool
    48  		v := recover()
    49  		if err, ok = v.(error); ok {
    50  			if err == io.EOF || err == io.ErrUnexpectedEOF {
    51  				err = FormatError("unexpected EOF")
    52  			}
    53  		}
    54  	}()
    55  	vs = make([]interface{}, 0)
    56  	s := sig.str
    57  	for s != "" {
    58  		err, rem := validSingle(s, &depthCounter{})
    59  		if err != nil {
    60  			return nil, err
    61  		}
    62  		v := dec.decode(s[:len(s)-len(rem)], 0)
    63  		vs = append(vs, v)
    64  		s = rem
    65  	}
    66  	return vs, nil
    67  }
    68  
    69  func (dec *decoder) decode(s string, depth int) interface{} {
    70  	dec.align(alignment(typeFor(s)))
    71  	switch s[0] {
    72  	case 'y':
    73  		var b [1]byte
    74  		if _, err := dec.in.Read(b[:]); err != nil {
    75  			panic(err)
    76  		}
    77  		dec.pos++
    78  		return b[0]
    79  	case 'b':
    80  		i := dec.decode("u", depth).(uint32)
    81  		switch {
    82  		case i == 0:
    83  			return false
    84  		case i == 1:
    85  			return true
    86  		default:
    87  			panic(FormatError("invalid value for boolean"))
    88  		}
    89  	case 'n':
    90  		var i int16
    91  		dec.binread(&i)
    92  		dec.pos += 2
    93  		return i
    94  	case 'i':
    95  		var i int32
    96  		dec.binread(&i)
    97  		dec.pos += 4
    98  		return i
    99  	case 'x':
   100  		var i int64
   101  		dec.binread(&i)
   102  		dec.pos += 8
   103  		return i
   104  	case 'q':
   105  		var i uint16
   106  		dec.binread(&i)
   107  		dec.pos += 2
   108  		return i
   109  	case 'u':
   110  		var i uint32
   111  		dec.binread(&i)
   112  		dec.pos += 4
   113  		return i
   114  	case 't':
   115  		var i uint64
   116  		dec.binread(&i)
   117  		dec.pos += 8
   118  		return i
   119  	case 'd':
   120  		var f float64
   121  		dec.binread(&f)
   122  		dec.pos += 8
   123  		return f
   124  	case 's':
   125  		length := dec.decode("u", depth).(uint32)
   126  		b := make([]byte, int(length)+1)
   127  		if _, err := io.ReadFull(dec.in, b); err != nil {
   128  			panic(err)
   129  		}
   130  		dec.pos += int(length) + 1
   131  		return string(b[:len(b)-1])
   132  	case 'o':
   133  		return ObjectPath(dec.decode("s", depth).(string))
   134  	case 'g':
   135  		length := dec.decode("y", depth).(byte)
   136  		b := make([]byte, int(length)+1)
   137  		if _, err := io.ReadFull(dec.in, b); err != nil {
   138  			panic(err)
   139  		}
   140  		dec.pos += int(length) + 1
   141  		sig, err := ParseSignature(string(b[:len(b)-1]))
   142  		if err != nil {
   143  			panic(err)
   144  		}
   145  		return sig
   146  	case 'v':
   147  		if depth >= 64 {
   148  			panic(FormatError("input exceeds container depth limit"))
   149  		}
   150  		var variant Variant
   151  		sig := dec.decode("g", depth).(Signature)
   152  		if len(sig.str) == 0 {
   153  			panic(FormatError("variant signature is empty"))
   154  		}
   155  		err, rem := validSingle(sig.str, &depthCounter{})
   156  		if err != nil {
   157  			panic(err)
   158  		}
   159  		if rem != "" {
   160  			panic(FormatError("variant signature has multiple types"))
   161  		}
   162  		variant.sig = sig
   163  		variant.value = dec.decode(sig.str, depth+1)
   164  		return variant
   165  	case 'h':
   166  		idx := dec.decode("u", depth).(uint32)
   167  		if int(idx) < len(dec.fds) {
   168  			return UnixFD(dec.fds[idx])
   169  		}
   170  		return UnixFDIndex(idx)
   171  	case 'a':
   172  		if len(s) > 1 && s[1] == '{' {
   173  			ksig := s[2:3]
   174  			vsig := s[3 : len(s)-1]
   175  			v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
   176  			if depth >= 63 {
   177  				panic(FormatError("input exceeds container depth limit"))
   178  			}
   179  			length := dec.decode("u", depth).(uint32)
   180  			// Even for empty maps, the correct padding must be included
   181  			dec.align(8)
   182  			spos := dec.pos
   183  			for dec.pos < spos+int(length) {
   184  				dec.align(8)
   185  				if !isKeyType(v.Type().Key()) {
   186  					panic(InvalidTypeError{v.Type()})
   187  				}
   188  				kv := dec.decode(ksig, depth+2)
   189  				vv := dec.decode(vsig, depth+2)
   190  				v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
   191  			}
   192  			return v.Interface()
   193  		}
   194  		if depth >= 64 {
   195  			panic(FormatError("input exceeds container depth limit"))
   196  		}
   197  		sig := s[1:]
   198  		length := dec.decode("u", depth).(uint32)
   199  		// capacity can be determined only for fixed-size element types
   200  		var capacity int
   201  		if s := sigByteSize(sig); s != 0 {
   202  			capacity = int(length) / s
   203  		}
   204  		v := reflect.MakeSlice(reflect.SliceOf(typeFor(sig)), 0, capacity)
   205  		// Even for empty arrays, the correct padding must be included
   206  		align := alignment(typeFor(s[1:]))
   207  		if len(s) > 1 && s[1] == '(' {
   208  			//Special case for arrays of structs
   209  			//structs decode as a slice of interface{} values
   210  			//but the dbus alignment does not match this
   211  			align = 8
   212  		}
   213  		dec.align(align)
   214  		spos := dec.pos
   215  		for dec.pos < spos+int(length) {
   216  			ev := dec.decode(s[1:], depth+1)
   217  			v = reflect.Append(v, reflect.ValueOf(ev))
   218  		}
   219  		return v.Interface()
   220  	case '(':
   221  		if depth >= 64 {
   222  			panic(FormatError("input exceeds container depth limit"))
   223  		}
   224  		dec.align(8)
   225  		v := make([]interface{}, 0)
   226  		s = s[1 : len(s)-1]
   227  		for s != "" {
   228  			err, rem := validSingle(s, &depthCounter{})
   229  			if err != nil {
   230  				panic(err)
   231  			}
   232  			ev := dec.decode(s[:len(s)-len(rem)], depth+1)
   233  			v = append(v, ev)
   234  			s = rem
   235  		}
   236  		return v
   237  	default:
   238  		panic(SignatureError{Sig: s})
   239  	}
   240  }
   241  
   242  // sigByteSize tries to calculates size of the given signature in bytes.
   243  //
   244  // It returns zero when it can't, for example when it contains non-fixed size
   245  // types such as strings, maps and arrays that require reading of the transmitted
   246  // data, for that we would need to implement the unread method for Decoder first.
   247  func sigByteSize(sig string) int {
   248  	var total int
   249  	for offset := 0; offset < len(sig); {
   250  		switch sig[offset] {
   251  		case 'y':
   252  			total += 1
   253  			offset += 1
   254  		case 'n', 'q':
   255  			total += 2
   256  			offset += 1
   257  		case 'b', 'i', 'u', 'h':
   258  			total += 4
   259  			offset += 1
   260  		case 'x', 't', 'd':
   261  			total += 8
   262  			offset += 1
   263  		case '(':
   264  			i := 1
   265  			depth := 1
   266  			for i < len(sig[offset:]) && depth != 0 {
   267  				if sig[offset+i] == '(' {
   268  					depth++
   269  				} else if sig[offset+i] == ')' {
   270  					depth--
   271  				}
   272  				i++
   273  			}
   274  			s := sigByteSize(sig[offset+1 : offset+i-1])
   275  			if s == 0 {
   276  				return 0
   277  			}
   278  			total += s
   279  			offset += i
   280  		default:
   281  			return 0
   282  		}
   283  	}
   284  	return total
   285  }
   286  
   287  // A FormatError is an error in the wire format.
   288  type FormatError string
   289  
   290  func (e FormatError) Error() string {
   291  	return "dbus: wire format error: " + string(e)
   292  }
   293  

View as plain text