Slice returns a new LinkBuffer, which is a zero-copy slice of this LinkBuffer, and only holds the ability of Reader. Slice will automatically execute a Release.
(n int)
| 374 | // |
| 375 | // Slice will automatically execute a Release. |
| 376 | func (b *UnsafeLinkBuffer) Slice(n int) (r Reader, err error) { |
| 377 | if n <= 0 { |
| 378 | return NewLinkBuffer(0), nil |
| 379 | } |
| 380 | // check whether enough or not. |
| 381 | if b.Len() < n { |
| 382 | return r, fmt.Errorf("link buffer readv[%d] not enough", n) |
| 383 | } |
| 384 | b.recalLen(-n) // re-cal length |
| 385 | |
| 386 | // just use for range |
| 387 | p := new(LinkBuffer) |
| 388 | p.length = int64(n) |
| 389 | |
| 390 | defer func() { |
| 391 | // set to read-only |
| 392 | p.flush = p.flush.next |
| 393 | p.write = p.flush |
| 394 | }() |
| 395 | |
| 396 | // single node |
| 397 | if b.isSingleNode(n) { |
| 398 | b.read.setFlag(flagReadExposed) |
| 399 | node := b.read.Refer(n) |
| 400 | p.head, p.read, p.flush = node, node, node |
| 401 | return p, nil |
| 402 | } |
| 403 | // multiple nodes |
| 404 | l := b.read.Len() |
| 405 | b.read.setFlag(flagReadExposed) |
| 406 | node := b.read.Refer(l) |
| 407 | b.read = b.read.next |
| 408 | |
| 409 | p.head, p.read, p.flush = node, node, node |
| 410 | for ack := n - l; ack > 0; ack = ack - l { |
| 411 | l = b.read.Len() |
| 412 | if l >= ack { |
| 413 | b.read.setFlag(flagReadExposed) |
| 414 | p.flush.next = b.read.Refer(ack) |
| 415 | p.flush = p.flush.next |
| 416 | break |
| 417 | } else if l > 0 { |
| 418 | b.read.setFlag(flagReadExposed) |
| 419 | p.flush.next = b.read.Refer(l) |
| 420 | p.flush = p.flush.next |
| 421 | } |
| 422 | b.read = b.read.next |
| 423 | } |
| 424 | return p, b.Release() |
| 425 | } |
| 426 | |
| 427 | // ------------------------------------------ implement zero-copy writer ------------------------------------------ |
| 428 |
nothing calls this directly
no test coverage detected