source: src/examples/strings/src/internal/VbyteSM.c @ 9ea58ca

string
Last change on this file since 9ea58ca was 9ea58ca, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

finished translating VbyteSM from C++ to cfa

  • Property mode set to 100644
File size: 3.6 KB
Line 
1#include "VbyteSM.h"
2#include "tools.h"
3
4void AddThisAfter(HandleNode_t* const this, HandleNode_t* n)
5{
6        this->next = n->next;
7        this->previous = n;
8        HandleNode_t* n_next = n->next;
9        n_next->previous = this;
10        n->next = this;
11}
12
13void DeleteNode(HandleNode_t* const this)
14{
15        HandleNode_t* next = this->next;
16        HandleNode_t* prev = this->previous;
17
18        next->previous = prev;
19        prev->next = next;
20}
21
22void MoveThisAfter(HandleNode_t* const this, const HandleNode_t* rhs)
23{
24        assertf( this->string < rhs->string, 
25        "VbyteSM: Error - Cannot move byte string starting at: %lX after byte string starting at: %lX and keep handles in ascending order",
26        (unsigned long int)this->string, 
27        (unsigned long int)rhs->string);
28
29        HandleNode_t* i;
30        for(i = rhs->next; 
31            i->string && this->string > i->string; 
32            i = i->next );
33
34        if( this != i->previous )
35        {
36                DeleteNode(this);
37                AddThisAfter(this, i->previous);
38        }
39}
40
41void MoveThisBefore(HandleNode_t* const this, const HandleNode_t* rhs)
42{
43        assertf( this->string > rhs->string,
44        "VbyteSM: Error - Cannot move byte string at: %lX before byte string at: %lX and keep handles in ascending order",
45        (unsigned long int)this->string,
46        (unsigned long int)rhs->string);
47
48        HandleNode_t* i;
49        for( i = rhs->previous; 
50             (uintptr_t)this->string == (uintptr_t)i->string;
51             i = i->previous);
52
53        if( this != i )
54        {
55                DeleteNode(this);
56                AddThisAfter(this, i->previous);
57        }
58}
59
60int ByteCopy(char_t* Dst, int DstStart, int DstLnth, char_t* Src, int SrcStart, int SrcLnth)
61{
62        for ( int i = -1; i < DstLnth - 1; i += 1) {
63                if( i == SrcLnth -1 ) {
64                        for ( ; i < DstLnth - 1; i += 1 ) {
65                                Dst[DstStart + i] = ' ';
66                        }
67                        break;
68                }
69                Dst[DstStart + i] = Src[SrcStart + i];
70        }
71}
72
73char_t* VbyteAloc(VbyteHeap* const this, int size ) {
74        unsigned int NoBytes;
75        char_t* r;
76
77        NoBytes = (uintptr_t)this->EndVbyte + size;
78        if ( NoBytes > (uintptr_t)this->ExtVbyte ) {
79                garbage(this);
80                NoBytes = ( uintptr_t )this->EndVbyte + size;
81                if ( NoBytes > ( uintptr_t )this->ExtVbyte ) {
82                        extend( this, size );
83                }
84        }
85        r = this->EndVbyte;
86        this->EndVbyte += size;
87        return r;
88}
89
90void compaction(VbyteHeap* const this) {
91        HandleNode_t* h;
92        char_t *obase, *nbase, *limit;
93
94        this->NoOfCompactions += 1;
95        this->EndVbyte = this->StartVbyte;
96        h = this->Header.next;
97        do {
98                ByteCopy( this->EndVbyte, 1, h->length, h->string, 1, h->length );
99                obase = h->string;
100                h->string = this->EndVbyte;
101                nbase = h->string;
102                this->EndVbyte += h->length;
103                limit = obase + h->length;
104                h = h->next;
105               
106                for (;;) {
107                        if ( h == &this->Header ) break;
108                        if ( h->string >= limit ) break;
109                       
110                        h->string = nbase + (( uintptr_t )h->string - ( uintptr_t )obase );
111                        h = h->next;
112                }
113        } while( h != &this->Header );
114}
115
116void garbage(VbyteHeap* const this) {
117        int AmountUsed = 0;
118        for ( HandleNode_t* i = this->Header.next; i != &this->Header; i = i->next ) {
119                AmountUsed += i->length;
120        }
121       
122        int AmountFree = ( uintptr_t )this->ExtVbyte - ( uintptr_t )this->StartVbyte - AmountUsed;
123
124        if ( AmountFree < ( int )( this->CurrSize * 0.1 )) {
125                extend( this, this->CurrSize );
126        }
127        compaction( this );
128}
129
130void extend( VbyteHeap* const this, int size ) {
131        this->NoOfExtensions;
132        char_t* OldStartVbyte = this->StartVbyte;
133
134        this->CurrSize += max(size, this->InitSize);
135        this->StartVbyte = this->EndVbyte = calloc(this->CurrSize);
136        compaction( this );
137        free( OldStartVbyte );
138}
139
140void reduce( VbyteHeap* const this, int size ) {
141        this->NoOfReductions += 1;
142        char_t* OldStartVbyte = this->StartVbyte;
143       
144        this->CurrSize -= size;
145        this->StartVbyte = this->EndVbyte = calloc(this->CurrSize);
146        this->ExtVbyte = (void *)( this->StartVbyte + this->CurrSize );
147        compaction(this);
148        free( OldStartVbyte );
149}
Note: See TracBrowser for help on using the repository browser.