root/trunk/orca/array.c

Revision 167, 3.9 kB (checked in by krobillard, 2 years ago)

Fixed a couple cases where reading beyond end of buffer.
Optimized ur_arrayErase() when elemSize == 16 and WORDSIZE == 64.

Line 
1 /*============================================================================
2     ORCA Interpreter
3     Copyright (C) 2005-2006  Karl Robillard
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 ===========================================================================*/
19
20
21 #include "os.h"
22 #include "ovalue.h"
23
24
25 void orArrayInit( OArray* arr, int elemSize, int elemCount )
26 {
27     long size = elemSize * elemCount;
28     if( size )
29     {
30         arr->buf = memAlloc( size );
31         if( arr->buf )
32             arr->avail = elemCount;
33         else
34             arr->avail = 0;
35     }
36     else
37     {
38         arr->buf   = 0;
39         arr->avail = 0;
40     }
41     arr->used  = 0;
42 }
43
44
45 /**
46   Frees the memory pointed to by arr->buf.
47 */
48 void orArrayFree( OArray* arr )
49 {
50     assert( arr );
51
52     if( arr->buf )
53     {
54         memFree( arr->buf );
55         arr->buf   = 0;
56         arr->avail = 0;
57         arr->used  = 0;
58     }
59 }
60
61
62 /**
63   Allocates enough memory to hold elemCount elements.
64   arr->used is not changed.
65 */
66 void orArrayReserve( OArray* arr, int elemSize, int elemCount )
67 {
68     assert( arr );
69     assert( arr->avail > -1 );
70
71     if( elemCount > arr->avail )
72     {
73         int count;
74         void* buf;
75
76         /* Double the buffer size (unless that is not big enough). */
77         count = arr->avail * 2;
78         if( count < elemCount )
79         {
80             count = (elemCount < 8) ? 8 : elemCount;
81         }
82
83         buf = memAlloc( elemSize * count );
84         assert( buf );
85         if( buf )
86         {
87             if( arr->buf )
88             {
89                 if( arr->used )
90                     memCpy( buf, arr->buf, elemSize * arr->used );
91                 memFree( arr->buf );
92             }
93             arr->buf   = buf;
94             arr->avail = count;
95         }
96     }
97 }
98
99
100 /**
101   Remove count elements from the array starting at index.
102 */
103 void orArrayErase( OArray* arr, int elemSize, int index, int count )
104 {
105     assert( arr );
106     assert( index < arr->used );
107
108     if( (index + count) >= arr->used )
109     {
110         arr->used = index;
111         return;
112     }
113
114     if( elemSize == 1 )
115     {
116         char* buf;
117         char* src;
118         char* end;
119
120         buf = arr->charArray + index;
121         src = buf + count;
122         end = arr->charArray + arr->used;
123
124         while( src != end )
125             *buf++ = *src++;
126     }
127     else if( elemSize == 16 )
128     {
129 #if __WORDSIZE == 64
130         uint64_t* buf;
131         uint64_t* src;
132         uint64_t* end;
133
134         buf = ((uint64_t*) arr->buf) + (index * 2);
135         src = buf + (count * 2);
136         end = ((uint64_t*) arr->buf) + (arr->used * 2);
137
138         while( src != end )
139         {
140             *buf++ = *src++;
141             *buf++ = *src++;
142         }
143 #else
144         uint32_t* buf;
145         uint32_t* src;
146         uint32_t* end;
147
148         buf = ((uint32_t*) arr->buf) + (index * 4);
149         src = buf + (count * 4);
150         end = ((uint32_t*) arr->buf) + (arr->used * 4);
151
152         while( src != end )
153         {
154             *buf++ = *src++;
155             *buf++ = *src++;
156             *buf++ = *src++;
157             *buf++ = *src++;
158         }
159 #endif
160     }
161     else
162     {
163         char* buf;
164         buf = arr->charArray + (elemSize * index);
165         memMove( buf, buf + (elemSize * count),
166                  elemSize * (arr->used - index - count) );
167     }
168
169     arr->used -= count;
170 }
171
172
173 /*EOF*/
Note: See TracBrowser for help on using the browser.