package srt import ( "math" "sort" ) type Datum struct { seq_num uint32 data []byte next *Datum } type DatumLink struct { queued int root *Datum end *Datum } type chains []*DatumLink func (c chains) Len() (int) { return len(c) } func (c chains) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c chains) Less(i, j int) (bool) { x_1 := c[i].end.seq_num x_2 := c[j].root.seq_num serial_add_limit := uint32(math.Pow(2, 30)) if (x_1 < x_2 && x_2 - x_1 < serial_add_limit) || (x_1 > x_2 && x_1 - x_2 > serial_add_limit) { return true } return false } type DatumStorage struct { main *DatumLink offshoots chains } func (buffer *DatumLink) NewDatum(pkt *Packet) { datum := new(Datum) datum.seq_num = pkt.header_info.(*DataHeader).seq_num datum.data = pkt.cif.([]byte) buffer.queued += 1 buffer.end.next = datum buffer.end = datum } func NewDatumLink(pkt *Packet) (*DatumLink) { buffer := new(DatumLink) root_datum := new(Datum) root_datum.seq_num = pkt.header_info.(*DataHeader).seq_num root_datum.data = pkt.cif.([]byte) buffer.root = root_datum buffer.end = root_datum buffer.queued = 1 return buffer } func NewDatumStorage(packet *Packet) (*DatumStorage) { storage := new(DatumStorage) storage.main = NewDatumLink(packet) return storage } func (storage *DatumStorage) NewDatum(pkt *Packet) { prev_num := (pkt.header_info.(*DataHeader).seq_num - 1) % uint32(math.Pow(2, 31)) if storage.main.end.seq_num == prev_num { storage.main.NewDatum(pkt) } else { for _, v := range storage.offshoots { if v.end.seq_num == prev_num { v.NewDatum(pkt) break } } } } func (buffer *DatumLink) Link(buffer_next *DatumLink) { buffer.end.next = buffer_next.root buffer.end = buffer_next.end buffer.queued += buffer_next.queued } func check_append_serial_next(buffer *DatumLink, buffer_next *DatumLink) (bool) { seq_1 := buffer.end.seq_num seq_2 := (seq_1 + 1) % uint32(math.Pow(2, 31)) if seq_1 == seq_2 { buffer.Link(buffer_next) return true } return false } func (storage *DatumStorage) Relink() { sort.Sort(storage.offshoots) buffer := storage.main i := 0 for i < len(storage.offshoots) { if check_append_serial_next(buffer, storage.offshoots[i]) { storage.offshoots = append(storage.offshoots[:i], storage.offshoots[i + 1:]...) } else { buffer = storage.offshoots[i] i++ } } }