inline void serializeString(SF::Archive & ar, std::basic_string<C,T,A> & s) { if (ar.isRead()) { boost::uint32_t count = 0; ar & count; SF::IStream &is = *ar.getIstream(); s.resize(0); std::size_t minSerializedLength = sizeof(C); if (ar.verifyAgainstArchiveSize(count*minSerializedLength)) { if (count > s.capacity()) { s.reserve(count); } } boost::uint32_t charsRemaining = count; const boost::uint32_t BufferSize = 512; C buffer[BufferSize]; while (charsRemaining) { boost::uint32_t charsToRead = RCF_MIN(BufferSize, charsRemaining); boost::uint32_t bytesToRead = charsToRead*sizeof(C); RCF_VERIFY( is.read( (char *) buffer, bytesToRead) == bytesToRead, RCF::Exception(RCF::_SfError_ReadFailure())) (bytesToRead)(BufferSize)(count); s.append(buffer, charsToRead); charsRemaining -= charsToRead; } } else if (ar.isWrite()) { boost::uint32_t count = static_cast<boost::uint32_t >(s.length()); ar & count; ar.getOstream()->writeRaw( (char *) s.c_str(), count*sizeof(C)); } }
void unescape_wide_string( const std::string &src, std::basic_string<unsigned int> &dest) { dest.reserve(src.size()); // about that long, but may be shorter for(unsigned i=0; i<src.size(); i++) { unsigned int ch=(unsigned char)src[i]; if(ch=='\\') // escape? { i++; assert(i<src.size()); // backslash can't be last character ch=(unsigned char)src[i]; switch(ch) { case '\\': dest.push_back(ch); break; case 'n': dest.push_back('\n'); break; /* NL (0x0a) */ case 't': dest.push_back('\t'); break; /* HT (0x09) */ case 'v': dest.push_back('\v'); break; /* VT (0x0b) */ case 'b': dest.push_back('\b'); break; /* BS (0x08) */ case 'r': dest.push_back('\r'); break; /* CR (0x0d) */ case 'f': dest.push_back('\f'); break; /* FF (0x0c) */ case 'a': dest.push_back('\a'); break; /* BEL (0x07) */ case '"': dest.push_back('"'); break; case '\'': dest.push_back('\''); break; case 'u': // universal character case 'U': // universal character i++; { std::string hex; unsigned count=(ch=='u')?4:8; hex.reserve(count); for(; count!=0 && i<src.size(); i++, count--) hex+=src[i]; // go back i--; unsigned int result; sscanf(hex.c_str(), "%x", &result); ch=result; } dest.push_back(ch); break; case 'x': // hex i++; { std::string hex; while(i<src.size() && isxdigit(src[i])) { hex+=src[i]; i++; } // go back i--; unsigned int result; sscanf(hex.c_str(), "%x", &result); ch=result; } dest.push_back(ch); break; default: if(isdigit(ch)) // octal { std::string octal; while(i<src.size() && isdigit(src[i])) { octal+=src[i]; i++; } // go back i--; unsigned int result; sscanf(octal.c_str(), "%o", &result); ch=result; dest.push_back(ch); } else { // Unknown escape sequence. // Both GCC and CL turn \% into %. dest.push_back(ch); } } } else dest.push_back(ch); } }