diff options
Diffstat (limited to 'lpg/libqr')
| -rw-r--r-- | lpg/libqr/qrgen.c | 68 | 
1 files changed, 61 insertions, 7 deletions
| diff --git a/lpg/libqr/qrgen.c b/lpg/libqr/qrgen.c index d59954d..77fdeb2 100644 --- a/lpg/libqr/qrgen.c +++ b/lpg/libqr/qrgen.c @@ -17,19 +17,18 @@ struct config {          enum qr_ec_level  ec;          enum qr_data_type dtype;          int               ansi; +        const char *      file;          const char *      input;  };  struct qr_code * create(int               version,                          enum qr_ec_level  ec,                          enum qr_data_type dtype, -                        const char *      input) +                        const char *      input, +                        size_t            len)  {          struct qr_data * data;          struct qr_code * code; -        size_t len; - -        len = strlen(input);          data = qr_data_create(version, ec, dtype, input, len); @@ -124,6 +123,7 @@ void show_help() {          fprintf(stderr,                  "Usage:\n\t%s [options] <data>\n\n"                  "\t-h         Display this help message\n" +                "\t-f <file>  File containing data to encode (- for stdin)\n"                  "\t-v <n>     Specify QR version (size) 1 <= n <= 40\n"                  "\t-e <type>  Specify EC type: L, M, Q, H\n"                  "\t-a         Output as ANSI graphics (default)\n" @@ -137,6 +137,7 @@ void set_default_config(struct config * conf)          conf->ec = QR_EC_LEVEL_M;          conf->dtype = QR_DATA_8BIT;          conf->ansi = 1; +        conf->file = NULL;          conf->input = NULL;  } @@ -145,7 +146,7 @@ void parse_options(int argc, char ** argv, struct config * conf)          int c;          for (;;) { -                c = getopt(argc, argv, ":hv:e:t:ap"); +                c = getopt(argc, argv, ":hf:v:e:t:ap");                  if (c == -1) /* no more options */                          break; @@ -155,6 +156,9 @@ void parse_options(int argc, char ** argv, struct config * conf)                          show_help();                          exit(0);                          break; +                case 'f': /* file */ +                        conf->file = optarg; +                        break;                  case 'v': /* version */                          conf->version = atoi(optarg);                          if (conf->version < 1 || conf->version > 40) { @@ -202,24 +206,74 @@ void parse_options(int argc, char ** argv, struct config * conf)          if (optind < argc)                  conf->input = argv[optind++]; -        if (!conf->input) { +        if (!conf->file && !conf->input) {                  fprintf(stderr, "No data (try -h for help)\n");                  exit(1);          }  } +void slurp_file(const char * path, char ** data, size_t * len) +{ +        const size_t chunk_size = 65536; +        FILE * file; +        char * tmpbuf; +        size_t count; + +        if (strcmp(path, "-") == 0) +                file = stdin; +        else +                file = fopen(path, "rb"); + +        if (!file) { +                fprintf(stderr, "Failed to open %s\n", path); +                exit(2); +        } + +        *data = NULL; +        *len = 0; + +        do { +                tmpbuf = realloc(*data, *len + chunk_size); +                if (!tmpbuf) { +                        perror("realloc"); +                        exit(2); +                } +                *data = tmpbuf; +                count = fread(*data + *len, 1, chunk_size, file); +                if (count == 0 && !feof(file)) { +                        perror("fread"); +                        exit(2); +                } +                *len += count; +        } while (*len == chunk_size); + +        fclose(file); +} +  int main(int argc, char ** argv) {          struct config conf;          struct qr_code * code; +        char * file_data; +        size_t len;          set_default_config(&conf);          parse_options(argc, argv, &conf); +        if (conf.file) +                slurp_file(conf.file, &file_data, &len); +        else +                len = strlen(conf.input); + +          code = create(conf.version,                        conf.ec,                        conf.dtype, -                      conf.input); +                      conf.file ? file_data : conf.input, +                      len); + +        if (conf.file) +                free(file_data);          if (conf.ansi)                  output_ansi(code->modules); | 
