extern DLLSERVER_API bool decompressResource(size32_t len, const void *data, StringBuffer &result) { bool hasVersion = len && (*(const byte *)data == 0x80); MemoryBuffer src; src.setBuffer(len, const_cast<void *>(data), false); byte version = 1; if (hasVersion) { src.skip(1); src.read(version); } MemoryBuffer tgt; switch (version) { case 1: decompressToBuffer(tgt, src); break; default: throwUnexpected(); } tgt.append((char)0); unsigned expandedLen = tgt.length(); result.setBuffer(expandedLen, reinterpret_cast<char *>(tgt.detach()), expandedLen-1); return true; }
extern DLLSERVER_API bool decompressResource(size32_t len, const void *data, StringBuffer &result) { MemoryBuffer tgt; decompressResource(len, data, tgt); tgt.append((char)0); unsigned expandedLen = tgt.length(); result.setBuffer(expandedLen, reinterpret_cast<char *>(tgt.detach()), expandedLen-1); return true; }
void CJHTreeNode::unpack(const void *node, bool needCopy) { memcpy(&hdr, node, sizeof(hdr)); SwapBigEndian(hdr); __int64 maxsib = keyHdr->getHdrStruct()->phyrec; if (!hdr.isValid(keyHdr->getNodeSize())) { PROGLOG("hdr.leafFlag=%d",(int)hdr.leafFlag); PROGLOG("hdr.rightSib=%" I64F "d",hdr.rightSib); PROGLOG("hdr.leftSib=%" I64F "d",hdr.leftSib); PROGLOG("maxsib=%" I64F "d",maxsib); PROGLOG("nodeSize=%d", keyHdr->getNodeSize()); PROGLOG("keyBytes=%d",(int)hdr.keyBytes); PrintStackReport(); throw MakeStringException(0, "Htree: Corrupt key node detected"); } if (!hdr.leafFlag) keyLen = keyHdr->getNodeKeyLength(); keyRecLen = keyLen + sizeof(offset_t); char *keys = ((char *) node) + sizeof(hdr); if (hdr.crc32) { unsigned crc = crc32(keys, hdr.keyBytes, 0); if (hdr.crc32 != crc) throw MakeStringException(0, "CRC error on key node"); } if (hdr.leafFlag==1) { firstSequence = *(unsigned __int64 *) keys; keys += sizeof(unsigned __int64); _WINREV(firstSequence); } if(isMetadata()) { unsigned short len = *reinterpret_cast<unsigned short *>(keys); _WINREV(len); expandedSize = len; keyBuf = (char *) allocMem(len); memcpy(keyBuf, keys+sizeof(unsigned short), len); } else if (isLeaf() && (keyType & HTREE_COMPRESSED_KEY)) { { MTIME_SECTION(queryActiveTimer(), "Compressed node expand"); expandedSize = keyHdr->getNodeSize(); bool quick = (keyType&HTREE_QUICK_COMPRESSED_KEY)==HTREE_QUICK_COMPRESSED_KEY; #ifndef _OLD_VERSION keyBuf = NULL; if (quick) rowexp.setown(expandQuickKeys(keys, needCopy)); if (!quick||!rowexp.get()) #endif { keyBuf = expandKeys(keys,keyLen,expandedSize,quick); } } assertex(keyBuf||rowexp.get()); } else { int i; if (keyType & COL_PREFIX) { MTIME_SECTION(queryActiveTimer(), "COL_PREFIX expand"); if (hdr.numKeys) { bool handleVariable = isVariable && isLeaf(); KEYRECSIZE_T workRecLen; MemoryBuffer keyBufMb; const char *source = keys; char *target; // do first row if (handleVariable) { memcpy(&workRecLen, source, sizeof(workRecLen)); _WINREV(workRecLen); size32_t tmpSz = sizeof(workRecLen) + sizeof(offset_t); target = (char *)keyBufMb.reserve(tmpSz+workRecLen); memcpy(target, source, tmpSz); source += tmpSz; target += tmpSz; } else { target = (char *)keyBufMb.reserveTruncate(hdr.numKeys * keyRecLen); workRecLen = keyRecLen - sizeof(offset_t); memcpy(target, source, sizeof(offset_t)); source += sizeof(offset_t); target += sizeof(offset_t); } // this is where next row gets data from const char *prev, *next = NULL; unsigned prevOffset = 0; if (handleVariable) prevOffset = target-((char *)keyBufMb.bufferBase()); else next = target; unsigned char pack1 = *source++; #ifdef _DEBUG assertex(0==pack1); // 1st time will be always be 0 #endif KEYRECSIZE_T left = workRecLen; while (left--) { *target = *source; source++; target++; } // do subsequent rows for (i = 1; i < hdr.numKeys; i++) { if (handleVariable) { memcpy(&workRecLen, source, sizeof(workRecLen)); _WINREV(workRecLen); target = (char *)keyBufMb.reserve(sizeof(workRecLen)+sizeof(offset_t)+workRecLen); size32_t tmpSz = sizeof(workRecLen)+sizeof(offset_t); memcpy(target, source, tmpSz); target += tmpSz; source += tmpSz; } else { memcpy(target, source, sizeof(offset_t)); source += sizeof(offset_t); target += sizeof(offset_t); } pack1 = *source++; #ifdef _DEBUG assertex(pack1<=workRecLen); #endif if (handleVariable) { prev = ((char *)keyBufMb.bufferBase())+prevOffset; // for next prevOffset = target-((char *)keyBufMb.bufferBase()); } else { prev = next; next = target; } left = workRecLen - pack1; while (pack1--) { *target = *prev; prev++; target++; } while (left--) { *target = *source; source++; target++; } } expandedSize = keyBufMb.length(); keyBuf = (char *)keyBufMb.detach(); assertex(keyBuf); } else { keyBuf = NULL; expandedSize = 0; } } else { MTIME_SECTION(queryActiveTimer(), "NO compression copy"); expandedSize = hdr.keyBytes + sizeof( __int64 ); // MORE - why is the +sizeof() there? keyBuf = (char *) allocMem(expandedSize); memcpy(keyBuf, keys, hdr.keyBytes + sizeof( __int64 )); } } }
int FuncCallStack::push(ITypeInfo* argType, IHqlExpression* curParam) { unsigned len = 0; char* str; int incsize; int inclen; IValue * paramValue = curParam->queryValue(); Owned<IValue> castParam; if (paramValue) // Not all constants have a paramValue - null, all, constant records etc { castParam.setown(paramValue->castTo(argType)); if(!castParam) { PrintLog("Failed to cast paramValue to argType in FuncCallStack::push"); return -1; } } switch (argType->getTypeCode()) { case type_string: case type_data: getStringFromIValue(len, str, castParam); // For STRINGn, len doesn't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_varstring: getStringFromIValue(len, str, castParam); push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_qstring: case type_unicode: case type_utf8: { unsigned argSize = castParam->getSize(); const void * text = castParam->queryValue(); str = (char *)malloc(argSize); memcpy(str, text, argSize); // For STRINGn, len doens't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { len = castParam->queryType()->getStringLen(); push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } } break; case type_varunicode: UNIMPLEMENTED; case type_real: #ifdef MAXFPREGS if (numFpRegs==MAXFPREGS) { PrintLog("Too many floating point registers needed in FuncCallStack::push"); return -1; } char tempbuf[sizeof(double)]; castParam->toMem(tempbuf); #ifdef FPREG_FIXEDSIZE if (argType->getSize()<=4) fpRegs[numFpRegs++] = *(float *)&tempbuf; else fpRegs[numFpRegs++] = *(double *)&tempbuf; #else // Variable size FP registers as on arm/x64 if (argType->getSize()<=4) fpRegs[numFpRegs].f = *(float *)&tempbuf; else fpRegs[numFpRegs].d = *(double *)&tempbuf; fpSizes[numFpRegs++] = argType->getSize(); #endif break; #else // fall through if no hw regs used for params #endif case type_boolean: case type_int: case type_decimal: case type_date: case type_char: case type_enumerated: case type_swapint: case type_packedint: incsize = argType->getSize(); inclen = align(incsize); assure(inclen); castParam->toMem(stackbuf+sp); memset(stackbuf+sp+incsize, 0, inclen - incsize); sp += inclen; break; case type_row: { if (hasMeta) { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } } if (curParam->getOperator()==no_null) { // MORE - check type matches MemoryBuffer out; createConstantNullRow(out, curParam->queryRecord()); str = (char *) out.detach(); push(sizeof(char *), &str); if(numToFree < MAXARGS) toFree[numToFree++] = str; } else return -1; break; } case type_record: { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } break; } default: EclIR::dump_ir(curParam); //code isn't here to pass sets/datasets to external functions.... return -1; } return sp; }