summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2021-09-15 21:25:21 -0400
committer AJR <ajrhacker@users.noreply.github.com>2021-09-15 21:26:26 -0400
commit43133765c1f5c0c72850a99ba708e328bf8b0d7e (patch)
tree2917e5d4fbd6b63ce01b6b875d38df5c9d620fba /src/lib/util
parentcaa9d4654e2fc5e94d5489d9ed662307926850c3 (diff)
Convert JED, PLA and JEDBIN parsers to (mostly) use ioprocs instead of raw memory interfaces
Diffstat (limited to 'src/lib/util')
-rw-r--r--src/lib/util/jedparse.cpp92
-rw-r--r--src/lib/util/jedparse.h6
-rw-r--r--src/lib/util/plaparse.cpp268
-rw-r--r--src/lib/util/plaparse.h2
4 files changed, 201 insertions, 167 deletions
diff --git a/src/lib/util/jedparse.cpp b/src/lib/util/jedparse.cpp
index d25b35c3328..f883aa747b9 100644
--- a/src/lib/util/jedparse.cpp
+++ b/src/lib/util/jedparse.cpp
@@ -16,11 +16,14 @@
***************************************************************************/
+#include "jedparse.h"
+
+#include "ioprocs.h"
+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
-#include "jedparse.h"
@@ -187,52 +190,68 @@ static void process_field(jed_data *data, const uint8_t *cursrc, const uint8_t *
loaded raw into memory
-------------------------------------------------*/
-int jed_parse(const void *data, size_t length, jed_data *result)
+int jed_parse(util::random_read &src, jed_data *result)
{
- const auto *cursrc = (const uint8_t *)data;
- const uint8_t *srcend = cursrc + length;
- const uint8_t *scan;
jed_parse_info pinfo;
- uint16_t checksum;
int i;
+ uint64_t actual;
/* initialize the output and the intermediate info struct */
memset(result, 0, sizeof(*result));
memset(&pinfo, 0, sizeof(pinfo));
/* first scan for the STX character; ignore anything prior */
- while (cursrc < srcend && *cursrc != 0x02)
- cursrc++;
- if (cursrc >= srcend)
- return JEDERR_INVALID_DATA;
+ uint8_t ch;
+ do
+ {
+ if (src.read(&ch, 1, actual) || actual != 1)
+ return JEDERR_INVALID_DATA;
+ }
+ while (ch != 0x02);
/* then scan to see if we have an ETX */
- scan = cursrc;
- checksum = 0;
- while (scan < srcend && *scan != 0x03)
- checksum += *scan++ & 0x7f;
- if (scan >= srcend)
+ uint64_t startpos = 0;
+ uint16_t checksum = ch;
+ do
+ {
+ if (src.read(&ch, 1, actual) || actual != 1)
+ return JEDERR_INVALID_DATA;
+ checksum += ch & 0x7f;
+
+ /* mark end of comment field */
+ if (ch == '*' && startpos == 0)
+ {
+ if (src.tell(startpos))
+ return JEDERR_INVALID_DATA;
+ }
+ }
+ while (ch != 0x03);
+
+ /* the ETX becomes the real srcend */
+ uint64_t endpos;
+ if (src.tell(endpos))
return JEDERR_INVALID_DATA;
+ endpos--;
/* see if there is a transmission checksum at the end */
- checksum += *scan;
- if (scan + 4 < srcend && ishex(scan[1]) && ishex(scan[2]) && ishex(scan[3]) && ishex(scan[4]))
+ uint8_t sumbuf[4];
+ if (!src.read(&sumbuf[0], 4, actual) && actual == 4 && ishex(sumbuf[0]) && ishex(sumbuf[1]) && ishex(sumbuf[2]) && ishex(sumbuf[3]))
{
- uint16_t dessum = (hexval(scan[1]) << 12) | (hexval(scan[2]) << 8) | (hexval(scan[3]) << 4) | hexval(scan[4] << 0);
+ uint16_t dessum = (hexval(sumbuf[0]) << 12) | (hexval(sumbuf[1]) << 8) | (hexval(sumbuf[2]) << 4) | hexval(sumbuf[3] << 0);
if (dessum != 0 && dessum != checksum)
return JEDERR_BAD_XMIT_SUM;
}
- /* the ETX becomes the real srcend */
- srcend = scan;
-
/* blast through the comment field */
- cursrc++;
- while (cursrc < srcend && *cursrc != '*')
- cursrc++;
+ if (startpos == 0 || src.seek(startpos, SEEK_SET))
+ return JEDERR_INVALID_DATA;
+ auto srcdata = std::make_unique<uint8_t[]>(endpos - startpos);
+ if (src.read(&srcdata[0], endpos - startpos, actual) || actual != endpos - startpos)
+ return JEDERR_INVALID_DATA;
+ const uint8_t *cursrc = &srcdata[0];
+ const uint8_t *const srcend = &srcdata[endpos - startpos];
/* now loop over fields and decide which ones go in the file output */
- cursrc++;
while (cursrc < srcend)
{
/* skip over delimiters */
@@ -242,7 +261,7 @@ int jed_parse(const void *data, size_t length, jed_data *result)
break;
/* end of field is an asterisk -- find it */
- scan = cursrc;
+ const uint8_t *scan = cursrc;
while (scan < srcend && *scan != '*')
scan++;
if (scan >= srcend)
@@ -255,11 +274,13 @@ int jed_parse(const void *data, size_t length, jed_data *result)
cursrc = scan + 1;
}
+ srcdata.reset();
+
/* if we got an explicit fuse count, override our computed count */
if (pinfo.explicit_numfuses != 0)
result->numfuses = pinfo.explicit_numfuses;
- /* clear out leftover bits */
+ /* clear out leftover bits g*/
if (result->numfuses % 8 != 0)
result->fusemap[result->numfuses / 8] &= (1 << (result->numfuses % 8)) - 1;
memset(&result->fusemap[(result->numfuses + 7) / 8], 0, sizeof(result->fusemap) - (result->numfuses + 7) / 8);
@@ -377,29 +398,26 @@ size_t jed_output(const jed_data *data, void *result, size_t length)
has been loaded raw into memory
-------------------------------------------------*/
-int jedbin_parse(const void *data, size_t length, jed_data *result)
+int jedbin_parse(util::read_stream &src, jed_data *result)
{
- const auto *cursrc = (const uint8_t *)data;
-
/* initialize the output */
memset(result, 0, sizeof(*result));
/* need at least 4 bytes */
- if (length < 4)
+ uint8_t buf[4];
+ uint64_t actual;
+ if (src.read(&buf[0], 4, actual) || actual != 4)
return JEDERR_INVALID_DATA;
/* first unpack the number of fuses */
- result->numfuses = (cursrc[0] << 24) | (cursrc[1] << 16) | (cursrc[2] << 8) | cursrc[3];
- cursrc += 4;
+ result->numfuses = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
if (result->numfuses == 0 || result->numfuses > JED_MAX_FUSES)
return JEDERR_INVALID_DATA;
/* now make sure we have enough data in the source */
- if (length < 4 + (result->numfuses + 7) / 8)
- return JEDERR_INVALID_DATA;
-
/* copy in the data */
- memcpy(result->fusemap, cursrc, (result->numfuses + 7) / 8);
+ if (src.read(result->fusemap, (result->numfuses + 7) / 8, actual) || actual != (result->numfuses + 7) / 8)
+ return JEDERR_INVALID_DATA;
return JEDERR_NONE;
}
diff --git a/src/lib/util/jedparse.h b/src/lib/util/jedparse.h
index 606daa318bd..c2ffe7942bc 100644
--- a/src/lib/util/jedparse.h
+++ b/src/lib/util/jedparse.h
@@ -13,6 +13,8 @@
#pragma once
+#include "utilfwd.h"
+
#include <cstddef>
#include <cstdint>
@@ -49,13 +51,13 @@ struct jed_data
***************************************************************************/
/* parse a file (read into memory) into a jed_data structure */
-int jed_parse(const void *data, size_t length, jed_data *result);
+int jed_parse(util::random_read &src, jed_data *result);
/* output a jed_data structure into a well-formatted JED file */
size_t jed_output(const jed_data *data, void *result, size_t length);
/* parse a binary JED file (read into memory) into a jed_data structure */
-int jedbin_parse(const void *data, size_t length, jed_data *result);
+int jedbin_parse(util::read_stream &src, jed_data *result);
/* output a jed_data structure into a binary JED file */
size_t jedbin_output(const jed_data *data, void *result, size_t length);
diff --git a/src/lib/util/plaparse.cpp b/src/lib/util/plaparse.cpp
index 09b7724375e..a085a27b635 100644
--- a/src/lib/util/plaparse.cpp
+++ b/src/lib/util/plaparse.cpp
@@ -12,6 +12,8 @@
#include "plaparse.h"
+#include "ioprocs.h"
+
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -61,19 +63,27 @@ static bool iscrlf(char c)
character stream
-------------------------------------------------*/
-static uint32_t suck_number(const uint8_t **src, const uint8_t *srcend)
+static uint32_t suck_number(util::random_read &src)
{
uint32_t value = 0;
// find first digit
- while (*src < srcend && !iscrlf(**src) && !isdigit(**src))
- (*src)++;
-
- // loop over and accumulate digits
- while (*src < srcend && isdigit(**src))
+ uint8_t ch;
+ uint64_t actual;
+ bool found = false;
+ while (!src.read(&ch, 1, actual) && actual == 1)
{
- value = value * 10 + (**src) - '0';
- (*src)++;
+ // loop over and accumulate digits
+ if (isdigit(ch))
+ {
+ found = true;
+ value = value * 10 + ch - '0';
+ }
+ else if (found || iscrlf(ch))
+ {
+ src.seek(-1, SEEK_CUR);
+ break;
+ }
}
return value;
@@ -89,7 +99,7 @@ static uint32_t suck_number(const uint8_t **src, const uint8_t *srcend)
process_terms - process input/output matrix
-------------------------------------------------*/
-static bool process_terms(jed_data *data, const uint8_t **src, const uint8_t *srcend, parse_info *pinfo)
+static bool process_terms(jed_data *data, util::random_read &src, uint8_t &ch, parse_info *pinfo)
{
uint32_t curinput = 0;
uint32_t curoutput = 0;
@@ -99,65 +109,65 @@ static bool process_terms(jed_data *data, const uint8_t **src, const uint8_t *sr
// PLA format documentation also describes them as simply 0, 1, 2, 3
static const char symbols[] = { "01-~" };
- while (*src < srcend && **src != '.' && **src != '#')
+ while (ch != '.' && ch != '#')
{
if (!outputs)
{
// and-matrix
- if (strrchr(symbols, **src))
+ if (strrchr(symbols, ch))
curinput++;
- switch (**src)
+ switch (ch)
{
- case '0':
- jed_set_fuse(data, data->numfuses++, 0);
- jed_set_fuse(data, data->numfuses++, 1);
+ case '0':
+ jed_set_fuse(data, data->numfuses++, 0);
+ jed_set_fuse(data, data->numfuses++, 1);
- if (LOG_PARSE) printf("01");
- break;
+ if (LOG_PARSE) printf("01");
+ break;
- case '1':
- jed_set_fuse(data, data->numfuses++, 1);
- jed_set_fuse(data, data->numfuses++, 0);
+ case '1':
+ jed_set_fuse(data, data->numfuses++, 1);
+ jed_set_fuse(data, data->numfuses++, 0);
- if (LOG_PARSE) printf("10");
- break;
+ if (LOG_PARSE) printf("10");
+ break;
- // anything goes
- case '-':
- jed_set_fuse(data, data->numfuses++, 1);
- jed_set_fuse(data, data->numfuses++, 1);
+ // anything goes
+ case '-':
+ jed_set_fuse(data, data->numfuses++, 1);
+ jed_set_fuse(data, data->numfuses++, 1);
- if (LOG_PARSE) printf("11");
- break;
+ if (LOG_PARSE) printf("11");
+ break;
- // this product term is inhibited
- case '~':
- jed_set_fuse(data, data->numfuses++, 0);
- jed_set_fuse(data, data->numfuses++, 0);
+ // this product term is inhibited
+ case '~':
+ jed_set_fuse(data, data->numfuses++, 0);
+ jed_set_fuse(data, data->numfuses++, 0);
- if (LOG_PARSE) printf("00");
- break;
+ if (LOG_PARSE) printf("00");
+ break;
- case ' ': case '\t':
- if (curinput > 0)
- {
- outputs = true;
- if (LOG_PARSE) printf(" ");
- }
- break;
+ case ' ': case '\t':
+ if (curinput > 0)
+ {
+ outputs = true;
+ if (LOG_PARSE) printf(" ");
+ }
+ break;
- default:
- break;
+ default:
+ break;
}
}
else
{
// or-matrix
- if (strrchr(symbols, **src))
+ if (strrchr(symbols, ch))
{
curoutput++;
- if (**src == '1')
+ if (ch == '1')
{
jed_set_fuse(data, data->numfuses++, 0);
if (LOG_PARSE) printf("0");
@@ -171,7 +181,7 @@ static bool process_terms(jed_data *data, const uint8_t **src, const uint8_t *sr
}
}
- if (iscrlf(**src) && outputs)
+ if (iscrlf(ch) && outputs)
{
outputs = false;
if (LOG_PARSE) printf("\n");
@@ -183,7 +193,14 @@ static bool process_terms(jed_data *data, const uint8_t **src, const uint8_t *sr
curoutput = 0;
}
- (*src)++;
+ uint64_t actual;
+ if (src.read(&ch, 1, actual))
+ return false;
+ if (actual != 1)
+ {
+ ch = 0;
+ break;
+ }
}
return true;
@@ -195,7 +212,7 @@ static bool process_terms(jed_data *data, const uint8_t **src, const uint8_t *sr
process_field - process a single field
-------------------------------------------------*/
-static bool process_field(jed_data *data, const uint8_t **src, const uint8_t *srcend, parse_info *pinfo)
+static bool process_field(jed_data *data, util::random_read &src, parse_info *pinfo)
{
// valid keywords
static const char *const keywords[] = { "i", "o", "p", "phase", "e", "\0" };
@@ -213,14 +230,15 @@ static bool process_field(jed_data *data, const uint8_t **src, const uint8_t *sr
// find keyword
char dest[0x10];
memset(dest, 0, sizeof(dest));
- const uint8_t *seek = *src;
int destptr = 0;
- while (seek < srcend && isalpha(*seek) && destptr < sizeof(dest) - 1)
+ uint8_t seek;
+ uint64_t actual;
+ while (!src.read(&seek, 1, actual) && actual == 1 && isalpha(seek))
{
- dest[destptr] = tolower(*seek);
- seek++;
- destptr++;
+ dest[destptr++] = tolower(seek);
+ if (destptr == sizeof(dest))
+ break;
}
uint8_t find = 0;
@@ -230,58 +248,55 @@ static bool process_field(jed_data *data, const uint8_t **src, const uint8_t *sr
if (find == KW_INVALID)
return false;
- (*src) += strlen(keywords[find]);
-
// handle it
switch (find)
{
- // number of inputs
- case KW_INPUTS:
- pinfo->inputs = suck_number(src, srcend);
- if (pinfo->inputs == 0 || pinfo->inputs >= (JED_MAX_FUSES/2))
- return false;
-
- if (LOG_PARSE) printf("Inputs: %u\n", pinfo->inputs);
- break;
-
- // number of outputs
- case KW_OUTPUTS:
- pinfo->outputs = suck_number(src, srcend);
- if (pinfo->outputs == 0 || pinfo->outputs >= (JED_MAX_FUSES/2))
- return false;
-
- if (LOG_PARSE) printf("Outputs: %u\n", pinfo->outputs);
- break;
-
- // number of product terms (optional)
- case KW_TERMS:
- pinfo->terms = suck_number(src, srcend);
- if (pinfo->terms == 0 || pinfo->terms >= (JED_MAX_FUSES/2))
- return false;
-
- if (LOG_PARSE) printf("Terms: %u\n", pinfo->terms);
- break;
-
- // output polarity (optional)
- case KW_PHASE:
- if (LOG_PARSE) printf("Phase...\n");
- while (*src < srcend && !iscrlf(**src) && pinfo->xorptr < (JED_MAX_FUSES/2))
+ // number of inputs
+ case KW_INPUTS:
+ pinfo->inputs = suck_number(src);
+ if (pinfo->inputs == 0 || pinfo->inputs >= (JED_MAX_FUSES/2))
+ return false;
+
+ if (LOG_PARSE) printf("Inputs: %u\n", pinfo->inputs);
+ break;
+
+ // number of outputs
+ case KW_OUTPUTS:
+ pinfo->outputs = suck_number(src);
+ if (pinfo->outputs == 0 || pinfo->outputs >= (JED_MAX_FUSES/2))
+ return false;
+
+ if (LOG_PARSE) printf("Outputs: %u\n", pinfo->outputs);
+ break;
+
+ // number of product terms (optional)
+ case KW_TERMS:
+ pinfo->terms = suck_number(src);
+ if (pinfo->terms == 0 || pinfo->terms >= (JED_MAX_FUSES/2))
+ return false;
+
+ if (LOG_PARSE) printf("Terms: %u\n", pinfo->terms);
+ break;
+
+ // output polarity (optional)
+ case KW_PHASE:
+ if (LOG_PARSE) printf("Phase...\n");
+ while (!src.read(&seek, 1, actual) && actual == 1 && !iscrlf(seek) && pinfo->xorptr < (JED_MAX_FUSES/2))
+ {
+ if (seek == '0' || seek == '1')
{
- if (**src == '0' || **src == '1')
- {
- // 0 is negative
- if (**src == '0')
- pinfo->xorval[pinfo->xorptr/32] |= 1 << (pinfo->xorptr & 31);
- pinfo->xorptr++;
- }
- (*src)++;
+ // 0 is negative
+ if (seek == '0')
+ pinfo->xorval[pinfo->xorptr/32] |= 1 << (pinfo->xorptr & 31);
+ pinfo->xorptr++;
}
- break;
+ }
+ break;
- // end of file (optional)
- case KW_END:
- if (LOG_PARSE) printf("End of file\n");
- break;
+ // end of file (optional)
+ case KW_END:
+ if (LOG_PARSE) printf("End of file\n");
+ break;
}
return true;
@@ -295,54 +310,53 @@ static bool process_field(jed_data *data, const uint8_t **src, const uint8_t *sr
-------------------------------------------------*/
/**
- * @fn int pla_parse(const void *data, size_t length, jed_data *result)
+ * @fn int pla_parse(util::random_read &src, jed_data *result)
*
* @brief Pla parse.
*
- * @param data The data.
- * @param length The length.
+ * @param src The source file.
* @param [out] result If non-null, the result.
*
* @return An int.
*/
-int pla_parse(const void *data, size_t length, jed_data *result)
+int pla_parse(util::random_read &src, jed_data *result)
{
- const auto *src = (const uint8_t *)data;
- const uint8_t *srcend = src + length;
-
parse_info pinfo;
memset(&pinfo, 0, sizeof(pinfo));
result->numfuses = 0;
memset(result->fusemap, 0, sizeof(result->fusemap));
- while (src < srcend)
+ uint8_t ch;
+ uint64_t actual;
+ while (!src.read(&ch, 1, actual) && actual == 1)
{
- switch (*src)
+ switch (ch)
{
- // comment line
- case '#':
- while (src < srcend && !iscrlf(*src))
- src++;
- break;
+ // comment line
+ case '#':
+ while (!src.read(&ch, 1, actual) && actual == 1)
+ {
+ if (iscrlf(ch))
+ break;
+ }
+ break;
- // keyword
- case '.':
- src++;
- if (!process_field(result, &src, srcend, &pinfo))
- return JEDERR_INVALID_DATA;
- break;
+ // keyword
+ case '.':
+ if (!process_field(result, src, &pinfo))
+ return JEDERR_INVALID_DATA;
+ break;
- // terms
- case '0': case '1': case '-': case '~':
- if (!process_terms(result, &src, srcend, &pinfo))
- return JEDERR_INVALID_DATA;
- break;
+ // terms
+ case '0': case '1': case '-': case '~':
+ if (!process_terms(result, src, ch, &pinfo))
+ return JEDERR_INVALID_DATA;
+ continue;
- default:
- src++;
- break;
+ default:
+ break;
}
}
diff --git a/src/lib/util/plaparse.h b/src/lib/util/plaparse.h
index 779a80f126b..fa430a92e09 100644
--- a/src/lib/util/plaparse.h
+++ b/src/lib/util/plaparse.h
@@ -21,6 +21,6 @@
***************************************************************************/
/* parse a file (read into memory) into a jed_data structure */
-int pla_parse(const void *data, size_t length, jed_data *result);
+int pla_parse(util::random_read &src, jed_data *result);
#endif // MAME_UTIL_PLAPARSE_H