parcel

300 阅读3分钟

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;
};