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 PACKET_SIZE 3000
44 #define READ_SIZE 9000
45 
46 static long serialno;
47 
48 static int corrupt_packets = 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[PACKET_SIZE];
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   memset (buf, 'a' + iter, PACKET_SIZE);
62 
63   op.packet = buf;
64   op.bytes = PACKET_SIZE;
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 != PACKET_SIZE)
106     FAIL ("Packet has incorrect size");
107 
108   if (op->packet[0] != 'a' + iter)
109     corrupt_packets++;
110 
111   if ((op->b_o_s == 0) != (b_o_s == 0))
112     FAIL ("Packet has incorrect b_o_s");
113 
114 #if 0
115   if ((op->e_o_s == 0) != (e_o_s == 0))
116     FAIL ("Packet has incorrect e_o_s");
117 
118   if (op->granulepos != -1 && op->granulepos != iter)
119     FAIL ("Packet has incorrect granulepos");
120 
121   if (op->packetno != iter)
122     FAIL ("Packet has incorrect packetno");
123 #endif
124 
125   iter++;
126   b_o_s = 0;
127   if (iter == 10) e_o_s = 1;
128 
129   if (iter % 3 == 0) return OGGZ_STOP_ERR;
130 
131   return OGGZ_CONTINUE;
132 }
133 
134 int
main(int argc,char * argv[])135 main (int argc, char * argv[])
136 {
137   OGGZ * reader, * writer;
138   unsigned char buf[READ_SIZE];
139   long n, remaining;
140 
141   INFO ("Testing ability to stop reading and purge (OGGZ_STOP_ERR)");
142 
143   writer = oggz_new (OGGZ_WRITE);
144   if (writer == NULL)
145     FAIL("newly created OGGZ writer == NULL");
146 
147   serialno = oggz_serialno_new (writer);
148 
149   if (oggz_write_set_hungry_callback (writer, hungry, 1, NULL) == -1)
150     FAIL("Could not set hungry callback");
151 
152   reader = oggz_new (OGGZ_READ);
153   if (reader == NULL)
154     FAIL("newly created OGGZ reader == NULL");
155 
156   oggz_set_read_callback (reader, -1, read_packet, NULL);
157 
158   while ((remaining = oggz_write_output (writer, buf, READ_SIZE)) > 0) {
159     n = oggz_read_input (reader, buf, remaining);
160 
161     if (n < remaining)
162       INFO ("+ Interrupted read detected");
163 
164     remaining -= n;
165 
166     n = oggz_read_input (reader, buf+n, remaining);
167     remaining -= n;
168   }
169 
170   /*
171    * The STOP_ERR above should have caused some packets to be incompletely
172    * delivered, hence if none were corrupted, the STOP_ERR was not purging
173    * correctly.
174    */
175   if (corrupt_packets == 0)
176     FAIL("Corrupted packets not detected");
177 
178   INFO("= Corrupted packets detected correctly");
179 
180   if (oggz_close (reader) != 0)
181     FAIL("Could not close OGGZ reader");
182 
183   if (oggz_close (writer) != 0)
184     FAIL("Could not close OGGZ writer");
185 
186   exit (0);
187 }
188