Ejemplo n.º 1
0
func (self *blobstoreStruct) op_get(operation *operations.Get,
	state *minos.OperationState) (ret bucket.BucketReturn) {

	commonOp := new(commonOperation)
	retStatus := commonOp.fill(operation.Key, nil)
	if !retStatus.IsOk() {
		return &bucket.ReturnGeneric{retStatus}
	}

	var value types.Array
	var status retcode.Status
	switch commonOp.operation {
	case operation_incubation_sum:
		var incInfo incubationState
		incInfo, status = self.incubator.information(state, commonOp.incubationId)
		if status.Code == retcode.OkNotFound {
			// Not found
			break
		}
		if !status.IsOk() {
			break
		}
		hash := incInfo.restoreHash().Sum(nil)
		hashEncoded, err := encoding.Cbor().Encode(hash)
		if err != nil {
			panic("Error encoding hash")
		}
		length := incInfo.length
		lengthEncoded, err := encoding.Cbor().Encode(length)
		if err != nil {
			panic("Error encoding length")
		}

		value = types.Array{hashEncoded, lengthEncoded}
	case operation_public_content:
		var skipData []byte
		var limitData []byte

		if len(commonOp.restKey) > 0 {
			skipData = commonOp.restKey[0]
		}
		if len(commonOp.restKey) > 1 {
			limitData = commonOp.restKey[1]
		}

		var err error
		var skip uint64
		if skipData != nil {
			skip, err = binary.ReadUvarint(bytes.NewReader(skipData))
			if err != nil {
				panic("Error decoding 'skip' (should be a variable uint)")
			}
		}

		var limit int64
		if limitData != nil {
			var limitUint64 uint64
			limitUint64, err = binary.ReadUvarint(bytes.NewReader(limitData))
			if err != nil {
				panic("Error decoding 'limit' (should be a variable uint)")
			}
			limit = int64(limitUint64)
		} else {
			limit = -1 // No limit
		}

		var data []byte
		var entireLength uint64
		data, entireLength, status = self.public.read(state, commonOp.hash,
			skip, limit)
		if !status.IsOk() {
			break
		}
		if status.Code == retcode.OkNotFound {
			// Not found
			break
		}

		var lengthEncoded []byte
		lengthEncoded, err = encoding.Cbor().Encode(entireLength)
		if err != nil {
			panic("Error encoding length")
		}

		// Ok, found it, return the value
		value = types.Array{data, lengthEncoded}
	case operation_public_length:
		var pubInfo publicState
		if commonOp.hash == nil {
			err := errors.New("Hash is missing for getting length")
			status = retcode.NewStatusError(retcode.ErrorClient, err)
		}
		pubInfo, status = self.public.information(state, commonOp.hash)
		if status.Code == retcode.OkNotFound {
			// Not found
			break
		}
		if !status.IsOk() {
			break
		}

		length := pubInfo.length
		lengthEncoded, err := encoding.Cbor().Encode(length)
		if err != nil {
			panic("Error encoding length")
		}

		value = types.Array{lengthEncoded}
	default:
		err := errors.New(fmt.Sprintf("Unknown operation: operation-code: "+
			"%v (this usually means you called GET instead of PUT)\n",
			commonOp.operation))
		status = retcode.NewStatusError(retcode.ErrorClient, err)
	}

	// Done, return
	if status.IsOk() {
		if status.Code == retcode.OkNotFound {
			if status.Text == "" {
				status.Text = fmt.Sprintf("Given hash is: %v", commonOp.hash)
			}
			return &bucket.ReturnGeneric{status}
		} else {
			return &operations.GetReturn{
				Status: status,
				Value:  value,
			}
		}
	} else {
		return &bucket.ReturnGeneric{status}
	}
}