You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
7.3 KiB
Go
305 lines
7.3 KiB
Go
/**
|
|
= Creative Commons Lizenzvertrag =
|
|
ebktools von der archium GmbH, Gera ist lizenziert unter einer Creative Commons Namensnennung - Nicht kommerziell - Keine Bearbeitungen 4.0 International Lizenz. (http://creativecommons.org/licenses/by-nc-nd/4.0/deed.de)
|
|
Individuelle über diese Lizenz hinausgehende Berechtigungen können Sie unter https://archium.org erhalten.
|
|
|
|
= Creative Commons License =
|
|
ebktools by archium GmbH, Gera is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. (http://creativecommons.org/licenses/by-nc-nd/4.0/)
|
|
Individual permissions beyond the scope of this license may be available at https://archium.org.
|
|
**/
|
|
package ebkTools
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"math"
|
|
"path"
|
|
"reflect"
|
|
"regexp"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
//Round rundet Zahlen
|
|
func Round(number float64, digits int8) float64 {
|
|
pow := math.Pow(10, float64(digits))
|
|
return math.Floor(number*pow+.5) / pow
|
|
}
|
|
|
|
//Concatstring verbindet zwei Strings mit größerer Performance als "+", prozeduales Verfahren
|
|
func Concatstring(args ...string) string {
|
|
var buffer bytes.Buffer
|
|
for _, v := range args {
|
|
buffer.WriteString(v)
|
|
}
|
|
return buffer.String()
|
|
}
|
|
|
|
//Join verbindet zwei Strings mit größerer Performance als "+", OOP-Verfahren
|
|
func (f *Concatablestring) Join(args ...string) string {
|
|
var buffer bytes.Buffer
|
|
buffer.WriteString(string(*f))
|
|
for _, v := range args {
|
|
buffer.WriteString(v)
|
|
}
|
|
return buffer.String()
|
|
}
|
|
|
|
//Concatablestring ist das Mutter-Objekt für die Join-Methode
|
|
type Concatablestring string
|
|
|
|
//String2args macht aus einem String einen Slice, trennt am Trennzeichen, berücksichtigt aber mit einfachen und doppelten Anführungszeichen eingegrenzte Bereiche
|
|
func String2args(s string) (ss []string) {
|
|
s = regexp.MustCompile(`([\s\p{Zs}]{1,})|('[^']*')|(\"[^\"]*\")`).ReplaceAllString(s, "${0}💇") // Leerzeichen innerhalb von Anführungszeichen sollen nicht ersetzt werden!
|
|
s = regexp.MustCompile(`[\s\p{Zs}💇]{1,}💇`).ReplaceAllString(s, "💇") // Entferne alle Leerzeichen VOR dem 💇; auch doppelte 💇 sollen verschwinden.
|
|
s = strings.Trim(s, "💇")
|
|
ss = strings.Split(s, "💇") // Bereinige die Stringränder, insbesondere das Ende
|
|
for i := 0; i < len(ss); i++ { // Entferne die Anführungszeichen und evtl. Leerzeichen
|
|
ss[i] = strings.Trim(ss[i], `"'`)
|
|
//fmt.Println(ss[i])
|
|
}
|
|
//fmt.Println(ss)
|
|
return // übertrage den Input in ein Array
|
|
}
|
|
|
|
//String2slice macht aus einer mit Kommas oder Leerzeichen getrennten Liste ein Slice
|
|
func String2slice(s string) (ss []string) {
|
|
s = strings.ReplaceAll(s, ",", " ")
|
|
s = strings.ReplaceAll(s, "\n", " ")
|
|
sst := strings.Split(s, " ")
|
|
|
|
for _, v := range sst {
|
|
if v != "" {
|
|
ss = append(ss, v)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
/*
|
|
package main
|
|
|
|
import (
|
|
. "ebkTools/schtrings"
|
|
"fmt"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println(Concatstring("a", "b", "c"))
|
|
|
|
teststring := (Concatablestring)("Anfangswert ")
|
|
|
|
fmt.Println(Join("gefolgt ", "von ", "meinem ", "Text"))
|
|
}
|
|
*/
|
|
|
|
// Funktionen um einzelne Bits innerhalb eines 8-Byte-Blockes (wenn int = int64) zum manipulieren oder abzufragen
|
|
|
|
// SetBit setzt das Bit an Position pos im int-Variable n.
|
|
func SetBit(n int, pos uint) int {
|
|
n |= (1 << pos)
|
|
return n
|
|
}
|
|
|
|
// ClearBit löscht das Bit an Position pos im int-Variable n.
|
|
func ClearBit(n int, pos uint) int {
|
|
mask := ^(1 << pos)
|
|
n &= mask
|
|
return n
|
|
}
|
|
|
|
//HasBit prüft, ob das Bit an Position pos gesetzt ist
|
|
func HasBit(n int, pos uint) bool {
|
|
val := n & (1 << pos)
|
|
return (val > 0)
|
|
}
|
|
|
|
//CodeCaller liefert die Datei und Codezeile der aufrufenden Datei als String zurück
|
|
func CodeCaller() string {
|
|
_, file, line, _ := runtime.Caller(1) // 1, nicht 0; sonst kommt immer Zeile "ebkTools:XX" heraus!
|
|
return path.Base(file) + ":" + strconv.Itoa(line)
|
|
}
|
|
|
|
//Ip4or6 prüft, ob der String eine IPv4 oder IPv6 repräsentiert
|
|
func Ip4or6(s string) uint8 {
|
|
for i := 0; i < len(s); i++ {
|
|
switch s[i] {
|
|
case '.':
|
|
return 4
|
|
case ':':
|
|
return 6
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Find if value is contained by slice and return the position it was found
|
|
func InArray(array interface{}, value interface{}) (exists bool, index int) {
|
|
log.Println("InArray() is deprecated an should be replaced by InSlice()")
|
|
return InSlice(array, value)
|
|
}
|
|
func InSlice(slice interface{}, value interface{}) (exists bool, index int) {
|
|
exists = false
|
|
index = -1
|
|
|
|
switch reflect.TypeOf(slice).Kind() {
|
|
case reflect.Slice:
|
|
s := reflect.ValueOf(slice)
|
|
|
|
for i := 0; i < s.Len(); i++ {
|
|
if reflect.DeepEqual(value, s.Index(i).Interface()) == true {
|
|
index = i
|
|
exists = true
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
//Check if string is inside slice
|
|
func StringInSlice(list *[]string, a string) bool {
|
|
for _, b := range *list {
|
|
if b == a {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Contains tells whether a contains x.
|
|
func SliceContainsString(haystack []string, needle string) int {
|
|
for i, v := range haystack {
|
|
if needle == v {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// All Values in Array are equal
|
|
func CheckSliceEquility(myslice interface{}) bool {
|
|
if reflect.ValueOf(myslice).Len() > 1 {
|
|
return reflect.DeepEqual(
|
|
reflect.ValueOf(myslice).Slice(1, reflect.ValueOf(myslice).Len()).Interface(),
|
|
reflect.ValueOf(myslice).Slice(0, reflect.ValueOf(myslice).Len()-1).Interface())
|
|
} else {
|
|
return true // One single value is always equal to itself
|
|
}
|
|
}
|
|
|
|
// Check error code
|
|
func Check(e error) {
|
|
if e != nil {
|
|
panic(e)
|
|
}
|
|
}
|
|
|
|
// Difference of two []string-Slices
|
|
// Set Difference: A - B
|
|
func StringsDiff(a, b []string) (diff []string) {
|
|
m := make(map[string]bool)
|
|
|
|
for _, item := range b {
|
|
m[item] = true
|
|
}
|
|
|
|
for _, item := range a {
|
|
if _, ok := m[item]; !ok {
|
|
diff = append(diff, item)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
//https://www.golangprograms.com/remove-duplicate-values-from-slice.html
|
|
func SliceIntUnique(intSlice []int) []int {
|
|
keys := make(map[int]bool)
|
|
list := []int{}
|
|
for _, entry := range intSlice {
|
|
if _, value := keys[entry]; !value {
|
|
keys[entry] = true
|
|
list = append(list, entry)
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
|
|
func GeneratorUmlaufListe(start, ende, einsprung int) (umlaufliste []int) {
|
|
for i := einsprung; i <= ende; i++ {
|
|
umlaufliste = append(umlaufliste, i)
|
|
}
|
|
for i := start; i < einsprung; i++ {
|
|
umlaufliste = append(umlaufliste, i)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Dank an https://programming.guide/go/formatting-byte-size-to-human-readable-format.html
|
|
func ByteCountDecimal(b int64) string {
|
|
const unit = 1024
|
|
if b < unit {
|
|
return fmt.Sprintf("%d B", b)
|
|
}
|
|
div, exp := int64(unit), 0
|
|
for n := b / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMGTPE"[exp])
|
|
}
|
|
|
|
func ByteCountBinary(b int64) string {
|
|
const unit = 1024
|
|
if b < unit {
|
|
return fmt.Sprintf("%d B", b)
|
|
}
|
|
div, exp := int64(unit), 0
|
|
for n := b / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp])
|
|
}
|
|
|
|
/*
|
|
const (
|
|
a = "archium"
|
|
b = "archidum"
|
|
c = "archivum"
|
|
)
|
|
|
|
func main() {
|
|
|
|
s := make([]string, 3, 3)
|
|
s = []string{a, b, c}
|
|
|
|
fmt.Println(CommonRunesInStringArray(s))
|
|
}
|
|
|
|
//results in "archi"
|
|
*/
|
|
func CommonRunesInStringArray(sa []string) string {
|
|
var tmpRunes []rune
|
|
|
|
for i, v := range sa[0] {
|
|
good := false
|
|
|
|
for _, w := range sa {
|
|
if v == rune(w[i]) {
|
|
good = true
|
|
} else {
|
|
good = false
|
|
}
|
|
}
|
|
if good {
|
|
tmpRunes = append(tmpRunes, v)
|
|
//fmt.Println(i, string(v))
|
|
}
|
|
}
|
|
return string(tmpRunes)
|
|
}
|