// DO NOT EDIT YOURSELF
// This source is auto generated by xim-gen

#![allow(clippy::identity_op)]

use alloc::string::{String, ToString};
use alloc::vec::Vec;

use core::convert::TryInto;
use core::fmt;

pub fn read<T>(b: &[u8]) -> Result<T, ReadError>
where
    T: XimRead,
{
    T::read(&mut Reader::new(b))
}

pub fn write<T>(val: T, out: &mut [u8])
where
    T: XimWrite,
{
    val.write(&mut Writer::new(out));
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum Endian {
    #[cfg(target_endian = "little")]
    Native = 0x6c,
    #[cfg(target_endian = "big")]
    Native = 0x42,
    // Big = 0x42,
    // Little = 0x6c,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum StatusContent {
    Text(StatusTextContent),
    Pixmap(u32),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum CommitData {
    Keysym {
        keysym: u32,
        syncronous: bool,
    },
    Chars {
        commited: Vec<u8>,
        syncronous: bool,
    },
    Both {
        keysym: u32,
        commited: Vec<u8>,
        syncronous: bool,
    },
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InputStyleList {
    pub styles: Vec<InputStyle>,
}
impl XimRead for InputStyleList {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            styles: {
                let len = u16::read(reader)? as usize;
                reader.consume(2)?;
                let mut out = Vec::with_capacity(len);
                for _ in 0..len {
                    out.push(InputStyle::read(reader)?);
                }
                out
            },
        })
    }
}
impl XimWrite for InputStyleList {
    fn write(&self, writer: &mut Writer) {
        (self.styles.len() as u16).write(writer);
        0u16.write(writer);
        for elem in self.styles.iter() {
            elem.write(writer);
        }
    }
    fn size(&self) -> usize {
        self.styles.len() * 4 + 4
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct HotKeyTriggers {
    pub triggers: Vec<(TriggerKey, HotKeyState)>,
}

#[derive(Debug)]
pub enum ReadError {
    EndOfStream,
    InvalidData(&'static str, String),
    Utf8Error(alloc::string::FromUtf8Error),
    NotNativeEndian,
}

impl From<alloc::string::FromUtf8Error> for ReadError {
    fn from(e: alloc::string::FromUtf8Error) -> Self {
        Self::Utf8Error(e)
    }
}

impl fmt::Display for ReadError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::EndOfStream => write!(f, "End of Stream"),
            Self::InvalidData(name, reason) => write!(f, "Invalid Data {}: {}", name, reason),
            Self::Utf8Error(e) => write!(f, "Not a Utf8 text {}", e),
            Self::NotNativeEndian => write!(f, "Not a native endian"),
        }
    }
}

#[cfg(feature = "std")]
impl std::error::Error for ReadError {}

fn pad4(len: usize) -> usize {
    match len % 4 {
        0 => 0,
        x => 4 - x,
    }
}

fn with_pad4(len: usize) -> usize {
    len + pad4(len)
}

pub struct Reader<'b> {
    bytes: &'b [u8],
    start: usize,
}

impl<'b> Reader<'b> {
    pub fn new(bytes: &'b [u8]) -> Self {
        Self {
            bytes,
            start: bytes.as_ptr() as usize,
        }
    }

    fn ptr_offset(&self) -> usize {
        self.bytes.as_ptr() as usize - self.start
    }

    pub fn cursor(&self) -> usize {
        self.bytes.len()
    }

    pub fn pad4(&mut self) -> Result<(), ReadError> {
        self.consume(pad4(self.ptr_offset()))?;
        Ok(())
    }

    #[inline(always)]
    pub fn eos(&self) -> ReadError {
        ReadError::EndOfStream
    }

    pub fn invalid_data(&self, ty: &'static str, item: impl ToString) -> ReadError {
        ReadError::InvalidData(ty, item.to_string())
    }

    pub fn u8(&mut self) -> Result<u8, ReadError> {
        let (b, new) = self.bytes.split_first().ok_or(ReadError::EndOfStream)?;
        self.bytes = new;
        Ok(*b)
    }

    pub fn i16(&mut self) -> Result<i16, ReadError> {
        let bytes = self.consume(2)?.try_into().unwrap();
        Ok(i16::from_ne_bytes(bytes))
    }

    pub fn u16(&mut self) -> Result<u16, ReadError> {
        let bytes = self.consume(2)?.try_into().unwrap();
        Ok(u16::from_ne_bytes(bytes))
    }

    pub fn u32(&mut self) -> Result<u32, ReadError> {
        let bytes = self.consume(4)?.try_into().unwrap();
        Ok(u32::from_ne_bytes(bytes))
    }

    pub fn i32(&mut self) -> Result<i32, ReadError> {
        let bytes = self.consume(4)?.try_into().unwrap();
        Ok(i32::from_ne_bytes(bytes))
    }

    pub fn consume(&mut self, len: usize) -> Result<&'b [u8], ReadError> {
        if self.bytes.len() >= len {
            let (out, new) = self.bytes.split_at(len);
            self.bytes = new;
            Ok(out)
        } else {
            Err(self.eos())
        }
    }
}

pub struct Writer<'b> {
    out: &'b mut [u8],
    idx: usize,
}

impl<'b> Writer<'b> {
    pub fn new(out: &'b mut [u8]) -> Self {
        Self { out, idx: 0 }
    }

    pub fn write_u8(&mut self, b: u8) {
        self.out[self.idx] = b;
        self.idx += 1;
    }

    pub fn write(&mut self, bytes: &[u8]) {
        self.out[self.idx..self.idx + bytes.len()].copy_from_slice(bytes);
        self.idx += bytes.len();
    }

    pub fn write_pad4(&mut self) {
        let pad = pad4(self.idx);
        let pad_bytes = [0; 4];
        self.write(&pad_bytes[..pad]);
    }
}

pub trait XimRead: Sized {
    fn read(reader: &mut Reader) -> Result<Self, ReadError>;
}

pub trait XimWrite {
    fn write(&self, writer: &mut Writer);
    /// byte size of format
    fn size(&self) -> usize;
}

impl<'a, T> XimWrite for &'a T
where
    T: XimWrite,
{
    #[inline(always)]
    fn write(&self, writer: &mut Writer) {
        (**self).write(writer);
    }
    #[inline(always)]
    fn size(&self) -> usize {
        (**self).size()
    }
}

impl XimRead for Endian {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let n = u8::read(reader)?;

        if n == Endian::Native as u8 {
            Ok(Self::Native)
        } else {
            Err(ReadError::NotNativeEndian)
        }
    }
}

impl XimWrite for Endian {
    fn write(&self, writer: &mut Writer) {
        (*self as u8).write(writer);
    }

    fn size(&self) -> usize {
        1
    }
}

impl XimRead for StatusContent {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let ty = u32::read(reader)?;

        match ty {
            0 => Ok(Self::Text(StatusTextContent::read(reader)?)),
            1 => Ok(Self::Pixmap(u32::read(reader)?)),
            _ => Err(reader.invalid_data("StatusContentType", ty)),
        }
    }
}

impl XimWrite for StatusContent {
    fn write(&self, writer: &mut Writer) {
        match self {
            StatusContent::Text(content) => {
                0u32.write(writer);
                content.write(writer);
            }
            StatusContent::Pixmap(pixmap) => {
                1u32.write(writer);
                pixmap.write(writer);
            }
        }
    }

    fn size(&self) -> usize {
        let size = match self {
            StatusContent::Text(content) => content.size(),
            StatusContent::Pixmap(pixmap) => core::mem::size_of_val(pixmap),
        };

        size + 4
    }
}

impl XimRead for CommitData {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let ty = reader.u16()?;

        match ty {
            2 | 3 => {
                let len = reader.u16()?;
                let bytes = reader.consume(len as usize)?;
                reader.pad4()?;
                Ok(Self::Chars {
                    commited: bytes.to_vec(),
                    syncronous: ty == 5,
                })
            }
            4 | 5 => {
                reader.consume(2)?;
                let keysym = reader.u32()?;
                Ok(Self::Keysym {
                    keysym,
                    syncronous: ty == 3,
                })
            }
            6 | 7 => {
                reader.consume(2)?;
                let keysym = reader.u32()?;
                let len = reader.u16()?;
                let bytes = reader.consume(len as usize)?;
                reader.pad4()?;
                Ok(Self::Both {
                    keysym,
                    commited: bytes.to_vec(),
                    syncronous: ty == 7,
                })
            }
            _ => Err(reader.invalid_data("CommitDataType", ty)),
        }
    }
}

