Statistics
| Branch: | Revision:

grapes / src / Chunkiser / input-stream-dumb.c @ 176b8de8

History | View | Annotate | Download (2.13 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6

    
7
#include <sys/types.h>
8
#include <sys/stat.h>
9
#include <fcntl.h>
10
#include <unistd.h>
11
#include <errno.h>
12
#include <stdint.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <string.h>
16

    
17
#include "chunkiser_iface.h"
18
#include "grapes_config.h"
19

    
20
struct chunkiser_ctx {
21
  int loop;        //loop on input file infinitely
22
  int chunk_size;
23
  int fds[2];
24
};
25
#define DEFAULT_CHUNK_SIZE 2 * 1024
26

    
27
static struct chunkiser_ctx *dumb_open(const char *fname, int *period, const char *config)
28
{
29
  struct tag *cfg_tags;
30
  struct chunkiser_ctx *res;
31

    
32
  res = malloc(sizeof(struct chunkiser_ctx));
33
  if (res == NULL) {
34
    return NULL;
35
  }
36

    
37
  res->loop = 0;
38
  res->fds[0] = open(fname, O_RDONLY);
39
  if (res->fds[0] < 0) {
40
    free(res);
41

    
42
    return NULL;
43
  }
44
  res->fds[1] = -1;
45

    
46
  *period = 0;
47
  res->chunk_size = DEFAULT_CHUNK_SIZE;
48
  cfg_tags = grapes_config_parse(config);
49
  if (cfg_tags) {
50
    const char *access_mode;
51

    
52
    grapes_config_value_int(cfg_tags, "loop", &res->loop);
53
    grapes_config_value_int(cfg_tags, "chunk_size", &res->chunk_size);
54
    access_mode = grapes_config_value_str(cfg_tags, "mode");
55
    if (access_mode && !strcmp(access_mode, "nonblock")) {
56
#ifndef _WIN32
57
      fcntl(res->fds[0], F_SETFL, O_NONBLOCK);
58
#else
59
      fprintf(stderr, "nonblock is not implemented yet\n");
60
#endif
61
    }
62
  }
63
  free(cfg_tags);
64

    
65
  return res;
66
}
67

    
68
static void dumb_close(struct chunkiser_ctx *s)
69
{
70
  close(s->fds[0]);
71
  free(s);
72
}
73

    
74
static uint8_t *dumb_chunkise(struct chunkiser_ctx *s, int id, int *size, uint64_t *ts)
75
{
76
  uint8_t *res;
77

    
78
  res = malloc(s->chunk_size);
79
  if (res == NULL) {
80
    *size = -1;
81

    
82
    return NULL;
83
  }
84
  *ts = 0;
85
  *size = read(s->fds[0], res, s->chunk_size);
86
  if ((*size == 0) && (errno != EAGAIN)) {
87
    *size = -1;
88
    if (s->loop) {
89
      if (lseek(s->fds[0], 0, SEEK_SET) == 0) {
90
        *size = 0;
91
      }
92
    }
93
    free(res);
94
    res = NULL;
95
  }
96

    
97
  return res;
98
}
99

    
100
const int *dumb_get_fds(const struct chunkiser_ctx *s)
101
{
102
  return s->fds;
103
}
104

    
105
struct chunkiser_iface in_dumb = {
106
  .open = dumb_open,
107
  .close = dumb_close,
108
  .chunkise = dumb_chunkise,
109
  .get_fds = dumb_get_fds,
110
};
111

    
112