ArithmeticCoding  0.0.0a
Arithmetic coding in C
C:/Users/clackn/Desktop/src/arithcode/test/stream.cc
Go to the documentation of this file.
00001 #include <gtest/gtest.h>
00002 #include "stream.h"
00003 
00005 
00006 // templated calls to the stream api
00007 // - won't work for u1 and u4 types, but these usually require
00008 //   special tests anyway
00009 template<class T> void push(stream_t *s, T v);
00010 #define DEFN_PUSH(a,b) \
00011   template<> void push<a>(stream_t *s, a v) { push_##b(s,v); }
00012 DEFN_PUSH(uint8_t ,u8);
00013 DEFN_PUSH(uint16_t,u16);
00014 DEFN_PUSH(uint32_t,u32);
00015 DEFN_PUSH(uint64_t,u64);
00016 DEFN_PUSH( int8_t ,i8);
00017 DEFN_PUSH( int16_t,i16);
00018 DEFN_PUSH( int32_t,i32);
00019 DEFN_PUSH( int64_t,i64);
00020 
00021 template<class T> T pop(stream_t *s);
00022 #define DEFN_POP(a,b) \
00023   template<> a pop(stream_t *s) { return pop_##b(s); }
00024 DEFN_POP(uint8_t ,u8);
00025 DEFN_POP(uint16_t,u16);
00026 DEFN_POP(uint32_t,u32);
00027 DEFN_POP(uint64_t,u64);
00028 DEFN_POP( int8_t ,i8);
00029 DEFN_POP( int16_t,i16);
00030 DEFN_POP( int32_t,i32);
00031 DEFN_POP( int64_t,i64);
00032 
00033 template<class T> void carry(stream_t *s);
00034 #define DEFN_CARRY(a,b) \
00035   template<> void carry<a> (stream_t *s) { carry_##b(s); }
00036 DEFN_CARRY(uint8_t ,u8);
00037 DEFN_CARRY(uint16_t,u16);
00038 DEFN_CARRY(uint32_t,u32);
00039 
00041 
00042 TEST(Attach,NullBuffer)
00043 { stream_t d={0};
00044   attach(&d,NULL,0);
00045   EXPECT_TRUE(d.d!=NULL);
00046   EXPECT_GT(d.nbytes,0);
00047   EXPECT_EQ(0,d.ibyte);
00048   EXPECT_EQ(0,d.ibit);
00049   //clean up
00050   { ASSERT_TRUE(d.d!=NULL);
00051     void *buf;
00052     size_t n;
00053     detach(&d,&buf,&n);
00054     EXPECT_EQ(0,n); // nothing pushed so zero length
00055     ASSERT_TRUE(buf!=NULL);
00056     free(buf);
00057   }
00058 }
00059 
00060 TEST(Attach,ExistingBuffer)
00061 { stream_t d={0};
00062   float buf[1024];
00063   size_t n = sizeof(buf)/sizeof(*buf);
00064   attach(&d,buf,n);
00065   EXPECT_EQ((void*)buf,(void*)d.d);
00066   EXPECT_EQ(n,d.nbytes);
00067   EXPECT_EQ(0,d.ibyte);
00068   EXPECT_EQ(0,d.ibit);
00069 }
00070 
00072 
00073 class StreamSanityTest : public ::testing::Test 
00074 { public:
00075     inline stream_t *s() {return &stream_;}
00076   protected:
00077     virtual void SetUp()
00078     { memset(&stream_,0,sizeof(stream_)); // important to zero things out
00079       attach(&stream_,NULL,0);
00080       memset(stream_.d,0,stream_.nbytes); // attach doesn't zero (nor should it) 
00081     }
00082     virtual void TearDown()
00083     { void *buf;
00084       size_t n;
00085       detach(&stream_,&buf,&n);
00086       if(buf) free(buf);
00087     }
00088   stream_t stream_;
00089 };
00090 
00092 
00093 TEST_F(StreamSanityTest,PushU1)
00094 { 
00095   push_u1(s(),1);
00096   push_u1(s(),0);
00097   push_u1(s(),0);
00098   push_u1(s(),1);
00099   EXPECT_EQ(0,s()->ibyte);
00100   EXPECT_EQ(4,s()->ibit);
00101   EXPECT_EQ(0x90,s()->d[0]);
00102 
00103   push_u1(s(),0);
00104   push_u1(s(),1);
00105   push_u1(s(),0);
00106   push_u1(s(),1);
00107   EXPECT_EQ(1,s()->ibyte);
00108   EXPECT_EQ(0,s()->ibit);
00109   EXPECT_EQ(0x95,s()->d[0]);
00110 }
00111 TEST_F(StreamSanityTest,PushU4)
00112 { 
00113   push_u4(s(),9);
00114   EXPECT_EQ(0,s()->ibyte);
00115   EXPECT_EQ(4,s()->ibit);
00116   EXPECT_EQ(0x90,s()->d[0]);
00117 
00118   push_u4(s(),5);
00119   EXPECT_EQ(1,s()->ibyte);
00120   EXPECT_EQ(0,s()->ibit);
00121   EXPECT_EQ(0x95,s()->d[0]);
00122 }
00123 TEST_F(StreamSanityTest,PushU8)
00124 { 
00125   push_u8(s(),0x95);
00126   EXPECT_EQ(1,s()->ibyte);
00127   EXPECT_EQ(0,s()->ibit);
00128   push_u8(s(),0x59);
00129   EXPECT_EQ(2,s()->ibyte);
00130   EXPECT_EQ(0,s()->ibit);
00131   EXPECT_EQ(0x95,s()->d[0]);
00132   EXPECT_EQ(0x59,s()->d[1]);
00133 }
00134 
00136 
00137 typedef testing::Types<
00138   uint8_t,
00139   uint16_t,
00140   uint32_t,
00141   uint64_t,
00142   int8_t,
00143   int16_t,
00144   int32_t,
00145   int64_t
00146   > RegularTypes;
00147 
00148 template<class T> class TypedStreamSanityTest : public StreamSanityTest {};
00149 
00150 TYPED_TEST_CASE(TypedStreamSanityTest,RegularTypes);
00151 
00152 TYPED_TEST(TypedStreamSanityTest,PushPop)
00153 { stream_t *t = StreamSanityTest::s();
00154   push<TypeParam>(t,1);
00155   push<TypeParam>(t,2);
00156   push<TypeParam>(t,3);
00157   push<TypeParam>(t,4);
00158   t->ibyte = 0;
00159   EXPECT_EQ(1,pop<TypeParam>(t));
00160   EXPECT_EQ(2,pop<TypeParam>(t));
00161   EXPECT_EQ(3,pop<TypeParam>(t));
00162   EXPECT_EQ(4,pop<TypeParam>(t));
00163   EXPECT_EQ(0,pop<TypeParam>(t)); // should return 0's on overflow
00164   EXPECT_EQ(0,pop<TypeParam>(t));
00165 }
00166 TEST_F(StreamSanityTest,PushPopU1)
00167 { stream_t *t = s();
00168   push_u1(t,1);
00169   push_u1(t,0);
00170   push_u1(t,1);
00171   push_u1(t,1);
00172   t->ibyte = 0;
00173   t->ibit = 0;
00174   EXPECT_EQ(1,pop_u1(t));
00175   EXPECT_EQ(0,pop_u1(t));
00176   EXPECT_EQ(1,pop_u1(t));
00177   EXPECT_EQ(1,pop_u1(t));
00178   EXPECT_EQ(0,pop_u1(t)); // should return 0's on overflow
00179   EXPECT_EQ(0,pop_u1(t));
00180 }
00181 TEST_F(StreamSanityTest,PushPopU4)
00182 { stream_t *t = s();
00183   push_u4(t,1);
00184   push_u4(t,2);
00185   push_u4(t,3);
00186   push_u4(t,4);
00187   EXPECT_EQ(2,t->ibyte);
00188   EXPECT_EQ(0,t->ibit);
00189   t->ibyte = 0;
00190   t->ibit = 0;
00191   EXPECT_EQ(1,pop_u4(t));
00192   EXPECT_EQ(2,pop_u4(t));
00193   EXPECT_EQ(3,pop_u4(t));
00194   EXPECT_EQ(4,pop_u4(t));
00195   EXPECT_EQ(0,pop_u4(t)); // should return 0's on overflow
00196   EXPECT_EQ(0,pop_u4(t));
00197 }
00198 
00200 
00201 typedef testing::Types<
00202   uint8_t,
00203   uint16_t,
00204   uint32_t
00205   > CarryTypes;
00206 
00207 template<class T> class TypedStreamCarryTest : public StreamSanityTest {};
00208 TYPED_TEST_CASE(TypedStreamCarryTest,CarryTypes);
00209 TYPED_TEST(TypedStreamCarryTest,Carry)
00210 { stream_t *t = StreamSanityTest::s();
00211   push<TypeParam>(t,2);
00212   push<TypeParam>(t,(TypeParam)-1);
00213   push<TypeParam>(t,(TypeParam)-1);
00214   push<TypeParam>(t,(TypeParam)-1);
00215   push<TypeParam>(t,(TypeParam)-1);
00216   carry<TypeParam>(t);
00217   push<TypeParam>(t,2);
00218   t->ibyte = 0;
00219   EXPECT_EQ(3,pop<TypeParam>(t));
00220   EXPECT_EQ(0,pop<TypeParam>(t));
00221   EXPECT_EQ(0,pop<TypeParam>(t));
00222   EXPECT_EQ(0,pop<TypeParam>(t));
00223   EXPECT_EQ(0,pop<TypeParam>(t)); 
00224   EXPECT_EQ(2,pop<TypeParam>(t)); 
00225   EXPECT_EQ(0,pop<TypeParam>(t)); // should return 0's on overflow
00226 }
00227  
00228 TEST_F(StreamSanityTest,CarryU1)
00229 { stream_t *t = s();
00230   push_u1(t,0);
00231   push_u1(t,1);
00232   push_u1(t,1);
00233   push_u1(t,1);
00234   push_u1(t,1);
00235   carry_u1(t);
00236   push_u1(t,1);
00237   t->ibyte = 0;
00238   t->ibit  = 0;
00239   EXPECT_EQ(1,pop_u1(t));
00240   EXPECT_EQ(0,pop_u1(t));
00241   EXPECT_EQ(0,pop_u1(t));
00242   EXPECT_EQ(0,pop_u1(t));
00243   EXPECT_EQ(0,pop_u1(t)); 
00244   EXPECT_EQ(1,pop_u1(t)); 
00245   EXPECT_EQ(0,pop_u1(t)); // should return 0's on overflow
00246 }
00247  
00248 TEST_F(StreamSanityTest,CarryU4)
00249 { stream_t *t = s();
00250   push_u4(t,2);
00251   push_u4(t,(uint8_t)-1);
00252   push_u4(t,(uint8_t)-1);
00253   push_u4(t,(uint8_t)-1);
00254   push_u4(t,(uint8_t)-1);
00255   carry_u4(t);
00256   push_u4(t,2);
00257   t->ibyte = 0;
00258   t->ibit  = 0;
00259   EXPECT_EQ(3,pop_u4(t));
00260   EXPECT_EQ(0,pop_u4(t));
00261   EXPECT_EQ(0,pop_u4(t));
00262   EXPECT_EQ(0,pop_u4(t));
00263   EXPECT_EQ(0,pop_u4(t)); 
00264   EXPECT_EQ(2,pop_u4(t)); 
00265   EXPECT_EQ(0,pop_u4(t)); // should return 0's on overflow
00266 }
 All Classes Files Functions Variables Typedefs Defines