00001 // Filename: nameUniquifier.cxx 00002 // Created by: drose (16Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "nameUniquifier.h" 00020 00021 #include <notify.h> 00022 00023 #include <stdio.h> 00024 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: NameUniquifier::Constructor 00028 // Access: Public 00029 // Description: Creates a new NameUniquifier. 00030 // 00031 // The separator string is used to separate the original 00032 // name (or supplied prefix) and the generated number 00033 // when a name must be generated. 00034 // 00035 // If the original name is empty, the empty string is 00036 // used, followed by the generated number. 00037 //////////////////////////////////////////////////////////////////// 00038 NameUniquifier:: 00039 NameUniquifier(const string &separator, 00040 const string &empty) : 00041 _separator(separator), 00042 _empty(empty) 00043 { 00044 _counter = 0; 00045 00046 if (_empty.empty()) { 00047 _empty = _separator; 00048 } 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: NameUniquifier::Destructor 00053 // Access: Public 00054 // Description: 00055 //////////////////////////////////////////////////////////////////// 00056 NameUniquifier:: 00057 ~NameUniquifier() { 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: NameUniquifier::add_name_body 00062 // Access: Private 00063 // Description: The actual implementation of the two flavors of 00064 // add_name(). 00065 // 00066 // If name is nonempty and so far unique, returns it 00067 // unchanged. 00068 // 00069 // Otherwise, generates and returns a new name according 00070 // to the following rules: 00071 // 00072 // If the prefix is empty, the new name is the 00073 // NameUniquifier's "empty" string followed by a number, 00074 // or the "separator" string if the "empty" string is 00075 // empty. 00076 // 00077 // If the prefix is nonempty, the new name is the 00078 // prefix, followed by the NameUniquifier's "separator" 00079 // string, followed by a number. 00080 //////////////////////////////////////////////////////////////////// 00081 string NameUniquifier:: 00082 add_name_body(const string &name, const string &prefix) { 00083 if (!name.empty()) { 00084 if (_names.insert(name).second) { 00085 // The name was successfully inserted into the set; therefore, 00086 // it's unique. Return it. 00087 return name; 00088 } 00089 } 00090 00091 // The name was not successfully inserted; there must be another one 00092 // already. Make up a new one. 00093 00094 // Keep trying to make up names until we make one that's unique. 00095 string temp_name; 00096 do { 00097 static const int max_len = 16; 00098 char num_str[max_len]; 00099 sprintf(num_str, "%d", ++_counter); 00100 nassertr((int)strlen(num_str) <= max_len, ""); 00101 00102 if (prefix.empty()) { 00103 temp_name = _empty + num_str; 00104 } else { 00105 temp_name = prefix + _separator + num_str; 00106 } 00107 } while (!_names.insert(temp_name).second); 00108 00109 return temp_name; 00110 } 00111