impl XimWrite for CommitData {
    fn write(&self, writer: &mut Writer) {
        match self {
            Self::Chars {
                commited,
                syncronous,
            } => {
                let flag = if *syncronous { 3u16 } else { 2u16 };
                flag.write(writer);
                (commited.len() as u16).write(writer);
                writer.write(&commited);
                writer.write_pad4();
            }
            Self::Keysym { keysym, syncronous } => {
                let flag = if *syncronous { 5u16 } else { 4u16 };
                flag.write(writer);
                0u16.write(writer);
                keysym.write(writer);
            }
            Self::Both {
                keysym,
                commited,
                syncronous,
            } => {
                let flag = if *syncronous { 7u16 } else { 6u16 };
                flag.write(writer);
                0u16.write(writer);
                keysym.write(writer);
                (commited.len() as u16).write(writer);
                writer.write(&commited);
                writer.write_pad4();
            }
        }
    }

    fn size(&self) -> usize {
        match self {
            Self::Keysym { .. } => with_pad4(6),
            Self::Chars { commited, .. } => with_pad4(commited.len() + 4),
            Self::Both { commited, .. } => with_pad4(commited.len() + 4 + 6),
        }
    }
}

impl XimRead for HotKeyTriggers {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let n = reader.u32()? as usize;
        let mut out = Vec::with_capacity(n);

        for _ in 0..n {
            out.push((TriggerKey::read(reader)?, HotKeyState::Off));
        }

        for _ in 0..n {
            out[n].1 = HotKeyState::read(reader)?;
        }

        Ok(Self { triggers: out })
    }
}

impl XimWrite for HotKeyTriggers {
    fn write(&self, writer: &mut Writer) {
        (self.triggers.len() as u32).write(writer);

        for (trigger, _) in self.triggers.iter() {
            trigger.write(writer);
        }

        for (_, state) in self.triggers.iter() {
            state.write(writer);
        }
    }

    fn size(&self) -> usize {
        self.triggers.len() * 8 + 4
    }
}

impl XimRead for u8 {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        reader.u8()
    }
}

impl XimWrite for u8 {
    fn write(&self, writer: &mut Writer) {
        writer.write_u8(*self)
    }

    fn size(&self) -> usize {
        1
    }
}

impl XimRead for bool {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(reader.u8()? != 0)
    }
}

impl XimWrite for bool {
    fn write(&self, writer: &mut Writer) {
        writer.write_u8(*self as u8)
    }

    fn size(&self) -> usize {
        1
    }
}

macro_rules! impl_int {
    ($ty:ident) => {
        impl XimRead for $ty {
            fn read(reader: &mut Reader) -> Result<Self, ReadError> {
                reader.$ty()
            }
        }

        impl XimWrite for $ty {
            fn write(&self, writer: &mut Writer) {
                writer.write(&self.to_ne_bytes())
            }

            fn size(&self) -> usize {
                core::mem::size_of::<$ty>()
            }
        }
    };
}

impl_int!(u16);
impl_int!(i16);
impl_int!(u32);
impl_int!(i32);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u16)]
pub enum AttrType {
    Separator = 0,
    Byte = 1,
    Word = 2,
    Long = 3,
    Char = 4,
    Window = 5,
    Style = 10,
    XRectangle = 11,
    XPoint = 12,
    XFontSet = 13,
    HotkeyTriggers = 15,
    StringConversion = 17,
    PreeditState = 18,
    ResetState = 19,
    NestedList = 32767,
}
impl XimRead for AttrType {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u16::read(reader)?;
        match repr {
            0 => Ok(Self::Separator),
            1 => Ok(Self::Byte),
            2 => Ok(Self::Word),
            3 => Ok(Self::Long),
            4 => Ok(Self::Char),
            5 => Ok(Self::Window),
            10 => Ok(Self::Style),
            11 => Ok(Self::XRectangle),
            12 => Ok(Self::XPoint),
            13 => Ok(Self::XFontSet),
            15 => Ok(Self::HotkeyTriggers),
            17 => Ok(Self::StringConversion),
            18 => Ok(Self::PreeditState),
            19 => Ok(Self::ResetState),
            32767 => Ok(Self::NestedList),
            _ => Err(reader.invalid_data("AttrType", repr)),
        }
    }
}
impl XimWrite for AttrType {
    fn write(&self, writer: &mut Writer) {
        (*self as u16).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u16>()
    }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum CaretDirection {
    ForwardChar = 0,
    BackwardChar = 1,
    ForwardWord = 2,
    BackwardWord = 3,
    CaretUp = 4,
    CaretDown = 5,
    NextLine = 6,
    PreviousLine = 7,
    LineStart = 8,
    LineEnd = 9,
    AbsolutePosition = 10,
    DontChange = 11,
}
impl XimRead for CaretDirection {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        match repr {
            0 => Ok(Self::ForwardChar),
            1 => Ok(Self::BackwardChar),
            2 => Ok(Self::ForwardWord),
            3 => Ok(Self::BackwardWord),
            4 => Ok(Self::CaretUp),
            5 => Ok(Self::CaretDown),
            6 => Ok(Self::NextLine),
            7 => Ok(Self::PreviousLine),
            8 => Ok(Self::LineStart),
            9 => Ok(Self::LineEnd),
            10 => Ok(Self::AbsolutePosition),
            11 => Ok(Self::DontChange),
            _ => Err(reader.invalid_data("CaretDirection", repr)),
        }
    }
}
impl XimWrite for CaretDirection {
    fn write(&self, writer: &mut Writer) {
        (*self as u32).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum CaretStyle {
    Invisible = 0,
    Primary = 1,
    Secondary = 2,
}
impl XimRead for CaretStyle {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        match repr {
            0 => Ok(Self::Invisible),
            1 => Ok(Self::Primary),
            2 => Ok(Self::Secondary),
            _ => Err(reader.invalid_data("CaretStyle", repr)),
        }
    }
}
impl XimWrite for CaretStyle {
    fn write(&self, writer: &mut Writer) {
        (*self as u32).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u16)]
pub enum ErrorCode {
    BadAlloc = 1,
    BadStyle = 2,
    BadClientWindow = 3,
    BadFocusWindow = 4,
    BadArea = 5,
    BadSpotLocation = 6,
    BadColormap = 7,
    BadAtom = 8,
    BadPixel = 9,
    BadPixmap = 10,
    BadName = 11,
    BadCursor = 12,
    BadProtocol = 13,
    BadForeground = 14,
    BadBackground = 15,
    LocaleNotSupported = 16,
    BadSomething = 999,
}
impl XimRead for ErrorCode {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u16::read(reader)?;
        match repr {
            1 => Ok(Self::BadAlloc),
            2 => Ok(Self::BadStyle),
            3 => Ok(Self::BadClientWindow),
            4 => Ok(Self::BadFocusWindow),
            5 => Ok(Self::BadArea),
            6 => Ok(Self::BadSpotLocation),
            7 => Ok(Self::BadColormap),
            8 => Ok(Self::BadAtom),
            9 => Ok(Self::BadPixel),
            10 => Ok(Self::BadPixmap),
            11 => Ok(Self::BadName),
            12 => Ok(Self::BadCursor),
            13 => Ok(Self::BadProtocol),
            14 => Ok(Self::BadForeground),
            15 => Ok(Self::BadBackground),
            16 => Ok(Self::LocaleNotSupported),
            999 => Ok(Self::BadSomething),
            _ => Err(reader.invalid_data("ErrorCode", repr)),
        }
    }
}
impl XimWrite for ErrorCode {
    fn write(&self, writer: &mut Writer) {
        (*self as u16).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u16>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ErrorFlag: u16 {
const INPUT_METHOD_ID_VALID = 1;
const INPUT_CONTEXT_ID_VALID = 2;
}
}
impl XimRead for ErrorFlag {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u16::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("ErrorFlag", repr))
    }
}
impl XimWrite for ErrorFlag {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u16>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Feedback: u32 {
const REVERSE = 1;
const UNDERLINE = 2;
const HIGHLIGHT = 4;
const PRIMARY = 8;
const SECONDARY = 16;
const TERTIARY = 32;
const VISIBLE_TO_FORWARD = 64;
const VISIBLE_TO_BACKWARD = 128;
const VISIBLE_CENTER = 256;
}
}
impl XimRead for Feedback {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("Feedback", repr))
    }
}
impl XimWrite for Feedback {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ForwardEventFlag: u16 {
const SYNCHRONOUS = 1;
const REQUEST_FILTERING = 2;
const REQUEST_LOOP_UPSTRING = 4;
}
}
impl XimRead for ForwardEventFlag {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u16::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("ForwardEventFlag", repr))
    }
}
impl XimWrite for ForwardEventFlag {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u16>()
    }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum HotKeyState {
    On = 1,
    Off = 2,
}
impl XimRead for HotKeyState {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        match repr {
            1 => Ok(Self::On),
            2 => Ok(Self::Off),
            _ => Err(reader.invalid_data("HotKeyState", repr)),
        }
    }
}
impl XimWrite for HotKeyState {
    fn write(&self, writer: &mut Writer) {
        (*self as u32).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct InputStyle: u32 {
const PREEDIT_AREA = 1;
const PREEDIT_CALLBACKS = 2;
const PREEDIT_POSITION = 4;
const PREEDIT_NOTHING = 8;
const PREEDIT_NONE = 16;
const STATUS_AREA = 256;
const STATUS_CALLBACKS = 512;
const STATUS_NOTHING = 1024;
const STATUS_NONE = 2048;
}
}
impl XimRead for InputStyle {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("InputStyle", repr))
    }
}
impl XimWrite for InputStyle {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PreeditDrawStatus: u32 {
const NO_STRING = 1;
const NO_FEEDBACK = 2;
}
}
impl XimRead for PreeditDrawStatus {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("PreeditDrawStatus", repr))
    }
}
impl XimWrite for PreeditDrawStatus {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PreeditStateFlag: u32 {
const UNKNOWN = 0;
const ENABLE = 1;
const DISABLE = 2;
}
}
impl XimRead for PreeditStateFlag {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        Self::from_bits(repr).ok_or_else(|| reader.invalid_data("PreeditStateFlag", repr))
    }
}
impl XimWrite for PreeditStateFlag {
    fn write(&self, writer: &mut Writer) {
        self.bits().write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum TriggerNotifyFlag {
    OnKeyList = 0,
    OffKeyList = 1,
}
impl XimRead for TriggerNotifyFlag {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let repr = u32::read(reader)?;
        match repr {
            0 => Ok(Self::OnKeyList),
            1 => Ok(Self::OffKeyList),
            _ => Err(reader.invalid_data("TriggerNotifyFlag", repr)),
        }
    }
}
impl XimWrite for TriggerNotifyFlag {
    fn write(&self, writer: &mut Writer) {
        (*self as u32).write(writer);
    }
    fn size(&self) -> usize {
        core::mem::size_of::<u32>()
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Attr {
    pub id: u16,
    pub ty: AttrType,
    pub name: AttributeName,
}
impl XimRead for Attr {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            id: u16::read(reader)?,
            ty: AttrType::read(reader)?,
            name: {
                let inner = AttributeName::read(reader)?;
                reader.pad4()?;
                inner
            },
        })
    }
}
impl XimWrite for Attr {
    fn write(&self, writer: &mut Writer) {
        self.id.write(writer);
        self.ty.write(writer);
        self.name.write(writer);
        writer.write_pad4();
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.id.size();
        content_size += self.ty.size();
        content_size += with_pad4(self.name.size() - 0);
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Attribute {
    pub id: u16,
    pub value: Vec<u8>,
}
impl XimRead for Attribute {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            id: u16::read(reader)?,
            value: {
                let inner = {
                    let len = u16::read(reader)?;
                    reader.consume(len as usize)?.to_vec()
                };
                reader.pad4()?;
                inner
            },
        })
    }
}
impl XimWrite for Attribute {
    fn write(&self, writer: &mut Writer) {
        self.id.write(writer);
        (self.value.len() as u16).write(writer);
        writer.write(&self.value);
        writer.write_pad4();
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.id.size();
        content_size += with_pad4(self.value.len() + 2 - 2) + 2;
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Extension {
    pub major_opcode: u8,
    pub minor_opcode: u8,
    pub name: String,
}
impl XimRead for Extension {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            major_opcode: u8::read(reader)?,
            minor_opcode: u8::read(reader)?,
            name: {
                let inner = {
                    let len = u16::read(reader)?;
                    String::from_utf8(reader.consume(len as usize)?.to_vec())?
                };
                reader.pad4()?;
                inner
            },
        })
    }
}
impl XimWrite for Extension {
    fn write(&self, writer: &mut Writer) {
        self.major_opcode.write(writer);
        self.minor_opcode.write(writer);
        (self.name.len() as u16).write(writer);
        writer.write(self.name.as_bytes());
        writer.write_pad4();
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.major_opcode.size();
        content_size += self.minor_opcode.size();
        content_size += with_pad4(self.name.len() + 2 + 0 - 0);
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FontSet {
    pub name: String,
}
impl XimRead for FontSet {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            name: {
                let inner = {
                    let len = u16::read(reader)?;
                    String::from_utf8(reader.consume(len as usize)?.to_vec())?
                };
                reader.pad4()?;
                inner
            },
        })
    }
}
impl XimWrite for FontSet {
    fn write(&self, writer: &mut Writer) {
        (self.name.len() as u16).write(writer);
        writer.write(self.name.as_bytes());
        writer.write_pad4();
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += with_pad4(self.name.len() + 2 + 0 - 0);
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Point {
    pub x: i16,
    pub y: i16,
}
impl XimRead for Point {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            x: i16::read(reader)?,
            y: i16::read(reader)?,
        })
    }
}
impl XimWrite for Point {
    fn write(&self, writer: &mut Writer) {
        self.x.write(writer);
        self.y.write(writer);
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.x.size();
        content_size += self.y.size();
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Rectangle {
    pub x: i16,
    pub y: i16,
    pub width: u16,
    pub height: u16,
}
impl XimRead for Rectangle {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            x: i16::read(reader)?,
            y: i16::read(reader)?,
            width: u16::read(reader)?,
            height: u16::read(reader)?,
        })
    }
}
impl XimWrite for Rectangle {
    fn write(&self, writer: &mut Writer) {
        self.x.write(writer);
        self.y.write(writer);
        self.width.write(writer);
        self.height.write(writer);
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.x.size();
        content_size += self.y.size();
        content_size += self.width.size();
        content_size += self.height.size();
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct StatusTextContent {
    pub status: PreeditDrawStatus,
    pub status_string: String,
    pub feedbacks: Vec<Feedback>,
}
impl XimRead for StatusTextContent {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            status: PreeditDrawStatus::read(reader)?,
            status_string: {
                let inner = {
                    let len = u16::read(reader)?;
                    String::from_utf8(reader.consume(len as usize)?.to_vec())?
                };
                reader.pad4()?;
                inner
            },
            feedbacks: {
                let mut out = Vec::new();
                let len = u16::read(reader)? as usize;
                let end = reader.cursor() - len;
                u16::read(reader)?;
                while reader.cursor() > end {
                    out.push(Feedback::read(reader)?);
                }
                out
            },
        })
    }
}
impl XimWrite for StatusTextContent {
    fn write(&self, writer: &mut Writer) {
        self.status.write(writer);
        (self.status_string.len() as u16).write(writer);
        writer.write(self.status_string.as_bytes());
        writer.write_pad4();
        ((self.feedbacks.iter().map(|e| e.size()).sum::<usize>() + 2 + 2 - 2 - 2) as u16)
            .write(writer);
        0u16.write(writer);
        for elem in self.feedbacks.iter() {
            elem.write(writer);
        }
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.status.size();
        content_size += with_pad4(self.status_string.len() + 2 + 0 - 0);
        content_size += self.feedbacks.iter().map(|e| e.size()).sum::<usize>() + 2 + 2;
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TriggerKey {
    pub keysym: u32,
    pub modifier: u32,
    pub modifier_mask: u32,
}
impl XimRead for TriggerKey {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            keysym: u32::read(reader)?,
            modifier: u32::read(reader)?,
            modifier_mask: u32::read(reader)?,
        })
    }
}
impl XimWrite for TriggerKey {
    fn write(&self, writer: &mut Writer) {
        self.keysym.write(writer);
        self.modifier.write(writer);
        self.modifier_mask.write(writer);
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.keysym.size();
        content_size += self.modifier.size();
        content_size += self.modifier_mask.size();
        content_size
    }
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct XEvent {
    pub response_type: u8,
    pub detail: u8,
    pub sequence: u16,
    pub time: u32,
    pub root: u32,
    pub event: u32,
    pub child: u32,
    pub root_x: i16,
    pub root_y: i16,
    pub event_x: i16,
    pub event_y: i16,
    pub state: u16,
    pub same_screen: bool,
}
impl XimRead for XEvent {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        Ok(Self {
            response_type: u8::read(reader)?,
            detail: u8::read(reader)?,
            sequence: u16::read(reader)?,
            time: u32::read(reader)?,
            root: u32::read(reader)?,
            event: u32::read(reader)?,
            child: u32::read(reader)?,
            root_x: i16::read(reader)?,
            root_y: i16::read(reader)?,
            event_x: i16::read(reader)?,
            event_y: i16::read(reader)?,
            state: u16::read(reader)?,
            same_screen: {
                let inner = bool::read(reader)?;
                reader.consume(1)?;
                inner
            },
        })
    }
}
impl XimWrite for XEvent {
    fn write(&self, writer: &mut Writer) {
        self.response_type.write(writer);
        self.detail.write(writer);
        self.sequence.write(writer);
        self.time.write(writer);
        self.root.write(writer);
        self.event.write(writer);
        self.child.write(writer);
        self.root_x.write(writer);
        self.root_y.write(writer);
        self.event_x.write(writer);
        self.event_y.write(writer);
        self.state.write(writer);
        self.same_screen.write(writer);
        writer.write(&[0u8; 1]);
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        content_size += self.response_type.size();
        content_size += self.detail.size();
        content_size += self.sequence.size();
        content_size += self.time.size();
        content_size += self.root.size();
        content_size += self.event.size();
        content_size += self.child.size();
        content_size += self.root_x.size();
        content_size += self.root_y.size();
        content_size += self.event_x.size();
        content_size += self.event_y.size();
        content_size += self.state.size();
        content_size += self.same_screen.size() + 1;
        content_size
    }
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum AttributeName {
    Area,
    AreaNeeded,
    Background,
    BackgroundPixmap,
    ClientWindow,
    ColorMap,
    Cursor,
    DestroyCallback,
    FilterEvents,
    FocusWindow,
    FontSet,
    Foreground,
    GeometryCallback,
    HotKey,
    HotKeyState,
    InputStyle,
    LineSpace,
    NestedList,
    PreeditAttributes,
    PreeditCaretCallback,
    PreeditDoneCallback,
    PreeditDrawCallback,
    PreeditStartCallback,
    PreeditState,
    PreeditStateNotifyCallback,
    QueryICValuesList,
    QueryIMValuesList,
    QueryInputStyle,
    R6PreeditCallback,
    ResetState,
    ResourceClass,
    ResourceName,
    SeparatorofNestedList,
    SpotLocation,
    StatusAttributes,
    StatusDoneCallback,
    StatusDrawCallback,
    StatusStartCallback,
    StdColorMap,
    StringConversion,
    StringConversionCallback,
    VisiblePosition,
}
impl AttributeName {
    pub fn name(self) -> &'static str {
        match self {
            Self::Area => "area",
            Self::AreaNeeded => "areaNeeded",
            Self::Background => "background",
            Self::BackgroundPixmap => "backgroundPixmap",
            Self::ClientWindow => "clientWindow",
            Self::ColorMap => "colorMap",
            Self::Cursor => "cursor",
            Self::DestroyCallback => "destroyCallback",
            Self::FilterEvents => "filterEvents",
            Self::FocusWindow => "focusWindow",
            Self::FontSet => "fontSet",
            Self::Foreground => "foreground",
            Self::GeometryCallback => "geometryCallback",
            Self::HotKey => "hotKey",
            Self::HotKeyState => "hotKeyState",
            Self::InputStyle => "inputStyle",
            Self::LineSpace => "lineSpace",
            Self::NestedList => "XNVaNestedList",
            Self::PreeditAttributes => "preeditAttributes",
            Self::PreeditCaretCallback => "preeditCaretCallback",
            Self::PreeditDoneCallback => "preeditDoneCallback",
            Self::PreeditDrawCallback => "preeditDrawCallback",
            Self::PreeditStartCallback => "preeditStartCallback",
            Self::PreeditState => "preeditState",
            Self::PreeditStateNotifyCallback => "preeditStateNotifyCallback",
            Self::QueryICValuesList => "queryICValuesList",
            Self::QueryIMValuesList => "queryIMValuesList",
            Self::QueryInputStyle => "queryInputStyle",
            Self::R6PreeditCallback => "r6PreeditCallback",
            Self::ResetState => "resetState",
            Self::ResourceClass => "resourceClass",
            Self::ResourceName => "resourceName",
            Self::SeparatorofNestedList => "separatorofNestedList",
            Self::SpotLocation => "spotLocation",
            Self::StatusAttributes => "statusAttributes",
            Self::StatusDoneCallback => "statusDoneCallback",
            Self::StatusDrawCallback => "statusDrawCallback",
            Self::StatusStartCallback => "statusStartCallback",
            Self::StdColorMap => "stdColorMap",
            Self::StringConversion => "stringConversion",
            Self::StringConversionCallback => "stringConversionCallback",
            Self::VisiblePosition => "visiblePosition",
        }
    }
}
impl XimRead for AttributeName {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let len = u16::read(reader)?;
        match reader.consume(len as usize)? {
            b"area" => Ok(Self::Area),
            b"areaNeeded" => Ok(Self::AreaNeeded),
            b"background" => Ok(Self::Background),
            b"backgroundPixmap" => Ok(Self::BackgroundPixmap),
            b"clientWindow" => Ok(Self::ClientWindow),
            b"colorMap" => Ok(Self::ColorMap),
            b"cursor" => Ok(Self::Cursor),
            b"destroyCallback" => Ok(Self::DestroyCallback),
            b"filterEvents" => Ok(Self::FilterEvents),
            b"focusWindow" => Ok(Self::FocusWindow),
            b"fontSet" => Ok(Self::FontSet),
            b"foreground" => Ok(Self::Foreground),
            b"geometryCallback" => Ok(Self::GeometryCallback),
            b"hotKey" => Ok(Self::HotKey),
            b"hotKeyState" => Ok(Self::HotKeyState),
            b"inputStyle" => Ok(Self::InputStyle),
            b"lineSpace" => Ok(Self::LineSpace),
            b"XNVaNestedList" => Ok(Self::NestedList),
            b"preeditAttributes" => Ok(Self::PreeditAttributes),
            b"preeditCaretCallback" => Ok(Self::PreeditCaretCallback),
            b"preeditDoneCallback" => Ok(Self::PreeditDoneCallback),
            b"preeditDrawCallback" => Ok(Self::PreeditDrawCallback),
            b"preeditStartCallback" => Ok(Self::PreeditStartCallback),
            b"preeditState" => Ok(Self::PreeditState),
            b"preeditStateNotifyCallback" => Ok(Self::PreeditStateNotifyCallback),
            b"queryICValuesList" => Ok(Self::QueryICValuesList),
            b"queryIMValuesList" => Ok(Self::QueryIMValuesList),
            b"queryInputStyle" => Ok(Self::QueryInputStyle),
            b"r6PreeditCallback" => Ok(Self::R6PreeditCallback),
            b"resetState" => Ok(Self::ResetState),
            b"resourceClass" => Ok(Self::ResourceClass),
            b"resourceName" => Ok(Self::ResourceName),
            b"separatorofNestedList" => Ok(Self::SeparatorofNestedList),
            b"spotLocation" => Ok(Self::SpotLocation),
            b"statusAttributes" => Ok(Self::StatusAttributes),
            b"statusDoneCallback" => Ok(Self::StatusDoneCallback),
            b"statusDrawCallback" => Ok(Self::StatusDrawCallback),
            b"statusStartCallback" => Ok(Self::StatusStartCallback),
            b"stdColorMap" => Ok(Self::StdColorMap),
            b"stringConversion" => Ok(Self::StringConversion),
            b"stringConversionCallback" => Ok(Self::StringConversionCallback),
            b"visiblePosition" => Ok(Self::VisiblePosition),
            bytes => Err(reader.invalid_data(
                "AttributeName",
                core::str::from_utf8(bytes).unwrap_or("NOT_UTF8"),
            )),
        }
    }
}
impl XimWrite for AttributeName {
    fn write(&self, writer: &mut Writer) {
        let name = self.name();
        (name.len() as u16).write(writer);
        writer.write(name.as_bytes());
    }
    fn size(&self) -> usize {
        self.name().len() + 2
    }
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Request {
    AuthNext {},
    AuthNg {},
    AuthReply {},
    AuthRequired {},
    AuthSetup {},
    Close {
        input_method_id: u16,
    },
    CloseReply {
        input_method_id: u16,
    },
    Commit {
        input_method_id: u16,
        input_context_id: u16,
        data: CommitData,
    },
    Connect {
        endian: Endian,
        client_major_protocol_version: u16,
        client_minor_protocol_version: u16,
        client_auth_protocol_names: Vec<String>,
    },
    ConnectReply {
        server_major_protocol_version: u16,
        server_minor_protocol_version: u16,
    },
    CreateIc {
        input_method_id: u16,
        ic_attributes: Vec<Attribute>,
    },
    CreateIcReply {
        input_method_id: u16,
        input_context_id: u16,
    },
    DestroyIc {
        input_method_id: u16,
        input_context_id: u16,
    },
    DestroyIcReply {
        input_method_id: u16,
        input_context_id: u16,
    },
    Disconnect {},
    DisconnectReply {},
    EncodingNegotiation {
        input_method_id: u16,
        encodings: Vec<String>,
        encoding_infos: Vec<String>,
    },
    EncodingNegotiationReply {
        input_method_id: u16,
        category: u16,
        index: i16,
    },
    Error {
        input_method_id: u16,
        input_context_id: u16,
        flag: ErrorFlag,
        code: ErrorCode,
        detail: String,
    },
    ForwardEvent {
        input_method_id: u16,
        input_context_id: u16,
        flag: ForwardEventFlag,
        serial_number: u16,
        xev: XEvent,
    },
    Geometry {
        input_method_id: u16,
        input_context_id: u16,
    },
    GetIcValues {
        input_method_id: u16,
        input_context_id: u16,
        ic_attributes: Vec<u16>,
    },
    GetIcValuesReply {
        input_method_id: u16,
        input_context_id: u16,
        ic_attributes: Vec<Attribute>,
    },
    GetImValues {
        input_method_id: u16,
        im_attributes: Vec<u16>,
    },
    GetImValuesReply {
        input_method_id: u16,
        im_attributes: Vec<Attribute>,
    },
    Open {
        locale: String,
    },
    OpenReply {
        input_method_id: u16,
        im_attrs: Vec<Attr>,
        ic_attrs: Vec<Attr>,
    },
    PreeditCaret {
        input_method_id: u16,
        input_context_id: u16,
        position: i32,
        direction: CaretDirection,
        style: CaretStyle,
    },
    PreeditCaretReply {
        input_method_id: u16,
        input_context_id: u16,
        position: i32,
    },
    PreeditDone {
        input_method_id: u16,
        input_context_id: u16,
    },
    PreeditDraw {
        input_method_id: u16,
        input_context_id: u16,
        caret: i32,
        chg_first: i32,
        chg_length: i32,
        status: PreeditDrawStatus,
        preedit_string: Vec<u8>,
        feedbacks: Vec<Feedback>,
    },
    PreeditStart {
        input_method_id: u16,
        input_context_id: u16,
    },
    PreeditStartReply {
        input_method_id: u16,
        input_context_id: u16,
        return_value: i32,
    },
    PreeditState {
        input_method_id: u16,
        input_context_id: u16,
        state: PreeditStateFlag,
    },
    QueryExtension {
        input_method_id: u16,
        extensions: Vec<String>,
    },
    QueryExtensionReply {
        input_method_id: u16,
        extensions: Vec<Extension>,
    },
    RegisterTriggerKeys {
        input_method_id: u16,
        on_keys: Vec<TriggerKey>,
        off_keys: Vec<TriggerKey>,
    },
    ResetIc {
        input_method_id: u16,
        input_context_id: u16,
    },
    ResetIcReply {
        input_method_id: u16,
        input_context_id: u16,
        preedit_string: Vec<u8>,
    },
    SetEventMask {
        input_method_id: u16,
        input_context_id: u16,
        forward_event_mask: u32,
        synchronous_event_mask: u32,
    },
    SetIcFocus {
        input_method_id: u16,
        input_context_id: u16,
    },
    SetIcValues {
        input_method_id: u16,
        input_context_id: u16,
        ic_attributes: Vec<Attribute>,
    },
    SetIcValuesReply {
        input_method_id: u16,
        input_context_id: u16,
    },
    SetImValues {
        input_method_id: u16,
        attributes: Vec<Attribute>,
    },
    SetImValuesReply {
        input_method_id: u16,
    },
    StatusDone {
        input_method_id: u16,
        input_context_id: u16,
    },
    StatusDraw {
        input_method_id: u16,
        input_context_id: u16,
        content: StatusContent,
    },
    StatusStart {
        input_method_id: u16,
        input_context_id: u16,
    },
    StrConversion {},
    StrConversionReply {},
    Sync {
        input_method_id: u16,
        input_context_id: u16,
    },
    SyncReply {
        input_method_id: u16,
        input_context_id: u16,
    },
    TriggerNotify {
        input_method_id: u16,
        input_context_id: u16,
        flag: TriggerNotifyFlag,
        index: u32,
        event_mask: u32,
    },
    TriggerNotifyReply {
        input_method_id: u16,
        input_context_id: u16,
    },
    UnsetIcFocus {
        input_method_id: u16,
        input_context_id: u16,
    },
}
impl Request {
    pub fn name(&self) -> &'static str {
        match self {
            Request::AuthNext { .. } => "AuthNext",
            Request::AuthNg { .. } => "AuthNg",
            Request::AuthReply { .. } => "AuthReply",
            Request::AuthRequired { .. } => "AuthRequired",
            Request::AuthSetup { .. } => "AuthSetup",
            Request::Close { .. } => "Close",
            Request::CloseReply { .. } => "CloseReply",
            Request::Commit { .. } => "Commit",
            Request::Connect { .. } => "Connect",
            Request::ConnectReply { .. } => "ConnectReply",
            Request::CreateIc { .. } => "CreateIc",
            Request::CreateIcReply { .. } => "CreateIcReply",
            Request::DestroyIc { .. } => "DestroyIc",
            Request::DestroyIcReply { .. } => "DestroyIcReply",
            Request::Disconnect { .. } => "Disconnect",
            Request::DisconnectReply { .. } => "DisconnectReply",
            Request::EncodingNegotiation { .. } => "EncodingNegotiation",
            Request::EncodingNegotiationReply { .. } => "EncodingNegotiationReply",
            Request::Error { .. } => "Error",
            Request::ForwardEvent { .. } => "ForwardEvent",
            Request::Geometry { .. } => "Geometry",
            Request::GetIcValues { .. } => "GetIcValues",
            Request::GetIcValuesReply { .. } => "GetIcValuesReply",
            Request::GetImValues { .. } => "GetImValues",
            Request::GetImValuesReply { .. } => "GetImValuesReply",
            Request::Open { .. } => "Open",
            Request::OpenReply { .. } => "OpenReply",
            Request::PreeditCaret { .. } => "PreeditCaret",
            Request::PreeditCaretReply { .. } => "PreeditCaretReply",
            Request::PreeditDone { .. } => "PreeditDone",
            Request::PreeditDraw { .. } => "PreeditDraw",
            Request::PreeditStart { .. } => "PreeditStart",
            Request::PreeditStartReply { .. } => "PreeditStartReply",
            Request::PreeditState { .. } => "PreeditState",
            Request::QueryExtension { .. } => "QueryExtension",
            Request::QueryExtensionReply { .. } => "QueryExtensionReply",
            Request::RegisterTriggerKeys { .. } => "RegisterTriggerKeys",
            Request::ResetIc { .. } => "ResetIc",
            Request::ResetIcReply { .. } => "ResetIcReply",
            Request::SetEventMask { .. } => "SetEventMask",
            Request::SetIcFocus { .. } => "SetIcFocus",
            Request::SetIcValues { .. } => "SetIcValues",
            Request::SetIcValuesReply { .. } => "SetIcValuesReply",
            Request::SetImValues { .. } => "SetImValues",
            Request::SetImValuesReply { .. } => "SetImValuesReply",
            Request::StatusDone { .. } => "StatusDone",
            Request::StatusDraw { .. } => "StatusDraw",
            Request::StatusStart { .. } => "StatusStart",
            Request::StrConversion { .. } => "StrConversion",
            Request::StrConversionReply { .. } => "StrConversionReply",
            Request::Sync { .. } => "Sync",
            Request::SyncReply { .. } => "SyncReply",
            Request::TriggerNotify { .. } => "TriggerNotify",
            Request::TriggerNotifyReply { .. } => "TriggerNotifyReply",
            Request::UnsetIcFocus { .. } => "UnsetIcFocus",
        }
    }
}
impl XimRead for Request {
    fn read(reader: &mut Reader) -> Result<Self, ReadError> {
        let major_opcode = reader.u8()?;
        let minor_opcode = reader.u8()?;
        let _length = reader.u16()?;
        match (major_opcode, minor_opcode) {
            (12, _) => Ok(Request::AuthNext {}),
            (14, _) => Ok(Request::AuthNg {}),
            (11, _) => Ok(Request::AuthReply {}),
            (10, _) => Ok(Request::AuthRequired {}),
            (13, _) => Ok(Request::AuthSetup {}),
            (32, _) => Ok(Request::Close {
                input_method_id: {
                    let inner = u16::read(reader)?;
                    reader.consume(2)?;
                    inner
                },
            }),
            (33, _) => Ok(Request::CloseReply {
                input_method_id: {
                    let inner = u16::read(reader)?;
                    reader.consume(2)?;
                    inner
                },
            }),
            (63, _) => Ok(Request::Commit {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                data: CommitData::read(reader)?,
            }),
            (1, _) => Ok(Request::Connect {
                endian: {
                    let inner = Endian::read(reader)?;
                    reader.consume(1)?;
                    inner
                },
                client_major_protocol_version: u16::read(reader)?,
                client_minor_protocol_version: u16::read(reader)?,
                client_auth_protocol_names: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push({
                            let inner = {
                                let len = u16::read(reader)?;
                                String::from_utf8(reader.consume(len as usize)?.to_vec())?
                            };
                            reader.pad4()?;
                            inner
                        });
                    }
                    out
                },
            }),
            (2, _) => Ok(Request::ConnectReply {
                server_major_protocol_version: u16::read(reader)?,
                server_minor_protocol_version: u16::read(reader)?,
            }),
            (50, _) => Ok(Request::CreateIc {
                input_method_id: u16::read(reader)?,
                ic_attributes: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(Attribute::read(reader)?);
                    }
                    out
                },
            }),
            (51, _) => Ok(Request::CreateIcReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (52, _) => Ok(Request::DestroyIc {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (53, _) => Ok(Request::DestroyIcReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (3, _) => Ok(Request::Disconnect {}),
            (4, _) => Ok(Request::DisconnectReply {}),
            (38, _) => Ok(Request::EncodingNegotiation {
                input_method_id: u16::read(reader)?,
                encodings: {
                    let inner = {
                        let mut out = Vec::new();
                        let len = u16::read(reader)? as usize;
                        let end = reader.cursor() - len;
                        while reader.cursor() > end {
                            out.push({
                                let len = u8::read(reader)?;
                                String::from_utf8(reader.consume(len as usize)?.to_vec())?
                            });
                        }
                        out
                    };
                    reader.pad4()?;
                    inner
                },
                encoding_infos: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    u16::read(reader)?;
                    while reader.cursor() > end {
                        out.push({
                            let inner = {
                                let len = u16::read(reader)?;
                                String::from_utf8(reader.consume(len as usize)?.to_vec())?
                            };
                            reader.pad4()?;
                            inner
                        });
                    }
                    out
                },
            }),
            (39, _) => Ok(Request::EncodingNegotiationReply {
                input_method_id: u16::read(reader)?,
                category: u16::read(reader)?,
                index: {
                    let inner = i16::read(reader)?;
                    reader.consume(2)?;
                    inner
                },
            }),
            (20, _) => Ok(Request::Error {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                flag: ErrorFlag::read(reader)?,
                code: ErrorCode::read(reader)?,
                detail: {
                    let inner = {
                        let len = u16::read(reader)?;
                        reader.consume(2)?;
                        String::from_utf8(reader.consume(len as usize)?.to_vec())?
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (60, _) => Ok(Request::ForwardEvent {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                flag: ForwardEventFlag::read(reader)?,
                serial_number: u16::read(reader)?,
                xev: XEvent::read(reader)?,
            }),
            (70, _) => Ok(Request::Geometry {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (56, _) => Ok(Request::GetIcValues {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                ic_attributes: {
                    let inner = {
                        let mut out = Vec::new();
                        let len = u16::read(reader)? as usize;
                        let end = reader.cursor() - len;
                        while reader.cursor() > end {
                            out.push(u16::read(reader)?);
                        }
                        out
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (57, _) => Ok(Request::GetIcValuesReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                ic_attributes: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    u16::read(reader)?;
                    while reader.cursor() > end {
                        out.push(Attribute::read(reader)?);
                    }
                    out
                },
            }),
            (44, _) => Ok(Request::GetImValues {
                input_method_id: u16::read(reader)?,
                im_attributes: {
                    let inner = {
                        let mut out = Vec::new();
                        let len = u16::read(reader)? as usize;
                        let end = reader.cursor() - len;
                        while reader.cursor() > end {
                            out.push(u16::read(reader)?);
                        }
                        out
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (45, _) => Ok(Request::GetImValuesReply {
                input_method_id: u16::read(reader)?,
                im_attributes: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(Attribute::read(reader)?);
                    }
                    out
                },
            }),
            (30, _) => Ok(Request::Open {
                locale: {
                    let inner = {
                        let len = u8::read(reader)?;
                        String::from_utf8(reader.consume(len as usize)?.to_vec())?
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (31, _) => Ok(Request::OpenReply {
                input_method_id: u16::read(reader)?,
                im_attrs: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(Attr::read(reader)?);
                    }
                    out
                },
                ic_attrs: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    u16::read(reader)?;
                    while reader.cursor() > end {
                        out.push(Attr::read(reader)?);
                    }
                    out
                },
            }),
            (76, _) => Ok(Request::PreeditCaret {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                position: i32::read(reader)?,
                direction: CaretDirection::read(reader)?,
                style: CaretStyle::read(reader)?,
            }),
            (77, _) => Ok(Request::PreeditCaretReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                position: i32::read(reader)?,
            }),
            (78, _) => Ok(Request::PreeditDone {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (75, _) => Ok(Request::PreeditDraw {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                caret: i32::read(reader)?,
                chg_first: i32::read(reader)?,
                chg_length: i32::read(reader)?,
                status: PreeditDrawStatus::read(reader)?,
                preedit_string: {
                    let inner = {
                        let len = u16::read(reader)?;
                        reader.consume(len as usize)?.to_vec()
                    };
                    reader.pad4()?;
                    inner
                },
                feedbacks: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    u16::read(reader)?;
                    while reader.cursor() > end {
                        out.push(Feedback::read(reader)?);
                    }
                    out
                },
            }),
            (73, _) => Ok(Request::PreeditStart {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (74, _) => Ok(Request::PreeditStartReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                return_value: i32::read(reader)?,
            }),
            (82, _) => Ok(Request::PreeditState {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                state: PreeditStateFlag::read(reader)?,
            }),
            (40, _) => Ok(Request::QueryExtension {
                input_method_id: u16::read(reader)?,
                extensions: {
                    let inner = {
                        let mut out = Vec::new();
                        let len = u16::read(reader)? as usize;
                        let end = reader.cursor() - len;
                        while reader.cursor() > end {
                            out.push({
                                let len = u8::read(reader)?;
                                String::from_utf8(reader.consume(len as usize)?.to_vec())?
                            });
                        }
                        out
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (41, _) => Ok(Request::QueryExtensionReply {
                input_method_id: u16::read(reader)?,
                extensions: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(Extension::read(reader)?);
                    }
                    out
                },
            }),
            (34, _) => Ok(Request::RegisterTriggerKeys {
                input_method_id: {
                    let inner = u16::read(reader)?;
                    reader.consume(2)?;
                    inner
                },
                on_keys: {
                    let mut out = Vec::new();
                    let len = u32::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(TriggerKey::read(reader)?);
                    }
                    out
                },
                off_keys: {
                    let mut out = Vec::new();
                    let len = u32::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(TriggerKey::read(reader)?);
                    }
                    out
                },
            }),
            (64, _) => Ok(Request::ResetIc {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (65, _) => Ok(Request::ResetIcReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                preedit_string: {
                    let inner = {
                        let len = u16::read(reader)?;
                        reader.consume(len as usize)?.to_vec()
                    };
                    reader.pad4()?;
                    inner
                },
            }),
            (37, _) => Ok(Request::SetEventMask {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                forward_event_mask: u32::read(reader)?,
                synchronous_event_mask: u32::read(reader)?,
            }),
            (58, _) => Ok(Request::SetIcFocus {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (54, _) => Ok(Request::SetIcValues {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                ic_attributes: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    u16::read(reader)?;
                    while reader.cursor() > end {
                        out.push(Attribute::read(reader)?);
                    }
                    out
                },
            }),
            (55, _) => Ok(Request::SetIcValuesReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (42, _) => Ok(Request::SetImValues {
                input_method_id: u16::read(reader)?,
                attributes: {
                    let mut out = Vec::new();
                    let len = u16::read(reader)? as usize;
                    let end = reader.cursor() - len;
                    while reader.cursor() > end {
                        out.push(Attribute::read(reader)?);
                    }
                    out
                },
            }),
            (43, _) => Ok(Request::SetImValuesReply {
                input_method_id: {
                    let inner = u16::read(reader)?;
                    reader.consume(2)?;
                    inner
                },
            }),
            (81, _) => Ok(Request::StatusDone {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (80, _) => Ok(Request::StatusDraw {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                content: StatusContent::read(reader)?,
            }),
            (79, _) => Ok(Request::StatusStart {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (71, _) => Ok(Request::StrConversion {}),
            (72, _) => Ok(Request::StrConversionReply {}),
            (61, _) => Ok(Request::Sync {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (62, _) => Ok(Request::SyncReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (35, _) => Ok(Request::TriggerNotify {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
                flag: TriggerNotifyFlag::read(reader)?,
                index: u32::read(reader)?,
                event_mask: u32::read(reader)?,
            }),
            (36, _) => Ok(Request::TriggerNotifyReply {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            (59, _) => Ok(Request::UnsetIcFocus {
                input_method_id: u16::read(reader)?,
                input_context_id: u16::read(reader)?,
            }),
            _ => Err(reader.invalid_data(
                "Opcode",
                alloc::format!("({}, {})", major_opcode, minor_opcode),
            )),
        }
    }
}
impl XimWrite for Request {
    fn write(&self, writer: &mut Writer) {
        match self {
            Request::AuthNext {} => {
                12u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::AuthNg {} => {
                14u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::AuthReply {} => {
                11u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::AuthRequired {} => {
                10u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::AuthSetup {} => {
                13u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::Close { input_method_id } => {
                32u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                writer.write(&[0u8; 2]);
            }
            Request::CloseReply { input_method_id } => {
                33u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                writer.write(&[0u8; 2]);
            }
            Request::Commit {
                input_method_id,
                input_context_id,
                data,
            } => {
                63u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                data.write(writer);
            }
            Request::Connect {
                endian,
                client_major_protocol_version,
                client_minor_protocol_version,
                client_auth_protocol_names,
            } => {
                1u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                endian.write(writer);
                writer.write(&[0u8; 1]);
                client_major_protocol_version.write(writer);
                client_minor_protocol_version.write(writer);
                ((client_auth_protocol_names
                    .iter()
                    .map(|e| with_pad4(e.len() + 2 + 0 - 0))
                    .sum::<usize>()
                    + 0
                    + 2
                    - 2
                    - 0) as u16)
                    .write(writer);
                for elem in client_auth_protocol_names.iter() {
                    (elem.len() as u16).write(writer);
                    writer.write(elem.as_bytes());
                    writer.write_pad4();
                }
            }
            Request::ConnectReply {
                server_major_protocol_version,
                server_minor_protocol_version,
            } => {
                2u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                server_major_protocol_version.write(writer);
                server_minor_protocol_version.write(writer);
            }
            Request::CreateIc {
                input_method_id,
                ic_attributes,
            } => {
                50u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in ic_attributes.iter() {
                    elem.write(writer);
                }
            }
            Request::CreateIcReply {
                input_method_id,
                input_context_id,
            } => {
                51u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::DestroyIc {
                input_method_id,
                input_context_id,
            } => {
                52u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::DestroyIcReply {
                input_method_id,
                input_context_id,
            } => {
                53u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::Disconnect {} => {
                3u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::DisconnectReply {} => {
                4u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::EncodingNegotiation {
                input_method_id,
                encodings,
                encoding_infos,
            } => {
                38u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((encodings.iter().map(|e| e.len() + 1 + 0).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in encodings.iter() {
                    (elem.len() as u8).write(writer);
                    writer.write(elem.as_bytes());
                }
                writer.write_pad4();
                ((encoding_infos
                    .iter()
                    .map(|e| with_pad4(e.len() + 2 + 0 - 0))
                    .sum::<usize>()
                    + 2
                    + 2
                    - 2
                    - 2) as u16)
                    .write(writer);
                0u16.write(writer);
                for elem in encoding_infos.iter() {
                    (elem.len() as u16).write(writer);
                    writer.write(elem.as_bytes());
                    writer.write_pad4();
                }
            }
            Request::EncodingNegotiationReply {
                input_method_id,
                category,
                index,
            } => {
                39u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                category.write(writer);
                index.write(writer);
                writer.write(&[0u8; 2]);
            }
            Request::Error {
                input_method_id,
                input_context_id,
                flag,
                code,
                detail,
            } => {
                20u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                flag.write(writer);
                code.write(writer);
                (detail.len() as u16).write(writer);
                writer.write(&[0u8; 2]);
                writer.write(detail.as_bytes());
                writer.write_pad4();
            }
            Request::ForwardEvent {
                input_method_id,
                input_context_id,
                flag,
                serial_number,
                xev,
            } => {
                60u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                flag.write(writer);
                serial_number.write(writer);
                xev.write(writer);
            }
            Request::Geometry {
                input_method_id,
                input_context_id,
            } => {
                70u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::GetIcValues {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                56u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                ((ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in ic_attributes.iter() {
                    elem.write(writer);
                }
                writer.write_pad4();
            }
            Request::GetIcValuesReply {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                57u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                ((ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 2 + 2 - 2 - 2) as u16)
                    .write(writer);
                0u16.write(writer);
                for elem in ic_attributes.iter() {
                    elem.write(writer);
                }
            }
            Request::GetImValues {
                input_method_id,
                im_attributes,
            } => {
                44u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((im_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in im_attributes.iter() {
                    elem.write(writer);
                }
                writer.write_pad4();
            }
            Request::GetImValuesReply {
                input_method_id,
                im_attributes,
            } => {
                45u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((im_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in im_attributes.iter() {
                    elem.write(writer);
                }
            }
            Request::Open { locale } => {
                30u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                (locale.len() as u8).write(writer);
                writer.write(locale.as_bytes());
                writer.write_pad4();
            }
            Request::OpenReply {
                input_method_id,
                im_attrs,
                ic_attrs,
            } => {
                31u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((im_attrs.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in im_attrs.iter() {
                    elem.write(writer);
                }
                ((ic_attrs.iter().map(|e| e.size()).sum::<usize>() + 2 + 2 - 2 - 2) as u16)
                    .write(writer);
                0u16.write(writer);
                for elem in ic_attrs.iter() {
                    elem.write(writer);
                }
            }
            Request::PreeditCaret {
                input_method_id,
                input_context_id,
                position,
                direction,
                style,
            } => {
                76u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                position.write(writer);
                direction.write(writer);
                style.write(writer);
            }
            Request::PreeditCaretReply {
                input_method_id,
                input_context_id,
                position,
            } => {
                77u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                position.write(writer);
            }
            Request::PreeditDone {
                input_method_id,
                input_context_id,
            } => {
                78u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::PreeditDraw {
                input_method_id,
                input_context_id,
                caret,
                chg_first,
                chg_length,
                status,
                preedit_string,
                feedbacks,
            } => {
                75u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                caret.write(writer);
                chg_first.write(writer);
                chg_length.write(writer);
                status.write(writer);
                (preedit_string.len() as u16).write(writer);
                writer.write(&preedit_string);
                writer.write_pad4();
                ((feedbacks.iter().map(|e| e.size()).sum::<usize>() + 2 + 2 - 2 - 2) as u16)
                    .write(writer);
                0u16.write(writer);
                for elem in feedbacks.iter() {
                    elem.write(writer);
                }
            }
            Request::PreeditStart {
                input_method_id,
                input_context_id,
            } => {
                73u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::PreeditStartReply {
                input_method_id,
                input_context_id,
                return_value,
            } => {
                74u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                return_value.write(writer);
            }
            Request::PreeditState {
                input_method_id,
                input_context_id,
                state,
            } => {
                82u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                state.write(writer);
            }
            Request::QueryExtension {
                input_method_id,
                extensions,
            } => {
                40u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((extensions.iter().map(|e| e.len() + 1 + 0).sum::<usize>() + 0 + 2 - 2 - 0)
                    as u16)
                    .write(writer);
                for elem in extensions.iter() {
                    (elem.len() as u8).write(writer);
                    writer.write(elem.as_bytes());
                }
                writer.write_pad4();
            }
            Request::QueryExtensionReply {
                input_method_id,
                extensions,
            } => {
                41u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((extensions.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in extensions.iter() {
                    elem.write(writer);
                }
            }
            Request::RegisterTriggerKeys {
                input_method_id,
                on_keys,
                off_keys,
            } => {
                34u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                writer.write(&[0u8; 2]);
                ((on_keys.iter().map(|e| e.size()).sum::<usize>() + 0 + 4 - 4 - 0) as u32)
                    .write(writer);
                for elem in on_keys.iter() {
                    elem.write(writer);
                }
                ((off_keys.iter().map(|e| e.size()).sum::<usize>() + 0 + 4 - 4 - 0) as u32)
                    .write(writer);
                for elem in off_keys.iter() {
                    elem.write(writer);
                }
            }
            Request::ResetIc {
                input_method_id,
                input_context_id,
            } => {
                64u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::ResetIcReply {
                input_method_id,
                input_context_id,
                preedit_string,
            } => {
                65u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                (preedit_string.len() as u16).write(writer);
                writer.write(&preedit_string);
                writer.write_pad4();
            }
            Request::SetEventMask {
                input_method_id,
                input_context_id,
                forward_event_mask,
                synchronous_event_mask,
            } => {
                37u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                forward_event_mask.write(writer);
                synchronous_event_mask.write(writer);
            }
            Request::SetIcFocus {
                input_method_id,
                input_context_id,
            } => {
                58u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::SetIcValues {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                54u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                ((ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 2 + 2 - 2 - 2) as u16)
                    .write(writer);
                0u16.write(writer);
                for elem in ic_attributes.iter() {
                    elem.write(writer);
                }
            }
            Request::SetIcValuesReply {
                input_method_id,
                input_context_id,
            } => {
                55u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::SetImValues {
                input_method_id,
                attributes,
            } => {
                42u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                ((attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2 - 0) as u16)
                    .write(writer);
                for elem in attributes.iter() {
                    elem.write(writer);
                }
            }
            Request::SetImValuesReply { input_method_id } => {
                43u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                writer.write(&[0u8; 2]);
            }
            Request::StatusDone {
                input_method_id,
                input_context_id,
            } => {
                81u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::StatusDraw {
                input_method_id,
                input_context_id,
                content,
            } => {
                80u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                content.write(writer);
            }
            Request::StatusStart {
                input_method_id,
                input_context_id,
            } => {
                79u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::StrConversion {} => {
                71u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::StrConversionReply {} => {
                72u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
            }
            Request::Sync {
                input_method_id,
                input_context_id,
            } => {
                61u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::SyncReply {
                input_method_id,
                input_context_id,
            } => {
                62u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::TriggerNotify {
                input_method_id,
                input_context_id,
                flag,
                index,
                event_mask,
            } => {
                35u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
                flag.write(writer);
                index.write(writer);
                event_mask.write(writer);
            }
            Request::TriggerNotifyReply {
                input_method_id,
                input_context_id,
            } => {
                36u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
            Request::UnsetIcFocus {
                input_method_id,
                input_context_id,
            } => {
                59u8.write(writer);
                0u8.write(writer);
                (((self.size() - 4) / 4) as u16).write(writer);
                input_method_id.write(writer);
                input_context_id.write(writer);
            }
        }
    }
    fn size(&self) -> usize {
        let mut content_size = 0;
        match self {
            Request::AuthNext {} => {}
            Request::AuthNg {} => {}
            Request::AuthReply {} => {}
            Request::AuthRequired {} => {}
            Request::AuthSetup {} => {}
            Request::Close { input_method_id } => {
                content_size += input_method_id.size() + 2;
            }
            Request::CloseReply { input_method_id } => {
                content_size += input_method_id.size() + 2;
            }
            Request::Commit {
                input_method_id,
                input_context_id,
                data,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += data.size();
            }
            Request::Connect {
                endian,
                client_major_protocol_version,
                client_minor_protocol_version,
                client_auth_protocol_names,
            } => {
                content_size += endian.size() + 1;
                content_size += client_major_protocol_version.size();
                content_size += client_minor_protocol_version.size();
                content_size += client_auth_protocol_names
                    .iter()
                    .map(|e| with_pad4(e.len() + 2 + 0 - 0))
                    .sum::<usize>()
                    + 0
                    + 2;
            }
            Request::ConnectReply {
                server_major_protocol_version,
                server_minor_protocol_version,
            } => {
                content_size += server_major_protocol_version.size();
                content_size += server_minor_protocol_version.size();
            }
            Request::CreateIc {
                input_method_id,
                ic_attributes,
            } => {
                content_size += input_method_id.size();
                content_size += ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2;
            }
            Request::CreateIcReply {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::DestroyIc {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::DestroyIcReply {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::Disconnect {} => {}
            Request::DisconnectReply {} => {}
            Request::EncodingNegotiation {
                input_method_id,
                encodings,
                encoding_infos,
            } => {
                content_size += input_method_id.size();
                content_size +=
                    with_pad4(encodings.iter().map(|e| e.len() + 1 + 0).sum::<usize>() + 0 + 2 - 2)
                        + 2;
                content_size += encoding_infos
                    .iter()
                    .map(|e| with_pad4(e.len() + 2 + 0 - 0))
                    .sum::<usize>()
                    + 2
                    + 2;
            }
            Request::EncodingNegotiationReply {
                input_method_id,
                category,
                index,
            } => {
                content_size += input_method_id.size();
                content_size += category.size();
                content_size += index.size() + 2;
            }
            Request::Error {
                input_method_id,
                input_context_id,
                flag,
                code,
                detail,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += flag.size();
                content_size += code.size();
                content_size += with_pad4(detail.len() + 2 + 2 - 0);
            }
            Request::ForwardEvent {
                input_method_id,
                input_context_id,
                flag,
                serial_number,
                xev,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += flag.size();
                content_size += serial_number.size();
                content_size += xev.size();
            }
            Request::Geometry {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::GetIcValues {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size +=
                    with_pad4(ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 0);
            }
            Request::GetIcValuesReply {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 2 + 2;
            }
            Request::GetImValues {
                input_method_id,
                im_attributes,
            } => {
                content_size += input_method_id.size();
                content_size +=
                    with_pad4(im_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2 - 2)
                        + 2;
            }
            Request::GetImValuesReply {
                input_method_id,
                im_attributes,
            } => {
                content_size += input_method_id.size();
                content_size += im_attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2;
            }
            Request::Open { locale } => {
                content_size += with_pad4(locale.len() + 1 + 0 - 0);
            }
            Request::OpenReply {
                input_method_id,
                im_attrs,
                ic_attrs,
            } => {
                content_size += input_method_id.size();
                content_size += im_attrs.iter().map(|e| e.size()).sum::<usize>() + 0 + 2;
                content_size += ic_attrs.iter().map(|e| e.size()).sum::<usize>() + 2 + 2;
            }
            Request::PreeditCaret {
                input_method_id,
                input_context_id,
                position,
                direction,
                style,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += position.size();
                content_size += direction.size();
                content_size += style.size();
            }
            Request::PreeditCaretReply {
                input_method_id,
                input_context_id,
                position,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += position.size();
            }
            Request::PreeditDone {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::PreeditDraw {
                input_method_id,
                input_context_id,
                caret,
                chg_first,
                chg_length,
                status,
                preedit_string,
                feedbacks,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += caret.size();
                content_size += chg_first.size();
                content_size += chg_length.size();
                content_size += status.size();
                content_size += with_pad4(preedit_string.len() + 2 - 0);
                content_size += feedbacks.iter().map(|e| e.size()).sum::<usize>() + 2 + 2;
            }
            Request::PreeditStart {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::PreeditStartReply {
                input_method_id,
                input_context_id,
                return_value,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += return_value.size();
            }
            Request::PreeditState {
                input_method_id,
                input_context_id,
                state,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += state.size();
            }
            Request::QueryExtension {
                input_method_id,
                extensions,
            } => {
                content_size += input_method_id.size();
                content_size += with_pad4(
                    extensions.iter().map(|e| e.len() + 1 + 0).sum::<usize>() + 0 + 2 - 0,
                );
            }
            Request::QueryExtensionReply {
                input_method_id,
                extensions,
            } => {
                content_size += input_method_id.size();
                content_size += extensions.iter().map(|e| e.size()).sum::<usize>() + 0 + 2;
            }
            Request::RegisterTriggerKeys {
                input_method_id,
                on_keys,
                off_keys,
            } => {
                content_size += input_method_id.size() + 2;
                content_size += on_keys.iter().map(|e| e.size()).sum::<usize>() + 0 + 4;
                content_size += off_keys.iter().map(|e| e.size()).sum::<usize>() + 0 + 4;
            }
            Request::ResetIc {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::ResetIcReply {
                input_method_id,
                input_context_id,
                preedit_string,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += with_pad4(preedit_string.len() + 2 - 0);
            }
            Request::SetEventMask {
                input_method_id,
                input_context_id,
                forward_event_mask,
                synchronous_event_mask,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += forward_event_mask.size();
                content_size += synchronous_event_mask.size();
            }
            Request::SetIcFocus {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::SetIcValues {
                input_method_id,
                input_context_id,
                ic_attributes,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += ic_attributes.iter().map(|e| e.size()).sum::<usize>() + 2 + 2;
            }
            Request::SetIcValuesReply {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::SetImValues {
                input_method_id,
                attributes,
            } => {
                content_size += input_method_id.size();
                content_size += attributes.iter().map(|e| e.size()).sum::<usize>() + 0 + 2;
            }
            Request::SetImValuesReply { input_method_id } => {
                content_size += input_method_id.size() + 2;
            }
            Request::StatusDone {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::StatusDraw {
                input_method_id,
                input_context_id,
                content,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += content.size();
            }
            Request::StatusStart {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::StrConversion {} => {}
            Request::StrConversionReply {} => {}
            Request::Sync {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::SyncReply {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::TriggerNotify {
                input_method_id,
                input_context_id,
                flag,
                index,
                event_mask,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
                content_size += flag.size();
                content_size += index.size();
                content_size += event_mask.size();
            }
            Request::TriggerNotifyReply {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
            Request::UnsetIcFocus {
                input_method_id,
                input_context_id,
            } => {
                content_size += input_method_id.size();
                content_size += input_context_id.size();
            }
        }
        content_size + 4
    }
}
