1 /*
2    Copyright (C) 2003 Commonwealth Scientific and Industrial Research
3    Organisation (CSIRO) Australia
4 
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8 
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11 
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15 
16    - Neither the name of CSIRO Australia nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19 
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #include "config.h"
34 
35 #include <string.h>
36 
37 #include "oggz/oggz.h"
38 
39 #include "oggz_tests.h"
40 
41 /* #define DEBUG */
42 
43 #define DATA_BUF_LEN 1024
44 
45 static long serialno;
46 static long bytes_generated = 0;
47 static int read_called = 0;
48 static int eof_reached = 0;
49 
50 static int
hungry(OGGZ * oggz,int empty,void * user_data)51 hungry (OGGZ * oggz, int empty, void * user_data)
52 {
53   unsigned char buf[1];
54   ogg_packet op;
55   static int iter = 0;
56   static long b_o_s = 1;
57   static long e_o_s = 0;
58 
59   if (iter > 10) return 1;
60 
61   buf[0] = 'a' + iter;
62 
63   op.packet = buf;
64   op.bytes = 1;
65   op.b_o_s = b_o_s;
66   op.e_o_s = e_o_s;
67   op.granulepos = iter;
68   op.packetno = iter;
69 
70   /* Main check */
71    if (oggz_write_feed (oggz, &op, serialno, 0, NULL) != 0)
72     FAIL ("Oggz write failed");
73 
74   iter++;
75   b_o_s = 0;
76   if (iter == 10) e_o_s = 1;
77 
78   return 0;
79 }
80 
81 static int
read_packet(OGGZ * oggz,oggz_packet * zp,long serialno,void * user_data)82 read_packet (OGGZ * oggz, oggz_packet * zp, long serialno, void * user_data)
83 {
84   ogg_packet * op = &zp->op;
85   static int iter = 0;
86   static long b_o_s = 1;
87   static long e_o_s = 0;
88 
89 #ifdef DEBUG
90   printf ("%08" PRI_OGGZ_OFF_T "x: serialno %010lu, "
91 	  "granulepos %" PRId64 ", packetno %" PRId64,
92 	  oggz_tell (oggz), serialno, op->granulepos, op->packetno);
93 
94   if (op->b_o_s) {
95     printf (" *** bos");
96   }
97 
98   if (op->e_o_s) {
99     printf (" *** eos");
100   }
101 
102   printf ("\n");
103 #endif
104 
105   if (op->bytes != 1)
106     FAIL ("Packet too long");
107 
108   if (op->packet[0] != 'a' + iter)
109     FAIL ("Packet contains incorrect data");
110 
111   if ((op->b_o_s == 0) != (b_o_s == 0))
112     FAIL ("Packet has incorrect b_o_s");
113 
114   if ((op->e_o_s == 0) != (e_o_s == 0))
115     FAIL ("Packet has incorrect e_o_s");
116 
117   if (op->granulepos != -1 && op->granulepos != iter)
118     FAIL ("Packet has incorrect granulepos");
119 
120   if (op->packetno != iter)
121     FAIL ("Packet has incorrect packetno");
122 
123   iter++;
124   b_o_s = 0;
125   if (iter == 10) e_o_s = 1;
126 
127   return OGGZ_STOP_OK;
128 }
129 
130 static size_t
my_io_read(void * user_handle,void * buf,size_t n)131 my_io_read (void * user_handle, void * buf, size_t n)
132 {
133   unsigned char * data_buf = (unsigned char *)user_handle;
134   static int offset = 0;
135   int len;
136 
137   /* Mark that the read IO method was actually used */
138   read_called++;
139 
140   len = MIN ((int)n, bytes_generated - offset);
141 
142   memcpy (buf, &data_buf[offset], len);
143 
144   offset += len;
145 
146   if (len == 0) eof_reached = 1;
147 
148   return len;
149 }
150 
151 int
main(int argc,char * argv[])152 main (int argc, char * argv[])
153 {
154   OGGZ * reader, * writer;
155   unsigned char data_buf[DATA_BUF_LEN];
156   long n, ret;
157 
158   INFO ("Testing override of IO reading");
159 
160   writer = oggz_new (OGGZ_WRITE);
161   if (writer == NULL)
162     FAIL("newly created OGGZ writer == NULL");
163 
164   serialno = oggz_serialno_new (writer);
165 
166   if (oggz_write_set_hungry_callback (writer, hungry, 1, NULL) == -1)
167     FAIL("Could not set hungry callback");
168 
169   reader = oggz_new (OGGZ_READ);
170   if (reader == NULL)
171     FAIL("newly created OGGZ reader == NULL");
172 
173   oggz_io_set_read (reader, my_io_read, data_buf);
174 
175   oggz_set_read_callback (reader, -1, read_packet, NULL);
176 
177   n = oggz_write_output (writer, data_buf, DATA_BUF_LEN);
178 
179   if (n >= DATA_BUF_LEN)
180     FAIL("Too much data generated by writer");
181 
182   bytes_generated = n;
183 
184   do {
185     ret = oggz_read (reader, 4);
186   } while (ret > 0 || ret == OGGZ_ERR_READ_STOP_OK);
187 
188   if (ret != 0) FAIL ("oggz_read didn't reach EOF");
189 
190   if (!eof_reached) FAIL ("oggz_read returned 0 before EOF");
191 
192   if (read_called == 0)
193     FAIL("Read method ignored");
194 
195   if (oggz_close (reader) != 0)
196     FAIL("Could not close OGGZ reader");
197 
198   if (oggz_close (writer) != 0)
199     FAIL("Could not close OGGZ writer");
200 
201   exit (0);
202 }
203