virtual void bindStringParam(const char *name, size32_t len, const char *val) { size32_t utf8chars; char *utf8; rtlStrToUtf8X(utf8chars, utf8, len, val); checkSqliteError(sqlite3_bind_text(stmt, findParameter(name), utf8, rtlUtf8Size(len, utf8), rtlFree)); }
virtual void processUtf8(unsigned len, const char *value, const RtlFieldInfo * field) { size32_t utf8chars; char *utf8; rtlUtf8ToUtf8X(utf8chars, utf8, len, value); MYSQL_BIND &bindInfo = createBindBuffer(MYSQL_TYPE_STRING, 0); bindInfo.buffer = utf8; bindInfo.buffer_length = rtlUtf8Size(utf8chars, utf8); bindInfo.length = &bindInfo.buffer_length; }
void ViewFieldTransformer::transform(MemoryAttr & utfTarget, const MemoryAttr & utfSrc) { //NB: The system utf8 functions typically take a length, whilst MemoryAttr provide a size. unsigned lenTarget; char * target; const char * source = static_cast<const char *>(utfSrc.get()); unsigned lenSource = rtlUtf8Length(utfSrc.length(), source); transform(lenTarget, target, lenSource, source); unsigned sizeTarget = rtlUtf8Size(lenTarget, target); utfTarget.setOwn(sizeTarget, target); }
void ViewFieldECLTransformer::transform(unsigned & lenTarget, char * & target, unsigned lenSource, const char * source, const HqlExprArray & extraArgs) { Owned<ITypeInfo> sourceType = makeUtf8Type(lenSource, 0); IValue * sourceValue = createUtf8Value(source, LINK(sourceType)); OwnedHqlExpr sourceExpr = createConstant(sourceValue); HqlExprArray actuals; actuals.append(*LINK(sourceExpr)); appendArray(actuals, extraArgs); Owned<IErrorReceiver> errorReporter = createThrowingErrorReceiver(); OwnedHqlExpr call = createBoundFunction(errorReporter, function, actuals, NULL, true); OwnedHqlExpr castValue = ensureExprType(call, utf8Type); OwnedHqlExpr folded = quickFoldExpression(castValue, NULL, 0); IValue * foldedValue = folded->queryValue(); assertex(foldedValue); unsigned len = foldedValue->queryType()->getStringLen(); const char * data = static_cast<const char *>(foldedValue->queryValue()); unsigned size = rtlUtf8Size(len, data); lenTarget = len; target = (char *)rtlMalloc(size); memcpy(target, data, size); }
virtual void compileEmbeddedScript(size32_t chars, const char *script) { size32_t len = rtlUtf8Size(chars, script); int rc = sqlite3_prepare_v2(db, script, len, stmt.ref(), NULL); checkSqliteError(rc); }
virtual void bindUTF8Param(const char *name, size32_t chars, const char *val) { size32_t sizeBytes = rtlUtf8Size(chars, val); checkSqliteError(sqlite3_bind_text(stmt, findParameter(name), val, sizeBytes, SQLITE_TRANSIENT)); // NOTE - requires size in bytes not chars }
size32_t DataSourceMetaData::getRecordSize(const void *rec) { if (isStoredFixedWidth) return storedFixedSize; if (!rec) return maxRecordSize; const byte * data = (const byte *)rec; unsigned curOffset = 0; unsigned bitsRemaining = 0; unsigned max = fields.ordinality() - numVirtualFields; for (unsigned idx=0; idx < max; idx++) { ITypeInfo & type = *fields.item(idx).type; unsigned size = type.getSize(); if (size == UNKNOWN_LENGTH) { const byte * cur = data + curOffset; switch (type.getTypeCode()) { case type_data: case type_string: case type_table: case type_groupedtable: size = *((unsigned *)cur) + sizeof(unsigned); break; case type_set: size = *((unsigned *)(cur + sizeof(bool))) + sizeof(unsigned) + sizeof(bool); break; case type_qstring: size = rtlQStrSize(*((unsigned *)cur)) + sizeof(unsigned); break; case type_unicode: size = *((unsigned *)cur)*2 + sizeof(unsigned); break; case type_utf8: size = sizeof(unsigned) + rtlUtf8Size(*(unsigned *)cur, cur+sizeof(unsigned)); break; case type_varstring: size = strlen((char *)cur)+1; break; case type_varunicode: size = (rtlUnicodeStrlen((UChar *)cur)+1)*2; break; case type_packedint: size = rtlGetPackedSize(cur); break; default: UNIMPLEMENTED; } } if (type.getTypeCode() == type_bitfield) { unsigned thisBits = type.getBitSize(); if (thisBits > bitsRemaining) { size = type.queryChildType()->getSize(); bitsRemaining = size * 8; } else size = 0; bitsRemaining -= thisBits; } else bitsRemaining = 0; curOffset += size; } return curOffset; }
void CSVOutputStream::writeUtf8(size32_t len, const char * data) { append(prefix); if (oldOutputFormat) { append(quote).append(rtlUtf8Size(len, data), data).append(quote); } else if (len) { // is this OTT? // not sure if best way but generate an array of utf8 sizes MemoryAttr ma; size32_t * cl; if (len>256) cl = (size32_t *)ma.allocate(sizeof(size32_t)*len); else cl = (size32_t *)alloca(sizeof(size32_t)*len); unsigned start=(unsigned)-1; unsigned end=0; const byte * s = (const byte *)data; unsigned i; for (i=0;i<len;i++) { const byte *p=s; UChar next = readUtf8Character(sizeof(UChar), s); cl[i] = (size32_t)(s-p); if (!u_isspace(next)) { end = i; if (start==(unsigned)-1) start = i; } } const byte *e=s; // do trim if (start!=(unsigned)-1) { for (i=0;i<start;i++) data += *(cl++); len -= start; end -= start; end++; while (end<len) e -= cl[--len]; } // now see if need quoting by looking for separator, terminator or quote // I *think* this can be done with memcmps as has to be exact size32_t sl = separator.length(); size32_t tl = terminator.length(); size32_t ql = quote.length(); bool needquote=false; s = (const byte *)data; for (i=0;i<len;i++) { size32_t l = (size32_t)(e-s); if (sl&&(l>=sl)&&(memcmp(separator.get(),s,sl)==0)) { needquote = true; break; } if (tl&&(l>=tl)&&(memcmp(terminator.get(),s,tl)==0)) { needquote = true; break; } if ((l>=ql)&&(memcmp(quote.get(),s,ql)==0)) { needquote = true; break; } s+=cl[i]; } if (needquote) { append(quote); s = (const byte *)data; for (i=0;i<len;i++) { size32_t l = (size32_t)(e-s); if ((l>=ql)&&(memcmp(quote.get(),s,ql)==0)) append(quote); append(cl[i],(const char *)s); s+=cl[i]; } append(quote); } else append((size32_t)(e-(const byte *)data),data); } prefix = separator; }