feat(): Função responsável em descompactar conteúdo
This commit is contained in:
parent
c00c5cab3c
commit
9ace6448bd
1 changed files with 97 additions and 39 deletions
|
|
@ -1,49 +1,107 @@
|
|||
@staticmethod
|
||||
def decompress(vf_string):
|
||||
"""
|
||||
Descomprime e decodifica texto compactado ou codificado.
|
||||
# Importa a biblioteca nativa 'zlib' usada para descompressão de dados binários.
|
||||
import base64
|
||||
import zlib
|
||||
|
||||
Agora:
|
||||
- Tenta automaticamente Base64 decode ANTES de tudo.
|
||||
- Depois detecta zlib.
|
||||
- Decodifica ISO-8859-1 se não for zlib.
|
||||
"""
|
||||
|
||||
if not vf_string:
|
||||
return ""
|
||||
# Define uma classe utilitária chamada 'String', contendo apenas métodos estáticos.
|
||||
# Essa abordagem permite o uso direto sem necessidade de instanciar a classe.
|
||||
class String:
|
||||
@staticmethod
|
||||
def decompress(vf_string):
|
||||
"""
|
||||
Descomprime e decodifica texto de origem WPTools/Firebird.
|
||||
|
||||
# Caso seja stream (ex.: BLOB Firebird)
|
||||
if hasattr(vf_string, "read"):
|
||||
vf_string = vf_string.read()
|
||||
Finalidade:
|
||||
Converter o conteúdo de campos BLOB ou strings compactadas (como no Delphi)
|
||||
em texto legível, detectando automaticamente se o conteúdo está:
|
||||
- Compactado com zlib
|
||||
- Codificado em ISO-8859-1 (padrão ANSI)
|
||||
- Representado como bytes puros
|
||||
"""
|
||||
# Verifica se o valor recebido é nulo, vazio ou None.
|
||||
# Se for, retorna string vazia para evitar erros de processamento.
|
||||
if not vf_string:
|
||||
return ""
|
||||
|
||||
# Garante bytes
|
||||
if isinstance(vf_string, str):
|
||||
vf_bytes = vf_string.encode("latin1", errors="ignore")
|
||||
else:
|
||||
vf_bytes = vf_string
|
||||
# Caso seja um objeto tipo stream (ex: campo BLOB do Firebird)
|
||||
# Campos BLOB geralmente possuem o método `.read()` para leitura de bytes.
|
||||
if hasattr(vf_string, "read"):
|
||||
vf_string = vf_string.read() # Lê o conteúdo completo do stream
|
||||
|
||||
# --- NOVO: TENTATIVA DE BASE64 DECODE ANTES ---
|
||||
try:
|
||||
# Remove quebras e espaços — comum em JSON, Firebird, Delphi
|
||||
cleaned = vf_bytes.strip().replace(b"\n", b"").replace(b"\r", b"")
|
||||
decoded = base64.b64decode(cleaned, validate=True)
|
||||
vf_bytes = decoded
|
||||
except Exception:
|
||||
# Não era base64, segue normalmente
|
||||
pass
|
||||
# Garante que o valor trabalhado é uma sequência de bytes (não string)
|
||||
# Se o dado já for texto (str), converte para bytes em codificação Latin-1,
|
||||
# que é compatível com ISO-8859-1 usado por sistemas Delphi/Firebird.
|
||||
if isinstance(vf_string, str):
|
||||
vf_bytes = vf_string.encode("latin1", errors="ignore")
|
||||
else:
|
||||
vf_bytes = vf_string # Já está em bytes, então apenas reaproveita
|
||||
|
||||
# Detecta assinatura zlib
|
||||
is_zlib = len(vf_bytes) > 2 and vf_bytes[0] == 0x78 and vf_bytes[1] in (0x9C, 0xDA)
|
||||
# Detecta se o conteúdo foi compactado com zlib.
|
||||
# A assinatura padrão do formato zlib começa com bytes: 0x78 0x9C ou 0x78 0xDA.
|
||||
is_zlib = (
|
||||
len(vf_bytes) > 2 and vf_bytes[0] == 0x78 and vf_bytes[1] in (0x9C, 0xDA)
|
||||
)
|
||||
|
||||
if is_zlib:
|
||||
# Se a detecção confirmar que o conteúdo é zlib, tenta descompactar.
|
||||
if is_zlib:
|
||||
try:
|
||||
# Descompacta os bytes e decodifica o texto usando ISO-8859-1 (ANSI),
|
||||
# que preserva corretamente acentuação e caracteres especiais.
|
||||
text = zlib.decompress(vf_bytes).decode("iso-8859-1", errors="ignore")
|
||||
return text
|
||||
except Exception:
|
||||
# Caso falhe (por dados corrompidos ou não comprimidos de fato),
|
||||
# o fluxo continua normalmente sem interromper a execução.
|
||||
pass
|
||||
|
||||
# Se não for zlib, tenta tratar o conteúdo como texto puro (não compactado)
|
||||
try:
|
||||
text = zlib.decompress(vf_bytes).decode("iso-8859-1", errors="ignore")
|
||||
return text
|
||||
# Decodifica os bytes diretamente de ISO-8859-1 (padrão usado pelo Delphi)
|
||||
return vf_bytes.decode("iso-8859-1", errors="ignore")
|
||||
except Exception:
|
||||
pass
|
||||
# Como fallback, converte para string bruta para evitar falhas.
|
||||
return str(vf_string)
|
||||
|
||||
# Caso não seja zlib, tenta apenas decodificar ISO-8859-1
|
||||
try:
|
||||
return vf_bytes.decode("iso-8859-1", errors="ignore")
|
||||
except Exception:
|
||||
return str(vf_string)
|
||||
# >>> NOVO MÉTODO <<<
|
||||
@staticmethod
|
||||
def compress(text, *, encoding: str = "iso-8859-1", as_base64: bool = True):
|
||||
"""
|
||||
Comprime texto/dados com zlib.
|
||||
|
||||
Parâmetros:
|
||||
text: str | bytes | stream (com .read())
|
||||
encoding: encoding usado quando 'text' for str (padrão: ISO-8859-1)
|
||||
as_base64: se True, retorna string Base64 do conteúdo comprimido;
|
||||
caso False, retorna bytes comprimidos.
|
||||
|
||||
Retorno:
|
||||
- bytes (zlib) quando as_base64=False
|
||||
- str (Base64) quando as_base64=True
|
||||
|
||||
Observações:
|
||||
- Use o mesmo 'encoding' ao descomprimir para simetria.
|
||||
- Ideal para armazenar em BLOB ou trafegar seguro (Base64).
|
||||
"""
|
||||
if text is None or text == "":
|
||||
return "" if as_base64 else b""
|
||||
|
||||
# Se for stream (ex.: BLOB do Firebird)
|
||||
if hasattr(text, "read"):
|
||||
raw = text.read()
|
||||
else:
|
||||
raw = text
|
||||
|
||||
# Garante bytes
|
||||
if isinstance(raw, str):
|
||||
raw_bytes = raw.encode(encoding, errors="ignore")
|
||||
else:
|
||||
raw_bytes = bytes(raw)
|
||||
|
||||
# Comprime com zlib
|
||||
comp = zlib.compress(raw_bytes)
|
||||
|
||||
# Opcional: codifica em Base64 para transporte/JSON
|
||||
if as_base64:
|
||||
return base64.b64encode(comp).decode("ascii")
|
||||
|
||||
return comp
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue