00001 /* 00002 Copyright (C) 2002-2004 The Pentagram team 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU General Public License 00006 as published by the Free Software Foundation; either version 2 00007 of the License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 00020 #include "pent_include.h" 00021 00022 #include "UCList.h" 00023 #include "UCMachine.h" 00024 #include "IDataSource.h" 00025 #include "ODataSource.h" 00026 00027 uint16 UCList::getStringIndex(uint32 index) 00028 { 00029 return elements[index*2] + (elements[index*2+1]<<8); 00030 } 00031 00032 std::string& UCList::getString(uint32 index) 00033 { 00034 uint16 sindex = getStringIndex(index); 00035 return UCMachine::get_instance()->getString(sindex); 00036 } 00037 00038 void UCList::freeStrings() 00039 { 00040 UCMachine *ucm = UCMachine::get_instance(); 00041 for (unsigned int i = 0; i < size; i++) { 00042 ucm->freeString(getStringIndex(i)); 00043 } 00044 free(); 00045 } 00046 00047 void UCList::copyStringList(UCList& l) 00048 { 00049 UCMachine *ucm = UCMachine::get_instance(); 00050 freeStrings(); 00051 for (unsigned int i = 0; i < l.size; i++) { 00052 uint16 s = ucm->duplicateString(l.getStringIndex(i)); 00053 uint8 tmp[2]; // ugly... 00054 tmp[0] = static_cast<uint8>(s & 0xFF); 00055 tmp[1] = static_cast<uint8>(s >> 8); 00056 append(tmp); 00057 } 00058 } 00059 00060 void UCList::unionStringList(UCList& l) 00061 { 00062 UCMachine *ucm = UCMachine::get_instance(); 00063 // take the union of two stringlists 00064 // i.e., append the second to this one, removing any duplicates 00065 for (unsigned int i = 0; i < l.size; i++) { 00066 if (!stringInList(l.getStringIndex(i))) { 00067 append(l[i]); 00068 } else { 00069 // free it if we're not keeping it 00070 ucm->freeString(l.getStringIndex(i)); 00071 } 00072 } 00073 l.free(); // NB: do _not_ free the strings in l, since they're in this one 00074 } 00075 00076 void UCList::substractStringList(UCList& l) 00077 { 00078 for (unsigned int i = 0; i < l.size; i++) 00079 removeString(l.getStringIndex(i)); 00080 } 00081 00082 bool UCList::stringInList(uint16 s) 00083 { 00084 std::string str = UCMachine::get_instance()->getString(s); 00085 for (unsigned int i = 0; i < size; i++) 00086 if (getString(i) == str) 00087 return true; 00088 00089 return false; 00090 } 00091 00092 void UCList::assignString(uint32 index, uint16 str) 00093 { 00094 // assign string str to element index 00095 // free old contents of element index; take ownership of str(?) 00096 00097 UCMachine::get_instance()->freeString(getStringIndex(index)); 00098 elements[index*elementsize] = static_cast<uint8>(str & 0xFF); 00099 elements[index*elementsize+1] = static_cast<uint8>(str >> 8); 00100 } 00101 00102 void UCList::removeString(uint16 s, bool nodel) 00103 { 00104 // do we need to erase all occurences of str or just the first one? 00105 // (deleting all, currently) 00106 std::string str = UCMachine::get_instance()->getString(s); 00107 for (unsigned int i = 0; i < size; i++) { 00108 if (getString(i) == str) { 00109 // free string 00110 if (!nodel) 00111 UCMachine::get_instance()->freeString(getStringIndex(i)); 00112 00113 // remove string from list 00114 elements.erase(elements.begin()+i*elementsize, 00115 elements.begin()+(i+1)*elementsize); 00116 size--; 00117 i--; // back up a bit 00118 } 00119 } 00120 } 00121 00122 void UCList::save(ODataSource* ods) 00123 { 00124 ods->write4(elementsize); 00125 ods->write4(size); 00126 ods->write(&(elements[0]), size*elementsize); 00127 } 00128 00129 00130 bool UCList::load(IDataSource* ids, uint32 version) 00131 { 00132 elementsize = ids->read4(); 00133 size = ids->read4(); 00134 elements.resize(size * elementsize); 00135 ids->read(&(elements[0]), size*elementsize); 00136 00137 return true; 00138 }