public static size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, uint maxLog) { BYTE *istart = (BYTE *)cSrc; BYTE *ip = istart; short[] counting = new short[Fse.FSE_MAX_SYMBOL_VALUE + 1]; uint tableLog; uint maxSymbolValue = FSE_MAX_SYMBOL_VALUE; /* normal FSE decoding mode */ size_t NCountLength = ReadNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); if (IsError(NCountLength)) { return(NCountLength); } //if (NCountLength >= cSrcSize) return ERROR( Error.srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ if (tableLog > maxLog) { return(ERROR(Error.tableLog_tooLarge)); } ip += NCountLength; cSrcSize -= NCountLength; { size_t errcod = BuildDTable(workSpace, counting, maxSymbolValue, tableLog); if (IsError(errcod)) { return(errcod); } } return(FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace)); /* always return, even if it is an error code */ }
[DllImport(dll)] public static extern unsafe void HoughCircles_my(BYTE *dxBuf, int dxBw, int dxBh, int dxType, int dxStep, BYTE *dyBuf, int dyBw, int dyBh, int dyType, int dyStep, BYTE *edgesBuf, int edgesBw, int edgesBh, int edgesType, int edgesStep, BYTE *accumBuf, int accumBw, int accumBh, int accumType, int accumStep, BYTE *nzBuf, int nzBw, int nzBh, int nzType, int nzStep, double dp, double minDist, double param2, int minRadius, int maxRadius, int *numCircles, float **circles_NewAlloc);
public static U64 XXH64_digest_endian(XXH64_state_t state /*, XXH_endianess endian*/) { BYTE *p = (BYTE *)state.mem64; BYTE *bEnd = p + state.memsize; U64 h64; if (state.total_len >= 32) { U64 v1 = state.v1; U64 v2 = state.v2; U64 v3 = state.v3; U64 v4 = state.v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = state.v3 + PRIME64_5; } h64 += (U64)state.total_len; while (p + 8 <= bEnd) { U64 k1 = XXH64_round(0, XXH_readLE64(p /*, endian*/)); h64 ^= k1; h64 = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; p += 8; } if (p + 4 <= bEnd) { h64 ^= (U64)(XXH_readLE32(p /*, endian*/)) * PRIME64_1; h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; p += 4; } while (p < bEnd) { h64 ^= (*p) * PRIME64_5; h64 = XXH_rotl64(h64, 11) * PRIME64_1; p++; } h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return(h64); }
public static void memset(void *dst, BYTE byteValue, size_t length) { BYTE *dstByte = (BYTE *)dst; for (size_t i = 0; i < length; ++i) { dstByte[i] = byteValue; } }
public static void memmove(BYTE[] dst, void *src, size_t length) { BYTE *srcByte = (BYTE *)src; for (size_t i = 0; i < length; ++i) { dst[i] = srcByte[i]; } }
public static void Wildcopy(void *dst, void *src, int length) { BYTE *srcByte = (BYTE *)src; BYTE *dstByte = (BYTE *)dst; for (long i = 0; i < length; ++i) { dstByte[i] = srcByte[i]; } }
public static void *memmove(void *dst, void *src, size_t length) { BYTE *srcByte = (BYTE *)src; BYTE *dstByte = (BYTE *)dst; for (size_t i = 0; i < length; ++i) { dstByte[i] = srcByte[i]; } return(dst); }
//#ifndef FSE_COMMONDEFS_ONLY ///*-******************************************************* //* Decompression (Byte symbols) //*********************************************************/ //size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) //{ // void* ptr = dt; // FSE_DTableHeader* DTableH = (FSE_DTableHeader*)ptr; // void* dPtr = dt + 1; // FSE_decode_t* cell = (FSE_decode_t*)dPtr; // DTableH->tableLog = 0; // DTableH->fastMode = 0; // cell->newState = 0; // cell->symbol = symbolValue; // cell->nbBits = 0; // return 0; //} //size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) //{ // void* ptr = dt; // FSE_DTableHeader* DTableH = (FSE_DTableHeader*)ptr; // void* dPtr = dt + 1; // FSE_decode_t* dinfo = (FSE_decode_t*)dPtr; // unsigned tableSize = 1 << nbBits; // unsigned tableMask = tableSize - 1; // unsigned maxSV1 = tableMask+1; // unsigned s; // /* Sanity checks */ // if (nbBits < 1) return ERROR( Error.GENERIC); /* min size */ // /* Build Decoding Table */ // DTableH->tableLog = (U16)nbBits; // DTableH->fastMode = 1; // for (s=0; s<maxSV1; s++) { // dinfo[s].newState = 0; // dinfo[s].symbol = (BYTE)s; // dinfo[s].nbBits = (BYTE)nbBits; // } // return 0; //} public static size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, void *cSrc, size_t cSrcSize, FSE_DTable *dt, uint fast) { BYTE *ostart = (BYTE *)dst; BYTE *op = ostart; BYTE *omax = op + maxDstSize; BYTE *olimit = omax - 3; BIT_DStream_t bitD = new BIT_DStream_t(); FSE_DState_t state1 = new FSE_DState_t(); FSE_DState_t state2 = new FSE_DState_t(); /* Init */ { size_t errcod = InitDStream(bitD, cSrc, cSrcSize); if (IsError(errcod)) { return(errcod); } } Fse.InitDState(state1, bitD, dt); Fse.InitDState(state2, bitD, dt); //#define FSE_GETSYMBOL(statePtr) fast ? DecodeSymbolFast(statePtr, &bitD) : DecodeSymbol(statePtr, &bitD) /* 4 symbols per loop */ for (; (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_unfinished) & (op < olimit); op += 4) { op[0] = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); //if (FSE_MAX_TABLELOG * 2 + 7 > sizeOfBitContainer * 8) /* This test must be static */ // ReloadDStream(bitD); op[1] = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); if (FSE_MAX_TABLELOG * 4 + 7 > sizeOfBitContainer * 8) /* This test must be static */ { if (ReloadDStream(bitD) > BIT_DStream_status.BIT_DStream_unfinished) { op += 2; break; } } op[2] = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); //if (FSE_MAX_TABLELOG * 2 + 7 > sizeOfBitContainer * 8) /* This test must be static */ // ReloadDStream(bitD); op[3] = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); } /* tail */ /* note : ReloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ while (true) { if (op > (omax - 2)) { return(ERROR(Error.dstSize_tooSmall)); } *op++ = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); if (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_overflow) { *op++ = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); break; } if (op > (omax - 2)) { return(ERROR(Error.dstSize_tooSmall)); } *op++ = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); if (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_overflow) { *op++ = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); break; } } return((size_t)(op - ostart)); }
//FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, void* input, size_t len, XXH_endianess endian) //{ // BYTE* p = ( BYTE*)input; // BYTE* bEnd = p + len; //#ifdef XXH_ACCEPT_NULL_INPUT_POINTER // if (input==NULL) return XXH_ERROR; //#endif // state->total_len_32 += (unsigned)len; // state->large_len |= (len>=16) | (state->total_len_32>=16); // if (state->memsize + len < 16) { /* fill in tmp buffer */ // XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); // state->memsize += (unsigned)len; // return XXH_OK; // } // if (state->memsize) { /* some data left from previous update */ // XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); // { U32* p32 = state->mem32; // state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; // state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; // state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; // state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; // } // p += 16-state->memsize; // state->memsize = 0; // } // if (p <= bEnd-16) { // BYTE* limit = bEnd - 16; // U32 v1 = state->v1; // U32 v2 = state->v2; // U32 v3 = state->v3; // U32 v4 = state->v4; // do { // v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; // v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; // v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; // v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; // } while (p<=limit); // state->v1 = v1; // state->v2 = v2; // state->v3 = v3; // state->v4 = v4; // } // if (p < bEnd) { // XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); // state->memsize = (unsigned)(bEnd-p); // } // return XXH_OK; //} //XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, void* input, size_t len) //{ // XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; // if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) // return XXH32_update_endian(state_in, input, len, XXH_littleEndian); // else // return XXH32_update_endian(state_in, input, len, XXH_bigEndian); //} //FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian ( XXH32_state_t* state, XXH_endianess endian) //{ // BYTE * p = ( BYTE*)state->mem32; // BYTE* bEnd = ( BYTE*)(state->mem32) + state->memsize; // U32 h32; // if (state->large_len) { // h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); // } else { // h32 = state->v3 /* == seed */ + PRIME32_5; // } // h32 += state->total_len_32; // while (p+4<=bEnd) { // h32 += XXH_readLE32(p, endian) * PRIME32_3; // h32 = XXH_rotl32(h32, 17) * PRIME32_4; // p+=4; // } // while (p<bEnd) { // h32 += (*p) * PRIME32_5; // h32 = XXH_rotl32(h32, 11) * PRIME32_1; // p++; // } // h32 ^= h32 >> 15; // h32 *= PRIME32_2; // h32 ^= h32 >> 13; // h32 *= PRIME32_3; // h32 ^= h32 >> 16; // return h32; //} //XXH_PUBLIC_API unsigned int XXH32_digest ( XXH32_state_t* state_in) //{ // XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; // if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) // return XXH32_digest_endian(state_in, XXH_littleEndian); // else // return XXH32_digest_endian(state_in, XXH_bigEndian); //} ///* **** XXH64 **** */ public static XXH_errorcode XXH64_update_endian(XXH64_state_t state, void *input, size_t len /*, XXH_endianess endian*/) { BYTE *p = (BYTE *)input; BYTE *bEnd = p + len; //#ifdef XXH_ACCEPT_NULL_INPUT_POINTER // if (input==NULL) return XXH_ERROR; //#endif state.total_len += len; if (state.memsize + len < 32) { /* fill in tmp buffer */ XXH_memcpy(((BYTE *)state.mem64) + state.memsize, input, len); state.memsize += (U32)len; return(XXH_errorcode.XXH_OK); } if (state.memsize != 0) { /* tmp buffer is full */ XXH_memcpy(((BYTE *)state.mem64) + state.memsize, input, 32 - state.memsize); state.v1 = XXH64_round(state.v1, XXH_readLE64(state.mem64 + 0 /*, endian*/)); state.v2 = XXH64_round(state.v2, XXH_readLE64(state.mem64 + 1 /*, endian*/)); state.v3 = XXH64_round(state.v3, XXH_readLE64(state.mem64 + 2 /*, endian*/)); state.v4 = XXH64_round(state.v4, XXH_readLE64(state.mem64 + 3 /*, endian*/)); p += 32 - state.memsize; state.memsize = 0; } if (p + 32 <= bEnd) { BYTE *limit = bEnd - 32; U64 v1 = state.v1; U64 v2 = state.v2; U64 v3 = state.v3; U64 v4 = state.v4; do { v1 = XXH64_round(v1, XXH_readLE64(p /*, endian*/)); p += 8; v2 = XXH64_round(v2, XXH_readLE64(p /*, endian*/)); p += 8; v3 = XXH64_round(v3, XXH_readLE64(p /*, endian*/)); p += 8; v4 = XXH64_round(v4, XXH_readLE64(p /*, endian*/)); p += 8; } while (p <= limit); state.v1 = v1; state.v2 = v2; state.v3 = v3; state.v4 = v4; } if (p < bEnd) { XXH_memcpy(state.mem64, p, (size_t)(bEnd - p)); state.memsize = (uint)(bEnd - p); } return(XXH_errorcode.XXH_OK); }
///* ************************************* //* Dependencies //***************************************/ //#include "mem.h" //#include "error_private.h" /* ERR_*, ERROR */ //#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ //#include "fse.h" //#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ //#include "huf.h" ///*=== Version ===*/ //unsigned VersionNumber(void) { return FSE_VERSION_NUMBER; } ///*=== Error Management ===*/ //unsigned IsError(size_t code) { return ERR_isError(code); } // char* GetErrorName(size_t code) { return ERR_getErrorName(code); } //unsigned IsError(size_t code) { return ERR_isError(code); } // char* GetErrorName(size_t code) { return ERR_getErrorName(code); } /*-************************************************************** * FSE NCount encoding-decoding ****************************************************************/ public static size_t ReadNCount(short[] normalizedCounter, uint *maxSVPtr, uint *tableLogPtr, void *headerBuffer, size_t hbSize) { BYTE *istart = (BYTE *)headerBuffer; BYTE *iend = istart + hbSize; BYTE *ip = istart; int nbBits; int remaining; int threshold; U32 bitStream; int bitCount; uint charnum = 0; int previous0 = 0; if (hbSize < 4) { return(ERROR(Error.srcSize_wrong)); } bitStream = MEM_readLE32(ip); nbBits = (int)(bitStream & 0xF) + Fse.FSE_MIN_TABLELOG; /* extract tableLog */ if (nbBits > Fse.FSE_TABLELOG_ABSOLUTE_MAX) { return(ERROR(Error.tableLog_tooLarge)); } bitStream >>= 4; bitCount = 4; *tableLogPtr = (size_t)nbBits; remaining = (1 << nbBits) + 1; threshold = 1 << nbBits; nbBits++; while ((remaining > 1) & (charnum <= *maxSVPtr)) { if (previous0 != 0) { uint n0 = charnum; while ((bitStream & 0xFFFF) == 0xFFFF) { n0 += 24; if (ip < iend - 5) { ip += 2; bitStream = MEM_readLE32(ip) >> bitCount; } else { bitStream >>= 16; bitCount += 16; } } while ((bitStream & 3) == 3) { n0 += 3; bitStream >>= 2; bitCount += 2; } n0 += bitStream & 3; bitCount += 2; if (n0 > *maxSVPtr) { return(ERROR(Error.maxSymbolValue_tooSmall)); } while (charnum < n0) { normalizedCounter[charnum++] = 0; } if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) { ip += bitCount >> 3; bitCount &= 7; bitStream = MEM_readLE32(ip) >> bitCount; } else { bitStream >>= 2; } } { int max = (2 * threshold - 1) - remaining; int count; if ((bitStream & (threshold - 1)) < (U32)max) { count = (int)bitStream & (threshold - 1); bitCount += nbBits - 1; } else { count = (int)bitStream & (2 * threshold - 1); if (count >= threshold) { count -= max; } bitCount += nbBits; } count--; /* extra accuracy */ remaining -= count < 0 ? -count : count; /* -1 means +1 */ normalizedCounter[charnum++] = (short)count; previous0 = count == 0 ? 1 : 0; while (remaining < threshold) { nbBits--; threshold >>= 1; } if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) { ip += bitCount >> 3; bitCount &= 7; } else { bitCount -= (int)(8 * (iend - 4 - ip)); ip = iend - 4; } bitStream = MEM_readLE32(ip) >> (bitCount & 31); } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ if (remaining != 1) { return(ERROR(Error.corruption_detected)); } if (bitCount > 32) { return(ERROR(Error.corruption_detected)); } *maxSVPtr = charnum - 1; ip += (bitCount + 7) >> 3; return((size_t)(ip - istart)); }
/*! ReadStats() : * Read compact Huffman tree, saved by WriteCTable(). * `huffWeight` is destination buffer. * `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. * @return : size read from `src` , or an error Code . * Note : Needed by ReadCTable() and HUF_readDTableX?() . */ public static size_t ReadStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, void *src, size_t srcSize) { U32 weightTotal; BYTE * ip = (BYTE *)src; size_t iSize; size_t oSize; if (srcSize == 0) { return(ERROR(Error.srcSize_wrong)); } iSize = ip[0]; /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ if (iSize >= 128) { /* special header */ oSize = iSize - 127; iSize = ((oSize + 1) / 2); if (iSize + 1 > srcSize) { return(ERROR(Error.srcSize_wrong)); } if (oSize >= hwSize) { return(ERROR(Error.corruption_detected)); } ip += 1; { U32 n; for (n = 0; n < oSize; n += 2) { huffWeight[n] = (BYTE)(ip[n / 2] >> 4); huffWeight[n + 1] = (BYTE)(ip[n / 2] & 15); } } } else { /* header compressed with FSE (normal case) */ FSE_DTable *fseWorkspace = stackalloc FSE_DTable[Fse.FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ if (iSize + 1 > srcSize) { return(ERROR(Error.srcSize_wrong)); } oSize = FseDecompress.FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ if (IsError(oSize)) { return(oSize); } } /* collect weight stats */ memset(rankStats, 0, (Huf.HUF_TABLELOG_MAX + 1) * sizeof(U32)); weightTotal = 0; { U32 n; for (n = 0; n < oSize; n++) { if (huffWeight[n] >= Huf.HUF_TABLELOG_MAX) { return(ERROR(Error.corruption_detected)); } rankStats[huffWeight[n]]++; weightTotal += ((U32)1 << huffWeight[n]) >> 1; } } if (weightTotal == 0) { return(ERROR(Error.corruption_detected)); } /* get last non-null symbol weight (implied, total must be 2^n) */ { U32 tableLog = BitStream.BIT_highbit32(weightTotal) + 1; if (tableLog > Huf.HUF_TABLELOG_MAX) { return(ERROR(Error.corruption_detected)); } *tableLogPtr = tableLog; /* determine last weight */ { U32 total = (U32)1 << (int)tableLog; U32 rest = total - weightTotal; U32 verif = (U32)1 << (int)BitStream.BIT_highbit32(rest); U32 lastWeight = BitStream.BIT_highbit32(rest) + 1; if (verif != rest) { return(ERROR(Error.corruption_detected)); /* last value must be a clean power of 2 */ } huffWeight[oSize] = (BYTE)lastWeight; rankStats[lastWeight]++; } } /* check tree construction validity */ if ((rankStats[1] < 2) || ((rankStats[1] & 1) != 0)) { return(ERROR(Error.corruption_detected)); /* by construction : at least 2 elts of rank 1, must be even */ } /* results */ *nbSymbolsPtr = (U32)(oSize + 1); return(iSize + 1); }
public void WriteTagListWithPublishInfo(DataIO pData) { if (m_pliPublishingIPs == null || m_pliPublishingIPs.Count == 0) { Debug.Assert(false); WriteTagList(pData); return; } uint nAdditionalTags = 1; if (!m_aAICHHashs.IsEmpty()) { nAdditionalTags++; } WriteTagListInc(pData, nAdditionalTags); // write the standard taglist but increase the tagcount by the count we wan to add // here we add a tag including how many publishers this entry has, the trustvalue and how many different names are known // this is supposed to get used in later versions as an indicator for the user how valid this result is (of course this tag // alone cannt be trusted 100%, because we could be a bad node, but its a part of the puzzle) uint uTrust = (ushort)(GetTrustValue() * 100); uint uPublishers = m_pliPublishingIPs.Count % 256; uint uNames = m_listFileNames.Count % 256; // 32 bit tag: <namecount uint8><publishers uint8><trustvalue*100 uint16> uint uTagValue = (uNames << 24) | (uPublishers << 16) | (uTrust << 0); KadTagUInt tag(TAG_PUBLISHINFO, uTagValue); pData.WriteTag(&tag); // Last but not least the AICH Hash tag, containing all reported (hopefulley exactly 1) AICH hashes for this file together // with the count of publishers who reported it if (!m_aAICHHashs.IsEmpty()) { SafeMemFile fileAICHTag(100); byte byCount = 0; // get count of AICH tags with popularity > 0 for (int i = 0; i < m_aAICHHashs.Count; i++) { if (m_anAICHHashPopularity[i] > 0) { byCount++; } // bobs tags in kad are limited to 255 bytes, so no more than 12 AICH hashes can be written // that shouldn't be an issue however, as the normal AICH hash count is 1, if we have more than // 10 for some reason we can't use it most likely anyway if (1 + (CAICHHash::GetHashSize() * (byCount + 1)) + (1 * (byCount + 1)) > 250) { DebugLogWarning("More than 12(!) AICH Hashs to send for search answer, have to truncate, entry: %s", m_uSourceID.ToHexString()); break; } } // write tag even on 0 count now fileAICHTag.WriteUInt8(byCount); byte nWritten = 0; byte j; for (j = 0; nWritten < byCount && j < m_aAICHHashs.GetCount(); j++) { if (m_anAICHHashPopularity[j] > 0) { fileAICHTag.WriteUInt8(m_anAICHHashPopularity[j]); m_aAICHHashs[j].Write(&fileAICHTag); nWritten++; } } Debug.Assert(nWritten == byCount && nWritten <= j); Debug.Assert(fileAICHTag.GetLength() <= 255); byte nSize = (byte)fileAICHTag.GetLength(); BYTE *byBuffer = fileAICHTag.Detach(); KadTagBsob tag(TAG_KADAICHHASHRESULT, byBuffer, nSize); pData.WriteTag(&tag); free(byBuffer); } }