📄 perdecoder.cxx
字号:
bool PERDecoder::do_visit(CHOICE& value){ memento_type memento; if (decodeChoicePreamle(value,memento)) { if (!value.isUnknownSelection() && !value.getSelection()->accept(*this)) return false; rollback(memento); return true; } return false;}bool PERDecoder::do_visit(SEQUENCE_OF_Base& value){ unsigned size; if (decodeConstrainedLength(value, size) < 0) return false; if (size > MaximumArraySize) return false; value.resize(size); SEQUENCE_OF_Base::iterator it = value.begin(), last = value.end(); for (; it != last; ++it) { if (*it == NULL) *it = value.createElement(); if (!(*it)->accept(*this)) { value.erase(it, last); return false; } } return true;}bool PERDecoder::do_visit(OpenData& data){ OCTET_STRING value; if (value.accept(*this)) { if (!data.has_buf()) data.grab(new OpenBuf); data.get_buf().swap(value); return true; } return false;}bool PERDecoder::do_revisit(OpenData& value){ if (!value.has_buf() || !value.has_data()) return false; PERDecoder decoder(&(*value.get_buf().begin()), &(*value.get_buf().end()), get_env()); return value.get_data().accept(decoder);}bool PERDecoder::do_visit(TypeConstrainedOpenData& value){ assert(value.has_data()); unsigned len; if (decodeLength(0, INT_MAX, len) != 0) return false; const char* nextPosition = beginPosition + len; bool ok = value.get_data().accept(*this); setPosition(nextPosition); return ok;}bool PERDecoder::do_visit(GeneralizedTime& value){ unsigned len; if (decodeLength(0, INT_MAX, len)) { std::vector<char> data(len); if (decodeBlock(&data[0], len)) { value.set(&data[0]); return true; } } return false;}Visitor::VISIT_SEQ_RESULT PERDecoder::preVisitExtensionRoots(SEQUENCE& value){ // X.691 Section 18 bool hasExtension = false; if (value.extendable()) { if (atEnd()) return FAIL; hasExtension = decodeSingleBit() ; // 18.1 } return decodeBitMap(value.optionMap.bitData, value.optionMap.size()) ? (hasExtension ? CONTINUE : NO_EXTENSION) : FAIL; // 18.2}Visitor::VISIT_SEQ_RESULT PERDecoder::visitExtensionRoot(SEQUENCE& value, int index, int optional_id){ if (optional_id == SEQUENCE::mandatory_ || value.hasOptionalField(optional_id)) { if (value.getField(index) == NULL) value.fields[index] = AbstractData::create(value.info()->fieldInfos[index]); if (value.getField(index) == NULL || !value.getField(index)->accept(*this)) return FAIL; } return CONTINUE;}Visitor::VISIT_SEQ_RESULT PERDecoder::preVisitExtensions(SEQUENCE& value){ unsigned totalExtensions; if (!decodeSmallUnsigned(totalExtensions)) return FAIL; totalExtensions++; if (totalExtensions > MaximumArraySize) return FAIL; value.extensionMap.resize(totalExtensions); Visitor::VISIT_SEQ_RESULT result; result = decodeBitMap(value.extensionMap.bitData, value.extensionMap.size()) ? CONTINUE : FAIL; return result;}Visitor::VISIT_SEQ_RESULT PERDecoder::visitKnownExtension(SEQUENCE& value, int index, int optional_id){ if (!value.hasOptionalField(optional_id)) return CONTINUE; unsigned len; if (decodeLength(0, INT_MAX, len) != 0) return FAIL; const char* nextExtensionPosition = beginPosition + len; if (value.getField(index) == NULL) value.fields[index] = AbstractData::create(value.info()->fieldInfos[index]); bool ok = value.getField(index) == NULL || value.getField(index)->accept(*this); setPosition(nextExtensionPosition); return ok ? CONTINUE : FAIL;}bool PERDecoder::visitUnknownExtensions(SEQUENCE& value){ unsigned unknownCount = value.extensionMap.size() - value.info()->knownExtensions; if (unknownCount <=0) return true; // Already read them for (unsigned i = value.info()->knownExtensions; i < (unsigned)value.extensionMap.size(); i++) { if (value.extensionMap[i]) { unsigned len; if (decodeLength(0, INT_MAX, len) != 0) return false; beginPosition += len; if (atEnd()) return false; } } return true;}void PERDecoder::setPosition(const char* newPos){ beginPosition = newPos < endPosition ? newPos : endPosition; bitOffset = 8;}void PERDecoder::byteAlign(){ if (bitOffset != 8) { bitOffset = 8; beginPosition++; }}unsigned PERDecoder::getBitsLeft() const{ return (endPosition - beginPosition)*8 - (8 - bitOffset);}int PERDecoder::decodeConstrainedLength(ConstrainedObject & obj, unsigned & length){ // The execution order is important in the following. The decodeSingleBit() function // must be called if extendableFlag is true, no matter what. if ((obj.getConstraintType() == ExtendableConstraint && decodeSingleBit()) || obj.getConstraintType() == Unconstrained) return decodeLength(0, INT_MAX, length); else return decodeLength(obj.getLowerLimit(), obj.getUpperLimit(), length);}bool PERDecoder::decodeSingleBit(){ if (getBitsLeft() == 0) return false; bitOffset--; bool value = (*beginPosition & (1 << bitOffset)) != 0; if (bitOffset == 0) { byteAlign(); } return value;}bool PERDecoder::decodeMultiBit(unsigned nBits, unsigned& value){ if (nBits <= sizeof(value)*8 && nBits <= getBitsLeft()) { if (nBits == 0) { value = 0; return true; } if (nBits < bitOffset) { bitOffset -= nBits; value = (static_cast<unsigned char>(*beginPosition) >> bitOffset) & ((1 << nBits) - 1); return true; } value = static_cast<unsigned char>(*beginPosition++) & ((1 << bitOffset) - 1); nBits -= bitOffset; bitOffset = 8; while (nBits >= 8) { value = (value << 8) | static_cast<unsigned char>(*beginPosition++); nBits -= 8; } if (nBits > 0) { bitOffset = 8 - nBits; value = (value << nBits) | (static_cast<unsigned char>(*beginPosition) >> bitOffset); } return true; } return false;}bool PERDecoder::decodeSmallUnsigned(unsigned & value){ // X.691 Section 10.6 if (!decodeSingleBit()) return decodeMultiBit(6, value); // 10.6.1 unsigned len; if (decodeLength(0, INT_MAX, len) != 0) // 10.6.2 return false; byteAlign(); return decodeMultiBit(len*8, value);}int PERDecoder::decodeLength(unsigned lower, unsigned upper, unsigned & len){ // X.691 section 10.9 if (upper != INT_MAX && !alignedFlag) { assert(upper - lower < 0x10000); // 10.9.4.2 unsupported unsigned base; if (!decodeMultiBit(CountBits(upper - lower + 1), base)) return -1; } if (upper < 65536) // 10.9.3.3 return decodeUnsigned(lower, upper, len); // 10.9.3.5 byteAlign(); if (atEnd()) return -1; if (decodeSingleBit() == 0) { return decodeMultiBit(7, len) ? 0 : -1; } if (decodeSingleBit() == 0) { return decodeMultiBit(14, len) ? 0 : -1; } // 10.9.3.8 unsupported return -1;}int PERDecoder::decodeUnsigned(unsigned lower, unsigned upper, unsigned & value){ // X.691 section 10.5 if (lower == upper) { // 10.5.4 value = lower; return 0; } if (atEnd()) return -1; unsigned range = (upper - lower) + 1; unsigned nBits = CountBits(range); if (alignedFlag && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1 if (nBits > 16) { // not 10.5.7.4 decodeLength(1, (nBits+7)/8, nBits); // 12.2.6 nBits *= 8; } else if (nBits > 8) // not 10.5.7.2 nBits = 16; // 10.5.7.3 byteAlign(); // 10.7.5.2 - 10.7.5.4 } if (decodeMultiBit(nBits, value)) { value += lower; return 0; } return -1;}unsigned PERDecoder::decodeBlock(char * bufptr, unsigned nBytes){ if (nBytes == 0) return 0; byteAlign(); if (beginPosition+nBytes > endPosition) nBytes = endPosition - beginPosition; if (nBytes == 0) return 0; memcpy(bufptr, beginPosition, nBytes); beginPosition += nBytes; return nBytes;}} // namespace ASN1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -