最后
希望本文对你有所启发,有任何面试上的建议也欢迎留言分享给大家。
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。
为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-
private:
-
Parcel(const Parcel& o);
-
Parcel& operator=(const Parcel& o);
-
status_t finishWrite(size_t len);
-
void releaseObjects();
-
void acquireObjects();
-
status_t growData(size_t len);
-
status_t restartWrite(size_t desired);
-
status_t continueWrite(size_t desired);
-
void freeDataNoInit();
-
void initState();
-
void scanForFds() const;
-
template
-
status_t readAligned(T *pArg) const;
-
template T readAligned() const;
-
template
-
status_t writeAligned(T val);
-
status_t mError;
-
uint8_t* mData;
-
size_t mDataSize;
-
size_t mDataCapacity;
-
mutable size_t mDataPos;
-
size_t* mObjects;
-
size_t mObjectsSize;
-
size_t mObjectsCapacity;
-
mutable size_t mNextObjectHint;
-
mutable bool mFdsKnown;
-
mutable bool mHasFds;
-
release_func mOwner;
-
void* mOwnerCookie;
-
};
-
// ---------------------------------------------------------------------------
-
inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
-
{
-
parcel.print(to);
-
return to;
-
}
-
// ---------------------------------------------------------------------------
-
// Generic acquire and release of objects.
-
void acquire_object(const sp& proc,
-
const flat_binder_object& obj, const void* who);
-
void release_object(const sp& proc,
-
const flat_binder_object& obj, const void* who);
-
void flatten_binder(const sp& proc,
-
const sp& binder, flat_binder_object* out);
-
void flatten_binder(const sp& proc,
-
const wp& binder, flat_binder_object* out);
-
status_t unflatten_binder(const sp& proc,
-
const flat_binder_object& flat, sp* out);
-
status_t unflatten_binder(const sp& proc,
-
const flat_binder_object& flat, wp* out);
-
}; // namespace android
-
// ---------------------------------------------------------------------------
-
#endif // ANDROID_PARCEL_H
[cpp] view plain copy
-
/*
-
* Copyright © 2005 The Android Open Source Project
-
*
-
* Licensed under the Apache License, Version 2.0 (the “License”);
-
* you may not use this file except in compliance with the License.
-
* You may obtain a copy of the License at
-
*
-
* http://www.apache.org/licenses/LICENSE-2.0
-
*
-
* Unless required by applicable law or agreed to in writing, software
-
* distributed under the License is distributed on an “AS IS” BASIS,
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-
* See the License for the specific language governing permissions and
-
* limitations under the License.
-
*/
-
#define LOG_TAG “Parcel”
-
//#define LOG_NDEBUG 0
-
#include <binder/Parcel.h>
-
#include <binder/Binder.h>
-
#include <binder/BpBinder.h>
-
#include <utils/Debug.h>
-
#include <binder/ProcessState.h>
-
#include <utils/Log.h>
-
#include <utils/String8.h>
-
#include <utils/String16.h>
-
#include <utils/TextOutput.h>
-
#include <utils/misc.h>
-
#include <utils/Flattenable.h>
-
#include <private/binder/binder_module.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <stdint.h>
-
#ifndef INT32_MAX
-
#define INT32_MAX ((int32_t)(2147483647))
-
#endif
-
#define LOG_REFS(…)
-
//#define LOG_REFS(…) LOG(LOG_DEBUG, “Parcel”, __VA_ARGS__)
-
// ---------------------------------------------------------------------------
-
#define PAD_SIZE(s) (((s)+3)&~3)
-
// XXX This can be made public if we want to provide
-
// support for typed data.
-
struct small_flat_data
-
{
-
uint32_t type;
-
uint32_t data;
-
};
-
namespace android {
-
void acquire_object(const sp& proc,
-
const flat_binder_object& obj, const void* who)
-
{
-
switch (obj.type) {
-
case BINDER_TYPE_BINDER:
-
if (obj.binder) {
-
LOG_REFS(“Parcel %p acquiring reference on local %p”, who, obj.cookie);
-
static_cast<IBinder*>(obj.cookie)->incStrong(who);
-
}
-
return;
-
case BINDER_TYPE_WEAK_BINDER:
-
if (obj.binder)
-
static_castRefBase::weakref\_type\*(obj.binder)->incWeak(who);
-
return;
-
case BINDER_TYPE_HANDLE: {
-
const sp b = proc->getStrongProxyForHandle(obj.handle);
-
if (b != NULL) {
-
LOG_REFS(“Parcel %p acquiring reference on remote %p”, who, b.get());
-
b->incStrong(who);
-
}
-
return;
-
}
-
case BINDER_TYPE_WEAK_HANDLE: {
-
const wp b = proc->getWeakProxyForHandle(obj.handle);
-
if (b != NULL) b.get_refs()->incWeak(who);
-
return;
-
}
-
case BINDER_TYPE_FD: {
-
// intentionally blank – nothing to do to acquire this, but we do
-
// recognize it as a legitimate object type.
-
return;
-
}
-
}
-
LOGD(“Invalid object type 0x%08lx”, obj.type);
-
}
-
void release_object(const sp& proc,
-
const flat_binder_object& obj, const void* who)
-
{
-
switch (obj.type) {
-
case BINDER_TYPE_BINDER:
-
if (obj.binder) {
-
LOG_REFS(“Parcel %p releasing reference on local %p”, who, obj.cookie);
-
static_cast<IBinder*>(obj.cookie)->decStrong(who);
-
}
-
return;
-
case BINDER_TYPE_WEAK_BINDER:
-
if (obj.binder)
-
static_castRefBase::weakref\_type\*(obj.binder)->decWeak(who);
-
return;
-
case BINDER_TYPE_HANDLE: {
-
const sp b = proc->getStrongProxyForHandle(obj.handle);
-
if (b != NULL) {
-
LOG_REFS(“Parcel %p releasing reference on remote %p”, who, b.get());
-
b->decStrong(who);
-
}
-
return;
-
}
-
case BINDER_TYPE_WEAK_HANDLE: {
-
const wp b = proc->getWeakProxyForHandle(obj.handle);
-
if (b != NULL) b.get_refs()->decWeak(who);
-
return;
-
}
-
case BINDER_TYPE_FD: {
-
if (obj.cookie != (void*)0) close(obj.handle);
-
return;
-
}
-
}
-
LOGE(“Invalid object type 0x%08lx”, obj.type);
-
}
-
inline static status_t finish_flatten_binder(
-
const sp& binder, const flat_binder_object& flat, Parcel* out)
-
{
-
return out->writeObject(flat, false);
-
}
-
status_t flatten_binder(const sp& proc,
-
const sp& binder, Parcel* out)
-
{
-
flat_binder_object obj;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
if (binder != NULL) {
-
IBinder *local = binder->localBinder();
-
if (!local) {
-
BpBinder *proxy = binder->remoteBinder();
-
if (proxy == NULL) {
-
LOGE(“null proxy”);
-
}
-
const int32_t handle = proxy ? proxy->handle() : 0;
-
obj.type = BINDER_TYPE_HANDLE;
-
obj.handle = handle;
-
obj.cookie = NULL;
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = local->getWeakRefs();
-
obj.cookie = local;
-
}
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
}
-
return finish_flatten_binder(binder, obj, out);
-
}
-
status_t flatten_binder(const sp& proc,
-
const wp& binder, Parcel* out)
-
{
-
flat_binder_object obj;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
if (binder != NULL) {
-
sp real = binder.promote();
-
if (real != NULL) {
-
IBinder *local = real->localBinder();
-
if (!local) {
-
BpBinder *proxy = real->remoteBinder();
-
if (proxy == NULL) {
-
LOGE(“null proxy”);
-
}
-
const int32_t handle = proxy ? proxy->handle() : 0;
-
obj.type = BINDER_TYPE_WEAK_HANDLE;
-
obj.handle = handle;
-
obj.cookie = NULL;
-
} else {
-
obj.type = BINDER_TYPE_WEAK_BINDER;
-
obj.binder = binder.get_refs();
-
obj.cookie = binder.unsafe_get();
-
}
-
return finish_flatten_binder(real, obj, out);
-
}
-
// XXX How to deal? In order to flatten the given binder,
-
// we need to probe it for information, which requires a primary
-
// reference… but we don’t have one.
-
//
-
// The OpenBinder implementation uses a dynamic_cast<> here,
-
// but we can’t do that with the different reference counting
-
// implementation we are using.
-
LOGE(“Unable to unflatten Binder weak reference!”);
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
return finish_flatten_binder(NULL, obj, out);
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
return finish_flatten_binder(NULL, obj, out);
-
}
-
}
-
inline static status_t finish_unflatten_binder(
-
BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
-
{
-
return NO_ERROR;
-
}
-
status_t unflatten_binder(const sp& proc,
-
const Parcel& in, sp* out)
-
{
-
const flat_binder_object* flat = in.readObject(false);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_BINDER:
-
*out = static_cast<IBinder*>(flat->cookie);
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_HANDLE:
-
*out = proc->getStrongProxyForHandle(flat->handle);
-
return finish_unflatten_binder(
-
static_cast<BpBinder*>(out->get()), *flat, in);
-
}
-
}
-
return BAD_TYPE;
-
}
-
status_t unflatten_binder(const sp& proc,
-
const Parcel& in, wp* out)
-
{
-
const flat_binder_object* flat = in.readObject(false);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_BINDER:
-
*out = static_cast<IBinder*>(flat->cookie);
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_WEAK_BINDER:
-
if (flat->binder != NULL) {
-
out->set_object_and_refs(
-
static_cast<IBinder*>(flat->cookie),
-
static_castRefBase::weakref\_type\*(flat->binder));
-
} else {
-
*out = NULL;
-
}
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_HANDLE:
-
case BINDER_TYPE_WEAK_HANDLE:
-
*out = proc->getWeakProxyForHandle(flat->handle);
-
return finish_unflatten_binder(
-
static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
-
}
-
}
-
return BAD_TYPE;
-
}
-
// ---------------------------------------------------------------------------
-
Parcel::Parcel()
-
{
-
initState();
-
}
-
Parcel::~Parcel()
-
{
-
freeDataNoInit();
-
}
-
const uint8_t* Parcel::data() const
-
{
-
return mData;
-
}
-
size_t Parcel::dataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
size_t Parcel::dataAvail() const
-
{
-
// TODO: decide what to do about the possibility that this can
-
// report an available-data size that exceeds a Java int’s max
-
// positive value, causing havoc. Fortunately this will only
-
// happen if someone constructs a Parcel containing more than two
-
// gigabytes of data, which on typical phone hardware is simply
-
// not possible.
-
return dataSize() - dataPosition();
-
}
-
size_t Parcel::dataPosition() const
-
{
-
return mDataPos;
-
}
-
size_t Parcel::dataCapacity() const
-
{
-
return mDataCapacity;
-
}
-
status_t Parcel::setDataSize(size_t size)
-
{
-
status_t err;
-
err = continueWrite(size);
-
if (err == NO_ERROR) {
-
mDataSize = size;
-
LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);
-
}
-
return err;
-
}
-
void Parcel::setDataPosition(size_t pos) const
-
{
-
mDataPos = pos;
-
mNextObjectHint = 0;
-
}
-
status_t Parcel::setDataCapacity(size_t size)
-
{
-
if (size > mDataSize) return continueWrite(size);
-
return NO_ERROR;
-
}
-
status_t Parcel::setData(const uint8_t* buffer, size_t len)
-
{
-
status_t err = restartWrite(len);
-
if (err == NO_ERROR) {
-
memcpy(const_cast<uint8_t*>(data()), buffer, len);
-
mDataSize = len;
-
mFdsKnown = false;
-
}
-
return err;
-
}
-
status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
-
{
-
const sp proc(ProcessState::self());
-
status_t err;
-
uint8_t *data = parcel->mData;
-
size_t *objects = parcel->mObjects;
-
size_t size = parcel->mObjectsSize;
-
int startPos = mDataPos;
-
int firstIndex = -1, lastIndex = -2;
-
if (len == 0) {
-
return NO_ERROR;
-
}
-
// range checks against the source parcel size
-
if ((offset > parcel->mDataSize)
-
|| (len > parcel->mDataSize)
-
|| (offset + len > parcel->mDataSize)) {
-
return BAD_VALUE;
-
}
-
// Count objects in range
-
for (int i = 0; i < (int) size; i++) {
-
size_t off = objects[i];
-
if ((off >= offset) && (off < offset + len)) {
-
if (firstIndex == -1) {
-
firstIndex = i;
-
}
-
lastIndex = i;
-
}
-
}
-
int numObjects = lastIndex - firstIndex + 1;
-
// grow data
-
err = growData(len);
-
if (err != NO_ERROR) {
-
return err;
-
}
-
// append data
-
memcpy(mData + mDataPos, data + offset, len);
-
mDataPos += len;
-
mDataSize += len;
-
if (numObjects > 0) {
-
// grow objects
-
if (mObjectsCapacity < mObjectsSize + numObjects) {
-
int newSize = ((mObjectsSize + numObjects)*3)/2;
-
size_t *objects =
-
(size_t*)realloc(mObjects, newSize*sizeof(size_t));
-
if (objects == (size_t*)0) {
-
return NO_MEMORY;
-
}
-
mObjects = objects;
-
mObjectsCapacity = newSize;
-
}
-
// append and acquire objects
-
int idx = mObjectsSize;
-
for (int i = firstIndex; i <= lastIndex; i++) {
-
size_t off = objects[i] - offset + startPos;
-
mObjects[idx++] = off;
-
mObjectsSize++;
-
flat_binder_object* flat
-
= reinterpret_cast<flat_binder_object*>(mData + off);
-
acquire_object(proc, *flat, this);
-
if (flat->type == BINDER_TYPE_FD) {
-
// If this is a file descriptor, we need to dup it so the
-
// new Parcel now owns its own fd, and can declare that we
-
// officially know we have fds.
-
flat->handle = dup(flat->handle);
-
flat->cookie = (void*)1;
-
mHasFds = mFdsKnown = true;
-
}
-
}
-
}
-
return NO_ERROR;
-
}
-
bool Parcel::hasFileDescriptors() const
-
{
-
if (!mFdsKnown) {
-
scanForFds();
-
}
-
return mHasFds;
-
}
-
status_t Parcel::writeInterfaceToken(const String16& interface)
-
{
-
// currently the interface identification token is just its name as a string
-
return writeString16(interface);
-
}
-
bool Parcel::checkInterface(IBinder* binder) const
-
{
-
return enforceInterface(binder->getInterfaceDescriptor());
-
}
-
bool Parcel::enforceInterface(const String16& interface) const
-
{
-
const String16 str(readString16());
-
if (str == interface) {
-
return true;
-
} else {
-
LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,
-
String8(interface).string(), String8(str).string());
-
return false;
-
}
-
}
-
const size_t* Parcel::objects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::objectsCount() const
-
{
-
return mObjectsSize;
-
}
-
status_t Parcel::errorCheck() const
-
{
-
return mError;
-
}
-
void Parcel::setError(status_t err)
-
{
-
mError = err;
-
}
-
status_t Parcel::finishWrite(size_t len)
-
{
-
//printf(“Finish write of %d/n”, len);
-
mDataPos += len;
-
LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);
-
if (mDataPos > mDataSize) {
-
mDataSize = mDataPos;
-
LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);
-
}
-
//printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);
-
return NO_ERROR;
-
}
-
status_t Parcel::writeUnpadded(const void* data, size_t len)
-
{
-
size_t end = mDataPos + len;
-
if (end < mDataPos) {
-
// integer overflow
-
return BAD_VALUE;
-
}
-
if (end <= mDataCapacity) {
-
restart_write:
-
memcpy(mData+mDataPos, data, len);
-
return finishWrite(len);
-
}
-
status_t err = growData(len);
-
if (err == NO_ERROR) goto restart_write;
-
return err;
-
}
-
status_t Parcel::write(const void* data, size_t len)
-
{
-
void* const d = writeInplace(len);
-
if (d) {
-
memcpy(d, data, len);
-
return NO_ERROR;
-
}
-
return mError;
-
}
-
void* Parcel::writeInplace(size_t len)
-
{
-
const size_t padded = PAD_SIZE(len);
-
// sanity check for integer overflow
-
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;
-
}
-
status_t Parcel::writeInt32(int32_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeInt64(int64_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeFloat(float val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeDouble(double val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeIntPtr(intptr_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeCString(const char* str)
-
{
-
return write(str, strlen(str)+1);
-
}
-
status_t Parcel::writeString8(const String8& str)
-
{
-
status_t err = writeInt32(str.bytes());
-
if (err == NO_ERROR) {
-
err = write(str.string(), str.bytes()+1);
-
}
-
return err;
-
}
-
status_t Parcel::writeString16(const String16& str)
-
{
-
return writeString16(str.string(), str.size());
-
}
-
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::writeStrongBinder(const sp& val)
-
{
-
return flatten_binder(ProcessState::self(), val, this);
-
}
-
status_t Parcel::writeWeakBinder(const wp& val)
-
{
-
return flatten_binder(ProcessState::self(), val, this);
-
}
-
status_t Parcel::writeNativeHandle(const native_handle* handle)
-
{
-
if (!handle || handle->version != sizeof(native_handle))
-
return BAD_TYPE;
-
status_t err;
-
err = writeInt32(handle->numFds);
-
if (err != NO_ERROR) return err;
-
err = writeInt32(handle->numInts);
-
if (err != NO_ERROR) return err;
-
for (int i=0 ; err==NO_ERROR && inumFds ; i++)
-
err = writeDupFileDescriptor(handle->data[i]);
-
if (err != NO_ERROR) {
-
LOGD(“write native handle, write dup fd failed”);
-
return err;
-
}
-
err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
-
return err;
-
}
-
status_t Parcel::writeFileDescriptor(int fd)
-
{
-
flat_binder_object obj;
-
obj.type = BINDER_TYPE_FD;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
obj.handle = fd;
-
obj.cookie = (void*)0;
-
return writeObject(obj, true);
-
}
-
status_t Parcel::writeDupFileDescriptor(int fd)
-
{
-
flat_binder_object obj;
-
obj.type = BINDER_TYPE_FD;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
obj.handle = dup(fd);
-
obj.cookie = (void*)1;
-
return writeObject(obj, true);
-
}
-
status_t Parcel::write(const Flattenable& val)
-
{
-
status_t err;
-
// size if needed
-
size_t len = val.getFlattenedSize();
-
size_t fd_count = val.getFdCount();
-
err = this->writeInt32(len);
-
if (err) return err;
-
err = this->writeInt32(fd_count);
-
if (err) return err;
-
// payload
-
void* buf = this->writeInplace(PAD_SIZE(len));
-
if (buf == NULL)
-
return BAD_VALUE;
-
int* fds = NULL;
-
if (fd_count) {
-
fds = new int[fd_count];
-
}
-
err = val.flatten(buf, len, fds, fd_count);
-
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-
err = this->writeDupFileDescriptor( fds[i] );
-
}
-
if (fd_count) {
-
delete [] fds;
-
}
-
return err;
-
}
-
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
-
{
-
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
-
const bool enoughObjects = mObjectsSize < mObjectsCapacity;
-
if (enoughData && enoughObjects) {
-
restart_write:
-
*reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
-
// Need to write meta-data?
-
if (nullMetaData || val.binder != NULL) {
-
mObjects[mObjectsSize] = mDataPos;
-
acquire_object(ProcessState::self(), val, this);
-
mObjectsSize++;
-
}
-
// remember if it’s a file descriptor
-
if (val.type == BINDER_TYPE_FD) {
-
mHasFds = mFdsKnown = true;
-
}
-
return finishWrite(sizeof(flat_binder_object));
-
}
-
if (!enoughData) {
-
const status_t err = growData(sizeof(val));
-
if (err != NO_ERROR) return err;
-
}
-
if (!enoughObjects) {
-
size_t newSize = ((mObjectsSize+2)*3)/2;
-
size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
-
if (objects == NULL) return NO_MEMORY;
-
mObjects = objects;
-
mObjectsCapacity = newSize;
-
}
-
goto restart_write;
-
}
-
void Parcel::remove(size_t start, size_t amt)
-
{
-
LOG_ALWAYS_FATAL(“Parcel::remove() not yet implemented!”);
-
}
-
status_t Parcel::read(void* outData, size_t len) const
-
{
-
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
-
memcpy(outData, mData+mDataPos, len);
-
mDataPos += PAD_SIZE(len);
-
LOGV(“read Setting data pos of %p to %d/n”, this, mDataPos);
-
return NO_ERROR;
-
}
-
return NOT_ENOUGH_DATA;
-
}
-
const void* Parcel::readInplace(size_t len) const
-
{
-
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
-
const void* data = mData+mDataPos;
-
mDataPos += PAD_SIZE(len);
-
LOGV(“readInplace Setting data pos of %p to %d/n”, this, mDataPos);
-
return data;
-
}
-
return NULL;
-
}
-
template
-
status_t Parcel::readAligned(T *pArg) const {
-
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
if ((mDataPos+sizeof(T)) <= mDataSize) {
-
const void* data = mData+mDataPos;
-
mDataPos += sizeof(T);
-
*pArg = *reinterpret_cast<const T*>(data);
-
return NO_ERROR;
-
} else {
-
return NOT_ENOUGH_DATA;
-
}
-
}
-
template
-
T Parcel::readAligned() const {
-
T result;
-
if (readAligned(&result) != NO_ERROR) {
-
result = 0;
-
}
-
return result;
-
}
-
template
-
status_t Parcel::writeAligned(T val) {
-
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-
restart_write:
-
*reinterpret_cast<T*>(mData+mDataPos) = val;
-
return finishWrite(sizeof(val));
-
}
-
status_t err = growData(sizeof(val));
-
if (err == NO_ERROR) goto restart_write;
-
return err;
-
}
-
status_t Parcel::readInt32(int32_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
int32_t Parcel::readInt32() const
-
{
-
return readAligned<int32_t>();
-
}
-
status_t Parcel::readInt64(int64_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
int64_t Parcel::readInt64() const
-
{
-
return readAligned<int64_t>();
-
}
-
status_t Parcel::readFloat(float *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
float Parcel::readFloat() const
-
{
-
return readAligned<float>();
-
}
-
status_t Parcel::readDouble(double *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
double Parcel::readDouble() const
-
{
-
return readAligned<double>();
-
}
-
status_t Parcel::readIntPtr(intptr_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
intptr_t Parcel::readIntPtr() const
-
{
-
return readAligned<intptr_t>();
-
}
-
const char* Parcel::readCString() const
-
{
-
const size_t avail = mDataSize-mDataPos;
-
if (avail > 0) {
-
const char* str = reinterpret_cast<const char*>(mData+mDataPos);
-
// is the string’s trailing NUL within the parcel’s valid bounds?
-
const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
-
if (eos) {
-
const size_t len = eos - str;
-
mDataPos += PAD_SIZE(len+1);
-
LOGV(“readCString Setting data pos of %p to %d/n”, this, mDataPos);
-
return str;
-
}
-
}
-
return NULL;
-
}
-
String8 Parcel::readString8() const
-
{
-
int32_t size = readInt32();
-
// watch for potential int overflow adding 1 for trailing NUL
-
if (size > 0 && size < INT32_MAX) {
-
const char* str = (const char*)readInplace(size+1);
-
if (str) return String8(str, size);
-
}
-
return String8();
-
}
-
String16 Parcel::readString16() const
-
{
-
size_t len;
-
const char16_t* str = readString16Inplace(&len);
-
if (str) return String16(str, len);
-
LOGE(“Reading a NULL string not supported here.”);
-
return String16();
-
}
-
const char16_t* Parcel::readString16Inplace(size_t* outLen) const
-
{
-
int32_t size = readInt32();
-
// watch for potential int overflow from size+1
-
if (size >= 0 && size < INT32_MAX) {
-
*outLen = size;
-
const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
-
if (str != NULL) {
-
return str;
-
}
-
}
-
*outLen = 0;
-
return NULL;
-
}
-
sp Parcel::readStrongBinder() const
-
{
-
sp val;
-
unflatten_binder(ProcessState::self(), *this, &val);
-
return val;
-
}
-
wp Parcel::readWeakBinder() const
-
{
-
wp val;
-
unflatten_binder(ProcessState::self(), *this, &val);
-
return val;
-
}
-
native_handle* Parcel::readNativeHandle() const
-
{
-
int numFds, numInts;
-
status_t err;
-
err = readInt32(&numFds);
-
if (err != NO_ERROR) return 0;
-
err = readInt32(&numInts);
-
if (err != NO_ERROR) return 0;
-
native_handle* h = native_handle_create(numFds, numInts);
-
for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
-
h->data[i] = dup(readFileDescriptor());
-
if (h->data[i] < 0) err = BAD_VALUE;
-
}
-
err = read(h->data + numFds, sizeof(int)*numInts);
-
if (err != NO_ERROR) {
-
native_handle_close(h);
-
native_handle_delete(h);
-
h = 0;
-
}
-
return h;
-
}
-
int Parcel::readFileDescriptor() const
-
{
-
const flat_binder_object* flat = readObject(true);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_FD:
-
//LOGI(“Returning file descriptor %ld from parcel %p/n”, flat->handle, this);
-
return flat->handle;
-
}
-
}
-
return BAD_TYPE;
-
}
-
status_t Parcel::read(Flattenable& val) const
-
{
-
// size
-
const size_t len = this->readInt32();
-
const size_t fd_count = this->readInt32();
-
// payload
-
void const* buf = this->readInplace(PAD_SIZE(len));
-
if (buf == NULL)
-
return BAD_VALUE;
-
int* fds = NULL;
-
if (fd_count) {
-
fds = new int[fd_count];
-
}
-
status_t err = NO_ERROR;
-
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-
fds[i] = dup(this->readFileDescriptor());
-
if (fds[i] < 0) err = BAD_VALUE;
-
}
-
if (err == NO_ERROR) {
-
err = val.unflatten(buf, len, fds, fd_count);
-
}
-
if (fd_count) {
-
delete [] fds;
-
}
-
return err;
-
}
-
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
-
{
-
const size_t DPOS = mDataPos;
-
if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
-
const flat_binder_object* obj
-
= reinterpret_cast<const flat_binder_object*>(mData+DPOS);
-
mDataPos = DPOS + sizeof(flat_binder_object);
-
if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
-
// When transferring a NULL object, we don’t write it into
-
// the object list, so we don’t want to check for it when
-
// reading.
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
// Ensure that this object is valid…
-
size_t* const OBJS = mObjects;
-
const size_t N = mObjectsSize;
-
size_t opos = mNextObjectHint;
-
if (N > 0) {
-
LOGV(“Parcel %p looking for obj at %d, hint=%d/n”,
-
this, DPOS, opos);
-
// Start at the current hint position, looking for an object at
-
// the current data position.
-
if (opos < N) {
-
while (opos < (N-1) && OBJS[opos] < DPOS) {
-
opos++;
-
}
-
} else {
-
opos = N-1;
-
}
-
if (OBJS[opos] == DPOS) {
-
// Found it!
-
LOGV(“Parcel found obj %d at index %d with forward search”,
-
this, DPOS, opos);
-
mNextObjectHint = opos+1;
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
// Look backwards for it…
-
while (opos > 0 && OBJS[opos] > DPOS) {
-
opos–;
-
}
-
if (OBJS[opos] == DPOS) {
-
// Found it!
-
LOGV(“Parcel found obj %d at index %d with backward search”,
-
this, DPOS, opos);
-
mNextObjectHint = opos+1;
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
}
-
LOGW(“Attempt to read object from Parcel %p at offset %d that is not in the object list”,
-
this, DPOS);
-
}
-
return NULL;
-
}
-
void Parcel::closeFileDescriptors()
-
{
-
size_t i = mObjectsSize;
-
if (i > 0) {
-
//LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);
-
}
-
while (i > 0) {
-
i–;
-
const flat_binder_object* flat
-
= reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
-
if (flat->type == BINDER_TYPE_FD) {
-
//LOGI(“Closing fd: %ld/n”, flat->handle);
-
close(flat->handle);
-
}
-
}
-
}
-
const uint8_t* Parcel::ipcData() const
-
{
-
return mData;
-
}
-
size_t Parcel::ipcDataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
const size_t* Parcel::ipcObjects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::ipcObjectsCount() const
-
{
-
return mObjectsSize;
-
}
-
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-
const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-
{
-
freeDataNoInit();
-
mError = NO_ERROR;
-
mData = const_cast<uint8_t*>(data);
-
mDataSize = mDataCapacity = dataSize;
-
//LOGI(“setDataReference Setting data size of %p to %lu (pid=%d)/n”, this, mDataSize, getpid());
-
mDataPos = 0;
-
LOGV(“setDataReference Setting data pos of %p to %d/n”, this, mDataPos);
-
mObjects = const_cast<size_t*>(objects);
-
mObjectsSize = mObjectsCapacity = objectsCount;
-
mNextObjectHint = 0;
-
mOwner = relFunc;
-
mOwnerCookie = relCookie;
-
scanForFds();
-
}
最后
代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。
所以,长征路还长,大家还是好好地做个务实的程序员吧。
最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
e;
-
if (i > 0) {
-
//LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);
-
}
-
while (i > 0) {
-
i–;
-
const flat_binder_object* flat
-
= reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
-
if (flat->type == BINDER_TYPE_FD) {
-
//LOGI(“Closing fd: %ld/n”, flat->handle);
-
close(flat->handle);
-
}
-
}
-
}
-
const uint8_t* Parcel::ipcData() const
-
{
-
return mData;
-
}
-
size_t Parcel::ipcDataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
const size_t* Parcel::ipcObjects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::ipcObjectsCount() const
-
{
-
return mObjectsSize;
-
}
-
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-
const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-
{
-
freeDataNoInit();
-
mError = NO_ERROR;
-
mData = const_cast<uint8_t*>(data);
-
mDataSize = mDataCapacity = dataSize;
-
//LOGI(“setDataReference Setting data size of %p to %lu (pid=%d)/n”, this, mDataSize, getpid());
-
mDataPos = 0;
-
LOGV(“setDataReference Setting data pos of %p to %d/n”, this, mDataPos);
-
mObjects = const_cast<size_t*>(objects);
-
mObjectsSize = mObjectsCapacity = objectsCount;
-
mNextObjectHint = 0;
-
mOwner = relFunc;
-
mOwnerCookie = relCookie;
-
scanForFds();
-
}
最后
代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。
所以,长征路还长,大家还是好好地做个务实的程序员吧。
最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!