/* zenutils - Utilities for working with creative firmwares. * Copyright 2007 (c) Rasmus Ry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "utils.h" #include #include std::string shared::replace_extension(const std::string& filename, const std::string& extension) { std::string newname; const char* name = filename.c_str(); const char* ext = strrchr(name, '.'); if (ext) { // If an extension was found, replace it. newname.assign(name, ext-name); newname += extension; } else { // If an extension was not found, append it. newname = name; newname += extension; } return newname; } std::string shared::remove_extension(const std::string& filename) { std::string newname; const char* name = filename.c_str(); const char* ext = strrchr(name, '.'); if (ext) { newname.assign(name, ext-name); } else { newname = name; } return newname; } std::string shared::double_quote(const std::string& str) { std::string out; for (int i = 0, j = str.length(); i < j; i++) { if (str[i] == '\\') out += "\\\\"; else out += str[i]; } return out; } bool shared::inflate_to_file(const bytes& buffer, const char* filename) { // Open output file. std::ofstream ofs; ofs.open(filename, std::ios::binary); if (!ofs) { return false; } // Initialize zlib. z_stream d_stream; // decompression stream d_stream.zalloc = Z_NULL; d_stream.zfree = Z_NULL; d_stream.opaque = Z_NULL; d_stream.next_in = const_cast(&buffer[0]); d_stream.avail_in = static_cast(buffer.size()); int ret = inflateInit(&d_stream); if (ret != Z_OK) return false; // Allocate buffer to hold the inflated data. const size_t BUFSIZE = 1048576; Bytef* infbuf = new Bytef[BUFSIZE]; if (!infbuf) return false; // Decompress untill the end of the input buffer. uLong totalout = 0; bool bLoop = true; while (bLoop) { d_stream.next_out = infbuf; d_stream.avail_out = BUFSIZE; ret = inflate(&d_stream, Z_NO_FLUSH); if (ret == Z_STREAM_END) { bLoop = false; } else if (ret != Z_OK) { inflateEnd(&d_stream); delete [] infbuf; return false; } // Write the inflated data to the output file. if (!ofs.write((const char*)infbuf, d_stream.total_out-totalout)) { inflateEnd(&d_stream); delete [] infbuf; return false; } totalout = d_stream.total_out; } // Cleanup and return. inflateEnd(&d_stream); delete [] infbuf; return true; } bool shared::deflate_to_file(const bytes& buffer, const char* filename) { // Open output file. std::ofstream ofs; ofs.open(filename, std::ios::binary); if (!ofs) { return false; } // Initialize zlib. z_stream c_stream; // compression stream. c_stream.zalloc = Z_NULL; c_stream.zfree = Z_NULL; c_stream.opaque = Z_NULL; int ret = deflateInit(&c_stream, Z_BEST_COMPRESSION); if (ret != Z_OK) return false; // Allocate buffer to hold the deflated data. const size_t BUFSIZE = 1048576; Bytef* defbuf = new Bytef[BUFSIZE]; if (!defbuf) return false; c_stream.avail_in = static_cast(buffer.size()); c_stream.next_in = const_cast(&buffer[0]); // Compress until end of the buffer. uLong totalout = 0; bool bLoop = true; while (bLoop) { c_stream.avail_out = BUFSIZE; c_stream.next_out = defbuf; ret = deflate(&c_stream, Z_NO_FLUSH); // no bad return value if (ret == Z_STREAM_END) { bLoop = false; } else if (ret == Z_BUF_ERROR && !c_stream.avail_in) { ret = deflate(&c_stream, Z_FINISH); // no bad return value bLoop = false; } else if (ret != Z_OK) { deflateEnd(&c_stream); delete [] defbuf; return false; } // Write the inflated data to the output file. if (!ofs.write((const char*)defbuf, c_stream.total_out-totalout)) { deflateEnd(&c_stream); delete [] defbuf; return false; } totalout = c_stream.total_out; } // Clean up and return. deflateEnd(&c_stream); delete [] defbuf; return true; }