// File: rurban[P]dgnlib/dgnwrite.cpp
// Function: DGNAddRawAttrLink
int DGNAddRawAttrLink( DGNHandle hDGN, DGNElemCore *psElement, 
                       int nLinkSize, unsigned char *pabyRawLinkData )

{
    int   iLinkage;

    if( nLinkSize % 2 == 1 )
        nLinkSize++;

    if( psElement->size + nLinkSize > 768 )
    {
        CPLError( CE_Failure, CPLE_ElementTooBig, 
                  "Attempt to add %d byte linkage to element exceeds maximum"
                  " element size.", 
                  nLinkSize );
        return -1;
    }
    
/* -------------------------------------------------------------------- */
/*      Ensure the attribute linkage bit is set.                        */
/* -------------------------------------------------------------------- */
    psElement->properties |= DGNPF_ATTRIBUTES;

/* -------------------------------------------------------------------- */
/*      Append the attribute linkage to the linkage area.               */
/* -------------------------------------------------------------------- */
    psElement->attr_bytes += nLinkSize;
    psElement->attr_data = (unsigned char *) 
        CPLRealloc( psElement->attr_data, psElement->attr_bytes );
    
    memcpy( psElement->attr_data + (psElement->attr_bytes-nLinkSize), 
            pabyRawLinkData, nLinkSize );
    
/* -------------------------------------------------------------------- */
/*      Grow the raw data, if we have rawdata.                          */
/* -------------------------------------------------------------------- */
    psElement->raw_bytes = psElement->raw_bytes += nLinkSize;
    psElement->raw_data = (unsigned char *) 
        CPLRealloc( psElement->raw_data, psElement->raw_bytes );
    
    memcpy( psElement->raw_data + (psElement->raw_bytes-nLinkSize), 
            pabyRawLinkData, nLinkSize );
    
/* -------------------------------------------------------------------- */
/*      If the element is a shape or chain complex header, then we      */
/*      need to increase the total complex group size appropriately.    */
/* -------------------------------------------------------------------- */
    if( psElement->stype == DGNST_COMPLEX_HEADER ||
        psElement->stype == DGNST_TEXT_NODE )  // compatible structures
    {
        DGNElemComplexHeader *psCT = (DGNElemComplexHeader *) psElement;

        psCT->totlength += (nLinkSize / 2);

        psElement->raw_data[36] = (unsigned char) (psCT->totlength % 256);
        psElement->raw_data[37] = (unsigned char) (psCT->totlength / 256);
    }

/* -------------------------------------------------------------------- */
/*      Ensure everything is updated properly, including element        */
/*      length and properties.                                          */
/* -------------------------------------------------------------------- */
    DGNUpdateElemCoreExtended( hDGN, psElement );

/* -------------------------------------------------------------------- */
/*      Figure out what the linkage index is.                           */
/* -------------------------------------------------------------------- */
    for( iLinkage = 0; ; iLinkage++ )
    {
        if( DGNGetLinkage( hDGN, psElement, iLinkage, NULL, NULL, NULL, NULL )
            == NULL )
            break;
    }

    return iLinkage-1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movl -0x1c(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
cmpl $0x1, %edx
jne 0x15fe0
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
addl -0x1c(%rbp), %eax
cmpl $0x300, %eax            # imm = 0x300
jle 0x16018
movl -0x1c(%rbp), %ecx
movl $0x3, %edi
movl $0x1, %esi
leaq 0x4895(%rip), %rdx      # 0x1a89a
movb $0x0, %al
callq 0x5740
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x16191
movq -0x18(%rbp), %rax
movl 0x24(%rax), %ecx
orl $0x800, %ecx            # imm = 0x800
movl %ecx, 0x24(%rax)
movl -0x1c(%rbp), %ecx
movq -0x18(%rbp), %rax
addl 0x34(%rax), %ecx
movl %ecx, 0x34(%rax)
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x18(%rbp), %rax
movslq 0x34(%rax), %rsi
callq 0x3120
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x34(%rax), %eax
subl -0x1c(%rbp), %eax
cltq
addq %rax, %rdi
movq -0x28(%rbp), %rsi
movslq -0x1c(%rbp), %rdx
callq 0x2240
movl -0x1c(%rbp), %ecx
movq -0x18(%rbp), %rax
addl 0x40(%rax), %ecx
movl %ecx, 0x40(%rax)
movq -0x18(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x18(%rbp), %rax
movslq 0x40(%rax), %rsi
callq 0x3120
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x40(%rax), %eax
subl -0x1c(%rbp), %eax
cltq
addq %rax, %rdi
movq -0x28(%rbp), %rsi
movslq -0x1c(%rbp), %rdx
callq 0x2240
movq -0x18(%rbp), %rax
cmpl $0x7, 0xc(%rax)
je 0x160e5
movq -0x18(%rbp), %rax
cmpl $0xd, 0xc(%rax)
jne 0x1613c
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x1c(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x38(%rbp), %rax
addl 0x50(%rax), %ecx
movl %ecx, 0x50(%rax)
movq -0x38(%rbp), %rax
movl 0x50(%rax), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movb %dl, %cl
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movb %cl, 0x24(%rax)
movq -0x38(%rbp), %rax
movl 0x50(%rax), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movb %al, %cl
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movb %cl, 0x25(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x12f50
movl $0x0, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
movl %eax, %r9d
movq %r9, %rcx
movq %r9, %r8
movq $0x0, (%rsp)
callq 0xa710
cmpq $0x0, %rax
jne 0x1617b
jmp 0x16188
jmp 0x1617d
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x16150
movl -0x2c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)