File: index_write.go

package info (click to toggle)
golang-github-biogo-hts 1.1.0%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,660 kB
  • sloc: makefile: 3
file content (122 lines) | stat: -rw-r--r-- 3,336 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright ©2014 The bíogo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package internal

import (
	"encoding/binary"
	"fmt"
	"io"

	"github.com/biogo/hts/bgzf"
)

// WriteIndex writes the Index to the given io.Writer.
func WriteIndex(w io.Writer, idx *Index, typ string) error {
	idx.sort()
	err := writeIndices(w, idx.Refs, typ)
	if err != nil {
		return err
	}
	if idx.Unmapped != nil {
		err = binary.Write(w, binary.LittleEndian, *idx.Unmapped)
	}
	return err
}

func writeIndices(w io.Writer, idx []RefIndex, typ string) error {
	for i := range idx {
		err := writeBins(w, idx[i].Bins, idx[i].Stats, typ)
		if err != nil {
			return err
		}
		err = writeIntervals(w, idx[i].Intervals, typ)
		if err != nil {
			return err
		}
	}
	return nil
}

func writeBins(w io.Writer, bins []Bin, stats *ReferenceStats, typ string) error {
	n := int32(len(bins))
	if stats != nil {
		n++
	}
	err := binary.Write(w, binary.LittleEndian, &n)
	if err != nil {
		return err
	}
	for _, b := range bins {
		err = binary.Write(w, binary.LittleEndian, b.Bin)
		if err != nil {
			return fmt.Errorf("%s: failed to write bin number: %v", typ, err)
		}
		err = writeChunks(w, b.Chunks, typ)
		if err != nil {
			return err
		}
	}
	if stats != nil {
		return writeStats(w, stats, typ)
	}
	return nil
}

func writeChunks(w io.Writer, chunks []bgzf.Chunk, typ string) error {
	err := binary.Write(w, binary.LittleEndian, int32(len(chunks)))
	if err != nil {
		return fmt.Errorf("%s: failed to write bin count: %v", typ, err)
	}
	for _, c := range chunks {
		err = binary.Write(w, binary.LittleEndian, vOffset(c.Begin))
		if err != nil {
			return fmt.Errorf("%s: failed to write chunk begin virtual offset: %v", typ, err)
		}
		err = binary.Write(w, binary.LittleEndian, vOffset(c.End))
		if err != nil {
			return fmt.Errorf("%s: failed to write chunk end virtual offset: %v", typ, err)
		}
	}
	return nil
}

func writeStats(w io.Writer, stats *ReferenceStats, typ string) error {
	var err error
	err = binary.Write(w, binary.LittleEndian, [2]uint32{StatsDummyBin, 2})
	if err != nil {
		return fmt.Errorf("%s: failed to write stats bin header: %v", typ, err)
	}
	err = binary.Write(w, binary.LittleEndian, vOffset(stats.Chunk.Begin))
	if err != nil {
		return fmt.Errorf("%s: failed to write index stats chunk begin virtual offset: %v", typ, err)
	}
	err = binary.Write(w, binary.LittleEndian, vOffset(stats.Chunk.End))
	if err != nil {
		return fmt.Errorf("%s: failed to write index stats chunk end virtual offset: %v", typ, err)
	}
	err = binary.Write(w, binary.LittleEndian, stats.Mapped)
	if err != nil {
		return fmt.Errorf("%s: failed to write index stats mapped count: %v", typ, err)
	}
	err = binary.Write(w, binary.LittleEndian, stats.Unmapped)
	if err != nil {
		return fmt.Errorf("%s: failed to write index stats unmapped count: %v", typ, err)
	}
	return nil
}

func writeIntervals(w io.Writer, offsets []bgzf.Offset, typ string) error {
	err := binary.Write(w, binary.LittleEndian, int32(len(offsets)))
	if err != nil {
		return err
	}
	for _, o := range offsets {
		err := binary.Write(w, binary.LittleEndian, vOffset(o))
		if err != nil {
			return fmt.Errorf("%s: failed to write tile interval virtual offset: %v", typ, err)
		}
	}
	return nil
}