func Download(t btesting.T, bucketId typing.BucketId, hash []byte, writer io.Writer) (entireLength uint64) { var skip int = 0 var limit int = readerBlockSize var entireLengthProcessed bool for { var err error skipEncoded := encoding.UIntToUVarInt(uint64(skip)) limitEncoded := encoding.UIntToUVarInt(uint64(limit)) //hash/[HASH]/content/VUI(skip_optional)/VUI(limit_optional) key := typing.Key{[]byte("hash"), hash, []byte("content"), skipEncoded, limitEncoded} value := operations.Get(t, bucketId, key, true) // value = [data, CBOR(entire_length)] if len(value) != 2 { t.Errorf("Got invalid get from bucket / expecting 2 elements in value. Have %v", len(value)) return } data := value[0] // Set entire length if !entireLengthProcessed { entireLengthEncoded := value[1] err = encoding.Cbor().Decode(entireLengthEncoded, &entireLength) entireLengthProcessed = true if err != nil { t.Errorf("Error decoding entire length %v", err) return } } _, err = writer.Write(data) if err != nil { t.Errorf("Unable to write to writer: %v", err) return } skip += readerBlockSize // Next one? End if we got less than requested or would exceed entire length if uint64(len(data)) < readerBlockSize || uint64(skip) >= entireLength { // No, end here return } } return }
func UnsignedVariableInt(payload string) (data []byte, err error) { u, err := strconv.ParseUint(payload, 10, 64) if err != nil { return } data = encoding.UIntToUVarInt(u) return }
func (self *Reader) Read(writer io.Writer, maxAllowedLength uint64) (entireLength uint64, errorTooLong bool, status retcode.Status) { var skip int = 0 var limit int = readerBlockSize var entireLengthProcessed bool for { var err error skipEncoded := encoding.UIntToUVarInt(uint64(skip)) limitEncoded := encoding.UIntToUVarInt(uint64(limit)) //hash/[HASH]/content/VUI(skip_optional)/VUI(limit_optional) key := types.Key{[]byte("hash"), self.Hash, []byte("content"), skipEncoded, limitEncoded} opGet := &operations.Get{ BucketId: self.BucketId, Key: key, } performRet := self.Dispatcher.Perform(self.Context, opGet) if !performRet.GetCode().IsOk() || performRet.GetCode() == retcode.OkNotFound { // Error or not found status = performRet.GetStatus() return } getReturn, ok := performRet.(*operations.GetReturn) if !ok { status = retcode.NewStatusFmt(retcode.ErrorServer, "Got invalid get return type %T", getReturn) return } // values = [data, CBOR(entire_length)] if len(getReturn.Value) != 2 { status = retcode.NewStatusFmt(retcode.ErrorServer, "Got invalid get from bucket / expecting 2 elements in value. Have %v", len(getReturn.Value)) return } data := getReturn.Value[0] // Set entire length if !entireLengthProcessed { entireLengthEncoded := getReturn.Value[1] err = encoding.Cbor().Decode(entireLengthEncoded, &entireLength) entireLengthProcessed = true if err != nil { status = retcode.NewStatusFmt(retcode.ErrorServer, "Error decoding entire length %v", err) return } // Check entire length if entireLength > maxAllowedLength { errorTooLong = true return } } _, err = writer.Write(data) if err != nil { status = retcode.NewStatusFmt(retcode.ErrorServer, "Unable to write to writer: %v", err) return } skip += readerBlockSize // Next one? End if we got less than requested or would exceed entire length if uint64(len(data)) < readerBlockSize || uint64(skip) >= entireLength { // No, end here return } } return }