2014-12-17 9 views
5

Potrzebuję prostej kompresji i dekompresji std :: string w C++. Spojrzałem na to site, a kod jest dla tablicy znaków. Co chcę wdrożyć są dwie funkcje:Prosta kompresja i dekompresja stringów Cli Zlib

std::string original = "This is to be compressed!!!!"; 
std::string compressed = string_compress(original); 
std::cout << compressed << std::endl; 
std::string decompressed = string_decompress(compressed); 
std::cout << decompressed << std::endl; 

próbowałem kompresję doładowania jak:

std::string CompressData(const std::string &data) 
{ 
    std::stringstream compressed; 
    std::stringstream decompressed; 
    decompressed << data; 
    boost::iostreams::filtering_streambuf<boost::iostreams::input> out; 
    out.push(boost::iostreams::zlib_compressor()); 
    out.push(decompressed); 
    boost::iostreams::copy(out, compressed); 
    return compressed.str(); 
} 

std::string DecompressData(const std::string &data) 
{ 
    std::stringstream compressed; 
    std::stringstream decompressed; 
    compressed << data; 
    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::zlib_decompressor()); 
    in.push(compressed); 
    boost::iostreams::copy(in, decompressed); 
    return decompressed.str(); 
} 

ale kod czasami daje znaki puste w ciąg tj \ u0000. Jak postępować, jeśli skompresowane dane zawierają te puste znaki. Czy zwracany jest typ string? Jak mogę zaimplementować funkcję string_compress i string_decompress używając zlib?

+4

skompresowanych danych jest tylko dane binarne. To nie jest rozsądny, czytelny ciąg (w sensie ludzkim). Nic więc dziwnego, że widzisz "dziwne" dane binarne w skompresowanym łańcuchu. To znaczy przecież dokładnie to, co to jest. – Cornstalks

+0

Dlaczego ważne jest, aby w skompresowanym łańcuchu były puste znaki? – Galik

+0

Ponieważ skompresowana wiadomość jest wysyłana do serwera jako ciąg Json. Ale serwer nie może otrzymać pełnej wiadomości, gdy zobaczy znak zerowy. – Pant

Odpowiedz

5

Można zrobić jak sugeruje @LawfulEvil. Oto fragment kodu, który działa :)

std::string original = "This is to be compressed!!!!"; 
std::string compressed_encoded = string_compress_encode(original); 
std::cout << compressed_encoded << std::endl; 
std::string decompressed_decoded = string_decompress_decode(compressed_encoded); 
std::cout << decompressed_decoded << std::endl; 

Korzystanie this jako biblioteka base64 kodowania/dekodowania

std::string string_compress_encode(const std::string &data) 
{ 
    std::stringstream compressed; 
    std::stringstream original; 
    original << data; 
    boost::iostreams::filtering_streambuf<boost::iostreams::input> out; 
    out.push(boost::iostreams::zlib_compressor()); 
    out.push(original); 
    boost::iostreams::copy(out, compressed); 

    /**need to encode here **/ 
    std::string compressed_encoded = base64_encode(reinterpret_cast<const unsigned char*>(compressed.c_str()), compressed.length()); 

    return compressed_encoded.str(); 
} 

std::string string_decompress_decode(const std::string &data) 
{ 
    std::stringstream compressed_encoded; 
    std::stringstream decompressed; 
    compressed_encoded << data; 

    /** first decode then decompress **/ 
    std::string compressed = base64_decode(compressed_encoded); 

    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::zlib_decompressor()); 
    in.push(compressed); 
    boost::iostreams::copy(in, decompressed); 
    return decompressed; 
} 
+1

Dzięki Zangetsu. Będę próbował tego kodu i poinformuję, czy to działa. – Pant

+2

Powinieneś naprawdę wymienić sekcję include twojego kodu pod kątem kompletności. – Kahless

1

Kompresja korzysta ze wszystkich dostępnych wartości dla każdego bajtu, więc będzie wyglądać jako "śmieci" lub "dziwne" podczas próby wyświetlenia jako ascii. Jego oczekiwano. Będziesz musiał kodować dane do transmisji/json pakowania, aby uniknąć wartości zerowych. Proponuję podstawę 64. Kod do zrobienia jest dostępny pod linkiem poniżej (którego nie napisałem, więc nie będę tu kopiował).

  1. http://www.adp-gmbh.ch/cpp/common/base64.html
  2. Binary data JSONCPP