From 42701f57d77c329870ef1a5190358a0c4cb66020 Mon Sep 17 00:00:00 2001
From: Alessandragr <alessandra-ribeiro@live.com>
Date: Sun, 9 Feb 2025 12:09:18 -0300
Subject: [PATCH] Correcting fonctions

---
 .gitignore                    |   2 +
 README.md                     |   1 +
 src/Model/GeneticMaterial.cpp | 549 +++++++++++++++++++++-------------
 3 files changed, 348 insertions(+), 204 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9f3bdd9..0d514de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ Docs/
 
 .vscode/
 *.json
+
+vcpkg/
\ No newline at end of file
diff --git a/README.md b/README.md
index 2bed8a1..6e75443 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
 # bioAPI
+## Description
 Development of an API using C++ for advanced biological data analysis using FASTQ and FASTA files.
diff --git a/src/Model/GeneticMaterial.cpp b/src/Model/GeneticMaterial.cpp
index 9a707eb..151195d 100644
--- a/src/Model/GeneticMaterial.cpp
+++ b/src/Model/GeneticMaterial.cpp
@@ -1,3 +1,4 @@
+#include <zlib.h>
 #include <iostream>
 #include <fstream>
 #include <string>
@@ -6,11 +7,27 @@
 #include <stdexcept>
 #include <optional>
 #include <zlib.h>
-#include <tar.h>
 #include <archive.h>
 #include <archive_entry.h>
 #include <vector>
 #include <unzip.h>
+#include <stdio.h>
+#include <cctype>
+#include <variant>
+
+
+bool startsWith(const std::string& str, const std::string& prefix) {
+    if (prefix.size() > str.size()) return false;
+    return str.compare(0, prefix.size(), prefix) == 0;
+}
+
+
+bool endsWith(const std::string& str, const std::string& suffix) {
+    if (suffix.size() > str.size()) return false;
+    return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
+}
+
+
 
 class GeneticMaterial {
 
@@ -19,110 +36,22 @@ class GeneticMaterial {
     std::optional<std::string> fileType; // Pode ser "FASTA", "FASTQ" ou std::nullopt
     std::optional<std::string> content; // Conteúdo do arquivo, ou std::nullopt se não carregado
 
-    fileData.content = (decompressedContent.str().empty()) ? std::nullopt : std::make_optional(decompressedContent.str());
+    
 
-    }; 
+    };
 
     protected:
         std::string filePath;
         std::string fileContent;
         std::string fileExtension;
+        FileContent fileData;
 
     public:
         GeneticMaterial(const std::string& path) : filePath(path) {}
+              
 
 
-
-        std::pair<std::vector<FileContent>, std::vector<FileContent>> verifyAndLoadFile(const std::string& filePath) {
-            std::pair<std::vector<FileContent>, std::vector<FileContent>> fileData;
-            
-            size_t position = filePath.find_last_of('.');
-                if(position==std::string::npos) {
-                    throw std::runtime_error("Arquivo sem extensão, insira um arquivo com uma extensão válida: FASTA, FASTQ, ZIP or TAR.");
-                }
-
-            std::string fileExtension = filePath.substr(position + 1);
-            std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower);
-            try {
-                if(fileExtension=="gz") {
-                    fileData = descompressGzipFile(filePath);
-                } else if(fileExtension=="tar") {
-                    fileData = descompressTarFile(filePath);
-                } else if(fileExtension=="zip") {
-                    fileData = decompressZipFile(filePath);
-                } else if (fileExtension=="fasta" || fileExtension=="fastq") {
-                    fileData = loadFileContent(filePath);
-                } else {
-                    throw std::runtime_error("Extensão não suportada: " + fileExtension + 
-                    "\n" + "Please insert files of type: FASTA, FASTQ, ZIP or TAR");
-                }
-            } catch (const std::exception& e) {
-                throw std::runtime_error("Erro ao processar o arquivo: " + std::string(e.what()));
-            }
-
-            return fileData;
-        }
-
-
-
-
-        void loadFileContent(const std::variant<std::string, std::vector<std::string>>& input, 
-            std::vector<FileContent>& fastaFiles, 
-            std::vector<FileContent>& fastqFiles) {
-
-            std::vector<std::string> filePaths;
-
-            if (std::holds_alternative<std::string>(input)) {
-                filePaths.push_back(std::get<std::string>(input)); // Adiciona o único caminho à lista
-            } else {
-                filePaths = std::get<std::vector<std::string>>(input); // Converte diretamente para a lista
-            }
-
-            // Processa cada arquivo na lista
-            for (const auto& filePath : filePaths) {
-                std::ifstream file(filePath, std::ios::binary);
-
-                if(!file.is_open()) {
-                    throw std::runtime_error("Não foi possível abrir o arquivo: " + filePath);
-                }
-
-                // Processar o arquivo em blocos
-                constexpr size_t bufferSize = 4096; // 4 KB
-                char buffer[bufferSize];
-                std::stringstream fileContent;
-
-                while (file.read(buffer, bufferSize)) {
-                    fileContent.append(buffer, file.gcount());
-                }
-
-                // Verifica se há bytes restantes no final do arquivo
-                if (file.gcount() > 0) {
-                    fileContent.append(buffer, file.gcount());
-                }
-
-                file.close();
-
-
-                FileContent fileData;
-                fileData.fileName = filePath;
-                fileData.content = fileContent.str();
-
-                if (filePath.ends_with(".fasta")) {
-                    fileData.fileType = "FASTA";
-                    fastaFiles.push_back(fileData);
-                } else if (filePath.ends_with(".fastq")) {
-                    fileData.fileType = "FASTQ";
-                    fastqFiles.push_back(fileData);
-                } else {
-                    throw std::runtime_error("Tipo de arquivo não suportado: " + filePath);
-                }
-            }
-        }
-
-
-
-
-        std::vector<FileContent> decompressGzipFile(const std::string& filePath) {
+        std::pair<std::vector<FileContent>, std::vector<FileContent>> decompressGzipFile(const std::string& filePath) {
             gzFile gzFile = gzopen(filePath.c_str(), "rb");
             if (!gzFile) {
                 throw std::runtime_error("Não foi possível abrir o arquivo GZIP: " + filePath);
@@ -151,188 +80,400 @@ class GeneticMaterial {
             }
 
             // Processa o conteúdo para dividir em FASTA/FASTQ
-            std::vector<FileContent> fileContents;
-            std::string content = decompressedContent.str();
+            std::vector<FileContent> fastaFiles;
+            std::vector<FileContent> fastqFiles;
 
-            std::istringstream contentStream(content);
+            std::istringstream contentStream(decompressedContent.str());
             std::string line;
             FileContent currentFile;
 
             while (std::getline(contentStream, line)) {
-                if (line.starts_with(">")) { // Início de um arquivo FASTA
-                    if (!currentFile.fileName.empty()) {
-                        fileContents.push_back(currentFile);
-                        currentFile = FileContent(); // Reinicia o arquivo atual
+                if (line.empty()) continue;
+                if (startsWith(line, ">")) { // Início de um arquivo FASTA
+                    if (!currentFile.content.has_value()) {
+                        if (currentFile.fileType == "FASTA") {
+                            fastaFiles.push_back(currentFile);
+                        } else if (currentFile.fileType == "FASTQ") {
+                            fastqFiles.push_back(currentFile);
+                        }
                     }
+                    currentFile = FileContent();
                     currentFile.fileType = "FASTA";
-                    currentFile.content += line + "\n";
-                } else if (line.starts_with("@")) { // Início de um arquivo FASTQ
-                    if (!currentFile.fileName.empty()) {
-                        fileContents.push_back(currentFile);
-                        currentFile = FileContent(); // Reinicia o arquivo atual
+                    *currentFile.content += line + "\n"; // Acessa o valor do optional
+                } else if (startsWith(line, "@")) { // Início de um arquivo FASTQ
+                     if (currentFile.fileType == "FASTA") {
+                        fastaFiles.push_back(currentFile);
+                    } else if (currentFile.fileType == "FASTQ") {
+                        fastqFiles.push_back(currentFile);
                     }
+                    currentFile = FileContent();
                     currentFile.fileType = "FASTQ";
-                    currentFile.content += line + "\n";
+                    *currentFile.content += line + "\n"; // Acessa o valor do optional
                 } else {
-                    currentFile.content += line + "\n";
+                    *currentFile.content += line + "\n"; // Acessa o valor do optional
                 }
             }
 
             // Adiciona o último arquivo processado
-            if (!currentFile.content.empty()) {
-                fileContents.push_back(currentFile);
+            if (!currentFile.content.has_value()) {
+                if (currentFile.fileType == "FASTA") {
+                    fastaFiles.push_back(currentFile);
+                } else if (currentFile.fileType == "FASTQ") {
+                    fastqFiles.push_back(currentFile);
+                }
             }
 
-            return fileContents;
+            return {fastaFiles, fastqFiles};
         }
 
         
 
 
 
+        std::pair<std::vector<FileContent>, std::vector<FileContent>> descompressTarFile(const std::string& filePath) {
+            struct archive* tarFile = archive_read_new();
 
+            if (!tarFile) {
+                throw std::runtime_error("Falha ao alocar memória para o manipulador de TAR.");
+            }
 
-        std::pair<std::vector<FileContent>, std::vector<FileContent>> descompressTarFile(const std::string& filePath) {        
-        struct archive* tarFile = archive_read_new();
-        struct archive_entry* entry;
-        std::vector<FileContent> fastaFiles;
-        std::vector<FileContent> fastqFiles; 
+            struct archive_entry* entry;
+            std::vector<FileContent> fastaFiles;
+            std::vector<FileContent> fastqFiles;
 
-        // Configurando o libarchive para lidar com arquivos TAR
-        archive_read_support_filter_all(tarFile);
-        archive_read_support_format_all(tarFile);
+            // Configurando o libarchive para lidar com arquivos TAR
+            archive_read_support_filter_all(tarFile);
+            archive_read_support_format_all(tarFile);
 
-        if (archive_read_open_filename(tarFile, filePath.c_str(), 10240) != ARCHIVE_OK) {
-            throw std::runtime_error("Não foi possível abrir o arquivo TAR: " + filePath);
+            if (archive_read_open_filename(tarFile, filePath.c_str(), 10240) != ARCHIVE_OK) {
+                archive_read_free(tarFile);  // Libera a memória antes de lançar a exceção e evita o vazamento de dados
+                throw std::runtime_error("Não foi possível abrir o arquivo TAR: " + filePath);
+            }
+
+            while (archive_read_next_header(tarFile, &entry) == ARCHIVE_OK) {
+                std::string currentFileName = archive_entry_pathname(entry);
+
+                // Converte o nome do arquivo para lowercase para evitar problemas de case
+                std::transform(currentFileName.begin(), currentFileName.end(), currentFileName.begin(), ::tolower);
+
+                // Filtra apenas arquivos .fasta ou .fastq
+                if (endsWith(currentFileName, ".fasta") || endsWith(currentFileName, ".fastq")) {
+                    std::cout << "Arquivo encontrado: " << currentFileName << std::endl;
+
+                    std::string fileType = (endsWith(currentFileName, ".fasta")) ? "FASTA" : "FASTQ";
+
+                    // Lê o conteúdo do arquivo
+                    std::ostringstream fileContent;
+                    const void* buffer;
+                    size_t size;
+                    int64_t offset;
+
+                    while (true) {
+                        int readBytes = archive_read_data_block(tarFile, &buffer, &size, &offset);
+                        if (readBytes == ARCHIVE_EOF) break;
+                        if (readBytes < ARCHIVE_OK) {
+                            archive_read_free(tarFile);
+                            throw std::runtime_error("Erro ao ler o arquivo: " + currentFileName);
+                        }
+
+                        if (buffer) {  // Verifica se buffer não é nullptr (caso extremo)
+                            fileContent.write(static_cast<const char*>(buffer), size);  // Adiciona o conteúdo ao stream
+                        }
+                    }
+
+                    // Cria o objeto FileContent
+                    FileContent fileData;
+                    fileData.fileName = currentFileName;
+                    fileData.fileType = std::make_optional(fileType);
+                    fileData.content = fileContent.str();
+
+                    if (fileType == "FASTA") {
+                        fastaFiles.push_back(std::move(fileData)); // Adiciona à lista de FASTA
+                    } else {
+                        fastqFiles.push_back(std::move(fileData));  // Adiciona à lista de FASTQ
+                    }
+
+                } else {
+                    std::cout << "Arquivo ignorado: " << currentFileName << std::endl;
+                }
+                // Avança para o próximo arquivo no TAR
+                archive_read_data_skip(tarFile);
+            }
+
+            archive_read_free(tarFile);  // Libera o recurso do arquivo TAR
+            return {std::move(fastaFiles), std::move(fastqFiles)};  // Retorna as listas separadas de FASTA e FASTQ
         }
 
-        while (archive_read_next_header(tarFile, &entry) == ARCHIVE_OK) {
-            std::string currentFileName = archive_entry_pathname(entry);
 
-            // Converte o nome do arquivo para lowercase para evitar problemas de case
+
+
+    std::pair<std::vector<FileContent>, std::vector<FileContent>> decompressZipFile(const std::string& filePath) {
+        unzFile zipFile = unzOpen(filePath.c_str());
+
+        if (!zipFile) {
+            throw std::runtime_error("Não foi possível abrir o arquivo ZIP: " + filePath);
+        }
+
+        if (unzGoToFirstFile(zipFile) != UNZ_OK) {
+            unzClose(zipFile);
+            throw std::runtime_error("Erro ao acessar o primeiro arquivo no ZIP: " + filePath);
+        }
+
+        // Vetores para armazenar os arquivos FASTA e FASTQ
+        std::vector<FileContent> fastaFiles;
+        std::vector<FileContent> fastqFiles;
+
+        do {
+            // Obtém o nome do arquivo atual no ZIP
+            char fileName[256];
+            unz_file_info fileInfo;
+
+            if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, sizeof(fileName), nullptr, 0, nullptr, 0) != UNZ_OK) {
+                unzClose(zipFile);
+                throw std::runtime_error("Erro ao obter informações do arquivo no ZIP.");
+            }
+
+            std::string currentFileName(fileName);
             std::transform(currentFileName.begin(), currentFileName.end(), currentFileName.begin(), ::tolower);
 
             // Filtra apenas arquivos .fasta ou .fastq
-            if (currentFileName.ends_with(".fasta") || currentFileName.ends_with(".fastq")) {
+            if (endsWith(currentFileName, ".fasta") || endsWith(currentFileName, ".fastq")) {
                 std::cout << "Arquivo encontrado: " << currentFileName << std::endl;
 
-
-                std::string fileType = (currentFileName.ends_with(".fasta")) ? "FASTA" : "FASTQ";
+                // Abre o arquivo atual dentro do ZIP
+                if (unzOpenCurrentFile(zipFile) != UNZ_OK) {
+                    unzClose(zipFile);
+                    throw std::runtime_error("Erro ao abrir arquivo dentro do ZIP: " + currentFileName);
+                }
 
                 // Lê o conteúdo do arquivo
-                std::stringstream fileContent;
-                const void* buffer;
-                size_t size;
-                int64_t offset;
-
-                while (true) {
-                    int readBytes = archive_read_data_block(tarFile, &buffer, &size, &offset);
-                    if (readBytes == ARCHIVE_EOF) break;
-                    if (readBytes < ARCHIVE_OK) {
-                        throw std::runtime_error("Erro ao ler o arquivo: " + currentFileName);
-                    }
+                std::string fileContent;
+                char buffer[4096];
+                int bytesRead;
 
-                    // Adiciona o conteúdo ao stream
-                    fileContent.write(static_cast<const char*>(buffer), size);
+                while ((bytesRead = unzReadCurrentFile(zipFile, buffer, sizeof(buffer))) > 0) {
+                    fileContent.append(buffer, bytesRead);
                 }
 
-                 // Cria o objeto FileContent
+                if (bytesRead < 0) {
+                    unzCloseCurrentFile(zipFile);
+                    unzClose(zipFile);
+                    throw std::runtime_error("Erro ao ler o arquivo dentro do ZIP: " + currentFileName);
+                }
+
+                unzCloseCurrentFile(zipFile);
+
+                // Cria o objeto FileContent
                 FileContent fileData;
                 fileData.fileName = currentFileName;
-                ffileData.fileType = std::make_optional(fileType);
-                fileData.content = fileContent.str();
+                fileData.fileType = std::make_optional(endsWith(currentFileName, ".fasta") ? "FASTA" : "FASTQ");
+                fileData.content = std::move(fileContent);
+
+                // Armazena o conteúdo no vetor apropriado
+                if (endsWith(currentFileName, ".fasta")) {
+                    fastaFiles.push_back(std::move(fileData));
+                } else if (endsWith(currentFileName, ".fastq")) {
+                    fastqFiles.push_back(std::move(fileData));
+                }
+            } else {
+                std::cout << "Arquivo ignorado: " << currentFileName << std::endl;
+            }
+        } while (unzGoToNextFile(zipFile) == UNZ_OK);
 
+        unzClose(zipFile);
+        return {std::move(fastaFiles), std::move(fastqFiles)};
+    }
 
-                if (fileType == "FASTA") {
-                    fastaFiles.push_back(fileData);  // Adiciona à lista de FASTA
-                } else {
-                    fastqFiles.push_back(fileData);  // Adiciona à lista de FASTQ
-                }
 
+
+
+    std::pair<std::vector<FileContent>, std::vector<FileContent>> verifyAndLoadFile(const std::string& filePath) {
+        std::pair<std::vector<FileContent>, std::vector<FileContent>> fileData;
+
+        size_t position = filePath.find_last_of('.');
+        if (position == std::string::npos) {
+            throw std::runtime_error("Arquivo sem extensão, insira um arquivo com uma extensão válida: FASTA, FASTQ, ZIP ou TAR.");
+        }
+
+        std::string fileExtension = filePath.substr(position + 1);
+        std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower);
+
+        try {
+            if (fileExtension == "gz") {
+                fileData = decompressGzipFile(filePath);
+            } else if (fileExtension == "tar") {
+                fileData = descompressTarFile(filePath);
+            } else if (fileExtension == "zip") {
+                fileData = decompressZipFile(filePath);
+            } else if (fileExtension == "fasta" || fileExtension == "fastq") {
+                // Chama a função loadFileContent e verifica se o retorno é válido
+                auto result = loadFileContent(filePath);
+                if (result) {
+                    const auto& [fastaFiles, fastqFiles] = *result;
+                    // Verifica se as listas não são nullopt e atribui às listas de fileData
+                    if (fastaFiles) {
+                        fileData.first = *fastaFiles;
+                    }
+                    if (fastqFiles) {
+                        fileData.second = *fastqFiles;
+                    }
             } else {
-                std::cout << "Arquivo ignorado: " << currentFileName << std::endl;
+                throw std::runtime_error("Falha ao carregar conteúdo do arquivo: " + filePath);
+            }
+        } else {
+            throw std::runtime_error("Extensão não suportada: " + fileExtension +
+                "\nPor favor, insira arquivos do tipo: FASTA, FASTQ, ZIP ou TAR.");
             }
-            // Avança para o próximo arquivo no TAR
-            archive_read_data_skip(tarFile);
+        } catch (const std::exception& e) {
+            throw std::runtime_error("Erro ao processar o arquivo: " + std::string(e.what()));
         }
 
-        archive_read_free(tarFile);  // Libera o recurso do arquivo TAR
-        return {fastaFiles, fastqFiles};  // Retorna as listas separadas de FASTA e FASTQ
+        return fileData;
     }
 
 
 
 
 
-        std::pair<std::vector<FileContent>, std::vector<FileContent>> decompressZipFile(const std::string& filePath) {      
-            unzFile zipFile = unzOpen(filePath.c_str());
 
-            if (!zipFile) {
-                throw std::runtime_error("Não foi possível abrir o arquivo ZIP: " + filePath);
+    std::optional<std::pair<std::optional<std::vector<FileContent>>, std::optional<std::vector<FileContent>>>> loadFileContent(const std::variant<std::string, 
+        std::vector<std::string>>& input) {
+
+        std::vector<std::string> filePaths;
+
+        // Verifica se o input é uma string ou um vetor de strings
+        if (std::holds_alternative<std::string>(input)) {
+            filePaths.push_back(std::get<std::string>(input)); // Adiciona o único caminho à lista
+        } else {
+            filePaths = std::get<std::vector<std::string>>(input); // Converte diretamente para a lista
+        }
+
+        // Vetores de arquivos FASTA e FASTQ
+        std::optional<std::vector<FileContent>> fastaFiles;
+        std::optional<std::vector<FileContent>> fastqFiles;
+
+        // Processa cada arquivo na lista
+        for (const auto& filePath : filePaths) {
+            std::ifstream file(filePath, std::ios::binary);
+
+            if (!file.is_open()) {
+                throw std::runtime_error("Não foi possível abrir o arquivo: " + filePath);
             }
 
+            // Processar o arquivo em blocos
+            constexpr size_t bufferSize = 4096; // 4 KB
+            char buffer[bufferSize];
+            std::stringstream fileContent;
 
-            if (unzGoToFirstFile(zipFile) != UNZ_OK) {
-                unzClose(zipFile);
-                throw std::runtime_error("Erro ao acessar o primeiro arquivo no ZIP: " + filePath);
+            while (file.read(buffer, bufferSize)) {
+                fileContent.write(buffer, file.gcount()); // Usa write em vez de append
+            }
+
+            // Verifica se há bytes restantes no final do arquivo
+            if (file.gcount() > 0) {
+                fileContent.write(buffer, file.gcount()); // Usa write em vez de append
             }
 
-            std::vector<std::string> fastaFiles;
-            std::vector<std::string> fastqFiles;
+            file.close();
+
+            // Cria o objeto FileContent
+            FileContent fileData;
+            fileData.fileName = filePath;
+            fileData.content = fileContent.str();
 
-            do {
-                // Obtém o nome do arquivo atual no ZIP
-                char fileName[256];
-                unz_file_info fileInfo;
-                
-                if (unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, sizeof(fileName), nullptr, 0, nullptr, 0) != UNZ_OK) {
-                    throw std::runtime_error("Erro ao obter informações do arquivo no ZIP.");
+            // Verifica o tipo de arquivo e adiciona ao vetor apropriado
+            if (endsWith(filePath, ".fasta")) {
+                if (!fastaFiles) {
+                fastaFiles = std::vector<FileContent>();  // Inicializa o vetor se necessário
+            }
+            fileData.fileType = "FASTA";
+            fastaFiles->push_back(fileData);
+            } else if (endsWith(filePath, ".fastq")) {
+                if (!fastqFiles) {
+                    fastqFiles = std::vector<FileContent>();  // Inicializa o vetor se necessário
                 }
+                fileData.fileType = "FASTQ";
+                fastqFiles->push_back(fileData);
+            } else {
+                throw std::runtime_error("Tipo de arquivo não suportado: " + filePath);
+            }
+        }
+        // Retorna a lista de arquivos FASTA e FASTQ como opcional
+        return std::make_optional(std::make_pair(std::move(fastaFiles), std::move(fastqFiles)));
+    }
+        
 
-                std::string currentFileName(fileName);
-                std::transform(currentFileName.begin(), currentFileName.end(), currentFileName.begin(), ::tolower);
 
 
-                if (currentFileName.ends_with(".fasta") || currentFileName.ends_with(".fastq")) {
-                    std::cout << "Arquivo encontrado: " << currentFileName << std::endl;
 
-                    // Abre o arquivo atual dentro do ZIP
-                    if (unzOpenCurrentFile(zipFile) != UNZ_OK) {
-                        throw std::runtime_error("Erro ao abrir arquivo dentro do ZIP: " + currentFileName);
-                    }
 
-                    // Lê o conteúdo do arquivo
-                    std::string fileContent;
-                    char buffer[4096];
-                    int bytesRead;
-                    while ((bytesRead = unzReadCurrentFile(zipFile, buffer, sizeof(buffer))) > 0) {
-                        fileContent.append(buffer, bytesRead);
-                    }
+    bool verifySequence(const std::string& fastaContent) {
+        bool erroEncontrado = false;
+        std::string line;
+        bool isHeader = true;
 
-                    if (bytesRead < 0) {
-                        unzCloseCurrentFile(zipFile);
-                        throw std::runtime_error("Erro ao ler o arquivo dentro do ZIP: " + currentFileName);
-                    }
+        // Percorre cada caractere da string
+        for (size_t i = 0; i < fastaContent.size(); ++i) {
+            char c = fastaContent[i];
 
-                    unzCloseCurrentFile(zipFile);
-
-                    // Armazena o conteúdo no vetor apropriado
-                    FileContent fileData = {currentFileName, fileContent};
-                    if (currentFileName.ends_with(".fasta")) {
-                        fastaFiles.push_back(fileData);
-                    } else if (currentFileName.ends_with(".fastq")) {
-                        fastqFiles.push_back(fileData);
+            // Verifica se é uma nova linha (fim de sequência ou cabeçalho)
+            if (c == '\n' || c == '\r') {
+                // Se a linha estava com cabeçalho (iniciada por ">", ignorar)
+                if (line.empty() || line[0] == '>') {
+                    // Linha de cabeçalho encontrada, ignora e reinicia
+                    line.clear();
+                    isHeader = true;
+                } else {
+                    // Verifica os caracteres da sequência
+                    for (char seqChar : line) {
+                        if (!isalpha(seqChar) && seqChar != 'N' && seqChar != 'n') {
+                            std::cerr << "Caractere inválido encontrado na sequência: " << seqChar << std::endl;
+                            erroEncontrado = true;
+                        }
                     }
+                    line.clear();
+                    isHeader = false;
+                }
+            } else {
+                // Acumula os caracteres da sequência ou cabeçalho
+                if (isHeader || c == '>') {
+                    line.push_back(c);
                 } else {
-                    std::cout << "Arquivo ignorado: " << currentFileName << std::endl;
+                    line.push_back(c); // Acumula caracteres da sequência
                 }
-            } while (unzGoToNextFile(zipFile) != UNZ_END_OF_LIST_OF_FILE);
-
-            unzClose(zipFile);
-            return {fastaFiles, fastqFiles};
             }
+        }
+
+        return !erroEncontrado;  // Retorna true se não houver caracteres inválidos
+    }
+
+
+
+
+    // Lê a sequência e me retorna quantos alinhamentos é possível fazer com ela
+    // Função para calcular o coeficiente binomial: C(n, k) = n! / (k! * (n-k)!)
+    uint64_t binomialCoefficient(int n, int k) {
+        if (k > n) return 0;
+        if (k == 0 || k == n) return 1;
+
+        uint64_t result = 1;
+        for (int i = 1; i <= k; ++i) {
+            result = result * (n - i + 1) / i;
+        }
+        return result;
+    }
+
+    // Função para calcular o número de alinhamentos globais possíveis
+    uint64_t calculateGlobalAlignments(int length1, int length2) {
+        int totalLength = length1 + length2;
+        return binomialCoefficient(totalLength, length1);
+    }
+
+    // Função para calcular o número de alinhamentos locais possíveis
+    uint64_t calculateLocalAlignments(int length1, int length2) {
+        return static_cast<uint64_t>((length1 + 1) * (length2 + 1) * (length1 + length2) / 2);
+    }
 
-        virtual ~GeneticMaterial() {}
+    virtual ~GeneticMaterial() {}
 };
-        // Verificações para saber se os arquivos fasta e fastq são válidos
-        // Falta acerta essa questão dos arquivos passados como fasta ou fastq. Quantos arquivos podem ser passado de uma só vez?
+        // Verificações para saber se os arquivos fasta e fastq são válidos.
-- 
GitLab