00001
00002
00004
00005 * Copyright (c) 1996-2000 Erwin Coumans <[email protected]>
00006 *
00007 * Permission to use, copy, modify, distribute and sell this software
00008 * and its documentation for any purpose is hereby granted without fee,
00009 * provided that the above copyright notice appear in all copies and
00010 * that both that copyright notice and this permission notice appear
00011 * in supporting documentation. Erwin Coumans makes no
00012 * representations about the suitability of this software for any
00013 * purpose. It is provided "as is" without express or implied warranty.
00014 *
00015 */
00016
00017
00018 #include "ListValue.h"
00019 #include "StringValue.h"
00020 #include "VoidValue.h"
00021
00022 int listvalue_bufferlen(PyObject* list)
00023 {
00024 return ( ((CListValue*)list)->GetCount());
00025 }
00026
00027 PyObject* listvalue_buffer_item(PyObject* list,int index)
00028 {
00029 if (index >= 0 && index < ((CListValue*) list)->GetCount())
00030 {
00031 PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython();
00032 if (pyobj)
00033 return pyobj;
00034 else
00035 return ((CListValue*) list)->GetValue(index)->AddRef();
00036
00037 }
00038 Py_Error(PyExc_IndexError, "Python ListIndex out of range");
00039 return NULL;
00040 }
00041
00042 static PyObject *
00043 listvalue_buffer_concat(PyObject * self, PyObject * other)
00044 {
00045
00046
00047
00048
00049 CListValue* listval = (CListValue*) self;
00050 listval->AddRef();
00051 if (other->ob_type == &PyList_Type)
00052 {
00053 bool error = false;
00054
00055 int i;
00056 int numitems = PyList_Size(other);
00057 for (i=0;i<numitems;i++)
00058 {
00059 PyObject* listitem = PyList_GetItem(other,i);
00060 CValue* listitemval = listval->ConvertPythonToValue(listitem);
00061 if (listitemval)
00062 {
00063 listval->Add(listitemval);
00064 } else
00065 {
00066 error = true;
00067 }
00068 }
00069
00070 if (error)
00071 Py_Error(PyExc_SystemError, "Python Error: couldn't add one or more items to a list");
00072
00073
00074 } else
00075 {
00076 if (other->ob_type == &CListValue::Type)
00077 {
00078
00079 CListValue* otherval = (CListValue*) other;
00080
00081
00082 for (int i=0;i<otherval->GetCount();i++)
00083 {
00084 otherval->Add(listval->GetValue(i)->AddRef());
00085 }
00086 }
00087 else
00088 {
00089 CValue* objval = listval->ConvertPythonToValue(other);
00090 if (objval)
00091 {
00092 listval->Add(objval);
00093 } else
00094 {
00095 Py_Error(PyExc_SystemError, "Python Error: couldn't add item to a list");
00096
00097 }
00098 }
00099 }
00100
00101 return self;
00102 }
00103
00104 static PySequenceMethods listvalue_as_sequence = {
00105 (inquiry)listvalue_bufferlen,
00106 (binaryfunc)listvalue_buffer_concat,
00107 0,
00108 (intargfunc)listvalue_buffer_item,
00109 0,
00110 0,
00111 0,
00112 };
00113
00114 static PyMappingMethods instance_as_mapping = {
00115 (inquiry)listvalue_bufferlen,
00116 0,
00117 0,
00118 };
00119
00120
00121 PyTypeObject CListValue::Type = {
00122 PyObject_HEAD_INIT(&PyType_Type)
00123 0,
00124 "CListValue",
00125 sizeof(CListValue),
00126 0,
00127
00128 PyDestructor,
00129 0,
00130 __getattr,
00131 __setattr,
00132 0,
00133 __repr,
00134 0,
00135 &listvalue_as_sequence,
00136 0,
00137 0,
00138 0,
00139 };
00140
00141 PyParentObject CListValue::Parents[] = {
00142 &CListValue::Type,
00143 &CValue::Type,
00144 NULL
00145 };
00146
00147 PyMethodDef CListValue::Methods[] = {
00148 {NULL,NULL}
00149 };
00150
00151 PyObject* CListValue::_getattr(char* attr) {
00152 _getattr_up(CValue);
00153 }
00154
00155
00157
00159
00160 CListValue::CListValue(PyTypeObject *T )
00161 : CPropValue(T)
00162 {
00163 m_bReleaseContents=true;
00164 }
00165
00166 CListValue::~CListValue()
00167 {
00168
00169 if (m_bReleaseContents) {
00170 for (int i=0;i<m_pValueArray.size();i++) {
00171 m_pValueArray[i]->Release();
00172 }
00173 }
00174 }
00175
00176
00177 static CCString gstrListRep=CCString("List");
00178
00179 const CCString & CListValue::GetText()
00180 {
00181
00182 return gstrListRep;
00183 }
00184
00185 CValue* CListValue::GetReplica() {
00186 CListValue* replica = new CListValue(*this);
00187
00188 CValue::AddDataToReplica(replica);
00189
00190 replica->m_bReleaseContents=true;
00191
00192 int numelements = m_pValueArray.size();
00193 int i=0;
00194 replica->m_pValueArray.resize(numelements);
00195 for (i=0;i<m_pValueArray.size();i++)
00196 replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
00197
00198
00199 return replica;
00200 };
00201
00202
00203 void CListValue::SetValue(int i, CValue *val)
00204 {
00205 assertd(i < m_pValueArray.size());
00206 m_pValueArray[i]=val;
00207 }
00208
00209 void CListValue::Resize(int num)
00210 {
00211 m_pValueArray.resize(num);
00212 }
00213
00214 void CListValue::Remove(int i)
00215 {
00216 assertd(i<m_pValueArray.size());
00217 m_pValueArray.erase(m_pValueArray.begin()+i);
00218 }
00219
00220 void CListValue::ReleaseAndRemoveAll()
00221 {
00222 for (int i=0;i<m_pValueArray.size();i++)
00223 m_pValueArray[i]->Release();
00224 m_pValueArray.clear();
00225 }
00226
00227 CValue* CListValue::FindValue(const CCString & name)
00228 {
00229 CValue* resultval = NULL;
00230 int i=0;
00231
00232 while (!resultval && i < GetCount())
00233 {
00234 CValue* myval = GetValue(i);
00235
00236 if (myval->GetName() == name)
00237 resultval = GetValue(i)->AddRef();
00238 else
00239 i++;
00240
00241 }
00242 return resultval;
00243
00244 }
00245
00246 bool CListValue::SearchValue(CValue *val)
00247 {
00248 for (int i=0;i<GetCount();i++)
00249 if (val == GetValue(i))
00250 return true;
00251 return false;
00252 }
00253
00254 void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
00255 {
00256 m_bReleaseContents = bReleaseContents;
00257 }
00258
00259 bool CListValue::RemoveValue(CValue *val)
00260 {
00261 bool result=false;
00262
00263 for (int i=GetCount()-1;i>=0;i--)
00264 if (val == GetValue(i))
00265 {
00266 Remove(i);
00267 result=true;
00268 }
00269 return result;
00270 }
00271
00272 void CListValue::MergeList(CListValue *otherlist)
00273 {
00274
00275 int numelements = this->GetCount();
00276 int numotherelements = otherlist->GetCount();
00277
00278
00279 Resize(numelements+numotherelements);
00280
00281 for (int i=0;i<numotherelements;i++)
00282 {
00283 SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
00284 }
00285
00286 }