00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef lint
00044 static const char libbu_bitv_RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/bitv.c,v 14.12 2006/08/31 05:50:24 lbutler Exp $ (ARL)";
00045 #endif
00046
00047 #include "common.h"
00048
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #ifdef HAVE_STRING_H
00052 # include <string.h>
00053 #else
00054 # include <strings.h>
00055 #endif
00056 #include <ctype.h>
00057 #include "machine.h"
00058 #include "bu.h"
00059
00060
00061
00062
00063
00064
00065
00066 struct bu_bitv *
00067 bu_bitv_new(unsigned int nbits)
00068 {
00069 struct bu_bitv *bv;
00070 int bv_bytes;
00071 int total_bytes;
00072
00073 bv_bytes = BU_BITS2BYTES(nbits);
00074 total_bytes = sizeof(struct bu_bitv) - 2*sizeof(bitv_t) + bv_bytes;
00075
00076 bv = (struct bu_bitv *)bu_malloc( (size_t)total_bytes, "struct bu_bitv" );
00077 BU_LIST_INIT( &bv->l );
00078 bv->l.magic = BU_BITV_MAGIC;
00079 bv->nbits = bv_bytes * 8;
00080 return bv;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void
00092 bu_bitv_free(struct bu_bitv *bv)
00093 {
00094 BU_CK_BITV(bv);
00095
00096 bv->l.forw = bv->l.back = BU_LIST_NULL;
00097 bu_free( (char *)bv, "struct bu_bitv" );
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 void
00108 bu_bitv_clear(struct bu_bitv *bv)
00109 {
00110 BU_CK_BITV(bv);
00111
00112 BU_BITV_ZEROALL(bv);
00113 }
00114
00115
00116
00117
00118 void
00119 bu_bitv_or(struct bu_bitv *ov, const struct bu_bitv *iv)
00120 {
00121 register bitv_t *out;
00122 register const bitv_t *in;
00123 register int words;
00124
00125 if( ov->nbits != iv->nbits ) bu_bomb("bu_bitv_or: length mis-match");
00126 out = ov->bits;
00127 in = iv->bits;
00128 words = BU_BITS2WORDS(iv->nbits);
00129 #ifdef VECTORIZE
00130 # include "noalias.h"
00131 for( --words; words >= 0; words-- )
00132 out[words] |= in[words];
00133 #else
00134 while( words-- > 0 )
00135 *out++ |= *in++;
00136 #endif
00137 }
00138
00139
00140
00141
00142 void
00143 bu_bitv_and(struct bu_bitv *ov, const struct bu_bitv *iv)
00144 {
00145 register bitv_t *out;
00146 register const bitv_t *in;
00147 register int words;
00148
00149 if( ov->nbits != iv->nbits ) bu_bomb("bu_bitv_and: length mis-match");
00150 out = ov->bits;
00151 in = iv->bits;
00152 words = BU_BITS2WORDS(iv->nbits);
00153 #ifdef VECTORIZE
00154 # include "noalias.h"
00155 for( --words; words >= 0; words-- )
00156 out[words] &= in[words];
00157 #else
00158 while( words-- > 0 )
00159 *out++ &= *in++;
00160 #endif
00161 }
00162
00163
00164
00165
00166
00167
00168 void
00169 bu_bitv_vls(struct bu_vls *v, register const struct bu_bitv *bv)
00170 {
00171 int seen = 0;
00172 register int i;
00173 int len;
00174
00175 BU_CK_VLS( v );
00176 BU_CK_BITV( bv );
00177
00178 len = bv->nbits;
00179
00180 bu_vls_strcat( v, "(" );
00181
00182
00183 for( i=0; i<len; i++ ) {
00184 if( BU_BITTEST(bv, i) == 0 ) continue;
00185 if( seen ) bu_vls_strcat( v, ", " );
00186 bu_vls_printf( v, "%d", i );
00187 seen = 1;
00188 }
00189 bu_vls_strcat( v, ") " );
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 void
00199 bu_pr_bitv(const char *str, register const struct bu_bitv *bv)
00200 {
00201 struct bu_vls v;
00202
00203 BU_CK_BITV(bv)
00204 bu_vls_init( &v );
00205 bu_vls_strcat( &v, str );
00206 bu_vls_strcat( &v, ": " );
00207 bu_bitv_vls( &v, bv );
00208 bu_log("%s", bu_vls_addr( &v ) );
00209 bu_vls_free( &v );
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 void
00219 bu_bitv_to_hex(struct bu_vls *v, register const struct bu_bitv *bv)
00220 {
00221 unsigned int word_count, byte_no;
00222
00223 BU_CK_VLS( v );
00224 BU_CK_BITV( bv );
00225
00226 word_count = bv->nbits/8/sizeof( bitv_t );
00227 byte_no = sizeof( bitv_t );
00228
00229 bu_vls_extend( v, word_count * sizeof( bitv_t ) * 2 + 1 );
00230 while( word_count-- )
00231 {
00232 while( byte_no-- )
00233 {
00234 bu_vls_printf( v, "%02lx",
00235 ((bv->bits[word_count] & (((bitv_t)0xff)<<(byte_no*8))) >> (byte_no*8)) & (bitv_t)0xff );
00236 }
00237 byte_no = sizeof( bitv_t );
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246 struct bu_bitv *
00247 bu_hex_to_bitv(const char *str)
00248 {
00249 char abyte[3];
00250 const char *str_start;
00251 unsigned int len=0;
00252 int bytes;
00253 struct bu_bitv *bv;
00254 unsigned long c;
00255 int word_count, byte_no;
00256
00257 abyte[2] = '\0';
00258
00259
00260 while( isspace( *str ) )
00261 str++;
00262
00263 str_start = str;
00264
00265 while( isxdigit( *str ) )
00266 str++;
00267
00268 len = str - str_start;
00269
00270 if( len < 2 || len%2 )
00271 {
00272
00273 bu_log( "bu_hex_to_bitv: illegal hex bitv (%s)\n", str_start );
00274 return( (struct bu_bitv *)NULL );
00275 }
00276
00277 bytes = len / 2;
00278 bv = bu_bitv_new( len * 4 );
00279 bu_bitv_clear( bv );
00280 word_count = bytes/sizeof( bitv_t );
00281 byte_no = bytes % sizeof( bitv_t );
00282 if( !byte_no )
00283 byte_no = sizeof( bitv_t );
00284 else
00285 word_count++;
00286
00287 str = str_start;
00288 while( word_count-- )
00289 {
00290 while( byte_no-- )
00291 {
00292
00293 abyte[0] = *str++;
00294 abyte[1] = *str++;
00295
00296
00297 c = strtoul( abyte, (char **)NULL, 16 );
00298
00299
00300 bv->bits[word_count] |= (bitv_t)c<<(byte_no*8);
00301 }
00302 byte_no = sizeof( bitv_t );
00303 }
00304
00305 return( bv );
00306 }
00307
00308
00309
00310
00311
00312
00313 struct bu_bitv *
00314 bu_bitv_dup(register const struct bu_bitv *bv)
00315 {
00316 struct bu_bitv *bv2;
00317
00318 bv2 = bu_bitv_new( bv->nbits );
00319 bu_bitv_clear( bv2 );
00320 bu_bitv_or( bv2, bv );
00321
00322 return( bv2 );
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333