github.com/GuanceCloud/cliutils@v1.1.21/diskcache/pos.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package diskcache
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"encoding/json"
    12  	"fmt"
    13  	"os"
    14  	"path/filepath"
    15  )
    16  
    17  type pos struct {
    18  	Seek int64  `json:"seek"`
    19  	Name []byte `json:"name"`
    20  
    21  	fname string        // where to dump the binary data
    22  	buf   *bytes.Buffer // reused buffer to build the binary data
    23  }
    24  
    25  func (p *pos) String() string {
    26  	return fmt.Sprintf("%s:%d", string(p.Name), p.Seek)
    27  }
    28  
    29  func posFromFile(fname string) (*pos, error) {
    30  	bin, err := os.ReadFile(filepath.Clean(fname))
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	if len(bin) <= 8 {
    36  		return nil, nil
    37  	}
    38  
    39  	var p pos
    40  	if err := p.UnmarshalBinary(bin); err != nil {
    41  		return nil, err
    42  	}
    43  	return &p, nil
    44  }
    45  
    46  func (p *pos) MarshalBinary() ([]byte, error) {
    47  	if p.buf == nil {
    48  		p.buf = new(bytes.Buffer)
    49  	}
    50  
    51  	p.buf.Reset()
    52  
    53  	if err := binary.Write(p.buf, binary.LittleEndian, p.Seek); err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	if _, err := p.buf.Write(p.Name); err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	return p.buf.Bytes(), nil
    62  }
    63  
    64  func (p *pos) UnmarshalBinary(bin []byte) error {
    65  	p.buf = bytes.NewBuffer(bin)
    66  
    67  	if err := binary.Read(p.buf, binary.LittleEndian, &p.Seek); err != nil {
    68  		return err
    69  	}
    70  
    71  	p.Name = p.buf.Bytes()
    72  	return nil
    73  }
    74  
    75  func (p *pos) reset() error {
    76  	p.Seek = -1
    77  	p.Name = nil
    78  	if p.buf != nil {
    79  		p.buf.Reset()
    80  	}
    81  
    82  	return p.dumpFile()
    83  }
    84  
    85  func (p *pos) dumpFile() error {
    86  	if data, err := p.MarshalBinary(); err != nil {
    87  		return err
    88  	} else {
    89  		return os.WriteFile(p.fname, data, 0o600)
    90  	}
    91  }
    92  
    93  // for benchmark.
    94  func (p *pos) dumpJSON() ([]byte, error) {
    95  	j, err := json.Marshal(p)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	return j, nil
   100  }