1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2011, 2014, 2015, 2018 Laboratoire de Recherche et
3 // Developpement de l'Epita (LRDE).
4 //
5 // This file is part of Spot, a model checking library.
6 //
7 // Spot is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Spot is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 
20 #include "config.h"
21 #include <iostream>
22 #include <spot/misc/intvcomp.hh>
23 #include <cstring>
24 
25 static int
check_vv(int * data,int size,unsigned expected=0)26 check_vv(int* data, int size, unsigned expected = 0)
27 {
28 
29   std::vector<int> input;
30   input.reserve(size);
31   for (int i = 0; i < size; ++i)
32     input.push_back(data[i]);
33 
34   std::vector<unsigned int> output;
35   spot::int_vector_vector_compress(input, output);
36 
37   std::cout << "WC[" << output.size() << "] ";
38   for (size_t i = 0; i < output.size(); ++i)
39     std::cout << output[i] << ' ';
40   std::cout << '\n';
41 
42   std::vector<int> decomp;
43   spot::int_vector_vector_decompress(output, decomp, size);
44 
45   std::cout << "WD[" << decomp.size() << "] ";
46   for (size_t i = 0; i < decomp.size(); ++i)
47     std::cout << decomp[i] << ' ';
48   std::cout << '\n';
49 
50   int res = (decomp != input);
51 
52   if (res)
53     {
54       std::cout << "*** cmp error *** " << std::endl;
55       std::cout << "WE[" << size << "] ";
56       for (int i = 0; i < size; ++i)
57         std::cout << data[i] << ' ';
58       std::cout << '\n';
59     }
60 
61   if (expected && (output.size() * sizeof(int) != expected))
62     {
63       std::cout << "*** size error *** (expected "
64                 << expected << " bytes, got " << output.size() * sizeof(int)
65                 << " bytes)" << std::endl;
66       res = 1;
67     }
68 
69   std::cout << '\n';
70 
71   return !!res;
72 }
73 
74 static int
check_av(int * data,int size,unsigned expected=0)75 check_av(int* data, int size, unsigned expected = 0)
76 {
77   const std::vector<unsigned int>* v =
78     spot::int_array_vector_compress(data, size);
79 
80   std::cout << "VC[" << v->size() << "] ";
81   for (size_t i = 0; i < v->size(); ++i)
82     std::cout << (*v)[i] << ' ';
83   std::cout << '\n';
84 
85   int* decomp = new int[size];
86   spot::int_vector_array_decompress(v, decomp, size);
87 
88   std::cout << "VD[" << size << "] ";
89   for (int i = 0; i < size; ++i)
90     std::cout << decomp[i] << ' ';
91   std::cout << '\n';
92 
93   int res = memcmp(data, decomp, size * sizeof(int));
94 
95   if (res)
96     {
97       std::cout << "*** cmp error *** " << res << std::endl;
98       std::cout << "VE[" << size << "] ";
99       for (int i = 0; i < size; ++i)
100         std::cout << data[i] << ' ';
101       std::cout << '\n';
102     }
103 
104   if (expected && (v->size() * sizeof(int) != expected))
105     {
106       std::cout << "*** size error *** (expected "
107                 << expected << " bytes, got " << v->size() * sizeof(int)
108                 << " bytes)" << std::endl;
109       res = 1;
110     }
111 
112   std::cout << '\n';
113 
114   delete v;
115   delete[] decomp;
116   return !!res;
117 }
118 
119 static int
check_aa(int * data,int size,unsigned expected=0)120 check_aa(int* data, int size, unsigned expected = 0)
121 {
122   int* comp = new int[size *2];
123   size_t csize = size * 2;
124   spot::int_array_array_compress(data, size, comp, csize);
125 
126   std::cout << "AC[" << csize << "] ";
127   for (size_t i = 0; i < csize; ++i)
128     std::cout << comp[i] << ' ';
129   std::cout << '\n';
130 
131   int* decomp = new int[size];
132   spot::int_array_array_decompress(comp, csize, decomp, size);
133 
134   std::cout << "AD[" << size << "] ";
135   for (int i = 0; i < size; ++i)
136     std::cout << decomp[i] << ' ';
137   std::cout << '\n';
138 
139   int res = memcmp(data, decomp, size * sizeof(int));
140 
141   if (res)
142     {
143       std::cout << "*** cmp error *** " << res << std::endl;
144       std::cout << "AE[" << size << "] ";
145       for (int i = 0; i < size; ++i)
146         std::cout << data[i] << ' ';
147       std::cout << '\n';
148     }
149 
150   if (expected && (csize * sizeof(int) != expected))
151     {
152       std::cout << "*** size error *** (expected "
153                 << expected << " bytes, got " << csize * sizeof(int)
154                 << " bytes)" << std::endl;
155       res = 1;
156     }
157 
158   std::cout << '\n';
159 
160   delete[] comp;
161   delete[] decomp;
162   return !!res;
163 }
164 
165 static int
check(int * comp,int size,unsigned expected=0)166 check(int* comp, int size, unsigned expected = 0)
167 {
168   return
169     check_vv(comp, size, expected) +
170     check_av(comp, size, expected) +
171     check_aa(comp, size, expected);
172 }
173 
main()174 int main()
175 {
176   int errors = 0;
177 
178   int comp1[] = { 1, 0, 0, 0, 0, 0, 3, 3, 4, 0, 0, 0 };
179   errors += check(comp1, sizeof(comp1) / sizeof(*comp1));
180 
181   int comp2[] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 1 };
182   errors += check(comp2, sizeof(comp2) / sizeof(*comp2));
183 
184   int comp3[] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
185                   0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0,
186                   0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1,
187                   0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
188                   0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1,
189                   0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0 };
190   errors += check(comp3, sizeof(comp3) / sizeof(*comp3));
191 
192   int comp4[] = { 1, 2, 1, 2, 1, 2, 2, 0 }; // 32 bits
193   errors += check(comp4, sizeof(comp4) / sizeof(*comp4), 4);
194 
195   int comp5[] = { 1, 2, 1, 2, 1, 2, 2, 0, 1, 2, 1, 2, 1, 2, 2, 0 }; // 64 bits
196   errors += check(comp5, sizeof(comp5) / sizeof(*comp5), 8);
197 
198   int comp6[] = { 1, 2, 1, 2, 1, 2, 2, 0, 1, 2, 1, 2, 1, 2, 2, 0,
199                   1, 2, 1, 2, 1, 2, 2, 0, 1, 2, 1, 2, 1, 2, 2, 0 }; // 128 bits
200   errors += check(comp6, sizeof(comp6) / sizeof(*comp6), 16);
201 
202   int comp7[] = { -4, -8, -10, 3, 49, 50, 0, 20, 13 };
203   errors += check(comp7, sizeof(comp7) / sizeof(*comp7));
204 
205   int comp8[] = { 4959, 6754, 8133, 10985, 11121, 14413, 17335, 20754,
206                   21317, 30008, 30381, 33494, 34935, 41210, 41417 };
207   errors += check(comp8, sizeof(comp8) / sizeof(*comp8));
208 
209   int comp9[] = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
210   errors += check(comp9, sizeof(comp9) / sizeof(*comp9));
211 
212   int comp10[] = { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
213                    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
214                    0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
215                    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218                    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
219                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
220                    9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10,
222                    0, 0, 0, 0, 0, 0, 0, 0, 9 };
223   errors += check(comp10, sizeof(comp10) / sizeof(*comp10));
224 
225   return errors;
226 }
227