mirror of
https://github.com/mamedev/mame.git
synced 2024-11-18 10:06:19 +01:00
Merge pull request #1868 from npwoods/imgtool_charconv_rewrite
[Imgtool] Rewrote charconv; now an interface rather than an enumeration
This commit is contained in:
commit
19529fe768
5 changed files with 237 additions and 226 deletions
|
@ -2,7 +2,7 @@
|
|||
// copyright-holders:Nathan Woods
|
||||
/***************************************************************************
|
||||
|
||||
charconv.c
|
||||
charconv.cpp
|
||||
|
||||
Imgtool character set conversion routines.
|
||||
|
||||
|
@ -10,153 +10,117 @@
|
|||
|
||||
#include "corestr.h"
|
||||
#include "charconv.h"
|
||||
#include "unicode.h"
|
||||
#include "coretmpl.h"
|
||||
|
||||
imgtool::simple_charconverter imgtool::charconverter_iso_8859_1(nullptr, nullptr);
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
utf8_from_latin1 - convert an ISO-8859-1
|
||||
character sequence to an UTF-8 string
|
||||
-------------------------------------------------*/
|
||||
//-------------------------------------------------
|
||||
// from_utf8
|
||||
//-------------------------------------------------
|
||||
|
||||
static char *utf8_from_latin1(const char *src)
|
||||
void imgtool::charconverter::from_utf8(std::ostream &dest, const std::string &src) const
|
||||
{
|
||||
char *buffer, *bufptr;
|
||||
from_utf8(dest, src.c_str(), src.size());
|
||||
}
|
||||
|
||||
/* validate input */
|
||||
if (!src)
|
||||
|
||||
//-------------------------------------------------
|
||||
// to_utf8
|
||||
//-------------------------------------------------
|
||||
|
||||
void imgtool::charconverter::to_utf8(std::ostream &dest, const std::string &src) const
|
||||
{
|
||||
to_utf8(dest, src.c_str(), src.size());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// simple_charconverter::simple_charconverter
|
||||
//-------------------------------------------------
|
||||
|
||||
imgtool::simple_charconverter::simple_charconverter(const char32_t lowpage[0x80], const char32_t highpage[0x80], unicode_normalization_form norm)
|
||||
: m_norm(norm), m_lowpage(lowpage), m_highpage(highpage)
|
||||
{
|
||||
// build the reverse lookup table
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
return nullptr;
|
||||
const char32_t *page = i >= 128 ? m_highpage : m_lowpage;
|
||||
char32_t unicode_char = page ? page[i % 128] : i;
|
||||
m_reverse_lookup.emplace_back(unicode_char, (char)i);
|
||||
}
|
||||
|
||||
/* allocate space for result, twice the source len to be safe */
|
||||
buffer = (char *) malloc(strlen(src) * 2 + 1);
|
||||
|
||||
/* point to the start */
|
||||
bufptr = buffer;
|
||||
|
||||
do
|
||||
// and sort it
|
||||
std::sort(m_reverse_lookup.begin(), m_reverse_lookup.end(), [](const std::pair<char32_t, char> &a, const std::pair<char32_t, char> &b)
|
||||
{
|
||||
unsigned char c = *src;
|
||||
return b.first > a.first;
|
||||
});
|
||||
}
|
||||
|
||||
if (c < 0x80)
|
||||
|
||||
//-------------------------------------------------
|
||||
// from_utf8
|
||||
//-------------------------------------------------
|
||||
|
||||
void imgtool::simple_charconverter::from_utf8(std::ostream &dest, const char *src, size_t src_length) const
|
||||
{
|
||||
// normalize the incoming unicode
|
||||
std::string normalized_src = normalize_unicode(src, src_length, m_norm);
|
||||
|
||||
auto iter = normalized_src.begin();
|
||||
while (iter != normalized_src.end())
|
||||
{
|
||||
// get the next character
|
||||
char32_t ch;
|
||||
int rc = uchar_from_utf8(&ch, &*iter, normalized_src.end() - iter);
|
||||
if (rc < 0)
|
||||
{
|
||||
*bufptr++ = c;
|
||||
}
|
||||
else if (c < 0xc0)
|
||||
ch = 0xFFFD;
|
||||
rc = 1;
|
||||
}
|
||||
iter += rc;
|
||||
|
||||
// do the reverse lookup
|
||||
auto lookup = std::lower_bound(m_reverse_lookup.begin(), m_reverse_lookup.end(), ch, [](const std::pair<char32_t, char> &a, const char32_t &b)
|
||||
{
|
||||
*bufptr++ = '\xc2';
|
||||
*bufptr++ = c;
|
||||
return a.first < b;
|
||||
});
|
||||
if (lookup == m_reverse_lookup.end())
|
||||
throw charconverter_exception();
|
||||
|
||||
// and output the results
|
||||
dest << lookup->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// to_utf8
|
||||
//-------------------------------------------------
|
||||
|
||||
void imgtool::simple_charconverter::to_utf8(std::ostream &dest, const char *src, size_t src_length) const
|
||||
{
|
||||
for (size_t i = 0; i < src_length; i++)
|
||||
{
|
||||
// which page is this in?
|
||||
const char32_t *page = ((src[i] & 0x80) == 0) ? m_lowpage : m_highpage;
|
||||
|
||||
// is this page present?
|
||||
if ((src[i] & 0x80) == 0)
|
||||
{
|
||||
// no - pass it on
|
||||
dest << src[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
*bufptr++ = '\xc3';
|
||||
*bufptr++ = c - 0x40;
|
||||
// yes - we need to do a lookup
|
||||
size_t base = ((src[i] & 0x80) == 0) ? 0x00 : 0x80;
|
||||
char32_t ch = page[((unsigned char)(src[i])) - base];
|
||||
if (ch == 0)
|
||||
throw charconverter_exception();
|
||||
|
||||
dest << utf8_from_uchar(ch);
|
||||
}
|
||||
} while (*src++);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
latin1_from_utf8 - convert an UTF-8
|
||||
character sequence to an ISO-8859-1 string
|
||||
-------------------------------------------------*/
|
||||
|
||||
static char *latin1_from_utf8(const char *src)
|
||||
{
|
||||
char *buffer, *bufptr;
|
||||
|
||||
/* validate input */
|
||||
if (!src)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* allocate space for result */
|
||||
buffer = (char *) malloc(strlen(src) + 1);
|
||||
|
||||
/* point to the start */
|
||||
bufptr = buffer;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned char c = *src;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*bufptr++ = c;
|
||||
}
|
||||
else if (c == 0xc2)
|
||||
{
|
||||
c = *++src;
|
||||
*bufptr++ = c;
|
||||
}
|
||||
else if (c == 0xc3)
|
||||
{
|
||||
c = *++src;
|
||||
*bufptr++ = c + 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* conversion failed */
|
||||
*bufptr++ = '\0';
|
||||
break;
|
||||
}
|
||||
} while(*src++);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
utf8_from_native - convert specified character
|
||||
sequence to an UTF-8 string
|
||||
-------------------------------------------------*/
|
||||
|
||||
char *utf8_from_native(imgtool_charset charset, const char *src)
|
||||
{
|
||||
char *result;
|
||||
|
||||
switch (charset)
|
||||
{
|
||||
case IMGTOOL_CHARSET_UTF8:
|
||||
result = core_strdup(src);
|
||||
break;
|
||||
|
||||
case IMGTOOL_CHARSET_ISO_8859_1:
|
||||
result = utf8_from_latin1(src);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = nullptr;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
native_from_utf8 - convert an UTF-8 string
|
||||
to specified character set
|
||||
-------------------------------------------------*/
|
||||
|
||||
char *native_from_utf8(imgtool_charset charset, const char *src)
|
||||
{
|
||||
char *result;
|
||||
|
||||
switch (charset)
|
||||
{
|
||||
case IMGTOOL_CHARSET_UTF8:
|
||||
result = core_strdup(src);
|
||||
break;
|
||||
|
||||
case IMGTOOL_CHARSET_ISO_8859_1:
|
||||
result = latin1_from_utf8(src);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = nullptr;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -9,23 +9,73 @@
|
|||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CHARCONV_H__
|
||||
#define __CHARCONV_H__
|
||||
#ifndef IMGTOOL_CHARCONV_H
|
||||
#define IMGTOOL_CHARCONV_H
|
||||
|
||||
#include "unicode.h"
|
||||
|
||||
/* Supported character sets */
|
||||
enum imgtool_charset
|
||||
namespace imgtool
|
||||
{
|
||||
IMGTOOL_CHARSET_UTF8,
|
||||
IMGTOOL_CHARSET_ISO_8859_1,
|
||||
// ======================> charconverter
|
||||
|
||||
// abstract base class for character conversions
|
||||
class charconverter
|
||||
{
|
||||
public:
|
||||
virtual void from_utf8(std::ostream &dest, const char *src, size_t src_length) const = 0;
|
||||
virtual void to_utf8(std::ostream &dest, const char *src, size_t src_length) const = 0;
|
||||
|
||||
void from_utf8(std::ostream &dest, const std::string &src) const;
|
||||
void to_utf8(std::ostream &dest, const std::string &src) const;
|
||||
|
||||
std::string from_utf8(const std::string &src) const
|
||||
{
|
||||
// inlining so that the return value can potentially be removed by return value optimization
|
||||
std::ostringstream stream;
|
||||
from_utf8(stream, src);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string to_utf8(const std::string &src) const
|
||||
{
|
||||
// inlining so that the return value can potentially be removed by return value optimization
|
||||
std::ostringstream stream;
|
||||
to_utf8(stream, src);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// ======================> simple_charconverter
|
||||
|
||||
// a simple implementation of charconverter that simply defines a code page for 0x80-0xFF
|
||||
class simple_charconverter : public charconverter
|
||||
{
|
||||
public:
|
||||
simple_charconverter(const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C)
|
||||
: simple_charconverter(nullptr, highpage, norm)
|
||||
{
|
||||
}
|
||||
|
||||
simple_charconverter(const char32_t lowpage[0x80], const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C);
|
||||
|
||||
virtual void from_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
||||
virtual void to_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<char32_t, char> > m_reverse_lookup;
|
||||
unicode_normalization_form m_norm;
|
||||
const char32_t *m_lowpage;
|
||||
const char32_t *m_highpage;
|
||||
};
|
||||
|
||||
// exception that can be thrown from charconverter::from_utf8() if a character is illegal (charconverter::to_utf8() should never throw this)
|
||||
class charconverter_exception
|
||||
{
|
||||
};
|
||||
|
||||
extern simple_charconverter charconverter_iso_8859_1;
|
||||
};
|
||||
|
||||
|
||||
/* Convert specified charset to UTF-8 */
|
||||
char *utf8_from_native(imgtool_charset charset, const char *src);
|
||||
|
||||
/* Convert UTF-8 string to specified charset */
|
||||
char *native_from_utf8(imgtool_charset charset, const char *src);
|
||||
|
||||
|
||||
#endif /* __CHARCONV_H__ */
|
||||
#endif // IMGTOOL_CHARCONV_H
|
||||
|
|
|
@ -120,11 +120,11 @@ static imgtoolerr_t markerrorsource(imgtoolerr_t err)
|
|||
|
||||
case IMGTOOLERR_FILENOTFOUND:
|
||||
case IMGTOOLERR_BADFILENAME:
|
||||
err = (imgtoolerr_t)(err | IMGTOOLERR_SRC_FILEONIMAGE);
|
||||
err = imgtoolerr_t(err | IMGTOOLERR_SRC_FILEONIMAGE);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = (imgtoolerr_t)(err | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
err = imgtoolerr_t(err | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
|
@ -150,13 +150,11 @@ static void internal_error(const imgtool_module *module, const char *message)
|
|||
|
||||
char *imgtool::partition::normalize_filename(const char *src)
|
||||
{
|
||||
imgtool_charset charset;
|
||||
// get charconverter from module
|
||||
imgtool::charconverter *charconverter = (imgtool::charconverter *) get_info_ptr(IMGTOOLINFO_PTR_CHARCONVERTER);
|
||||
|
||||
// get charset from module
|
||||
charset = (imgtool_charset) (int) get_info_int(IMGTOOLINFO_INT_CHARSET);
|
||||
|
||||
// and dupe it
|
||||
return native_from_utf8(charset, src);
|
||||
// and convert
|
||||
return core_strdup(charconverter ? charconverter->from_utf8(src).c_str() : src);
|
||||
}
|
||||
|
||||
|
||||
|
@ -374,7 +372,7 @@ imgtoolerr_t imgtool::image::identify_file(const char *fname, imgtool_module **m
|
|||
}
|
||||
|
||||
if (!modules[0])
|
||||
return (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
return imgtoolerr_t(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
|
||||
return IMGTOOLERR_SUCCESS;
|
||||
}
|
||||
|
@ -405,7 +403,7 @@ imgtoolerr_t imgtool::image::get_geometry(uint32_t *tracks, uint32_t *heads, uin
|
|||
|
||||
/* implemented? */
|
||||
if (!module().get_geometry)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
return module().get_geometry(*this, tracks, heads, sectors);
|
||||
}
|
||||
|
@ -421,7 +419,7 @@ imgtoolerr_t imgtool::image::read_sector(uint32_t track, uint32_t head,
|
|||
{
|
||||
// implemented?
|
||||
if (!module().read_sector)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
return module().read_sector(*this, track, head, sector, buffer);
|
||||
}
|
||||
|
@ -437,7 +435,7 @@ imgtoolerr_t imgtool::image::write_sector(uint32_t track, uint32_t head,
|
|||
{
|
||||
// implemented?
|
||||
if (!module().write_sector)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
return module().write_sector(*this, track, head, sector, buffer, len);
|
||||
}
|
||||
|
@ -453,7 +451,7 @@ imgtoolerr_t imgtool::image::get_block_size(uint32_t &length)
|
|||
{
|
||||
// implemented?
|
||||
if (module().block_size == 0)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
length = module().block_size;
|
||||
return IMGTOOLERR_SUCCESS;
|
||||
|
@ -468,7 +466,7 @@ imgtoolerr_t imgtool::image::read_block(uint64_t block, void *buffer)
|
|||
{
|
||||
// implemented?
|
||||
if (!module().read_block)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
return module().read_block(*this, buffer, block);
|
||||
}
|
||||
|
@ -482,7 +480,7 @@ imgtoolerr_t imgtool::image::write_block(uint64_t block, const void *buffer)
|
|||
{
|
||||
// implemented?
|
||||
if (!module().write_block)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
return module().write_block(*this, buffer, block);
|
||||
}
|
||||
|
@ -920,7 +918,7 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s
|
|||
// is the requested functionality implemented?
|
||||
if ((read_or_write == OSD_FOPEN_RW_CREATE) ? !module->create : !module->open)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -928,7 +926,7 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s
|
|||
pool = pool_alloc_lib(nullptr);
|
||||
if (!pool)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -936,7 +934,7 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s
|
|||
stream = imgtool::stream::open(filename, read_or_write);
|
||||
if (!stream)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
err = imgtoolerr_t(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_IMAGEFILE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -946,7 +944,7 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s
|
|||
extra_bytes = pool_malloc_lib(pool, module->image_extra_bytes);
|
||||
if (!extra_bytes)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY);
|
||||
goto done;
|
||||
}
|
||||
memset(extra_bytes, 0, module->image_extra_bytes);
|
||||
|
@ -956,7 +954,7 @@ imgtoolerr_t imgtool::image::internal_open(const imgtool_module *module, const s
|
|||
try { image = std::make_unique<imgtool::image>(*module, pool, extra_bytes); }
|
||||
catch (std::bad_alloc const &)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1004,7 @@ imgtoolerr_t imgtool::image::open(const std::string &modulename, const std::stri
|
|||
|
||||
module = imgtool_find_module(modulename);
|
||||
if (!module)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE);
|
||||
return imgtoolerr_t(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE);
|
||||
|
||||
return open(module, filename, read_or_write, outimg);
|
||||
}
|
||||
|
@ -1072,7 +1070,7 @@ imgtoolerr_t imgtool::image::create(const std::string &modulename, const std::st
|
|||
|
||||
module = imgtool_find_module(modulename);
|
||||
if (!module)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE);
|
||||
return imgtoolerr_t(IMGTOOLERR_MODULENOTFOUND | IMGTOOLERR_SRC_MODULE);
|
||||
|
||||
return create(module, filename, opts, image);
|
||||
}
|
||||
|
@ -1160,7 +1158,7 @@ imgtoolerr_t imgtool::partition::cannonicalize_path(uint32_t flags, const char *
|
|||
/* do we specify a path when paths are not supported? */
|
||||
if (*path && **path)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_CANNOTUSEPATH | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_CANNOTUSEPATH | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
*path = nullptr; /* normalize empty path */
|
||||
|
@ -1327,14 +1325,14 @@ imgtoolerr_t imgtool::partition::list_file_attributes(const char *path, uint32_t
|
|||
|
||||
if (!m_list_attrs)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(path);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1371,14 +1369,14 @@ imgtoolerr_t imgtool::partition::get_file_attributes(const char *path, const uin
|
|||
|
||||
if (!m_get_attrs)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(path);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1414,7 +1412,7 @@ imgtoolerr_t imgtool::partition::put_file_attributes(const char *path, const uin
|
|||
|
||||
if (!m_set_attrs)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1475,14 +1473,14 @@ imgtoolerr_t imgtool::partition::get_icon_info(const char *path, imgtool_iconinf
|
|||
|
||||
if (!m_get_iconinfo)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(path);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1527,7 +1525,7 @@ imgtoolerr_t imgtool::partition::suggest_file_filters(const char *path,
|
|||
|
||||
if (!m_suggest_transfer)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1601,7 +1599,7 @@ imgtoolerr_t imgtool::partition::get_chain(const char *path, imgtool_chainent *c
|
|||
assert(chain_size > 0);
|
||||
|
||||
if (!m_get_chain)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
// initialize the chain array, so the module's get_chain function can be lazy
|
||||
for (i = 0; i < chain_size; i++)
|
||||
|
@ -1694,7 +1692,7 @@ imgtoolerr_t imgtool::partition::get_free_space(uint64_t &sz)
|
|||
imgtoolerr_t err;
|
||||
|
||||
if (!m_free_space)
|
||||
return (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
return imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
|
||||
err = m_free_space(*this, &sz);
|
||||
if (err)
|
||||
|
@ -1717,7 +1715,7 @@ imgtoolerr_t imgtool::partition::read_file(const char *filename, const char *for
|
|||
|
||||
if (!m_read_file)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1727,7 +1725,7 @@ imgtoolerr_t imgtool::partition::read_file(const char *filename, const char *for
|
|||
filter(FILTINFO_PTR_READFILE, &u);
|
||||
if (!u.read_file)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1783,7 +1781,7 @@ imgtoolerr_t imgtool::partition::write_file(const char *filename, const char *fo
|
|||
|
||||
if (!m_write_file)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1793,7 +1791,7 @@ imgtoolerr_t imgtool::partition::write_file(const char *filename, const char *fo
|
|||
filter(FILTINFO_PTR_WRITEFILE, &u);
|
||||
if (!u.write_file)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1812,7 +1810,7 @@ imgtoolerr_t imgtool::partition::write_file(const char *filename, const char *fo
|
|||
buf = (char*)malloc(strlen(filename) + 1);
|
||||
if (!buf)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_OUTOFMEMORY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY);
|
||||
goto done;
|
||||
}
|
||||
strcpy(buf, filename);
|
||||
|
@ -1922,14 +1920,14 @@ imgtoolerr_t imgtool::partition::get_file(const char *filename, const char *fork
|
|||
f = imgtool::stream::open(dest, OSD_FOPEN_WRITE);
|
||||
if (!f)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
err = imgtoolerr_t(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(filename);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1956,8 +1954,7 @@ imgtoolerr_t imgtool::partition::put_file(const char *newfname, const char *fork
|
|||
{
|
||||
imgtoolerr_t err;
|
||||
imgtool::stream::ptr f;
|
||||
imgtool_charset charset;
|
||||
char *alloc_newfname = nullptr;
|
||||
std::string alloc_newfname;
|
||||
std::string basename;
|
||||
|
||||
if (!newfname)
|
||||
|
@ -1966,30 +1963,27 @@ imgtoolerr_t imgtool::partition::put_file(const char *newfname, const char *fork
|
|||
newfname = basename.c_str();
|
||||
}
|
||||
|
||||
charset = (imgtool_charset) (int) get_info_int(IMGTOOLINFO_INT_CHARSET);
|
||||
if (charset != IMGTOOL_CHARSET_UTF8)
|
||||
imgtool::charconverter *charconverter = (imgtool::charconverter *) get_info_ptr(IMGTOOLINFO_PTR_CHARCONVERTER);
|
||||
if (charconverter)
|
||||
{
|
||||
/* convert to native format */
|
||||
alloc_newfname = native_from_utf8(charset, newfname);
|
||||
if (alloc_newfname == nullptr)
|
||||
// convert to native format
|
||||
try
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
goto done;
|
||||
alloc_newfname = charconverter->from_utf8(newfname);
|
||||
}
|
||||
|
||||
newfname = alloc_newfname;
|
||||
catch (charconverter_exception)
|
||||
{
|
||||
return imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
}
|
||||
newfname = alloc_newfname.c_str();
|
||||
}
|
||||
|
||||
f = imgtool::stream::open(source, OSD_FOPEN_READ);
|
||||
if (f)
|
||||
err = write_file(newfname, fork, *f, opts, filter);
|
||||
else
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
err = imgtoolerr_t(IMGTOOLERR_FILENOTFOUND | IMGTOOLERR_SRC_NATIVEFILE);
|
||||
|
||||
done:
|
||||
/* clean up */
|
||||
if (alloc_newfname != nullptr)
|
||||
free(alloc_newfname);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -2008,14 +2002,14 @@ imgtoolerr_t imgtool::partition::delete_file(const char *fname)
|
|||
|
||||
if (!m_delete_file)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(fname);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2055,14 +2049,14 @@ imgtoolerr_t imgtool::partition::list_file_forks(const char *path, imgtool_forke
|
|||
|
||||
if (!m_list_forks)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_fname = normalize_filename(path);
|
||||
if (new_fname == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2100,14 +2094,14 @@ imgtoolerr_t imgtool::partition::create_directory(const char *path)
|
|||
// implemented?
|
||||
if (!m_create_dir)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_path = normalize_filename(path);
|
||||
if (new_path == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2145,14 +2139,14 @@ imgtoolerr_t imgtool::partition::delete_directory(const char *path)
|
|||
// implemented?
|
||||
if (!m_delete_dir)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_path = normalize_filename(path);
|
||||
if (new_path == nullptr)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_BADFILENAME | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2444,7 +2438,7 @@ imgtool::directory::directory(imgtool::partition &partition)
|
|||
imgtoolerr_t imgtool::directory::open(imgtool::partition &partition, const std::string &path_string, imgtool::directory::ptr &outenum)
|
||||
{
|
||||
const char *path = path_string.c_str();
|
||||
imgtoolerr_t err = (imgtoolerr_t)IMGTOOLERR_SUCCESS;
|
||||
imgtoolerr_t err = imgtoolerr_t(IMGTOOLERR_SUCCESS);
|
||||
imgtool::directory::ptr enumeration;
|
||||
char *alloc_path = nullptr;
|
||||
char *new_path = nullptr;
|
||||
|
@ -2453,7 +2447,7 @@ imgtoolerr_t imgtool::directory::open(imgtool::partition &partition, const std::
|
|||
|
||||
if (!partition.m_next_enum)
|
||||
{
|
||||
err = (imgtoolerr_t)(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
err = imgtoolerr_t(IMGTOOLERR_UNIMPLEMENTED | IMGTOOLERR_SRC_FUNCTIONALITY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2467,7 +2461,7 @@ imgtoolerr_t imgtool::directory::open(imgtool::partition &partition, const std::
|
|||
try { enumeration = std::make_unique<directory>(partition); }
|
||||
catch (std::bad_alloc const &)
|
||||
{
|
||||
err = (imgtoolerr_t)IMGTOOLERR_OUTOFMEMORY;
|
||||
err = imgtoolerr_t(IMGTOOLERR_OUTOFMEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2521,17 +2515,19 @@ imgtoolerr_t imgtool::directory::get_next(imgtool_dirent &ent)
|
|||
if (err)
|
||||
return markerrorsource(err);
|
||||
|
||||
int charset = m_partition.get_info_int(IMGTOOLINFO_INT_CHARSET);
|
||||
|
||||
if (charset)
|
||||
imgtool::charconverter *charconverter = (imgtool::charconverter *) m_partition.get_info_ptr(IMGTOOLINFO_PTR_CHARCONVERTER);
|
||||
if (charconverter)
|
||||
{
|
||||
char *new_fname = utf8_from_native((imgtool_charset)charset, ent.filename);
|
||||
|
||||
if (!new_fname)
|
||||
return IMGTOOLERR_BADFILENAME;
|
||||
|
||||
snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", new_fname);
|
||||
free(new_fname);
|
||||
std::string new_fname;
|
||||
try
|
||||
{
|
||||
new_fname = charconverter->to_utf8(ent.filename);
|
||||
}
|
||||
catch (charconverter_exception)
|
||||
{
|
||||
return imgtoolerr_t(IMGTOOLERR_BADFILENAME);
|
||||
}
|
||||
snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", new_fname.c_str());
|
||||
}
|
||||
|
||||
// don't trust the module!
|
||||
|
|
|
@ -165,7 +165,6 @@ enum
|
|||
IMGTOOLINFO_INT_CREATION_UNTESTED,
|
||||
IMGTOOLINFO_INT_SUPPORTS_BOOTBLOCK,
|
||||
IMGTOOLINFO_INT_BLOCK_SIZE,
|
||||
IMGTOOLINFO_INT_CHARSET,
|
||||
|
||||
IMGTOOLINFO_INT_CLASS_SPECIFIC = 0x08000,
|
||||
|
||||
|
@ -205,6 +204,7 @@ enum
|
|||
IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE,
|
||||
IMGTOOLINFO_PTR_MAKE_CLASS,
|
||||
IMGTOOLINFO_PTR_LIST_PARTITIONS,
|
||||
IMGTOOLINFO_PTR_CHARCONVERTER,
|
||||
|
||||
IMGTOOLINFO_PTR_CLASS_SPECIFIC = 0x18000,
|
||||
|
||||
|
@ -311,6 +311,7 @@ union imgtoolinfo
|
|||
|
||||
const util::option_guide *createimage_optguide;
|
||||
const util::option_guide *writefile_optguide;
|
||||
const imgtool::charconverter *charconverter;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2386,7 +2386,6 @@ void amiga_floppy_get_info(const imgtool_class *imgclass, uint32_t state, union
|
|||
case IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES: info->i = sizeof(amiga_iterator); break;
|
||||
case IMGTOOLINFO_INT_SUPPORTS_LASTMODIFIED_TIME: info->i = 1; break;
|
||||
case IMGTOOLINFO_INT_PATH_SEPARATOR: info->i = '/'; break;
|
||||
case IMGTOOLINFO_INT_CHARSET: info->i = IMGTOOL_CHARSET_ISO_8859_1; break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case IMGTOOLINFO_STR_NAME: strcpy(info->s = imgtool_temp_str(), "amiga_floppy"); break;
|
||||
|
@ -2415,5 +2414,6 @@ void amiga_floppy_get_info(const imgtool_class *imgclass, uint32_t state, union
|
|||
case IMGTOOLINFO_PTR_GET_ICON_INFO: info->get_iconinfo = amiga_image_geticoninfo; break;
|
||||
case IMGTOOLINFO_PTR_SUGGEST_TRANSFER: info->suggest_transfer = amiga_image_suggesttransfer; break;
|
||||
case IMGTOOLINFO_PTR_CREATEIMAGE_OPTGUIDE: info->createimage_optguide = &amiga_createimage_optionguide; break;
|
||||
case IMGTOOLINFO_PTR_CHARCONVERTER: info->charconverter = &imgtool::charconverter_iso_8859_1; break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue