1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, 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 /*-----------------------------------------------------------------------------
15 * Id: buffer L "Buffer"
16 *
17 * Summary: Binary data. It is possible to use variables of the #b(buf) type
18 for working with memory. Use this type if you want to store and manage the
19 binary data.
20 *
21 * List: *Operators,buf_oplen,buf_opind,buf_opeq,buf_opsum,buf_opadd,buf_opeqeq,
22 buf_types2buf,
23 *Methods,buf_align,buf_append,buf_clear,buf_copy,buf_crc,buf_del,
24 buf_expand,buf_free,buf_findch,buf_getmultistr,buf_getmultiustr,
25 buf_insert,
26 buf_ptr,buf_read,buf_replace,buf_reserve,buf_write,buf_writeappend
27 *
28 -----------------------------------------------------------------------------*/
29
30 /*-----------------------------------------------------------------------------
31 * Id: buf_opsum F4
32 *
33 * Summary: Putting two buffers together and creating a resulting buffer.
34 *
35 * Return: The new result buffer.
36 *
37 -----------------------------------------------------------------------------*/
38
39 operator buf +<result>( buf left, buf right )
40 {
41 ( result = left ) += right
42 }
43
44 /*-----------------------------------------------------------------------------
45 * Id: buf_types2buf F3
46 *
47 * Summary: Converting types to buf. Convert #b(uint) to #b(buf) =>
48 #b('buf( uint )').
49 *
50 * Title: buf( type )
51 *
52 * Return: The result buffer.
53 *
54 -----------------------------------------------------------------------------*/
55
56 method buf uint.buf<result>
57 {
58 result.free()
59 result += this
60 }
61
62 /*-----------------------------------------------------------------------------
63 * Id: buf_replace F2
64 *
65 * Summary: Replacing data. The method replaces binary data in an object.
66 *
67 * Params: offset - The offset of the data being replaced.
68 size - The size of the data being replaced.
69 value - The #b(buf) object with new data.
70 *
71 * Return: #lng/retobj#
72 *
73 -----------------------------------------------------------------------------*/
74
75 method buf buf.replace( uint offset, uint size, buf value )
76 {
77 if offset >= *this : return this += value
78
79 if offset + size > *this : size = *this - offset
80
81 uint len = *value
82 int dif = len - size
83 uint end = offset + size
84
85 if dif < 0 : this.del( end - uint( -dif ), uint( -dif ))
86 if dif > 0
87 {
88 this.expand( *this + len )
89 mmove( this.data + end + dif,
90 this.data + end, this.use - end )
91 this.use += dif
92 }
93 mcopy( this.data + offset, value.data, len )
94
95 return this
96 }
97
98 /*-----------------------------------------------------------------------------
99 * Id: buf_insert F2
100 *
101 * Summary: Data insertion. The method inserts one buf object into another.
102 *
103 * Params: offset - The offset where data will be inserted. If the offset is /
104 greater than the size, data is added to the end to the buffer.
105 value - The #b(buf) object with the data to be inserted.
106 *
107 * Return: #lng/retobj#
108 *
109 -----------------------------------------------------------------------------*/
110
111 method buf buf.insert( uint offset, buf value )
112 {
113 return this.insert( offset, value.ptr(), *value )
114 }
115
116 /*-----------------------------------------------------------------------------
117 * Id: buf_crc F3
118 *
119 * Summary: Calculating the checksum. The method calculates the checksum of data
120 for an object of the #b(buf).
121 *
122 * Return: The checksum is returned.
123 *
124 -----------------------------------------------------------------------------*/
125
126 method uint buf.crc
127 {
128 return crc( this.data, this.use, 0xFFFFFFFF )
129 }
130
131 /*-----------------------------------------------------------------------------
132 * Id: buf_align F3
133 *
134 * Summary: Data alignment. The method aligns the binary data and appends
135 zeros if it is required.
136 *
137 * Return: #lng/retobj#
138 *
139 -----------------------------------------------------------------------------*/
140
141 method buf buf.align
142 {
143 reserved zero[4]
144
145 if this.use & 3
146 {
147 this.append( &zero, 4 - ( this.use & 3 ))
148 }
149 return this
150 }
151
152 /*-----------------------------------------------------------------------------
153 * Id: buf_read F2
154 *
155 * Summary: Reading from a file. The method reads data from the file.
156 *
157 * Params: filename - Filename.
158 *
159 * Return: The size of the read data.
160 *
161 -----------------------------------------------------------------------------*/
162
163 method uint buf.read( str filename )
164 {
165 file f
166 this.use = 0
167 if f.open( filename, $OP_READONLY )
168 {
169 uint size = f.getsize()
170 .reserve( size + 128 ) // резервируем для возможного str
171 this.use = f.read( this.data, size )
172 f.close( )
173 }
174 return this.use
175 }
176
177 /*-----------------------------------------------------------------------------
178 * Id: buf_write F2
179 *
180 * Summary: Writing to a file. The method writes data to the file.
181 *
182 * Params: filename - Filename.
183 *
184 * Return: The size of the written data.
185 *
186 -----------------------------------------------------------------------------*/
187
188 method uint buf.write( str filename )
189 {
190 file f
191 uint wr
192
193 if f.open( filename, $OP_CREATE )
194 {
195 wr = f.write( this.data, *this )
196 f.close( )
197 return wr
198 }
199 return 0
200 }
201
202 /*-----------------------------------------------------------------------------
203 ** Id: buf_writeappend F2
204 *
205 * Summary: Appending data to a file. The method appends data to the specified
206 file.
207 *
208 * Params: filename - Filename.
209 *
210 * Return: The size of the written data.
211 *
212 -----------------------------------------------------------------------------*/
213
214 method uint buf.writeappend( str filename )
215 {
216 file f
217 uint wr
218
219 if f.open( filename, $OP_ALWAYS )
220 {
221 f.setpos( 0, $FILE_END )
222 wr = f.write( this.data, *this )
223 f.close( )
224 return wr
225 }
226 return 0
227 }
228
229 /*Тип buf является встроенным
230 Структура buf включена в компилятор:
231 type buf < index = byte > {
232 uint data
233 uint use // занятый размер буфера
234 uint size // полный размер буфера
235 uint step // На сколько минимально увеличивать размер
236 }
237 В компилятор включены следующее методы и операции:
238 buf buf.append( uint ptr, uint size )
239 buf buf.array( uint index ) скрыт
240 buf buf.clear()
241 buf buf.copy( uint ptr, uint size )
242 buf buf.del( uint offset, uint size )
243 buf.delete() скрыт
244 buf buf.expand( uint size )
245 buf buf.free()
246 uint buf.findch( uint ch )
247 uint buf.index( uint index ) скрыт
248 buf buf.init() скрыт
249 buf buf.insert( uint off ptr size ) скрыт
250 buf buf.load( uint ptr, uint size )//Системный метод
251 uint buf.ptr()
252 buf buf.reserve( uint size )
253
254 *buf
255 buf = buf
256 buf += buf
257 buf += ubyte
258 buf += ushort
259 buf += uint
260 buf += ulong
261 buf == buf
262 buf != buf
263
264 */