github.com/trim21/go-phpserialize@v0.0.22-0.20240301204449-2fca0319b3f0/internal/encoder/uint_at_string.go (about)

     1  package encoder
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strconv"
     7  	"unsafe"
     8  
     9  	"github.com/trim21/go-phpserialize/internal/runtime"
    10  )
    11  
    12  func compileUintAsString(rt *runtime.Type) (encoder, error) {
    13  	switch rt.Kind() {
    14  	case reflect.Uint8:
    15  		return encodeUint8AsString, nil
    16  	case reflect.Uint16:
    17  		return encodeUint16AsString, nil
    18  	case reflect.Uint32:
    19  		return encodeUint32AsString, nil
    20  	case reflect.Uint64:
    21  		return encodeUint64AsString, nil
    22  	case reflect.Uint:
    23  		return encodeUintAsString, nil
    24  	}
    25  
    26  	panic(fmt.Sprintf("unexpected kind %s", rt.Kind()))
    27  }
    28  
    29  func encodeUint8AsString(buf *Ctx, b []byte, p uintptr) ([]byte, error) {
    30  	value := **(**uint8)(unsafe.Pointer(&p))
    31  	return appendUintAsString(b, uint64(value))
    32  
    33  }
    34  
    35  func encodeUint16AsString(buf *Ctx, b []byte, p uintptr) ([]byte, error) {
    36  	value := **(**uint16)(unsafe.Pointer(&p))
    37  	return appendUintAsString(b, uint64(value))
    38  
    39  }
    40  
    41  func encodeUint32AsString(buf *Ctx, b []byte, p uintptr) ([]byte, error) {
    42  	value := **(**uint32)(unsafe.Pointer(&p))
    43  	return appendUintAsString(b, uint64(value))
    44  
    45  }
    46  
    47  func encodeUint64AsString(buf *Ctx, b []byte, p uintptr) ([]byte, error) {
    48  	value := **(**uint64)(unsafe.Pointer(&p))
    49  	return appendUintAsString(b, uint64(value))
    50  
    51  }
    52  
    53  func encodeUintAsString(buf *Ctx, b []byte, p uintptr) ([]byte, error) {
    54  	value := **(**uint)(unsafe.Pointer(&p))
    55  	return appendUintAsString(b, uint64(value))
    56  }
    57  
    58  func appendUintAsString(b []byte, v uint64) ([]byte, error) {
    59  	b = appendStringHead(b, uintDigitsCount(v))
    60  	b = append(b, '"')
    61  	b = strconv.AppendUint(b, v, 10)
    62  	b = append(b, '"', ';')
    63  	return b, nil
    64  }
    65  
    66  func uintDigitsCount(number uint64) int64 {
    67  	var count int64
    68  	if number == 0 {
    69  		return 1
    70  	}
    71  
    72  	for number != 0 {
    73  		number /= 10
    74  		count += 1
    75  	}
    76  
    77  	return count
    78  }