Esempio n. 1
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);
        }
Esempio n. 2
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);
        }