mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Conver to regular Go vendor + dep tool
This commit is contained in:
+180
@@ -0,0 +1,180 @@
|
||||
// Copyright (c) 2011 Mikkel Krautz
|
||||
// The use of this source code is goverened by a BSD-style
|
||||
// license that can be found in the LICENSE-file.
|
||||
|
||||
package ar
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// A Writer provides sequential writing of an ar archive in BSD format. It does not support
|
||||
// writing in the GNU format, since the GNU-style extended filenames cannot be written sequentially.
|
||||
// The BSD ar format is widely compatible with most modern ar readers out there.
|
||||
//
|
||||
// An ar archive consists of a sequence of files. Call WriteHeader to begin a new file,
|
||||
// and then call Write to supply that file's data, writing at most hdr.Size bytes in total.
|
||||
//
|
||||
// Example:
|
||||
// aw := ar.NewWriter(w)
|
||||
// hdr := new(ar.Header)
|
||||
// hdr.Size = length of data in bytes
|
||||
// // populate other hdr fields as desired
|
||||
// if err := aw.WriteHeader(hdr); err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
// io.Copy(tw, data)
|
||||
// tw.Close()
|
||||
type Writer struct {
|
||||
w io.Writer
|
||||
offset int64
|
||||
dataRemain int64
|
||||
closed bool
|
||||
}
|
||||
|
||||
// NewWriter creates a new Writer writing to w.
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{w, 0, 0, false}
|
||||
}
|
||||
|
||||
// Closes the ar achive, flushing any unwritten data to the underlying writer.
|
||||
func (aw *Writer) Close() error {
|
||||
err := aw.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aw.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flush finishes writing the current file (optional).
|
||||
func (aw *Writer) Flush() error {
|
||||
if aw.closed {
|
||||
return ErrWriteAfterClose
|
||||
}
|
||||
if aw.offset%2 != 0 {
|
||||
_, err := io.WriteString(aw.w, "\n")
|
||||
aw.offset += int64(1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes the current entry in the ar archive. Write returns the error ErrWriteTooLong
|
||||
// if more than hdr.Size bytes are written following a call to WriteHeader.
|
||||
func (aw *Writer) Write(b []byte) (n int, err error) {
|
||||
if aw.closed {
|
||||
return 0, ErrWriteAfterClose
|
||||
}
|
||||
// Overflow check
|
||||
tooLong := false
|
||||
if int64(len(b)) > aw.dataRemain {
|
||||
b = b[0:aw.dataRemain]
|
||||
tooLong = true
|
||||
}
|
||||
n, err = aw.w.Write(b)
|
||||
aw.dataRemain -= int64(n)
|
||||
// Warn if the write would have overflowed the
|
||||
// space set aside for the provided data.
|
||||
if err == nil && tooLong {
|
||||
err = ErrWriteTooLong
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteHeader writes hdr and prepares to accept the file's content. WriteHeader calls Flush to
|
||||
// correctly pad the last written file. Calling after WriteHeader a Close will return ErrWriteAfterClose.
|
||||
func (aw *Writer) WriteHeader(hdr *Header) (err error) {
|
||||
if aw.closed {
|
||||
return ErrWriteAfterClose
|
||||
}
|
||||
|
||||
// Flush previous data write
|
||||
err = aw.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we're at the beginning of the writer, write
|
||||
// the global header.
|
||||
if aw.offset == 0 {
|
||||
nwritten, err := io.WriteString(aw.w, globalHeader)
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
newName string
|
||||
newSize int64
|
||||
)
|
||||
|
||||
longFn := len(hdr.Name) > 15
|
||||
if longFn {
|
||||
newName = bsdLongFileNamePrefix + strconv.Itoa(len(hdr.Name))
|
||||
newSize = hdr.Size + int64(len(hdr.Name))
|
||||
} else {
|
||||
newName = hdr.Name
|
||||
newSize = hdr.Size
|
||||
}
|
||||
|
||||
nwritten, err := io.WriteString(aw.w, encodeArString(newName, 16))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, encodeArString(strconv.FormatInt(hdr.Mtime, 10), 12))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, encodeArString(strconv.Itoa(hdr.Uid), 6))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, encodeArString(strconv.Itoa(hdr.Gid), 6))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, encodeArString(strconv.FormatInt(hdr.Mode, 8), 8))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, encodeArString(strconv.FormatInt(newSize, 10), 10))
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nwritten, err = io.WriteString(aw.w, fileHeaderMagic)
|
||||
aw.offset += int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if longFn {
|
||||
nwritten, err = io.WriteString(aw.w, hdr.Name)
|
||||
aw.offset += int64(nwritten)
|
||||
aw.dataRemain = newSize - int64(nwritten)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
aw.dataRemain = newSize
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user