github.com/boki/go-xmp@v1.0.1/models/qt/types.go (about)

     1  // Trimmer Media SDK
     2  //
     3  // Copyright (c) 2013-2016 KIDTSUNAMI
     4  // Author: alex@kidtsunami.com
     5  //
     6  
     7  package qt
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"trimmer.io/go-xmp/xmp"
    16  )
    17  
    18  type LocationRole int
    19  
    20  const (
    21  	LocationRoleShooting  LocationRole = 0
    22  	LocationRoleReal      LocationRole = 1
    23  	LocationRoleFictional LocationRole = 2
    24  )
    25  
    26  type Bool int // 0 no, 1 yes
    27  
    28  func (b Bool) Value() bool {
    29  	return b == 1
    30  }
    31  
    32  // defined to overwrite UnmarshalText, otherwise similar to xmp.AltString
    33  //
    34  type MultilangArray xmp.AltString
    35  
    36  func (x *MultilangArray) UnmarshalText(data []byte) error {
    37  	// TODO: need samples
    38  	return nil
    39  }
    40  
    41  func (x MultilangArray) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error {
    42  	return xmp.MarshalArray(e, node, xmp.AltString(x).Typ(), xmp.AltString(x))
    43  }
    44  
    45  func (x *MultilangArray) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error {
    46  	return xmp.UnmarshalArray(d, node, xmp.AltString(*x).Typ(), (*xmp.AltString)(x))
    47  }
    48  
    49  type Location struct {
    50  	Body      string       `xmp:"qt:Body,attr"`
    51  	Date      xmp.Date     `xmp:"qt:Date,attr"`
    52  	Longitude xmp.GPSCoord `xmp:"qt:Longitude,attr"`
    53  	Latitude  xmp.GPSCoord `xmp:"qt:Latitude,attr"`
    54  	Altitude  float64      `xmp:"qt:Altitude,attr"`
    55  	Name      string       `xmp:"qt:Name,attr"`
    56  	Note      string       `xmp:"qt:Note,attr"`
    57  	Role      LocationRole `xmp:"qt:Role,attr"`
    58  }
    59  
    60  func (x *Location) UnmarshalText(data []byte) error {
    61  	// todo: need sample data
    62  	return nil
    63  }
    64  
    65  type Point struct {
    66  	X int
    67  	Y int
    68  }
    69  
    70  func (x Point) IsZero() bool {
    71  	return x.X == 0 && x.Y == 0
    72  }
    73  
    74  func (x Point) String() string {
    75  	buf := bytes.Buffer{}
    76  	buf.WriteString(strconv.FormatInt(int64(x.X), 10))
    77  	buf.WriteByte(',')
    78  	buf.WriteString(strconv.FormatInt(int64(x.Y), 10))
    79  	return buf.String()
    80  }
    81  
    82  func (x *Point) UnmarshalText(data []byte) error {
    83  	v := string(data)
    84  	f := "%d,%d"
    85  	switch true {
    86  	case strings.Contains(v, "/"):
    87  		f = "%d/%d"
    88  	case strings.Contains(v, ":"):
    89  		f = "%d:%d"
    90  	case strings.Contains(v, " "):
    91  		f = "%d %d"
    92  	case strings.Contains(v, ";"):
    93  		f = "%d;%d"
    94  	}
    95  	p := Point{}
    96  	if _, err := fmt.Sscanf(v, f, &p.X, &p.Y); err != nil {
    97  		return fmt.Errorf("qt: invalid point value '%s': %v", v, err)
    98  	}
    99  	*x = p
   100  	return nil
   101  }
   102  
   103  func (x Point) MarshalText() ([]byte, error) {
   104  	if x.IsZero() {
   105  		return nil, nil
   106  	}
   107  	return []byte(x.String()), nil
   108  }
   109  
   110  type ContentRating struct {
   111  	Standard string `xmp:"qt:Standard,attr"`
   112  	Rating   string `xmp:"qt:Rating,attr"`
   113  	Score    string `xmp:"qt:Score,attr"`
   114  	Reasons  string `xmp:"qt:Reasons,attr"`
   115  }
   116  
   117  func (x ContentRating) IsZero() bool {
   118  	return x.Standard == "" && x.Rating == ""
   119  }
   120  
   121  func (x ContentRating) String() string {
   122  	buf := bytes.Buffer{}
   123  	buf.WriteByte('(')
   124  	buf.WriteString(x.Standard)
   125  	buf.WriteByte('|')
   126  	buf.WriteString(x.Rating)
   127  	buf.WriteByte('|')
   128  	buf.WriteString(x.Score)
   129  	buf.WriteByte('|')
   130  	buf.WriteString(x.Reasons)
   131  	return buf.String()
   132  }
   133  
   134  func (x *ContentRating) UnmarshalText(data []byte) error {
   135  	cr := ContentRating{}
   136  	v := string(data)
   137  	v = strings.TrimSpace(v)
   138  	v = strings.TrimPrefix(v, "(")
   139  	v = strings.TrimSuffix(v, ")")
   140  	for i, s := range strings.Split(v, "|") {
   141  		switch i {
   142  		case 1:
   143  			cr.Standard = s
   144  		case 2:
   145  			cr.Rating = s
   146  		case 3:
   147  			cr.Score = s
   148  		case 4:
   149  			cr.Reasons = s
   150  		}
   151  	}
   152  	*x = cr
   153  	return nil
   154  }
   155  
   156  func (x ContentRating) MarshalText() ([]byte, error) {
   157  	if x.IsZero() {
   158  		return nil, nil
   159  	}
   160  	return []byte(x.String()), nil
   161  }