github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/code.google.com/p/gogoprotobuf/proto/pointer_unsafe_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 // +build !appengine 28 29 // This file contains the implementation of the proto field accesses using package unsafe. 30 31 package proto 32 33 import ( 34 "reflect" 35 "unsafe" 36 ) 37 38 func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} { 39 point := unsafe.Pointer(uintptr(p) + uintptr(f)) 40 r := reflect.NewAt(t, point) 41 return r.Interface() 42 } 43 44 func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} { 45 point := unsafe.Pointer(uintptr(p) + uintptr(f)) 46 r := reflect.NewAt(t, point) 47 if r.Elem().IsNil() { 48 return nil 49 } 50 return r.Elem().Interface() 51 } 52 53 func copyUintPtr(oldptr, newptr uintptr, size int) { 54 for j := 0; j < size; j++ { 55 oldb := (*byte)(unsafe.Pointer(oldptr + uintptr(j))) 56 *(*byte)(unsafe.Pointer(newptr + uintptr(j))) = *oldb 57 } 58 } 59 60 func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { 61 copyUintPtr(uintptr(oldptr), uintptr(newptr), size) 62 } 63 64 func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { 65 size := typ.Elem().Size() 66 oldHeader := structPointer_GetSliceHeader(base, f) 67 newLen := oldHeader.Len + 1 68 slice := reflect.MakeSlice(typ, newLen, newLen) 69 bas := toStructPointer(slice) 70 for i := 0; i < oldHeader.Len; i++ { 71 newElemptr := uintptr(bas) + uintptr(i)*size 72 oldElemptr := oldHeader.Data + uintptr(i)*size 73 copyUintPtr(oldElemptr, newElemptr, int(size)) 74 } 75 76 oldHeader.Data = uintptr(bas) 77 oldHeader.Len = newLen 78 oldHeader.Cap = newLen 79 80 return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size))) 81 } 82 83 // RefBool returns a *bool field in the struct. 84 func structPointer_RefBool(p structPointer, f field) *bool { 85 return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) 86 } 87 88 // RefString returns the address of a string field in the struct. 89 func structPointer_RefString(p structPointer, f field) *string { 90 return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) 91 } 92 93 func structPointer_FieldPointer(p structPointer, f field) structPointer { 94 return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f))) 95 } 96 97 func structPointer_GetRefStructPointer(p structPointer, f field) structPointer { 98 return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))) 99 } 100 101 func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader { 102 return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f))) 103 } 104 105 func structPointer_Add(p structPointer, size field) structPointer { 106 return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size))) 107 } 108 109 func structPointer_Len(p structPointer, f field) int { 110 return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f)))) 111 } 112 113 // refWord32 is the address of a 32-bit value field. 114 type refWord32 *uint32 115 116 func refWord32_IsNil(p refWord32) bool { 117 return p == nil 118 } 119 120 func refWord32_Set(p refWord32, o *Buffer, x uint32) { 121 if len(o.uint32s) == 0 { 122 o.uint32s = make([]uint32, uint32PoolSize) 123 } 124 o.uint32s[0] = x 125 *p = o.uint32s[0] 126 o.uint32s = o.uint32s[1:] 127 } 128 129 func refWord32_Get(p refWord32) uint32 { 130 return *p 131 } 132 133 func structPointer_RefWord32(p structPointer, f field) refWord32 { 134 return refWord32((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) 135 } 136 137 // refWord64 is like refWord32 but for 32-bit values. 138 type refWord64 *uint64 139 140 func refWord64_Set(p refWord64, o *Buffer, x uint64) { 141 if len(o.uint64s) == 0 { 142 o.uint64s = make([]uint64, uint64PoolSize) 143 } 144 o.uint64s[0] = x 145 *p = o.uint64s[0] 146 o.uint64s = o.uint64s[1:] 147 } 148 149 func refWord64_IsNil(p refWord64) bool { 150 return p == nil 151 } 152 153 func refWord64_Get(p refWord64) uint64 { 154 return *p 155 } 156 157 func structPointer_RefWord64(p structPointer, f field) refWord64 { 158 return refWord64((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) 159 }