parcel连续内存空间存放数据
/**
* parcel连续的内存空间
* mData 存放数据
* mDataPos 偏移指向最后一个数据的下一个位置
* mObjects 存放所有flat_binder_object数据在mData中的偏移位置
* mObjects方便读取所有flat_binder_object数据
* readInt诸如此类知道长度的读取,直接读取sizeOf(T)长度数据, mDataPos + sizeOf(T)
* readString诸如此类数据, 需要先读取长度readInt,再读取按4个字节倍数读取data, data(0, n)即最终数据
* writeInt诸如此类数据直接写入,mDataPos + sizeOf(T)
* readString诸如此类数据,需要填充按4个字节倍数写入
*/
// This macro should never be used at runtime, as a too large value
// of s could cause an integer overflow. Instead, you should always
// use the wrapper function pad_size()
/**
* 3 0011
* ~3 1100
* 假如s 为 3 3+3=6 110
* 1100
* 0110 &
* 0100 = 4
*/
#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
static size_t pad_size(size_t s) {
if (s > (SIZE_T_MAX - 3)) {
abort();
}
return PAD_SIZE_UNSAFE(s);
}
/***
* write T, 如 int、float、long
* @tparam T
* @param val
* @return
*/
template<class T>
status_t Parcel::writeAligned(T val) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
// 判断是否空间不足
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
// 空间足够直接写入数据
*reinterpret_cast<T*>(mData+mDataPos) = val;
// mDataPos增加新写入数据长度
// mDataPos + sizeof(val)
return finishWrite(sizeof(val));
}
// 扩容后继续写入
status_t err = growData(sizeof(val));
if (err == NO_ERROR) goto restart_write;
return err;
}
// 写入类似字符串这种非固定长度字节
// 先写入数据长度
// 按4字节对齐写入数据
status_t Parcel::writeString16(const char16_t* str, size_t len)
{
if (str == NULL) return writeInt32(-1);
status_t err = writeInt32(len);
if (err == NO_ERROR) {
len *= sizeof(char16_t);
uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
if (data) {
memcpy(data, str, len);
*reinterpret_cast<char16_t*>(data+len) = 0;
return NO_ERROR;
}
err = mError;
}
return err;
}
status_t Parcel::writeString16(const char16_t* str, size_t len)
{
if (str == NULL) return writeInt32(-1);
status_t err = writeInt32(len);
if (err == NO_ERROR) {
len *= sizeof(char16_t);
uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
if (data) {
memcpy(data, str, len);
*reinterpret_cast<char16_t*>(data+len) = 0;
return NO_ERROR;
}
err = mError;
}
return err;
}
/**
* 写入pad_size(len) 4字节对齐数据长度
* @param len
* @return
*/
void* Parcel::writeInplace(size_t len)
{
if (len > INT32_MAX) {
// don't accept size_t values which may have come from an
// inadvertent conversion from a negative int.
return NULL;
}
// pad_size (((s)+3)&~3)
// padded = (((len)+3)&~len)
const size_t padded = pad_size(len);
// sanity check for integer overflow
// padded 负数错误
if (mDataPos+padded < mDataPos) {
return NULL;
}
if ((mDataPos+padded) <= mDataCapacity) {
restart_write:
//printf("Writing %ld bytes, padded to %ld\n", len, padded);
uint8_t* const data = mData+mDataPos;
// Need to pad at end?
if (padded != len) {
#if BYTE_ORDER == BIG_ENDIAN
static const uint32_t mask[4] = {
0x00000000, 0xffffff00, 0xffff0000, 0xff000000
};
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
static const uint32_t mask[4] = {
0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
};
#endif
//printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
// *reinterpret_cast<void**>(data+padded-4));
*reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
}
finishWrite(padded);
return data;
}
status_t err = growData(padded);
if (err == NO_ERROR) goto restart_write;
return NULL;
}
/**
* parcel 写入binder扁平化数据flat_binder_object
* @param mData存放所有数据
*
* @param nullMetaData
* @return
*/
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
{
// 还有足够空间存入binder扁平化数据flat_binder_object
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
// 还有足够binder对象大小存入binder扁平化数据flat_binder_object
const bool enoughObjects = mObjectsSize < mObjectsCapacity;
if (enoughData && enoughObjects) {
restart_write:
// mdata数据起始指针
// 当前数据最后一个数据位置mDataPos
// 存放flat_binder_object数据
*reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
// remember if it's a file descriptor
if (val.hdr.type == BINDER_TYPE_FD) {
if (!mAllowFds) {
// fail before modifying our object index
return FDS_NOT_ALLOWED;
}
mHasFds = mFdsKnown = true;
}
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
// mobjects数组记录此次存放flat_binder_object数据位置mDataPos
mObjects[mObjectsSize] = mDataPos;
acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
// mObjects数量 + 1
mObjectsSize++;
}
// mDataPos = mDataPos + 一个flat_binder_object长度
return finishWrite(sizeof(flat_binder_object));
}
// 空间不足存放binder扁平化对象,扩容
if (!enoughData) {
const status_t err = growData(sizeof(val));
if (err != NO_ERROR) return err;
}
// binder数量已超标扩容
if (!enoughObjects) {
size_t newSize = ((mObjectsSize+2)*3)/2;
if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
if (objects == NULL) return NO_MEMORY;
mObjects = objects;
mObjectsCapacity = newSize;
}
// 扩容后重新写入
goto restart_write;
}
uintptr_t Parcel::ipcData() const
{
return reinterpret_cast<uintptr_t>(mData);
}
size_t Parcel::ipcDataSize() const
{
return (mDataSize > mDataPos ? mDataSize : mDataPos);
}
/**
* mObjects作用就体现了,可以快速获取object对象即所有flat_binder_object对象
* @return
*/
uintptr_t Parcel::ipcObjects() const
{
return reinterpret_cast<uintptr_t>(mObjects);
}
size_t Parcel::ipcObjectsCount() const
{
return mObjectsSize;
}
struct flat_binder_object {
/* 8 bytes for large_flat_header. */
unsigned long type;
unsigned long flags;
/* 8 bytes of data. */
// void * 无类型指针可指向任何类型数据
// 每个传输的flat_binder_object数据
// 本地binder对象会挂载在当前进程binder_proc binder_node节点树上
// 本地binder对象会挂载以handle句柄为标识在远程调用进程binder_proc binder_node_desc节点树上
union {
void *binder; /* local object */
signed long handle; /* remote object */
};
/* extra data associated with local object */
// cookie指针强转成BBinder对应到服务
void *cookie;
};