/* Unpack a dir from b, returning it, the rest of the buffer, and the error status. An empty buffer yields Dir{} and it is ok. */ func UnpackDir(buf []byte) (Dir, []byte, error) { d := Dir{} var k, v string var err error if len(buf) == 0 { return Dir{}, buf, nil } if len(buf) < 4 { return nil, buf, errors.New("short buffer") } n := int(binary.LittleEndian.Uint32(buf[:4])) if len(buf) < n+4 { return nil, buf, errors.New("short buffer") } buf = buf[4:] b := buf[:n] buf = buf[n:] for len(b) > 0 { k, b, err = nchan.GetString(b) if err != nil { return nil, buf, err } v, b, err = nchan.GetString(b) if err != nil { return nil, buf, err } d[k] = v } return d, buf, nil }
func UnpackMsg(buf []byte) (*Msg, error) { m := &Msg{} if len(buf) < 1 { return nil, errors.New("short msg") } m.Op = MsgId(buf[0]) if m.Op<Tmin || m.Op>=Tend { return nil, fmt.Errorf("unknown msg type %d", buf[0]) } buf = buf[1:] var err error m.Rid, buf, err = nchan.GetString(buf) if err != nil { return nil, err } if m.Op==Tget || m.Op==Tput { if len(buf) < 8 { return nil, errors.New("short msg") } m.Off = int64(binary.LittleEndian.Uint64(buf[0:])) buf = buf[8:] } if m.Op == Tget { if len(buf) < 8 { return nil, errors.New("short msg") } m.Count = int64(binary.LittleEndian.Uint64(buf[0:])) buf = buf[8:] } if m.Op==Tput || m.Op==Tmkdir || m.Op==Twstat { m.D, buf, err = zx.UnpackDir(buf) if err != nil { return nil, err } } if m.Op == Tmove { m.To, buf, err = nchan.GetString(buf) if err != nil { return nil, err } } if m.Op==Tfind || m.Op==Tget || m.Op==Tput || m.Op==Tfindget { m.Pred, buf, err = nchan.GetString(buf) if err != nil { return nil, err } } if m.Op==Tfind || m.Op==Tfindget { m.Spref, buf, err = nchan.GetString(buf) if err != nil { return nil, err } m.Dpref, buf, err = nchan.GetString(buf) if err != nil { return nil, err } if len(buf) < 8 { return nil, errors.New("short msg") } m.Depth = int(binary.LittleEndian.Uint64(buf[0:])) buf = buf[8:] } return m, nil }