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