// File: /workspace/github_cpp_makefile_star2_O2/hyp1231[P]FMSS/filesystem.cpp
// Function: FileSystem::CreateInCurDir(int&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
bool FileSystem::CreateInCurDir(int &dir_inodeNum, const string &filename, bool isFile) {
    /*
        step 1: make sure filename isn't too large; otherwise, return FALSE
    */

    if((int)filename.size() > 8) {
        cout << "[Error] filename is too long" << endl;
        return false;
    }

    /*
        step 2: make sure no files have the same name; otherwise, return FALSE
    */

    int new_dir_inodeNum = Get_file_inodeNum_from_dir(dir_inodeNum, filename);
    if(new_dir_inodeNum != -1) {
        dir_inodeNum = new_dir_inodeNum;
        return false;
    }

    /*  
        step 3: search for empty index_node
    */

    int next_inodeNum = Find_empty_inodeNum();
    if(next_inodeNum == -1) {
        cout << "[Error] Cannot find an empty inode" << endl;
        return false;
    }    

    /*
        step 4: search the block_bitmap for empty blocks
    */

    int next_dataBLKNum = Find_empty_dataBLKNum();
    if(next_dataBLKNum == -1) {
        cout << "[Error] Cannot find an empty data block" << endl;
        return false;
    }

    /*
        step 5: create new pair of mapping in its directory's data block
    */

    char inode_buf[64], buf[BLKsize];
    Get_inode_from_inodeNum(inode_buf, dir_inodeNum);

    // modify directory data block
    D.Getblk(buf, Get_actual_dataBLKnumber(byte2int(inode_buf, 42, 44)));
    for(int i = 0; i + 12 <= BLKsize; i += 12) {
    	// find used = 0
    	if(byte2int(buf, i + 8, i + 10) == 0) {
    		// set used = 1;
    		Fill_byte_by_num(buf, i + 8, i + 10, 1);
    		// set filename
    		Fill_byte_by_str(buf, i, i + (int)filename.size(), filename);
    		// zero end of str
    		if((int)filename.size() < 8) {
    			buf[i + filename.size()] = 0;
    		}

    		// set next inodeNum
    		Fill_byte_by_num(buf, i + 10, i + 12, next_inodeNum);

    		break;
    	} 
    }
    D.Putblk(buf, Get_actual_dataBLKnumber(byte2int(inode_buf, 42, 44)));

    /*
        step 6: initialize the inode and the first data block ( set the first block's first byte = 0xFF(EOF) )
    */

    // modify next inode
    D.Getblk(buf, Get_actual_inodeBLKnumber(next_inodeNum));
    int st = 64 * (next_inodeNum % 16);

    string curTime = getTime();
    // set flag
    if (isFile)
        Fill_byte_by_num(buf, st, st + 2, 0);
    else
        Fill_byte_by_num(buf, st, st + 2, 1);
    Fill_byte_by_str(buf, st + 2, st + 2 + (int)filename.size(), filename);
    Fill_byte_by_str(buf, st + 10, st + (int)curTime.size() + 10, curTime);
    Fill_byte_by_str(buf, st + 26, st + (int)curTime.size() + 26, curTime);
    Fill_byte_by_num(buf, st + 42, st + 44, next_dataBLKNum);

    D.Putblk(buf, Get_actual_inodeBLKnumber(next_inodeNum));

    // modify next data block
    D.Getblk(buf, Get_actual_dataBLKnumber(next_dataBLKNum));
    if (isFile) {
        // EOF
        Fill_byte_by_num(buf, 0, 1, -1);  
    }
    else {
        // set index of "."
        Fill_byte_by_str(buf, 0, 8, ".");
        Fill_byte_by_num(buf, 8, 10, 1);
        Fill_byte_by_num(buf, 10, 12, next_inodeNum);
        // set index of ".."
        Fill_byte_by_str(buf, 12, 20, "..");
        Fill_byte_by_num(buf, 20, 22, 1);
        Fill_byte_by_num(buf, 22, 24, dir_inodeNum);
    }
    D.Putblk(buf, Get_actual_dataBLKnumber(next_dataBLKNum));

    /*
        step 7: change inode bitmap and data block bitmap, save the super block
    */

    Fill_inode_bitmap(next_inodeNum, true);
    Fill_data_block_bitmap(next_dataBLKNum, true);
    Save_superBLK();

    dir_inodeNum = next_inodeNum;
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
cmpl $0x9, 0x8(%rdx)
jl 0x33c5
movq 0x7c21(%rip), %rdi      # 0xafd0
leaq 0x40ab(%rip), %rsi      # 0x7461
callq 0x21d0
movq %rax, %rdi
callq 0x20f0
jmp 0x33e1
movl %ecx, %r12d
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
movl (%rsi), %esi
xorl %ecx, %ecx
callq 0x2ff2
cmpl $-0x1, %eax
je 0x33f2
movl %eax, (%rbx)
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x31da
movl %eax, -0x30(%rbp)
cmpl $-0x1, %eax
je 0x35ed
movq %r14, %rdi
callq 0x321e
cmpl $-0x1, %eax
je 0x3600
movl %r12d, -0x38(%rbp)
movq %rsp, -0x58(%rbp)
movl %eax, -0x4c(%rbp)
movl %eax, -0x34(%rbp)
movl (%r14), %eax
movq %rsp, %r12
addq $0xf, %rax
andq $-0x10, %rax
subq %rax, %r12
movq %r12, %rsp
movq %rbx, -0x60(%rbp)
movl (%rbx), %edx
leaq -0xe0(%rbp), %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x3176
leaq 0x8(%r14), %rbx
pushq $0x2a
popq %rsi
pushq $0x2c
popq %rdx
movq %r13, %rdi
callq 0x2917
leal 0x6(%rax), %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2648
xorl %r13d, %r13d
movq %rbx, -0x48(%rbp)
leal 0xc(%r13), %eax
cmpl (%r14), %eax
jg 0x34ee
leal 0x8(%r13), %esi
leal 0xa(%r13), %edx
movq %r12, %rdi
callq 0x2917
addq $0xc, %r13
testl %eax, %eax
jne 0x3478
leaq -0x2(%r13), %rdx
leal -0x4(%r13), %esi
pushq $0x1
popq %rcx
movq %r12, %rdi
movq %rdx, -0x40(%rbp)
callq 0x2b1c
movq 0x8(%r15), %rbx
leal (%rbx,%r13), %edx
addl $-0xc, %edx
leal -0xc(%r13), %esi
movq %r12, %rdi
movq %r15, %rcx
callq 0x2b3c
cmpl $0x7, %ebx
jg 0x34d8
addq %r12, %rbx
movb $0x0, -0xc(%r13,%rbx)
movq %r12, %rdi
movq -0x40(%rbp), %rsi
movl %r13d, %edx
movl -0x30(%rbp), %ecx
callq 0x2b1c
movq -0x48(%rbp), %rbx
leaq -0xe0(%rbp), %rdi
pushq $0x2a
popq %rsi
pushq $0x2c
popq %rdx
callq 0x2917
leal 0x6(%rax), %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x271c
pushq $0x10
popq %rcx
movl -0x30(%rbp), %eax
cltd
idivl %ecx
movl %edx, %r13d
leal 0x1(%rax), %edx
movl %edx, -0x40(%rbp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2648
shll $0x6, %r13d
leaq -0xa0(%rbp), %rdi
callq 0x2b6a
leal 0x2(%r13), %ebx
movl -0x38(%rbp), %eax
xorb $0x1, %al
movzbl %al, %ecx
movq %r12, %rdi
movl %r13d, %esi
movl %ebx, %edx
callq 0x2b1c
movl 0x8(%r15), %edx
addl %ebx, %edx
movq %r12, %rdi
movl %ebx, %esi
movq %r15, %rcx
callq 0x2b3c
leal 0xa(%r13), %esi
leaq -0xa0(%rbp), %rcx
movl 0x8(%rcx), %ebx
leal (%rbx,%r13), %edx
addl $0xa, %edx
movq %r12, %rdi
movq %rcx, %r15
callq 0x2b3c
leal 0x1a(%r13), %esi
leal (%rbx,%r13), %edx
addl $0x1a, %edx
movq -0x48(%rbp), %rbx
movq %r12, %rdi
movq %r15, %rcx
callq 0x2b3c
leal 0x2a(%r13), %esi
orl $0x2c, %r13d
movq %r12, %rdi
movl %r13d, %edx
movl -0x34(%rbp), %ecx
callq 0x2b1c
movq %rbx, %rdi
movq %r12, %rsi
movl -0x40(%rbp), %edx
callq 0x271c
movq -0x60(%rbp), %r13
movl -0x4c(%rbp), %edx
addl $0x6, %edx
movq %rbx, %rdi
movq %r12, %rsi
movl %edx, %r15d
callq 0x2648
cmpb $0x0, -0x38(%rbp)
je 0x3613
movb $-0x1, (%r12)
jmp 0x36af
movq 0x79dc(%rip), %rdi      # 0xafd0
leaq 0x3e83(%rip), %rsi      # 0x747e
jmp 0x33b6
movq 0x79c9(%rip), %rdi      # 0xafd0
leaq 0x3e93(%rip), %rsi      # 0x74a1
jmp 0x33b6
leaq 0x3eb0(%rip), %rsi      # 0x74ca
leaq -0x80(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x27fc
pushq $0x8
popq %rdx
leaq -0x80(%rbp), %rbx
movq %r12, %rdi
xorl %esi, %esi
movq %rbx, %rcx
callq 0x2b3c
movq %rbx, %rdi
callq 0x20e0
movw $0x1, 0x8(%r12)
movl -0x30(%rbp), %eax
movb %al, 0xa(%r12)
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movb %al, 0xb(%r12)
leaq 0x3e62(%rip), %rsi      # 0x74c9
leaq -0x80(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x27fc
pushq $0xc
popq %rsi
pushq $0x14
popq %rdx
movq %r12, %rdi
movq %rbx, %rcx
callq 0x2b3c
movq %rbx, %rdi
callq 0x20e0
movw $0x1, 0x14(%r12)
movl (%r13), %eax
movb %al, 0x16(%r12)
cltd
movl $0x100, %ecx            # imm = 0x100
idivl %ecx
movb %al, 0x17(%r12)
movq -0x48(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
movl %r15d, %edx
callq 0x271c
pushq $0xa
popq %rcx
movl -0x30(%rbp), %eax
cltd
idivl %ecx
movl %edx, %ecx
pushq $0x1
popq %rsi
movl %esi, %edx
shll %cl, %edx
cltq
orb %dl, 0x50(%r14,%rax)
pushq $0x50
popq %rcx
movl -0x34(%rbp), %eax
cltd
idivl %ecx
movl %edx, %ecx
shll %cl, %esi
cltq
orb %sil, 0x5a(%r14,%rax)
movq %r14, %rdi
callq 0x32ca
movl -0x30(%rbp), %eax
movl %eax, (%r13)
leaq -0xa0(%rbp), %rdi
callq 0x20e0
movq -0x58(%rbp), %rsp
movb $0x1, %al
jmp 0x33e3
jmp 0x3714
jmp 0x3714
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x20e0
movq %rbx, %rdi
callq 0x2340
nop