diff options
| author | 2025-03-09 17:47:56 +0100 | |
|---|---|---|
| committer | 2025-12-01 22:08:04 +0100 | |
| commit | b1af8fd87760b34e3ff2fd3bda38f211815a0473 (patch) | |
| tree | 9317fad1a7ec298d7a8d2678e4e422953bbc6f33 /vendor/codeberg.org/gruf/go-structr/runtime.go | |
| parent | [chore] update URLs to forked source (diff) | |
| download | gotosocial-b1af8fd87760b34e3ff2fd3bda38f211815a0473.tar.xz | |
[chore] remove vendor
Diffstat (limited to 'vendor/codeberg.org/gruf/go-structr/runtime.go')
| -rw-r--r-- | vendor/codeberg.org/gruf/go-structr/runtime.go | 294 |
1 files changed, 0 insertions, 294 deletions
diff --git a/vendor/codeberg.org/gruf/go-structr/runtime.go b/vendor/codeberg.org/gruf/go-structr/runtime.go deleted file mode 100644 index 508cd6e4c..000000000 --- a/vendor/codeberg.org/gruf/go-structr/runtime.go +++ /dev/null @@ -1,294 +0,0 @@ -package structr - -import ( - "fmt" - "reflect" - "runtime" - "strings" - "unicode" - "unicode/utf8" - "unsafe" - - "codeberg.org/gruf/go-mangler/v2" - "codeberg.org/gruf/go-xunsafe" -) - -// struct_field contains pre-prepared type -// information about a struct's field member, -// including memory offset and hash function. -type struct_field struct { - - // struct field type mangling - // (i.e. fast serializing) fn. - mangle mangler.Mangler - - // zero value data, used when - // nil encountered during ptr - // offset following. - zero unsafe.Pointer - - // mangled zero value string, - // to check zero value keys. - zerostr string - - // offsets defines whereabouts in - // memory this field is located, - // and after how many dereferences. - offsets []next_offset -} - -// next_offset defines a next offset location -// in a struct_field, first by the number of -// derefences required, then by offset from -// that final memory location. -type next_offset struct { - derefs int - offset uintptr -} - -// get_type_iter returns a prepared xunsafe.TypeIter{} for generic parameter type, -// with flagIndir specifically set as we always take a reference to value type. -func get_type_iter[T any]() xunsafe.TypeIter { - rtype := reflect.TypeOf((*T)(nil)).Elem() - flags := xunsafe.Reflect_flag(xunsafe.Abi_Type_Kind(rtype)) - flags |= xunsafe.Reflect_flagIndir // always comes from unsafe ptr - return xunsafe.ToTypeIter(rtype, flags) -} - -// find_field will search for a struct field with given set of names, -// where names is a len > 0 slice of names account for struct nesting. -func find_field(t xunsafe.TypeIter, names []string) (sfield struct_field, ftype reflect.Type) { - var ( - // is_exported returns whether name is exported - // from a package; can be func or struct field. - is_exported = func(name string) bool { - r, _ := utf8.DecodeRuneInString(name) - return unicode.IsUpper(r) - } - - // pop_name pops the next name from - // the provided slice of field names. - pop_name = func() string { - name := names[0] - names = names[1:] - if !is_exported(name) { - panic(fmt.Sprintf("field is not exported: %s", name)) - } - return name - } - - // field is the iteratively searched - // struct field value in below loop. - field reflect.StructField - ) - - // Take reference - // of parent iter. - o := t - - for len(names) > 0 { - // Pop next name. - name := pop_name() - - var n int - rtype := t.Type - flags := t.Flag - - // Iteratively dereference pointer types. - for rtype.Kind() == reflect.Pointer { - - // If this actual indirect memory, - // increase dereferences counter. - if flags&xunsafe.Reflect_flagIndir != 0 { - n++ - } - - // Get next elem type. - rtype = rtype.Elem() - - // Get next set of dereferenced element type flags. - flags = xunsafe.ReflectPointerElemFlags(flags, rtype) - - // Update type iter info. - t = t.Child(rtype, flags) - } - - // Check for valid struct type. - if rtype.Kind() != reflect.Struct { - panic(fmt.Sprintf("field %s is not struct (or ptr-to): %s", rtype, name)) - } - - // Set offset info. - var off next_offset - off.derefs = n - - var ok bool - - // Look for the next field by name. - field, ok = rtype.FieldByName(name) - if !ok { - panic(fmt.Sprintf("unknown field: %s", name)) - } - - // Set next offset value. - off.offset = field.Offset - sfield.offsets = append(sfield.offsets, off) - - // Calculate value flags, and set next nested field type. - flags = xunsafe.ReflectStructFieldFlags(t.Flag, field.Type) - t = t.Child(field.Type, flags) - } - - // Set final field type. - ftype = t.TypeInfo.Type - - // Get mangler from type info. - sfield.mangle = mangler.Get(t) - - // Calculate zero value string. - zptr := zero_value_ptr(o, sfield.offsets) - zstr := string(sfield.mangle(nil, zptr)) - sfield.zerostr = zstr - sfield.zero = zptr - - return -} - -// zero_value iterates the type contained in TypeIter{} along the given -// next_offset{} values, creating new ptrs where necessary, returning the -// zero reflect.Value{} after fully iterating the next_offset{} slice. -func zero_value(t xunsafe.TypeIter, offsets []next_offset) reflect.Value { - v := reflect.New(t.Type).Elem() - for _, offset := range offsets { - for range offset.derefs { - if v.IsNil() { - new := reflect.New(v.Type().Elem()) - v.Set(new) - } - v = v.Elem() - } - for i := 0; i < v.NumField(); i++ { - if v.Type().Field(i).Offset == offset.offset { - v = v.Field(i) - break - } - } - } - return v -} - -// zero_value_ptr returns the unsafe pointer address of the result of zero_value(). -func zero_value_ptr(t xunsafe.TypeIter, offsets []next_offset) unsafe.Pointer { - return zero_value(t, offsets).Addr().UnsafePointer() -} - -// extract_fields extracts given structfields from the provided value type, -// this is done using predetermined struct field memory offset locations. -func extract_fields(ptr unsafe.Pointer, fields []struct_field) []unsafe.Pointer { - - // Prepare slice of field value pointers. - ptrs := make([]unsafe.Pointer, len(fields)) - if len(ptrs) != len(fields) { - panic(assert("BCE")) - } - - for i, field := range fields { - // loop scope. - fptr := ptr - - for _, offset := range field.offsets { - // Dereference any ptrs to offset. - fptr = deref(fptr, offset.derefs) - if fptr == nil { - break - } - - // Jump forward by offset to next ptr. - fptr = unsafe.Pointer(uintptr(fptr) + - offset.offset) - } - - if fptr == nil { - // Use zero value. - fptr = field.zero - } - - // Set field ptr. - ptrs[i] = fptr - } - - return ptrs -} - -// pkey_field contains pre-prepared type -// information about a primary key struct's -// field member, including memory offset. -type pkey_field struct { - - // zero value data, used when - // nil encountered during ptr - // offset following. - zero unsafe.Pointer - - // offsets defines whereabouts in - // memory this field is located. - offsets []next_offset -} - -// extract_pkey will extract a pointer from 'ptr', to -// the primary key struct field defined by 'field'. -func extract_pkey(ptr unsafe.Pointer, field pkey_field) unsafe.Pointer { - for _, offset := range field.offsets { - - // Dereference any ptrs to offset. - ptr = deref(ptr, offset.derefs) - if ptr == nil { - break - } - - // Jump forward by offset to next ptr. - ptr = unsafe.Pointer(uintptr(ptr) + - offset.offset) - } - - if ptr == nil { - // Use zero value. - ptr = field.zero - } - - return ptr -} - -// deref will dereference ptr 'n' times (or until nil). -func deref(p unsafe.Pointer, n int) unsafe.Pointer { - for ; n > 0; n-- { - if p == nil { - return nil - } - p = *(*unsafe.Pointer)(p) - } - return p -} - -// assert can be called to indicated a block -// of code should not be able to be reached, -// it returns a BUG report with callsite. -func assert(assert string) string { - pcs := make([]uintptr, 1) - _ = runtime.Callers(2, pcs) - funcname := "go-structr" // by default use just our library name - if frames := runtime.CallersFrames(pcs); frames != nil { - frame, _ := frames.Next() - funcname = frame.Function - if i := strings.LastIndexByte(funcname, '/'); i != -1 { - funcname = funcname[i+1:] - } - } - var buf strings.Builder - buf.Grow(32 + len(assert) + len(funcname)) - buf.WriteString("BUG: assertion \"") - buf.WriteString(assert) - buf.WriteString("\" failed in ") - buf.WriteString(funcname) - return buf.String() -} |
