Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,88 @@
package main
import (
"bufio"
"errors"
"fmt"
"os"
"reflect"
"unsafe"
)
type foobar struct {
Exported int // In Go identifiers that are capitalized are exported,
unexported int // while lowercase identifiers are not.
}
func main() {
obj := foobar{12, 42}
fmt.Println("obj:", obj)
examineAndModify(&obj)
fmt.Println("obj:", obj)
anotherExample()
}
// For simplicity this skips several checks. It assumes the thing in the
// interface is a pointer without checking (v.Kind()==reflect.Ptr),
// it then assumes it is a structure type with two int fields
// (v.Kind()==reflect.Struct, f.Type()==reflect.TypeOf(int(0))).
func examineAndModify(any interface{}) {
v := reflect.ValueOf(any) // get a reflect.Value
v = v.Elem() // dereference the pointer
fmt.Println(" v:", v, "=", v.Interface())
t := v.Type()
// Loop through the struct fields
fmt.Printf(" %3s %-10s %-4s %s\n", "Idx", "Name", "Type", "CanSet")
for i := 0; i < v.NumField(); i++ {
f := v.Field(i) // reflect.Value of the field
fmt.Printf(" %2d: %-10s %-4s %t\n", i,
t.Field(i).Name, f.Type(), f.CanSet())
}
// "Exported", field 0, has CanSet==true so we can do:
v.Field(0).SetInt(16)
// "unexported", field 1, has CanSet==false so the following
// would fail at run-time with:
// panic: reflect: reflect.Value.SetInt using value obtained using unexported field
//v.Field(1).SetInt(43)
// However, we can bypass this restriction with the unsafe
// package once we know what type it is (so we can use the
// correct pointer type, here *int):
vp := v.Field(1).Addr() // Take the fields's address
up := unsafe.Pointer(vp.Pointer()) // … get an int value of the address and convert it "unsafely"
p := (*int)(up) // … and end up with what we want/need
fmt.Printf(" vp has type %-14T = %v\n", vp, vp)
fmt.Printf(" up has type %-14T = %#0x\n", up, up)
fmt.Printf(" p has type %-14T = %v pointing at %v\n", p, p, *p)
*p = 43 // effectively obj.unexported = 43
// or an incr all on one ulgy line:
*(*int)(unsafe.Pointer(v.Field(1).Addr().Pointer()))++
// Note that as-per the package "unsafe" documentation,
// the return value from vp.Pointer *must* be converted to
// unsafe.Pointer in the same expression; the result is fragile.
//
// I.e. it is invalid to do:
// thisIsFragile := vp.Pointer()
// up := unsafe.Pointer(thisIsFragile)
}
// This time we'll use an external package to demonstrate that it's not
// restricted to things defined locally. We'll mess with bufio.Reader's
// interal workings by happening to know they have a non-exported
// "err error" field. Of course future versions of Go may not have this
// field or use it in the same way :).
func anotherExample() {
r := bufio.NewReader(os.Stdin)
// Do the dirty stuff in one ugly and unsafe statement:
errp := (*error)(unsafe.Pointer(
reflect.ValueOf(r).Elem().FieldByName("err").Addr().Pointer()))
*errp = errors.New("unsafely injected error value into bufio inner workings")
_, err := r.ReadByte()
fmt.Println("bufio.ReadByte returned error:", err)
}

View file

@ -0,0 +1,17 @@
link printf
procedure main()
(x := foo(1,2,3)).print() # create and show a foo
printf("Fieldnames of foo x : ") # show fieldnames
every printf(" %i",fieldnames(x)) # __s (self), __m (methods), vars
printf("\n")
printf("var 1 of foo x = %i\n", x.var1) # read var1 from outside x
x.var1 := -1 # change var1 from outside x
x.print() # show we changed it
end
class foo(var1,var2,var3) # class with no set/read methods
method print()
printf("foo var1=%i, var2=%i, var3=%i\n",var1,var2,var3)
end
end