File: usage.cc

package info (click to toggle)
libcrcutil 1.0-5.4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,212 kB
  • sloc: cpp: 4,237; sh: 1,112; ansic: 191; makefile: 54; awk: 17
file content (209 lines) | stat: -rw-r--r-- 6,390 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// Copyright 2010 Google Inc.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "std_headers.h"
#include "interface.h"

static const size_t kRollWindow = 4;
static const unsigned char kTestData[] = "abcdefgh";

static const int kTestDataHead =
    static_cast<size_t>((sizeof(kTestData) - 1) / 4);
static const int kTestDataTail =
    static_cast<size_t>(sizeof(kTestData) - 1 - kTestDataHead);

typedef crcutil_interface::UINT64 uint64;

// GCC -- up to 4.5.0 inclusively -- is not aware that the right format
// to print "long long" is "%ll[oudx]". Such nonsense does not prevent
// it from complaining about format mismatch, though. Here is the cure.
void xprintf(const char *format, ...) {
  va_list va;
  va_start(va, format);
  vprintf(format, va);
  va_end(va);
  fflush(stdout);
}

//
// Please notice that when working with 64-bit and smaller CRCs,
// the use of "hi" part of CRC value is unnecessary.
//
void Show(const crcutil_interface::CRC *crc) {
  char buffer[sizeof(kTestData) + 32];

  //
  // Access CRC properties.
  //
  uint64 lo;
  crc->GeneratingPolynomial(&lo);
  xprintf("Generating polynomial 0x%llx, degree %llu",
          lo,
          static_cast<uint64>(crc->Degree()));
  crc->CanonizeValue(&lo);
  xprintf(", canonize_value=0x%llx", lo);

  crc->RollStartValue(&lo);
  xprintf(", roll start value=0x%llx, roll window=%llu",
          lo,
          static_cast<uint64>(crc->RollWindowBytes()));

  //
  // Check integrity of CRC tables.
  //
  crc->SelfCheckValue(&lo);
  xprintf(", self check value 0x%llx\n", lo);

  //
  // Compute CRC.
  //
  lo = 0;
  crc->Compute(kTestData, sizeof(kTestData) - 1, &lo);
  xprintf("CRC32C(\"%s\") = 0x%llx\n", kTestData, lo);

  //
  // Compute CRC (incrementally).
  //
  lo = 0;
  crc->Compute(kTestData, kTestDataHead, &lo);
  xprintf("CRC32C(\"%.*s\", 0) = 0x%llx, ", kTestDataHead, kTestData, lo);
  crc->Compute(kTestData + kTestDataHead, kTestDataTail, &lo);
  xprintf("CRC32C(\"%s\", CRC32(\"%.*s\", 0)) = 0x%llx = CRC32(\"%s\")\n",
      kTestData + kTestDataHead, kTestDataHead, kTestData, lo, kTestData);

  //
  // Compute CRC of a message filled with 0s.
  //
  lo = 1;
  crc->CrcOfZeroes(sizeof(buffer), &lo);

  uint64 lo1 = 1;
  memset(buffer, 0, sizeof(buffer));
  crc->Compute(buffer, sizeof(buffer), &lo1);
  xprintf("CRC of %d zeroes = %llx, expected %llx\n",
          static_cast<int>(sizeof(buffer)),
          lo,
          lo1);


  //
  // Use rolling CRC.
  //
  xprintf("RollingCrc expected =");
  for (size_t i = 0; i <= kRollWindow; ++i) {
    crc->RollStartValue(&lo);
    crc->Compute(kTestData + i, kRollWindow, &lo);
    xprintf(" 0x%llx", lo);
  }
  xprintf("\n");

  crc->RollStart(kTestData, &lo, NULL);
  xprintf("RollingCrc actual   = 0x%llx", lo);
  for (size_t i = 1; i <= kRollWindow; ++i) {
    crc->Roll(kTestData[i - 1], kTestData[i - 1 + kRollWindow], &lo, NULL);
    xprintf(" 0x%llx", lo);
  }
  xprintf("\n");

  //
  // Change initial value.
  //
  lo = 0;
  crc->Compute(kTestData, sizeof(kTestData) - 1, &lo);
  uint64 lo1_expected = 1;
  crc->Compute(kTestData, sizeof(kTestData) - 1, &lo1_expected);
  lo1 = lo;
  crc->ChangeStartValue(0, 0,   // old start value
                        1, 0,   // new start value
                        sizeof(kTestData) - 1,
                        &lo1);
  xprintf("CRC(\"%s\", 0) = 0x%llx, CRC(\"%s\", 1)=0x%llx, expected 0x%llx\n",
      kTestData, lo, kTestData, lo1, lo1_expected);

  //
  // Concatenate CRCs.
  //
  uint64 start_value = 1;
  lo = start_value;
  crc->Compute(kTestData, kTestDataHead, &lo);
  lo1 = 0;
  crc->Compute(kTestData + kTestDataHead, kTestDataTail, &lo1);

  uint64 lo2 = lo;
  crc->Concatenate(lo1, 0, kTestDataTail, &lo2);

  uint64 lo2_expected = start_value;
  crc->Compute(kTestData, sizeof(kTestData) - 1, &lo2_expected);

  xprintf("CRC(\"%.*s\", 1) = 0x%llx, CRC(\"%s\", 0)=0x%llx, "
         "CRC(\"%s\", 1) = 0x%llx, expected 0x%llx\n",
         kTestDataHead, kTestData, lo,
         kTestData + kTestDataHead, lo1,
         kTestData, lo2,
         lo2_expected);

  //
  // Store complementary CRC so that CRC of a message followed
  // by complementary CRC value produces predefined result (e.g. 0).
  //
  memcpy(buffer, kTestData, sizeof(kTestData) - 1);
  lo = 1;
  crc->Compute(buffer, sizeof(kTestData) - 1, &lo);
  size_t stored_crc_bytes = crc->StoreComplementaryCrc(
    buffer + sizeof(kTestData) - 1,
    lo, 0,
    0);

  // Compute CRC of message + complementary CRC using the same start value
  // (start value could be changed via ChangeStartValue()).
  lo1 = 1;
  crc->Compute(buffer, sizeof(kTestData) - 1 + stored_crc_bytes, &lo1);

  xprintf("Crc of message + complementary CRC = %llx, expected 0\n", lo1);

  //
  // Store CRC after the message and ensure that CRC of message + its
  // CRC produces constant result irrespective of message data.
  //
  memcpy(buffer, kTestData, sizeof(kTestData) - 1);
  lo = 1;
  crc->Compute(buffer, sizeof(kTestData) - 1, &lo);
  stored_crc_bytes = crc->StoreCrc(buffer + sizeof(kTestData) - 1, lo);

  // Compute CRC of message + its CRC using start value of 0.
  lo1 = 1;
  crc->Compute(buffer, sizeof(kTestData) - 1 + stored_crc_bytes, &lo1);

  // Ensure that it matches "predicted" constant value, irrespective
  // of a message or CRC start value.
  crc->CrcOfCrc(&lo2);
  xprintf("CrcOfCrc=%llx, expected %llx\n", lo1, lo2);

  xprintf("\n");
}

void ShowAndDelete(crcutil_interface::CRC *crc) {
  Show(crc);
  crc->Delete();
}

int main() {
  ShowAndDelete(crcutil_interface::CRC::Create(
      0xEB31D82E, 0, 32, true, 0x1111, 0, kRollWindow,
      crcutil_interface::CRC::IsSSE42Available(), NULL));
  ShowAndDelete(crcutil_interface::CRC::Create(
      0x82f63b78, 0, 32, true, 0x2222, 0, kRollWindow,
      crcutil_interface::CRC::IsSSE42Available(), NULL));
  return 0;
}