github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/extensions_gogo.go (about)

     1  // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
     2  // http://code.google.com/p/gogoprotobuf/gogoproto
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are
     6  // met:
     7  //
     8  //     * Redistributions of source code must retain the above copyright
     9  // notice, this list of conditions and the following disclaimer.
    10  //     * Redistributions in binary form must reproduce the above
    11  // copyright notice, this list of conditions and the following disclaimer
    12  // in the documentation and/or other materials provided with the
    13  // distribution.
    14  //
    15  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    16  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    17  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    18  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    19  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    20  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    21  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    22  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    23  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    24  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    25  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    26  
    27  package proto
    28  
    29  import (
    30  	"bytes"
    31  	"fmt"
    32  	"reflect"
    33  	"sort"
    34  	"strings"
    35  )
    36  
    37  func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool {
    38  	if reflect.ValueOf(pb).IsNil() {
    39  		return ifnotset
    40  	}
    41  	value, err := GetExtension(pb, extension)
    42  	if err != nil {
    43  		return ifnotset
    44  	}
    45  	if value == nil {
    46  		return ifnotset
    47  	}
    48  	if value.(*bool) == nil {
    49  		return ifnotset
    50  	}
    51  	return *(value.(*bool))
    52  }
    53  
    54  func (this *Extension) Equal(that *Extension) bool {
    55  	return bytes.Equal(this.enc, that.enc)
    56  }
    57  
    58  func SizeOfExtensionMap(m map[int32]Extension) (n int) {
    59  	return sizeExtensionMap(m)
    60  }
    61  
    62  type sortableMapElem struct {
    63  	field int32
    64  	ext   Extension
    65  }
    66  
    67  func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {
    68  	s := make(sortableExtensions, 0, len(m))
    69  	for k, v := range m {
    70  		s = append(s, &sortableMapElem{field: k, ext: v})
    71  	}
    72  	return s
    73  }
    74  
    75  type sortableExtensions []*sortableMapElem
    76  
    77  func (this sortableExtensions) Len() int { return len(this) }
    78  
    79  func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }
    80  
    81  func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }
    82  
    83  func (this sortableExtensions) String() string {
    84  	sort.Sort(this)
    85  	ss := make([]string, len(this))
    86  	for i := range this {
    87  		ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext)
    88  	}
    89  	return "map[" + strings.Join(ss, ",") + "]"
    90  }
    91  
    92  func StringFromExtensionsMap(m map[int32]Extension) string {
    93  	return newSortableExtensionsFromMap(m).String()
    94  }
    95  
    96  func StringFromExtensionsBytes(ext []byte) string {
    97  	m, err := BytesToExtensionsMap(ext)
    98  	if err != nil {
    99  		panic(err)
   100  	}
   101  	return StringFromExtensionsMap(m)
   102  }
   103  
   104  func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
   105  	if err := encodeExtensionMap(m); err != nil {
   106  		return 0, err
   107  	}
   108  	keys := make([]int, 0, len(m))
   109  	for k := range m {
   110  		keys = append(keys, int(k))
   111  	}
   112  	sort.Ints(keys)
   113  	for _, k := range keys {
   114  		n += copy(data[n:], m[int32(k)].enc)
   115  	}
   116  	return n, nil
   117  }
   118  
   119  func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
   120  	if m[id].value == nil || m[id].desc == nil {
   121  		return m[id].enc, nil
   122  	}
   123  	if err := encodeExtensionMap(m); err != nil {
   124  		return nil, err
   125  	}
   126  	return m[id].enc, nil
   127  }
   128  
   129  func size(buf []byte, wire int) (int, error) {
   130  	switch wire {
   131  	case WireVarint:
   132  		_, n := DecodeVarint(buf)
   133  		return n, nil
   134  	case WireFixed64:
   135  		return 8, nil
   136  	case WireBytes:
   137  		v, n := DecodeVarint(buf)
   138  		return int(v) + n, nil
   139  	case WireFixed32:
   140  		return 4, nil
   141  	case WireStartGroup:
   142  		offset := 0
   143  		for {
   144  			u, n := DecodeVarint(buf[offset:])
   145  			fwire := int(u & 0x7)
   146  			offset += n
   147  			if fwire == WireEndGroup {
   148  				return offset, nil
   149  			}
   150  			s, err := size(buf[offset:], wire)
   151  			if err != nil {
   152  				return 0, err
   153  			}
   154  			offset += s
   155  		}
   156  	}
   157  	return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire)
   158  }
   159  
   160  func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {
   161  	m := make(map[int32]Extension)
   162  	i := 0
   163  	for i < len(buf) {
   164  		tag, n := DecodeVarint(buf[i:])
   165  		if n <= 0 {
   166  			return nil, fmt.Errorf("unable to decode varint")
   167  		}
   168  		fieldNum := int32(tag >> 3)
   169  		wireType := int(tag & 0x7)
   170  		l, err := size(buf[i+n:], wireType)
   171  		if err != nil {
   172  			return nil, err
   173  		}
   174  		end := i + int(l) + n
   175  		m[int32(fieldNum)] = Extension{enc: buf[i:end]}
   176  		i = end
   177  	}
   178  	return m, nil
   179  }
   180  
   181  func NewExtension(e []byte) Extension {
   182  	ee := Extension{enc: make([]byte, len(e))}
   183  	copy(ee.enc, e)
   184  	return ee
   185  }
   186  
   187  func (this Extension) GoString() string {
   188  	return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
   189  }