// File: btbujiangjun[P]abcdl/include/utils/ModelLoader.h
// Function: bool abcdl::utils::ModelLoader::write<float>(std::vector<abcdl::algebra::Matrix<float>*, std::allocator<abcdl::algebra::Matrix<float>*>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
bool ModelLoader::write(std::vector<abcdl::algebra::Matrix<T>*> models,
                        const std::string& path,
                        const std::string& signature,
                        bool is_append){
    std::vector<abcdl::algebra::Matrix<T>*> old_models;
    if(is_append){
        read<T>(path, &old_models, signature);
    }
    
    size_t num_models = models.size() + old_models.size();
    std::vector<ModelInfo> infos;

    if(!generate_header(old_models, &infos) || !generate_header(models, &infos)){
        return false;
    }
     
    /**
    std::ofstream out_file(path, std::ios::binary);
    std::ofstream out_file(path, std::ios::out);

    out_file.write(signature.c_str(), sizeof(char)*signature.size());
    out_file.write((char*)&num_models, sizeof(size_t));
    for(auto&& info : infos){
        out_file.write(&info.type, sizeof(char));
        out_file.write((char*)&info.rows, sizeof(size_t));
        out_file.write((char*)&info.cols, sizeof(size_t));
    }

    size_t num_old_models = old_models.size();
    for(size_t i = 0; i != num_old_models; i++){
        out_file.write((char*)old_models[i]->data(), sizeof(T) * infos[i].rows * infos[i].cols);
    }

    num_models = models.size();
    for(size_t i = 0; i != num_models; i++){
        ModelInfo info = infos[i+num_old_models];
        out_file.write((char*)models[i]->data(), sizeof(T) * info.rows * info.cols);
    }
    **/

    std::ofstream out_file(path, std::ios::out);
    out_file << signature << std::endl;
    out_file << num_models << std::endl;
    for(auto&& info : infos){
        out_file << info.type << std::endl;
        out_file << info.rows << std::endl;
        out_file << info.cols << std::endl;
    }
    
    size_t num_old_models = old_models.size();
    for(size_t i = 0; i != num_old_models; i++){
        size_t model_size = infos[i].rows * infos[i].cols;
        for(size_t j = 0; j < model_size; j++){
            out_file << old_models[i]->get_data(j) << std::endl;
        }
    }

    num_models = models.size();
    for(size_t i = 0; i < num_models; i++){
        size_t model_size = infos[i + num_old_models].rows * infos[i + num_old_models].cols;
        for(size_t j = 0; j < model_size; j++){
            out_file << models[i]->get_data(j) << std::endl;
        }
    }
    out_file.close();

    return true;
}

