OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [lib/] [v2_0/] [src/] [int64.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./lib/current/src/int64.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    hmt
57
// Contributors: hmt
58
// Date:         2000-05-30
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/** file: test.c - test of 64-bit integer stuff
93
*
94
*
95
* 21-jan-1998: David Perkins <dperkins@dsperkins.com>
96
*
97
*/
98
 
99
#include <config.h>
100
#include <sys/types.h>
101
#include <stdio.h>
102
#include <stdlib.h>
103
#include <ctype.h>
104
#if HAVE_STRING_H
105
#include <string.h>
106
#else
107
#include <strings.h>
108
#endif
109
#if HAVE_WINSOCK_H
110
#include <winsock.h>
111
#endif
112
#include "asn1.h"
113
#include "int64.h"
114
 
115
#define TRUE 1
116
#define FALSE 0
117
 
118
/** divBy10 - divide an unsigned 64-bit integer by 10
119
*
120
* call with:
121
*   u64 - number to be divided
122
*   pu64Q - location to store quotient
123
*   puR - location to store remainder
124
*
125
*/
126
void
127
divBy10(U64 u64,
128
        U64 *pu64Q,
129
        unsigned int *puR)
130
{
131
    unsigned long ulT;
132
    unsigned long ulQ;
133
    unsigned long ulR;
134
 
135
 
136
    /* top 16 bits */
137
    ulT = (u64.high>>16) & 0x0ffff;
138
    ulQ = ulT/10;
139
    ulR = ulT%10;
140
    pu64Q->high = ulQ<<16;
141
 
142
    /* next 16 */
143
    ulT = (u64.high & 0x0ffff);
144
        ulT += (ulR<<16);
145
    ulQ = ulT/10;
146
    ulR = ulT%10;
147
    pu64Q->high = pu64Q->high | ulQ;
148
 
149
    /* next 16 */
150
    ulT = ((u64.low>>16) & 0x0ffff) + (ulR<<16);
151
    ulQ = ulT/10;
152
    ulR = ulT%10;
153
    pu64Q->low = ulQ<<16;
154
 
155
    /* final 16 */
156
    ulT = (u64.low & 0x0ffff);
157
        ulT += (ulR<<16);
158
    ulQ = ulT/10;
159
    ulR = ulT%10;
160
    pu64Q->low = pu64Q->low | ulQ;
161
 
162
    *puR = (unsigned int)(ulR);
163
 
164
 
165
} /* divBy10 */
166
 
167
 
168
/** multBy10 - multiply an unsigned 64-bit integer by 10
169
*
170
* call with:
171
*   u64 - number to be multiplied
172
*   pu64P - location to store product
173
*
174
*/
175
void
176
multBy10(U64 u64,
177
         U64 *pu64P)
178
{
179
    unsigned long ulT;
180
    unsigned long ulP;
181
    unsigned long ulK;
182
 
183
 
184
    /* lower 16 bits */
185
    ulT = u64.low & 0x0ffff;
186
    ulP = ulT * 10;
187
    ulK = ulP>>16;
188
    pu64P->low = ulP & 0x0ffff;
189
 
190
    /* next 16 */
191
    ulT = (u64.low>>16) & 0x0ffff;
192
    ulP = (ulT * 10) + ulK;
193
    ulK = ulP>>16;
194
    pu64P->low = (ulP & 0x0ffff)<<16 | pu64P->low;
195
 
196
    /* next 16 bits */
197
    ulT = u64.high & 0x0ffff;
198
    ulP = (ulT * 10) + ulK;
199
    ulK = ulP>>16;
200
    pu64P->high = ulP & 0x0ffff;
201
 
202
    /* final 16 */
203
    ulT = (u64.high>>16) & 0x0ffff;
204
    ulP = (ulT * 10) + ulK;
205
    ulK = ulP>>16;
206
    pu64P->high = (ulP & 0x0ffff)<<16 | pu64P->high;
207
 
208
 
209
} /* multBy10 */
210
 
211
 
212
/** incrByU16 - add an unsigned 16-bit int to an unsigned 64-bit integer
213
*
214
* call with:
215
*   pu64 - number to be incremented
216
*   u16 - amount to add
217
*
218
*/
219
void
220
incrByU16(U64 *pu64,
221
          unsigned int u16)
222
{
223
    unsigned long ulT1;
224
    unsigned long ulT2;
225
    unsigned long ulR;
226
    unsigned long ulK;
227
 
228
 
229
    /* lower 16 bits */
230
    ulT1 = pu64->low;
231
    ulT2 = ulT1 & 0x0ffff;
232
    ulR = ulT2 + u16;
233
    ulK = ulR>>16;
234
    if (ulK == 0) {
235
        pu64->low = ulT1 + u16;
236
        return;
237
    }
238
 
239
    /* next 16 bits */
240
    ulT2 = (ulT1>>16) & 0x0ffff;
241
    ulR = ulT2+1;
242
    ulK = ulR>>16;
243
    if (ulK == 0) {
244
        pu64->low = ulT1 + u16;
245
        return;
246
    }
247
 
248
    /* next 32 - ignore any overflow */
249
    pu64->low = (ulT1 + u16) & 0x0FFFFFFFFL;
250
    pu64->high++;
251
 
252
} /* incrByV16 */
253
 
254
void
255
incrByU32(U64 *pu64,
256
          unsigned int u32)
257
{
258
  unsigned int tmp;
259
  tmp = pu64->low;
260
  pu64->low += u32;
261
  if (pu64->low < tmp)
262
    pu64->high++;
263
}
264
 
265
/* pu64out = pu64one - pu64two */
266
void
267
u64Subtract(U64 *pu64one,
268
            U64 *pu64two,
269
            U64 *pu64out)
270
{
271
  if (pu64one->low > pu64two->low) {
272
    pu64out->low = 0xffffffff - pu64two->low + pu64one->low + 1;
273
    pu64out->high = pu64one->high - pu64two->high - 1;
274
  } else {
275
    pu64out->low = pu64one->low - pu64two->low;
276
    pu64out->high = pu64one->high - pu64two->high;
277
  }
278
}
279
 
280
/** zeroU64 - set an unsigned 64-bit number to zero
281
*
282
* call with:
283
*   pu64 - number to be zero'ed
284
*
285
*/
286
void
287
zeroU64(U64 *pu64)
288
{
289
 
290
    pu64->low = 0;
291
    pu64->high = 0;
292
} /* zeroU64 */
293
 
294
 
295
/** isZeroU64 - check if an unsigned 64-bit number is
296
*
297
* call with:
298
*   pu64 - number to be zero'ed
299
*
300
*/
301
int
302
isZeroU64(U64 *pu64)
303
{
304
 
305
    if ((pu64->low == 0) && (pu64->high == 0))
306
        return(TRUE);
307
    else
308
        return(FALSE);
309
 
310
} /* isZeroU64 */
311
 
312
void
313
printU64(char * buf, /* char [I64CHARSZ+1]; */
314
         U64 *pu64)
315
{
316
  U64 u64a;
317
  U64 u64b;
318
 
319
  char aRes [I64CHARSZ+1];
320
  unsigned int u;
321
  int j;
322
 
323
  u64a.high = pu64->high;
324
  u64a.low = pu64->low;
325
  aRes[I64CHARSZ] = 0;
326
  for (j = 0; j < I64CHARSZ; j++) {
327
    divBy10(u64a, &u64b, &u);
328
    aRes[(I64CHARSZ-1)-j] = (char)('0' + u);
329
    u64a.high = u64b.high;
330
    u64a.low = u64b.low;
331
    if (isZeroU64(&u64a))
332
      break;
333
  }
334
  strcpy(buf, &aRes[(I64CHARSZ-1)-j]);
335
}
336
 
337
void
338
printI64(char * buf, /* char [I64CHARSZ+1]; */
339
         U64 *pu64)
340
{
341
  U64 u64a;
342
  U64 u64b;
343
 
344
  char aRes [I64CHARSZ+1];
345
  unsigned int u;
346
  int j, sign=0;
347
 
348
  if (pu64->high & 0x80000000) {
349
    u64a.high = ~pu64->high;
350
    u64a.low = ~pu64->low;
351
    sign = 1;
352
    incrByU32(&u64a, 1);  /* bit invert and incr by 1 to print 2s complement */
353
  } else {
354
    u64a.high = pu64->high;
355
    u64a.low = pu64->low;
356
  }
357
 
358
  aRes[I64CHARSZ] = 0;
359
  for (j = 0; j < I64CHARSZ; j++) {
360
    divBy10(u64a, &u64b, &u);
361
    aRes[(I64CHARSZ-1)-j] = (char)('0' + u);
362
    u64a.high = u64b.high;
363
    u64a.low = u64b.low;
364
    if (isZeroU64(&u64a))
365
      break;
366
  }
367
  if (sign == 1) {
368
    aRes[(I64CHARSZ-1)-j-1] = '-';
369
    strcpy(buf, &aRes[(I64CHARSZ-1)-j-1]);
370
    return;
371
  }
372
  strcpy(buf, &aRes[(I64CHARSZ-1)-j]);
373
}
374
 
375
int
376
read64(U64 *i64,
377
       const char *string)
378
{
379
  U64 i64p;
380
  unsigned int u;
381
  int sign = 0;
382
  int ok = 0;
383
 
384
  zeroU64(i64);
385
  if (*string == '-') {
386
    sign = 1;
387
    string++;
388
  }
389
 
390
  while (*string && isdigit(*string)) {
391
    ok = 1;
392
    u = *string - '0';
393
    multBy10(*i64, &i64p);
394
    memcpy(i64, &i64p, sizeof(i64p));
395
    incrByU16(i64, u);
396
    string++;
397
  }
398
  if (sign) {
399
    i64->high = ~i64->high;
400
    i64->low = ~i64->low;
401
    incrByU16(i64,1);
402
  }
403
  return ok;
404
}
405
 
406
 
407
 
408
 
409
#ifdef TESTING
410
void
411
main(int argc, char *argv[])
412
{
413
    int i;
414
    int j;
415
    int l;
416
    unsigned int u;
417
    U64 u64a;
418
    U64 u64b;
419
#define MXSZ 20
420
    char aRes[MXSZ+1];
421
 
422
 
423
    if (argc < 2) {
424
        printf("This program takes numbers from the command line\n"
425
               "and prints them out.\n"
426
               "Usage: test <unsignedInt>...\n");
427
        exit(1);
428
    }
429
 
430
    aRes[MXSZ] = 0;
431
 
432
    for (i = 1; i < argc; i++) {
433
        l = strlen(argv[i]);
434
        zeroU64(&u64a);
435
        for (j = 0; j < l; j++) {
436
            if (!isdigit(argv[i][j])) {
437
                printf("Argument is not a number \"%s\"\n", argv[i]);
438
                exit(1);
439
            }
440
            u = argv[i][j] - '0';
441
            multBy10(u64a, &u64b);
442
            u64a = u64b;
443
            incrByU16(&u64a, u);
444
        }
445
 
446
        printf("number \"%s\" in hex is '%08x%08x'h\n",
447
                argv[i], u64a.high, u64a.low);
448
 
449
        printf("number is \"%s\"\n", printU64(&u64a));
450
        for (j = 0; j < MXSZ; j++) {
451
            divBy10(u64a, &u64b, &u);
452
            aRes[(MXSZ-1)-j] = (char)('0' + u);
453
            u64a = u64b;
454
            if (isZeroU64(&u64a))
455
                break;
456
        }
457
 
458
        printf("number is \"%s\"\n", &aRes[(MXSZ-1)-j]);
459
    }
460
        exit(0);
461
} /* main */
462
#endif /* TESTING */
463
 
464
/* file: test.c */
465
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.