// ZipT is the typed version of Zip.
//
//   - resultSelectorFn is of type "func(TFirst,TSecond)TResult"
//
// NOTE: Zip has better performance than ZipT.
6032
func (q Query) ZipT(q2 Query,
	resultSelectorFn interface{}) Query {
	resultSelectorGenericFunc, err := newGenericFunc(
		"ZipT", "resultSelectorFn", resultSelectorFn,
		simpleParamValidator(newElemTypeSlice(new(genericType), new(genericType)), newElemTypeSlice(new(genericType))),
	)
	if err != nil {
		panic(err)
	}

	resultSelectorFunc := func(item1 interface{}, item2 interface{}) interface{} {
		return resultSelectorGenericFunc.Call(item1, item2)
	}

	return q.Zip(q2, resultSelectorFunc)
}
896607
func Zip(ctx context.Context, src, dst, dstRoot string) (err error) {
	// Create destination file
	var dstFile *os.File
	if dstFile, err = os.Create(dst); err != nil {
		return err
	}
	defer dstFile.Close()

	// Create zip writer
	var zw = zip.NewWriter(dstFile)
	defer zw.Close()

	// Walk
	filepath.Walk(src, func(path string, info os.FileInfo, e1 error) (e2 error) {
		// Process error
		if e1 != nil {
			return e1
		}

		// Init header
		var h *zip.FileHeader
		if h, e2 = zip.FileInfoHeader(info); e2 != nil {
			return
		}

		// Set header info
		h.Name = filepath.Join(dstRoot, strings.TrimPrefix(path, src))
		if info.IsDir() {
			h.Name += "/"
		} else {
			h.Method = zip.Deflate
		}

		// Create writer
		var w io.Writer
		if w, e2 = zw.CreateHeader(h); e2 != nil {
			return
		}

		// If path is dir, stop here
		if info.IsDir() {
			return
		}

		// Open path
		var walkFile *os.File
		if walkFile, e2 = os.Open(path); e2 != nil {
			return
		}
		defer walkFile.Close()

		// Copy
		if _, e2 = astiio.Copy(ctx, walkFile, w); e2 != nil {
			return
		}
		return
	})
	return
}
352297
func ReadZip(f *zip.ReadCloser) (*File, error) {
	defer f.Close()
	return ReadZipReader(&f.Reader)
}
738416
func Unzip(ctx context.Context, src, dst string) (err error) {
	// Clean up on error
	defer func(err *error) {
		if *err != nil || ctx.Err() != nil {
			astilog.Debugf("Removing %s...", dst)
			os.RemoveAll(dst)
		}
	}(&err)

	// Unzipping
	astilog.Debugf("Unzipping %s into %s", src, dst)
	if err = astiarchive.Unzip(ctx, src, dst); err != nil {
		err = errors.Wrapf(err, "unzipping %s into %s failed", src, dst)
		return
	}
	return
}
756437
func (*Zip) CheckExt(filename string) error {
	if !strings.HasSuffix(filename, ".zip") {
		return fmt.Errorf("filename must have a .zip extension")
	}
	return nil
}
718119
func zipExeReaderElf(rda io.ReaderAt, size int64) (*zip.Reader, error) {
	file, err := elf.NewFile(rda)
	if err != nil {
		return nil, err
	}

	var max int64
	for _, sect := range file.Sections {
		if sect.Type == elf.SHT_NOBITS {
			continue
		}

		// Check if this section has a zip file
		if zfile, err := zip.NewReader(sect, int64(sect.Size)); err == nil {
			return zfile, nil
		}

		// Otherwise move end of file pointer
		end := int64(sect.Offset + sect.Size)
		if end > max {
			max = end
		}
	}

	// No zip file within binary, try appended to end
	section := io.NewSectionReader(rda, max, size-max)
	return zip.NewReader(section, section.Size())
}
1127195
func (t Term) Zip(args ...interface{}) Term {
	return constructMethodTerm(t, "Zip", p.Term_ZIP, args, map[string]interface{}{})
}
133516
func Unzip(ctx context.Context, src, dst string) (err error) {
	// Parse src path
	var split = strings.Split(src, ".zip")
	src = split[0] + ".zip"
	var internalPath string
	if len(split) >= 2 {
		internalPath = split[1]
	}

	// Open overall reader
	var r *zip.ReadCloser
	if r, err = zip.OpenReader(src); err != nil {
		return errors.Wrapf(err, "astiarchive: opening overall zip reader on %s failed", src)
	}
	defer r.Close()

	// Loop through files to determine their type
	var dirs, files, symlinks = make(map[string]*zip.File), make(map[string]*zip.File), make(map[string]*zip.File)
	for _, f := range r.File {
		// Validate internal path
		var n = string(os.PathSeparator) + f.Name
		if internalPath != "" && !strings.HasPrefix(n, internalPath) {
			continue
		}
		var p = filepath.Join(dst, strings.TrimPrefix(n, internalPath))

		// Check file type
		if f.FileInfo().Mode()&os.ModeSymlink != 0 {
			symlinks[p] = f
		} else if f.FileInfo().IsDir() {
			dirs[p] = f
		} else {
			files[p] = f
		}
	}

	// Create dirs
	for p, f := range dirs {
		if err = os.MkdirAll(p, f.FileInfo().Mode().Perm()); err != nil {
			return errors.Wrapf(err, "astiarchive: mkdirall %s failed", p)
		}
	}

	// Create files
	for p, f := range files {
		if err = createZipFile(ctx, f, p); err != nil {
			return errors.Wrapf(err, "astiarchive: creating zip file into %s failed", p)
		}
	}

	// Create symlinks
	for p, f := range symlinks {
		if err = createZipSymlink(f, p); err != nil {
			return errors.Wrapf(err, "astiarchive: creating zip symlink into %s failed", p)
		}
	}
	return
}
555601
func (s *CreateScriptInput) SetZipFile(v []byte) *CreateScriptInput {
	s.ZipFile = v
	return s
}
616171
func (z *Zip) Write(f File) error {
	if z.zw == nil {
		return fmt.Errorf("zip archive was not created for writing first")
	}
	if f.FileInfo == nil {
		return fmt.Errorf("no file info")
	}
	if f.FileInfo.Name() == "" {
		return fmt.Errorf("missing file name")
	}

	header, err := zip.FileInfoHeader(f)
	if err != nil {
		return fmt.Errorf("%s: getting header: %v", f.Name(), err)
	}

	if f.IsDir() {
		header.Name += "/" // required - strangely no mention of this in zip spec? but is in godoc...
		header.Method = zip.Store
	} else {
		ext := strings.ToLower(path.Ext(header.Name))
		if _, ok := compressedFormats[ext]; ok && z.SelectiveCompression {
			header.Method = zip.Store
		} else {
			header.Method = zip.Deflate
		}
	}

	writer, err := z.zw.CreateHeader(header)
	if err != nil {
		return fmt.Errorf("%s: making header: %v", f.Name(), err)
	}

	return z.writeFile(f, writer)
}
143376
func IndexSortF(Len int, Less func(i, j int) bool) []int {
	indexes := make([]int, Len)
	for i := range indexes {
		indexes[i] = i
	}
	sort.Sort(InterfaceStruct{
		LenF: func() int {
			return Len
		},
		LessF: func(i, j int) bool {
			return Less(indexes[i], indexes[j])
		},
		SwapF: func(i, j int) {
			indexes[i], indexes[j] = indexes[j], indexes[i]
		},
	})
	return indexes
}
315798
func (a *MinMaxAllocator) AllocateNext() (int, bool, error) {
	a.lock.Lock()
	defer a.lock.Unlock()

	// Fast check if we're out of items
	if a.free <= 0 {
		return 0, false, ErrRangeFull
	}

	// Scan from the minimum until we find a free item
	for i := a.min; i <= a.max; i++ {
		if !a.has(i) {
			a.used[i] = true
			a.free--
			return i, true, nil
		}
	}

	// no free item found, but a.free != 0
	return 0, false, ErrInternal
}
409026
func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
}
1157612
func (g *Graph) ast() {

	if g == nil {
		return
	}

	for _, node := range g.Out {
		if node.ThisString() == TypeExpression {
			node._ast()
		} else {
			node.ast()
		}
	}
}
289400
func CreateFlat(inputPath string, zipPath string) error {
	ctx := context{
		createBaseDir: false,
		zipPath:       zipPath,
	}
	return createZip(inputPath, zipPath, ctx)
}
666900
func Ext(in string) string {
	_, ext := fileAndExt(in, fpb)
	return ext
}
1328847
func zip(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("zip does not accept keyword arguments")
	}
	rows, cols := 0, len(args)
	iters := make([]Iterator, cols)
	defer func() {
		for _, iter := range iters {
			if iter != nil {
				iter.Done()
			}
		}
	}()
	for i, seq := range args {
		it := Iterate(seq)
		if it == nil {
			return nil, fmt.Errorf("zip: argument #%d is not iterable: %s", i+1, seq.Type())
		}
		iters[i] = it
		n := Len(seq)
		if i == 0 || n < rows {
			rows = n // possibly -1
		}
	}
	var result []Value
	if rows >= 0 {
		// length known
		result = make([]Value, rows)
		array := make(Tuple, cols*rows) // allocate a single backing array
		for i := 0; i < rows; i++ {
			tuple := array[:cols:cols]
			array = array[cols:]
			for j, iter := range iters {
				iter.Next(&tuple[j])
			}
			result[i] = tuple
		}
	} else {
		// length not known
	outer:
		for {
			tuple := make(Tuple, cols)
			for i, iter := range iters {
				if !iter.Next(&tuple[i]) {
					break outer
				}
			}
			result = append(result, tuple)
		}
	}
	return NewList(result), nil
}