github.com/shaardie/u-root@v4.0.1-0.20190127173353-f24a1c26aa2e+incompatible/pkg/io/uintn.go (about)

     1  // Copyright 2012-2019 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package io
     6  
     7  import (
     8  	"fmt"
     9  	"unsafe"
    10  )
    11  
    12  // UintN is a wrapper around uint types and provides a few io-related
    13  // functions.
    14  type UintN interface {
    15  	// Return size in bytes.
    16  	Size() int64
    17  
    18  	// Return string formatted in hex.
    19  	String() string
    20  
    21  	// Read from given address with native endianess.
    22  	read(addr unsafe.Pointer) error
    23  
    24  	// Write to given address with native endianess.
    25  	write(addr unsafe.Pointer) error
    26  }
    27  
    28  // Uint8 is a wrapper around uint8.
    29  type Uint8 uint8
    30  
    31  // Uint16 is a wrapper around uint16.
    32  type Uint16 uint16
    33  
    34  // Uint32 is a wrapper around uint32.
    35  type Uint32 uint32
    36  
    37  // Uint64 is a wrapper around uint64.
    38  type Uint64 uint64
    39  
    40  // Size of uint8 is 1.
    41  func (u *Uint8) Size() int64 {
    42  	return 1
    43  }
    44  
    45  // Size of uint16 is 2.
    46  func (u *Uint16) Size() int64 {
    47  	return 2
    48  }
    49  
    50  // Size of uint32 is 4.
    51  func (u *Uint32) Size() int64 {
    52  	return 4
    53  }
    54  
    55  // Size of uint64 is 8.
    56  func (u *Uint64) Size() int64 {
    57  	return 8
    58  }
    59  
    60  // String formats a uint8 in hex.
    61  func (u *Uint8) String() string {
    62  	return fmt.Sprintf("%#02x", *u)
    63  }
    64  
    65  // String formats a uint16 in hex.
    66  func (u *Uint16) String() string {
    67  	return fmt.Sprintf("%#04x", *u)
    68  }
    69  
    70  // String formats a uint32 in hex.
    71  func (u *Uint32) String() string {
    72  	return fmt.Sprintf("%#08x", *u)
    73  }
    74  
    75  // String formats a uint64 in hex.
    76  func (u *Uint64) String() string {
    77  	return fmt.Sprintf("%#016x", *u)
    78  }
    79  
    80  func (u *Uint8) read(addr unsafe.Pointer) error {
    81  	*u = Uint8(*(*uint8)(addr)) // TODO: rewrite in Go assembly for ARM
    82  	return nil                  // TODO: catch misalign, segfault, sigbus, ...
    83  }
    84  
    85  func (u *Uint16) read(addr unsafe.Pointer) error {
    86  	*u = Uint16(*(*uint16)(addr)) // TODO: rewrite in Go assembly for ARM
    87  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
    88  }
    89  
    90  func (u *Uint32) read(addr unsafe.Pointer) error {
    91  	*u = Uint32(*(*uint32)(addr)) // TODO: rewrite in Go assembly for ARM
    92  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
    93  }
    94  
    95  func (u *Uint64) read(addr unsafe.Pointer) error {
    96  	// Warning: On arm, this uses two ldr's rather than ldrd.
    97  	*u = Uint64(*(*uint64)(addr)) // TODO: rewrite in Go assembly for ARM
    98  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
    99  }
   100  
   101  func (u *Uint8) write(addr unsafe.Pointer) error {
   102  	*(*uint8)(addr) = uint8(*u) // TODO: rewrite in Go assembly for ARM
   103  	return nil                  // TODO: catch misalign, segfault, sigbus, ...
   104  }
   105  
   106  func (u *Uint16) write(addr unsafe.Pointer) error {
   107  	*(*uint16)(addr) = uint16(*u) // TODO: rewrite in Go assembly for ARM
   108  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   109  }
   110  
   111  func (u *Uint32) write(addr unsafe.Pointer) error {
   112  	*(*uint32)(addr) = uint32(*u) // TODO: rewrite in Go assembly for ARM
   113  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   114  }
   115  
   116  func (u *Uint64) write(addr unsafe.Pointer) error {
   117  	// Warning: On arm, this uses two str's rather than strd.
   118  	*(*uint64)(addr) = uint64(*u) // TODO: rewrite in Go assembly for ARM
   119  	return nil                    // TODO: catch misalign, segfault, sigbus, ...
   120  }