[VOL-1349] EPON ONU adapter (package B)

Change-Id: I609ba349c429bc7e87c74b66bb1121841f9caef6
diff --git a/vendor/gopkg.in/jcmturner/rpc.v1/ndr/decoder.go b/vendor/gopkg.in/jcmturner/rpc.v1/ndr/decoder.go
new file mode 100644
index 0000000..6157b4e
--- /dev/null
+++ b/vendor/gopkg.in/jcmturner/rpc.v1/ndr/decoder.go
@@ -0,0 +1,393 @@
+// Package ndr provides the ability to unmarshal NDR encoded byte steams into Go data structures
+package ndr
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+)
+
+// Struct tag values
+const (
+	TagConformant = "conformant"
+	TagVarying    = "varying"
+	TagPointer    = "pointer"
+	TagPipe       = "pipe"
+)
+
+// Decoder unmarshals NDR byte stream data into a Go struct representation
+type Decoder struct {
+	r             *bufio.Reader // source of the data
+	size          int           // initial size of bytes in buffer
+	ch            CommonHeader  // NDR common header
+	ph            PrivateHeader // NDR private header
+	conformantMax []uint32      // conformant max values that were moved to the beginning of the structure
+	s             interface{}   // pointer to the structure being populated
+	current       []string      // keeps track of the current field being populated
+}
+
+type deferedPtr struct {
+	v   reflect.Value
+	tag reflect.StructTag
+}
+
+// NewDecoder creates a new instance of a NDR Decoder.
+func NewDecoder(r io.Reader) *Decoder {
+	dec := new(Decoder)
+	dec.r = bufio.NewReader(r)
+	dec.r.Peek(int(commonHeaderBytes)) // For some reason an operation is needed on the buffer to initialise it so Buffered() != 0
+	dec.size = dec.r.Buffered()
+	return dec
+}
+
+// Decode unmarshals the NDR encoded bytes into the pointer of a struct provided.
+func (dec *Decoder) Decode(s interface{}) error {
+	dec.s = s
+	err := dec.readCommonHeader()
+	if err != nil {
+		return err
+	}
+	err = dec.readPrivateHeader()
+	if err != nil {
+		return err
+	}
+	_, err = dec.r.Discard(4) //The next 4 bytes are an RPC unique pointer referent. We just skip these.
+	if err != nil {
+		return Errorf("unable to process byte stream: %v", err)
+	}
+
+	return dec.process(s, reflect.StructTag(""))
+}
+
+func (dec *Decoder) process(s interface{}, tag reflect.StructTag) error {
+	// Scan for conformant fields as their max counts are moved to the beginning
+	// http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagfcjh_37
+	err := dec.scanConformantArrays(s, tag)
+	if err != nil {
+		return err
+	}
+	// Recursively fill the struct fields
+	var localDef []deferedPtr
+	err = dec.fill(s, tag, &localDef)
+	if err != nil {
+		return Errorf("could not decode: %v", err)
+	}
+	// Read any deferred referents associated with pointers
+	for _, p := range localDef {
+		err = dec.process(p.v, p.tag)
+		if err != nil {
+			return fmt.Errorf("could not decode deferred referent: %v", err)
+		}
+	}
+	return nil
+}
+
+// scanConformantArrays scans the structure for embedded conformant fields and captures the maximum element counts for
+// dimensions of the array that are moved to the beginning of the structure.
+func (dec *Decoder) scanConformantArrays(s interface{}, tag reflect.StructTag) error {
+	err := dec.conformantScan(s, tag)
+	if err != nil {
+		return fmt.Errorf("failed to scan for embedded conformant arrays: %v", err)
+	}
+	for i := range dec.conformantMax {
+		dec.conformantMax[i], err = dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not read preceding conformant max count index %d: %v", i, err)
+		}
+	}
+	return nil
+}
+
+// conformantScan inspects the structure's fields for whether they are conformant.
+func (dec *Decoder) conformantScan(s interface{}, tag reflect.StructTag) error {
+	ndrTag := parseTags(tag)
+	if ndrTag.HasValue(TagPointer) {
+		return nil
+	}
+	v := getReflectValue(s)
+	switch v.Kind() {
+	case reflect.Struct:
+		for i := 0; i < v.NumField(); i++ {
+			err := dec.conformantScan(v.Field(i), v.Type().Field(i).Tag)
+			if err != nil {
+				return err
+			}
+		}
+	case reflect.String:
+		if !ndrTag.HasValue(TagConformant) {
+			break
+		}
+		dec.conformantMax = append(dec.conformantMax, uint32(0))
+	case reflect.Slice:
+		if !ndrTag.HasValue(TagConformant) {
+			break
+		}
+		d, t := sliceDimensions(v.Type())
+		for i := 0; i < d; i++ {
+			dec.conformantMax = append(dec.conformantMax, uint32(0))
+		}
+		// For string arrays there is a common max for the strings within the array.
+		if t.Kind() == reflect.String {
+			dec.conformantMax = append(dec.conformantMax, uint32(0))
+		}
+	}
+	return nil
+}
+
+func (dec *Decoder) isPointer(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) (bool, error) {
+	// Pointer so defer filling the referent
+	ndrTag := parseTags(tag)
+	if ndrTag.HasValue(TagPointer) {
+		p, err := dec.readUint32()
+		if err != nil {
+			return true, fmt.Errorf("could not read pointer: %v", err)
+		}
+		ndrTag.delete(TagPointer)
+		if p != 0 {
+			// if pointer is not zero add to the deferred items at end of stream
+			*def = append(*def, deferedPtr{v, ndrTag.StructTag()})
+		}
+		return true, nil
+	}
+	return false, nil
+}
+
+func getReflectValue(s interface{}) (v reflect.Value) {
+	if r, ok := s.(reflect.Value); ok {
+		v = r
+	} else {
+		if reflect.ValueOf(s).Kind() == reflect.Ptr {
+			v = reflect.ValueOf(s).Elem()
+		}
+	}
+	return
+}
+
+// fill populates fields with values from the NDR byte stream.
+func (dec *Decoder) fill(s interface{}, tag reflect.StructTag, localDef *[]deferedPtr) error {
+	v := getReflectValue(s)
+
+	//// Pointer so defer filling the referent
+	ptr, err := dec.isPointer(v, tag, localDef)
+	if err != nil {
+		return fmt.Errorf("could not process struct field(%s): %v", strings.Join(dec.current, "/"), err)
+	}
+	if ptr {
+		return nil
+	}
+
+	// Populate the value from the byte stream
+	switch v.Kind() {
+	case reflect.Struct:
+		dec.current = append(dec.current, v.Type().Name()) //Track the current field being filled
+		// in case struct is a union, track this and the selected union field for efficiency
+		var unionTag reflect.Value
+		var unionField string // field to fill if struct is a union
+		// Go through each field in the struct and recursively fill
+		for i := 0; i < v.NumField(); i++ {
+			fieldName := v.Type().Field(i).Name
+			dec.current = append(dec.current, fieldName) //Track the current field being filled
+			//fmt.Fprintf(os.Stderr, "DEBUG Decoding: %s\n", strings.Join(dec.current, "/"))
+			structTag := v.Type().Field(i).Tag
+			ndrTag := parseTags(structTag)
+
+			// Union handling
+			if !unionTag.IsValid() {
+				// Is this field a union tag?
+				unionTag = dec.isUnion(v.Field(i), structTag)
+			} else {
+				// What is the selected field value of the union if we don't already know
+				if unionField == "" {
+					unionField, err = unionSelectedField(v, unionTag)
+					if err != nil {
+						return fmt.Errorf("could not determine selected union value field for %s with discriminat"+
+							" tag %s: %v", v.Type().Name(), unionTag, err)
+					}
+				}
+				if ndrTag.HasValue(TagUnionField) && fieldName != unionField {
+					// is a union and this field has not been selected so will skip it.
+					dec.current = dec.current[:len(dec.current)-1] //This field has been skipped so remove it from the current field tracker
+					continue
+				}
+			}
+
+			// Check if field is a pointer
+			if v.Field(i).Type().Implements(reflect.TypeOf(new(RawBytes)).Elem()) &&
+				v.Field(i).Type().Kind() == reflect.Slice && v.Field(i).Type().Elem().Kind() == reflect.Uint8 {
+				//field is for rawbytes
+				structTag, err = addSizeToTag(v, v.Field(i), structTag)
+				if err != nil {
+					return fmt.Errorf("could not get rawbytes field(%s) size: %v", strings.Join(dec.current, "/"), err)
+				}
+				ptr, err := dec.isPointer(v.Field(i), structTag, localDef)
+				if err != nil {
+					return fmt.Errorf("could not process struct field(%s): %v", strings.Join(dec.current, "/"), err)
+				}
+				if !ptr {
+					err := dec.readRawBytes(v.Field(i), structTag)
+					if err != nil {
+						return fmt.Errorf("could not fill raw bytes struct field(%s): %v", strings.Join(dec.current, "/"), err)
+					}
+				}
+			} else {
+				err := dec.fill(v.Field(i), structTag, localDef)
+				if err != nil {
+					return fmt.Errorf("could not fill struct field(%s): %v", strings.Join(dec.current, "/"), err)
+				}
+			}
+			dec.current = dec.current[:len(dec.current)-1] //This field has been filled so remove it from the current field tracker
+		}
+		dec.current = dec.current[:len(dec.current)-1] //This field has been filled so remove it from the current field tracker
+	case reflect.Bool:
+		i, err := dec.readBool()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Uint8:
+		i, err := dec.readUint8()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Uint16:
+		i, err := dec.readUint16()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Uint32:
+		i, err := dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Uint64:
+		i, err := dec.readUint64()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Int8:
+		i, err := dec.readInt8()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Int16:
+		i, err := dec.readInt16()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Int32:
+		i, err := dec.readInt32()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Int64:
+		i, err := dec.readInt64()
+		if err != nil {
+			return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.String:
+		ndrTag := parseTags(tag)
+		conformant := ndrTag.HasValue(TagConformant)
+		// strings are always varying so this is assumed without an explicit tag
+		var s string
+		var err error
+		if conformant {
+			s, err = dec.readConformantVaryingString(localDef)
+			if err != nil {
+				return fmt.Errorf("could not fill with conformant varying string: %v", err)
+			}
+		} else {
+			s, err = dec.readVaryingString(localDef)
+			if err != nil {
+				return fmt.Errorf("could not fill with varying string: %v", err)
+			}
+		}
+		v.Set(reflect.ValueOf(s))
+	case reflect.Float32:
+		i, err := dec.readFloat32()
+		if err != nil {
+			return fmt.Errorf("could not fill %v: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Float64:
+		i, err := dec.readFloat64()
+		if err != nil {
+			return fmt.Errorf("could not fill %v: %v", v.Type().Name(), err)
+		}
+		v.Set(reflect.ValueOf(i))
+	case reflect.Array:
+		err := dec.fillFixedArray(v, tag, localDef)
+		if err != nil {
+			return err
+		}
+	case reflect.Slice:
+		if v.Type().Implements(reflect.TypeOf(new(RawBytes)).Elem()) && v.Type().Elem().Kind() == reflect.Uint8 {
+			//field is for rawbytes
+			err := dec.readRawBytes(v, tag)
+			if err != nil {
+				return fmt.Errorf("could not fill raw bytes struct field(%s): %v", strings.Join(dec.current, "/"), err)
+			}
+			break
+		}
+		ndrTag := parseTags(tag)
+		conformant := ndrTag.HasValue(TagConformant)
+		varying := ndrTag.HasValue(TagVarying)
+		if ndrTag.HasValue(TagPipe) {
+			err := dec.fillPipe(v, tag)
+			if err != nil {
+				return err
+			}
+			break
+		}
+		_, t := sliceDimensions(v.Type())
+		if t.Kind() == reflect.String && !ndrTag.HasValue(subStringArrayValue) {
+			// String array
+			err := dec.readStringsArray(v, tag, localDef)
+			if err != nil {
+				return err
+			}
+			break
+		}
+		// varying is assumed as fixed arrays use the Go array type rather than slice
+		if conformant && varying {
+			err := dec.fillConformantVaryingArray(v, tag, localDef)
+			if err != nil {
+				return err
+			}
+		} else if !conformant && varying {
+			err := dec.fillVaryingArray(v, tag, localDef)
+			if err != nil {
+				return err
+			}
+		} else {
+			//default to conformant and not varying
+			err := dec.fillConformantArray(v, tag, localDef)
+			if err != nil {
+				return err
+			}
+		}
+	default:
+		return fmt.Errorf("unsupported type")
+	}
+	return nil
+}
+
+// readBytes returns a number of bytes from the NDR byte stream.
+func (dec *Decoder) readBytes(n int) ([]byte, error) {
+	//TODO make this take an int64 as input to allow for larger values on all systems?
+	b := make([]byte, n, n)
+	m, err := dec.r.Read(b)
+	if err != nil || m != n {
+		return b, fmt.Errorf("error reading bytes from stream: %v", err)
+	}
+	return b, nil
+}