116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/*
216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License.
616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at
716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software
1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and
1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License.
1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */
1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
17b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define LOG_TAG "MtpDataPacket"
18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood
19d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include "MtpDataPacket.h"
20d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
21d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include <algorithm>
22bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang#include <errno.h>
23d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include <fcntl.h>
2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h>
2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/types.h>
260cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include <usbhost/usbhost.h>
2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStringBuffer.h"
28487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include "IMtpHandle.h"
2916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
307850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android {
317850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
32d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirononamespace {
33d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// Reads the exact |count| bytes from |fd| to |buf|.
34d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// Returns |count| if it succeed to read the bytes. Otherwise returns -1. If it reaches EOF, the
35d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// function regards it as an error.
36d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironossize_t readExactBytes(int fd, void* buf, size_t count) {
37d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    if (count > SSIZE_MAX) {
38d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        return -1;
39d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
40d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    size_t read_count = 0;
41d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    while (read_count < count) {
42d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        int result = read(fd, static_cast<int8_t*>(buf) + read_count, count - read_count);
43d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        // Assume that EOF is error.
44d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        if (result <= 0) {
45d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            return -1;
46d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        }
47d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        read_count += result;
48d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
49d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    return read_count == count ? count : -1;
50d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono}
51d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono}  // namespace
52d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
5316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::MtpDataPacket()
5444c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood    :   MtpPacket(MTP_BUFFER_SIZE),   // MAX_USBFS_BUFFER_SIZE
5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mOffset(MTP_CONTAINER_HEADER_SIZE)
5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
5916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::~MtpDataPacket() {
6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::reset() {
6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::reset();
6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset = MTP_CONTAINER_HEADER_SIZE;
6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setOperationCode(MtpOperationCode code) {
6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
6916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setTransactionID(MtpTransactionID id) {
7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
75ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt8(uint8_t& value) {
76ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (mPacketSize - mOffset < sizeof(value))
77ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return false;
78ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    value = mBuffer[mOffset++];
79ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return true;
80ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood}
81ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood
82ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt16(uint16_t& value) {
83ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (mPacketSize - mOffset < sizeof(value))
84ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return false;
8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
86ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
87ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mOffset += sizeof(value);
88ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return true;
8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
91ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt32(uint32_t& value) {
92ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (mPacketSize - mOffset < sizeof(value))
93ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return false;
9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
95ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |
9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint32_t)mBuffer[offset + 2] << 16)  | ((uint32_t)mBuffer[offset + 3] << 24);
97ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mOffset += sizeof(value);
98ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return true;
9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
101ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt64(uint64_t& value) {
102ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (mPacketSize - mOffset < sizeof(value))
103ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return false;
10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
105ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |
10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |
10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 6] << 48)  | ((uint64_t)mBuffer[offset + 7] << 56);
109ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    mOffset += sizeof(value);
110ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return true;
11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
113ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt128(uint128_t& value) {
114ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]);
115a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
116a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
117ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getString(MtpStringBuffer& string)
11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
119ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    return string.readFromPacket(this);
12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
122335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt8List* MtpDataPacket::getAInt8() {
123ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
124ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
125ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
126335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int8List* result = new Int8List;
127ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
128ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        int8_t value;
129ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getInt8(value)) {
130ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
131ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
132ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
133bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
134ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
136335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
137335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
138335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt8List* MtpDataPacket::getAUInt8() {
139ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
140ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
141ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
142335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt8List* result = new UInt8List;
143ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
144ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        uint8_t value;
145ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getUInt8(value)) {
146ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
147ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
148ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
149bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
150ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
152335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
153335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
154335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt16List* MtpDataPacket::getAInt16() {
155ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
156ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
157ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
158335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int16List* result = new Int16List;
159ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
160ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        int16_t value;
161ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getInt16(value)) {
162ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
163ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
164ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
165bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
166ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
167335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
168335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
169335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
170335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt16List* MtpDataPacket::getAUInt16() {
171ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
172ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
173ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
174335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt16List* result = new UInt16List;
175ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
176ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        uint16_t value;
177ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getUInt16(value)) {
178ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
179ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
180ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
181bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
182ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
183335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
184335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
185335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
186335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt32List* MtpDataPacket::getAInt32() {
187ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
188ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
189ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
190335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int32List* result = new Int32List;
191ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
192ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        int32_t value;
193ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getInt32(value)) {
194ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
195ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
196ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
197bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
198ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
199335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
200335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
201335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
202335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt32List* MtpDataPacket::getAUInt32() {
203ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
204ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
205ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
206335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt32List* result = new UInt32List;
207ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
208ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        uint32_t value;
209ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getUInt32(value)) {
210ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
211ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
212ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
213bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
214ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
215335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
216335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
217335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
218335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt64List* MtpDataPacket::getAInt64() {
219ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
220ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
221ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
222335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int64List* result = new Int64List;
223ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
224ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        int64_t value;
225ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getInt64(value)) {
226ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
227ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
228ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
229bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
230ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
231335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
232335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
233335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
234335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt64List* MtpDataPacket::getAUInt64() {
235ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    uint32_t count;
236ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    if (!getUInt32(count))
237ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        return NULL;
238335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt64List* result = new UInt64List;
239ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    for (uint32_t i = 0; i < count; i++) {
240ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        uint64_t value;
241ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        if (!getUInt64(value)) {
242ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            delete result;
243ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood            return NULL;
244ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood        }
245bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang        result->push_back(value);
246ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood    }
247335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
248335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
249335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt8(int8_t value) {
25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 1);
25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)value;
25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt8(uint8_t value) {
25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 1);
25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)value;
26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt16(int16_t value) {
26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 2);
26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt16(uint16_t value) {
27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 2);
27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt32(int32_t value) {
28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 4);
28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
28616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
28716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt32(uint32_t value) {
29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 4);
29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt64(int64_t value) {
30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 8);
30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
30516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
30616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
30716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
30816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
30916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
31016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
31116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
31216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
31316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
31416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt64(uint64_t value) {
31516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 8);
31616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
31716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
31816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
31916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
32016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
32116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
32216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
32316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
32416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
32516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
32616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
32716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
328a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putInt128(const int128_t& value) {
329a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[0]);
330a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[1]);
331a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[2]);
332a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[3]);
333a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
334a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
335a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putUInt128(const uint128_t& value) {
336a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[0]);
337a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[1]);
338a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[2]);
339a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[3]);
340a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
341a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
3428277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putInt128(int64_t value) {
3438277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putInt64(value);
3445959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood    putInt64(value < 0 ? -1 : 0);
3458277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood}
3468277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
3478277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putUInt128(uint64_t value) {
3488277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putUInt64(value);
3498277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putUInt64(0);
3508277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood}
3518277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt8(const int8_t* values, int count) {
35316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
35416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
35516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt8(*values++);
35616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
35716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
35816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
35916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt8(*values++);
36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt16(const int16_t* values, int count) {
36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt16(*values++);
36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt16(*values++);
37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
376782aef17c9921a3bf401a0432878df5031f2328bMike Lockwoodvoid MtpDataPacket::putAUInt16(const UInt16List* values) {
377782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    size_t count = (values ? values->size() : 0);
378782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    putUInt32(count);
379782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    for (size_t i = 0; i < count; i++)
380782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        putUInt16((*values)[i]);
381782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood}
382782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood
38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt32(const int32_t* values, int count) {
38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt32(*values++);
38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt32(*values++);
39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
39516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const UInt32List* list) {
39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (!list) {
39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putEmptyArray();
39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    } else {
39916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        size_t size = list->size();
40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt32(size);
40116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        for (size_t i = 0; i < size; i++)
40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            putUInt32((*list)[i]);
40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
40416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
40516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
40616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt64(const int64_t* values, int count) {
40716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
40816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
40916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt64(*values++);
41016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
41116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
41216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
41316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
41416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
41516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt64(*values++);
41616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
41716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4181865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const MtpStringBuffer& string) {
41916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    string.writeToPacket(this);
42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4221865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const char* s) {
42316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpStringBuffer string(s);
42416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    string.writeToPacket(this);
42516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4271865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const uint16_t* string) {
4281865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    int count = 0;
429014897f5aece2c6212418934bd4618326979f17aYin Liu    for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
4301865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        if (string[i])
4311865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood            count++;
4321865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        else
4331865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood            break;
4341865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    }
435de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    putUInt8(count > 0 ? count + 1 : 0);
4361865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    for (int i = 0; i < count; i++)
4371865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        putUInt16(string[i]);
438de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    // only terminate with zero if string is not empty
439de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    if (count > 0)
440de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood        putUInt16(0);
4411865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood}
4421865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood
443487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#ifdef MTP_DEVICE
444487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::read(IMtpHandle *h) {
445487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int ret = h->read(mBuffer, MTP_BUFFER_SIZE);
446ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    if (ret < MTP_CONTAINER_HEADER_SIZE)
44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return -1;
448ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    mPacketSize = ret;
44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset = MTP_CONTAINER_HEADER_SIZE;
45016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ret;
45116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
45216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
453487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::write(IMtpHandle *h) {
45416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
45516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
456487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int ret = h->write(mBuffer, mPacketSize);
45716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return (ret < 0 ? ret : 0);
45816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
45964000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood
460487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::writeData(IMtpHandle *h, void* data, uint32_t length) {
461ebb1081a624a773a67c49b279c775e18e693c4fcMarco Nelissen    allocate(length + MTP_CONTAINER_HEADER_SIZE);
462ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
463ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    length += MTP_CONTAINER_HEADER_SIZE;
464ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
46564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
466487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int ret = h->write(mBuffer, length);
46764000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    return (ret < 0 ? ret : 0);
46864000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood}
46964000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood
47016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_DEVICE
47116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
47216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST
47342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::read(struct usb_request *request) {
47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // first read the header
47542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
47642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = mBufferSize;
47742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int length = transfer(request);
478437e945013318de54746422c8b44306e6d5319caMike Lockwood    if (length >= MTP_CONTAINER_HEADER_SIZE) {
4793e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        // look at the length field to see if the data spans multiple packets
4803e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
48133bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood        allocate(totalLength);
482b3be006498f28f2630264135e88d266b540bcec3Daichi Hirono        while (totalLength > static_cast<uint32_t>(length)) {
48342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            request->buffer = mBuffer + length;
48433bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood            request->buffer_length = totalLength - length;
48542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            int ret = transfer(request);
4863e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            if (ret >= 0)
4873e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                length += ret;
4883e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            else {
4893e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                length = ret;
4903e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                break;
4913e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            }
4923e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
4933e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
4943e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (length >= 0)
4953e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        mPacketSize = length;
4963e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return length;
49716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
49816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
49942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
5000cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    int read = 0;
5010cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    while (read < length) {
50242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer = (char *)buffer + read;
50342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer_length = length - read;
50442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        int ret = transfer(request);
5050cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        if (ret < 0) {
5060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood            return ret;
5070cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        }
5080cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        read += ret;
5090cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    }
5100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return read;
5110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
5120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
513b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Queue a read request.  Call readDataWait to wait for result
51442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataAsync(struct usb_request *req) {
51542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    if (usb_request_queue(req)) {
51629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("usb_endpoint_queue failed, errno: %d", errno);
517b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood        return -1;
518b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood    }
519b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood    return 0;
520b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood}
521b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
522b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Wait for result of readDataAsync
52342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataWait(struct usb_device *device) {
524cb8d8af1ad71ca7b800d298376dec7e6b1c1c766Philip P. Moltmann    struct usb_request *req = usb_request_wait(device, -1);
52542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    return (req ? req->actual_length : -1);
526b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood}
527b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
52842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataHeader(struct usb_request *request) {
52942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
53042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = request->max_packet_size;
53142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int length = transfer(request);
5320cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    if (length >= 0)
5330cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        mPacketSize = length;
5340cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return length;
5350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
5360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
537d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironoint MtpDataPacket::write(struct usb_request *request, UrbPacketDivisionMode divisionMode) {
538d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    if (mPacketSize < MTP_CONTAINER_HEADER_SIZE || mPacketSize > MTP_BUFFER_SIZE) {
539d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        ALOGE("Illegal packet size.");
540d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        return -1;
541d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
5420cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
54316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
54416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
545d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
546d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    size_t processedBytes = 0;
547d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    while (processedBytes < mPacketSize) {
548d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        const size_t write_size =
549d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                processedBytes == 0 && divisionMode == FIRST_PACKET_ONLY_HEADER ?
550d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                        MTP_CONTAINER_HEADER_SIZE : mPacketSize - processedBytes;
551d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        request->buffer = mBuffer + processedBytes;
552d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        request->buffer_length = write_size;
553d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        const int result = transfer(request);
554d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        if (result < 0) {
555d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            ALOGE("Failed to write bytes to the device.");
556d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            return -1;
557d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        }
558d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        processedBytes += result;
559d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
560d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
561d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    return processedBytes == mPacketSize ? processedBytes : -1;
56216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
56316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
564d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironoint MtpDataPacket::write(struct usb_request *request,
565d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                         UrbPacketDivisionMode divisionMode,
566d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                         int fd,
567d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                         size_t payloadSize) {
568d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    // Obtain the greatest multiple of minimum packet size that is not greater than
569d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    // MTP_BUFFER_SIZE.
570d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    if (request->max_packet_size <= 0) {
571d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        ALOGE("Cannot determine bulk transfer size due to illegal max packet size %d.",
572d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono              request->max_packet_size);
573d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        return -1;
574d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
575d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    const size_t maxBulkTransferSize =
576d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            MTP_BUFFER_SIZE - (MTP_BUFFER_SIZE % request->max_packet_size);
577d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    const size_t containerLength = payloadSize + MTP_CONTAINER_HEADER_SIZE;
578d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    size_t processedBytes = 0;
579d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    bool readError = false;
580d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
581d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    // Bind the packet with given request.
582d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    request->buffer = mBuffer;
583d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    allocate(maxBulkTransferSize);
584d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
585d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    while (processedBytes < containerLength) {
586d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        size_t bulkTransferSize = 0;
587d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
588d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        // prepare header.
589d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        const bool headerSent = processedBytes != 0;
590d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        if (!headerSent) {
591d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, containerLength);
592d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
593d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            bulkTransferSize += MTP_CONTAINER_HEADER_SIZE;
594d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        }
595d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
596d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        // Prepare payload.
597d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        if (headerSent || divisionMode == FIRST_PACKET_HAS_PAYLOAD) {
598d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            const size_t processedPayloadBytes =
599d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                    headerSent ? processedBytes - MTP_CONTAINER_HEADER_SIZE : 0;
600d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            const size_t maxRead = payloadSize - processedPayloadBytes;
601d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            const size_t maxWrite = maxBulkTransferSize - bulkTransferSize;
602d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            const size_t bulkTransferPayloadSize = std::min(maxRead, maxWrite);
603d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            // prepare payload.
604d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            if (!readError) {
605d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                const ssize_t result = readExactBytes(
606d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                        fd,
607d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                        mBuffer + bulkTransferSize,
608d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                        bulkTransferPayloadSize);
609d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                if (result < 0) {
610d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                    ALOGE("Found an error while reading data from FD. Send 0 data instead.");
611d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                    readError = true;
612d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                }
613d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            }
614d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            if (readError) {
615d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono                memset(mBuffer + bulkTransferSize, 0, bulkTransferPayloadSize);
616d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            }
617d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            bulkTransferSize += bulkTransferPayloadSize;
618d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        }
619d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
620d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        // Bulk transfer.
621d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        mPacketSize = bulkTransferSize;
622d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        request->buffer_length = bulkTransferSize;
623d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        const int result = transfer(request);
624d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        if (result != static_cast<ssize_t>(bulkTransferSize)) {
625d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            // Cannot recover writing error.
626d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            ALOGE("Found an error while write data to MtpDevice.");
627d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono            return -1;
628d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        }
629d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
630d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        // Update variables.
631d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono        processedBytes += bulkTransferSize;
632d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    }
633d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono
634d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono    return readError ? -1 : processedBytes;
6350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
6360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
63716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_HOST
6387850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
6394fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hironovoid* MtpDataPacket::getData(int* outLength) const {
6403e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
6413e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (length > 0) {
6423e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        void* result = malloc(length);
6433e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        if (result) {
6443e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length);
6454fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono            *outLength = length;
6463e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            return result;
6473e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
6483e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
6494fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono    *outLength = 0;
6503e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return NULL;
6513e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood}
6523e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
6537850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood}  // namespace android
654