diff options
Diffstat (limited to 'src/lib')
39 files changed, 1101 insertions, 931 deletions
diff --git a/src/lib/formats/c3040_dsk.c b/src/lib/formats/c3040_dsk.c new file mode 100644 index 00000000000..9fb6669ab20 --- /dev/null +++ b/src/lib/formats/c3040_dsk.c @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c3040_dsk.c + + Commodore 3040 sector disk image format + +*********************************************************************/ + +#include <assert.h> + +#include "formats/c3040_dsk.h" + +c3040_format::c3040_format() : d64_format(file_formats) +{ +} + +const char *c3040_format::name() const +{ + return "c3040"; +} + +const char *c3040_format::description() const +{ + return "Commodore 3040 disk image"; +} + +const char *c3040_format::extensions() const +{ + return "d67"; +} + +const c3040_format::format c3040_format::file_formats[] = { + { // d67, dos 1, 35 tracks, head 48 tpi, stepper 96 tpi + floppy_image::FF_525, floppy_image::SSSD, 690, 35, 1, 256, 9, 8 + }, + {} +}; + +const int c3040_format::c3040_sectors_per_track[] = +{ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, // 1-17 + 20, 20, 20, 20, 20, 20, 20, // 18-24 + 18, 18, 18, 18, 18, 18, // 25-30 + 17, 17, 17, 17, 17, // 31-35 + 17, 17, 17, 17, 17, // 36-40 + 17, 17 // 41-42 +}; + +const int c3040_format::c3040_gap2[] = +{ + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // 1-17 + 8, 8, 8, 8, 8, 8, 8, // 18-24 + 15, 15, 15, 15, 15, 15, // 25-30 + 12, 12, 12, 12, 12 // 31-35 +}; + +floppy_image_format_t::desc_e* c3040_format::get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2) +{ + static floppy_image_format_t::desc_e desc[] = { + /* 00 */ { SECTOR_LOOP_START, 0, -1 }, + /* 01 */ { SYNC_GCR5, 2 }, + /* 02 */ { GCR5, 0x08, 1 }, + /* 03 */ { CRC, 1 }, + /* 04 */ { CRC_CBM_START, 1 }, + /* 05 */ { SECTOR_ID_GCR5 }, + /* 06 */ { TRACK_ID_DOS2_GCR5 }, + /* 07 */ { GCR5, id2, 1 }, + /* 08 */ { GCR5, id1, 1 }, + /* 09 */ { CRC_END, 1 }, + /* 10 */ { GCR5, 0x00, f.gap_1 }, + /* 11 */ { SYNC_GCR5, 2 }, + /* 12 */ { GCR5, 0x07, 1 }, + /* 13 */ { CRC_CBM_START, 2 }, + /* 14 */ { SECTOR_DATA_GCR5, -1 }, + /* 15 */ { CRC_END, 2 }, + /* 16 */ { CRC, 2 }, + /* 17 */ { GCR5, 0x00, gap_2 }, + /* 18 */ { SECTOR_LOOP_END }, + /* 19 */ { GCR5, 0x00, 0 }, + /* 20 */ { RAWBITS, 0x14a, 0 }, + /* 21 */ { END } + }; + + desc[17].p2 = gap_2; // TODO why?!? + + current_size = 20 + (1+1+4)*10 + f.gap_1*10 + 20 + (1+f.sector_base_size+1)*10 + gap_2*10; + + current_size *= sector_count; + return desc; +} + +void c3040_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size) +{ + desc[19].p2 = remaining_size / 10; + desc[20].p2 = remaining_size % 10; + desc[20].p1 >>= remaining_size & 0x01; +} + +const floppy_format_type FLOPPY_C3040_FORMAT = &floppy_image_format_creator<c3040_format>; diff --git a/src/lib/formats/c3040_dsk.h b/src/lib/formats/c3040_dsk.h new file mode 100644 index 00000000000..cbf320273a8 --- /dev/null +++ b/src/lib/formats/c3040_dsk.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c3040_dsk.h + + Commodore 3040 sector disk image format + +*********************************************************************/ + +#ifndef C3040_DSK_H_ +#define C3040_DSK_H_ + +#include "d64_dsk.h" + +class c3040_format : public d64_format { +public: + c3040_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +protected: + virtual int get_sectors_per_track(const format &f, int track) { return c3040_sectors_per_track[track]; } + virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); + virtual int get_gap2(const format &f, int head, int track) { return c3040_gap2[track]; } + virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + + static const format file_formats[]; + + static const int c3040_gap2[]; + static const int c3040_sectors_per_track[]; +}; + +extern const floppy_format_type FLOPPY_C3040_FORMAT; + + + +#endif diff --git a/src/lib/formats/c4040_dsk.c b/src/lib/formats/c4040_dsk.c new file mode 100644 index 00000000000..9e6dff7f627 --- /dev/null +++ b/src/lib/formats/c4040_dsk.c @@ -0,0 +1,91 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c4040_dsk.c + + Commodore 4040 sector disk image format + +*********************************************************************/ + +#include <assert.h> + +#include "formats/c4040_dsk.h" + +c4040_format::c4040_format() : d64_format(file_formats) +{ +} + +const char *c4040_format::name() const +{ + return "c4040"; +} + +const char *c4040_format::description() const +{ + return "Commodore 4040 disk image"; +} + +const char *c4040_format::extensions() const +{ + return "d64"; +} + +const c4040_format::format c4040_format::file_formats[] = { + { // c4040, dos 2, 35 tracks, head 48 tpi, stepper 96 tpi + floppy_image::FF_525, floppy_image::SSSD, 683, 35, 1, 256, 9, 8 + }, + {} +}; + +const int c4040_format::c4040_gap2[] = +{ + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // 1-17 + 19, 19, 19, 19, 19, 19, 19, // 18-24 + 15, 15, 15, 15, 15, 15, // 25-30 + 12, 12, 12, 12, 12 // 31-35 +}; + +floppy_image_format_t::desc_e* c4040_format::get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2) +{ + static floppy_image_format_t::desc_e desc[] = { + /* 00 */ { SECTOR_LOOP_START, 0, -1 }, + /* 01 */ { SYNC_GCR5, 4 }, + /* 02 */ { GCR5, 0x08, 1 }, + /* 03 */ { CRC, 1 }, + /* 04 */ { CRC_CBM_START, 1 }, + /* 05 */ { SECTOR_ID_GCR5 }, + /* 06 */ { TRACK_ID_DOS2_GCR5 }, + /* 07 */ { GCR5, id2, 1 }, + /* 08 */ { GCR5, id1, 1 }, + /* 09 */ { CRC_END, 1 }, + /* 10 */ { GCR5, 0x00, f.gap_1 }, + /* 11 */ { SYNC_GCR5, 4 }, + /* 12 */ { GCR5, 0x07, 1 }, + /* 13 */ { CRC_CBM_START, 2 }, + /* 14 */ { SECTOR_DATA_GCR5, -1 }, + /* 15 */ { CRC_END, 2 }, + /* 16 */ { CRC, 2 }, + /* 17 */ { GCR5, 0x00, gap_2 }, + /* 18 */ { SECTOR_LOOP_END }, + /* 19 */ { GCR5, 0x00, 0 }, + /* 20 */ { RAWBITS, 0x14a, 0 }, + /* 21 */ { END } + }; + + desc[17].p2 = gap_2; // TODO why?!? + + current_size = 40 + (1+1+4)*10 + f.gap_1*10 + 40 + (1+f.sector_base_size+1)*10 + gap_2*10; + + current_size *= sector_count; + return desc; +} + +void c4040_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size) +{ + desc[19].p2 = remaining_size / 10; + desc[20].p2 = remaining_size % 10; + desc[20].p1 >>= remaining_size & 0x01; +} + +const floppy_format_type FLOPPY_C4040_FORMAT = &floppy_image_format_creator<c4040_format>; diff --git a/src/lib/formats/c4040_dsk.h b/src/lib/formats/c4040_dsk.h new file mode 100644 index 00000000000..231b961c765 --- /dev/null +++ b/src/lib/formats/c4040_dsk.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c4040_dsk.h + + Commodore 4040 sector disk image format + +*********************************************************************/ + +#ifndef C4040_DSK_H_ +#define C4040_DSK_H_ + +#include "d64_dsk.h" + +class c4040_format : public d64_format { +public: + c4040_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +protected: + virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); + virtual int get_gap2(const format &f, int head, int track) { return c4040_gap2[track]; } + virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + + static const format file_formats[]; + + static const int c4040_gap2[]; +}; + +extern const floppy_format_type FLOPPY_C4040_FORMAT; + + + +#endif diff --git a/src/lib/formats/c8280_dsk.c b/src/lib/formats/c8280_dsk.c new file mode 100644 index 00000000000..cb39b5c3ea5 --- /dev/null +++ b/src/lib/formats/c8280_dsk.c @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c8280_dsk.c + + Commodore 8280 disk image format + +*********************************************************************/ + +#include "formats/c8280_dsk.h" + +c8280_format::c8280_format() : wd177x_format(formats) +{ +} + +const char *c8280_format::name() const +{ + return "c8280"; +} + +const char *c8280_format::description() const +{ + return "Commodore 8280 disk image"; +} + +const char *c8280_format::extensions() const +{ + return "dsk"; +} + +const c8280_format::format c8280_format::formats[] = { + // 80x4e 12x00 3xf6 fc + // 50x4e 12x00 3xf5 fe 2x00 01 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 02 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 03 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 04 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 05 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 06 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 07 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 08 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 09 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0a 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0b 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0c 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0d 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0e 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0f 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 10 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 11 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 12 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 13 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 14 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 15 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 16 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 17 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 18 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 19 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 1a 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 653x4e + { + floppy_image::FF_8, floppy_image::DSDD, floppy_image::MFM, + 1200, 26, 77, 2, 256, {}, 1, {}, 50, 22, 54 + }, + + {} +}; + +const floppy_format_type FLOPPY_C8280_FORMAT = &floppy_image_format_creator<c8280_format>; diff --git a/src/lib/formats/c8280_dsk.h b/src/lib/formats/c8280_dsk.h new file mode 100644 index 00000000000..eed34f5d846 --- /dev/null +++ b/src/lib/formats/c8280_dsk.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c8280_dsk.h + + Commodore 8280 disk image format + +*********************************************************************/ + +#ifndef C8280_DSK_H_ +#define C8280_DSK_H_ + +#include "wd177x_dsk.h" + +class c8280_format : public wd177x_format { +public: + c8280_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +private: + static const format formats[]; +}; + +extern const floppy_format_type FLOPPY_C8280_FORMAT; + +#endif diff --git a/src/lib/formats/cbm_crt.c b/src/lib/formats/cbm_crt.c index 3be90b29ab1..dce20d6e603 100644 --- a/src/lib/formats/cbm_crt.c +++ b/src/lib/formats/cbm_crt.c @@ -122,7 +122,7 @@ static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] = // cbm_crt_get_card - get slot interface card //------------------------------------------------- -void cbm_crt_get_card(astring &result, core_file *file) +void cbm_crt_get_card(std::string &result, core_file *file) { // read the header cbm_crt_header header; @@ -132,11 +132,11 @@ void cbm_crt_get_card(astring &result, core_file *file) { UINT16 hardware = pick_integer_be(header.hardware, 0, 2); - result.cpy(CRT_C64_SLOT_NAMES[hardware]); + result.assign(CRT_C64_SLOT_NAMES[hardware]); return; } - result.reset(); + result.clear(); } diff --git a/src/lib/formats/cbm_crt.h b/src/lib/formats/cbm_crt.h index 8049ddacff7..9be37bc0740 100644 --- a/src/lib/formats/cbm_crt.h +++ b/src/lib/formats/cbm_crt.h @@ -135,7 +135,7 @@ struct cbm_crt_chip // FUNCTION PROTOTYPES //************************************************************************** -void cbm_crt_get_card(astring &result, core_file *file); +void cbm_crt_get_card(std::string &result, core_file *file); bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game); bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh); diff --git a/src/lib/formats/ccvf_dsk.c b/src/lib/formats/ccvf_dsk.c index 03ee6fd0dbc..44d919bc88e 100644 --- a/src/lib/formats/ccvf_dsk.c +++ b/src/lib/formats/ccvf_dsk.c @@ -93,18 +93,18 @@ bool ccvf_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) dynamic_buffer img(size); io_generic_read(io, &img[0], 0, size); - astring ccvf = astring((const char *)&img[0], size); + std::string ccvf = std::string((const char *)&img[0], size); dynamic_buffer bytes(78720); int start = 0, end = 0; - astring line; + std::string line; UINT32 byteoffs = 0; char hex[3] = {0}; do { - end = ccvf.chr(start, 10); - line.cpysubstr(ccvf, start, end); - if (line.find(0, "Compucolor Virtual Floppy Disk Image") && line.find(0, "Label") && line.find(0, "Track")) { + end = ccvf.find_first_of(10, start); + line.assign(ccvf.substr(start, end)); + if (line.find("Compucolor Virtual Floppy Disk Image") != std::string::npos && line.find("Label") != std::string::npos && line.find("Track") != std::string::npos) { for (int byte = 0; byte < 32; byte++) { if (byteoffs==78720) break; hex[0]=line[byte * 2]; diff --git a/src/lib/formats/d64_dsk.c b/src/lib/formats/d64_dsk.c index 3bcbee87727..531ce441b99 100644 --- a/src/lib/formats/d64_dsk.c +++ b/src/lib/formats/d64_dsk.c @@ -122,6 +122,25 @@ void d64_format::get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 id2 = id[1]; } +int d64_format::get_image_offset(const format &f, int _head, int _track) +{ + int offset = 0; + if (_head) { + for (int track = 0; track < f.track_count; track++) { + offset += compute_track_size(f, track); + } + } + for (int track = 0; track < _track; track++) { + offset += compute_track_size(f, track); + } + return offset; +} + +int d64_format::compute_track_size(const format &f, int track) +{ + return this->get_sectors_per_track(f, track) * f.sector_base_size; +} + UINT32 d64_format::get_cell_size(const format &f, int track) { return cell_size[speed_zone[track]]; @@ -220,8 +239,9 @@ bool d64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) int physical_track = this->get_physical_track(f, head, track); int sector_count = this->get_sectors_per_track(f, track); int track_size = sector_count*f.sector_base_size; + int gap2 = this->get_gap2(f, head, track); - floppy_image_format_t::desc_e *desc = this->get_sector_desc(f, current_size, sector_count, id1, id2, f.gap_2); + floppy_image_format_t::desc_e *desc = this->get_sector_desc(f, current_size, sector_count, id1, id2, gap2); int remaining_size = total_size - current_size; if(remaining_size < 0) @@ -244,9 +264,51 @@ bool d64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) return true; } -bool d64_format::supports_save() const +bool d64_format::save(io_generic *io, floppy_image *image) +{ + const format &f = formats[0]; + + for(int head=0; head < f.head_count; head++) { + for(int track=0; track < f.track_count; track++) { + int sector_count = this->get_sectors_per_track(f, track); + int track_size = compute_track_size(f, track); + UINT8 sectdata[40*256] = { 0 }; + desc_s sectors[40]; + int offset = get_image_offset(f, head, track); + + build_sector_description(f, sectdata, 0, 0, sectors, sector_count); + extract_sectors(image, f, sectors, track, head, sector_count); + io_generic_write(io, sectdata, offset, track_size); + } + } + + return true; +} + +void d64_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - return false; + UINT8 bitstream[500000/8]; + UINT8 sectdata[50000]; + desc_xs sectors[256]; + int physical_track = this->get_physical_track(f, head, track); + int cell_size = this->get_cell_size(f, track); + int track_size; + + // Extract the sectors + generate_bitstream_from_track(physical_track, head, cell_size, bitstream, track_size, image); + extract_sectors_from_bitstream_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata), head, f.track_count); + + for(int i=0; i<sector_count; i++) { + desc_s &ds = sdesc[i]; + desc_xs &xs = sectors[ds.sector_id]; + if(!xs.data) + memset((void *)ds.data, 0, ds.size); + else if(xs.size < ds.size) { + memcpy((void *)ds.data, xs.data, xs.size); + memset((UINT8 *)ds.data + xs.size, 0, xs.size - ds.size); + } else + memcpy((void *)ds.data, xs.data, ds.size); + } } const floppy_format_type FLOPPY_D64_FORMAT = &floppy_image_format_creator<d64_format>; diff --git a/src/lib/formats/d64_dsk.h b/src/lib/formats/d64_dsk.h index 573bbab4cbc..558d4ebf1c2 100644 --- a/src/lib/formats/d64_dsk.h +++ b/src/lib/formats/d64_dsk.h @@ -36,7 +36,8 @@ public: virtual int identify(io_generic *io, UINT32 form_factor); virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); - virtual bool supports_save() const; + virtual bool save(io_generic *io, floppy_image *image); + virtual bool supports_save() const { return true; } protected: enum @@ -63,9 +64,13 @@ protected: virtual int get_sectors_per_track(const format &f, int track); virtual int get_disk_id_offset(const format &f); void get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 &id2); + virtual int get_image_offset(const format &f, int head, int track); + int compute_track_size(const format &f, int track); + virtual int get_gap2(const format &f, int head, int track) { return f.gap_2; } virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, UINT32 error_offs, desc_s *sectors, int sector_count) const; virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + void extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count); static const format file_formats[]; diff --git a/src/lib/formats/d67_dsk.c b/src/lib/formats/d67_dsk.c deleted file mode 100644 index b512e55b694..00000000000 --- a/src/lib/formats/d67_dsk.c +++ /dev/null @@ -1,56 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/********************************************************************* - - formats/d67_dsk.c - - Commodore 2040 sector disk image format - -*********************************************************************/ - -#include <assert.h> - -#include "formats/d67_dsk.h" - -d67_format::d67_format() : d64_format(file_formats) -{ -} - -const char *d67_format::name() const -{ - return "d67"; -} - -const char *d67_format::description() const -{ - return "Commodore 2040 disk image"; -} - -const char *d67_format::extensions() const -{ - return "d67"; -} - -const d67_format::format d67_format::file_formats[] = { - { // d67, dos 1, 35 tracks, head 48 tpi, stepper 96 tpi - floppy_image::FF_525, floppy_image::SSSD, 690, 35, 1, 256, 9, 8 - }, - {} -}; - -const int d67_format::d67_sectors_per_track[] = -{ - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, // 1-17 - 20, 20, 20, 20, 20, 20, 20, // 18-24 - 18, 18, 18, 18, 18, 18, // 25-30 - 17, 17, 17, 17, 17, // 31-35 - 17, 17, 17, 17, 17, // 36-40 - 17, 17 // 41-42 -}; - -int d67_format::get_sectors_per_track(const format &f, int track) -{ - return d67_sectors_per_track[track]; -} - -const floppy_format_type FLOPPY_D67_FORMAT = &floppy_image_format_creator<d67_format>; diff --git a/src/lib/formats/d67_dsk.h b/src/lib/formats/d67_dsk.h deleted file mode 100644 index c28c1a4d37f..00000000000 --- a/src/lib/formats/d67_dsk.h +++ /dev/null @@ -1,36 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/********************************************************************* - - formats/d67_dsk.h - - Commodore 2040 sector disk image format - -*********************************************************************/ - -#ifndef D67_DSK_H_ -#define D67_DSK_H_ - -#include "d64_dsk.h" - -class d67_format : public d64_format { -public: - d67_format(); - - virtual const char *name() const; - virtual const char *description() const; - virtual const char *extensions() const; - -protected: - virtual int get_sectors_per_track(const format &f, int track); - - static const format file_formats[]; - - static const int d67_sectors_per_track[]; -}; - -extern const floppy_format_type FLOPPY_D67_FORMAT; - - - -#endif diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c index 0f17c7e3b4d..35ab1af359d 100644 --- a/src/lib/formats/flopimg.c +++ b/src/lib/formats/flopimg.c @@ -2366,6 +2366,16 @@ UINT8 floppy_image_format_t::sbyte_mfm_r(const UINT8 *bitstream, int &pos, int t return res; } +UINT8 floppy_image_format_t::sbyte_gcr5_r(const UINT8 *bitstream, int &pos, int track_size) +{ + UINT16 gcr = 0; + for(int i=0; i<10; i++) { + if(sbit_rp(bitstream, pos, track_size)) + gcr |= 0x200 >> i; + } + + return (gcr5bw_tb[gcr >> 5] << 4) | gcr5bw_tb[gcr & 0x1f]; +} void floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size) { @@ -2801,3 +2811,147 @@ void floppy_image_format_t::build_pc_track_mfm(int track, int head, floppy_image generate_track_from_levels(track, head, track_data, 0, image); } + +void floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size, int head, int tracks) +{ + memset(sectors, 0, 256*sizeof(desc_xs)); + + // Don't bother if it's just too small + if(track_size < 100) + return; + + // Start by detecting all id and data blocks + int hblk[100], dblk[100]; + int hblk_count = 0, dblk_count = 0; + + // Precharge the shift register to detect over-the-index stuff + UINT16 shift_reg = 0; + for(int i=0; i<16; i++) + if(sbit_r(bitstream, track_size-16+i)) + shift_reg |= 0x8000 >> i; + + // Scan the bitstream for sync marks and follow them to check for blocks + bool sync = false; + for(int i=0; i<track_size; i++) { + int bit = sbit_r(bitstream, i); + shift_reg = ((shift_reg << 1) | bit) & 0x3ff; + + if (sync && !bit) { + UINT8 id = sbyte_gcr5_r(bitstream, i, track_size); + + switch (id) { + case 0x08: + if(hblk_count < 100) + hblk[hblk_count++] = i-10; + break; + + case 0x07: + if(dblk_count < 100) + dblk[dblk_count++] = i-10; + break; + } + } + + sync = (shift_reg == 0x3ff); + } + + // Then extract the sectors + int sectdata_pos = 0; + for(int i=0; i<hblk_count; i++) { + int pos = hblk[i]; + ATTR_UNUSED UINT8 block_id = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 crc = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 sector = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 track = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 id2 = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 id1 = sbyte_gcr5_r(bitstream, pos, track_size); + + if (crc ^ sector ^ track ^ id2 ^ id1) { + // header crc mismatch + } + + pos = dblk[i]; + block_id = sbyte_gcr5_r(bitstream, pos, track_size); + + if (track > tracks) track -= tracks; + sectors[sector].track = track; + sectors[sector].head = head; + sectors[sector].size = 256; + sectors[sector].data = sectdata + sectdata_pos; + UINT8 data_crc = 0; + for(int j=0; j<sectors[sector].size; j++) { + UINT8 data = sbyte_gcr5_r(bitstream, pos, track_size); + data_crc ^= data; + sectdata[sectdata_pos++] = data; + } + data_crc ^= sbyte_gcr5_r(bitstream, pos, track_size); + if (data_crc) { + // data crc mismatch + } + } +} + +void floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size) +{ + memset(sectors, 0, 256*sizeof(desc_xs)); + + // Don't bother if it's just too small + if(track_size < 100) + return; + + // Start by detecting all id and data blocks + int hblk[100], dblk[100]; + int hblk_count = 0, dblk_count = 0; + + // Precharge the shift register to detect over-the-index stuff + UINT16 shift_reg = 0; + for(int i=0; i<16; i++) + if(sbit_r(bitstream, track_size-16+i)) + shift_reg |= 0x8000 >> i; + + // Scan the bitstream for sync marks and follow them to check for blocks + bool sync = false; + for(int i=0; i<track_size; i++) { + int bit = sbit_r(bitstream, i); + shift_reg = ((shift_reg << 1) | bit) & 0x3ff; + + if (sync && !bit) { + UINT8 id = sbyte_gcr5_r(bitstream, i, track_size); + + switch (id) { + case 0x07: + if(hblk_count < 100) + hblk[hblk_count++] = i-10; + break; + + case 0x08: + if(dblk_count < 100) + dblk[dblk_count++] = i-10; + break; + } + } + + sync = (shift_reg == 0x3ff); + } + + // Then extract the sectors + int sectdata_pos = 0; + for(int i=0; i<hblk_count; i++) { + int pos = hblk[i]; + ATTR_UNUSED UINT8 block_id = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 track = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 sector = sbyte_gcr5_r(bitstream, pos, track_size); + + pos = dblk[i]; + block_id = sbyte_gcr5_r(bitstream, pos, track_size); + + sectors[sector].track = track & 0x7f; + sectors[sector].head = BIT(track, 7); + sectors[sector].size = 512; + sectors[sector].data = sectdata + sectdata_pos; + for(int j=0; j<sectors[sector].size; j++) { + UINT8 data = sbyte_gcr5_r(bitstream, pos, track_size); + sectdata[sectdata_pos++] = data; + } + } +} diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index aaae76530ac..59b652643b6 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -471,6 +471,7 @@ protected: C1541 tr 18-24 3.50 300 3500 C1541 tr 25-30 3.75 300 3750 C1541 tr 31+ 4.00 300 4000 + 8" DD 1 360 1200 5.25" SD 4 300 4000 5.25" DD 2 300 2000 5.25" HD 1 360 1200 @@ -519,6 +520,10 @@ protected: void extract_sectors_from_bitstream_mfm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); //! PC-type sectors with FM encoding void extract_sectors_from_bitstream_fm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); + //! Commodore type sectors with GCR5 encoding + void extract_sectors_from_bitstream_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size, int head, int tracks); + //! Victor 9000 type sectors with GCR5 encoding + void extract_sectors_from_bitstream_victor_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); //! @brief Get a geometry (including sectors) from an image. @@ -572,6 +577,7 @@ protected: void gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc); UINT8 sbyte_mfm_r(const UINT8 *bitstream, int &pos, int track_size); + UINT8 sbyte_gcr5_r(const UINT8 *bitstream, int &pos, int track_size); private: enum { CRC_NONE, CRC_AMIGA, CRC_CBM, CRC_CCITT, CRC_CCITT_FM, CRC_MACHEAD, CRC_FCS, CRC_VICTOR_HDR, CRC_VICTOR_DATA }; diff --git a/src/lib/formats/imd_dsk.c b/src/lib/formats/imd_dsk.c index 463b5b771d2..8600590c735 100644 --- a/src/lib/formats/imd_dsk.c +++ b/src/lib/formats/imd_dsk.c @@ -135,6 +135,91 @@ static floperr_t imd_read_indexed_sector(floppy_image_legacy *floppy, int head, return internal_imd_read_sector(floppy, head, track, sector, TRUE, buffer, buflen); } +static floperr_t imd_expand_file(floppy_image_legacy *floppy , UINT64 offset , size_t amount) +{ + if (amount == 0) { + return FLOPPY_ERROR_SUCCESS; + } + + UINT64 file_size = floppy_image_size(floppy); + + if (offset > file_size) { + return FLOPPY_ERROR_INTERNAL; + } + + UINT64 size_after_off = file_size - offset; + + if (size_after_off == 0) { + return FLOPPY_ERROR_SUCCESS; + } + + UINT8 *buffer = global_alloc_array(UINT8 , size_after_off); + + // Read the part of file after offset + floppy_image_read(floppy , buffer , offset , size_after_off); + + // Add zeroes + floppy_image_write_filler(floppy , 0 , offset , amount); + + // Write back the part of file after offset + floppy_image_write(floppy, buffer, offset + amount, size_after_off); + + global_free_array(buffer); + + // Update track offsets + struct imddsk_tag *tag = get_tag(floppy); + for (int track = 0; track < tag->tracks; track++) { + for (int head = 0; head < tag->heads; head++) { + UINT64 *track_off = &(tag->track_offsets[ (track << 1) + head ]); + if (*track_off >= offset) { + *track_off += amount; + } + } + } + + return FLOPPY_ERROR_SUCCESS; +} + +static floperr_t imd_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam) +{ + UINT64 offset; + floperr_t err; + UINT8 header[1]; + + // take sector offset + err = get_offset(floppy, head, track, sector_index, TRUE, &offset); + if (err) + return err; + + floppy_image_read(floppy, header, offset, 1); + + switch (header[ 0 ]) { + case 0: + return FLOPPY_ERROR_SEEKERROR; + + default: + // Expand image file (from 1 byte to a whole sector) + err = imd_expand_file(floppy , offset , buflen - 1); + if (err) { + return err; + } + // Fall through! + + case 1: + case 3: + case 5: + case 7: + // Turn every kind of sector into type 1 (normal data) + header[ 0 ] = 1; + floppy_image_write(floppy, header, offset, 1); + // Write sector + floppy_image_write(floppy, buffer, offset + 1, buflen); + break; + } + + return FLOPPY_ERROR_SUCCESS; +} + static floperr_t imd_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, UINT32 *sector_length) { floperr_t err; @@ -266,6 +351,7 @@ FLOPPY_CONSTRUCT( imd_dsk_construct ) callbacks = floppy_callbacks(floppy); callbacks->read_sector = imd_read_sector; callbacks->read_indexed_sector = imd_read_indexed_sector; + callbacks->write_indexed_sector = imd_write_indexed_sector; callbacks->get_sector_length = imd_get_sector_length; callbacks->get_heads_per_disk = imd_get_heads_per_disk; callbacks->get_tracks_per_disk = imd_get_tracks_per_disk; diff --git a/src/lib/formats/victor9k_dsk.c b/src/lib/formats/victor9k_dsk.c index 7376b3208a7..21dc6397e8e 100644 --- a/src/lib/formats/victor9k_dsk.c +++ b/src/lib/formats/victor9k_dsk.c @@ -298,14 +298,28 @@ bool victor9k_format::load(io_generic *io, UINT32 form_factor, floppy_image *ima return true; } -bool victor9k_format::supports_save() const +int victor9k_format::get_rpm(int head, int track) { - return false; + return rpm[speed_zone[head][track]]; } -int victor9k_format::get_rpm(int head, int track) +int victor9k_format::get_image_offset(const format &f, int _head, int _track) { - return rpm[speed_zone[head][track]]; + int offset = 0; + if (_head) { + for (int track = 0; track < f.track_count; track++) { + offset += compute_track_size(f, _head, track); + } + } + for (int track = 0; track < _track; track++) { + offset += compute_track_size(f, _head, track); + } + return offset; +} + +int victor9k_format::compute_track_size(const format &f, int head, int track) +{ + return sectors_per_track[head][track] * f.sector_base_size; } const victor9k_format::format victor9k_format::formats[] = { @@ -376,4 +390,49 @@ const int victor9k_format::rpm[9] = 252, 267, 283, 300, 320, 342, 368, 401, 417 }; +bool victor9k_format::save(io_generic *io, floppy_image *image) +{ + const format &f = formats[0]; + + for(int head=0; head < f.head_count; head++) { + for(int track=0; track < f.track_count; track++) { + int sector_count = sectors_per_track[head][track]; + int track_size = compute_track_size(f, head, track); + UINT8 sectdata[40*512]; + desc_s sectors[40]; + int offset = get_image_offset(f, head, track); + + build_sector_description(f, sectdata, 0, sectors, sector_count); + extract_sectors(image, f, sectors, track, head, sector_count); + io_generic_write(io, sectdata, offset, track_size); + } + } + + return true; +} + +void victor9k_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) +{ + UINT8 bitstream[500000/8]; + UINT8 sectdata[50000]; + desc_xs sectors[256]; + int track_size; + + // Extract the sectors + generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], bitstream, track_size, image); + extract_sectors_from_bitstream_victor_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + + for(int i=0; i<sector_count; i++) { + desc_s &ds = sdesc[i]; + desc_xs &xs = sectors[ds.sector_id]; + if(!xs.data) + memset((void *)ds.data, 0, ds.size); + else if(xs.size < ds.size) { + memcpy((void *)ds.data, xs.data, xs.size); + memset((UINT8 *)ds.data + xs.size, 0, xs.size - ds.size); + } else + memcpy((void *)ds.data, xs.data, ds.size); + } +} + const floppy_format_type FLOPPY_VICTOR_9000_FORMAT = &floppy_image_format_creator<victor9k_format>; diff --git a/src/lib/formats/victor9k_dsk.h b/src/lib/formats/victor9k_dsk.h index 22f43fa7e3b..1564f1474f7 100644 --- a/src/lib/formats/victor9k_dsk.h +++ b/src/lib/formats/victor9k_dsk.h @@ -31,13 +31,10 @@ public: virtual const char *description() const; virtual const char *extensions() const; - int find_size(io_generic *io, UINT32 form_factor); virtual int identify(io_generic *io, UINT32 form_factor); - void log_boot_sector(UINT8 *data); - floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count); - void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, desc_s *sectors, int sector_count) const; virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); - virtual bool supports_save() const; + virtual bool save(io_generic *io, floppy_image *image); + virtual bool supports_save() const { return true; } static int get_rpm(int head, int track); @@ -48,6 +45,14 @@ protected: static const int sectors_per_track[2][80]; static const int speed_zone[2][80]; static const int rpm[9]; + + int find_size(io_generic *io, UINT32 form_factor); + void log_boot_sector(UINT8 *data); + floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count); + void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, desc_s *sectors, int sector_count) const; + int get_image_offset(const format &f, int head, int track); + int compute_track_size(const format &f, int head, int track); + void extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count); }; extern const floppy_format_type FLOPPY_VICTOR_9000_FORMAT; diff --git a/src/lib/util/astring.c b/src/lib/util/astring.c deleted file mode 100644 index 7f2b3411adf..00000000000 --- a/src/lib/util/astring.c +++ /dev/null @@ -1,483 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - astring.c - - Allocated string manipulation functions. - -****************************************************************************/ - -#include "astring.h" -#include "osdcore.h" - -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <new> - - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -static const astring dummy_astring; - - - -//************************************************************************** -// INLINE FUNCTIONS -//************************************************************************** - -//------------------------------------------------- -// ensure_room - ensure we have room for a -// given string, or else reallocate our buffer -//------------------------------------------------- - -bool astring::ensure_room(int length) -{ - // always fail to expand the dummy - if (this == &dummy_astring) - return false; - - // if we have the room, do nothing - if (m_alloclen >= length + 1) - return true; - - // allocate a new buffer with some slop - int alloclen = length + 256; - char *newbuf = new char[alloclen]; - - // swap in the new buffer and free the old one - char *oldbuf = (m_text == m_smallbuf) ? NULL : m_text; - m_text = strcpy(newbuf, m_text); - m_len = strlen(m_text); - m_alloclen = alloclen; - delete[] oldbuf; - - return true; -} - - -//------------------------------------------------- -// safe_string_base - return a "safe" string -// base for a given start index -//------------------------------------------------- - -inline char *astring::safe_string_base(int start) const -{ - int max = len(); - return (start >= 0 && start < max) ? m_text + start : m_text + max; -} - - -//------------------------------------------------- -// normalize_substr - normalize substr parameters -//------------------------------------------------- - -inline void astring::normalize_substr(int &start, int &count, int length) const -{ - // limit start - if (start < 0) - start = 0; - else if (start > length) - start = length; - - // update count - if (count == -1 || start + count > length) - count = length - start; -} - - - -//************************************************************************** -// ASTRING ALLOCATION -//************************************************************************** - -//------------------------------------------------- -// init - constructor helper -//------------------------------------------------- - -astring &astring::init() -{ - // initialize ourselves to point to the internal buffer - m_text = m_smallbuf; - m_alloclen = ARRAY_LENGTH(m_smallbuf); - m_smallbuf[0] = 0; - m_len = 0; - return *this; -} - - -//------------------------------------------------- -// ~astring - destructor -//------------------------------------------------- - -astring::~astring() -{ - if (m_text != m_smallbuf) - delete[] m_text; -} - - - -/*************************************************************************** - INLINE ASTRING CHANGES -***************************************************************************/ - -//------------------------------------------------- -// cpy - copy a character array into an astring -//------------------------------------------------- - -astring &astring::cpy(const char *src, int count) -{ - // make room; if we fail or if we are the dummy, do nothing - if (!ensure_room(count)) - return *this; - - // copy the raw data and NULL-terminate - if (count > 0 && m_text != src) - memcpy(m_text, src, count); - m_text[count] = 0; - m_len = count; - return *this; -} - - -//------------------------------------------------- -// cpysubstr - copy a substring of one string to -// another -//------------------------------------------------- - -astring &astring::cpysubstr(const astring &src, int start, int count) -{ - normalize_substr(start, count, src.len()); - return cpy(src.m_text + start, count); -} - - -//------------------------------------------------- -// ins - insert a character array into an astring -//------------------------------------------------- - -astring &astring::ins(int insbefore, const char *src, int count) -{ - // make room; if we fail or if we are the dummy, do nothing - int dstlength = len(); - if (!ensure_room(dstlength + count)) - return *this; - - // adjust insbefore to be logical - if (insbefore < 0 || insbefore > dstlength) - insbefore = dstlength; - - // copy the data an NULL-terminate - if (insbefore < dstlength) - memmove(m_text + insbefore + count, m_text + insbefore, dstlength - insbefore); - memcpy(m_text + insbefore, src, count); - m_text[dstlength + count] = 0; - m_len = dstlength + count; - return *this; -} - - -//------------------------------------------------- -// inssubstr - insert a substring of one string -// into another -//------------------------------------------------- - -astring &astring::inssubstr(int insbefore, const astring &src, int start, int count) -{ - normalize_substr(start, count, src.len()); - return ins(insbefore, src.m_text + start, count); -} - - -//------------------------------------------------- -// substr - extract a substring of ourself, -// removing everything else -//------------------------------------------------- - -astring &astring::substr(int start, int count) -{ - // ignore attempts to do this on the dummy - if (this == &dummy_astring) - return *this; - - // normalize parameters - normalize_substr(start, count, len()); - - // move the data and NULL-terminate - if (count > 0 && start > 0) - memmove(m_text, m_text + start, count); - m_text[count] = 0; - m_len = count; - return *this; -} - - -//------------------------------------------------- -// del - delete a substring of ourself, keeping -// everything else -//------------------------------------------------- - -astring &astring::del(int start, int count) -{ - // ignore attempts to do this on the dummy - if (this == &dummy_astring) - return *this; - - // normalize parameters - int strlength = len(); - normalize_substr(start, count, strlength); - - // move the data and NULL-terminate - if (count > 0) - memmove(m_text + start, m_text + start + count, strlength - (start + count)); - m_text[strlength - count] = 0; - m_len = strlength - count; - return *this; -} - - -//------------------------------------------------- -// vprintf - vprintf text into an astring -//-------------------------------------------------*/ - -int astring::vprintf(const char *format, va_list args) -{ - // sprintf into the temporary buffer - char tempbuf[4096]; - int result = vsprintf(tempbuf, format, args); - - // set the result - cpy(tempbuf); - return result; -} - - -//------------------------------------------------- -// catprintf - formatted vprintf to the end of -// an astring -//------------------------------------------------- - -int astring::catvprintf(const char *format, va_list args) -{ - // sprintf into the temporary buffer - char tempbuf[4096]; - int result = vsprintf(tempbuf, format, args); - - // append the result - cat(tempbuf); - return result; -} - - - -/*************************************************************************** - ASTRING QUERIES -***************************************************************************/ - -//------------------------------------------------- -// cmp - compare a character array to an astring -//------------------------------------------------- - -int astring::cmp(const char *str2, int count) const -{ - // loop while equal until we hit the end of strings - int index; - for (index = 0; index < count; index++) - if (m_text[index] == 0 || m_text[index] != str2[index]) - break; - - // determine the final result - if (index < count) - return m_text[index] - str2[index]; - if (m_text[index] == 0) - return 0; - return 1; -} - - -//------------------------------------------------- -// cmpsubstr - compare a substring to an astring -//------------------------------------------------- - -int astring::cmpsubstr(const astring &str2, int start, int count) const -{ - normalize_substr(start, count, str2.len()); - return cmp(str2.m_text + start, count); -} - - -//------------------------------------------------- -// icmp - compare a character array to an astring -//------------------------------------------------- - -int astring::icmp(const char *str2, int count) const -{ - // loop while equal until we hit the end of strings - int index; - for (index = 0; index < count; index++) - if (m_text[index] == 0 || tolower(m_text[index]) != tolower(str2[index])) - break; - - // determine the final result - if (index < count) - return tolower(m_text[index]) - tolower(str2[index]); - if (m_text[index] == 0) - return 0; - return 1; -} - - -//------------------------------------------------- -// icmpsubstr - compare a substring to an astring -//------------------------------------------------- - -int astring::icmpsubstr(const astring &str2, int start, int count) const -{ - normalize_substr(start, count, str2.len()); - return icmp(str2.m_text + start, count); -} - - -//------------------------------------------------- -// chr - return the index of a character in an -// astring -//------------------------------------------------- - -int astring::chr(int start, int ch) const -{ - char *result = strchr(safe_string_base(start), ch); - return (result != NULL) ? (result - m_text) : -1; -} - - -//------------------------------------------------- -// rchr - return the index of a character in an -// astring, searching from the end -//------------------------------------------------- - -int astring::rchr(int start, int ch) const -{ - char *result = strrchr(safe_string_base(start), ch); - return (result != NULL) ? (result - m_text) : -1; -} - - -//------------------------------------------------- -// find - find a C string in an astring -//-------------------------------------------------*/ - -int astring::find(int start, const char *search) const -{ - char *result = strstr(safe_string_base(start), search); - return (result != NULL) ? (result - m_text) : -1; -} - - -//------------------------------------------------- -// replacec - search in an astring for a C string, -// replacing all instances with another C string -// and returning the number of matches -//------------------------------------------------- - -int astring::replace(int start, const char *search, const char *replace) -{ - int searchlen = strlen(search); - int replacelen = strlen(replace); - int matches = 0; - - for (int curindex = find(start, search); curindex != -1; curindex = find(curindex + replacelen, search)) - { - matches++; - del(curindex, searchlen).ins(curindex, replace); - } - return matches; -} - - - -//************************************************************************** -// ASTRING UTILITIES -//************************************************************************** - -//------------------------------------------------- -// delchr - delete all instances of 'ch' -//------------------------------------------------- - -astring &astring::delchr(int ch) -{ - // simple deletion - char *dst = m_text; - for (char *src = m_text; *src != 0; src++) - if (*src != ch) - *dst++ = *src; - *dst = 0; - m_len = strlen(m_text); - return *this; -} - - -//------------------------------------------------- -// replacechr - replace all instances of 'ch' -// with 'newch' -//------------------------------------------------- - -astring &astring::replacechr(int ch, int newch) -{ - // simple replacement - for (char *text = m_text; *text != 0; text++) - if (*text == ch) - *text = newch; - return *this; -} - - -//------------------------------------------------- -// makeupper - convert string to all upper-case -//------------------------------------------------- - -astring &astring::makeupper() -{ - // just makeupper() on all characters - for (char *text = m_text; *text != 0; text++) - *text = toupper((UINT8)*text); - return *this; -} - - -//------------------------------------------------- -// makelower - convert string to all lower-case -//------------------------------------------------- - -astring &astring::makelower() -{ - // just tolower() on all characters - for (char *text = m_text; *text != 0; text++) - *text = tolower((UINT8)*text); - return *this; -} - - -//------------------------------------------------- -// trimspace - remove all space characters from -// beginning/end -//------------------------------------------------- - -astring &astring::trimspace() -{ - // first remove stuff from the end - for (char *ptr = m_text + len() - 1; ptr >= m_text && (!(*ptr & 0x80) && isspace(UINT8(*ptr))); ptr--) - *ptr = 0; - - // then count how much to remove from the beginning - char *ptr; - for (ptr = m_text; *ptr != 0 && (!(*ptr & 0x80) && isspace(UINT8(*ptr))); ptr++) ; - if (ptr > m_text) - substr(ptr - m_text); - m_len = strlen(m_text); - return *this; -} diff --git a/src/lib/util/astring.h b/src/lib/util/astring.h deleted file mode 100644 index 089ee585dae..00000000000 --- a/src/lib/util/astring.h +++ /dev/null @@ -1,156 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - astring.h - - Allocated string manipulation functions. - -***************************************************************************/ - -#pragma once - -#ifndef __ASTRING_H__ -#define __ASTRING_H__ - -#include <stdarg.h> -#include <ctype.h> -#include "osdcomm.h" - - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// basic allocated string class -class astring -{ -public: - // simple construction/destruction - astring() { init(); } - ~astring(); - - // construction with copy - astring(const char *string) { init(); if(string) cpy(string); } - astring(const char *string, int length) { init().cpy(string, length); } - astring(const astring &string) { init().cpy(string); } - astring(const astring &string, int start, int count = -1) { init().cpysubstr(string, start, count); } - - // assignment operators - astring &operator=(const char *string) { return cpy(string); } - astring &operator=(const astring &string) { return cpy(string); } - - // concatenation operators - astring& operator+=(const astring &string) { return cat(string); } - friend astring operator+(const astring &lhs, const astring &rhs) { return astring(lhs) += rhs; } - friend astring operator+(const astring &lhs, const char *rhs) { return astring(lhs) += rhs; } - friend astring operator+(const char *lhs, const astring &rhs) { return astring(lhs) += rhs; } - - // comparison operators - bool operator==(const char *string) const { return (cmp(string) == 0); } - bool operator==(const astring &string) const { return (cmp(string) == 0); } - bool operator!=(const char *string) const { return (cmp(string) != 0); } - bool operator!=(const astring &string) const { return (cmp(string) != 0); } - bool operator<(const char *string) const { return (cmp(string) < 0); } - bool operator<(const astring &string) const { return (cmp(string) < 0); } - bool operator<=(const char *string) const { return (cmp(string) <= 0); } - bool operator<=(const astring &string) const { return (cmp(string) <= 0); } - bool operator>(const char *string) const { return (cmp(string) > 0); } - bool operator>(const astring &string) const { return (cmp(string) > 0); } - bool operator>=(const char *string) const { return (cmp(string) >= 0); } - bool operator>=(const astring &string) const { return (cmp(string) >= 0); } - - // character access operators - char operator[](int index) const { return (index < len()) ? m_text[index] : 0; } - - // implicit boolean conversion operators - operator bool() { return m_text[0] != 0; } - operator bool() const { return m_text[0] != 0; } - - // C string conversion operators and helpers - const char *c_str() const { return m_text; } - - // buffer management - astring &reset() { return cpy(""); } - astring &expand(int length) { ensure_room(length); return *this; } - - // length query - int len() const { return m_len; } - - // copy helpers - astring &cpy(const char *src, int count); - astring &cpysubstr(const astring &src, int start, int count = -1); - astring &cpy(const astring &src) { return cpy(src.c_str(), src.len()); } - astring &cpy(const char *src) { return cpy(src, strlen(src)); } - - // insertion helpers - astring &ins(int insbefore, const char *src, int count); - astring &inssubstr(int insbefore, const astring &src, int start, int count = -1); - astring &ins(int insbefore, const astring &src) { return ins(insbefore, src.c_str(), src.len()); } - astring &ins(int insbefore, const char *src) { return ins(insbefore, src, strlen(src)); } - - // concatenation helpers (== insert at end) - astring &cat(const char *src, int count) { return ins(-1, src, count); } - astring &catsubstr(const astring &src, int start, int count = -1) { return inssubstr(-1, src, start, count); } - astring &cat(const astring &src) { return ins(-1, src.c_str(), src.len()); } - astring &cat(const char *src) { return ins(-1, src, strlen(src)); } - astring &cat(char ch) { return ins(-1, &ch, 1); } - - // substring helpers - astring &substr(int start, int count = -1); - astring &del(int start, int count = -1); - - // formatted string helpers - int vprintf(const char *format, va_list args); - int catvprintf(const char *format, va_list args); - int printf(const char *format, ...) ATTR_PRINTF(2,3) { va_list ap; va_start(ap, format); int result = this->vprintf(format, ap); va_end(ap); return result; } - int catprintf(const char *format, ...) ATTR_PRINTF(2,3) { va_list ap; va_start(ap, format); int result = catvprintf(format, ap); va_end(ap); return result; } - astring &format(const char *format, ...) ATTR_PRINTF(2,3) { va_list ap; va_start(ap, format); this->vprintf(format, ap); va_end(ap); return *this; } - astring &catformat(const char *format, ...) ATTR_PRINTF(2,3) { va_list ap; va_start(ap, format); catvprintf(format, ap); va_end(ap); return *this; } - - // comparison helpers - int cmp(const char *str2, int count) const; - int cmpsubstr(const astring &str2, int start, int count = -1) const; - int cmp(const astring &str2) const { return cmp(str2.c_str(), str2.len()); } - int cmp(const char *str2) const { return cmp(str2, strlen(str2)); } - - // case-insensitive comparison helpers - int icmp(const char *str2, int count) const; - int icmpsubstr(const astring &str2, int start, int count = -1) const; - int icmp(const astring &str2) const { return icmp(str2.c_str(), str2.len()); } - int icmp(const char *str2) const { return icmp(str2, strlen(str2)); } - - // character searching helpers - int chr(int start, int ch) const; - int rchr(int start, int ch) const; - - // string searching/replacing helpers - int find(int start, const char *search) const; - int find(const char *search) const { return find(0, search); } - int replace(int start, const char *search, const char *replace); - int replace(const char *search, const char *_replace) { return replace(0, search, _replace); } - - // misc utilities - astring &delchr(int ch); - astring &replacechr(int ch, int newch); - astring &makeupper(); - astring &makelower(); - astring &trimspace(); - -private: - // internal helpers - astring &init(); - char *safe_string_base(int start) const; - bool ensure_room(int length); - void normalize_substr(int &start, int &count, int length) const; - - // internal state - char * m_text; - int m_alloclen; - char m_smallbuf[64]; - int m_len; -}; - - -#endif /* __ASTRING_H__ */ diff --git a/src/lib/util/cdrom.c b/src/lib/util/cdrom.c index ce9a0e7b130..6655418583a 100644 --- a/src/lib/util/cdrom.c +++ b/src/lib/util/cdrom.c @@ -811,7 +811,7 @@ const char *cdrom_get_subtype_string(UINT32 subtype) chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) { - astring metadata; + std::string metadata; chd_error err; int i; @@ -983,7 +983,7 @@ chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc) /* write the metadata */ for (i = 0; i < toc->numtrks; i++) { - astring metadata; + std::string metadata; if (!(toc->flags & CD_FLAG_GDROM)) { char submode[32]; @@ -998,7 +998,7 @@ chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc) strcpy(submode, cdrom_get_type_string(toc->tracks[i].pgtype)); } - metadata.format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), + strprintf(metadata, CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].pregap, submode, cdrom_get_subtype_string(toc->tracks[i].pgsub), toc->tracks[i].postgap); @@ -1006,7 +1006,7 @@ chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc) } else { - metadata.format(GDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), + strprintf(metadata, GDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].padframes, toc->tracks[i].pregap, cdrom_get_type_string(toc->tracks[i].pgtype), cdrom_get_subtype_string(toc->tracks[i].pgsub), toc->tracks[i].postgap); diff --git a/src/lib/util/chd.c b/src/lib/util/chd.c index 9c5674e7559..3dd088c0121 100644 --- a/src/lib/util/chd.c +++ b/src/lib/util/chd.c @@ -1039,7 +1039,7 @@ chd_error chd_file::write_bytes(UINT64 offset, const void *buffer, UINT32 bytes) // of the given type //------------------------------------------------- -chd_error chd_file::read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, astring &output) +chd_error chd_file::read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, std::string &output) { // wrap this for clean reporting try @@ -1054,7 +1054,7 @@ chd_error chd_file::read_metadata(chd_metadata_tag searchtag, UINT32 searchindex char* metabuf = new char[metaentry.length+1]; memset(metabuf, 0x00, metaentry.length+1); file_read(metaentry.offset + METADATA_HEADER_SIZE, metabuf, metaentry.length); - output.cpy(metabuf); + output.assign(metabuf); delete[] metabuf; return CHDERR_NONE; } @@ -1409,7 +1409,7 @@ const char *chd_file::error_string(chd_error err) UINT32 chd_file::guess_unitbytes() { // look for hard disk metadata; if found, then the unit size == sector size - astring metadata; + std::string metadata; int i0, i1, i2, i3; if (read_metadata(HARD_DISK_METADATA_TAG, 0, metadata) == CHDERR_NONE && sscanf(metadata.c_str(), HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4) return i3; diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h index 5062ca9c23a..d767c0889e0 100644 --- a/src/lib/util/chd.h +++ b/src/lib/util/chd.h @@ -15,7 +15,8 @@ #include "osdcore.h" #include "coretmpl.h" -#include "astring.h" +#include "corestr.h" +#include <string> #include "bitmap.h" #include "corefile.h" #include "hashing.h" @@ -347,12 +348,12 @@ public: chd_error write_bytes(UINT64 offset, const void *buffer, UINT32 bytes); // metadata management - chd_error read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, astring &output); + chd_error read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, std::string &output); chd_error read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, dynamic_buffer &output); chd_error read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 &resultlen); chd_error read_metadata(chd_metadata_tag searchtag, UINT32 searchindex, dynamic_buffer &output, chd_metadata_tag &resulttag, UINT8 &resultflags); chd_error write_metadata(chd_metadata_tag metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen, UINT8 flags = CHD_MDFLAGS_CHECKSUM); - chd_error write_metadata(chd_metadata_tag metatag, UINT32 metaindex, const astring &input, UINT8 flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, input.c_str(), input.len() + 1, flags); } + chd_error write_metadata(chd_metadata_tag metatag, UINT32 metaindex, const std::string &input, UINT8 flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, input.c_str(), input.length() + 1, flags); } chd_error write_metadata(chd_metadata_tag metatag, UINT32 metaindex, const dynamic_buffer &input, UINT8 flags = CHD_MDFLAGS_CHECKSUM) { return write_metadata(metatag, metaindex, &input[0], input.size(), flags); } chd_error delete_metadata(chd_metadata_tag metatag, UINT32 metaindex); chd_error clone_all_metadata(chd_file &source); diff --git a/src/lib/util/chdcd.c b/src/lib/util/chdcd.c index 0720a6b9aa0..992c95bfeae 100644 --- a/src/lib/util/chdcd.c +++ b/src/lib/util/chdcd.c @@ -38,13 +38,13 @@ static char linebuffer[512]; IMPLEMENTATION ***************************************************************************/ -static astring get_file_path(astring &path) +static std::string get_file_path(std::string &path) { - int pos = path.rchr( 0, '\\'); + int pos = path.find_last_of('\\'); if (pos!=-1) { path = path.substr(0,pos+1); } else { - pos = path.rchr( 0, '/'); + pos = path.find_last_of('/'); path = path.substr(0,pos+1); } return path; @@ -360,7 +360,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_ UINT32 chain_offs, chunk_size; int done = 0; - astring path = astring(tocfname); + std::string path = std::string(tocfname); infile = fopen(tocfname, "rb"); path = get_file_path(path); @@ -437,7 +437,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_ track_end = read_uint64(infile); // printf("Track %d: sector size %d mode %x index0 %llx index1 %llx track_end %llx (pregap %d sectors, length %d sectors)\n", track, size, mode, index0, index1, track_end, (UINT32)(index1-index0)/size, (UINT32)(track_end-index1)/size); - outinfo.track[track-1].fname.cpy(tocfname); + outinfo.track[track-1].fname.assign(tocfname); outinfo.track[track-1].offset = offset + (UINT32)(index1-index0); outinfo.track[track-1].idx0offs = 0; outinfo.track[track-1].idx1offs = 0; @@ -530,7 +530,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_ chd_error chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo) { FILE *infile; - astring path = astring(tocfname); + std::string path = std::string(tocfname); infile = fopen(tocfname, "rb"); path = get_file_path(path); @@ -597,7 +597,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ FILE *infile; int i, numtracks; - astring path = astring(tocfname); + std::string path = std::string(tocfname); infile = fopen(tocfname, "rt"); path = get_file_path(path); @@ -663,7 +663,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ outinfo.track[trknum].swap = true; } - astring name; + std::string name; tok=strtok(NULL," "); name = tok; @@ -675,9 +675,9 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ name += tok; } } while(tok!=NULL && (strrchr(tok,'"')-tok !=(strlen(tok)-1))); - name = name.delchr('"'); + strdelchr(name,'"'); } - outinfo.track[trknum].fname.cpy(path).cat(name); + outinfo.track[trknum].fname.assign(path).append(name); sz = get_file_size(outinfo.track[trknum].fname.c_str()); @@ -717,9 +717,9 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i FILE *infile; int i, trknum; static char token[512]; - astring lastfname; + std::string lastfname; UINT32 wavlen, wavoffs; - astring path = astring(tocfname); + std::string path = std::string(tocfname); infile = fopen(tocfname, "rt"); path = get_file_path(path); @@ -753,7 +753,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i TOKENIZE /* keep the filename */ - lastfname.cpy(path).cat(token); + lastfname.assign(path).append(token); /* get the file type */ TOKENIZE @@ -810,7 +810,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i outinfo.track[trknum].idx0offs = -1; outinfo.track[trknum].idx1offs = 0; - outinfo.track[trknum].fname.cpy(lastfname); // default filename to the last one + outinfo.track[trknum].fname.assign(lastfname); // default filename to the last one // printf("trk %d: fname %s offset %d\n", trknum, outinfo.track[trknum].fname.c_str(), outinfo.track[trknum].offset); @@ -925,7 +925,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i if (trknum == (outtoc.numtrks-1)) { /* if we have the same filename as the last track, do it that way */ - if (trknum != 0 && outinfo.track[trknum].fname == outinfo.track[trknum-1].fname) + if (trknum != 0 && (outinfo.track[trknum].fname.compare(outinfo.track[trknum-1].fname)==0)) { tlen = get_file_size(outinfo.track[trknum].fname.c_str()); if (tlen == 0) @@ -952,7 +952,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i else { /* if we have the same filename as the next track, do it that way */ - if (outinfo.track[trknum].fname == outinfo.track[trknum+1].fname) + if (outinfo.track[trknum].fname.compare(outinfo.track[trknum+1].fname)==0) { outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs; @@ -1028,7 +1028,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i return chdcd_parse_iso(tocfname, outtoc, outinfo); } - astring path = astring(tocfname); + std::string path = std::string(tocfname); infile = fopen(tocfname, "rt"); path = get_file_path(path); @@ -1064,7 +1064,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i TOKENIZE /* keep the filename */ - outinfo.track[trknum].fname.cpy(path).cat(token); + outinfo.track[trknum].fname.assign(path).append(token); /* get either the offset or the length */ TOKENIZE diff --git a/src/lib/util/chdcd.h b/src/lib/util/chdcd.h index d32fc6c0c73..b0f3623ce61 100644 --- a/src/lib/util/chdcd.h +++ b/src/lib/util/chdcd.h @@ -17,9 +17,9 @@ struct chdcd_track_input_entry { chdcd_track_input_entry() { reset(); } - void reset() { fname.reset(); offset = idx0offs = idx1offs = 0; swap = false; } + void reset() { fname.clear(); offset = idx0offs = idx1offs = 0; swap = false; } - astring fname; // filename for each track + std::string fname; // filename for each track UINT32 offset; // offset in the data file for each track bool swap; // data needs to be byte swapped UINT32 idx0offs; diff --git a/src/lib/util/chdcodec.c b/src/lib/util/chdcodec.c index df253489f7e..3a7781fced8 100644 --- a/src/lib/util/chdcodec.c +++ b/src/lib/util/chdcodec.c @@ -1619,7 +1619,7 @@ UINT32 chd_avhuff_compressor::compress(const UINT8 *src, UINT32 srclen, UINT8 *d void chd_avhuff_compressor::postinit() { // get the metadata - astring metadata; + std::string metadata; chd_error err = chd().read_metadata(AV_METADATA_TAG, 0, metadata); if (err != CHDERR_NONE) throw err; diff --git a/src/lib/util/corefile.c b/src/lib/util/corefile.c index 491c35cacbf..4ada0f36aae 100644 --- a/src/lib/util/corefile.c +++ b/src/lib/util/corefile.c @@ -888,7 +888,7 @@ int CLIB_DECL core_fprintf(core_file *f, const char *fmt, ...) assumptions about path separators -------------------------------------------------*/ -astring &core_filename_extract_base(astring &result, const char *name, bool strip_extension) +std::string &core_filename_extract_base(std::string &result, const char *name, bool strip_extension) { /* find the start of the name */ const char *start = name + strlen(name); @@ -896,11 +896,11 @@ astring &core_filename_extract_base(astring &result, const char *name, bool stri start--; /* copy the rest into an astring */ - result.cpy(start); + result.assign(start); /* chop the extension if present */ if (strip_extension) - result.substr(0, result.rchr(0, '.')); + result = result.substr(0, result.find_last_of('.')); return result; } diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h index 07ac491e1f2..42dfd70aef8 100644 --- a/src/lib/util/corefile.h +++ b/src/lib/util/corefile.h @@ -14,7 +14,8 @@ #define __COREFILE_H__ #include <stdarg.h> -#include "astring.h" +#include "corestr.h" +#include <string> #include "coretmpl.h" @@ -121,7 +122,7 @@ int CLIB_DECL core_fprintf(core_file *f, const char *fmt, ...) ATTR_PRINTF(2,3); /* ----- filename utilities ----- */ /* extract the base part of a filename (remove extensions and paths) */ -astring &core_filename_extract_base(astring &result, const char *name, bool strip_extension = false); +std::string &core_filename_extract_base(std::string &result, const char *name, bool strip_extension = false); /* true if the given filename ends with a particular extension */ int core_filename_ends_with(const char *filename, const char *extension); diff --git a/src/lib/util/corestr.c b/src/lib/util/corestr.c index a8e49f9b1f6..8a78a672ac6 100644 --- a/src/lib/util/corestr.c +++ b/src/lib/util/corestr.c @@ -191,3 +191,125 @@ char *core_i64_format(UINT64 value, UINT8 mindigits, bool is_octal) { return is_octal ? core_i64_oct_format(value,mindigits) : core_i64_hex_format(value,mindigits); } + +/*------------------------------------------------- + std::string helpers +-------------------------------------------------*/ + +#include <algorithm> + +int strvprintf(std::string &str, const char *format, va_list args) +{ + char tempbuf[4096]; + int result = vsprintf(tempbuf, format, args); + + // set the result + str.assign(tempbuf); + return result; +} + +int strprintf(std::string &str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + int retVal = strvprintf(str, format, ap); + va_end(ap); + return retVal; +} + +std::string strformat(std::string &str, const char *format, ...) +{ + std::string retVal; + va_list ap; + va_start(ap, format); + strvprintf(str, format, ap); + va_end(ap); + retVal.assign(str); + return retVal; +} + +int strcatvprintf(std::string &str, const char *format, va_list args) +{ + char tempbuf[4096]; + int result = vsprintf(tempbuf, format, args); + + // set the result + str.append(tempbuf); + return result; +} + +int strcatprintf(std::string &str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + int retVal = strcatvprintf(str, format, ap); + va_end(ap); + return retVal; +} + +void strdelchr(std::string& str, char chr) +{ + for (size_t i = 0; i < str.length(); i++) + { + if (str[i] == chr) + { + str.erase(i, 1); + i--; + } + } +} + +void strreplacechr(std::string& str, char ch, char newch) +{ + for (size_t i = 0; i < str.length(); i++) + { + if (str[i] == ch) str[i] = newch; + } +} + +std::string strtrimspace(std::string& str) +{ + int start = 0; + for (size_t i = 0; i < str.length(); i++) + { + if (!isspace(UINT8(str[i]))) break; + start++; + } + int end = str.length(); + if (end > 0) + { + for (size_t i = str.length() - 1; i > 0; i--) + { + if (!isspace(UINT8(str[i]))) break; + end--; + } + } + str = str.substr(start, end-start); + return str; +} + +std::string strmakeupper(std::string& str) +{ + std::transform(str.begin(), str.end(), str.begin(), ::toupper); + return str; +} + +std::string strmakelower(std::string& str) +{ + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + return str; +} + +int strreplace(std::string &str, const std::string& search, const std::string& replace) +{ + int searchlen = search.length(); + int replacelen = replace.length(); + int matches = 0; + + for (int curindex = str.find(search, 0); curindex != -1; curindex = str.find(search, curindex + replacelen)) + { + matches++; + str.erase(curindex, searchlen).insert(curindex, replace); + } + return matches; +} diff --git a/src/lib/util/corestr.h b/src/lib/util/corestr.h index e9750b5f85f..519e1edc849 100644 --- a/src/lib/util/corestr.h +++ b/src/lib/util/corestr.h @@ -62,4 +62,19 @@ char *core_i64_format(UINT64 value, UINT8 mindigits, bool is_octal); char *core_i64_hex_format(UINT64 value, UINT8 mindigits); char *core_i64_oct_format(UINT64 value, UINT8 mindigits); +#include <string> + +int strvprintf(std::string &str, const char *format, va_list args); +int strcatvprintf(std::string &str, const char *format, va_list args); +int strprintf(std::string &str, const char *format, ...) ATTR_PRINTF(2, 3); +int strcatprintf(std::string &str, const char *format, ...) ATTR_PRINTF(2, 3); +std::string strformat(std::string &str, const char *format, ...) ATTR_PRINTF(2, 3); + +void strdelchr(std::string& str, char chr); +void strreplacechr(std::string& str, char ch, char newch); +std::string strtrimspace(std::string& str); +std::string strmakeupper(std::string& str); +std::string strmakelower(std::string& str); +int strreplace(std::string &str, const std::string& search, const std::string& replace); + #endif /* __CORESTR_H__ */ diff --git a/src/lib/util/harddisk.c b/src/lib/util/harddisk.c index 7fce13ca638..4760a5fd51f 100644 --- a/src/lib/util/harddisk.c +++ b/src/lib/util/harddisk.c @@ -40,7 +40,7 @@ hard_disk_file *hard_disk_open(chd_file *chd) { int cylinders, heads, sectors, sectorbytes; hard_disk_file *file; - astring metadata; + std::string metadata; chd_error err; /* punt if no CHD */ diff --git a/src/lib/util/hashing.c b/src/lib/util/hashing.c index d7be3af1427..1481de34a12 100644 --- a/src/lib/util/hashing.c +++ b/src/lib/util/hashing.c @@ -79,11 +79,11 @@ bool sha1_t::from_string(const char *string, int length) // as_string - convert to a string //------------------------------------------------- -const char *sha1_t::as_string(astring &buffer) const +const char *sha1_t::as_string(std::string &buffer) const { - buffer.reset(); + buffer.clear(); for (int i = 0; i < ARRAY_LENGTH(m_raw); i++) - buffer.catformat("%02x", m_raw[i]); + strcatprintf(buffer, "%02x", m_raw[i]); return buffer.c_str(); } @@ -122,11 +122,11 @@ bool md5_t::from_string(const char *string, int length) // as_string - convert to a string //------------------------------------------------- -const char *md5_t::as_string(astring &buffer) const +const char *md5_t::as_string(std::string &buffer) const { - buffer.reset(); + buffer.clear(); for (int i = 0; i < ARRAY_LENGTH(m_raw); i++) - buffer.catformat("%02x", m_raw[i]); + strcatprintf(buffer, "%02x", m_raw[i]); return buffer.c_str(); } @@ -166,9 +166,10 @@ bool crc32_t::from_string(const char *string, int length) // as_string - convert to a string //------------------------------------------------- -const char *crc32_t::as_string(astring &buffer) const +const char *crc32_t::as_string(std::string &buffer) const { - return buffer.format("%08x", m_raw).c_str(); + strprintf(buffer, "%08x", m_raw); + return buffer.c_str(); } @@ -218,9 +219,10 @@ bool crc16_t::from_string(const char *string, int length) // as_string - convert to a string //------------------------------------------------- -const char *crc16_t::as_string(astring &buffer) const +const char *crc16_t::as_string(std::string &buffer) const { - return buffer.format("%04x", m_raw).c_str(); + strprintf(buffer, "%04x", m_raw); + return buffer.c_str(); } diff --git a/src/lib/util/hashing.h b/src/lib/util/hashing.h index 78e02c6e145..b0de6a5c3c8 100644 --- a/src/lib/util/hashing.h +++ b/src/lib/util/hashing.h @@ -14,7 +14,8 @@ #define __HASHING_H__ #include "osdcore.h" -#include "astring.h" +#include "corestr.h" +#include <string> #include "md5.h" #include "sha1.h" @@ -33,7 +34,7 @@ struct sha1_t bool operator!=(const sha1_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } operator UINT8 *() { return m_raw; } bool from_string(const char *string, int length = -1); - const char *as_string(astring &buffer) const; + const char *as_string(std::string &buffer) const; UINT8 m_raw[20]; static const sha1_t null; }; @@ -84,7 +85,7 @@ struct md5_t bool operator!=(const md5_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } operator UINT8 *() { return m_raw; } bool from_string(const char *string, int length = -1); - const char *as_string(astring &buffer) const; + const char *as_string(std::string &buffer) const; UINT8 m_raw[16]; static const md5_t null; }; @@ -135,7 +136,7 @@ struct crc32_t crc32_t &operator=(const UINT32 crc) { m_raw = crc; return *this; } operator UINT32() const { return m_raw; } bool from_string(const char *string, int length = -1); - const char *as_string(astring &buffer) const; + const char *as_string(std::string &buffer) const; UINT32 m_raw; static const crc32_t null; }; @@ -181,7 +182,7 @@ struct crc16_t crc16_t &operator=(const UINT16 crc) { m_raw = crc; return *this; } operator UINT16() const { return m_raw; } bool from_string(const char *string, int length = -1); - const char *as_string(astring &buffer) const; + const char *as_string(std::string &buffer) const; UINT16 m_raw; static const crc16_t null; }; diff --git a/src/lib/util/options.c b/src/lib/util/options.c index f5beddf1d71..d229624017a 100644 --- a/src/lib/util/options.c +++ b/src/lib/util/options.c @@ -13,7 +13,8 @@ #include <ctype.h> #include <assert.h> #include "options.h" -#include "astring.h" +#include "corestr.h" +#include <string> @@ -63,24 +64,24 @@ core_options::entry::entry(const char *name, const char *description, UINT32 fla if (name != NULL) { // first extract any range - astring namestr(name); - int lparen = namestr.chr(0, '('); - int dash = namestr.chr(lparen + 1, '-'); - int rparen = namestr.chr(dash + 1, ')'); + std::string namestr(name); + int lparen = namestr.find_first_of('(',0); + int dash = namestr.find_first_of('-',lparen + 1); + int rparen = namestr.find_first_of(')',dash + 1); if (lparen != -1 && dash != -1 && rparen != -1) { - m_minimum.cpysubstr(namestr, lparen + 1, dash - (lparen + 1)).trimspace(); - m_maximum.cpysubstr(namestr, dash + 1, rparen - (dash + 1)).trimspace(); - namestr.del(lparen, rparen + 1 - lparen); + strtrimspace(m_minimum.assign(namestr.substr(lparen + 1, dash - (lparen + 1)))); + strtrimspace(m_maximum.assign(namestr.substr(dash + 1, rparen - (dash + 1)))); + namestr.erase(lparen, rparen + 1 - lparen); } // then chop up any semicolon-separated names int semi; int nameindex = 0; - while ((semi = namestr.chr(0, ';')) != -1 && nameindex < ARRAY_LENGTH(m_name)) + while ((semi = namestr.find_first_of(';')) != -1 && nameindex < ARRAY_LENGTH(m_name)) { - m_name[nameindex++].cpysubstr(namestr, 0, semi); - namestr.del(0, semi + 1); + m_name[nameindex++].assign(namestr.substr(0, semi)); + namestr.erase(0, semi + 1); } // finally add the last item @@ -332,11 +333,11 @@ void core_options::set_description(const char *name, const char *description) // command line arguments //------------------------------------------------- -bool core_options::parse_command_line(int argc, char **argv, int priority, astring &error_string) +bool core_options::parse_command_line(int argc, char **argv, int priority, std::string &error_string) { // reset the errors and the command - error_string.reset(); - m_command.reset(); + error_string.clear(); + m_command.clear(); // iterate through arguments int unadorned_index = 0; @@ -352,7 +353,7 @@ bool core_options::parse_command_line(int argc, char **argv, int priority, astri entry *curentry = m_entrymap.find(optionname); if (curentry == NULL) { - error_string.catprintf("Error: unknown option: %s\n", curarg); + strcatprintf(error_string, "Error: unknown option: %s\n", curarg); retval = false; if (!is_unadorned) arg++; continue; @@ -362,9 +363,9 @@ bool core_options::parse_command_line(int argc, char **argv, int priority, astri if (curentry->type() == OPTION_COMMAND) { // can only have one command - if (m_command) + if (!m_command.empty()) { - error_string.catprintf("Error: multiple commands specified -%s and %s\n", m_command.c_str(), curarg); + strcatprintf(error_string,"Error: multiple commands specified -%s and %s\n", m_command.c_str(), curarg); return false; } m_command = curentry->name(); @@ -381,7 +382,7 @@ bool core_options::parse_command_line(int argc, char **argv, int priority, astri newdata = argv[++arg]; else { - error_string.catprintf("Error: option %s expected a parameter\n", curarg); + strcatprintf(error_string, "Error: option %s expected a parameter\n", curarg); return false; } @@ -397,7 +398,7 @@ bool core_options::parse_command_line(int argc, char **argv, int priority, astri // an INI file //------------------------------------------------- -bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_priority, astring &error_string) +bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_priority, std::string &error_string) { // loop over lines in the file char buffer[4096]; @@ -422,7 +423,7 @@ bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_p // if we hit the end early, print a warning and continue if (*temp == 0) { - error_string.catprintf("Warning: invalid line in INI: %s", buffer); + strcatprintf(error_string,"Warning: invalid line in INI: %s", buffer); continue; } @@ -446,7 +447,7 @@ bool core_options::parse_ini_file(core_file &inifile, int priority, int ignore_p if (curentry == NULL) { if (priority >= ignore_priority) - error_string.catprintf("Warning: unknown option in INI: %s\n", optionname); + strcatprintf(error_string, "Warning: unknown option in INI: %s\n", optionname); continue; } @@ -476,10 +477,10 @@ void core_options::revert(int priority) // the optional diff //------------------------------------------------- -const char *core_options::output_ini(astring &buffer, const core_options *diff) +const char *core_options::output_ini(std::string &buffer, const core_options *diff) { // INI files are complete, so always start with a blank buffer - buffer.reset(); + buffer.clear(); int num_valid_headers = 0; int unadorned_index = 0; @@ -515,8 +516,8 @@ const char *core_options::output_ini(astring &buffer, const core_options *diff) if (last_header != NULL) { if (num_valid_headers++) - buffer.catprintf("\n"); - buffer.catprintf("#\n# %s\n#\n", last_header); + strcatprintf(buffer,"\n"); + strcatprintf(buffer, "#\n# %s\n#\n", last_header); last_header = NULL; } @@ -524,9 +525,9 @@ const char *core_options::output_ini(astring &buffer, const core_options *diff) if (!is_unadorned) { if (strchr(value, ' ') != NULL) - buffer.catprintf("%-25s \"%s\"\n", name, value); + strcatprintf(buffer,"%-25s \"%s\"\n", name, value); else - buffer.catprintf("%-25s %s\n", name, value); + strcatprintf(buffer,"%-25s %s\n", name, value); } } } @@ -540,21 +541,21 @@ const char *core_options::output_ini(astring &buffer, const core_options *diff) // output_help - output option help to a string //------------------------------------------------- -const char *core_options::output_help(astring &buffer) +const char *core_options::output_help(std::string &buffer) { // start empty - buffer.reset(); + buffer.clear(); // loop over all items for (entry *curentry = m_entrylist.first(); curentry != NULL; curentry = curentry->next()) { // header: just print if (curentry->is_header()) - buffer.catprintf("\n#\n# %s\n#\n", curentry->description()); + strcatprintf(buffer,"\n#\n# %s\n#\n", curentry->description()); // otherwise, output entries for all non-deprecated items else if (curentry->description() != NULL) - buffer.catprintf("-%-20s%s\n", curentry->name(), curentry->description()); + strcatprintf(buffer,"-%-20s%s\n", curentry->name(), curentry->description()); } return buffer.c_str(); } @@ -617,13 +618,13 @@ bool core_options::exists(const char *name) const // set_value - set the raw option value //------------------------------------------------- -bool core_options::set_value(const char *name, const char *value, int priority, astring &error_string) +bool core_options::set_value(const char *name, const char *value, int priority, std::string &error_string) { // find the entry first entry *curentry = m_entrymap.find(name); if (curentry == NULL) { - error_string.catprintf("Attempted to set unknown option %s\n", name); + strcatprintf(error_string, "Attempted to set unknown option %s\n", name); return false; } @@ -631,17 +632,17 @@ bool core_options::set_value(const char *name, const char *value, int priority, return validate_and_set_data(*curentry, value, priority, error_string); } -bool core_options::set_value(const char *name, int value, int priority, astring &error_string) +bool core_options::set_value(const char *name, int value, int priority, std::string &error_string) { - astring tempstr; - tempstr.printf("%d", value); + std::string tempstr; + strprintf(tempstr,"%d", value); return set_value(name, tempstr.c_str(), priority, error_string); } -bool core_options::set_value(const char *name, float value, int priority, astring &error_string) +bool core_options::set_value(const char *name, float value, int priority, std::string &error_string) { - astring tempstr; - tempstr.printf("%f", value); + std::string tempstr; + strprintf(tempstr, "%f", value); return set_value(name, tempstr.c_str(), priority, error_string); } @@ -687,7 +688,7 @@ void core_options::append_entry(core_options::entry &newentry) // for boolean options add a "no" variant as well if (newentry.type() == OPTION_BOOLEAN) - m_entrymap.add(astring("no").cat(newentry.name(name)).c_str(), &newentry); + m_entrymap.add(std::string("no").append(newentry.name(name)).c_str(), &newentry); } } @@ -701,7 +702,7 @@ void core_options::remove_entry(core_options::entry &delentry) { // remove all names from the map for (int name = 0; name < ARRAY_LENGTH(delentry.m_name); name++) - if (delentry.m_name[name]) + if (!delentry.m_name[name].empty()) m_entrymap.remove(delentry.m_name[name].c_str()); // remove the entry from the list @@ -730,17 +731,18 @@ void core_options::copyfrom(const core_options &src) // then set it //------------------------------------------------- -bool core_options::validate_and_set_data(core_options::entry &curentry, const char *newdata, int priority, astring &error_string) +bool core_options::validate_and_set_data(core_options::entry &curentry, const char *newdata, int priority, std::string &error_string) { // trim any whitespace - astring data(newdata); - data.trimspace(); + std::string data(newdata); + strtrimspace(data); + // trim quotes - if (data.chr(0, '"') == 0 && data.rchr(0, '"') == data.len() - 1) + if (data.find_first_of('"') == 0 && data.find_last_of('"') == data.length() - 1) { - data.del(0, 1); - data.del(data.len() - 1, 1); + data.erase(0, 1); + data.erase(data.length() - 1, 1); } // validate the type of data and optionally the range @@ -752,7 +754,7 @@ bool core_options::validate_and_set_data(core_options::entry &curentry, const ch case OPTION_BOOLEAN: if (sscanf(data.c_str(), "%d", &ival) != 1 || ival < 0 || ival > 1) { - error_string.catprintf("Illegal boolean value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); + strcatprintf(error_string, "Illegal boolean value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); return false; } break; @@ -761,12 +763,12 @@ bool core_options::validate_and_set_data(core_options::entry &curentry, const ch case OPTION_INTEGER: if (sscanf(data.c_str(), "%d", &ival) != 1) { - error_string.catprintf("Illegal integer value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); + strcatprintf(error_string, "Illegal integer value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); return false; } if (curentry.has_range() && (ival < atoi(curentry.minimum()) || ival > atoi(curentry.maximum()))) { - error_string.catprintf("Out-of-range integer value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.c_str(), curentry.minimum(), curentry.maximum(), curentry.value()); + strcatprintf(error_string, "Out-of-range integer value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.c_str(), curentry.minimum(), curentry.maximum(), curentry.value()); return false; } break; @@ -775,12 +777,12 @@ bool core_options::validate_and_set_data(core_options::entry &curentry, const ch case OPTION_FLOAT: if (sscanf(data.c_str(), "%f", &fval) != 1) { - error_string.catprintf("Illegal float value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); + strcatprintf(error_string, "Illegal float value for %s: \"%s\"; reverting to %s\n", curentry.name(), data.c_str(), curentry.value()); return false; } if (curentry.has_range() && (fval < atof(curentry.minimum()) || fval > atof(curentry.maximum()))) { - error_string.catprintf("Out-of-range float value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.c_str(), curentry.minimum(), curentry.maximum(), curentry.value()); + strcatprintf(error_string, "Out-of-range float value for %s: \"%s\" (must be between %s and %s); reverting to %s\n", curentry.name(), data.c_str(), curentry.minimum(), curentry.maximum(), curentry.value()); return false; } break; @@ -793,7 +795,7 @@ bool core_options::validate_and_set_data(core_options::entry &curentry, const ch case OPTION_INVALID: case OPTION_HEADER: default: - error_string.catprintf("Attempted to set invalid option %s\n", curentry.name()); + strcatprintf(error_string, "Attempted to set invalid option %s\n", curentry.name()); return false; } diff --git a/src/lib/util/options.h b/src/lib/util/options.h index 1b9528ff433..1ef4636e1e6 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -75,7 +75,7 @@ public: public: // getters entry *next() const { return m_next; } - const char *name(int index = 0) const { return (index < ARRAY_LENGTH(m_name) && m_name[index]) ? m_name[index].c_str() : NULL; } + const char *name(int index = 0) const { return (index < ARRAY_LENGTH(m_name) && !m_name[index].empty()) ? m_name[index].c_str() : NULL; } const char *description() const { return m_description; } const char *value() const { return m_data.c_str(); } const char *default_value() const { return m_defdata.c_str(); } @@ -87,7 +87,7 @@ public: bool is_header() const { return type() == OPTION_HEADER; } bool is_command() const { return type() == OPTION_COMMAND; } bool is_internal() const { return m_flags & OPTION_FLAG_INTERNAL; } - bool has_range() const { return (m_minimum && m_maximum); } + bool has_range() const { return (!m_minimum.empty() && !m_maximum.empty()); } int priority() const { return m_priority; } // setters @@ -105,11 +105,11 @@ public: bool m_error_reported; // have we reported an error on this option yet? int m_priority; // priority of the data set const char * m_description; // description for this item - astring m_name[4]; // up to 4 names for the item - astring m_data; // data for this item - astring m_defdata; // default data for this item - astring m_minimum; // minimum value - astring m_maximum; // maximum value + std::string m_name[4]; // up to 4 names for the item + std::string m_data; // data for this item + std::string m_defdata; // default data for this item + std::string m_minimum; // minimum value + std::string m_maximum; // maximum value }; // construction/destruction @@ -138,15 +138,15 @@ public: void remove_entry(entry &delentry); // parsing/input - bool parse_command_line(int argc, char **argv, int priority, astring &error_string); - bool parse_ini_file(core_file &inifile, int priority, int ignore_priority, astring &error_string); + bool parse_command_line(int argc, char **argv, int priority, std::string &error_string); + bool parse_ini_file(core_file &inifile, int priority, int ignore_priority, std::string &error_string); // reverting void revert(int priority = OPTION_PRIORITY_MAXIMUM); // output - const char *output_ini(astring &buffer, const core_options *diff = NULL); - const char *output_help(astring &buffer); + const char *output_ini(std::string &buffer, const core_options *diff = NULL); + const char *output_help(std::string &buffer); // reading const char *value(const char *option) const; @@ -160,9 +160,9 @@ public: // setting void set_command(const char *command); - bool set_value(const char *name, const char *value, int priority, astring &error_string); - bool set_value(const char *name, int value, int priority, astring &error_string); - bool set_value(const char *name, float value, int priority, astring &error_string); + bool set_value(const char *name, const char *value, int priority, std::string &error_string); + bool set_value(const char *name, int value, int priority, std::string &error_string); + bool set_value(const char *name, float value, int priority, std::string &error_string); void set_flag(const char *name, UINT32 mask, UINT32 flags); // misc @@ -174,12 +174,12 @@ private: void reset(); void append_entry(entry &newentry); void copyfrom(const core_options &src); - bool validate_and_set_data(entry &curentry, const char *newdata, int priority, astring &error_string); + bool validate_and_set_data(entry &curentry, const char *newdata, int priority, std::string &error_string); // internal state simple_list<entry> m_entrylist; // head of list of entries tagmap_t<entry *> m_entrymap; // map for fast lookup - astring m_command; // command found + std::string m_command; // command found static const char *const s_option_unadorned[]; // array of unadorned option "names" }; diff --git a/src/lib/util/tagmap.h b/src/lib/util/tagmap.h index a2b82e2da96..50550f3e6c3 100644 --- a/src/lib/util/tagmap.h +++ b/src/lib/util/tagmap.h @@ -15,7 +15,7 @@ #include "osdcore.h" #include "coretmpl.h" -#include "astring.h" +#include <string> #ifdef MAME_DEBUG #include "eminline.h" #endif @@ -67,7 +67,7 @@ public: m_object(object) { } // accessors - const astring &tag() const { return m_tag; } + const std::string &tag() const { return m_tag; } _ElementType object() const { return m_object; } // setters @@ -81,7 +81,7 @@ public: // internal state entry_t * m_next; UINT32 m_fullhash; - astring m_tag; + std::string m_tag; _ElementType m_object; }; diff --git a/src/lib/util/xmlfile.c b/src/lib/util/xmlfile.c index e03893134f9..8635cfc427f 100644 --- a/src/lib/util/xmlfile.c +++ b/src/lib/util/xmlfile.c @@ -698,7 +698,7 @@ static void expat_data(void *data, const XML_Char *s, int len) if ((*curnode)->value != NULL) { memcpy(newdata, (*curnode)->value, oldlen); - free((*curnode)->value); + free((void *)(*curnode)->value); } (*curnode)->value = newdata; diff --git a/src/lib/util/zippath.c b/src/lib/util/zippath.c index 4872f379135..e4433ac0fc4 100644 --- a/src/lib/util/zippath.c +++ b/src/lib/util/zippath.c @@ -23,7 +23,7 @@ struct zippath_returned_directory { zippath_returned_directory *next; - astring name; + std::string name; }; @@ -48,7 +48,7 @@ public: /* specific to ZIP directories */ bool called_zip_first; zip_file *zipfile; - astring zipprefix; + std::string zipprefix; zippath_returned_directory *returned_dirlist; }; @@ -109,13 +109,19 @@ static void parse_parent_path(const char *path, int *beginpos, int *endpos) zippath_parent - retrieves the parent directory -------------------------------------------------*/ -astring &zippath_parent(astring &dst, const char *path) +std::string &zippath_parent(std::string &dst, const char *path) { int pos; parse_parent_path(path, &pos, NULL); /* return the result */ - return (pos >= 0) ? dst.cpy(path, pos + 1) : dst.reset(); + if (pos >= 0) { + dst.assign(path, pos + 1); + } + else { + dst.clear(); + } + return dst; } @@ -125,12 +131,12 @@ astring &zippath_parent(astring &dst, const char *path) directory basename -------------------------------------------------*/ -astring &zippath_parent_basename(astring &dst, const char *path) +std::string &zippath_parent_basename(std::string &dst, const char *path) { int beginpos, endpos; parse_parent_path(path, &beginpos, &endpos); - - return dst.cpy(path + beginpos + 1, endpos - beginpos); + dst.copy((char*)(path + beginpos + 1), endpos - beginpos); + return dst; } @@ -139,11 +145,11 @@ astring &zippath_parent_basename(astring &dst, const char *path) zippath_combine - combines two paths -------------------------------------------------*/ -astring &zippath_combine(astring &dst, const char *path1, const char *path2) +std::string &zippath_combine(std::string &dst, const char *path1, const char *path2) { if (!strcmp(path2, ".")) { - dst.cpy(path1); + dst.assign(path1); } else if (!strcmp(path2, "..")) { @@ -151,15 +157,15 @@ astring &zippath_combine(astring &dst, const char *path1, const char *path2) } else if (osd_is_absolute_path(path2)) { - dst.cpy(path2); + dst.assign(path2); } else if ((path1[0] != '\0') && !is_path_separator(path1[strlen(path1) - 1])) { - dst.cpy(path1).cat(PATH_SEPARATOR).cat(path2); + dst.assign(path1).append(PATH_SEPARATOR).append(path2); } else { - dst.cpy(path1).cat(path2); + dst.assign(path1).append(path2); } return dst; } @@ -243,7 +249,7 @@ done: zippath_fopen - opens a zip path file -------------------------------------------------*/ -file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, astring &revised_path) +file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path) { file_error filerr = FILERR_NOT_FOUND; zip_error ziperr; @@ -254,13 +260,13 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil int len; /* first, set up the two types of paths */ - astring mainpath(filename); - astring subpath; + std::string mainpath(filename); + std::string subpath; file = NULL; /* loop through */ - while((file == NULL) && (mainpath.len() > 0) - && ((openflags == OPEN_FLAG_READ) || (subpath.len() == 0))) + while((file == NULL) && (mainpath.length() > 0) + && ((openflags == OPEN_FLAG_READ) || (subpath.length() == 0))) { /* is the mainpath a ZIP path? */ if (is_zip_file(mainpath.c_str())) @@ -276,7 +282,7 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil goto done; } - if (subpath.len() > 0) + if (subpath.length() > 0) header = zippath_find_sub_path(zip, subpath.c_str(), &entry_type); else header = zip_file_first_file(zip); @@ -293,8 +299,8 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil goto done; /* update subpath, if appropriate */ - if (subpath.len() == 0) - subpath.cpy(header->filename); + if (subpath.length() == 0) + subpath.assign(header->filename); /* we're done */ goto done; @@ -306,7 +312,7 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil goto done; } - if (subpath.len() == 0) + if (subpath.length() == 0) filerr = core_fopen(filename, openflags, &file); else filerr = FILERR_NOT_FOUND; @@ -315,40 +321,44 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&fil if (filerr != FILERR_NONE) { /* go up a directory */ - astring temp; + std::string temp; zippath_parent(temp, mainpath.c_str()); /* append to the sub path */ - if (subpath.len() > 0) + if (subpath.length() > 0) { - astring temp2; - temp2.cpysubstr(mainpath, temp.len()).cat(PATH_SEPARATOR).cat(subpath); - subpath.cpy(temp2); + std::string temp2; + mainpath = mainpath.substr(temp.length()); + temp2.assign(mainpath).append(PATH_SEPARATOR).append(subpath); + subpath.assign(temp2); } else - subpath.cpysubstr(mainpath, temp.len()); - + { + mainpath = mainpath.substr(temp.length()); + subpath.assign(mainpath); + } /* get the new main path, truncating path separators */ - len = temp.len(); + len = temp.length(); while (len > 0 && is_zip_file_separator(temp[len - 1])) len--; - mainpath.cpysubstr(temp, 0, len); + temp = temp.substr(0, len); + mainpath.assign(temp); } } done: /* store the revised path */ - revised_path.reset(); + revised_path.clear(); if (filerr == FILERR_NONE) { /* cannonicalize mainpath */ filerr = osd_get_full_path(&alloc_fullpath, mainpath.c_str()); if (filerr == FILERR_NONE) { - if (subpath.len() > 0) - revised_path.cpy(alloc_fullpath).cat(PATH_SEPARATOR).cat(subpath); + if (subpath.length() > 0) + revised_path.assign(alloc_fullpath).append(PATH_SEPARATOR).append(subpath); else - revised_path.cpy(alloc_fullpath); + revised_path.assign(alloc_fullpath); } } @@ -534,7 +544,7 @@ static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const cha true path and ZIP entry components -------------------------------------------------*/ -static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, astring &newpath) +static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath) { file_error err; osd_directory_entry *current_entry = NULL; @@ -542,21 +552,22 @@ static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_ty int went_up = FALSE; int i; - newpath.reset(); + newpath.clear(); /* be conservative */ entry_type = ENTTYPE_NONE; zipfile = NULL; - astring apath(path); - astring apath_trimmed; + std::string apath(path); + std::string apath_trimmed; do { /* trim the path of trailing path separators */ - i = apath.len(); + i = apath.length(); while (i > 1 && is_path_separator(apath[i - 1])) i--; - apath_trimmed.cpysubstr(apath, 0, i); + apath = apath.substr(0, i); + apath_trimmed.assign(apath); /* stat the path */ current_entry = osd_stat(apath_trimmed.c_str()); @@ -574,8 +585,8 @@ static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_ty /* if we have not found the file or directory, go up */ current_entry_type = ENTTYPE_NONE; went_up = TRUE; - astring parent; - apath.cpy(zippath_parent(parent, apath.c_str())); + std::string parent; + apath.assign(zippath_parent(parent, apath.c_str())); } } while (current_entry_type == ENTTYPE_NONE && !is_root(apath.c_str())); @@ -591,10 +602,10 @@ static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_ty if ((current_entry_type == ENTTYPE_FILE) && is_zip_file(apath_trimmed.c_str()) && (zip_file_open(apath_trimmed.c_str(), &zipfile) == ZIPERR_NONE)) { - i = strlen(path + apath.len()); - while (i > 0 && is_zip_path_separator(path[apath.len() + i - 1])) + i = strlen(path + apath.length()); + while (i > 0 && is_zip_path_separator(path[apath.length() + i - 1])) i--; - newpath.cpy(path + apath.len(), i); + newpath.assign(path + apath.length(), i); /* this was a true ZIP path - attempt to identify the type of path */ zippath_find_sub_path(zipfile, newpath.c_str(), ¤t_entry_type); @@ -612,7 +623,7 @@ static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_ty err = FILERR_NOT_FOUND; goto done; } - newpath.cpy(path); + newpath.assign(path); } /* success! */ @@ -716,7 +727,7 @@ void zippath_closedir(zippath_directory *directory) static const char *get_relative_path(zippath_directory *directory, const zip_file_header *header) { const char *result = NULL; - int len = directory->zipprefix.len(); + int len = directory->zipprefix.length(); if ((len <= strlen(header->filename)) && !strncmp(directory->zipprefix.c_str(), header->filename, len)) @@ -807,7 +818,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory) /* we've found a new directory; add this to returned_dirlist */ rdent = new zippath_returned_directory; rdent->next = directory->returned_dirlist; - rdent->name.cpy(relpath, separator - relpath); + rdent->name.assign(relpath, separator - relpath); directory->returned_dirlist = rdent; /* ...and return it */ diff --git a/src/lib/util/zippath.h b/src/lib/util/zippath.h index 12c7546ae9a..ff79409f0e8 100644 --- a/src/lib/util/zippath.h +++ b/src/lib/util/zippath.h @@ -12,7 +12,7 @@ #define __ZIPPATH_H__ #include "corefile.h" -#include "astring.h" +#include <string> #include "unzip.h" @@ -31,19 +31,19 @@ class zippath_directory; /* ----- path operations ----- */ /* retrieves the parent directory */ -astring &zippath_parent(astring &dst, const char *path); +std::string &zippath_parent(std::string &dst, const char *path); /* retrieves the parent directory basename */ -astring &zippath_parent_basename(astring &dst, const char *path); +std::string &zippath_parent_basename(std::string &dst, const char *path); /* combines two paths */ -astring &zippath_combine(astring &dst, const char *path1, const char *path2); +std::string &zippath_combine(std::string &dst, const char *path1, const char *path2); /* ----- file operations ----- */ /* opens a zip path file */ -file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, astring &revised_path); +file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path); /* ----- directory operations ----- */ |