⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int_attr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
			cursorMoveType == CURSOR_MOVE_PREV )
			{
			/* Move from the start of the current group to the start of the
			   preceding group */
			newCursor = attributeFindStart( newCursor, getAttrFunction );
			if( newCursor != NULL )
				newCursor = getAttrFunction( newCursor, NULL, NULL, NULL,
											 ATTR_PREV );
			if( newCursor != NULL )
				newCursor = attributeFindStart( newCursor, getAttrFunction );
			}
		else
			{
			REQUIRES_N( cursorMoveType == CURSOR_MOVE_NEXT || \
						cursorMoveType == CURSOR_MOVE_END );

			/* Move from the end of the current group to the start of the
			   next group */
			newCursor = attributeFindEnd( newCursor, getAttrFunction );
			if( newCursor != NULL )
				newCursor = getAttrFunction( newCursor, NULL, NULL, NULL,
											 ATTR_NEXT );
			}
		}
	ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
	ENSURES_N( lastCursor != NULL );	/* We went through the loop at least once */

	/* If the new cursor is NULL, we've reached the start or end of the
	   attribute list */
	if( newCursor == NULL )
		{
		/* If it's an absolute move we've reached our destination, otherwise
		   there's nowhere left to move to.  We move to the start of the
		   first or last attribute that we got to before we ran out of
		   attributes to make sure that we don't fall off the start/end of
		   the list */
		return( absMove ? \
				attributeFindStart( lastCursor, getAttrFunction ) : NULL );
		}

	/* We've found what we were looking for */
	return( newCursor );
	}

/* Moving by attribute or attribute instance is rather simpler than moving by
   group.  For attributes we move backwards or forwards until we either run 
   out of attributes or the next attribute belongs to a different group.  For 
   attribute instances we move similarly, except that we stop when we reach 
   an attribute whose group type, attribute type, and instance type don't 
   match the current one.  We have to explicitly keep track of whether the 
   cursor was successfully moved rather than checking that its value has 
   changed because some object types implement composite attributes that 
   maintain an attribute-internal virtual cursor, which can return the same 
   attribute pointer multiple times if the move is internal to the 
   (composite) attribute */

CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1, 2 ) ) \
static const void *moveCursorByAttribute( const void *currentCursor,
										  GETATTRFUNCTION getAttrFunction,
										  IN_ENUM( CURSOR_MOVE ) \
											const CURSOR_MOVE_TYPE cursorMoveType, 
										  IN_INT int count, 
										  const BOOLEAN absMove )
	{
	CRYPT_ATTRIBUTE_TYPE groupID;
	BOOLEAN cursorMoved = FALSE;
	const void *newCursor = currentCursor;
	int iterationCount;

	assert( isReadPtr( currentCursor, MIN_ATTRLIST_SIZE ) );

	REQUIRES_N( getAttrFunction != NULL );
	REQUIRES_N( cursorMoveType > CURSOR_MOVE_NONE && \
				cursorMoveType < CURSOR_MOVE_LAST );
	REQUIRES_N( count > 0 && count <= MAX_INTLENGTH );

	if( getAttrFunction( currentCursor, &groupID, NULL, NULL, 
						 ATTR_CURRENT ) == NULL )
		return( NULL );
	ENSURES_N( groupID != CRYPT_ATTRIBUTE_NONE );
	if( cursorMoveType == CURSOR_MOVE_START || \
		cursorMoveType == CURSOR_MOVE_PREV )
		{
		CRYPT_ATTRIBUTE_TYPE prevGroupID;
		const void *prevCursor;

		prevCursor = getAttrFunction( newCursor, &prevGroupID, NULL, 
									  NULL, ATTR_PREV );
		for( iterationCount = 0; \
			 count-- > 0 && prevCursor != NULL && prevGroupID == groupID && \
				iterationCount < FAILSAFE_ITERATIONS_MAX;
			 iterationCount++ )
			{
			newCursor = prevCursor;
			prevCursor = getAttrFunction( newCursor, &prevGroupID, NULL, 
										  NULL, ATTR_PREV );
			cursorMoved = TRUE;
			}
		ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
		}
	else
		{
		CRYPT_ATTRIBUTE_TYPE nextGroupID;
		const void *nextCursor;

		REQUIRES_N( cursorMoveType == CURSOR_MOVE_NEXT || \
					cursorMoveType == CURSOR_MOVE_END );

		nextCursor = getAttrFunction( newCursor, &nextGroupID, NULL,
									  NULL, ATTR_NEXT );
		for( iterationCount = 0; \
			 count-- > 0 && nextCursor != NULL && nextGroupID == groupID && \
				iterationCount < FAILSAFE_ITERATIONS_MAX;
			 iterationCount++ )
			{
			newCursor = nextCursor;
			nextCursor = getAttrFunction( newCursor, &nextGroupID, NULL,
										  NULL, ATTR_NEXT );
			cursorMoved = TRUE;
			}
		ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
		}

	if( !absMove && !cursorMoved )
		return( NULL );
	return( newCursor );
	}

CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1, 2 ) ) \
static const void *moveCursorByInstance( const void *currentCursor,
										 GETATTRFUNCTION getAttrFunction,
										 IN_ENUM( CURSOR_MOVE ) \
											const CURSOR_MOVE_TYPE cursorMoveType, 
										 IN_INT int count, 
										 const BOOLEAN absMove )
	{
	CRYPT_ATTRIBUTE_TYPE groupID, attributeID, instanceID;
	BOOLEAN cursorMoved = FALSE;
	const void *newCursor = currentCursor;
	int iterationCount;

	assert( isReadPtr( currentCursor, MIN_ATTRLIST_SIZE ) );

	REQUIRES_N( getAttrFunction != NULL );
	REQUIRES_N( cursorMoveType > CURSOR_MOVE_NONE && \
				cursorMoveType < CURSOR_MOVE_LAST );
	REQUIRES_N( count > 0 && count <= MAX_INTLENGTH );

	if( getAttrFunction( currentCursor, &groupID, &attributeID, 
						 &instanceID, ATTR_CURRENT ) == NULL )
		return( NULL );
	ENSURES_N( groupID != CRYPT_ATTRIBUTE_NONE && \
			   attributeID != CRYPT_ATTRIBUTE_NONE );
	if( cursorMoveType == CURSOR_MOVE_START || \
		cursorMoveType == CURSOR_MOVE_PREV )
		{
		CRYPT_ATTRIBUTE_TYPE prevGroupID, prevAttrID, prevInstID;
		const void *prevCursor;

		prevCursor = getAttrFunction( newCursor, &prevGroupID,
									  &prevAttrID, &prevInstID,
									  ATTR_PREV );
		for( iterationCount = 0; \
			 count-- > 0 && prevCursor != NULL && prevGroupID == groupID && \
				prevAttrID == attributeID && prevInstID == instanceID && \
				iterationCount < FAILSAFE_ITERATIONS_MAX;
			 iterationCount++ )
			{
			newCursor = prevCursor;
			prevCursor = getAttrFunction( newCursor, &prevGroupID,
										  &prevAttrID, &prevInstID,
										  ATTR_PREV );
			cursorMoved = TRUE;
			}
		ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
		}
	else
		{
		CRYPT_ATTRIBUTE_TYPE nextGroupID, nextAttrID, nextInstID;
		const void *nextCursor;

		REQUIRES_N( cursorMoveType == CURSOR_MOVE_NEXT || \
					cursorMoveType == CURSOR_MOVE_END );

		nextCursor = getAttrFunction( newCursor, &nextGroupID,
									  &nextAttrID, &nextInstID,
									  ATTR_NEXT );
		for( iterationCount = 0; \
			 count-- > 0 && nextCursor != NULL && nextGroupID == groupID && \
				nextAttrID == attributeID && nextInstID == instanceID && \
				iterationCount < FAILSAFE_ITERATIONS_MAX;
			 iterationCount++ )
			{
			newCursor = nextCursor;
			nextCursor = getAttrFunction( newCursor, &nextGroupID,
										  &nextAttrID, &nextInstID,
										  ATTR_NEXT );
			cursorMoved = TRUE;
			}
		ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
		}

	if( !absMove && !cursorMoved )
		return( NULL );
	return( newCursor );
	}

/* Move the attribute cursor relative to the current cursor position */

CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) )\
const void *attributeMoveCursor( IN_OPT const void *currentCursor,
								 IN GETATTRFUNCTION getAttrFunction,
								 IN_ATTRIBUTE \
									const CRYPT_ATTRIBUTE_TYPE attributeMoveType,
								 IN_RANGE( CRYPT_CURSOR_LAST, \
										   CRYPT_CURSOR_FIRST ) /* Values are -ve */
									const int cursorMoveType )
	{
	typedef struct {
		const int moveCode;
		const CURSOR_MOVE_TYPE cursorMoveType;
		} MOVECODE_MAP_INFO;
	static const MOVECODE_MAP_INFO moveCodeMap[] = {
		{ CRYPT_CURSOR_FIRST, CURSOR_MOVE_START },
		{ CRYPT_CURSOR_PREVIOUS, CURSOR_MOVE_PREV },
		{ CRYPT_CURSOR_NEXT, CURSOR_MOVE_NEXT },
		{ CRYPT_CURSOR_LAST, CURSOR_MOVE_END },
		{ 0, CURSOR_MOVE_NONE }, { 0, CURSOR_MOVE_NONE }
		};
	const BOOLEAN absMove = ( cursorMoveType == CRYPT_CURSOR_FIRST || \
							  cursorMoveType == CRYPT_CURSOR_LAST ) ? \
							TRUE : FALSE;
	CURSOR_MOVE_TYPE moveType;
	int count, i;

	assert( currentCursor == NULL || \
			isReadPtr( currentCursor, MIN_ATTRLIST_SIZE ) );

	REQUIRES_N( getAttrFunction != NULL );
	REQUIRES_N( attributeMoveType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
				attributeMoveType == CRYPT_ATTRIBUTE_CURRENT || \
				attributeMoveType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );
	REQUIRES_N( cursorMoveType >= CRYPT_CURSOR_LAST && \
				cursorMoveType <= CRYPT_CURSOR_FIRST );	/* Values are -ve */

	/* Positioning in null attribute lists is always unsuccessful */
	if( currentCursor == NULL )
		return( NULL );

	/* Convert the move type into a more logical cursor move code */
	for( i = 0; 
		 moveCodeMap[ i ].moveCode != cursorMoveType && \
			moveCodeMap[ i ].moveCode != 0 && \
			i < FAILSAFE_ARRAYSIZE( moveCodeMap, MOVECODE_MAP_INFO ); 
		 i++ );
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( moveCodeMap, MOVECODE_MAP_INFO ) );
	ENSURES_N( moveCodeMap[ i ].moveCode != 0 );
	moveType = moveCodeMap[ i ].cursorMoveType;

	/* Set the amount that we want to move by based on the position code.
	   This means that we can handle the movement in a simple while loop
	   instead of having to special-case it for moves by one item */
	count = absMove ? MAX_INTLENGTH : 1;

	/* Perform the appropriate attribute move type */
	switch( attributeMoveType )
		{
		case CRYPT_ATTRIBUTE_CURRENT_GROUP:
			return( moveCursorByGroup( currentCursor, getAttrFunction, 
									   moveType, count, absMove ) );

		case CRYPT_ATTRIBUTE_CURRENT:
			return( moveCursorByAttribute( currentCursor, getAttrFunction,
										   moveType, count, absMove ) );

		case CRYPT_ATTRIBUTE_CURRENT_INSTANCE:
			return( moveCursorByInstance( currentCursor, getAttrFunction,
										  moveType, count, absMove ) );
		}

	/* Everything else is an error */
	retIntError_Null();
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -