Index: work/alien_formats/altium/pcbdoc_ascii.h =================================================================== --- work/alien_formats/altium/pcbdoc_ascii.h (revision 35453) +++ work/alien_formats/altium/pcbdoc_ascii.h (revision 35454) @@ -6,6 +6,8 @@ static inline long ucdf_fread(ucdf_file_t *fp, char *dst, long len) { + if (feof(fp)) + return 0; return fread(dst, 1, len, fp); } Index: work/alien_formats/altium/pcbdoc_bin.c =================================================================== --- work/alien_formats/altium/pcbdoc_bin.c (revision 35453) +++ work/alien_formats/altium/pcbdoc_bin.c (revision 35454) @@ -1,10 +1,84 @@ +#include #include "pcbdoc_ascii.h" #include "pcbdoc_bin.h" +#warning remove: +#include + +#define MAX_REC_LEN (1UL << 20) + +/* convert a file integer (len bytes wide) into a native integer, assuming source is little-endian */ +static long load_int(unsigned const char *src, int len) +{ + int n, sh; + long tmp, res = 0; + + for(sh = n = 0; n < len; n++,sh += 8,src++) { + tmp = *src; + tmp = (tmp << sh); + res |= tmp; + } + + /* "sign extend" */ + if (res >= (1UL << (len*8-1))) + res = -((1UL << (len*8)) - res); + + return res; +} + +#define buf_grow(tmp, len) \ +do { \ + if (tmp->alloced < len) { \ + free(tmp->data); \ + tmp->data = malloc(len); \ + if (tmp->data == NULL) { \ + tmp->alloced = 0; \ + return -1; \ + } \ + tmp->alloced = len; \ + } \ +} while(0) + +static long read_rec_l4b(ucdf_file_t *fp, altium_buf_t *tmp) +{ + unsigned char lens[4]; + long len, res; + + if (ucdf_fread(fp, (void *)lens, 4) != 4) + return -1; + + len = load_int(lens, 4); + if ((len < 0) || (len >= MAX_REC_LEN)) + return -1; + + buf_grow(tmp, len+1); + res = ucdf_fread(fp, (void *)tmp->data, len); + if (res == 0) + return 0; + + if (res != len) + return -1; + + tmp->data[len] = '\0'; /* safety: always make it a valid string just in case it is text */ + + return len; +} + +static int pcbdoc_bin_parse_ascii(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *record, const char *fields) +{ +#warning TODO + return 0; +} + int pcbdoc_bin_parse_board6(rnd_hidlib_t *hidlib, altium_tree_t *tree, ucdf_file_t *fp, altium_buf_t *tmp) { - - return -1; + for(;;) { + long len = read_rec_l4b(fp, tmp); + if (len <= 0) + return len; + if (pcbdoc_bin_parse_ascii(hidlib, tree, "BOARD", (char *)tmp->data) != 0) + return -1; + } }