acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
block.h
1#pragma once
2
3
4#include "acme/memory/_memory.h"
5//#include "acme/prototype/prototype/_u32hash.h"
6
7
8#include "acme/prototype/collection/array_range.h"
9
10
11
12
13CLASS_DECL_ACME character_count string_get_length(const ::ansi_character* psz) noexcept;
14CLASS_DECL_ACME character_count string_safe_length(const_char_pointer psz) noexcept;
15
16
17using BLOCK = ::range < ::u8 * >;
18//using BLOCK = array_range < ::range < ::u8 * > >;
19//struct CLASS_DECL_ACME BLOCK
20//{
21//
22// ::u8 * m_pbegin;
23// ::collection::count m_iSize;
24//
25//
26// memsize length_in_bytes() const { return sizeof(::u8) * m_iSize; }
27//
28//};
29
30template<typename T, std::size_t N>
31constexpr std::size_t øarray_count(const T (&)[N])
32{
33 return N;
34}
35
36
37template <typename TYPE >
38const TYPE * __memory_address_of(const TYPE a[]) { return (TYPE *)a; }
39
40template <typename TYPE >
41const TYPE * __memory_address_of(const TYPE & a) { return &a; }
42
43
44struct CLASS_DECL_ACME block :
45 public BLOCK
46{
47
48 using PRIMITIVE_BLOCK_TAG = PRIMITIVE_BLOCK_TAG_TYPE;
49
50 //using BLOCK::BLOCK;
51
52 block() : BLOCK() {}
53 block(const block & block)
54 {
55 this->m_begin = block.m_begin;
56 this->m_end = block.m_end;
57 }
58
59 block(const range < ::u8 * > & range);
60 block(const memory_base & memory);
61 block(const memory_base * pmemory);
62 block(const atom & atom);
63
64 //template < ::collection::count c >
65 //block(const ::i8(&sz)[c])
66 //{
67
68 // this->m_begin = (::u8 *)(sz);
69 // this->m_end = (::u8 *)(this->m_begin + c);
70
71 //}
72 //template < ::collection::count c >
73 //block(const ::u8(&ba)[c])
74 //{
75
76 // this->m_begin = (::u8 *) ba;
77 // this->m_end = (::u8 *) (this->m_begin + c);
78
79 //}
80 template<const_pointer_to_prototype_character PSZ>
81 block(PSZ psz)
82 {
83 this->m_begin = (::u8 *)(psz);
84 this->m_end = (::u8 *)(psz + ::string_safe_length(psz));
85 }
86
87 template<const_array_of_prototype_character CONSTCHARACTERA>
88 block(CONSTCHARACTERA a)
89 {
90 this->m_begin = (::u8 *) (a);
91 this->m_end = (::u8 *)(&a[0] + øarray_count(a) - 1);
92 }
93 template<array_of_non_prototype_character NONCHARACTERA>
94 block(NONCHARACTERA & a)
95 {
96 this->m_begin = (::u8 *)(a);
97 this->m_end = (::u8 *)(&a[0] + øarray_count(a));
98 }
99
100 // template<prototype_character CHARACTER, ::collection::count c>
101 // requires(c > 1)
102 //block(const CHARACTER (&a)[c]) : block((const void *)a, (memsize)(sizeof(CHARACTER) * (c - 1)))
103 //{
104 //}
105 //block(const ::scoped_string & scopedstr);
106 template < prototype_integral INTEGRAL >
107 block(INTEGRAL & i) : block(e_as_little_endian_block, i) {}
108 template < typename TYPE >
109 block(enum_as_little_endian_block, TYPE & t) :
110 block((void *)&t, sizeof(t))
111 {
112#if BIG_ENDIAN
113 reverse(m_begin, m_end);
114#endif
115 }
116 template < typename TYPE >
117 block(enum_as_block, TYPE & t) : block((void *)&t, sizeof(t)) {}
118 template < typename TYPE >
119 block(enum_as_block, const TYPE & t) : block((void *)&t, sizeof(t)) {}
120 block(const void * begin, const void * end) : BLOCK((::u8 *)begin, (::u8 *)end) {}
121 template < prototype_integral INTEGRAL >
122 block(const void * data, INTEGRAL count) : BLOCK((::u8 *) data, count) { }
123
124 //block & operator = (const block & block)
125 //{
126 //
127 // if (this != &block)
128 // {
129
130 // this->m_begin = block.m_begin;
131 // this->m_end = block.m_end;
132
133 // assign_block(block);
134
135 // }
136
137 // return *this;
138
139 //}
140
141 //void * get_data() { return m_pbegin; }
142 //const void * get_data() const { return m_pbegin; }
143 //memsize get_size() const { return m_iSize; }
144 //const ::u8 * data () const { return (const ::u8 *) m_pbegin; }
145 //::u8 * data() { return (::u8 *)m_pbegin; }
146 //::collection::count size() const { return (::collection::count)m_iSize; }
147
148
149 constexpr bool has_data() const { return !this->is_empty(); }
150
151 template < typename TYPE >
152 const TYPE* as_pointer() const
153 {
154
155 return (const TYPE*)begin();
156
157 }
158
159 template < typename TYPE >
160 TYPE* as_pointer()
161 {
162
163 return (TYPE*) begin();
164
165 }
166
167
168 template<typename ITERATOR_TYPE>
169 ::range<ITERATOR_TYPE> as_range()
170 {
171 ASSERT(this->size() % sizeof(typename ::range < ITERATOR_TYPE>::ITEM) == 0);
172 return {(ITERATOR_TYPE)begin(), (ITERATOR_TYPE)end()};
173 }
174
175
176 template<typename ITERATOR_TYPE>
177 const ::range < ITERATOR_TYPE > as_range() const
178 {
179 ASSERT(this->size() % sizeof(typename ::range<ITERATOR_TYPE>::ITEM) == 0);
180 return {(ITERATOR_TYPE) begin(), (ITERATOR_TYPE)end()};
181 }
182
183
184 template<typename ITERATOR_TYPE>
185 ::character_range<ITERATOR_TYPE> as_character_range()
186 {
187 ASSERT(this->size() % sizeof(typename ::range < ITERATOR_TYPE>::ITEM) == 0);
188 return {(ITERATOR_TYPE)begin(), (ITERATOR_TYPE)end()};
189 }
190
191
192 template<typename ITERATOR_TYPE>
193 const ::character_range < ITERATOR_TYPE > as_character_range() const
194 {
195 ASSERT(this->size() % sizeof(typename ::range<ITERATOR_TYPE>::ITEM) == 0);
196 return {(ITERATOR_TYPE) begin(), (ITERATOR_TYPE)end()};
197 }
198
199
200 template < prototype_aggregate AGGREGATE >
201 block & operator = (const AGGREGATE & aggregate)
202 {
203
204 if (this->size() < sizeof(AGGREGATE))
205 {
206
207 throw_exception(error_end_of_file);
208
209 }
210
211 ::memory_copy(this->m_begin, &aggregate, sizeof(aggregate));
212
213 return *this;
214
215 }
216
217 template < character_count c >
218 block & operator = (const ::u8(&ba)[c])
219 {
220
221 if (this->size() < c)
222 {
223
224 throw_exception(error_end_of_file);
225
226 }
227
228 ::memory_copy(this->m_begin, ba, c);
229
230 return *this;
231
232 }
233
234 template < typename T >
235 block & operator >>(T & t)
236 {
237
238 if (this->size() < sizeof(T))
239 {
240
241 throw_exception(error_end_of_file);
242
243 }
244
245 ::memory_copy(&t, this->begin(), sizeof(t));
246
247 return *this;
248
249 }
250
251 template < character_count c >
252 block & operator >>(::u8(&ba)[c])
253 {
254
255 if (this->size() < c)
256 {
257
258 throw_exception(error_end_of_file);
259
260 }
261
262 memory_copy(ba, this->m_begin, c);
263
264 return *this;
265
266 }
267
268
269
270//#ifdef UNIVERSAL_WINDOWS
271//
272// ::winrt::Windows::Storage::Streams::IBuffer^ get_os_buffer(memsize pos = 0, memsize size = -1) const;
273// Array < uchar, 1U >^ get_os_bytes(memsize pos, memsize size) const;
274//
275//#endif
276
277 block & from_base64(const ::scoped_string & scopedstr) const;
278
279
280 ::std::strong_ordering compare(const block& block) const
281 {
282
283 auto commonSize = minimum(size(), block.size());
284
285 auto ordering = memory_order(begin(), block.begin(), commonSize) <=>0;
286
287 if (ordering != 0)
288 {
289
290 return ordering;
291
292 }
293
294 return size() <=> block.size();
295
296 }
297
298
299 bool operator == (const block& block) const
300 {
301
302 if (block.size() != size())
303 {
304
305 return false;
306
307 }
308
309 if (size() <= 0)
310 {
311
312 return true;
313
314 }
315
316 return memory_order(begin(), block.begin(), (size_t)size()) == 0;
317
318 }
319
320
321 bool operator != (const block& block) const
322 {
323
324 return !operator == (block);
325
326 }
327
328
329 memsize find(const ::block& blockFind, memsize start = 0) const;
330
331 inline memsize _find(const ::block& blockFind, memsize start = 0) const
332 {
333 return ((::u8*)_memory_find(
334 as_pointer<::u8>() + start, size() - start,
335 blockFind.begin(), blockFind.size())) - as_pointer <::u8>();
336
337 }
338
339
340 inline void copy(const ::block & block)
341 {
342
343 memory_copy(m_begin, block.data(), minimum(block.size(), this->size()));
344
345 }
346
347
348 inline bool begins(const ::block & block) const
349 {
350
351 if(block.is_empty())
352 {
353
354 return true;
355
356 }
357
358 if(this->size() < block.size())
359 {
360
361 return false;
362
363 }
364
365 if(::memory_order(this->data(), block.data(), block.size()) != 0)
366 {
367
368 return false;
369
370 }
371
372 return true;
373
374 }
375
376
377 inline bool ends(const ::block & block) const
378 {
379
380 if(block.is_empty())
381 {
382
383 return true;
384
385 }
386
387 if(this->size() < block.size())
388 {
389
390 return false;
391
392 }
393
394 if(::memory_order(this->end() - block.size(), block.data(), block.size()) != 0)
395 {
396
397 return false;
398
399 }
400
401 return true;
402
403 }
404
405
406 ::u8 & first_byte(::collection::index i = 0){return this->m_begin[i];}
407 ::u8 first_byte(::collection::index i = 0)const{return this->m_begin[i];}
408 ::u8 & last_byte(::collection::index i = -1){return this->m_end[i];}
409 ::u8 last_byte(::collection::index i = -1)const{return this->m_end[i];}
410
411};
412
413
414namespace acme
415{
416
417
418 template < typename T >
419 inline void memory_free(T * & p);
420
421}
422
423
424
425
426template < typename ITEM_TYPE >
428{
429public:
430
431
432 //using TYPE = ::array_range < ::range < ITEM_TYPE * > >;
433 using TYPE = ::range < ITEM_TYPE * >;
434
435
436};
437
438
439template < >
440class GET_BLOCK_TYPE< ::u8 >
441{
442public:
443
444 using TYPE = ::block;
445
446};
447
448
449template < typename TYPE >
450inline ::block as_memory_block(const TYPE & type)
451{
452
453 return { (void *)&type, (memsize) sizeof(TYPE) };
454
455}
456
457
458template < prototype_character CHARACTER >
459inline ::block as_block(const ::range<const CHARACTER *> & range)
460{
461
462 return { (void *)range.m_begin, (memsize) (range.m_end - range.m_begin) * sizeof(CHARACTER) };
463
464}
465
466
467template < >
468inline ::hash32 as_hash32 < const ::block & >(const ::block & b)
469{
470
471 if (!b)
472 {
473
474 return { 0 };
475
476 }
477
478 auto psz = b.begin();
479
480 ::u32 uHash = 0;
481
482 character_count i = 1;
483
484 auto len = minimum(64, b.size());
485
486 for (; i < len; i++)
487 {
488
489 if (i % 4 == 3)
490 {
491
492 uHash = (uHash << 5) + ((::u32 *)psz)[i >> 2];
493
494 }
495
496 }
497
498 psz += i;
499
500 i %= 4;
501
502 if (i > 0)
503 {
504
505 while (i-- >= 0) uHash = (uHash << 5) + *(--psz);
506
507 }
508
509 return { uHash };
510
511}
512
513
Definition block.h:428
Definition atom.h:237
Definition character_range.h:77
Definition memory_base.h:92
Definition memory.h:33
Definition range.h:223
include "aura/graphics/image/context.h"
Definition aaaa__defer.h:32
Definition _forward_declaration.h:1303
Definition block.h:46