messages.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package protocol
  2. import "io"
  3. type request struct {
  4. name string
  5. offset int64
  6. size uint32
  7. hash []byte
  8. }
  9. type header struct {
  10. version int
  11. msgID int
  12. msgType int
  13. }
  14. func encodeHeader(h header) uint32 {
  15. return uint32(h.version&0xf)<<28 +
  16. uint32(h.msgID&0xfff)<<16 +
  17. uint32(h.msgType&0xff)<<8
  18. }
  19. func decodeHeader(u uint32) header {
  20. return header{
  21. version: int(u>>28) & 0xf,
  22. msgID: int(u>>16) & 0xfff,
  23. msgType: int(u>>8) & 0xff,
  24. }
  25. }
  26. func (w *marshalWriter) writeHeader(h header) {
  27. w.writeUint32(encodeHeader(h))
  28. }
  29. func (w *marshalWriter) writeIndex(idx []FileInfo) {
  30. w.writeUint32(uint32(len(idx)))
  31. for _, f := range idx {
  32. w.writeString(f.Name)
  33. w.writeUint32(f.Flags)
  34. w.writeUint64(uint64(f.Modified))
  35. w.writeUint32(f.Version)
  36. w.writeUint32(uint32(len(f.Blocks)))
  37. for _, b := range f.Blocks {
  38. w.writeUint32(b.Size)
  39. w.writeBytes(b.Hash)
  40. }
  41. }
  42. }
  43. func WriteIndex(w io.Writer, idx []FileInfo) (int, error) {
  44. mw := marshalWriter{w: w}
  45. mw.writeIndex(idx)
  46. return int(mw.getTot()), mw.err
  47. }
  48. func (w *marshalWriter) writeRequest(r request) {
  49. w.writeString(r.name)
  50. w.writeUint64(uint64(r.offset))
  51. w.writeUint32(r.size)
  52. w.writeBytes(r.hash)
  53. }
  54. func (w *marshalWriter) writeResponse(data []byte) {
  55. w.writeBytes(data)
  56. }
  57. func (w *marshalWriter) writeOptions(opts map[string]string) {
  58. w.writeUint32(uint32(len(opts)))
  59. for k, v := range opts {
  60. w.writeString(k)
  61. w.writeString(v)
  62. }
  63. }
  64. func (r *marshalReader) readHeader() header {
  65. return decodeHeader(r.readUint32())
  66. }
  67. func (r *marshalReader) readIndex() []FileInfo {
  68. var files []FileInfo
  69. nfiles := r.readUint32()
  70. if nfiles > 0 {
  71. files = make([]FileInfo, nfiles)
  72. for i := range files {
  73. files[i].Name = r.readString()
  74. files[i].Flags = r.readUint32()
  75. files[i].Modified = int64(r.readUint64())
  76. files[i].Version = r.readUint32()
  77. nblocks := r.readUint32()
  78. blocks := make([]BlockInfo, nblocks)
  79. for j := range blocks {
  80. blocks[j].Size = r.readUint32()
  81. blocks[j].Hash = r.readBytes()
  82. }
  83. files[i].Blocks = blocks
  84. }
  85. }
  86. return files
  87. }
  88. func ReadIndex(r io.Reader) ([]FileInfo, error) {
  89. mr := marshalReader{r: r}
  90. idx := mr.readIndex()
  91. return idx, mr.err
  92. }
  93. func (r *marshalReader) readRequest() request {
  94. var req request
  95. req.name = r.readString()
  96. req.offset = int64(r.readUint64())
  97. req.size = r.readUint32()
  98. req.hash = r.readBytes()
  99. return req
  100. }
  101. func (r *marshalReader) readResponse() []byte {
  102. return r.readBytes()
  103. }
  104. func (r *marshalReader) readOptions() map[string]string {
  105. n := r.readUint32()
  106. opts := make(map[string]string, n)
  107. for i := 0; i < int(n); i++ {
  108. k := r.readString()
  109. v := r.readString()
  110. opts[k] = v
  111. }
  112. return opts
  113. }