github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/code.google.com/p/gogoprotobuf/proto/encode_gogo.go (about)

     1  // Extensions for Protocol Buffers to create more go like structures.
     2  //
     3  // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
     4  // http://code.google.com/p/gogoprotobuf/gogoproto
     5  //
     6  // Go support for Protocol Buffers - Google's data interchange format
     7  //
     8  // Copyright 2010 The Go Authors.  All rights reserved.
     9  // http://code.google.com/p/goprotobuf/
    10  //
    11  // Redistribution and use in source and binary forms, with or without
    12  // modification, are permitted provided that the following conditions are
    13  // met:
    14  //
    15  //     * Redistributions of source code must retain the above copyright
    16  // notice, this list of conditions and the following disclaimer.
    17  //     * Redistributions in binary form must reproduce the above
    18  // copyright notice, this list of conditions and the following disclaimer
    19  // in the documentation and/or other materials provided with the
    20  // distribution.
    21  //     * Neither the name of Google Inc. nor the names of its
    22  // contributors may be used to endorse or promote products derived from
    23  // this software without specific prior written permission.
    24  //
    25  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    26  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    27  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    28  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    29  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    30  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    31  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    32  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    33  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    34  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    35  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    36  
    37  package proto
    38  
    39  import (
    40  	"reflect"
    41  )
    42  
    43  type Sizer interface {
    44  	Size() int
    45  }
    46  
    47  // Encode a reference to bool pointer.
    48  func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
    49  	v := structPointer_RefBool(base, p.field)
    50  	if v == nil {
    51  		return ErrNil
    52  	}
    53  	x := 0
    54  	if *v {
    55  		x = 1
    56  	}
    57  	o.buf = append(o.buf, p.tagcode...)
    58  	p.valEnc(o, uint64(x))
    59  	return nil
    60  }
    61  
    62  func size_ref_bool(p *Properties, base structPointer) int {
    63  	v := structPointer_RefBool(base, p.field)
    64  	if v == nil {
    65  		return 0
    66  	}
    67  	return len(p.tagcode) + 1 // each bool takes exactly one byte
    68  }
    69  
    70  // Encode a reference to int32 pointer.
    71  func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
    72  	v := structPointer_RefWord32(base, p.field)
    73  	if refWord32_IsNil(v) {
    74  		return ErrNil
    75  	}
    76  	x := refWord32_Get(v)
    77  	o.buf = append(o.buf, p.tagcode...)
    78  	p.valEnc(o, uint64(x))
    79  	return nil
    80  }
    81  
    82  func size_ref_int32(p *Properties, base structPointer) (n int) {
    83  	v := structPointer_RefWord32(base, p.field)
    84  	if refWord32_IsNil(v) {
    85  		return 0
    86  	}
    87  	x := refWord32_Get(v)
    88  	n += len(p.tagcode)
    89  	n += p.valSize(uint64(x))
    90  	return
    91  }
    92  
    93  // Encode a reference to an int64 pointer.
    94  func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
    95  	v := structPointer_RefWord64(base, p.field)
    96  	if refWord64_IsNil(v) {
    97  		return ErrNil
    98  	}
    99  	x := refWord64_Get(v)
   100  	o.buf = append(o.buf, p.tagcode...)
   101  	p.valEnc(o, x)
   102  	return nil
   103  }
   104  
   105  func size_ref_int64(p *Properties, base structPointer) (n int) {
   106  	v := structPointer_RefWord64(base, p.field)
   107  	if refWord64_IsNil(v) {
   108  		return 0
   109  	}
   110  	x := refWord64_Get(v)
   111  	n += len(p.tagcode)
   112  	n += p.valSize(x)
   113  	return
   114  }
   115  
   116  // Encode a reference to a string pointer.
   117  func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
   118  	v := structPointer_RefString(base, p.field)
   119  	if v == nil {
   120  		return ErrNil
   121  	}
   122  	x := *v
   123  	o.buf = append(o.buf, p.tagcode...)
   124  	o.EncodeStringBytes(x)
   125  	return nil
   126  }
   127  
   128  func size_ref_string(p *Properties, base structPointer) (n int) {
   129  	v := structPointer_RefString(base, p.field)
   130  	if v == nil {
   131  		return 0
   132  	}
   133  	x := *v
   134  	n += len(p.tagcode)
   135  	n += sizeStringBytes(x)
   136  	return
   137  }
   138  
   139  // Encode a reference to a message struct.
   140  func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error {
   141  	var state errorState
   142  	structp := structPointer_GetRefStructPointer(base, p.field)
   143  	if structPointer_IsNil(structp) {
   144  		return ErrNil
   145  	}
   146  
   147  	// Can the object marshal itself?
   148  	if p.isMarshaler {
   149  		m := structPointer_Interface(structp, p.stype).(Marshaler)
   150  		data, err := m.Marshal()
   151  		if err != nil && !state.shouldContinue(err, nil) {
   152  			return err
   153  		}
   154  		o.buf = append(o.buf, p.tagcode...)
   155  		o.EncodeRawBytes(data)
   156  		return nil
   157  	}
   158  
   159  	// need the length before we can write out the message itself,
   160  	// so marshal into a separate byte buffer first.
   161  	obuf := o.buf
   162  	o.buf = o.bufalloc()
   163  
   164  	err := o.enc_struct(p.stype, p.sprop, structp)
   165  
   166  	nbuf := o.buf
   167  	o.buf = obuf
   168  	if err != nil && !state.shouldContinue(err, nil) {
   169  		o.buffree(nbuf)
   170  		return err
   171  	}
   172  	o.buf = append(o.buf, p.tagcode...)
   173  	o.EncodeRawBytes(nbuf)
   174  	o.buffree(nbuf)
   175  	return nil
   176  }
   177  
   178  //TODO this is only copied, please fix this
   179  func size_ref_struct_message(p *Properties, base structPointer) int {
   180  	structp := structPointer_GetRefStructPointer(base, p.field)
   181  	if structPointer_IsNil(structp) {
   182  		return 0
   183  	}
   184  
   185  	// Can the object marshal itself?
   186  	if p.isMarshaler {
   187  		m := structPointer_Interface(structp, p.stype).(Marshaler)
   188  		data, _ := m.Marshal()
   189  		n0 := len(p.tagcode)
   190  		n1 := sizeRawBytes(data)
   191  		return n0 + n1
   192  	}
   193  
   194  	n0 := len(p.tagcode)
   195  	n1 := size_struct(p.stype, p.sprop, structp)
   196  	n2 := sizeVarint(uint64(n1)) // size of encoded length
   197  	return n0 + n1 + n2
   198  }
   199  
   200  // Encode a slice of references to message struct pointers ([]struct).
   201  func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
   202  	var state errorState
   203  	ss := structPointer_GetStructPointer(base, p.field)
   204  	ss1 := structPointer_GetRefStructPointer(ss, field(0))
   205  	size := p.stype.Size()
   206  	l := structPointer_Len(base, p.field)
   207  	for i := 0; i < l; i++ {
   208  		structp := structPointer_Add(ss1, field(uintptr(i)*size))
   209  		if structPointer_IsNil(structp) {
   210  			return ErrRepeatedHasNil
   211  		}
   212  
   213  		// Can the object marshal itself?
   214  		if p.isMarshaler {
   215  			m := structPointer_Interface(structp, p.stype).(Marshaler)
   216  			data, err := m.Marshal()
   217  			if err != nil && !state.shouldContinue(err, nil) {
   218  				return err
   219  			}
   220  			o.buf = append(o.buf, p.tagcode...)
   221  			o.EncodeRawBytes(data)
   222  			continue
   223  		}
   224  
   225  		obuf := o.buf
   226  		o.buf = o.bufalloc()
   227  
   228  		err := o.enc_struct(p.stype, p.sprop, structp)
   229  
   230  		nbuf := o.buf
   231  		o.buf = obuf
   232  		if err != nil && !state.shouldContinue(err, nil) {
   233  			o.buffree(nbuf)
   234  			if err == ErrNil {
   235  				return ErrRepeatedHasNil
   236  			}
   237  			return err
   238  		}
   239  		o.buf = append(o.buf, p.tagcode...)
   240  		o.EncodeRawBytes(nbuf)
   241  
   242  		o.buffree(nbuf)
   243  	}
   244  	return nil
   245  }
   246  
   247  //TODO this is only copied, please fix this
   248  func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
   249  	ss := structPointer_GetStructPointer(base, p.field)
   250  	ss1 := structPointer_GetRefStructPointer(ss, field(0))
   251  	size := p.stype.Size()
   252  	l := structPointer_Len(base, p.field)
   253  	n += l * len(p.tagcode)
   254  	for i := 0; i < l; i++ {
   255  		structp := structPointer_Add(ss1, field(uintptr(i)*size))
   256  		if structPointer_IsNil(structp) {
   257  			return // return the size up to this point
   258  		}
   259  
   260  		// Can the object marshal itself?
   261  		if p.isMarshaler {
   262  			m := structPointer_Interface(structp, p.stype).(Marshaler)
   263  			data, _ := m.Marshal()
   264  			n += len(p.tagcode)
   265  			n += sizeRawBytes(data)
   266  			continue
   267  		}
   268  
   269  		n0 := size_struct(p.stype, p.sprop, structp)
   270  		n1 := sizeVarint(uint64(n0)) // size of encoded length
   271  		n += n0 + n1
   272  	}
   273  	return
   274  }
   275  
   276  func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error {
   277  	i := structPointer_InterfaceRef(base, p.field, p.ctype)
   278  	if i == nil {
   279  		return ErrNil
   280  	}
   281  	custom := i.(Marshaler)
   282  	data, err := custom.Marshal()
   283  	if err != nil {
   284  		return err
   285  	}
   286  	if data == nil {
   287  		return ErrNil
   288  	}
   289  	o.buf = append(o.buf, p.tagcode...)
   290  	o.EncodeRawBytes(data)
   291  	return nil
   292  }
   293  
   294  func size_custom_bytes(p *Properties, base structPointer) (n int) {
   295  	n += len(p.tagcode)
   296  	i := structPointer_InterfaceRef(base, p.field, p.ctype)
   297  	if i == nil {
   298  		return 0
   299  	}
   300  	custom := i.(Marshaler)
   301  	data, _ := custom.Marshal()
   302  	n += sizeRawBytes(data)
   303  	return
   304  }
   305  
   306  func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error {
   307  	custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler)
   308  	data, err := custom.Marshal()
   309  	if err != nil {
   310  		return err
   311  	}
   312  	if data == nil {
   313  		return ErrNil
   314  	}
   315  	o.buf = append(o.buf, p.tagcode...)
   316  	o.EncodeRawBytes(data)
   317  	return nil
   318  }
   319  
   320  func size_custom_ref_bytes(p *Properties, base structPointer) (n int) {
   321  	n += len(p.tagcode)
   322  	i := structPointer_InterfaceAt(base, p.field, p.ctype)
   323  	if i == nil {
   324  		return 0
   325  	}
   326  	custom := i.(Marshaler)
   327  	data, _ := custom.Marshal()
   328  	n += sizeRawBytes(data)
   329  	return
   330  }
   331  
   332  func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error {
   333  	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
   334  	if inter == nil {
   335  		return ErrNil
   336  	}
   337  	slice := reflect.ValueOf(inter)
   338  	l := slice.Len()
   339  	for i := 0; i < l; i++ {
   340  		v := slice.Index(i)
   341  		custom := v.Interface().(Marshaler)
   342  		data, err := custom.Marshal()
   343  		if err != nil {
   344  			return err
   345  		}
   346  		o.buf = append(o.buf, p.tagcode...)
   347  		o.EncodeRawBytes(data)
   348  	}
   349  	return nil
   350  }
   351  
   352  func size_custom_slice_bytes(p *Properties, base structPointer) (n int) {
   353  	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
   354  	if inter == nil {
   355  		return 0
   356  	}
   357  	slice := reflect.ValueOf(inter)
   358  	l := slice.Len()
   359  	n += l * len(p.tagcode)
   360  	for i := 0; i < l; i++ {
   361  		v := slice.Index(i)
   362  		custom := v.Interface().(Marshaler)
   363  		data, _ := custom.Marshal()
   364  		n += sizeRawBytes(data)
   365  	}
   366  	return
   367  }