bool bailin::MemBuffer::PopLeft( MemBuffer* pBuffer, int nLen ) { if (pBuffer == NULL || m_nCurLen < nLen) { return false; } // 拷贝数据 pBuffer->Append(m_pBuffer, nLen); RemoveLeft(nLen); return true; }
TExpressionPtr ExpressionParser::ParseOperationExpression(StringPtrLen str) const { BracketsBalancer balancer; auto max_operation = OperationType::None; auto max_operation_amount = -1L; auto tail = str; // Find operation with zero bracket balance and with maximum value. // Maximum value means minimal arithmetic priority. for (; tail.Len() > 0; tail.RemoveLeft(1)) { if (!balancer.ProcessChar(tail.At(0)) && balancer.GetBalance() == 0) { OperationType operation = StartsWithOperation(tail); // TODO: Skip the whole operation symbols if (operation != OperationType::None) { if (operation > max_operation) { max_operation = operation; max_operation_amount = 1; } else if (operation == max_operation) { ++max_operation_amount; } } } } if (OperationType::None == max_operation) { // No operations with zero balance return TExpressionPtr(); } assert(balancer.GetBalance() == 0); auto max_operation_str = OperationTypeToString(max_operation); auto max_operation_str_len = std::strlen(max_operation_str); if (OperationType::Negation == max_operation) { if (!str.StartsWith(max_operation_str)) { Error("Incorrect usage of unary operation '", max_operation_str, "'."); } str.RemoveLeft(max_operation_str_len); auto child_expression = ParseExpression(str); return std::make_unique<OperationExpression>(std::move(child_expression)); } TExpressionPtrVector children_expressions; children_expressions.reserve(max_operation_amount + 1); tail = str; while (tail.Len() > 0) { if (!balancer.ProcessChar(tail.At(0)) && balancer.GetBalance() == 0) { if (tail.StartsWith(max_operation_str)) { auto child_expression = ParseExpression(str.Left(tail.Ptr())); children_expressions.push_back(std::move(child_expression)); tail.RemoveLeft(max_operation_str_len); str = tail; continue; } } tail.RemoveLeft(1); } auto child_expression = ParseExpression(str); children_expressions.push_back(std::move(child_expression)); return std::make_unique<OperationExpression>(max_operation, std::move(children_expressions)); }