...

Source file src/github.com/dsoprea/go-exif/v3/common/utility.go

Documentation: github.com/dsoprea/go-exif/v3/common

     1  package exifcommon
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/dsoprea/go-logging"
    12  )
    13  
    14  var (
    15  	timeType = reflect.TypeOf(time.Time{})
    16  )
    17  
    18  // DumpBytes prints a list of hex-encoded bytes.
    19  func DumpBytes(data []byte) {
    20  	fmt.Printf("DUMP: ")
    21  	for _, x := range data {
    22  		fmt.Printf("%02x ", x)
    23  	}
    24  
    25  	fmt.Printf("\n")
    26  }
    27  
    28  // DumpBytesClause prints a list like DumpBytes(), but encapsulated in
    29  // "[]byte { ... }".
    30  func DumpBytesClause(data []byte) {
    31  	fmt.Printf("DUMP: ")
    32  
    33  	fmt.Printf("[]byte { ")
    34  
    35  	for i, x := range data {
    36  		fmt.Printf("0x%02x", x)
    37  
    38  		if i < len(data)-1 {
    39  			fmt.Printf(", ")
    40  		}
    41  	}
    42  
    43  	fmt.Printf(" }\n")
    44  }
    45  
    46  // DumpBytesToString returns a stringified list of hex-encoded bytes.
    47  func DumpBytesToString(data []byte) string {
    48  	b := new(bytes.Buffer)
    49  
    50  	for i, x := range data {
    51  		_, err := b.WriteString(fmt.Sprintf("%02x", x))
    52  		log.PanicIf(err)
    53  
    54  		if i < len(data)-1 {
    55  			_, err := b.WriteRune(' ')
    56  			log.PanicIf(err)
    57  		}
    58  	}
    59  
    60  	return b.String()
    61  }
    62  
    63  // DumpBytesClauseToString returns a comma-separated list of hex-encoded bytes.
    64  func DumpBytesClauseToString(data []byte) string {
    65  	b := new(bytes.Buffer)
    66  
    67  	for i, x := range data {
    68  		_, err := b.WriteString(fmt.Sprintf("0x%02x", x))
    69  		log.PanicIf(err)
    70  
    71  		if i < len(data)-1 {
    72  			_, err := b.WriteString(", ")
    73  			log.PanicIf(err)
    74  		}
    75  	}
    76  
    77  	return b.String()
    78  }
    79  
    80  // ExifFullTimestampString produces a string like "2018:11:30 13:01:49" from a
    81  // `time.Time` struct. It will attempt to convert to UTC first.
    82  func ExifFullTimestampString(t time.Time) (fullTimestampPhrase string) {
    83  	t = t.UTC()
    84  
    85  	return fmt.Sprintf("%04d:%02d:%02d %02d:%02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
    86  }
    87  
    88  // ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49" into a UTC
    89  // `time.Time` struct.
    90  func ParseExifFullTimestamp(fullTimestampPhrase string) (timestamp time.Time, err error) {
    91  	defer func() {
    92  		if state := recover(); state != nil {
    93  			err = log.Wrap(state.(error))
    94  		}
    95  	}()
    96  
    97  	parts := strings.Split(fullTimestampPhrase, " ")
    98  	datestampValue, timestampValue := parts[0], parts[1]
    99  
   100  	// Normalize the separators.
   101  	datestampValue = strings.ReplaceAll(datestampValue, "-", ":")
   102  	timestampValue = strings.ReplaceAll(timestampValue, "-", ":")
   103  
   104  	dateParts := strings.Split(datestampValue, ":")
   105  
   106  	year, err := strconv.ParseUint(dateParts[0], 10, 16)
   107  	if err != nil {
   108  		log.Panicf("could not parse year")
   109  	}
   110  
   111  	month, err := strconv.ParseUint(dateParts[1], 10, 8)
   112  	if err != nil {
   113  		log.Panicf("could not parse month")
   114  	}
   115  
   116  	day, err := strconv.ParseUint(dateParts[2], 10, 8)
   117  	if err != nil {
   118  		log.Panicf("could not parse day")
   119  	}
   120  
   121  	timeParts := strings.Split(timestampValue, ":")
   122  
   123  	hour, err := strconv.ParseUint(timeParts[0], 10, 8)
   124  	if err != nil {
   125  		log.Panicf("could not parse hour")
   126  	}
   127  
   128  	minute, err := strconv.ParseUint(timeParts[1], 10, 8)
   129  	if err != nil {
   130  		log.Panicf("could not parse minute")
   131  	}
   132  
   133  	second, err := strconv.ParseUint(timeParts[2], 10, 8)
   134  	if err != nil {
   135  		log.Panicf("could not parse second")
   136  	}
   137  
   138  	timestamp = time.Date(int(year), time.Month(month), int(day), int(hour), int(minute), int(second), 0, time.UTC)
   139  	return timestamp, nil
   140  }
   141  
   142  // IsTime returns true if the value is a `time.Time`.
   143  func IsTime(v interface{}) bool {
   144  
   145  	// TODO(dustin): Add test
   146  
   147  	return reflect.TypeOf(v) == timeType
   148  }
   149  

View as plain text