// File: bluesky466[P]ResourcesArscDemo/main.cpp
// Function: main
int main(int argc, char *argv[]) {
	FILE* pFile = fopen(argv[1], "rb");

	printf("=====================RES_TABLE_TYPE=====================\n");
	readResTableHeader(pFile);

	printf("=====================RES_STRING_POOL_TYPE=====================\n");
	struct ResStringPool_header globalStringPoolHeader = readResStringPoolHeader(pFile);
	unsigned char* pGlobalStrings = readStringsFromStringPool(pFile, globalStringPoolHeader);
	struct ResTable_package packageHeader;

	printf("=====================RES_TABLE_PACKAGE_TYPE=====================\n");
	while(readResTablePackageHeader(pFile, &packageHeader)) {
		printf("=====================types=====================\n");
		struct ResStringPool_header typeStringPoolHeader = readResStringPoolHeader(pFile);
		unsigned char* pTypeStrings = readStringsFromStringPool(pFile, typeStringPoolHeader);

		printf("=====================keys=====================\n");
		struct ResStringPool_header keyStringPoolHeader = readResStringPoolHeader(pFile);
		unsigned char* pKeyStrings = readStringsFromStringPool(pFile, keyStringPoolHeader);

		/*
		struct ResChunk_header chunkHeader;
		uint8_t id;
		while(fread((void*)&chunkHeader, sizeof(struct ResChunk_header), 1, pFile)
				&& chunkHeader.type != RES_TABLE_PACKAGE_TYPE) {
			fread((void*)&id, sizeof(uint8_t), 1, pFile);
			printf("0x%x, %d\n", chunkHeader.type, id);
			fseek(pFile, chunkHeader.size - sizeof(struct ResChunk_header) - sizeof(uint8_t), SEEK_CUR);
		}
		continue;
		*/

		struct ResTable_type typeHeader;
		struct ResTable_typeSpec typeSpecHeader;
		uint32_t config;
		uint16_t type;
		while(fread((void*)&type, sizeof(u_int16_t), 1, pFile) != 0) {
			fseek(pFile, -sizeof(uint16_t), SEEK_CUR);
			if(RES_TABLE_TYPE_SPEC_TYPE == type) {
				fread((void*)&typeSpecHeader, sizeof(struct ResTable_typeSpec), 1, pFile);
				printf("type: id=0x%x,name=", typeSpecHeader.id);
				printStringFromStringsPool(
						(uint32_t*)pTypeStrings,
						(char*)pTypeStrings + typeStringPoolHeader.stringsStart - sizeof(struct ResStringPool_header),
						typeSpecHeader.id - 1,
						typeStringPoolHeader.flags & ResStringPool_header::UTF8_FLAG
				);

				for(int i = 0 ; i < typeSpecHeader.entryCount ; i++) {
					fread((void*)&config, sizeof(uint32_t), 1, pFile);
					printf("0x%x\n",config);
				}
			} else if(RES_TABLE_TYPE_TYPE == type) {
				fread((void*)&typeHeader, sizeof(struct ResTable_type), 1, pFile);
				printConfig(typeHeader.config);

				// 实际struct ResTable_type的大小可能不同sdk版本不一样,所以typeHeader.header.headerSize才是真正的头部大小
				fseek(pFile, typeHeader.header.headerSize -  sizeof(struct ResTable_type), SEEK_CUR);;

				uint32_t* pOffsets = (uint32_t*)malloc(typeHeader.entryCount * sizeof(uint32_t));
				fread((void*)pOffsets, sizeof(uint32_t), typeHeader.entryCount, pFile);

				unsigned char* pData = (unsigned char*)malloc(typeHeader.header.size - typeHeader.entriesStart);
				fread((void*)pData, typeHeader.header.size - typeHeader.entriesStart, 1, pFile);

				for(int i = 0 ; i< typeHeader.entryCount ; i++) {
					uint32_t offset = *(pOffsets + i);
					if(offset == ResTable_type::NO_ENTRY) {
						continue;
					}
					struct ResTable_entry* pEntry = (struct ResTable_entry*)(pData + offset);
					printf("entryIndex: 0x%x, key :\n", i);
					printStringFromStringsPool(
							(uint32_t*)pKeyStrings,
							(char*)pKeyStrings + keyStringPoolHeader.stringsStart - sizeof(struct ResStringPool_header),
							pEntry->key.index,
							keyStringPoolHeader.flags & ResStringPool_header::UTF8_FLAG
					);
					if(pEntry->flags & ResTable_entry::FLAG_COMPLEX) {
						struct ResTable_map_entry* pMapEntry = (struct ResTable_map_entry*)(pData + offset);
						for(int i = 0; i <pMapEntry->count ; i++) {
							struct ResTable_map* pMap =
							   	(struct ResTable_map*)(pData + offset + pMapEntry->size + i * sizeof(struct ResTable_map));
							printf("\tname:0x%08x, valueType:%u, value:%u\n",
									pMap->name.ident, pMap->value.dataType, pMap->value.data);
						}
					} else {
						struct Res_value* pValue = (struct Res_value*)((unsigned char*)pEntry + sizeof(struct ResTable_entry));
						printf("value :\n");
						printValue(pValue, globalStringPoolHeader, pGlobalStrings);
						printf("\n");
					}
				}
				free(pOffsets);
				free(pData);
			} else {
				break;
			}
		}
	}

	fclose(pFile);
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x6c50(%rip), %rsi      # 0x9028
callq 0x21d0
movq %rax, -0x18(%rbp)
leaq 0x6c43(%rip), %rdi      # 0x902b
movb $0x0, %al
callq 0x2030
movq -0x18(%rbp), %rdi
callq 0x2a00
leaq 0x6c66(%rip), %rdi      # 0x9065
movb $0x0, %al
callq 0x2030
movq -0x18(%rbp), %rsi
leaq -0x34(%rbp), %rdi
callq 0x2a80
movq -0x18(%rbp), %rdi
movq -0x34(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x2c(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x24(%rbp), %rax
movq %rax, -0x50(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x48(%rbp)
leaq -0x60(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movl 0x18(%rax), %eax
movl %eax, 0x18(%rsp)
callq 0x2af0
movq %rax, -0x40(%rbp)
leaq 0x6c3c(%rip), %rdi      # 0x90a5
movb $0x0, %al
callq 0x2030
movq -0x18(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x2bd0
cmpl $0x0, %eax
je 0x29e1
leaq 0x6c57(%rip), %rdi      # 0x90e7
movb $0x0, %al
callq 0x2030
movq -0x18(%rbp), %rsi
leaq -0x19c(%rbp), %rdi
callq 0x2a80
movq -0x18(%rbp), %rdi
movq -0x19c(%rbp), %rax
movq %rax, -0x1c8(%rbp)
movq -0x194(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x18c(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movl -0x184(%rbp), %eax
movl %eax, -0x1b0(%rbp)
leaq -0x1c8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movl 0x18(%rax), %eax
movl %eax, 0x18(%rsp)
callq 0x2af0
movq %rax, -0x1a8(%rbp)
leaq 0x6bfd(%rip), %rdi      # 0x9118
movb $0x0, %al
callq 0x2030
movq -0x18(%rbp), %rsi
leaq -0x1e4(%rbp), %rdi
callq 0x2a80
movq -0x18(%rbp), %rdi
movq -0x1e4(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x1dc(%rbp), %rax
movq %rax, -0x208(%rbp)
movq -0x1d4(%rbp), %rax
movq %rax, -0x200(%rbp)
movl -0x1cc(%rbp), %eax
movl %eax, -0x1f8(%rbp)
leaq -0x210(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movl 0x18(%rax), %eax
movl %eax, 0x18(%rsp)
callq 0x2af0
movq %rax, -0x1f0(%rbp)
movq -0x18(%rbp), %rcx
leaq -0x25e(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x2250
cmpq $0x0, %rax
je 0x29dc
movq -0x18(%rbp), %rdi
movq $-0x2, %rsi
movl $0x1, %edx
callq 0x21b0
movzwl -0x25e(%rbp), %ecx
movl $0x202, %eax            # imm = 0x202
cmpl %ecx, %eax
jne 0x26ad
movq -0x18(%rbp), %rcx
leaq -0x258(%rbp), %rdi
movl $0x10, %esi
movl $0x1, %edx
callq 0x2250
movzbl -0x250(%rbp), %esi
leaq 0x6b34(%rip), %rdi      # 0x9148
movb $0x0, %al
callq 0x2030
movq -0x1a8(%rbp), %rdi
movq -0x1a8(%rbp), %rsi
movl -0x188(%rbp), %eax
addq %rax, %rsi
addq $-0x1c, %rsi
movzbl -0x250(%rbp), %edx
subl $0x1, %edx
movl -0x18c(%rbp), %ecx
andl $0x100, %ecx            # imm = 0x100
callq 0x2c50
movl $0x0, -0x264(%rbp)
movl -0x264(%rbp), %eax
cmpl -0x24c(%rbp), %eax
jae 0x26a8
movq -0x18(%rbp), %rcx
leaq -0x25c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2250
movl -0x25c(%rbp), %esi
leaq 0x6acc(%rip), %rdi      # 0x915c
movb $0x0, %al
callq 0x2030
movl -0x264(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x264(%rbp)
jmp 0x265b
jmp 0x29d7
movzwl -0x25e(%rbp), %ecx
movl $0x201, %eax            # imm = 0x201
cmpl %ecx, %eax
jne 0x29d3
movq -0x18(%rbp), %rcx
leaq -0x248(%rbp), %rdi
movl $0x38, %esi
movl $0x1, %edx
callq 0x2250
leaq -0x248(%rbp), %rsi
addq $0x14, %rsi
leaq -0x288(%rbp), %rdi
movl $0x24, %edx
callq 0x2130
movl -0x268(%rbp), %ecx
movq %rsp, %rax
movl %ecx, 0x20(%rax)
movups -0x288(%rbp), %xmm0
movups -0x278(%rbp), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x2cb0
movq -0x18(%rbp), %rdi
movzwl -0x246(%rbp), %eax
movl %eax, %esi
subq $0x38, %rsi
movl $0x1, %edx
callq 0x21b0
movl -0x23c(%rbp), %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x2210
movq %rax, -0x290(%rbp)
movq -0x290(%rbp), %rdi
movl -0x23c(%rbp), %eax
movl %eax, %edx
movq -0x18(%rbp), %rcx
movl $0x4, %esi
callq 0x2250
movl -0x244(%rbp), %eax
subl -0x238(%rbp), %eax
movl %eax, %eax
movl %eax, %edi
callq 0x2210
movq %rax, -0x298(%rbp)
movq -0x298(%rbp), %rdi
movl -0x244(%rbp), %eax
subl -0x238(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
movq -0x18(%rbp), %rcx
movl $0x1, %edx
callq 0x2250
movl $0x0, -0x29c(%rbp)
movl -0x29c(%rbp), %eax
cmpl -0x23c(%rbp), %eax
jae 0x29b9
movq -0x290(%rbp), %rax
movslq -0x29c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x2a0(%rbp)
cmpl $-0x1, -0x2a0(%rbp)
jne 0x27ef
jmp 0x29a5
movq -0x298(%rbp), %rax
movl -0x2a0(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x2a8(%rbp)
movl -0x29c(%rbp), %esi
leaq 0x694f(%rip), %rdi      # 0x9162
movb $0x0, %al
callq 0x2030
movq -0x1f0(%rbp), %rdi
movq -0x1f0(%rbp), %rsi
movl -0x1d0(%rbp), %eax
addq %rax, %rsi
addq $-0x1c, %rsi
movq -0x2a8(%rbp), %rax
movl 0x4(%rax), %edx
movl -0x1d4(%rbp), %ecx
andl $0x100, %ecx            # imm = 0x100
callq 0x2c50
movq -0x2a8(%rbp), %rax
movzwl 0x2(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x2914
movq -0x298(%rbp), %rax
movl -0x2a0(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x2b0(%rbp)
movl $0x0, -0x2b4(%rbp)
movl -0x2b4(%rbp), %eax
movq -0x2b0(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jae 0x290f
movq -0x298(%rbp), %rax
movl -0x2a0(%rbp), %ecx
addq %rcx, %rax
movq -0x2b0(%rbp), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movslq -0x2b4(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x2c0(%rbp)
movq -0x2c0(%rbp), %rax
movl (%rax), %esi
movq -0x2c0(%rbp), %rax
movzbl 0x7(%rax), %edx
movq -0x2c0(%rbp), %rax
movl 0x8(%rax), %ecx
leaq 0x6887(%rip), %rdi      # 0x917b
movb $0x0, %al
callq 0x2030
movl -0x2b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b4(%rbp)
jmp 0x2888
jmp 0x29a3
movq -0x2a8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x2c8(%rbp)
leaq 0x6874(%rip), %rdi      # 0x91a1
movb $0x0, %al
callq 0x2030
movq -0x2c8(%rbp), %rdi
movq -0x34(%rbp), %rax
movq %rax, -0x2e8(%rbp)
movq -0x2c(%rbp), %rax
movq %rax, -0x2e0(%rbp)
movq -0x24(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x2d0(%rbp)
movq -0x40(%rbp), %rsi
leaq -0x2e8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movl 0x18(%rax), %eax
movl %eax, 0x18(%rsp)
callq 0x2d20
leaq 0x6908(%rip), %rdi      # 0x92a4
movb $0x0, %al
callq 0x2030
jmp 0x29a5
movl -0x29c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x29c(%rbp)
jmp 0x27b8
movq -0x290(%rbp), %rdi
callq 0x21e0
movq -0x298(%rbp), %rdi
callq 0x21e0
jmp 0x29d5
jmp 0x29dc
jmp 0x29d7
jmp 0x259f
jmp 0x2470
movq -0x18(%rbp), %rdi
callq 0x2180
xorl %eax, %eax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
nopw %cs:(%rax,%rax)