github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/internal/util/mem.go (about)

     1  package util
     2  
     3  import (
     4  	"bytes"
     5  	"math"
     6  
     7  	"github.com/tetratelabs/wazero/api"
     8  )
     9  
    10  func View(mod api.Module, ptr uint32, size uint64) []byte {
    11  	if ptr == 0 {
    12  		panic(NilErr)
    13  	}
    14  	if size > math.MaxUint32 {
    15  		panic(RangeErr)
    16  	}
    17  	if size == 0 {
    18  		return nil
    19  	}
    20  	buf, ok := mod.Memory().Read(ptr, uint32(size))
    21  	if !ok {
    22  		panic(RangeErr)
    23  	}
    24  	return buf
    25  }
    26  
    27  func ReadUint8(mod api.Module, ptr uint32) uint8 {
    28  	if ptr == 0 {
    29  		panic(NilErr)
    30  	}
    31  	v, ok := mod.Memory().ReadByte(ptr)
    32  	if !ok {
    33  		panic(RangeErr)
    34  	}
    35  	return v
    36  }
    37  
    38  func ReadUint32(mod api.Module, ptr uint32) uint32 {
    39  	if ptr == 0 {
    40  		panic(NilErr)
    41  	}
    42  	v, ok := mod.Memory().ReadUint32Le(ptr)
    43  	if !ok {
    44  		panic(RangeErr)
    45  	}
    46  	return v
    47  }
    48  
    49  func WriteUint8(mod api.Module, ptr uint32, v uint8) {
    50  	if ptr == 0 {
    51  		panic(NilErr)
    52  	}
    53  	ok := mod.Memory().WriteByte(ptr, v)
    54  	if !ok {
    55  		panic(RangeErr)
    56  	}
    57  }
    58  
    59  func WriteUint32(mod api.Module, ptr uint32, v uint32) {
    60  	if ptr == 0 {
    61  		panic(NilErr)
    62  	}
    63  	ok := mod.Memory().WriteUint32Le(ptr, v)
    64  	if !ok {
    65  		panic(RangeErr)
    66  	}
    67  }
    68  
    69  func ReadUint64(mod api.Module, ptr uint32) uint64 {
    70  	if ptr == 0 {
    71  		panic(NilErr)
    72  	}
    73  	v, ok := mod.Memory().ReadUint64Le(ptr)
    74  	if !ok {
    75  		panic(RangeErr)
    76  	}
    77  	return v
    78  }
    79  
    80  func WriteUint64(mod api.Module, ptr uint32, v uint64) {
    81  	if ptr == 0 {
    82  		panic(NilErr)
    83  	}
    84  	ok := mod.Memory().WriteUint64Le(ptr, v)
    85  	if !ok {
    86  		panic(RangeErr)
    87  	}
    88  }
    89  
    90  func ReadFloat64(mod api.Module, ptr uint32) float64 {
    91  	return math.Float64frombits(ReadUint64(mod, ptr))
    92  }
    93  
    94  func WriteFloat64(mod api.Module, ptr uint32, v float64) {
    95  	WriteUint64(mod, ptr, math.Float64bits(v))
    96  }
    97  
    98  func ReadString(mod api.Module, ptr, maxlen uint32) string {
    99  	if ptr == 0 {
   100  		panic(NilErr)
   101  	}
   102  	switch maxlen {
   103  	case 0:
   104  		return ""
   105  	case math.MaxUint32:
   106  		// avoid overflow
   107  	default:
   108  		maxlen = maxlen + 1
   109  	}
   110  	mem := mod.Memory()
   111  	buf, ok := mem.Read(ptr, maxlen)
   112  	if !ok {
   113  		buf, ok = mem.Read(ptr, mem.Size()-ptr)
   114  		if !ok {
   115  			panic(RangeErr)
   116  		}
   117  	}
   118  	if i := bytes.IndexByte(buf, 0); i < 0 {
   119  		panic(NoNulErr)
   120  	} else {
   121  		return string(buf[:i])
   122  	}
   123  }
   124  
   125  func WriteBytes(mod api.Module, ptr uint32, b []byte) {
   126  	buf := View(mod, ptr, uint64(len(b)))
   127  	copy(buf, b)
   128  }
   129  
   130  func WriteString(mod api.Module, ptr uint32, s string) {
   131  	buf := View(mod, ptr, uint64(len(s)+1))
   132  	buf[len(s)] = 0
   133  	copy(buf, s)
   134  }