public function getCursor(GetCursorRequest $request)
    {
        $params  = array();
        $headers = array();

        $project  = $request->getProject() ?: '';
        $logStore = $request->getLogStore() ?: '';
        $shardId  = is_null($request->getShardId()) ? '' : $request->getShardId();

        $mode     = $request->getMode() ?: '';
        $fromTime = $request->getFromTime() ?: -1;

        if (( empty( $mode ) xor $fromTime == -1 ) == false) {
            if ( ! empty( $mode )) {
                throw new Exception ("[RequestError] Request is failed. Mode and fromTime can not be not empty simultaneously");
            } else {
                throw new Exception ("[RequestError] Request is failed. Mode and fromTime can not be empty simultaneously");
            }
        }
        if ( ! empty( $mode ) && strcmp($mode, 'begin') !== 0 && strcmp($mode, 'end') !== 0) {
            throw new Exception ("[RequestError] Request is failed. Mode value invalid:$mode");
        }
        if ($fromTime !== -1 && ( is_integer($fromTime) == false || $fromTime < 0 )) {
            throw new Exception ("[RequestError] Request is failed. FromTime value invalid:$fromTime");
        }
        $params['type'] = 'cursor';
        if ($fromTime !== -1) {
            $params['from'] = $fromTime;
        } else {
            $params['mode'] = $mode;
        }
        $resource = '/logstores/' . $logStore . '/shards/' . $shardId;

        list( $resp, $header ) = $this->send("GET", $project, null, $resource, $params, $headers);

        $requestId = isset ( $header ['x-log-requestid'] ) ? $header ['x-log-requestid'] : '';

        $resp = $this->parseToJson($resp, $requestId);

        return new GetCursorResponse($resp, $header);
    }