// Path: library/src/main/java/com/jwoolston/android/uvc/requests/Request.java
// public enum Request {
// 
//     RC_UNDEFINED((byte) 0x00),
//     SET_CUR((byte) 0x01),
//     SET_CUR_ALL((byte) 0x11),
//     GET_CUR((byte) 0x81),
//     GET_MIN((byte) 0x82),
//     GET_MAX((byte) 0x83),
//     GET_RES((byte) 0x84),
//     GET_LEN((byte) 0x85),
//     GET_INFO((byte) 0x86),
//     GET_DEF((byte) 0x87),
//     GET_CUR_ALL((byte) 0x91),
//     GET_MIN_ALL((byte) 0x92),
//     GET_MAX_ALL((byte) 0x93),
//     GET_RES_ALL((byte) 0x94),
//     GET_DEF_ALL((byte) 0x97);
// 
//     public final byte code;
// 
//     Request(byte code) {
//         this.code = code;
//     }
// 
//     @Override
//     public String toString() {
//         return (name() + "(0x" + Integer.toHexString(0xFF & code) + ')');
//     }
// }
// 
// Path: library/src/main/java/com/jwoolston/android/uvc/requests/VideoClassRequest.java
// public abstract class VideoClassRequest {
// 
//     protected static final byte SET_REQUEST_INF_ENTITY = 0x21; // Set Request type targeting entity or interface
//     protected static final byte SET_REQUEST_ENDPOINT   = 0x22; // Set Request type targeting endpoint
//     protected static final byte GET_REQUEST_INF_ENTITY = (byte) 0xA1; // Get Request type targeting entity or interface
//     protected static final byte GET_REQUEST_ENDPOINT   = (byte) 0xA2; // Get Request type targeting endpoint
// 
//     private final byte    requestType;
//     private final Request request;
// 
//     private short wValue;
//     private short wIndex;
//     private byte[] data;
// 
//     protected static short getIndex(VideoTerminal terminal, VideoClassInterface classInterface) {
//         return (short) (((0xFF & terminal.getTerminalID()) << 8) | (0xFF & classInterface.getUsbInterface().getId()));
//     }
// 
//     protected VideoClassRequest(byte requestType, @NonNull Request request, short value, short index,
//                                 @NonNull byte[] data) {
//         this.requestType = requestType;
//         this.request = request;
//         wValue = value;
//         wIndex = index;
//         this.data = data;
//     }
// 
//     public byte getRequestType() {
//         return requestType;
//     }
// 
//     public byte getRequest() {
//         return request.code;
//     }
// 
//     public short getValue() {
//         return wValue;
//     }
// 
//     public short getIndex() {
//         return wIndex;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
//     public int getLength() {
//         return data.length;
//     }
// 
//     @Override public String toString() {
//         final StringBuffer sb = new StringBuffer(getClass().getSimpleName());
//         sb.append("{");
//         sb.append("requestType=0x").append(Integer.toHexString(0xFF & requestType).toUpperCase(Locale.US));
//         sb.append(", request=").append(request);
//         sb.append(", wValue=0x").append(Integer.toHexString(wValue).toUpperCase(Locale.US));
//         sb.append(", wIndex=").append(wIndex);
//         sb.append(", data=");
//         if (data == null) {
//             sb.append("null");
//         } else {
//             sb.append('[');
//             for (int i = 0; i < data.length; ++i) {
//                 sb.append(i == 0 ? "" : ", ").append(data[i]);
//             }
//             sb.append(']');
//         }
//         sb.append('}');
//         return sb.toString();
//     }
// }


import android.support.annotation.NonNull;
import com.jwoolston.android.uvc.requests.Request;
import com.jwoolston.android.uvc.requests.VideoClassRequest;
package com.jwoolston.android.uvc.requests.streaming;


/**
 * These requests are used to set or read an attribute of an interface Control inside the VideoStreaming interface of
 * the video function.
 *
 * The bRequest field indicates which attribute the request is manipulating. The MIN, MAX, and RES attributes are not
 * supported for the Set request. The wValue field specifies the Control Selector (CS) in the high byte, and the low
 * byte must be set to zero. The Control Selector indicates which type of Control this request is manipulating. If
 * the request specifies an unknown S to that endpoint, the control pipe must indicate a stall.
 *
 * @author Jared Woolston (Jared.Woolston@gmail.com)
 * @see <a href=http://www.usb.org/developers/docs/devclass_docs/USB_Video_Class_1_5.zip>UVC 1.5 Class
 * Specification §4.2.1</a>
 */
public abstract class VSInterfaceControlRequest extends VideoClassRequest {

