parcel

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2026 License: CC0-1.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// StabilityUndeclared is the default stability for null binder objects.
	StabilityUndeclared = StabilityLevel(0)

	// StabilitySystem is the stability for system (non-VNDK) binder objects.
	// This matches getLocalLevel() in system builds.
	StabilitySystem = StabilityLevel(0b001100) // 12
)

Variables

This section is empty.

Functions

func ReadParcelableHeader

func ReadParcelableHeader(
	p *Parcel,
) (int, error)

ReadParcelableHeader reads the size of a parcelable payload and returns the end position (the byte offset where this parcelable's data ends). The size includes the 4-byte size field itself, so endPos = (position before size) + size.

Increments the parcel's nesting depth counter and returns an error if the maximum depth (maxParcelableDepth) is exceeded. Call SkipToParcelableEnd (or the generated footer code) to decrement it.

func ReadTypedList

func ReadTypedList[T Parcelable](
	p *Parcel,
	factory func() T,
) ([]T, error)

ReadTypedList reads a list of Parcelable items using the provided factory to create new instances. Returns nil if the count is -1.

func SkipToParcelableEnd

func SkipToParcelableEnd(
	p *Parcel,
	endPos int,
)

SkipToParcelableEnd sets the parcel position to endPos, allowing forward-compatible skipping of unknown fields. Decrements the parcelable nesting depth counter incremented by ReadParcelableHeader.

func WriteParcelableFooter

func WriteParcelableFooter(
	p *Parcel,
	headerPos int,
)

WriteParcelableFooter patches the size at headerPos. The size value is the distance from headerPos to the current end of the parcel, which includes the 4-byte size field itself. This matches the AIDL NDK convention: writeToParcel writes size = end_pos - start_pos, and readFromParcel skips to start_pos + size.

func WriteParcelableHeader

func WriteParcelableHeader(
	p *Parcel,
) int

WriteParcelableHeader writes a placeholder int32 for the total size of a parcelable payload. Returns the position of the placeholder, which must be passed to WriteParcelableFooter after writing the payload.

func WriteTypedList

func WriteTypedList[T Parcelable](
	p *Parcel,
	items []T,
) error

WriteTypedList writes a list of Parcelable items. Writes int32 count (or -1 for nil slice), then marshals each item.

Types

type Parcel

type Parcel struct {
	// contains filtered or unexported fields
}

Parcel is a container for serialized Binder IPC data. Data is 4-byte aligned, little-endian.

Parcel is not safe for concurrent use. Callers must synchronize access externally.

func FromBytes

func FromBytes(
	data []byte,
) *Parcel

FromBytes creates a Parcel from existing serialized data.

func New

func New() *Parcel

New creates a new empty Parcel.

func (*Parcel) Data

func (p *Parcel) Data() []byte

Data returns the internal byte slice. Callers must not modify it.

func (*Parcel) Len

func (p *Parcel) Len() int

Len returns the length of the data buffer.

func (*Parcel) Objects

func (p *Parcel) Objects() []uint64

Objects returns the offsets of flat_binder_objects.

func (*Parcel) Position

func (p *Parcel) Position() int

Position returns the current read position.

func (*Parcel) ReadBool

func (p *Parcel) ReadBool() (bool, error)

ReadBool reads a boolean from an int32 value.

func (*Parcel) ReadByteArray

func (p *Parcel) ReadByteArray() ([]byte, error)

ReadByteArray reads a byte array with an int32 length prefix. Returns nil if the length is -1. A length of 0 returns an empty non-nil slice, distinguishing "present but empty" from "absent" (nil).

func (*Parcel) ReadFileDescriptor

func (p *Parcel) ReadFileDescriptor() (int32, error)

ReadFileDescriptor reads a flat_binder_object with type BINDER_TYPE_FD and returns the file descriptor.

func (*Parcel) ReadFixedByteArray

func (p *Parcel) ReadFixedByteArray(
	fixedSize int,
) ([]byte, error)

ReadFixedByteArray reads a fixed-size byte array matching the AIDL byte[N] wire format: int32(size) followed by exactly size raw bytes. It verifies that the declared size matches fixedSize.

func (*Parcel) ReadFloat32

func (p *Parcel) ReadFloat32() (float32, error)

ReadFloat32 reads a 32-bit floating point number.

func (*Parcel) ReadFloat64

func (p *Parcel) ReadFloat64() (float64, error)

ReadFloat64 reads a 64-bit floating point number.

func (*Parcel) ReadInt32

func (p *Parcel) ReadInt32() (int32, error)

ReadInt32 reads a 32-bit signed integer.

func (*Parcel) ReadInt64

func (p *Parcel) ReadInt64() (int64, error)

ReadInt64 reads a 64-bit signed integer.

func (*Parcel) ReadInterfaceToken

func (p *Parcel) ReadInterfaceToken() (string, error)

ReadInterfaceToken reads a Binder interface token, consuming the strict-mode policy header, work-source UID, vendor header, and returns the descriptor.

func (*Parcel) ReadNullableString

func (p *Parcel) ReadNullableString() (*string, error)

ReadNullableString reads a string in UTF-8 wire format, distinguishing null from empty. Returns nil for null strings (byteLen < 0) and a pointer to the string value otherwise.

func (*Parcel) ReadNullableString16

func (p *Parcel) ReadNullableString16() (*string, error)

ReadNullableString16 reads a string in UTF-16LE wire format, distinguishing null from empty. Returns nil for null strings (charCount == -1) and a pointer to the string value otherwise.

func (*Parcel) ReadNullableStrongBinder

func (p *Parcel) ReadNullableStrongBinder() (uint32, bool, error)

ReadNullableStrongBinder reads a flat_binder_object that may be null. Returns the handle and true if a valid binder is present, or 0 and false if the binder is null. Null is detected as: type==0 (all-zero object) or BINDER_TYPE_BINDER with binder pointer==0 (Android's representation of a null IBinder). Also reads the int32 stability level that follows the flat_binder_object.

func (*Parcel) ReadPaddedByte

func (p *Parcel) ReadPaddedByte() (byte, error)

ReadPaddedByte reads a single byte (consuming 4 bytes with padding).

func (*Parcel) ReadParcelFileDescriptor

func (p *Parcel) ReadParcelFileDescriptor() (int32, error)

ReadParcelFileDescriptor reads a ParcelFileDescriptor (AIDL type) from the parcel. The wire format matches Android's NDK deserialization:

int32      - null indicator (0 = null, non-zero = non-null)
int32      - hasComm flag (from Parcel::readParcelFileDescriptor)
FD object  - flat_binder_object with BINDER_TYPE_FD

Returns -1 for a null ParcelFileDescriptor.

func (*Parcel) ReadString

func (p *Parcel) ReadString() (string, error)

ReadString reads a string in UTF-8 wire format (for @utf8InCpp). Reads int32 byte length. If -1, returns empty string. Then reads byteLen+1 bytes (including null terminator), padded to 4 bytes.

func (*Parcel) ReadString16

func (p *Parcel) ReadString16() (string, error)

ReadString16 reads a string in UTF-16LE wire format. Reads int32 char count. If -1, returns empty string. Then reads (charCount+1)*2 bytes (including null terminator), padded to 4 bytes.

func (*Parcel) ReadStrongBinder

func (p *Parcel) ReadStrongBinder() (uint32, error)

ReadStrongBinder reads a non-null flat_binder_object and returns the handle. Accepts both BINDER_TYPE_HANDLE and BINDER_TYPE_BINDER; for both types, reads the uint32 at offset 8 (handle or low 32 bits of binder pointer). Also reads the int32 stability level that follows the flat_binder_object.

Returns an error if the binder is null (BINDER_TYPE_BINDER with binder=0), matching the AIDL-generated UNEXPECTED_NULL check in the C++ implementation.

func (*Parcel) ReadUint32

func (p *Parcel) ReadUint32() (uint32, error)

ReadUint32 reads a 32-bit unsigned integer.

func (*Parcel) ReadUint64

func (p *Parcel) ReadUint64() (uint64, error)

ReadUint64 reads a 64-bit unsigned integer.

func (*Parcel) Recycle

func (p *Parcel) Recycle()

Recycle resets the parcel for reuse. Allocates fresh slices instead of reusing the old backing arrays to prevent aliased mutation: callers that retained a reference to Data() or Objects() before Recycle must not observe writes from subsequent parcel operations. This trades pooling efficiency for correctness.

func (*Parcel) SetPosition

func (p *Parcel) SetPosition(
	pos int,
)

SetPosition sets the current read position, clamping to [0, len(data)]. Non-aligned positions are allowed; read operations align internally.

func (*Parcel) WriteBool

func (p *Parcel) WriteBool(
	v bool,
)

WriteBool writes a boolean as an int32 (0 or 1).

func (*Parcel) WriteByteArray

func (p *Parcel) WriteByteArray(
	data []byte,
)

WriteByteArray writes a byte array with an int32 length prefix, padded to 4 bytes. A nil slice writes -1 as the length.

func (*Parcel) WriteFileDescriptor

func (p *Parcel) WriteFileDescriptor(
	fd int32,
)

WriteFileDescriptor writes a flat_binder_object with type BINDER_TYPE_FD containing the given file descriptor.

func (*Parcel) WriteFixedByteArray

func (p *Parcel) WriteFixedByteArray(
	data []byte,
	fixedSize int,
)

WriteFixedByteArray writes a fixed-size byte array matching the AIDL byte[N] wire format: int32(fixedSize) followed by exactly fixedSize raw bytes (4-byte aligned). If data is shorter than fixedSize, the remaining bytes are zero-filled. If data is longer, it is truncated.

func (*Parcel) WriteFloat32

func (p *Parcel) WriteFloat32(
	v float32,
)

WriteFloat32 writes a 32-bit floating point number.

func (*Parcel) WriteFloat64

func (p *Parcel) WriteFloat64(
	v float64,
)

WriteFloat64 writes a 64-bit floating point number.

func (*Parcel) WriteInt32

func (p *Parcel) WriteInt32(
	v int32,
)

WriteInt32 writes a 32-bit signed integer.

func (*Parcel) WriteInt64

func (p *Parcel) WriteInt64(
	v int64,
)

WriteInt64 writes a 64-bit signed integer.

func (*Parcel) WriteInterfaceToken

func (p *Parcel) WriteInterfaceToken(
	descriptor string,
)

WriteInterfaceToken writes a Binder interface token (descriptor) with the strict-mode policy header, work-source UID, vendor header, and descriptor. The format matches Android's Parcel::writeInterfaceToken:

int32: strict-mode policy | STRICT_MODE_PENALTY_GATHER
int32: work-source UID (or -1 for none)
int32: vendor header ('SYST' for system builds)
String16: interface descriptor

func (*Parcel) WriteLocalBinder

func (p *Parcel) WriteLocalBinder(
	binderPtr uintptr,
	cookie uintptr,
)

WriteLocalBinder writes a local binder object to the parcel.

binderPtr is the binder node address -- the kernel uses it to find or create the binder_node that represents this object. It must be a unique, non-zero process-space address (analogous to BBinder::getWeakRefs() in the C++ implementation).

cookie is echoed back in incoming BR_TRANSACTION events and is used by the process for dispatch (analogous to the BBinder* pointer in C++). It must also be a non-zero process-space address.

The kernel converts this BINDER_TYPE_BINDER into BINDER_TYPE_HANDLE in the receiving process.

After the flat_binder_object, an int32 stability level is written (matching Android's Parcel::finishFlattenBinder).

func (*Parcel) WriteNullString

func (p *Parcel) WriteNullString()

WriteNullString writes a null string sentinel (-1 length) in UTF-8 wire format.

func (*Parcel) WriteNullString16

func (p *Parcel) WriteNullString16()

WriteNullString16 writes a null string sentinel (-1 length) in UTF-16LE wire format.

func (*Parcel) WriteNullStrongBinder

func (p *Parcel) WriteNullStrongBinder()

WriteNullStrongBinder writes a null flat_binder_object. Android's flattenBinder(nullptr) writes type=BINDER_TYPE_BINDER with binder=0 and cookie=0. The null object is NOT recorded in the objects array (Parcel::writeObject skips it when binder==0 && !nullMetaData). Intentionally does not record an offset in the objects array, matching AOSP behavior: null binder objects are inert data, not real binder refs. Followed by UNDECLARED stability level (finishFlattenBinder).

func (*Parcel) WritePaddedByte

func (p *Parcel) WritePaddedByte(
	v byte,
)

WritePaddedByte writes a single byte as a sign-extended int32 (4 bytes, little-endian), matching AOSP's wire format.

func (*Parcel) WriteParcelFileDescriptor

func (p *Parcel) WriteParcelFileDescriptor(
	fd int32,
)

WriteParcelFileDescriptor writes a ParcelFileDescriptor (AIDL type) to the parcel. The wire format matches Android's NDK serialization:

int32(1)   - non-null indicator (from AParcel_writeParcelFileDescriptor)
int32(0)   - hasComm flag (from Parcel::writeParcelFileDescriptor)
FD object  - flat_binder_object with BINDER_TYPE_FD

A negative fd writes int32(0) as the null indicator (no further data).

func (*Parcel) WriteRawBytes

func (p *Parcel) WriteRawBytes(
	data []byte,
)

WriteRawBytes writes raw bytes into the parcel with 4-byte alignment padding but no length prefix. This matches C++ Parcel::writeInplace and is used to write Flattenable data blobs.

func (*Parcel) WriteString

func (p *Parcel) WriteString(
	s string,
)

WriteString writes a string in UTF-8 wire format (for @utf8InCpp). Writes int32 byte length, then UTF-8 bytes with a null terminator, padded to 4 bytes. An empty string writes length 0 followed by a null byte. Use WriteNullString to write a null sentinel (-1 length).

func (*Parcel) WriteString16

func (p *Parcel) WriteString16(
	s string,
)

WriteString16 writes a string in UTF-16LE wire format. Writes int32 char count (number of UTF-16 code units), then UTF-16LE encoded data with a null terminator, padded to 4 bytes. An empty string writes length 0 followed by a UTF-16 null terminator. Use WriteNullString16 to write a null sentinel (-1 length).

func (*Parcel) WriteStrongBinder

func (p *Parcel) WriteStrongBinder(
	handle uint32,
)

WriteStrongBinder writes a flat_binder_object with the given handle. Records the offset in the parcel's objects array. After the flat_binder_object, an int32 stability level is written (matching Android's Parcel::finishFlattenBinder).

func (*Parcel) WriteUint32

func (p *Parcel) WriteUint32(
	v uint32,
)

WriteUint32 writes a 32-bit unsigned integer.

func (*Parcel) WriteUint64

func (p *Parcel) WriteUint64(
	v uint64,
)

WriteUint64 writes a 64-bit unsigned integer.

type Parcelable

type Parcelable interface {
	MarshalParcel(p *Parcel) error
	UnmarshalParcel(p *Parcel) error
}

Parcelable is the interface for types that can be serialized to/from a Parcel.

type StabilityLevel

type StabilityLevel int32

StabilityLevel represents the binder stability level from android/binder/Stability.h, written as int32 after each flat_binder_object by Parcel::finishFlattenBinder.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL