// File: /workspace/github_cpp_makefile_star2_O3/rurban[P]dgnlib/dgnread.cpp
// Function: DGNParseTagSet(DGNInfo*)
static DGNElemCore *DGNParseTagSet( DGNInfo * psDGN )

{
    DGNElemCore *psElement;
    DGNElemTagSet *psTagSet;
    int          nDataOffset, iTag;
            
    psTagSet = (DGNElemTagSet *) CPLCalloc(sizeof(DGNElemTagSet),1);
    psElement = (DGNElemCore *) psTagSet;
    psElement->stype = DGNST_TAG_SET;

    DGNParseCore( psDGN, psElement );

/* -------------------------------------------------------------------- */
/*      Parse the overall information.                                  */
/* -------------------------------------------------------------------- */
    psTagSet->tagCount = 
        psDGN->abyElem[44] + psDGN->abyElem[45] * 256;
    psTagSet->flags = 
        psDGN->abyElem[46] + psDGN->abyElem[47] * 256;
    psTagSet->tagSetName = CPLStrdup( (const char *) (psDGN->abyElem + 48) );

/* -------------------------------------------------------------------- */
/*      Get the tag set number out of the attributes, if available.     */
/* -------------------------------------------------------------------- */
    psTagSet->tagSet = -1;

    if( psElement->attr_bytes >= 8 
        && psElement->attr_data[0] == 0x03
        && psElement->attr_data[1] == 0x10
        && psElement->attr_data[2] == 0x2f
        && psElement->attr_data[3] == 0x7d )
        psTagSet->tagSet = psElement->attr_data[4]
            + psElement->attr_data[5] * 256;

/* -------------------------------------------------------------------- */
/*      Parse each of the tag definitions.                              */
/* -------------------------------------------------------------------- */
    psTagSet->tagList = (DGNTagDef *) 
        CPLMalloc(sizeof(DGNTagDef) * psTagSet->tagCount);

    nDataOffset = 48 + strlen(psTagSet->tagSetName) + 1 + 1; 

    for( iTag = 0; iTag < psTagSet->tagCount; iTag++ )
    {
        DGNTagDef *tagDef = psTagSet->tagList + iTag;

        CPLAssert( nDataOffset < psDGN->nElemBytes );

        /* collect tag name. */
        tagDef->name = CPLStrdup( (char *) psDGN->abyElem + nDataOffset );
        nDataOffset += strlen(tagDef->name)+1;

        /* Get tag id */
        tagDef->id = psDGN->abyElem[nDataOffset]
            + psDGN->abyElem[nDataOffset+1] * 256;
        nDataOffset += 2;

        /* Get User Prompt */
        tagDef->prompt = CPLStrdup( (char *) psDGN->abyElem + nDataOffset );
        nDataOffset += strlen(tagDef->prompt)+1;


        /* Get type */
        tagDef->type = psDGN->abyElem[nDataOffset]
            + psDGN->abyElem[nDataOffset+1] * 256;
        nDataOffset += 2;

        /* skip five zeros */
        nDataOffset += 5;

        /* Get the default */
        if( tagDef->type == 1 )
        {
            tagDef->defaultValue.string = 
                CPLStrdup( (char *) psDGN->abyElem + nDataOffset );
            nDataOffset += strlen(tagDef->defaultValue.string)+1;
        }
        else if( tagDef->type == 3 || tagDef->type == 5 )
        {
            memcpy( &(tagDef->defaultValue.integer), 
                    psDGN->abyElem + nDataOffset, 4 );
            tagDef->defaultValue.integer = 
                CPL_LSBWORD32( tagDef->defaultValue.integer );
            nDataOffset += 4;
        }
        else if( tagDef->type == 4 )
        {
            memcpy( &(tagDef->defaultValue.real), 
                    psDGN->abyElem + nDataOffset, 8 );
            DGN2IEEEDouble( &(tagDef->defaultValue.real) );
            nDataOffset += 8;
        }
        else
            nDataOffset += 4;
    }
    return psElement;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl $0x70, %edi
movl $0x1, %esi
callq 0x2d20
movq %rax, %r12
movl $0xa, 0xc(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0xab08
movzwl 0x3c(%rbx), %eax
movl %eax, 0x50(%r12)
movzwl 0x3e(%rbx), %eax
movl %eax, 0x58(%r12)
movq %rbx, %r14
leaq 0x40(%rbx), %rdi
callq 0x2e41
movq %rax, 0x60(%r12)
movl $0xffffffff, 0x54(%r12) # imm = 0xFFFFFFFF
cmpl $0x8, 0x34(%r12)
jl 0xb4ed
movq 0x38(%r12), %rax
cmpb $0x3, (%rax)
jne 0xb4ed
cmpb $0x10, 0x1(%rax)
jne 0xb4ed
cmpb $0x2f, 0x2(%rax)
jne 0xb4ed
cmpb $0x7d, 0x3(%rax)
jne 0xb4ed
movzwl 0x4(%rax), %eax
movl %eax, 0x54(%r12)
movslq 0x50(%r12), %rax
shlq $0x3, %rax
leaq (%rax,%rax,4), %rdi
callq 0x2d6b
movq %rax, 0x68(%r12)
cmpl $0x0, 0x50(%r12)
jle 0xb61a
leaq 0x10(%r14), %r13
movq 0x60(%r12), %rdi
callq 0x2120
movq %rax, %r15
addl $0x32, %r15d
addq $0x12, %r14
movq %r14, 0x10(%rsp)
movl $0x20, %ebp
xorl %ebx, %ebx
movq %r12, 0x8(%rsp)
movq 0x68(%r12), %r12
movslq %r15d, %r15
leaq (%r15,%r13), %rdi
callq 0x2e41
movq %rax, -0x20(%r12,%rbp)
movq %rax, %rdi
callq 0x2120
movl %r15d, %r14d
addl %eax, %r14d
addl %r15d, %eax
incl %eax
movslq %eax, %rdi
movzwl (%r13,%rdi), %eax
movl %eax, -0x18(%r12,%rbp)
addq 0x10(%rsp), %rdi
callq 0x2e41
movq %rax, -0x10(%r12,%rbp)
movq %rax, %rdi
callq 0x2120
leal (%rax,%r14), %r15d
addl $0x4, %r15d
movslq %r15d, %rax
movzwl (%r13,%rax), %ecx
movl %ecx, -0x8(%r12,%rbp)
decl %ecx
cmpl $0x4, %ecx
ja 0xb5c2
addq $0x7, %rax
leaq 0x5260(%rip), %rdx      # 0x10810
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl (%r13,%rax), %eax
movl %eax, (%r12,%rbp)
addl $0xb, %r15d
jmp 0xb600
movslq %eax, %rdi
addq %r13, %rdi
callq 0x2e41
movq %rax, (%r12,%rbp)
movq %rax, %rdi
callq 0x2120
addl %eax, %r15d
addl $0x8, %r15d
jmp 0xb600
movq (%r13,%rax), %rax
movq %rax, (%r12,%rbp)
addq %rbp, %r12
movq %r12, %rdi
callq 0x6f74
addl $0xf, %r15d
incq %rbx
movq 0x8(%rsp), %r12
movslq 0x50(%r12), %rax
addq $0x28, %rbp
cmpq %rax, %rbx
jl 0xb53a
movq %r12, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq