예제 #1
0
        //-------------------------------------------------
        //  close - close a file and free all data; also
        //  remove the file if requested
        //-------------------------------------------------
        public void close()
        {
            // close files and free memory
            if (m_zipfile != null)
            {
                m_zipfile.Dispose();
            }
            m_zipfile = null;

            if (m_file != null)
            {
                m_file.Dispose();
            }
            m_file = null;

            m_zipdata.clear();

            if (m_remove_on_close)
            {
                m_osdfile.remove(m_fullpath);
            }

            m_remove_on_close = false;

            // reset our hashes and path as well
            m_hashes.reset();
            m_fullpath = "";
        }
예제 #2
0
        //-------------------------------------------------
        //  load_zipped_file - load a ZIPped file
        //-------------------------------------------------
        osd_file.error load_zipped_file()
        {
            assert(m_file == null);
            assert(m_zipdata.empty());
            assert(m_zipfile != null);

            // allocate some memory
            m_zipdata.resize((int)m_ziplength);

            // read the data into our buffer and return
            var ziperr = m_zipfile.decompress(m_zipdata, (UInt32)m_zipdata.size());

            if (ziperr != util.archive_file.error.NONE)
            {
                m_zipdata.clear();
                return(osd_file.error.FAILURE);
            }

            // convert to RAM file
            osd_file.error filerr = util.core_file.open_ram(m_zipdata, (UInt32)m_zipdata.size(), m_openflags, out m_file);
            if (filerr != osd_file.error.NONE)
            {
                m_zipdata.clear();
                return(osd_file.error.FAILURE);
            }

            // close out the ZIP file
            m_zipfile.Dispose();
            m_zipfile = null;
            return(osd_file.error.NONE);
        }
예제 #3
0
        //-------------------------------------------------
        //  load_zipped_file - load a ZIPped file
        //-------------------------------------------------
        std.error_condition load_zipped_file()
        {
            assert(m_file == null);
            assert(m_zipdata.empty());
            assert(m_zipfile != null);

            // allocate some memory
            m_zipdata.resize(m_ziplength);

            // read the data into our buffer and return
            var ziperr = m_zipfile.decompress(m_zipdata, (uint32_t)m_zipdata.size());

            if (ziperr)
            {
                m_zipdata.clear();
                return(ziperr);
            }

            // convert to RAM file
            std.error_condition filerr = util.core_file.open_ram(m_zipdata, m_zipdata.size(), m_openflags, out m_file);
            if (filerr)
            {
                m_zipdata.clear();
                return(filerr);
            }

            // close out the ZIP file
            m_zipfile.Dispose();
            m_zipfile = null;
            return(new std.error_condition());
        }
예제 #4
0
        public emu_file(string searchpath, u32 openflags)
        {
            m_file                  = null;
            m_iterator              = new path_iterator(searchpath);
            m_mediapaths            = new path_iterator(searchpath);
            m_crc                   = 0;
            m_openflags             = openflags;
            m_zipfile               = null;
            m_ziplength             = 0;
            m_remove_on_close       = false;
            m_restrict_to_mediapath = false;


            // sanity check the open flags
            if ((m_openflags & OPEN_FLAG_HAS_CRC) > 0 && (m_openflags & OPEN_FLAG_WRITE) > 0)
            {
                throw new emu_fatalerror("Attempted to open a file for write with OPEN_FLAG_HAS_CRC");
            }
        }
예제 #5
0
        emu_file(u32 openflags, empty_t unused)
        {
            m_filename              = "";
            m_fullpath              = "";
            m_file                  = null;
            m_iterator              = new emu_file_searchpath_vector();
            m_mediapaths            = new emu_file_searchpath_vector();
            m_first                 = true;
            m_crc                   = 0;
            m_openflags             = openflags;
            m_zipfile               = null;
            m_ziplength             = 0;
            m_remove_on_close       = false;
            m_restrict_to_mediapath = 0;


            // sanity check the open flags
            if ((m_openflags & OPEN_FLAG_HAS_CRC) != 0 && (m_openflags & OPEN_FLAG_WRITE) != 0)
            {
                throw new emu_fatalerror("Attempted to open a file for write with OPEN_FLAG_HAS_CRC");
            }
        }
