EnglishРусский  

   ..

   compare.c

   fields.c

   ged.c

   ged.def

   ged.h

   record.c

   select.c

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2009, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * Author: Alexey Krivonogov ( gentee )
 11 *
 12 ******************************************************************************/
 13 
 14 #include "ged.h"
 15 
 16 cmpfunc  fcmp[] = { 0, &cmpbyte, &cmpubyte, &cmpshort, &cmpushort, &cmpint, 
 17                      &cmpuint, 0, 0, 0, 0, &cmpstr, &cmpustr };
 18 
 19 /* Filter format
 20    uint size of data
 21    cmd - SF_
 22        uint - number of the field from 0
 23        uint - len [for string fields]
 24        uint - value
 25 */
 26 
 27 /* Index format
 28    uint - size of data
 29    uint - number of the field
 30    uint - flags & len
 31 */
 32 
 33 int    ges_compare( pvoid left, pvoid right, uint param )
 34 {
 35    pgedfield  pfield;
 36    pubyte     lrec, rrec;
 37    pgedsel    psel = (pgedsel)param;
 38    puint      pind = ( puint )buf_ptr( PINDEX );
 39    puint      pend = ( puint )(( pubyte )pind + buf_len( PINDEX ));
 40    uint       len, flag;
 41    int        ok = 0;
 42    
 43    lrec = psel->pdb->db + ( *(pubyte)left - 1 ) * psel->pdb->fsize;
 44    rrec = psel->pdb->db + ( *(pubyte)right - 1 ) * psel->pdb->fsize;
 45 
 46    while ( pind < pend && !ok )
 47    {
 48       pfield = psel->pdb->fields + *pind++;
 49       flag = *pind++;
 50       
 51       len = flag & 0xFFFF;
 52       if ( !len )
 53          len = pfield->width;
 54       ok = fcmp[ pfield->ftype ]( lrec + pfield->offset, 
 55                                   rrec + pfield->offset, len );
 56       if ( flag & IF_DESC )
 57          ok = -ok;
 58    }
 59    return ok;
 60 }
 61 
 62 BOOL   ges_updateindex( pgedsel psel )
 63 {
 64    if ( buf_len( PINDEX ))
 65    {
 66       quicksort( buf_ptr( PSELECT ), psel->reccount, sizeof( uint ), 
 67                  (cmpfunc)&ges_compare, (uint)psel );
 68    }
 69    return TRUE;
 70 }
 71 
 72 BOOL   ges_reverse( pgedsel psel )
 73 {
 74    uint   i, itemp, count = psel->reccount >> 1;
 75    puint  pi = ( puint )buf_ptr( PSELECT );
 76 
 77    for (i = 0; i < count; i++ )
 78    {
 79       itemp = pi[i];
 80       pi[i] = pi[ psel->reccount - i - 1 ];
 81       pi[ psel->reccount - i - 1 ] = itemp;
 82    }
 83    ges_goto( psel, psel->reccount - psel->reccur + 1 );
 84    return TRUE;
 85 }
 86 
 87 BOOL   ges_index( pgedsel psel, puint index )
 88 {
 89    buf_copy( PINDEX, (pubyte)index + sizeof( uint ), *index );
 90 
 91    return ges_updateindex( psel );
 92 }
 93 
 94 BOOL   ges_update( pgedsel psel )
 95 {
 96    uint   i;
 97    pubyte prec;
 98    pged   pdb;
 99    puint  pstart = ( puint )buf_ptr( PFILTER );
100    puint  pend = ( puint )(( pubyte )pstart + buf_len( PFILTER ));
101 
102    pdb = psel->pdb;
103    prec = pdb->db;
104    buf_clear( PSELECT );
105    for ( i = 0; i < pdb->reccount; i++ )
106    {
107       puint  pflt = pstart;
108       uint   ok = 0;
109       uint   ifield, cmd, not, or, len, type;
110 
111       if ( *prec )   // Deleted mark
112          continue;
113       while ( pflt < pend )
114       {
115          cmd = *pflt & 0xFFFFFF;
116          not = *pflt & SF_NOT;
117          or  = *pflt & SF_OR;
118          
119          if ( cmd > SF_ALL )
120          {
121             ifield = *++pflt;
122             pflt++;
123             type = pdb->fields[ ifield ].ftype;
124             if ( type == FT_STR )
125                len = *pflt++;
126             else
127                if ( type == FT_USTR )
128                   len = *pflt++;
129          }
130          switch ( cmd )
131          {
132             case SF_ALL:
133                ok = !*prec;
134                break;
135             case SF_EQ:
136                ok = !fcmp[ type ]( pflt, 
137                            prec + pdb->fields[ ifield ].offset, len );
138                break;
139             case SF_LESS:
140                ok = fcmp[ type ](  
141                            prec + pdb->fields[ ifield ].offset, pflt, len ) < 0;
142                break;
143             case SF_GREAT:
144                ok = fcmp[ type ]( 
145                            prec + pdb->fields[ ifield ].offset, pflt,  len ) > 0;
146                break;
147             case SF_END:
148                break;
149          }
150          if ( not )
151             ok = !ok;
152          if ( or )
153          {
154             if ( ok ) break;
155          }
156          else
157             if ( !ok ) break;
158          switch ( type )
159          {
160             case FT_STR:
161                pflt = ( puint )((pubyte)pflt + len );
162                break;
163             case FT_USTR:
164                pflt = ( puint )((pubyte)pflt + ( len << 1 ));
165                break;
166             default:
167                pflt++; 
168          }
169       }
170       if ( ok )
171       {
172          buf_appenduint( PSELECT, i + 1 );
173       }
174       prec += pdb->fsize;
175    }
176    psel->reccount = buf_len( PSELECT ) >> 2;
177 
178    ges_updateindex( psel );
179    ges_goto( psel, 1 );
180    return TRUE;
181 }
182 
183 BOOL   ges_select( pgedsel psel, pged pdb, puint filter, puint index )
184 {
185    psel->sm = mem_alloc( sizeof( selmem ));
186 
187    mem_zero( psel->sm, sizeof( selmem ));
188    buf_init( PSELECT );
189    buf_init( PINDEX );
190    buf_init( PFILTER );
191 
192    psel->pdb = pdb;
193    buf_copy( PFILTER, (pubyte)filter + sizeof( uint ), *filter );
194    ges_update( psel );
195    ges_index( psel, index );
196    ges_goto( psel, 1 );
197 
198    return TRUE;
199 }
200 
201 BOOL   ges_close( pgedsel psel )
202 {
203    buf_delete( PSELECT );
204    buf_delete( PINDEX );
205    buf_delete( PFILTER );
206    mem_free( psel->sm );
207 
208    return TRUE;
209 }
210 
211 uint  ges_goto( pgedsel psel, uint pos )
212 {
213    if ( pos > psel->reccount )
214       pos = 0;
215    psel->reccur = pos;
216    return psel->reccur;
217 }
218 
219 uint  ges_recno( pgedsel psel )
220 {
221    if ( !psel->reccur )
222       return 0;
223 
224    return *( ( puint )buf_ptr( PSELECT ) + psel->reccur - 1 );
225 }
226 
227 BOOL  ges_eof( pgedsel psel )
228 {
229    return !psel->reccur;
230 }
231 
232 /*
233 pgedsel ged_select( pgedsel psel, pged pdb )
234 {
235    return psel;
236 }
237 
238 pubyte ged_goto( pgedsel psel, uint pos )
239 {
240    pged pdb = psel->pdb;
241 
242    if ( pos > pdb->reccount && !pos )
243    {
244       psel->reccur = 0;
245       psel->recptr = buf_ptr( &psel->record );
246       mem_zero( psel->recptr, pdb->fsize + 1 );
247    }
248    else
249    {
250       psel->reccur = pos;
251       psel->recptr = ( pubyte )buf_ptr( &pdb->data ) + pdb->head->oversize +
252                     ( pos - 1 ) * pdb->fsize; 
253    }
254    return psel->recptr;
255 }
256 */
Редактировать