1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
*/
/*! \file flatom.cpp
\brief Definitions for handling the t_atom type and lists thereof.
*/
#include "flext.h"
#include <string.h> // for memcpy
#if FLEXT_SYS != FLEXT_SYS_JMAX
int flext::CmpAtom(const t_atom &a,const t_atom &b)
{
if(GetType(a) == GetType(b)) {
switch(GetType(a)) {
case A_FLOAT: return GetFloat(a) == GetFloat(b)?0:(GetFloat(a) < GetFloat(b)?-1:1);
#if FLEXT_SYS == FLEXT_SYS_MAX
case A_INT: return GetInt(a) == GetInt(b)?0:(GetInt(a) < GetInt(b)?-1:1);
#endif
case A_SYMBOL: return GetSymbol(a) == GetSymbol(b)?0:(GetSymbol(a) < GetSymbol(b)?-1:1);
#if FLEXT_SYS == FLEXT_SYS_PD
case A_POINTER: return GetPointer(a) == GetPointer(b)?0:(GetPointer(a) < GetPointer(b)?-1:1);
#endif
default:
// can't be compared.....
FLEXT_ASSERT(false);
return 0;
}
}
else
return GetType(a) < GetType(b)?-1:1;
}
#else
#error Not implemented
#endif
t_atom *flext::CopyList(int argc,const t_atom *argv)
{
t_atom *dst = new t_atom[argc];
memcpy(dst,argv,argc*sizeof(t_atom));
return dst;
}
static void copyatoms(int cnt,t_atom *dst,const t_atom *src)
{
if(dst < src)
// forward
memcpy(dst,src,cnt*sizeof(t_atom));
else
// backwards
while(cnt--) dst[cnt] = src[cnt];
}
void flext::AtomList::Alloc(int sz,int keepix,int keeplen,int keepto)
{
if(lst) {
if(cnt == sz) return; // no change
t_atom *l = new t_atom[sz];
if(keepix >= 0)
// keep contents
copyatoms(keeplen >= 0?keeplen:(cnt > sz?sz:cnt),l+keepto,lst+keepix);
delete[] lst;
lst = l,cnt = sz;
}
else {
FLEXT_ASSERT(cnt == 0);
lst = new t_atom[cnt = sz];
}
}
flext::AtomList::~AtomList() { Free(); }
void flext::AtomList::Free()
{
if(lst) {
delete[] lst; lst = NULL;
cnt = 0;
}
else
FLEXT_ASSERT(cnt == 0);
}
flext::AtomList &flext::AtomList::Set(int argc,const t_atom *argv,int offs,bool resize)
{
int ncnt = argc+offs;
if(resize) Alloc(ncnt);
// argv can be NULL independently from argc
if(argv) copyatoms(argc,lst+offs,argv);
return *this;
}
int flext::AtomList::Compare(const AtomList &a) const
{
if(Count() == a.Count()) {
for(int i = 0; i < Count(); ++i) {
int cmp = CmpAtom(lst[i],a[i]);
if(cmp) return cmp;
}
return 0;
}
else
return Count() < a.Count()?-1:1;
}
flext::AtomListStaticBase::~AtomListStaticBase() { Free(); }
void flext::AtomListStaticBase::Alloc(int sz,int keepix,int keeplen,int keepto)
{
if(sz < precnt) {
if(lst != predata && lst) {
if(keepix >= 0)
// keep contents
copyatoms(keeplen >= 0?keeplen:(cnt > sz?sz:cnt),predata+keepto,lst+keepix);
AtomList::Free();
}
lst = predata,cnt = sz;
}
else
AtomList::Alloc(sz,keepix,keeplen,keepto);
}
void flext::AtomListStaticBase::Free()
{
if(lst != predata) AtomList::Free();
else lst = NULL,cnt = 0;
}
|