예제 #6
0
        osd_file.error attempt_zipped()
        {
            string []    suffixes   = new string[] { ".zip", ".7z" }; //char const *const suffixes[] = { ".zip", ".7z" };
            open_func [] open_funcs = new open_func[] { util.archive_file.open_zip, util.archive_file.open_7z };

            // loop over archive types
            string savepath = m_fullpath;
            string filename = "";

            for (int i = 0; i < suffixes.Length; i++, m_fullpath = savepath, filename = "")
            {
                // loop over directory parts up to the start of filename
                while (true)
                {
                    // find the final path separator
                    var dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
                    if (dirsep == -1)
                    {
                        break;
                    }

                    if (restrict_to_mediapath() && !part_of_mediapath(m_fullpath))
                    {
                        break;
                    }

                    // insert the part from the right of the separator into the head of the filename
                    if (!filename.empty())
                    {
                        filename = filename.Insert(0, "/");
                    }
                    filename = filename.Insert(0, m_fullpath.substr(dirsep + 1));

                    // remove this part of the filename and append an archive extension
                    m_fullpath  = m_fullpath.Substring(0, dirsep);
                    m_fullpath += suffixes[i];

                    // attempt to open the archive file
                    util.archive_file       zip;
                    util.archive_file.error ziperr = open_funcs[i](m_fullpath, out zip);

                    // chop the archive suffix back off the filename before continuing
                    m_fullpath = m_fullpath.substr(0, dirsep);

                    // if we failed to open this file, continue scanning
                    if (ziperr != util.archive_file.error.NONE)
                    {
                        continue;
                    }

                    int header = -1;

                    // see if we can find a file with the right name and (if available) CRC
                    if ((m_openflags & OPEN_FLAG_HAS_CRC) != 0)
                    {
                        header = zip.search(m_crc, filename, false);
                    }
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc, filename, true);
                    }

                    // if that failed, look for a file with the right CRC, but the wrong filename
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc);
                    }

                    // if that failed, look for a file with the right name;
                    // reporting a bad checksum is more helpful and less confusing than reporting "ROM not found"
                    if (header < 0)
                    {
                        header = zip.search(filename, false);
                    }
                    if (header < 0)
                    {
                        header = zip.search(filename, true);
                    }

                    // if we got it, read the data
                    if (header >= 0)
                    {
                        m_zipfile   = zip;
                        m_ziplength = m_zipfile.current_uncompressed_length();

                        // build a hash with just the CRC
                        m_hashes.reset();
                        m_hashes.add_crc(m_zipfile.current_crc());
                        return(((m_openflags & OPEN_FLAG_NO_PRELOAD) != 0) ? osd_file.error.NONE : load_zipped_file());
                    }

                    // close up the archive file and try the next level
                    zip.Dispose();
                    zip = null;  //.reset();
                }
            }

            return(osd_file.error.NOT_FOUND);
        }
예제 #7
0
        std.error_condition attempt_zipped()
        {
            //typedef std::error_condition (*open_func)(std::string_view filename, util::archive_file::ptr &result);
            //char const *const suffixes[] = { ".zip", ".7z" };
            //open_func const open_funcs[ARRAY_LENGTH(suffixes)] = { &util::archive_file::open_zip, &util::archive_file::open_7z };

            // loop over archive types
            string savepath = m_fullpath;
            string filename = "";

            for (unsigned i = 0; i < std.size(suffixes); i++, m_fullpath = savepath, filename = "")
            {
                // loop over directory parts up to the start of filename
                while (true)
                {
                    if (!part_of_mediapath(m_fullpath))
                    {
                        break;
                    }

                    // find the final path separator
                    //auto const dirsepiter(std::find_if(m_fullpath.rbegin(), m_fullpath.rend(), util::is_directory_separator));
                    //if (dirsepiter == m_fullpath.rend())
                    //    break;
                    //std::string::size_type const dirsep(std::distance(m_fullpath.begin(), dirsepiter.base()) - 1);
                    var dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
                    if (dirsep == npos)
                    {
                        break;
                    }

                    // insert the part from the right of the separator into the head of the filename
                    if (!filename.empty())
                    {
                        filename = filename.insert_(0, "/");
                    }
                    filename = filename.insert_(0, m_fullpath.substr(dirsep + 1));

                    // remove this part of the filename and append an archive extension
                    m_fullpath  = m_fullpath.Substring(0, (int)dirsep);
                    m_fullpath += suffixes[i];
                    LOG(null, "emu_file: looking for '{0}' in archive '{1}'\n", filename, m_fullpath);

                    // attempt to open the archive file
                    util.archive_file   zip;
                    std.error_condition ziperr = open_funcs[i](m_fullpath, out zip);

                    // chop the archive suffix back off the filename before continuing
                    m_fullpath = m_fullpath.substr(0, dirsep);

                    // if we failed to open this file, continue scanning
                    if (ziperr)
                    {
                        continue;
                    }

                    int header = -1;

                    // see if we can find a file with the right name and (if available) CRC
                    if ((m_openflags & OPEN_FLAG_HAS_CRC) != 0)
                    {
                        header = zip.search(m_crc, filename, false);
                    }
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc, filename, true);
                    }

                    // if that failed, look for a file with the right CRC, but the wrong filename
                    if (header < 0 && ((m_openflags & OPEN_FLAG_HAS_CRC) != 0))
                    {
                        header = zip.search(m_crc);
                    }

                    // if that failed, look for a file with the right name;
                    // reporting a bad checksum is more helpful and less confusing than reporting "ROM not found"
                    if (header < 0)
                    {
                        header = zip.search(filename, false);
                    }
                    if (header < 0)
                    {
                        header = zip.search(filename, true);
                    }

                    // if we got it, read the data
                    if (header >= 0)
                    {
                        m_zipfile   = zip;
                        m_ziplength = m_zipfile.current_uncompressed_length();

                        // build a hash with just the CRC
                        m_hashes.reset();
                        m_hashes.add_crc(m_zipfile.current_crc());
                        m_fullpath = savepath;
                        return((m_openflags & OPEN_FLAG_NO_PRELOAD) != 0 ? new std.error_condition() : load_zipped_file());
                    }

                    // close up the archive file and try the next level
                    zip.Dispose();
                    zip = null;  //.reset();
                }
            }

            return(std.errc.no_such_file_or_directory);
        }