Hex Artifact Content

Artifact 9da21d39e02ab22e8ce1d0b455519fe17b235e4d:


0000: 2f 2f 20 50 61 63 6b 61 67 65 20 69 6f 75 74 69  // Package iouti
0010: 6c 20 63 6f 6e 74 61 69 6e 73 20 76 61 72 69 6f  l contains vario
0020: 75 73 20 63 6f 6e 73 74 72 75 63 74 73 20 66 6f  us constructs fo
0030: 72 20 69 6f 20 6f 70 65 72 61 74 69 6f 6e 73 2e  r io operations.
0040: 0a 70 61 63 6b 61 67 65 20 69 6f 75 74 69 6c 0a  .package ioutil.
0050: 0a 69 6d 70 6f 72 74 20 28 0a 09 22 69 6f 22 0a  .import (.."io".
0060: 29 0a 0a 2f 2f 20 41 6e 20 66 75 6e 63 74 69 6f  )..// An functio
0070: 6e 20 61 6c 69 61 73 20 74 79 70 65 20 74 68 61  n alias type tha
0080: 74 20 69 6d 70 6c 65 6d 65 6e 74 73 20 69 6f 2e  t implements io.
0090: 57 72 69 74 65 72 2e 0a 74 79 70 65 20 57 72 69  Writer..type Wri
00a0: 74 65 72 46 75 6e 63 20 66 75 6e 63 28 5b 5d 62  terFunc func([]b
00b0: 79 74 65 29 20 28 69 6e 74 2c 20 65 72 72 6f 72  yte) (int, error
00c0: 29 0a 0a 2f 2f 20 44 65 6c 65 67 61 74 65 73 20  )..// Delegates 
00d0: 74 68 65 20 63 61 6c 6c 20 74 6f 20 74 68 65 20  the call to the 
00e0: 57 72 69 74 65 72 46 75 6e 63 20 77 68 69 6c 65  WriterFunc while
00f0: 20 69 6d 70 6c 65 6d 65 6e 74 69 6e 67 20 69 6f   implementing io
0100: 2e 57 72 69 74 65 72 2e 0a 66 75 6e 63 20 28 77  .Writer..func (w
0110: 20 57 72 69 74 65 72 46 75 6e 63 29 20 57 72 69   WriterFunc) Wri
0120: 74 65 28 62 20 5b 5d 62 79 74 65 29 20 28 69 6e  te(b []byte) (in
0130: 74 2c 20 65 72 72 6f 72 29 20 7b 0a 09 72 65 74  t, error) {..ret
0140: 75 72 6e 20 77 28 62 29 0a 7d 0a 0a 2f 2f 20 41  urn w(b).}..// A
0150: 6e 20 66 75 6e 63 74 69 6f 6e 20 61 6c 69 61 73  n function alias
0160: 20 74 79 70 65 20 74 68 61 74 20 69 6d 70 6c 65   type that imple
0170: 6d 65 6e 74 73 20 69 6f 2e 52 65 61 64 65 72 2e  ments io.Reader.
0180: 0a 74 79 70 65 20 52 65 61 64 65 72 46 75 6e 63  .type ReaderFunc
0190: 20 66 75 6e 63 28 5b 5d 62 79 74 65 29 20 28 69   func([]byte) (i
01a0: 6e 74 2c 20 65 72 72 6f 72 29 0a 0a 2f 2f 20 44  nt, error)..// D
01b0: 65 6c 65 67 61 74 65 73 20 74 68 65 20 63 61 6c  elegates the cal
01c0: 6c 20 74 6f 20 74 68 65 20 57 72 69 74 65 72 46  l to the WriterF
01d0: 75 6e 63 20 77 68 69 6c 65 20 69 6d 70 6c 65 6d  unc while implem
01e0: 65 6e 74 69 6e 67 20 69 6f 2e 52 65 61 64 65 72  enting io.Reader
01f0: 2e 0a 66 75 6e 63 20 28 72 20 52 65 61 64 65 72  ..func (r Reader
0200: 46 75 6e 63 29 20 52 65 61 64 28 62 20 5b 5d 62  Func) Read(b []b
0210: 79 74 65 29 20 28 69 6e 74 2c 20 65 72 72 6f 72  yte) (int, error
0220: 29 20 7b 0a 09 72 65 74 75 72 6e 20 72 28 62 29  ) {..return r(b)
0230: 0a 7d 0a 0a 2f 2f 20 52 65 74 75 72 6e 73 20 61  .}..// Returns a
0240: 20 77 72 69 74 65 72 20 74 68 61 74 20 64 65 6c   writer that del
0250: 65 67 61 74 65 73 20 63 61 6c 6c 73 20 74 6f 20  egates calls to 
0260: 57 72 69 74 65 28 2e 2e 2e 29 20 77 68 69 6c 65  Write(...) while
0270: 20 65 6e 73 75 72 69 6e 67 0a 2f 2f 20 74 68 61   ensuring.// tha
0280: 74 20 69 74 20 69 73 20 6e 65 76 65 72 20 63 61  t it is never ca
0290: 6c 6c 65 64 20 77 69 74 68 20 6c 65 73 73 20 62  lled with less b
02a0: 79 74 65 73 20 74 68 61 6e 20 74 68 65 20 73 70  ytes than the sp
02b0: 65 63 69 66 69 65 64 20 61 6d 6f 75 6e 74 2e 0a  ecified amount..
02c0: 2f 2f 0a 2f 2f 20 43 61 6c 6c 73 20 77 69 74 68  //.// Calls with
02d0: 20 66 65 77 65 72 20 62 79 74 65 73 20 61 72 65   fewer bytes are
02e0: 20 62 75 66 66 65 72 65 64 20 77 68 69 6c 65 20   buffered while 
02f0: 61 20 63 61 6c 6c 20 77 69 74 68 20 61 20 6e 69  a call with a ni
0300: 6c 20 73 6c 69 63 65 0a 2f 2f 20 63 61 75 73 65  l slice.// cause
0310: 73 20 74 68 65 20 62 75 66 66 65 72 20 74 6f 20  s the buffer to 
0320: 62 65 20 66 6c 75 73 68 65 64 20 74 6f 20 74 68  be flushed to th
0330: 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 77 72 69  e underlying wri
0340: 74 65 72 2e 0a 66 75 6e 63 20 53 69 7a 65 64 57  ter..func SizedW
0350: 72 69 74 65 72 28 77 72 69 74 65 72 20 69 6f 2e  riter(writer io.
0360: 57 72 69 74 65 72 2c 20 73 69 7a 65 20 69 6e 74  Writer, size int
0370: 29 20 69 6f 2e 57 72 69 74 65 72 20 7b 0a 09 76  ) io.Writer {..v
0380: 61 72 20 62 75 66 66 65 72 20 5b 5d 62 79 74 65  ar buffer []byte
0390: 20 3d 20 6d 61 6b 65 28 5b 5d 62 79 74 65 2c 20   = make([]byte, 
03a0: 30 2c 20 73 69 7a 65 29 0a 09 76 61 72 20 77 72  0, size)..var wr
03b0: 69 74 65 20 57 72 69 74 65 72 46 75 6e 63 0a 0a  ite WriterFunc..
03c0: 09 77 72 69 74 65 20 3d 20 66 75 6e 63 28 69 6e  .write = func(in
03d0: 70 75 74 20 5b 5d 62 79 74 65 29 20 28 69 6e 74  put []byte) (int
03e0: 2c 20 65 72 72 6f 72 29 20 7b 0a 09 09 76 61 72  , error) {...var
03f0: 20 28 0a 09 09 09 63 6f 75 6e 74 20 69 6e 74 0a   (....count int.
0400: 09 09 09 65 72 72 20 20 20 65 72 72 6f 72 0a 09  ...err   error..
0410: 09 29 0a 0a 09 09 2f 2f 20 46 6c 75 73 68 20 74  .)....// Flush t
0420: 68 65 20 62 75 66 66 65 72 20 77 68 65 6e 20 63  he buffer when c
0430: 61 6c 6c 65 64 20 77 69 74 68 20 6e 6f 20 62 79  alled with no by
0440: 74 65 73 20 74 6f 20 77 72 69 74 65 0a 09 09 69  tes to write...i
0450: 66 20 69 6e 70 75 74 20 3d 3d 20 6e 69 6c 20 7b  f input == nil {
0460: 0a 09 09 09 2f 2f 20 43 61 6c 6c 20 74 68 65 20  ....// Call the 
0470: 77 72 69 74 65 72 20 77 69 74 68 20 77 68 61 74  writer with what
0480: 65 76 65 72 20 77 65 20 68 61 76 65 20 69 6e 20  ever we have in 
0490: 73 74 6f 72 65 2e 2e 0a 09 09 09 63 6f 75 6e 74  store......count
04a0: 2c 20 65 72 72 20 3d 20 77 72 69 74 65 72 2e 57  , err = writer.W
04b0: 72 69 74 65 28 62 75 66 66 65 72 29 0a 0a 09 09  rite(buffer)....
04c0: 09 2f 2f 20 41 64 76 61 6e 63 65 20 74 68 65 20  .// Advance the 
04d0: 62 75 66 66 65 72 0a 09 09 09 62 75 66 66 65 72  buffer....buffer
04e0: 20 3d 20 62 75 66 66 65 72 5b 3a 63 6f 70 79 28   = buffer[:copy(
04f0: 62 75 66 66 65 72 2c 20 62 75 66 66 65 72 5b 63  buffer, buffer[c
0500: 6f 75 6e 74 3a 5d 29 5d 0a 0a 09 09 09 72 65 74  ount:])].....ret
0510: 75 72 6e 20 30 2c 20 65 72 72 0a 09 09 7d 0a 0a  urn 0, err...}..
0520: 09 09 2f 2f 20 44 65 6c 65 67 61 74 65 20 74 6f  ..// Delegate to
0530: 20 74 68 65 20 77 72 69 74 65 72 20 69 66 20 74   the writer if t
0540: 68 65 20 73 69 7a 65 20 69 73 20 72 69 67 68 74  he size is right
0550: 0a 09 09 69 66 20 6c 65 6e 28 62 75 66 66 65 72  ...if len(buffer
0560: 29 20 3d 3d 20 30 20 26 26 20 6c 65 6e 28 69 6e  ) == 0 && len(in
0570: 70 75 74 29 20 3e 3d 20 73 69 7a 65 20 7b 0a 09  put) >= size {..
0580: 09 09 72 65 74 75 72 6e 20 77 72 69 74 65 72 2e  ..return writer.
0590: 57 72 69 74 65 28 69 6e 70 75 74 29 0a 09 09 7d  Write(input)...}
05a0: 0a 0a 09 09 2f 2f 20 41 70 70 65 6e 64 20 64 61  ....// Append da
05b0: 74 61 20 74 6f 20 74 68 65 20 62 75 66 66 65 72  ta to the buffer
05c0: 0a 09 09 63 6f 75 6e 74 20 3d 20 63 6f 70 79 28  ...count = copy(
05d0: 62 75 66 66 65 72 5b 6c 65 6e 28 62 75 66 66 65  buffer[len(buffe
05e0: 72 29 3a 73 69 7a 65 5d 2c 20 69 6e 70 75 74 29  r):size], input)
05f0: 0a 09 09 62 75 66 66 65 72 20 3d 20 62 75 66 66  ...buffer = buff
0600: 65 72 5b 3a 6c 65 6e 28 62 75 66 66 65 72 29 2b  er[:len(buffer)+
0610: 63 6f 75 6e 74 5d 0a 0a 09 09 2f 2f 20 52 65 74  count]....// Ret
0620: 75 72 6e 20 69 66 20 77 65 20 64 6f 6e 27 74 20  urn if we don't 
0630: 68 61 76 65 20 65 6e 6f 75 67 68 20 62 79 74 65  have enough byte
0640: 73 20 74 6f 20 77 72 69 74 65 0a 09 09 69 66 20  s to write...if 
0650: 6c 65 6e 28 62 75 66 66 65 72 29 20 3c 20 73 69  len(buffer) < si
0660: 7a 65 20 7b 0a 09 09 09 72 65 74 75 72 6e 20 6c  ze {....return l
0670: 65 6e 28 69 6e 70 75 74 29 2c 20 6e 69 6c 0a 09  en(input), nil..
0680: 09 7d 0a 0a 09 09 2f 2f 20 46 6c 75 73 68 20 74  .}....// Flush t
0690: 68 65 20 62 75 66 66 65 72 20 61 73 20 69 74 20  he buffer as it 
06a0: 69 73 20 66 69 6c 6c 65 64 0a 09 09 5f 2c 20 65  is filled..._, e
06b0: 72 72 20 3d 20 77 72 69 74 65 28 6e 69 6c 29 0a  rr = write(nil).
06c0: 09 09 69 66 20 65 72 72 20 21 3d 20 6e 69 6c 20  ..if err != nil 
06d0: 7b 0a 09 09 09 72 65 74 75 72 6e 20 63 6f 75 6e  {....return coun
06e0: 74 2c 20 65 72 72 0a 09 09 7d 0a 0a 09 09 2f 2f  t, err...}....//
06f0: 20 48 61 6e 64 6c 65 20 74 68 65 20 72 65 73 74   Handle the rest
0700: 20 6f 66 20 74 68 65 20 69 6e 70 75 74 0a 09 09   of the input...
0710: 72 65 74 75 72 6e 20 77 72 69 74 65 28 69 6e 70  return write(inp
0720: 75 74 5b 63 6f 75 6e 74 3a 5d 29 0a 09 7d 0a 0a  ut[count:])..}..
0730: 09 72 65 74 75 72 6e 20 77 72 69 74 65 0a 7d 0a  .return write.}.
0740: 0a 2f 2f 20 52 65 74 75 72 6e 73 20 61 20 72 65  .// Returns a re
0750: 61 64 65 72 20 74 68 61 74 20 64 65 6c 65 67 61  ader that delega
0760: 74 65 73 20 63 61 6c 6c 73 20 74 6f 20 52 65 61  tes calls to Rea
0770: 64 28 2e 2e 2e 29 20 77 68 69 6c 65 20 65 6e 73  d(...) while ens
0780: 75 72 69 6e 67 0a 2f 2f 20 74 68 61 74 20 74 68  uring.// that th
0790: 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20  e output buffer 
07a0: 69 73 20 6e 65 76 65 72 20 73 6d 61 6c 6c 65 72  is never smaller
07b0: 20 74 68 61 6e 20 74 68 65 20 72 65 71 75 69 72   than the requir
07c0: 65 64 20 73 69 7a 65 0a 2f 2f 20 61 6e 64 20 69  ed size.// and i
07d0: 73 20 64 6f 77 6e 73 69 7a 65 64 20 74 6f 20 61  s downsized to a
07e0: 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 74 68 65   multiple of the
07f0: 20 72 65 71 75 69 72 65 64 20 73 69 7a 65 20 69   required size i
0800: 66 20 6c 61 72 67 65 72 2e 0a 66 75 6e 63 20 53  f larger..func S
0810: 69 7a 65 64 52 65 61 64 65 72 28 72 65 61 64 65  izedReader(reade
0820: 72 20 69 6f 2e 52 65 61 64 65 72 2c 20 73 69 7a  r io.Reader, siz
0830: 65 20 69 6e 74 29 20 69 6f 2e 52 65 61 64 65 72  e int) io.Reader
0840: 20 7b 0a 09 76 61 72 20 62 75 66 66 65 72 20 5b   {..var buffer [
0850: 5d 62 79 74 65 20 3d 20 6d 61 6b 65 28 5b 5d 62  ]byte = make([]b
0860: 79 74 65 2c 20 30 2c 20 73 69 7a 65 29 0a 0a 09  yte, 0, size)...
0870: 72 65 74 75 72 6e 20 52 65 61 64 65 72 46 75 6e  return ReaderFun
0880: 63 28 66 75 6e 63 28 6f 75 74 70 75 74 20 5b 5d  c(func(output []
0890: 62 79 74 65 29 20 28 69 6e 74 2c 20 65 72 72 6f  byte) (int, erro
08a0: 72 29 20 7b 0a 09 09 76 61 72 20 28 0a 09 09 09  r) {...var (....
08b0: 63 6f 75 6e 74 20 69 6e 74 0a 09 09 09 65 72 72  count int....err
08c0: 20 20 20 65 72 72 6f 72 0a 09 09 29 0a 09 73 74     error...)..st
08d0: 61 72 74 3a 0a 09 09 2f 2f 20 52 65 70 6c 79 20  art:...// Reply 
08e0: 77 69 74 68 20 74 68 65 20 62 75 66 66 65 72 65  with the buffere
08f0: 64 20 64 61 74 61 20 69 66 20 74 68 65 72 65 20  d data if there 
0900: 69 73 20 61 6e 79 0a 09 09 69 66 20 6c 65 6e 28  is any...if len(
0910: 62 75 66 66 65 72 29 20 3e 20 30 20 7b 0a 09 09  buffer) > 0 {...
0920: 09 63 6f 75 6e 74 20 3d 20 63 6f 70 79 28 6f 75  .count = copy(ou
0930: 74 70 75 74 2c 20 62 75 66 66 65 72 29 0a 0a 09  tput, buffer)...
0940: 09 09 2f 2f 20 41 64 76 61 6e 63 65 20 74 68 65  ..// Advance the
0950: 20 64 61 74 61 20 69 6e 20 74 68 65 20 62 75 66   data in the buf
0960: 66 65 72 0a 09 09 09 62 75 66 66 65 72 20 3d 20  fer....buffer = 
0970: 62 75 66 66 65 72 5b 3a 63 6f 70 79 28 62 75 66  buffer[:copy(buf
0980: 66 65 72 2c 20 62 75 66 66 65 72 5b 63 6f 75 6e  fer, buffer[coun
0990: 74 3a 5d 29 5d 0a 0a 09 09 09 2f 2f 20 52 65 74  t:])].....// Ret
09a0: 75 72 6e 20 63 6f 75 6e 74 20 61 6e 64 20 65 72  urn count and er
09b0: 72 6f 72 20 69 66 20 77 65 20 68 61 76 65 20 72  ror if we have r
09c0: 65 61 64 20 74 68 65 20 77 68 6f 6c 65 20 62 75  ead the whole bu
09d0: 66 66 65 72 0a 09 09 09 69 66 20 6c 65 6e 28 62  ffer....if len(b
09e0: 75 66 66 65 72 29 20 3d 3d 20 30 20 7b 0a 09 09  uffer) == 0 {...
09f0: 09 09 72 65 74 75 72 6e 20 63 6f 75 6e 74 2c 20  ..return count, 
0a00: 65 72 72 0a 09 09 09 7d 0a 0a 09 09 09 2f 2f 20  err....}.....// 
0a10: 44 6f 20 6e 6f 74 20 70 72 6f 70 61 67 61 74 65  Do not propagate
0a20: 20 61 6e 20 65 72 72 6f 72 20 75 6e 74 69 6c 20   an error until 
0a30: 74 68 65 20 62 75 66 66 65 72 20 69 73 20 65 78  the buffer is ex
0a40: 68 61 75 73 74 65 64 0a 09 09 09 72 65 74 75 72  hausted....retur
0a50: 6e 20 63 6f 75 6e 74 2c 20 6e 69 6c 0a 09 09 7d  n count, nil...}
0a60: 0a 0a 09 09 2f 2f 20 44 65 6c 65 67 61 74 65 20  ....// Delegate 
0a70: 69 66 20 74 68 65 20 62 75 66 66 65 72 20 69 73  if the buffer is
0a80: 20 65 6d 70 74 79 20 61 6e 64 20 74 68 65 20 64   empty and the d
0a90: 65 73 74 69 6e 61 74 69 6f 6e 20 62 75 66 66 65  estination buffe
0aa0: 72 20 69 73 20 6c 61 72 67 65 20 65 6e 6f 75 67  r is large enoug
0ab0: 68 0a 09 09 69 66 20 6c 65 6e 28 6f 75 74 70 75  h...if len(outpu
0ac0: 74 29 20 3e 3d 20 73 69 7a 65 20 7b 0a 09 09 09  t) >= size {....
0ad0: 72 65 74 75 72 6e 20 72 65 61 64 65 72 2e 52 65  return reader.Re
0ae0: 61 64 28 6f 75 74 70 75 74 5b 3a 28 6c 65 6e 28  ad(output[:(len(
0af0: 6f 75 74 70 75 74 29 2f 73 69 7a 65 29 2a 73 69  output)/size)*si
0b00: 7a 65 5d 29 0a 09 09 7d 0a 0a 09 09 2f 2f 20 50  ze])...}....// P
0b10: 65 72 66 6f 72 6d 20 61 20 72 65 61 64 20 69 6e  erform a read in
0b20: 74 6f 20 74 68 65 20 62 75 66 66 65 72 0a 09 09  to the buffer...
0b30: 63 6f 75 6e 74 2c 20 65 72 72 20 3d 20 72 65 61  count, err = rea
0b40: 64 65 72 2e 52 65 61 64 28 62 75 66 66 65 72 5b  der.Read(buffer[
0b50: 3a 73 69 7a 65 5d 29 0a 0a 09 09 2f 2f 20 53 69  :size])....// Si
0b60: 7a 65 20 74 68 65 20 62 75 66 66 65 72 20 64 6f  ze the buffer do
0b70: 77 6e 20 74 6f 20 74 68 65 20 72 65 61 64 20 64  wn to the read d
0b80: 61 74 61 20 73 69 7a 65 0a 09 09 2f 2f 20 61 6e  ata size...// an
0b90: 64 20 72 65 73 74 61 72 74 20 69 66 20 77 65 20  d restart if we 
0ba0: 68 61 76 65 20 73 75 63 63 65 73 73 66 75 6c 6c  have successfull
0bb0: 79 20 72 65 61 64 20 73 6f 6d 65 20 62 79 74 65  y read some byte
0bc0: 73 0a 09 09 62 75 66 66 65 72 20 3d 20 62 75 66  s...buffer = buf
0bd0: 66 65 72 5b 3a 63 6f 75 6e 74 5d 0a 09 09 69 66  fer[:count]...if
0be0: 20 6c 65 6e 28 62 75 66 66 65 72 29 20 3e 20 30   len(buffer) > 0
0bf0: 20 7b 0a 09 09 09 67 6f 74 6f 20 73 74 61 72 74   {....goto start
0c00: 0a 09 09 7d 0a 0a 09 09 2f 2f 20 52 65 74 75 72  ...}....// Retur
0c10: 6e 69 6e 67 20 6f 6e 20 65 72 72 2f 6d 69 73 62  ning on err/misb
0c20: 65 68 61 76 69 6e 67 20 6e 6f 6f 70 20 72 65 61  ehaving noop rea
0c30: 64 65 72 0a 09 09 72 65 74 75 72 6e 20 30 2c 20  der...return 0, 
0c40: 65 72 72 0a 09 7d 29 0a 7d 0a                    err..}).}.