本文整理汇总了C++中ParseException函数的典型用法代码示例。如果您正苦于以下问题:C++ ParseException函数的具体用法?C++ ParseException怎么用?C++ ParseException使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ParseException函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: loadFile
static std::string
loadFile (boost::property_tree::ptree &config,
const boost::filesystem::path &file)
{
boost::filesystem::path extension = file.extension();
boost::filesystem::path extension2 = file.stem().extension();
std::string fileName = file.filename().string();
boost::property_tree::ptree readConfig;
if (extension2.string() == ".conf") {
if (extension.string() == ".json") {
boost::property_tree::read_json (file.string(), readConfig);
} else if (extension.string() == ".info") {
boost::property_tree::read_info (file.string(), readConfig);
} else if (extension.string() == ".ini") {
boost::property_tree::read_ini (file.string(), readConfig);
} else if (extension.string() == ".xml") {
boost::property_tree::read_xml (file.string(), readConfig);
} else {
throw ParseException ("Unknonw file format");
}
} else {
throw ParseException ("Unknonw file format");
}
mergePropertyTrees (config, readConfig);
config.put ("configPath", file.parent_path().string() );
fileName = fileName.substr (0, fileName.size() - extension.string().size() );
fileName = fileName.substr (0, fileName.size() - extension2.string().size() );
return fileName;
}
开发者ID:startgeek,项目名称:kurento-media-server,代码行数:34,代码来源:loadConfig.cpp
示例2: while
bool EntTokenizer::NextKV()
{
while(currentPtr != strEnd)
{
switch(*currentPtr)
{
case '\"':
*currentPtr = 0;
currentPtr++;
return true;
case '{':
if(bInBlock)
{
throw ParseException("Unexpected start of block.", GetCharNum());
}
bInBlock = true;
break;
case '}':
if(!bInBlock)
{
throw ParseException("Unexpected end of block.", GetCharNum());
}
bInBlock = false;
blocksRead++;
break;
default:
break;
}
currentPtr++;
}
currentPtr = NULL;
return false;
}
开发者ID:HoLyCoWzOrZ,项目名称:resgen,代码行数:35,代码来源:enttokenizer.cpp
示例3: ParseException
// _____________________________________________________________________________
ParsedQuery SparqlParser::parse(const string& query) {
ParsedQuery result;
result._originalString = query;
// Split prologue
size_t i = query.find("SELECT");
if (i == string::npos) {
throw ParseException("Missing keyword \"SELECT\", "
"currently only select queries are supported.");
}
size_t j = query.find("WHERE");
if (j == string::npos) {
throw ParseException("Missing keyword \"WHERE\", "
"currently only select queries are supported.");
}
if (i >= j) {
throw ParseException("Keyword \"WHERE\" "
"found after keyword \"SELECT\". Invalid query.");
}
size_t k = query.find("}", j);
if (k == string::npos) {
throw ParseException("Missing \"}\" symbol after \"WHERE\".");
}
parsePrologue(ad_utility::strip(query.substr(0, i), " \n\t"), result);
parseSelect(ad_utility::strip(query.substr(i, j - i), " \n\t"), result);
parseWhere(ad_utility::strip(query.substr(j, k - j + 1), " \n\t"), result);
parseSolutionModifiers(ad_utility::strip(query.substr(k + 1), " \n\t"),
result);
return result;
}
开发者ID:anukat2015,项目名称:SparqlEngineDraft,代码行数:36,代码来源:SparqlParser.cpp
示例4: assignOptionArgument
void CommandLineParser::parseDuration()
{
QString durationString;
QString choppedDurationString;
assignOptionArgument(maxDurationoption(), durationString);
choppedDurationString = durationString;
const char suffix = durationString.at(durationString.count() - 1).toLatin1();
const bool hasSuffix = !std::isdigit(suffix);
if (hasSuffix)
choppedDurationString.chop(1);
bool ok;
m_maxDuration = choppedDurationString.toInt(&ok);
if (!ok || m_maxDuration <= 0) {
throw ParseException(QString::fromLocal8Bit("Invalid duration argument '%1'.")
.arg(durationString));
}
if (hasSuffix) {
switch (suffix) {
case 'm': break;
case 'd': m_maxDuration *= 24; // Fall-through.
case 'h': m_maxDuration *= 60; break;
default:
throw ParseException(QString::fromLocal8Bit("Invalid duration suffix '%1'.")
.arg(suffix));
}
}
}
开发者ID:Distrotech,项目名称:qbs,代码行数:27,代码来源:commandlineparser.cpp
示例5: Q_ASSERT
void CommandLineParser::parse(const QStringList &commandLine)
{
m_profile.clear();
m_startCommit.clear();
m_maxDuration = 0;
m_jobCount = 0;
m_log = false;
m_commandLine = commandLine;
Q_ASSERT(!m_commandLine.isEmpty());
m_command = m_commandLine.takeFirst();
while (!m_commandLine.isEmpty()) {
const QString arg = m_commandLine.takeFirst();
if (arg == profileOption())
assignOptionArgument(arg, m_profile);
else if (arg == startCommitOption())
assignOptionArgument(arg, m_startCommit);
else if (arg == jobCountOption())
assignOptionArgument(arg, m_jobCount);
else if (arg == maxDurationoption())
parseDuration();
else if (arg == logOption())
m_log = true;
else
throw ParseException(QString::fromLocal8Bit("Unknown parameter '%1'").arg(arg));
}
if (m_profile.isEmpty())
throw ParseException("No profile given.");
if (m_startCommit.isEmpty())
throw ParseException("No start commit given.");
}
开发者ID:Distrotech,项目名称:qbs,代码行数:30,代码来源:commandlineparser.cpp
示例6: switch
string
WKTReader::getNextWord(StringTokenizer *tokenizer)
{
int type=tokenizer->nextToken();
switch(type){
case StringTokenizer::TT_EOF:
throw ParseException("Expected word but encountered end of stream");
case StringTokenizer::TT_EOL:
throw ParseException("Expected word but encountered end of line");
case StringTokenizer::TT_NUMBER:
throw ParseException("Expected word but encountered number", tokenizer->getNVal());
case StringTokenizer::TT_WORD:
{
string word = tokenizer->getSVal();
int i = word.size();
while( --i >= 0 )
{
word[i] = static_cast<char>(toupper(word[i]));
}
return word;
}
case '(':
return "(";
case ')':
return ")";
case ',':
return ",";
}
assert(0);
//throw ParseException("Encountered unexpected StreamTokenizer type");
return "";
}
开发者ID:BlueEyes-Lin,项目名称:sunmap,代码行数:33,代码来源:WKTReader.cpp
示例7: while
float WalkingEngineKick::readFloat(char*& buf)
{
while(*buf == ' ' || *buf == '\t')
++buf;
char* result = buf;
if(*buf == '-')
++buf;
while(isdigit(*buf))
++buf;
if(buf == result)
throw ParseException("expected float");
if(*buf == '.')
{
++buf;
while(isdigit(*buf))
++buf;
if(*buf && *buf != ' ' && *buf != '\t' && *buf != '\r' && *buf != '\n')
throw ParseException("expected float");
}
char c = *buf;
*buf = '\0';
float f = float(atof(result));
*buf = c;
return f;
}
开发者ID:MisterSquishy,项目名称:nbites,代码行数:25,代码来源:WalkingEngineKick.cpp
示例8: fetchSchemaValues
void SchemaItem::processUniqueAttributeValueSetReferences(const std::map<std::string, std::vector<std::shared_ptr<SchemaValue>>> &uniqueAttributeValueSets)
{
for (auto setRefIt = m_uniqueAttributeValueSetReferences.begin(); setRefIt != m_uniqueAttributeValueSetReferences.end(); ++setRefIt)
{
auto keyIt = uniqueAttributeValueSets.find(setRefIt->second.m_setName);
if (keyIt != uniqueAttributeValueSets.end())
{
for (auto cfgIt = keyIt->second.begin(); cfgIt != keyIt->second.end(); ++cfgIt)
{
std::shared_ptr<SchemaValue> pKeyRefAttribute = *cfgIt; // this is the reference attribute from which attributeName must be a member
std::string cfgValuePath = ((setRefIt->second.m_elementPath != ".") ? setRefIt->second.m_elementPath : "") + "@" + setRefIt->second.m_attributeName;
std::vector<std::shared_ptr<SchemaValue>> cfgValues;
fetchSchemaValues(cfgValuePath, cfgValues);
if (!cfgValues.empty())
{
for (auto attrIt = cfgValues.begin(); attrIt != cfgValues.end(); ++attrIt)
{
(*attrIt)->setUniqueValueSetRef(pKeyRefAttribute);
}
}
else
{
throw(ParseException("Attribute " + (setRefIt->second.m_attributeName + " not found when adding keyRef for key " + (setRefIt->second.m_setName))));
}
}
}
else
{
throw(ParseException("Keyref to key '" + (setRefIt->second.m_setName + "' was not found")));
}
}
}
开发者ID:dcamper,项目名称:HPCC-Platform,代码行数:32,代码来源:SchemaItem.cpp
示例9: data
void DocumentConverter::characters(const XMLCh* const chars,
const unsigned int length)
{
// Should we just ignore these characters?
if (ignoreDepth > 0) return;
// Ignore pure whitespace
unsigned int l;
for (l = 0; l < length; ++l) {
XMLCh c = chars[l];
if (c == ' ' || c == '\n' || c == '\r' || c == '\t') continue;
break;
}
if (l == length) return;
try {
// This conversion should be safe. CDATA may only contain valid XML
// characters. These are defined in the XML 1.0 specification as the set
// 0x9, 0xA, 0xD, 0x20-0xD7FF, 0xE000-0xFFFD, 0x10000-0x10FFFF.
XMLChToVXIchar data(chars);
doc->AddContent(data.c_str(), wcslen(data.c_str()));
}
catch (const VXMLDocumentModel::OutOfMemory &) {
ParseException(L"unable to allocate memory for content");
}
catch (const VXMLDocumentModel::InternalError &) {
ParseException(L"corrupted document tree; unable to add content");
}
}
开发者ID:chemeris,项目名称:sipxecs,代码行数:29,代码来源:DocumentConverter.cpp
示例10: while
void CommandLineParser::parseArgs(const std::vector<StringView>& args, CommandLineFlags& result) const
{
size_t numPositionalConsumed = 0;
size_t numFlagConsumed = 0;
while (numFlagConsumed < args.size())
{
auto flag = args[numFlagConsumed];
if (!isOption(flag)) // Positional arguments
{
if (numPositionalConsumed >= posFlagMap.size())
throw ParseException("too many positional arguments");
auto inserted = result.addFlag(posFlagMap[numPositionalConsumed].first, flag);
assert(inserted && "Insertion failed");
++numPositionalConsumed;
}
else // Optional arguments
{
flag.remove_prefix(1);
// See if flag is "-help"
if (flag == "help")
throw HelpException();
auto itr = optFlagMap.find(flag);
if (itr == optFlagMap.end())
throw ParseException("Option not recognized: " + flag.to_string());
if (itr->second.defaultValue)
{
++numFlagConsumed;
if (numFlagConsumed >= args.size())
throw ParseException("More argument needs to be provided after option " + flag.to_string());
auto flagArg = args[numFlagConsumed];
if (isOption(flagArg))
throw ParseException("Found another option instead of an argument after option " + flag.to_string());
auto inserted = result.addFlag(flag, flagArg);
assert(inserted && "Insertion failed");
}
else
{
auto inserted = result.addFlag(flag, "");
assert(inserted && "Insertion failed");
}
}
++numFlagConsumed;
}
if (numPositionalConsumed < posFlagMap.size())
throw ParseException("Not enough positional arguments are provided");
for (auto const& mapping: optFlagMap)
{
if (mapping.second.defaultValue && result.lookup(mapping.first) == nullptr)
result.addFlag(mapping.first, *mapping.second.defaultValue);
}
}
开发者ID:grievejia,项目名称:hermes,代码行数:59,代码来源:CommandLineParser.cpp
示例11: parseInt
int StringBuilder::parseInt() const
{
if( m_pos == 0 ) throw ParseException("StringBuilder::parseInt(): Cannot parse a '0' length string!");
if( m_pos == m_alloc ) growCapacity((size_t)1); // make sure we have enough room for the following temproary '/0' termination
int lvalue;
if(sscanf(m_buffer,"%d",&lvalue)!=1) throw ParseException("StringBuilder::parseInt()");
return lvalue;
}
开发者ID:JonnyWideFoot,项目名称:pd,代码行数:8,代码来源:stringbuilder.cpp
示例12: sscanf
double StringBuilder::parseDouble( size_t _index ) const
{
if( m_pos == 0 || _index >= m_pos-1 ) throw ParseException("StringBuilder::parseDouble( size_t _index )");
if( m_pos == m_alloc ) growCapacity((size_t)1); // make sure we have enough room for the following temproary '/0' termination
m_buffer[m_pos] = 0; // ensure a '0' terminated string for sscanf() but do not increase the size of the string
double lvalue;
if(sscanf(&m_buffer[_index],"%lf",&lvalue)!=1) throw ParseException("StringBuilder::parseDouble()");
return lvalue;
}
开发者ID:JonnyWideFoot,项目名称:pd,代码行数:9,代码来源:stringbuilder.cpp
示例13: ParseException
void CommandLineParser::assignOptionArgument(const QString &option, QString &argument)
{
if (m_commandLine.isEmpty())
throw ParseException(QString::fromLocal8Bit("Option '%1' needs an argument.").arg(option));
argument = m_commandLine.takeFirst();
if (argument.isEmpty()) {
throw ParseException(QString::fromLocal8Bit("Argument for option '%1' must not be empty.")
.arg(option));
}
}
开发者ID:Distrotech,项目名称:qbs,代码行数:10,代码来源:commandlineparser.cpp
示例14: throw
void SchemaItem::postProcessConfig(const std::map<std::string, std::vector<std::shared_ptr<SchemaValue>>> &uniqueAttributeValueSets)
{
//
// Make sure that the item type value for all children that are insertable (minRequired = 0 or maxAllowed > minRequired)
std::set<std::string> itemTypes;
for (auto it = m_children.begin(); it != m_children.end(); ++it)
{
if (it->second->isInsertable())
{
auto rc = itemTypes.insert(it->second->getItemType());
if (!rc.second)
{
throw(ParseException("Duplicate itemType(" + it->second->getItemType() + ") found for element " + m_properties["name"]));
}
}
}
processUniqueAttributeValueSetReferences(uniqueAttributeValueSets);
//
// Post process the attributes
for (auto it = m_attributes.begin(); it != m_attributes.end(); ++it)
{
//
// If this is a mirroed value, go find the source and attach ourselves so that if that value changes,
// it is replicated to us.
if (it->second->isMirroredValue())
{
std::vector<std::shared_ptr<SchemaValue>> cfgValues;
fetchSchemaValues(it->second->getMirrorFromPath(), cfgValues);
if (!cfgValues.empty() && cfgValues.size() == 1)
{
if (cfgValues.size() == 1)
{
it->second->addMirroredSchemaValue(cfgValues[0]);
}
else
{
throw(ParseException("Multiple sources found for mirror from path for attribute " + it->second->getName() + " (path=" + it->second->getMirrorFromPath()));
}
}
else
{
throw(ParseException("Mirrored from source not found for attribute " + it->second->getName() + " path=" + it->second->getMirrorFromPath()));
}
}
}
//
// Post process all of our children now
for (auto it = m_children.begin(); it!= m_children.end(); ++it)
{
it->second->postProcessConfig(uniqueAttributeValueSets);
}
}
开发者ID:dcamper,项目名称:HPCC-Platform,代码行数:55,代码来源:SchemaItem.cpp
示例15: chopstr
void PopsDat::parse( const std::string& _Line )
{
std::vector<std::string> parts = chopstr( _Line, TOKEN_WHITESPACE.c_str() );
if( parts.size() != 5 ) throw ParseException("POPS: Atom set initial line contains the wrong number of elements");
if(
0 != str2int( parts[0], expectedAtomTypeCount ) ||
0 != str2double( parts[1], b12 ) ||
0 != str2double( parts[2], b13 ) ||
0 != str2double( parts[3], b14 ) ||
0 != str2double( parts[4], bOther )
) throw ParseException("POPS: Invalid value in atom set initial line");
return;
}
开发者ID:JonnyWideFoot,项目名称:pd,代码行数:13,代码来源:pops.cpp
示例16: throw
novatel_gps_msgs::TrackstatPtr
novatel_gps_driver::TrackstatParser::ParseAscii(const novatel_gps_driver::NovatelSentence& sentence) throw(ParseException)
{
if (sentence.body.size() < ASCII_BODY_FIELDS)
{
std::stringstream error;
error << "Unexpected number of body fields in TRACKSTAT log: " << sentence.body.size();
throw ParseException(error.str());
}
uint32_t n_channels = 0;
ParseUInt32(sentence.body[3], n_channels, 10);
if (sentence.body.size() != ASCII_BODY_FIELDS + n_channels * ASCII_CHANNEL_FIELDS)
{
std::stringstream error;
error << "Size of TRACKSTAT log did not match expected size.";
throw ParseException(error.str());
}
bool valid = true;
novatel_gps_msgs::TrackstatPtr msg = boost::make_shared<novatel_gps_msgs::Trackstat>();
msg->solution_status = sentence.body[0];
msg->position_type = sentence.body[1];
valid &= ParseFloat(sentence.body[2], msg->cutoff);
msg->channels.resize(n_channels);
for (size_t i = 0; i < static_cast<size_t>(n_channels); ++i)
{
size_t offset = 4 + i * ASCII_CHANNEL_FIELDS;
novatel_gps_msgs::TrackstatChannel& channel = msg->channels[i];
valid &= ParseInt16(sentence.body[offset], channel.prn);
valid &= ParseInt16(sentence.body[offset+1], channel.glofreq);
valid &= ParseUInt32(sentence.body[offset+2], channel.ch_tr_status, 16);
valid &= ParseDouble(sentence.body[offset+3], channel.psr);
valid &= ParseFloat(sentence.body[offset+4], channel.doppler);
valid &= ParseFloat(sentence.body[offset+5], channel.c_no);
valid &= ParseFloat(sentence.body[offset+6], channel.locktime);
valid &= ParseFloat(sentence.body[offset+7], channel.psr_res);
channel.reject = sentence.body[offset+8];
valid &= ParseFloat(sentence.body[offset+9], channel.psr_weight);
}
if (!valid)
{
std::stringstream error;
error << "Error parsing TRACKSTAT log.";
throw ParseException(error.str());
}
return msg;
}
开发者ID:lardemua,项目名称:drivers,代码行数:51,代码来源:trackstat.cpp
示例17: ASSERT
int ConfigMapParser::parse(bool noThrow)
{
int returnValue = 0;
ASSERT(lexer);
ASSERT(configMap);
try
{
if(!lexer->isValid())
{
returnValue = ConfigMap::E_FILE;
throw ParseException(0, 0, "Cannot read file.");
}
nextToken(); // get the first token
return file(configMap);
}
catch(ParseException& pe)
{
// If the returnValue indicates not that the file connot be opened, there
// has to be a syntax error.
if (returnValue != ConfigMap::E_FILE)
returnValue = ConfigMap::E_SYNTAX;
if(verbose)
pe.printError(lexer->getFilename());
std::stringstream buf;
std::cout<<"[EXCEPTION ERROR ] ConfigMapParser.cpp 3"<<std::endl;
buf << lexer->getFilename() << ":" << pe.line << "," << pe.column << ": " << pe.what();
ParseException e = ParseException(pe.line, pe.column, buf.str());
if (noThrow)
setError(e);
else
throw e;
}
catch(invalid_key)
{
if(verbose)
OUTPUT_ERROR("ConfigMapParser::parse catched a invalid_key exception.\n"
"This indicates, that there is a bug into the parser.");
ASSERT(false);
}
catch(std::invalid_argument)
{
if(verbose)
OUTPUT_ERROR("ConfigMapParser::parse catched a invalid_argument exception.\n"
"This indicates, that there is a bug into the parser.");
ASSERT(false);
}
return returnValue;
}
开发者ID:coryalini,项目名称:nbites,代码行数:50,代码来源:ConfigMapParser.cpp
示例18: while
ASTNode* ASTExpressionBuilder::shuntingYardAlgorithm()
{
_operators.clear();
_results.clear();
while (!_tokens.empty()) {
_token = _tokens.front();
_tokens.pop_front();
if (isKeyword("+") || isKeyword("-") || isKeyword("*") || isKeyword("/")) {
while (!_operators.empty() && getOprPriority(_token) <= getOprPriority(_operators.back())) {
buildOperators();
}
_operators.push_back(_token);
} else if (isKeyword("(")) {
_operators.push_back("(");
} else if (isKeyword(")")) {
while (!_operators.empty() && _operators.back() != "(") {
buildOperators();
}
if (_operators.empty()) {
throw ParseException(_token, "Mismatched parentheses");
}
_operators.pop_back();
} else if (isDigits() || isName()) {
buildOperands();
} else {
throw ParseException(_token, "Unable to parse expression");
}
getToken();
}
while (!_operators.empty()) {
if (_operators.back() == "(") {
throw ParseException(_token, "Mismatched parentheses");
}
buildOperators();
}
ASTNode* expNode = _results.back();
_results.pop_back();
return expNode;
}
开发者ID:kwajunyong,项目名称:chocolate-muffins,代码行数:49,代码来源:ASTExpressionBuilder.cpp
示例19: readMutations
std::set<AAMutation> readMutations(std::istream& mutationFile,
std::string prefix)
throw (ParseException)
{
std::set<AAMutation> result;
std::string line;
typedef boost::tokenizer<boost::escaped_list_separator<char> > csv_tok;
getline(mutationFile, line);
csv_tok tok(line);
for (csv_tok::iterator i = tok.begin(); i != tok.end(); ++i) {
std::string mutation = *i;
if (mutation.length() < prefix.length() + 2)
throw ParseException("", "Error while parsing mutation '"
+ mutation + "': too short for mutation with "
"prefix '" + prefix + "'", false);
if (mutation.substr(0, prefix.length()) != prefix)
throw ParseException("", "Error while parsing mutation '"
+ mutation + "': expected to start with '"
+ prefix + "'", false);
try {
AminoAcid aa(mutation[mutation.length() - 1]);
char *endptr;
std::string posStr = mutation.substr(prefix.length(),
mutation.length()
- prefix.length() - 1);
int pos
= strtol(posStr.c_str(), &endptr, 10);
if (*endptr != 0)
throw ParseException("", "could not parse position", false);
result.insert(AAMutation(pos, aa));
} catch (ParseException& e) {
throw ParseException("", "Error while parsing mutation '"
+ mutation + "': " + e.message(), false);
}
}
return result;
}
开发者ID:rega-cev,项目名称:libseq,代码行数:49,代码来源:Mutation.C
示例20: docPtr
XMLTree::XMLTree(bool validate, const char *docBuffer, std::size_t bufferLen)
: docPtr(NULL) {
if (static_cast<const char *> (NULL) == docBuffer) {
throw std::invalid_argument("XMLTree(docBuffer) is NULL");
}
if (0 == bufferLen) {
bufferLen = std::strlen(docBuffer);
if (0 == bufferLen) {
throw std::invalid_argument("XMLTree(docBuffer) is empty");
}
}
if (INT_MAX < bufferLen) {
throw std::invalid_argument("XMLTree(docBuffer) too long");
}
docPtr = xmlReadMemory(docBuffer, static_cast<int> (bufferLen), NULL, NULL, XML_PARSE_NONET);
if (static_cast<xmlDocPtr> (NULL) == docPtr) {
throw ParseException("XMLTree() unable to parse docBuffer");
}
if (validate) {
//
// Now, try to validate the document.
//
XMLErrorData errorData("XMLTree() ");
xmlValidCtxt cvp;
cvp.userData = &errorData;
cvp.error = reinterpret_cast<xmlValidityErrorFunc> (XMLErrorHandler);
cvp.warning = reinterpret_cast<xmlValidityErrorFunc> (XMLErrorHandler);
if (!xmlValidateDocument(&cvp, docPtr)) {
xmlFreeDoc(docPtr);
if (errorData.errorDetected) {
throw ParseException(errorData.message);
} else {
throw ParseException("XMLTree() docBuffer does not validate");
}
}
}
if (static_cast<xmlNodePtr> (NULL) == xmlDocGetRootElement(docPtr)) {
xmlFreeDoc(docPtr);
throw ParseException("XMLTree() empty document");
}
}
开发者ID:JonathanFu,项目名称:OpenAM-1,代码行数:48,代码来源:xml_tree.cpp
注:本文中的ParseException函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论