Index: altium_parser/main.c =================================================================== --- altium_parser/main.c (revision 35272) +++ altium_parser/main.c (revision 35273) @@ -6,6 +6,7 @@ { const char *fn = "A.PcbDoc"; FILE *f; + altium_tree_t tree = {0}; f = fopen(fn, "r"); if (f == NULL) { @@ -18,5 +19,11 @@ return -1; } + if (pcbdoc_ascii_parse_file(NULL, &tree, fn) != 0) { + fprintf(stderr, "failed to parse '%s'\n", fn); + return -1; + } + + return 0; -} \ No newline at end of file +} Index: altium_parser/pcbdoc_ascii.c =================================================================== --- altium_parser/pcbdoc_ascii.c (revision 35272) +++ altium_parser/pcbdoc_ascii.c (revision 35273) @@ -33,6 +33,8 @@ #include "pcbdoc_ascii.h" +#define block_size 65536L + int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f) { char line[256], *s; @@ -53,3 +55,100 @@ return 1; } + +static int pcbdoc_ascii_load_blocks(altium_tree_t *tree, FILE *f, long max) +{ + long curr = 0, next; + + for(;;) { + int c; + altium_block_t *blk; + + /* seek at potential end-of-block */ + next = curr + block_size; + if (next > max-1) + next = max-1; + fseek(f, next, SEEK_SET); + + /* seek first record separator (or eof) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + next++; + if ((c == '\r') || (c == '\n')) + break; + } + + if (c != EOF) { + /* seek end of record separator section (typica: \r\n) */ + for(;;) { + c = fgetc(f); + if (c == EOF) + break; + if ((c != '\r') && (c != '\n')) + break; + next++; + } + } + + if (next == curr) + break; + + /* by now "next" points to the first character of the next block */ + blk = malloc(sizeof(altium_block_t) + (next-curr)); + if (blk == NULL) { + fprintf(stderr, "pcbdoc_ascii_load_blocks: failed to alloc memory\n"); + return -1; + } + memset(&blk->link, 0, sizeof(blk->link)); + blk->size = next-curr; + fseek(f, curr, SEEK_SET); + if (fread(&blk->raw, blk->size, 1, f) != 1) { + free(blk); + fprintf(stderr, "pcbdoc_ascii_load_blocks: can't read that many: %ld from %ld (%ld; max is %ld)\n", blk->size, curr, curr+blk->size, max); + return -1; + } + gdl_append(&tree->blocks, blk, link); +/* printf("curr=%ld next=%ld\n", curr, next);*/ + curr = next; + } + + return 0; +} + + +static int pcbdoc_ascii_parse_blocks(altium_tree_t *tree) +{ + altium_block_t *blk; + + for(blk = gdl_first(&tree->blocks); blk != NULL; blk = gdl_next(&tree->blocks, blk)) { + } + + return 0; +} + +int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn) +{ + FILE *f; + int res; + long filesize; + + filesize = rnd_file_size(hidlib, fn); + if (filesize <= 0) + return -1; + + f = fopen(fn, "rb"); + if (f == NULL) + return -1; + + res = pcbdoc_ascii_load_blocks(tree, f, filesize); + fclose(f); + + if (res != 0) + return -1; + + + return pcbdoc_ascii_parse_blocks(tree); +} + Index: altium_parser/pcbdoc_ascii.h =================================================================== --- altium_parser/pcbdoc_ascii.h (revision 35272) +++ altium_parser/pcbdoc_ascii.h (revision 35273) @@ -28,4 +28,5 @@ } altium_tree_t; int pcbdoc_ascii_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *file_name, FILE *f); +int pcbdoc_ascii_parse_file(rnd_hidlib_t *hidlib, altium_tree_t *tree, const char *fn); Index: altium_parser/plug_io.h =================================================================== --- altium_parser/plug_io.h (revision 35272) +++ altium_parser/plug_io.h (revision 35273) @@ -1,7 +1,29 @@ +#ifndef PLUG_IO_H +#define PLUG_IO_H +#include +#include +#include + typedef struct { int dummy; +} rnd_hidlib_t; + +typedef struct { + int dummy; } pcb_plug_io_t; typedef enum { pcb_plug_iot_dummy } pcb_plug_iot_t; + +static inline long rnd_file_size(rnd_hidlib_t *hidlib, const char *path) +{ + struct stat st; + if (stat(path, &st) != 0) + return -1; + if (st.st_size > LONG_MAX) + return -1; + return st.st_size; +} + +#endif