...

Source file src/github.com/Microsoft/go-winio/backuptar/strconv.go

Documentation: github.com/Microsoft/go-winio/backuptar

     1  //go:build windows
     2  
     3  package backuptar
     4  
     5  import (
     6  	"archive/tar"
     7  	"fmt"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  // Functions copied from https://github.com/golang/go/blob/master/src/archive/tar/strconv.go
    14  // as we need to manage the LIBARCHIVE.creationtime PAXRecord manually.
    15  // Idea taken from containerd which did the same thing.
    16  
    17  // parsePAXTime takes a string of the form %d.%d as described in the PAX
    18  // specification. Note that this implementation allows for negative timestamps,
    19  // which is allowed for by the PAX specification, but not always portable.
    20  func parsePAXTime(s string) (time.Time, error) {
    21  	const maxNanoSecondDigits = 9
    22  
    23  	// Split string into seconds and sub-seconds parts.
    24  	ss, sn := s, ""
    25  	if pos := strings.IndexByte(s, '.'); pos >= 0 {
    26  		ss, sn = s[:pos], s[pos+1:]
    27  	}
    28  
    29  	// Parse the seconds.
    30  	secs, err := strconv.ParseInt(ss, 10, 64)
    31  	if err != nil {
    32  		return time.Time{}, tar.ErrHeader
    33  	}
    34  	if len(sn) == 0 {
    35  		return time.Unix(secs, 0), nil // No sub-second values
    36  	}
    37  
    38  	// Parse the nanoseconds.
    39  	if strings.Trim(sn, "0123456789") != "" {
    40  		return time.Time{}, tar.ErrHeader
    41  	}
    42  	if len(sn) < maxNanoSecondDigits {
    43  		sn += strings.Repeat("0", maxNanoSecondDigits-len(sn)) // Right pad
    44  	} else {
    45  		sn = sn[:maxNanoSecondDigits] // Right truncate
    46  	}
    47  	nsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed
    48  	if len(ss) > 0 && ss[0] == '-' {
    49  		return time.Unix(secs, -1*nsecs), nil // Negative correction
    50  	}
    51  	return time.Unix(secs, nsecs), nil
    52  }
    53  
    54  // formatPAXTime converts ts into a time of the form %d.%d as described in the
    55  // PAX specification. This function is capable of negative timestamps.
    56  func formatPAXTime(ts time.Time) (s string) {
    57  	secs, nsecs := ts.Unix(), ts.Nanosecond()
    58  	if nsecs == 0 {
    59  		return strconv.FormatInt(secs, 10)
    60  	}
    61  
    62  	// If seconds is negative, then perform correction.
    63  	sign := ""
    64  	if secs < 0 {
    65  		sign = "-"             // Remember sign
    66  		secs = -(secs + 1)     // Add a second to secs
    67  		nsecs = -(nsecs - 1e9) // Take that second away from nsecs
    68  	}
    69  	return strings.TrimRight(fmt.Sprintf("%s%d.%09d", sign, secs, nsecs), "0")
    70  }
    71  

View as plain text