180 lines
3.2 KiB
Go
180 lines
3.2 KiB
Go
|
package runtime
|
||
|
|
||
|
import (
|
||
|
"unsafe"
|
||
|
)
|
||
|
|
||
|
func malloc(size uint32) unsafe.Pointer __asm__("malloc");
|
||
|
|
||
|
func MemMove(dest, src []byte, n int) {
|
||
|
if dest == nil || src == nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if len(dest) < n || len(src) < n {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
equal := true
|
||
|
for i := 0; i < n; i++ {
|
||
|
if dest[i] != src[i] {
|
||
|
equal = false
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if equal {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for i := 0; i < n; i++ {
|
||
|
dest[i] = src[i]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Memcmp(a, b []byte) int {
|
||
|
lenA := len(a)
|
||
|
lenB := len(b)
|
||
|
minLen := lenA
|
||
|
if lenB < minLen {
|
||
|
minLen = lenB
|
||
|
}
|
||
|
|
||
|
// Преобразуем срезы байтов в указатели на память
|
||
|
ptrA := (*int32)(unsafe.Pointer(&a[0]))
|
||
|
ptrB := (*int32)(unsafe.Pointer(&b[0]))
|
||
|
|
||
|
// Сравниваем по 4 байт (размер int32) за раз
|
||
|
for i := 0; i < minLen/4; i++ {
|
||
|
if *ptrA != *ptrB {
|
||
|
// Если найдены различающиеся байты, возвращаем результат сравнения
|
||
|
if *ptrA < *ptrB {
|
||
|
return -1
|
||
|
} else {
|
||
|
return 1
|
||
|
}
|
||
|
}
|
||
|
ptrA = (*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(ptrA)) + unsafe.Sizeof(*ptrA)))
|
||
|
ptrB = (*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(ptrB)) + unsafe.Sizeof(*ptrB)))
|
||
|
}
|
||
|
|
||
|
// Если длины срезов отличаются, возвращаем результат сравнения длин
|
||
|
if lenA < lenB {
|
||
|
return -1
|
||
|
} else if lenA > lenB {
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func MemEqual32(a, b []byte) bool {
|
||
|
if len(a) != len(b) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(a)/4; i++ {
|
||
|
offset := i * 4
|
||
|
valA := uint32(a[offset])<<24 | uint32(a[offset+1])<<16 | uint32(a[offset+2])<<8 | uint32(a[offset+3])
|
||
|
valB := uint32(b[offset])<<24 | uint32(b[offset+1])<<16 | uint32(b[offset+2])<<8 | uint32(b[offset+3])
|
||
|
|
||
|
if valA != valB {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func MemEqual8(dest, src []byte, n int) bool {
|
||
|
if len(dest) < n || len(src) < n {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for i := 0; i < n; i++ {
|
||
|
if dest[i] != src[i] {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func StrEqual(a, b string) bool {
|
||
|
if len(a) != len(b) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(a); i++ {
|
||
|
if a[i] != b[i] {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func ConcatStrings(strs ...string) string {
|
||
|
totalLen := 0
|
||
|
for _, str := range strs {
|
||
|
totalLen += len(str)
|
||
|
}
|
||
|
|
||
|
result := make([]byte, totalLen)
|
||
|
offset := 0
|
||
|
for _, str := range strs {
|
||
|
copy(result[offset:], []byte(str))
|
||
|
offset += len(str)
|
||
|
}
|
||
|
|
||
|
return string(result)
|
||
|
}
|
||
|
|
||
|
func SliceBytetoString(slice []byte) string {
|
||
|
str := ""
|
||
|
for _, b := range slice {
|
||
|
str += string(b)
|
||
|
}
|
||
|
return str
|
||
|
}
|
||
|
|
||
|
func IntString(n int) string {
|
||
|
if n == 0 {
|
||
|
return "0"
|
||
|
}
|
||
|
|
||
|
var result string
|
||
|
isNegative := false
|
||
|
|
||
|
if n < 0 {
|
||
|
isNegative = true
|
||
|
n = -n
|
||
|
}
|
||
|
|
||
|
for n > 0 {
|
||
|
digit := n % 10
|
||
|
result = string('0'+digit) + result
|
||
|
n /= 10
|
||
|
}
|
||
|
|
||
|
if isNegative {
|
||
|
result = "-" + result
|
||
|
}
|
||
|
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func StringToSliceByte(str string) []byte {
|
||
|
slice := make([]byte, len(str))
|
||
|
for i := 0; i < len(str); i++ {
|
||
|
slice[i] = str[i]
|
||
|
}
|
||
|
return slice
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
func MakeSlice(et *uint32, len, cap int) unsafe.Pointer {
|
||
|
|
||
|
return malloc(0x1000)
|
||
|
}
|