ics - unfolder.go
1 package ics
2
3 import (
4 "bytes"
5 "io"
6 )
7
8 type unfolder struct {
9 r io.Reader
10 bufLen int
11 buf [2]byte
12 }
13
14 func (u *unfolder) Read(p []byte) (int, error) {
15 var (
16 m, n int
17 err error
18 )
19 q := p
20 if u.bufLen > 0 {
21 n = copy(p, u.buf[:u.bufLen])
22 if n > 0 {
23 u.buf[0] = u.buf[1]
24 u.bufLen -= n
25 p = p[n:]
26 m += n
27 }
28 }
29 for len(p) > 0 && err == nil {
30 n, err = u.r.Read(p)
31 m += n
32 p = p[:n]
33 var toRead int
34 for {
35 pos := bytes.Index(p, eol[:])
36 if pos == -1 {
37 break
38 }
39 copy(p[pos:], p[pos+3:])
40 p = p[pos:]
41 toRead += 3
42 }
43 p = p[len(p)-toRead:]
44 m -= toRead
45 }
46 q = q[:m]
47 for err == nil {
48 if lq := len(q); lq > 0 && q[lq-1] == '\r' {
49 u.bufLen, err = u.r.Read(u.buf[:])
50 if u.bufLen < 2 {
51 break
52 }
53 if u.buf[0] == '\n' && u.buf[1] == ' ' {
54 m--
55 if err == nil {
56 n, err = u.r.Read(q[lq-1:])
57 m += n
58 u.bufLen = 0
59 }
60 } else {
61 break
62 }
63 } else if lq > 1 && q[lq-2] == '\r' && q[lq-1] == '\n' {
64 u.bufLen, err = u.r.Read(u.buf[:1])
65 if u.bufLen < 1 {
66 break
67 }
68 if u.buf[0] == ' ' {
69 m -= 2
70 if err == nil {
71 n, err = u.Read(q[lq-2:])
72 m += n
73 u.bufLen = 0
74 }
75 } else {
76 break
77 }
78 } else {
79 break
80 }
81 }
82 return m, err
83 }