-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon.go
61 lines (51 loc) · 1.58 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Copyright (C) 2014 Jakob Borg. All rights reserved.
// Copyright (C) 2018 Dario Castañé. All rights reserved. Use of this source code
// is governed by an MIT-style license that can be found in the LICENSE file.
package xdr
import (
"fmt"
"reflect"
)
var padBytes = []byte{0, 0, 0}
// Padding returns the number of bytes that should be added to an item of length l
// bytes to conform to the XDR padding standard. This function is used by the
// generated marshalling code.
func Padding(l int) int {
d := l % 4
if d == 0 {
return 0
}
return 4 - d
}
// ElementSizeExceeded returns an error describing the violated size
// constraint. This function is used by the generated marshalling code.
func ElementSizeExceeded(field string, size, limit int) error {
return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit)
}
// Sizer is a value that can return its XDR serialized size.
type Sizer interface {
XDRSize() int
}
// SizeOfSlice returns the XDR encoded size of the given []T. Supported types
// for T are string, []byte and types implementing Sizer. SizeOfSlice
// panics if the parameter is not a slice or if T is not one of the supported
// types. This function is used by the generated marshalling code.
func SizeOfSlice(ss interface{}) int {
l := 0
switch ss := ss.(type) {
case []string:
for _, s := range ss {
l += 4 + len(s) + Padding(len(s))
}
case [][]byte:
for _, s := range ss {
l += 4 + len(s) + Padding(len(s))
}
default:
v := reflect.ValueOf(ss)
for i := 0; i < v.Len(); i++ {
l += v.Index(i).Interface().(Sizer).XDRSize()
}
}
return l
}