Changeset 625
- Timestamp:
- 03/10/07 12:20:10 (18 months ago)
- Location:
- branches/newnet/museekd/museekd
- Files:
-
- 2 modified
-
codesetmanager.cpp (modified) (8 diffs)
-
codesetmanager.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/newnet/museekd/museekd/codesetmanager.cpp
r611 r625 29 29 Museek::CodesetManager::~CodesetManager() 30 30 { 31 /* Free all the stored iconv contexts. */ 31 32 std::map<std::pair<std::string, std::string>, iconv_t>::iterator it, end = m_Contexts.end(); 32 33 for(it = m_Contexts.begin(); it != end; ++it) … … 37 38 Museek::CodesetManager::convert(const std::string & from, const std::string & to, const std::string & str) 38 39 { 40 /* No point in trying to convert an emtpy string. */ 39 41 if(str.empty()) 40 42 return str; 41 43 44 /* Get our iconv conversion context. */ 42 45 iconv_t context = getContext(from, to); 46 /* Guess and allocate a buffer. str.size() * 4 should be enough to hold a 47 converted string to any character set, even UTF32. */ 43 48 size_t buf_len = str.size() * 4 + 1; 44 49 char * out_buf = new char[buf_len]; … … 48 53 while(1) 49 54 { 55 /* Fetch pointer to the source data. */ 50 56 const char * inbuf = str.data(); 51 57 char * out_ptr = out_buf; … … 53 59 out_left = buf_len; 54 60 61 /* Try to convert the string. */ 55 62 r = iconv(context, (ICONV_INPUT_TYPE)&inbuf, &in_left, &out_ptr, &out_left); 56 if(r == (size_t)-1 && errno == E2BIG) 63 if(r == (size_t)-1 && errno == E2BIG) // Output buffer not large enough 57 64 { 58 65 delete [] out_buf; 59 buf_len *= 2; 66 buf_len *= 2; // Try a buffer twice as large 60 67 out_buf = new char[buf_len]; 61 68 continue; 62 69 } 70 /* FIXME: There should be additional error handling here, strings that 71 hold invalid characters will be truncated. */ 63 72 break; 64 73 } 65 74 75 /* Create the result string. */ 66 76 std::string ret; 67 77 if(r != (size_t)-1 && in_left == 0) 68 78 ret.assign(out_buf, buf_len - out_left); 69 79 80 // Free the output buffer. 70 81 delete [] out_buf; 71 82 return ret; … … 75 86 Museek::CodesetManager::getNetworkCodeset(const std::string & domain, const std::string & key) const 76 87 { 88 // Try to get the requested character set 77 89 std::string codeset = museekd()->config()->get(domain, key); 78 if(codeset.empty()) 90 if(codeset.empty()) // Get the default network encoding 79 91 codeset = museekd()->config()->get("encoding", "network"); 80 if(codeset.empty()) 92 if(codeset.empty()) // Fall back to UTF-8 81 93 codeset = "UTF-8"; 82 94 return codeset; … … 92 104 Museek::CodesetManager::fromRoomMap(const std::string & room, const std::map<std::string, std::string> & map) 93 105 { 106 // Get the character set for the room. 94 107 std::string codeset = getNetworkCodeset("encoding.rooms", room); 95 108 96 109 std::map<std::string, std::string> result; 97 110 111 // Iterate over the map, convert values and store them in 'result' 98 112 std::map<std::string, std::string>::const_iterator it, end = map.end(); 99 113 for(it = map.begin(); it != end; ++it) … … 112 126 Museek::CodesetManager::getContext(const std::string & from, const std::string & to) 113 127 { 128 // This is the context store key. 114 129 std::pair<std::string, std::string> key(from, to); 130 // Check if we've already constructed this iconv context. 115 131 std::map<std::pair<std::string, std::string>, iconv_t>::iterator it; 116 132 it = m_Contexts.find(key); … … 118 134 return (*it).second; 119 135 136 // Create the iconv context for this conversion. 120 137 iconv_t context = iconv_open(from.c_str(), to.c_str()); 138 // Currently, we don't handle invalid contexts very well. 121 139 assert(context != (iconv_t)-1); 140 // Store the context for future use. 122 141 m_Contexts[key] = context; 123 142 return context; -
branches/newnet/museekd/museekd/codesetmanager.h
r611 r625 36 36 CodesetManager(Museekd * museekd); 37 37 38 /* Frees all stored iconv contexts. */ 38 39 ~CodesetManager(); 39 40 41 /* Return pointer to museekd instance. */ 40 42 Museekd * museekd() const 41 43 { … … 43 45 } 44 46 47 /* Convert 'str' from character set 'from' to character set 'to' */ 45 48 std::string convert(const std::string & from, const std::string & to, const std::string & str); 49 /* Convert 'str' from character set 'from' to UTF8 */ 46 50 std::string toUtf8(const std::string & from, const std::string & str) 47 51 { 48 52 return convert(from, "UTF-8", str); 49 53 } 54 /* Convert 'str' from UTF8 to character set 'to' */ 50 55 std::string fromUtf8(const std::string & to, const std::string & str) 51 56 { … … 53 58 } 54 59 60 /* Convert 'str' from character set set for room 'room' to UTF8 */ 55 61 std::string fromRoom(const std::string & room, const std::string & str); 62 /* Convert values in map from character set set for room 'room' to UTF8 */ 56 63 std::map<std::string, std::string> fromRoomMap(const std::string & room, const std::map<std::string, std::string> & map); 64 /* Convert 'str' from UTF8 to character set set for room 'room' */ 57 65 std::string toRoom(const std::string & room, const std::string & str); 58 66 59 67 private: 68 /* Get the character set for an object from the configuration */ 60 69 std::string getNetworkCodeset(const std::string & domain, const std::string & key) const; 70 /* Get an iconv conversion context from character set 'from' to 'to'. */ 61 71 iconv_t getContext(const std::string & from, const std::string & to); 62 72 73 /* Weak reference to museekd instance. */ 63 74 NewNet::WeakRefPtr<Museekd> m_Museekd; 75 /* Iconv context cache. */ 64 76 std::map<std::pair<std::string, std::string>, iconv_t> m_Contexts; 65 77 };
