📄 mbuflib.c
字号:
if (mbufSeg == NULL) /* use head if mbuf NULL */ mbufSeg = mbufId->mbufHead; while ((mbufNext = mbufSeg->m_next) != NULL) /* join */ { if (!(M_HASCL(mbufSeg)) || !(M_HASCL(mbufNext))) break; /* must be clusters */ if ((mtod (mbufSeg, int) + mbufSeg->m_len) != (mtod (mbufNext, int))) break; /* data must be adjacent */ /* check that mbuf params are the exact same */ if ((mbufSeg->m_type != mbufNext->m_type) || (mbufSeg->m_flags != mbufNext->m_flags) || (mbufSeg->m_extBuf != mbufNext->m_extBuf) || (mbufSeg->m_extRefCnt != mbufNext->m_extRefCnt) || (mbufSeg->m_extFreeRtn != mbufNext->m_extFreeRtn) || (mbufSeg->m_extArg1 != mbufNext->m_extArg1) || (mbufSeg->m_extArg2 != mbufNext->m_extArg2) || (mbufSeg->m_extArg3 != mbufNext->m_extArg3) || (mbufSeg->m_extSize != mbufNext->m_extSize)) break; mbufSeg->m_len += mbufNext->m_len; /* join */ mbufSeg->m_next = m_free (mbufNext); /* bump */ status = OK; } return (status); }#endif /* FALSE *//********************************************************************************* _mbufSegFindPrev - find the mbuf prev to a specified byte location** This routine finds the mbuf in <mbufId> that is previous to the byte* location specified by <mbufSeg> and <pOffset>. Once found, a pointer* to the m_next pointer of that mbuf is returned by this routine,* and the offset to the specified location is returned in <pOffset>. ** This routine is similar to _mbufSegFind(), except that a pointer to the* previous mbuf's m_next is returned by this routine, instead of the mbuf* itself. Additionally, the end boundary case differs. This routine will* return a valid pointer and offset when the specified byte is the byte just* past the end of the chain. Return values for this "imaginary" byte* will also be returned when an offset of MBUF_END is passed in.** RETURNS:* A pointer to the m_next pointer of the mbuf previous to the mbuf associated* with the mbuf containing the specified byte, or NULL if the operation failed.** NOMANUAL*/LOCAL MBUF_SEG * _mbufSegFindPrev ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg, /* mbuf base for <pOffset> */ int * pOffset /* relative byte offset */ ) { MBUF_SEG * pMbufPrev; /* prev ptr for return */ MBUF_SEG mbuf; /* mbuf in chain */ int offset; /* offset in bytes */ int length; /* length counter */ if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (NULL); } pMbufPrev = &mbufId->mbufHead; /* init prev ptr to head */ if ((mbuf = mbufId->mbufHead) == NULL) /* is this chain empty ? */ { if ((mbufSeg == NULL) && (*pOffset == 0))/* empty mbuf ID ? */ return (pMbufPrev); /* OK, if explicit */ else /* else error condition */ { errno = S_mbufLib_ID_EMPTY; return (NULL); } } if ((offset = *pOffset) == MBUF_BEGIN) /* shortcut to head of chain */ { *pOffset = 0; return (pMbufPrev); } else if (offset == MBUF_END) /* shortcut to end of chain */ { if (mbufSeg != NULL) mbuf = mbufSeg; /* set base as <mbufSeg> */ for (; mbuf->m_next != NULL; mbuf = mbuf->m_next) ; /* find last mbuf in chain */ *pOffset = 0; /* imaginary byte past mbuf */ return (&mbuf->m_next); } else if (offset < 0) /* counting backwards ? */ { if ((mbufSeg == NULL) || (mbufSeg == mbufId->mbufHead)) { errno = S_mbufLib_OFFSET_INVALID; return (NULL); /* offset before head */ } for (length = 0; (mbuf->m_next != NULL) && (mbuf->m_next != mbufSeg); mbuf = mbuf->m_next) { length += mbuf->m_len; /* find length up to base */ pMbufPrev = &mbuf->m_next; } if (mbuf->m_next == NULL) { errno = S_mbufLib_SEGMENT_NOT_FOUND; return (NULL); /* couldn't find base mbufSeg */ } if (-(offset) < mbuf->m_len) /* within one mbuf */ { *pOffset += mbuf->m_len; return (pMbufPrev); } if ((offset += length + mbuf->m_len) < 0)/* adjust to positive */ { errno = S_mbufLib_OFFSET_INVALID; return (NULL); } mbuf = mbufId->mbufHead; pMbufPrev = &mbufId->mbufHead; /* init prev ptr to head */ } else if ((mbufSeg != NULL) && (mbufSeg != mbuf))/* new base, init head */ { if (offset < mbufSeg->m_len) /* dest within this base ? */ { if ((mbuf = _mbufSegPrev (mbufId, mbufSeg)) != NULL) return (&mbuf->m_next); /* located previous mbuf */ else return (NULL); } mbuf = mbufSeg; /* set base as <mbufSeg> */ } for (; (mbuf != NULL) && (offset >= mbuf->m_len); mbuf = mbuf->m_next) { offset -= mbuf->m_len; /* find right mbuf in chain */ pMbufPrev = &mbuf->m_next; } if ((mbuf == NULL) && (offset != 0)) { errno = S_mbufLib_OFFSET_INVALID; return (NULL); /* too large offset */ } *pOffset = offset; /* return new offset */ return (pMbufPrev); /* return found mbuf */ }/********************************************************************************* _mbufSegFind - find the mbuf containing a specified byte location** This routine finds the mbuf in <mbufId> that contains the byte location* specified by <mbufSeg> and <pOffset>. Once found, the mbuf is returned* by this routine, and the offset to the specified location is returned* in <pOffset>. ** <mbufSeg> determines the base from which <pOffset> is counted.* If <mbufSeg> is NULL, then <pOffset> starts from the beginning of <mbufId>.* If <mbufSeg> is not NULL, then <pOffset> starts relative to that* mbuf. Byte locations after <mbufSeg> would be specified with a* positive offset, whereas locations previous to <mbufSeg> would be* accessed with a negative offset.** <pOffset> is a pointer to a byte offset into the mbuf chain, with offset 0* being the first byte of data in the mbuf. The offset does not reset* for each mbuf in the chain when counting through <mbufId>. For example,* if offset 100 is the last byte in a particular mbuf, offset 101 will be* the first byte in the next mbuf. Also, the offset may be a negative value.* An offset of -1 locates the last byte in the previous mbuf. If offset -55* is the first byte in a mbuf, an offset -56 would be the last byte in the* preceding mbuf.** The last byte in the mbuf chain may be specified by passing in an offset of* MBUF_END, which would cause this routine to return the last mbuf* in the chain, and return an offset to the last byte in that mbuf.* Likewise, an offset of MBUF_BEGIN may be passed in to specify the* first byte in the chain, causing the routine to return the first mbuf* in the chain, and return an offset of 0.** If the <mbufSeg>, <pOffset> pair specify a byte location past the end* of the chain, or before the first byte in the chain, NULL is returned by* this routine.** RETURNS:* An mbuf pointer associated with the mbuf containing the specified byte,* or NULL if the operation failed.** NOMANUAL*/MBUF_SEG _mbufSegFind ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg, /* mbuf base for <pOffset> */ int * pOffset /* relative byte offset */ ) { MBUF_SEG mbuf; /* mbuf in chain */ int offset; /* offset in bytes */ int length; /* length counter */ if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (NULL); } if ((mbuf = mbufId->mbufHead) == NULL) /* is this chain empty ? */ { errno = S_mbufLib_ID_EMPTY; return (NULL); } if ((offset = *pOffset) == MBUF_BEGIN) /* shortcut to head of chain */ { *pOffset = 0; return (mbuf); } else if (offset == MBUF_END) /* shortcut to end of chain */ { if (mbufSeg != NULL) mbuf = mbufSeg; /* set base as <mbufSeg> */ for (; mbuf->m_next != NULL; mbuf = mbuf->m_next) ; /* find last mbuf in chain */ *pOffset = mbuf->m_len - 1; /* stuff new offset */ return (mbuf); } else if (offset < 0) /* counting backwards ? */ { if ((mbufSeg == NULL) || (mbufSeg == mbufId->mbufHead)) { errno = S_mbufLib_OFFSET_INVALID; return (NULL); /* offset before head */ } for (length = 0; (mbuf->m_next != NULL) && (mbuf->m_next != mbufSeg); mbuf = mbuf->m_next) length += mbuf->m_len; /* find length up to base */ if (mbuf->m_next == NULL) { errno = S_mbufLib_SEGMENT_NOT_FOUND; return (NULL); /* couldn't find base mbufSeg */ } if (-(offset) < mbuf->m_len) /* within one mbuf */ { *pOffset += mbuf->m_len; return (mbuf); } if ((offset += length + mbuf->m_len) < 0)/* adjust to positive */ { errno = S_mbufLib_OFFSET_INVALID; return (NULL); } mbuf = mbufId->mbufHead; } else if (mbufSeg != NULL) mbuf = mbufSeg; /* set base as <mbufSeg> */ for (; (mbuf != NULL) && (offset >= mbuf->m_len); mbuf = mbuf->m_next) offset -= mbuf->m_len; /* find right mbuf in chain */ if (mbuf == NULL) errno = S_mbufLib_OFFSET_INVALID; else *pOffset = offset; /* return new offset */ return (mbuf); /* return found mbuf */ }/********************************************************************************* _mbufSegNext - get the next mbuf in an mbuf chain** This routine finds the mbuf in <mbufId> that is just after the* mbuf <mbufSeg>. If <mbufSeg> is NULL, the mbuf after the first* mbuf in <mbufId> is returned. If <mbufSeg> is the last mbuf in* <mbufId>, NULL is returned** RETURNS:* An mbuf pointer associated with the mbuf after <mbufSeg>, * or NULL if the operation failed.** NOMANUAL*/MBUF_SEG _mbufSegNext ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg /* mbuf to get next mbuf */ ) { if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (NULL); } if (mbufId->mbufHead == NULL) /* is this chain empty ? */ { errno = S_mbufLib_ID_EMPTY; return (NULL); } /* get mbuf after <mbufSeg> (or start of chain if <mbufSeg> is NULL) */ if (mbufSeg == NULL) return (mbufId->mbufHead->m_next); else return (mbufSeg->m_next); }/********************************************************************************* _mbufSegPrev - get the previous mbuf in an mbuf chain** This routine finds the mbuf in <mbufId> that is just previous* to the mbuf <mbufSeg>. If <mbufSeg> is NULL, or is the first* mbuf in <mbufId>, NULL will be returned.** RETURNS:* An mbuf pointer associated with the mbuf previous to <mbufSeg>,* or NULL if the operation failed.** NOMANUAL*/MBUF_SEG _mbufSegPrev ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg /* mbuf to get previous mbuf */ ) { MBUF_SEG mbuf = mbufId->mbufHead;/* mbuf in chain */ if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (NULL); } if ((mbufSeg == NULL) || (mbufSeg == mbuf)) return (NULL); /* no previous to first mbuf */ /* * Find <mbufSeg> and return a pointer to the previous mbuf. * Note: OK if <mbufSeg> is not found... the return will be NULL anyway. */ for (; (mbuf != NULL) && (mbuf->m_next != mbufSeg); mbuf = mbuf->m_next) ; if (mbuf == NULL) /* could not find mbufSeg */ errno = S_mbufLib_SEGMENT_NOT_FOUND; return (mbuf); }/********************************************************************************* _mbufSegData - determine the location of data in an mbuf** This routine returns the location of the first byte of data in the mbuf* <mbufSeg>. If <mbufSeg> is NULL, the location of data in the first mbuf* in <mbufId> is returned.** RETURNS:* A pointer to the first byte of data in the specified mbuf,* or NULL if the mbuf chain is empty.** NOMANUAL*/caddr_t _mbufSegData ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg /* mbuf to get pointer to data */ ) { if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (NULL); } if (mbufId->mbufHead == NULL) /* is this chain empty ? */ { errno = S_mbufLib_ID_EMPTY; return (NULL); } /* get data location <mbufSeg> (or start of chain if <mbufSeg> is NULL) */ if (mbufSeg == NULL) return (mtod (mbufId->mbufHead, caddr_t)); else return (mtod (mbufSeg, caddr_t)); }/********************************************************************************* _mbufSegLength - determine the length of an mbuf** This routine returns the number of bytes in the mbuf <mbufSeg>. * If <mbufSeg> is NULL, the length of the first mbuf in <mbufId> is* returned. ** RETURNS:* The number of bytes in the specified mbuf, or ERROR if incorrect parameters.** NOMANUAL*/int _mbufSegLength ( MBUF_ID mbufId, /* mbuf ID to examine */ MBUF_SEG mbufSeg /* mbuf to determine length of */ ) { if (mbufId == NULL || mbufId->type != MBUF_VALID) /* invalid ID ? */ { errno = S_mbufLib_ID_INVALID; return (ERROR); } if (mbufId->mbufHead == NULL) /* is this chain empty ? */ { if (mbufSeg == NULL) /* empty mbuf chain */ return (0); errno = S_mbufLib_SEGMENT_NOT_FOUND; return (ERROR); } /* get length of <mbufSeg> (or start of chain if <mbufSeg> is NULL) */ if (mbufSeg == NULL) return (mbufId->mbufHead->m_len); else return (mbufSeg->m_len); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -