github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/pkg/shortcut/shortcut.go (about)

     1  // Package shortcut can be used to manipulate files in the .url format (from
     2  // windows). See
     3  // http://www.lyberty.com/encyc/articles/tech/dot_url_format_-_an_unofficial_guide.html
     4  package shortcut
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"io"
    10  )
    11  
    12  // ErrInvalidShortcut is the error when a .url file cannot be parsed.
    13  var ErrInvalidShortcut = errors.New("The file is not in the expected format")
    14  
    15  // Result is the result of the parsing of a .url file.
    16  type Result struct {
    17  	URL string
    18  }
    19  
    20  var (
    21  	section  = []byte("[InternetShortcut]")
    22  	urlField = []byte("URL")
    23  )
    24  
    25  // Parse extracts information from a .url file.
    26  func Parse(r io.Reader) (Result, error) {
    27  	var result Result
    28  	buf, err := io.ReadAll(r)
    29  	if err != nil {
    30  		return result, err
    31  	}
    32  	lines := bytes.Split(buf, []byte{'\n'})
    33  	firstLine := bytes.TrimSuffix(lines[0], []byte{'\r'})
    34  	if len(lines) < 2 || !bytes.Equal(firstLine, section) {
    35  		return result, ErrInvalidShortcut
    36  	}
    37  	for _, line := range lines[1:] {
    38  		line = bytes.TrimSuffix(line, []byte{'\r'})
    39  		parts := bytes.SplitN(line, []byte{'='}, 2)
    40  		if len(parts) == 2 && bytes.Equal(parts[0], urlField) {
    41  			result.URL = string(parts[1])
    42  		}
    43  	}
    44  	return result, nil
    45  }
    46  
    47  // Generate creates the content of a .url file for the given destination URL.
    48  func Generate(url string) []byte {
    49  	u := []byte(url)
    50  	n := len(section) + 2 + len(urlField) + 1 + len(u) + 2
    51  	buf := make([]byte, n)
    52  	i := 0
    53  	copy(buf[i:i+len(section)], section)
    54  	i += len(section)
    55  	buf[i] = '\r'
    56  	i++
    57  	buf[i] = '\n'
    58  	i++
    59  	copy(buf[i:i+len(urlField)], urlField)
    60  	i += len(urlField)
    61  	buf[i] = '='
    62  	i++
    63  	copy(buf[i:i+len(u)], u)
    64  	i += len(u)
    65  	buf[i] = '\r'
    66  	i++
    67  	buf[i] = '\n'
    68  	return buf
    69  }