// File: /workspace/github_cpp_makefile_star2_O1/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 0x2d54
movq %rax, %r14
movl $0xa, 0xc(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0xafa2
movzwl 0x3c(%rbx), %eax
movl %eax, 0x50(%r14)
movzwl 0x3e(%rbx), %eax
movl %eax, 0x58(%r14)
leaq 0x40(%rbx), %rdi
callq 0x2e6c
movq %rax, 0x60(%r14)
movl $0xffffffff, 0x54(%r14) # imm = 0xFFFFFFFF
cmpl $0x8, 0x34(%r14)
jl 0xba3a
movq 0x38(%r14), %rax
cmpb $0x3, (%rax)
jne 0xba3a
cmpb $0x10, 0x1(%rax)
jne 0xba3a
cmpb $0x2f, 0x2(%rax)
jne 0xba3a
cmpb $0x7d, 0x3(%rax)
jne 0xba3a
movzwl 0x4(%rax), %eax
movl %eax, 0x54(%r14)
movslq 0x50(%r14), %rax
shlq $0x3, %rax
leaq (%rax,%rax,4), %rdi
callq 0x2d9b
movq %rax, 0x68(%r14)
cmpl $0x0, 0x50(%r14)
jle 0xbb5b
addq $0x10, %rbx
movq 0x60(%r14), %rdi
callq 0x2120
movq %rax, %r15
addl $0x32, %r15d
leaq 0x2(%rbx), %rax
movq %rax, 0x8(%rsp)
movl $0x20, %ebp
xorl %r13d, %r13d
movq %r14, 0x10(%rsp)
movq 0x68(%r14), %r12
movslq %r15d, %r15
leaq (%rbx,%r15), %rdi
callq 0x2e6c
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 (%rbx,%rdi), %eax
movl %eax, -0x18(%r12,%rbp)
addq 0x8(%rsp), %rdi
callq 0x2e6c
movq %rax, -0x10(%r12,%rbp)
movq %rax, %rdi
callq 0x2120
leal (%rax,%r14), %r15d
addl $0x4, %r15d
movslq %r15d, %rax
movzwl (%rbx,%rax), %ecx
movl %ecx, -0x8(%r12,%rbp)
decl %ecx
cmpl $0x4, %ecx
ja 0xbb05
addq $0x7, %rax
leaq 0x5c83(%rip), %rdx      # 0x11778
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl (%rbx,%rax), %eax
movl %eax, (%r12,%rbp)
addl $0xb, %r15d
jmp 0xbb42
movslq %eax, %rdi
addq %rbx, %rdi
callq 0x2e6c
movq %rax, (%r12,%rbp)
movq %rax, %rdi
callq 0x2120
addl %eax, %r15d
addl $0x8, %r15d
jmp 0xbb42
movq (%rbx,%rax), %rax
movq %rax, (%r12,%rbp)
addq %rbp, %r12
movq %r12, %rdi
callq 0x70b4
addl $0xf, %r15d
incq %r13
movq 0x10(%rsp), %r14
movslq 0x50(%r14), %rax
addq $0x28, %rbp
cmpq %rax, %r13
jl 0xba84
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)