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 int write_called = 0;
47 
48 static int
hungry(OGGZ * oggz,int empty,void * user_data)49 hungry (OGGZ * oggz, int empty, void * user_data)
50 {
51   unsigned char buf[1];
52   ogg_packet op;
53   static int iter = 0;
54   static long b_o_s = 1;
55   static long e_o_s = 0;
56 
57   if (iter > 10) return 1;
58 
59   buf[0] = 'a' + iter;
60 
61   op.packet = buf;
62   op.bytes = 1;
63   op.b_o_s = b_o_s;
64   op.e_o_s = e_o_s;
65   op.granulepos = iter;
66   op.packetno = iter;
67 
68   /* Main check */
69    if (oggz_write_feed (oggz, &op, serialno, 0, NULL) != 0)
70     FAIL ("Oggz write failed");
71 
72   iter++;
73   b_o_s = 0;
74   if (iter == 10) e_o_s = 1;
75 
76   return 0;
77 }
78 
79 static int
read_packet(OGGZ * oggz,oggz_packet * zp,long serialno,void * user_data)80 read_packet (OGGZ * oggz, oggz_packet * zp, long serialno, void * user_data)
81 {
82   ogg_packet * op = &zp->op;
83   static int iter = 0;
84   static long b_o_s = 1;
85   static long e_o_s = 0;
86 
87 #ifdef DEBUG
88   printf ("%08" PRI_OGGZ_OFF_T "x: serialno %010lu, "
89 	  "granulepos %" PRId64 ", packetno %" PRId64,
90 	  oggz_tell (oggz), serialno, op->granulepos, op->packetno);
91 
92   if (op->b_o_s) {
93     printf (" *** bos");
94   }
95 
96   if (op->e_o_s) {
97     printf (" *** eos");
98   }
99 
100   printf ("\n");
101 #endif
102 
103   if (op->bytes != 1)
104     FAIL ("Packet too long");
105 
106   if (op->packet[0] != 'a' + iter)
107     FAIL ("Packet contains incorrect data");
108 
109   if ((op->b_o_s == 0) != (b_o_s == 0))
110     FAIL ("Packet has incorrect b_o_s");
111 
112   if ((op->e_o_s == 0) != (e_o_s == 0))
113     FAIL ("Packet has incorrect e_o_s");
114 
115   if (op->granulepos != -1 && op->granulepos != iter)
116     FAIL ("Packet has incorrect granulepos");
117 
118   if (op->packetno != iter)
119     FAIL ("Packet has incorrect packetno");
120 
121   iter++;
122   b_o_s = 0;
123   if (iter == 10) e_o_s = 1;
124 
125   return 0;
126 }
127 
128 static size_t
my_io_write(void * user_handle,void * buf,size_t n)129 my_io_write (void * user_handle, void * buf, size_t n)
130 {
131   unsigned char * data_buf = (unsigned char *)user_handle;
132   static int offset = 0;
133   int len;
134 
135   /* Mark that the write IO method was actually used */
136   write_called++;
137 
138   len = MIN ((int)n, DATA_BUF_LEN - offset);
139   memcpy (&data_buf[offset], buf, len);
140 
141   offset += len;
142 
143   return len;
144 }
145 
146 int
main(int argc,char * argv[])147 main (int argc, char * argv[])
148 {
149   OGGZ * reader, * writer;
150   unsigned char data_buf[DATA_BUF_LEN];
151   long n;
152 
153   INFO ("Testing override of IO writing");
154 
155   writer = oggz_new (OGGZ_WRITE);
156   if (writer == NULL)
157     FAIL("newly created OGGZ writer == NULL");
158 
159   serialno = oggz_serialno_new (writer);
160 
161   if (oggz_write_set_hungry_callback (writer, hungry, 1, NULL) == -1)
162     FAIL("Could not set hungry callback");
163 
164   oggz_io_set_write (writer, my_io_write, data_buf);
165 
166   reader = oggz_new (OGGZ_READ);
167   if (reader == NULL)
168     FAIL("newly created OGGZ reader == NULL");
169 
170   oggz_set_read_callback (reader, -1, read_packet, NULL);
171 
172   /* Write using the IO callback */
173   n = oggz_write (writer, DATA_BUF_LEN);
174 
175   if (n == 0)
176     FAIL("No data generated by writer");
177 
178   if (n >= DATA_BUF_LEN)
179     FAIL("Too much data generated by writer");
180 
181   if (write_called == 0)
182     FAIL("Write method ignored");
183 
184   /* Verify the contents */
185   oggz_read_input (reader, data_buf, n);
186 
187   if (oggz_close (reader) != 0)
188     FAIL("Could not close OGGZ reader");
189 
190   if (oggz_close (writer) != 0)
191     FAIL("Could not close OGGZ writer");
192 
193   exit (0);
194 }
195