00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037
00038 #include <stdlib.h>
00039 #include <sys/types.h>
00040 #include <errno.h>
00041 #include <unistd.h>
00042
00043 #include "rdd.h"
00044 #include "reader.h"
00045
00052 typedef struct _RDD_ATOMIC_READER {
00053 RDD_READER *parent;
00054 } RDD_ATOMIC_READER;
00055
00056
00057
00058
00059 static int rdd_atomic_read(RDD_READER *r, unsigned char *buf, unsigned nbyte,
00060 unsigned *nread);
00061 static int rdd_atomic_tell(RDD_READER *r, rdd_count_t *pos);
00062 static int rdd_atomic_seek(RDD_READER *r, rdd_count_t pos);
00063 static int rdd_atomic_close(RDD_READER *r, int recurse);
00064
00065 static RDD_READ_OPS atomic_read_ops = {
00066 rdd_atomic_read,
00067 rdd_atomic_tell,
00068 rdd_atomic_seek,
00069 rdd_atomic_close
00070 };
00071
00072 int
00073 rdd_open_atomic_reader(RDD_READER **self, RDD_READER *p)
00074 {
00075 RDD_READER *r = 0;
00076 RDD_ATOMIC_READER *state = 0;
00077 int rc;
00078
00079 if (p == NULL) {
00080 return RDD_BADARG;
00081 }
00082
00083 rc = rdd_new_reader(&r, &atomic_read_ops, sizeof(RDD_ATOMIC_READER));
00084 if (rc != RDD_OK) {
00085 return rc;
00086 }
00087 state = (RDD_ATOMIC_READER *) r->state;
00088 state->parent = p;
00089
00090 *self = r;
00091 return RDD_OK;
00092 }
00093
00094 static int
00095 rdd_atomic_read(RDD_READER *self, unsigned char *buf, unsigned nbyte,
00096 unsigned *nread)
00097 {
00098 RDD_ATOMIC_READER *state = self->state;
00099 rdd_count_t pos;
00100 int rc1;
00101 int rc2;
00102
00103
00104
00105 if ((rc1 = rdd_reader_tell(state->parent, &pos)) != RDD_OK) {
00106 return rc1;
00107 }
00108
00109 rc2 = rdd_reader_read(state->parent, buf, nbyte, nread);
00110 if (rc2 == RDD_OK) {
00111 return RDD_OK;
00112 }
00113
00114
00115
00116 if ((rc1 = rdd_reader_seek(state->parent, pos)) != RDD_OK) {
00117 return rc1;
00118 }
00119
00120 return rc2;
00121 }
00122
00123 static int
00124 rdd_atomic_tell(RDD_READER *self, rdd_count_t *pos)
00125 {
00126 RDD_ATOMIC_READER *state = self->state;
00127
00128 return rdd_reader_tell(state->parent, pos);
00129 }
00130
00131 static int
00132 rdd_atomic_seek(RDD_READER *self, rdd_count_t pos)
00133 {
00134 RDD_ATOMIC_READER *state = self->state;
00135
00136 return rdd_reader_seek(state->parent, pos);
00137 }
00138
00139 static int
00140 rdd_atomic_close(RDD_READER *self, int recurse)
00141 {
00142 RDD_ATOMIC_READER *state = self->state;
00143
00144 if (recurse) {
00145 return rdd_reader_close(state->parent, 1 );
00146 } else {
00147 return RDD_OK;
00148 }
00149 }