// Assembly:
subq $0x388, %rsp            # imm = 0x388
movq %rsi, 0x70(%rsp)
movb %r8b, %al
movq %rdi, 0x378(%rsp)
movq %rsi, 0x370(%rsp)
movq %rdx, 0x368(%rsp)
movq %rcx, 0x360(%rsp)
andb $0x1, %al
movb %al, 0x35f(%rsp)
movq 0x378(%rsp), %rax
movq %rax, 0x78(%rsp)
leaq 0x340(%rsp), %rdi
callq 0x2c290
testb $0x1, 0x35f(%rsp)
je 0x2d11b
movq 0x78(%rsp), %rdi
movq 0x368(%rsp), %rsi
movq 0x360(%rsp), %rcx
leaq 0x340(%rsp), %rdx
callq 0x2c2a0
jmp 0x2d100
jmp 0x2d11b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x338(%rsp)
movl %eax, 0x334(%rsp)
jmp 0x2d738
movq 0x70(%rsp), %rdi
callq 0x2c820
movq %rax, 0x60(%rsp)
leaq 0x340(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x2c820
movq %rax, %rcx
movq 0x60(%rsp), %rax
addq %rcx, %rax
movq %rax, 0x328(%rsp)
leaq 0x310(%rsp), %rdi
callq 0x2f730
movq 0x68(%rsp), %rsi
movb $0x0, 0x2df(%rsp)
leaq 0x2f8(%rsp), %rdi
callq 0x2d760
jmp 0x2d178
movq 0x78(%rsp), %rdi
leaq 0x2f8(%rsp), %rsi
leaq 0x310(%rsp), %rdx
callq 0x30c70
movb %al, 0x5f(%rsp)
jmp 0x2d198
movb 0x5f(%rsp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x5e(%rsp)
jne 0x2d1a9
jmp 0x2d1ef
movq 0x70(%rsp), %rsi
leaq 0x2e0(%rsp), %rdi
callq 0x2d760
jmp 0x2d1bd
movq 0x78(%rsp), %rdi
movb $0x1, 0x2df(%rsp)
leaq 0x2e0(%rsp), %rsi
leaq 0x310(%rsp), %rdx
callq 0x30c70
movb %al, 0x5d(%rsp)
jmp 0x2d1e5
movb 0x5d(%rsp), %al
xorb $-0x1, %al
movb %al, 0x5e(%rsp)
movb 0x5e(%rsp), %al
movb %al, 0x5c(%rsp)
testb $0x1, 0x2df(%rsp)
jne 0x2d203
jmp 0x2d210
leaq 0x2e0(%rsp), %rdi
callq 0x2cfe0
leaq 0x2f8(%rsp), %rdi
callq 0x2cfe0
movb 0x5c(%rsp), %al
testb $0x1, %al
jne 0x2d22a
jmp 0x2d2b2
movb $0x0, 0x387(%rsp)
movl $0x1, 0x2d8(%rsp)
jmp 0x2d700
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x338(%rsp)
movl %eax, 0x334(%rsp)
jmp 0x2d72b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x338(%rsp)
movl %eax, 0x334(%rsp)
jmp 0x2d2a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x338(%rsp)
movl %eax, 0x334(%rsp)
testb $0x1, 0x2df(%rsp)
jne 0x2d291
jmp 0x2d29e
leaq 0x2e0(%rsp), %rdi
callq 0x2cfe0
jmp 0x2d2a0
leaq 0x2f8(%rsp), %rdi
callq 0x2cfe0
jmp 0x2d72b
movq 0x368(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
movl $0x10, %edx
callq 0x97b0
jmp 0x2d2ce
movq 0x360(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x93d0
movq %rax, 0x50(%rsp)
jmp 0x2d2ea
movq 0x50(%rsp), %rdi
movq 0x9eca2(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d2fd
movq 0x328(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x90d0
movq %rax, 0x48(%rsp)
jmp 0x2d319
movq 0x48(%rsp), %rdi
movq 0x9ec73(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d32c
leaq 0x310(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x2fe20
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x2fc80
movq %rax, 0xc0(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x30e40
testb $0x1, %al
jne 0x2d384
jmp 0x2d46b
leaq 0xc8(%rsp), %rdi
callq 0x30e80
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movsbl (%rax), %esi
leaq 0xd8(%rsp), %rdi
callq 0x94b0
movq %rax, 0x40(%rsp)
jmp 0x2d3b8
movq 0x40(%rsp), %rdi
movq 0x9ebd4(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d3cb
movq 0xb8(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x90d0
movq %rax, 0x38(%rsp)
jmp 0x2d3eb
movq 0x38(%rsp), %rdi
movq 0x9eba1(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d3fe
movq 0xb8(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x90d0
movq %rax, 0x30(%rsp)
jmp 0x2d41e
movq 0x30(%rsp), %rdi
movq 0x9eb6e(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d431
jmp 0x2d433
leaq 0xc8(%rsp), %rdi
callq 0x30e90
jmp 0x2d366
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x338(%rsp)
movl %eax, 0x334(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x9620
jmp 0x2d72b
leaq 0x340(%rsp), %rdi
callq 0x2c820
movq %rax, 0xb0(%rsp)
movq $0x0, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
cmpq 0xb0(%rsp), %rax
je 0x2d59a
movq 0xa8(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x2f7b0
movq 0x8(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0xa8(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x2f7b0
movq %rax, %rcx
movq 0x28(%rsp), %rax
imulq 0x10(%rcx), %rax
movq %rax, 0xa0(%rsp)
movq $0x0, 0x98(%rsp)
movq 0x98(%rsp), %rax
cmpq 0xa0(%rsp), %rax
jae 0x2d57f
movq 0xa8(%rsp), %rsi
leaq 0x340(%rsp), %rdi
callq 0x2cc90
movq (%rax), %rdi
movq 0x98(%rsp), %rsi
callq 0x30eb0
movq %rax, 0x20(%rsp)
jmp 0x2d534
movq 0x20(%rsp), %rax
movss (%rax), %xmm0
leaq 0xd8(%rsp), %rdi
callq 0x9310
movq %rax, 0x18(%rsp)
jmp 0x2d551
movq 0x18(%rsp), %rdi
movq 0x9ea3b(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d564
jmp 0x2d566
movq 0x98(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x98(%rsp)
jmp 0x2d4f6
jmp 0x2d581
movq 0xa8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa8(%rsp)
jmp 0x2d48c
movq 0x70(%rsp), %rdi
callq 0x2c820
movq %rax, 0x328(%rsp)
movq $0x0, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0x328(%rsp), %rax
jae 0x2d6d1
movq 0x90(%rsp), %rsi
addq 0xb0(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x2f7b0
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x90(%rsp), %rsi
addq 0xb0(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x2f7b0
movq %rax, %rcx
movq 0x10(%rsp), %rax
imulq 0x10(%rcx), %rax
movq %rax, 0x88(%rsp)
movq $0x0, 0x80(%rsp)
movq 0x80(%rsp), %rax
cmpq 0x88(%rsp), %rax
jae 0x2d6b6
movq 0x70(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x2cc90
movq (%rax), %rdi
movq 0x80(%rsp), %rsi
callq 0x30eb0
movq %rax, 0x8(%rsp)
jmp 0x2d66d
movq 0x8(%rsp), %rax
movss (%rax), %xmm0
leaq 0xd8(%rsp), %rdi
callq 0x9310
movq %rax, (%rsp)
jmp 0x2d689
movq (%rsp), %rdi
movq 0x9e904(%rip), %rsi     # 0xcbf98
callq 0x9450
jmp 0x2d69b
jmp 0x2d69d
movq 0x80(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x80(%rsp)
jmp 0x2d632
jmp 0x2d6b8
movq 0x90(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x90(%rsp)
jmp 0x2d5b8
leaq 0xd8(%rsp), %rdi
callq 0x95e0
jmp 0x2d6e0
movb $0x1, 0x387(%rsp)
movl $0x1, 0x2d8(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x9620
leaq 0x310(%rsp), %rdi
callq 0x2f840
leaq 0x340(%rsp), %rdi
callq 0x2cfe0
movb 0x387(%rsp), %al
andb $0x1, %al
addq $0x388, %rsp            # imm = 0x388
retq
leaq 0x310(%rsp), %rdi
callq 0x2f840
leaq 0x340(%rsp), %rdi
callq 0x2cfe0
movq 0x338(%rsp), %rdi
callq 0x9700
nopw %cs:(%rax,%rax)
nopl (%rax)