    private static short valueFromControlSelector(@NonNull ControlSelector selector) {
// Path: library/src/main/java/com/jwoolston/android/uvc/requests/Request.java
// public enum Request {
// 
//     RC_UNDEFINED((byte) 0x00),
//     SET_CUR((byte) 0x01),
//     SET_CUR_ALL((byte) 0x11),
//     GET_CUR((byte) 0x81),
//     GET_MIN((byte) 0x82),
//     GET_MAX((byte) 0x83),
//     GET_RES((byte) 0x84),
//     GET_LEN((byte) 0x85),
//     GET_INFO((byte) 0x86),
//     GET_DEF((byte) 0x87),
//     GET_CUR_ALL((byte) 0x91),
//     GET_MIN_ALL((byte) 0x92),
//     GET_MAX_ALL((byte) 0x93),
//     GET_RES_ALL((byte) 0x94),
//     GET_DEF_ALL((byte) 0x97);
// 
//     public final byte code;
// 
//     Request(byte code) {
//         this.code = code;
//     }
// 
//     @Override
//     public String toString() {
//         return (name() + "(0x" + Integer.toHexString(0xFF & code) + ')');
//     }
// }
// 
// Path: library/src/main/java/com/jwoolston/android/uvc/requests/VideoClassRequest.java
// public abstract class VideoClassRequest {
// 
//     protected static final byte SET_REQUEST_INF_ENTITY = 0x21; // Set Request type targeting entity or interface
//     protected static final byte SET_REQUEST_ENDPOINT   = 0x22; // Set Request type targeting endpoint
//     protected static final byte GET_REQUEST_INF_ENTITY = (byte) 0xA1; // Get Request type targeting entity or interface
//     protected static final byte GET_REQUEST_ENDPOINT   = (byte) 0xA2; // Get Request type targeting endpoint
// 
//     private final byte    requestType;
//     private final Request request;
// 
//     private short wValue;
//     private short wIndex;
//     private byte[] data;
// 
//     protected static short getIndex(VideoTerminal terminal, VideoClassInterface classInterface) {
//         return (short) (((0xFF & terminal.getTerminalID()) << 8) | (0xFF & classInterface.getUsbInterface().getId()));
//     }
// 
//     protected VideoClassRequest(byte requestType, @NonNull Request request, short value, short index,
//                                 @NonNull byte[] data) {
//         this.requestType = requestType;
//         this.request = request;
//         wValue = value;
//         wIndex = index;
//         this.data = data;
//     }
// 
//     public byte getRequestType() {
//         return requestType;
//     }
// 
//     public byte getRequest() {
//         return request.code;
//     }
// 
//     public short getValue() {
//         return wValue;
//     }
// 
//     public short getIndex() {
//         return wIndex;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
//     public int getLength() {
//         return data.length;
//     }
// 
//     @Override public String toString() {
//         final StringBuffer sb = new StringBuffer(getClass().getSimpleName());
//         sb.append("{");
//         sb.append("requestType=0x").append(Integer.toHexString(0xFF & requestType).toUpperCase(Locale.US));
//         sb.append(", request=").append(request);
//         sb.append(", wValue=0x").append(Integer.toHexString(wValue).toUpperCase(Locale.US));
//         sb.append(", wIndex=").append(wIndex);
//         sb.append(", data=");
//         if (data == null) {
//             sb.append("null");
//         } else {
//             sb.append('[');
//             for (int i = 0; i < data.length; ++i) {
//                 sb.append(i == 0 ? "" : ", ").append(data[i]);
//             }
//             sb.append(']');
//         }
//         sb.append('}');
//         return sb.toString();
//     }
// }


// Path: library/src/main/java/com/jwoolston/android/uvc/requests/streaming/VSInterfaceControlRequest.java
import android.support.annotation.NonNull;
import com.jwoolston.android.uvc.requests.Request;
import com.jwoolston.android.uvc.requests.VideoClassRequest;

package com.jwoolston.android.uvc.requests.streaming;


/**
 * These requests are used to set or read an attribute of an interface Control inside the VideoStreaming interface of
 * the video function.
 *
 * The bRequest field indicates which attribute the request is manipulating. The MIN, MAX, and RES attributes are not
 * supported for the Set request. The wValue field specifies the Control Selector (CS) in the high byte, and the low
 * byte must be set to zero. The Control Selector indicates which type of Control this request is manipulating. If
 * the request specifies an unknown S to that endpoint, the control pipe must indicate a stall.
 *
 * @author Jared Woolston (Jared.Woolston@gmail.com)
 * @see <a href=http://www.usb.org/developers/docs/devclass_docs/USB_Video_Class_1_5.zip>UVC 1.5 Class
 * Specification §4.2.1</a>
 */
public abstract class VSInterfaceControlRequest extends VideoClassRequest {

    private static short valueFromControlSelector(@NonNull ControlSelector selector) {
        return ((short) (0xFFFF & (selector.code << 8)));