wxString pgForeignKey::GetDefinition() { wxString sql; sql = wxT("(") + GetQuotedFkColumns() + wxT(")\n REFERENCES ") + GetQuotedSchemaPrefix(GetRefSchema()) + qtIdent(GetReferences()) + wxT(" (") + GetQuotedRefColumns() + wxT(")"); if (GetDatabase()->BackendMinimumVersion(7, 4) || GetMatch() == wxT("FULL")) sql += wxT(" MATCH ") + GetMatch(); sql += wxT("\n ON UPDATE ") + GetOnUpdate() + wxT(" ON DELETE ") + GetOnDelete(); if (GetDeferrable()) { sql += wxT(" DEFERRABLE INITIALLY "); if (GetDeferred()) sql += wxT("DEFERRED"); else sql += wxT("IMMEDIATE"); } if (GetDatabase()->BackendMinimumVersion(9, 1) && !GetValid()) sql += wxT("\n NOT VALID"); return sql; }
wxString wxRegEx::GetMatch(const wxString& text, size_t index) const { size_t start, len; if ( !GetMatch(&start, &len, index) ) return wxEmptyString; return text.Mid(start, len); }
int wxRegExImpl::Replace(wxString *text, const wxString& replacement, size_t maxMatches) const { wxCHECK_MSG( text, wxNOT_FOUND, wxT("NULL text in wxRegEx::Replace") ); wxCHECK_MSG( IsValid(), wxNOT_FOUND, wxT("must successfully Compile() first") ); // the input string #ifndef WXREGEX_CONVERT_TO_MB const wxChar *textstr = text->c_str(); size_t textlen = text->length(); #else const wxWX2MBbuf textstr = WXREGEX_CHAR(*text); if (!textstr) { wxLogError(_("Failed to find match for regular expression: %s"), GetErrorMsg(0, true).c_str()); return 0; } size_t textlen = strlen(textstr); text->clear(); #endif // the replacement text wxString textNew; // the result, allow 25% extra wxString result; result.reserve(5 * textlen / 4); // attempt at optimization: don't iterate over the string if it doesn't // contain back references at all bool mayHaveBackrefs = replacement.find_first_of(wxT("\\&")) != wxString::npos; if ( !mayHaveBackrefs ) { textNew = replacement; } // the position where we start looking for the match size_t matchStart = 0; // number of replacement made: we won't make more than maxMatches of them // (unless maxMatches is 0 which doesn't limit the number of replacements) size_t countRepl = 0; // note that "^" shouldn't match after the first call to Matches() so we // use wxRE_NOTBOL to prevent it from happening while ( (!maxMatches || countRepl < maxMatches) && Matches( #ifndef WXREGEX_CONVERT_TO_MB textstr + matchStart, #else textstr.data() + matchStart, #endif countRepl ? wxRE_NOTBOL : 0 WXREGEX_IF_NEED_LEN(textlen - matchStart)) ) { // the string possibly contains back references: we need to calculate // the replacement text anew after each match if ( mayHaveBackrefs ) { mayHaveBackrefs = false; textNew.clear(); textNew.reserve(replacement.length()); for ( const wxChar *p = replacement.c_str(); *p; p++ ) { size_t index = (size_t)-1; if ( *p == wxT('\\') ) { if ( wxIsdigit(*++p) ) { // back reference wxChar *end; index = (size_t)wxStrtoul(p, &end, 10); p = end - 1; // -1 to compensate for p++ in the loop } //else: backslash used as escape character } else if ( *p == wxT('&') ) { // treat this as "\0" for compatbility with ed and such index = 0; } // do we have a back reference? if ( index != (size_t)-1 ) { // yes, get its text size_t start, len; if ( !GetMatch(&start, &len, index) ) { wxFAIL_MSG( wxT("invalid back reference") ); // just eat it... } else { textNew += wxString( #ifndef WXREGEX_CONVERT_TO_MB textstr #else textstr.data() #endif + matchStart + start, *wxConvCurrent, len); mayHaveBackrefs = true; } } else // ordinary character { textNew += *p; } } } size_t start, len; if ( !GetMatch(&start, &len) ) { // we did have match as Matches() returned true above! wxFAIL_MSG( wxT("internal logic error in wxRegEx::Replace") ); return wxNOT_FOUND; } // an insurance against implementations that don't grow exponentially // to ensure building the result takes linear time if (result.capacity() < result.length() + start + textNew.length()) result.reserve(2 * result.length()); #ifndef WXREGEX_CONVERT_TO_MB result.append(*text, matchStart, start); #else result.append(wxString(textstr.data() + matchStart, *wxConvCurrent, start)); #endif matchStart += start; result.append(textNew); countRepl++; matchStart += len; } #ifndef WXREGEX_CONVERT_TO_MB result.append(*text, matchStart, wxString::npos); #else result.append(wxString(textstr.data() + matchStart, *wxConvCurrent)); #endif *text = result; return countRepl; }
void CAnchors::GetPaddedResults(CLineVector & baseResult, CLineVector & compResult) const { unsigned int matchCount = GetMatchCount(); unsigned int gapCount = GetGapCount(); unsigned int matchPos = 0; unsigned int gapPos = 0; while(matchPos < matchCount) { { CTable baseTable, compTable; GetMatch(matchPos, baseTable, compTable); for (size_t i = 1; i < baseTable.size() - 1; ++i) { CLine baseLine = baseTable[i]; CLine compLine = compTable[i]; CLine::TYPE type = baseLine.Equals(compLine, 0) ? CLine::TYPE_MATCH : CLine::TYPE_SIMILAR; if (type == CLine::TYPE_SIMILAR) { CTable baseLineTable(baseLine.GetText(), true); CTable compLineTable(compLine.GetText(), true); CAnchors lineAnchors(baseLineTable, compLineTable, 0); CLineVector baseLineVector, compLineVector; lineAnchors.GetResults(baseLineVector, compLineVector); SetCharTypes(baseLine, baseLineVector); SetCharTypes(compLine, compLineVector); } baseLine.SetType(type); compLine.SetType(type); baseResult.push_back(baseLine); compResult.push_back(compLine); } ATLASSERT(baseResult.size() == compResult.size()); ++matchPos; } if (gapPos < gapCount) { CTable baseTable, compTable; GetGap(gapPos, baseTable, compTable); if (baseTable.size() <= 2) //Added lines { ATLASSERT(compTable.size() > 2); AppendBlankLines(baseResult, compTable, CLine::TYPE_ADDED); AppendTable(compResult, compTable, CLine::TYPE_ADDED); } else if (compTable.size() <= 2) //Deleted lines { ATLASSERT(baseTable.size() > 2); AppendTable(baseResult, baseTable, CLine::TYPE_DELETED); AppendBlankLines(compResult, baseTable, CLine::TYPE_DELETED); } else if (m_accuracy > 35) // Don't recurse too much. { AppendTable(baseResult, baseTable, CLine::TYPE_DELETED); AppendBlankLines(compResult, baseTable, CLine::TYPE_DELETED); AppendBlankLines(baseResult, compTable, CLine::TYPE_ADDED); AppendTable(compResult, compTable, CLine::TYPE_ADDED); } else { CAnchors gapAnchors(baseTable, compTable, m_accuracy + 5); gapAnchors.GetPaddedResults(baseResult, compResult); } ATLASSERT(baseResult.size() == compResult.size()); ++gapPos; } } }
void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h, const unsigned char* array, size_t pos, size_t size, size_t limit, unsigned short* sublen, unsigned short* distance, unsigned short* length) { unsigned short hpos = pos & ZOPFLI_WINDOW_MASK, p, pp; unsigned short bestdist = 0; unsigned short bestlength = 1; const unsigned char* scan; const unsigned char* match; const unsigned char* arrayend; const unsigned char* arrayend_safe; #if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE int chain_counter = ZOPFLI_MAX_CHAIN_HITS; /* For quitting early. */ #endif unsigned dist = 0; /* Not unsigned short on purpose. */ int* hhead = h->head; unsigned short* hprev = h->prev; int* hhashval = h->hashval; int hval = h->val; #ifdef ZOPFLI_LONGEST_MATCH_CACHE if (TryGetFromLongestMatchCache(s, pos, &limit, sublen, distance, length)) { assert(pos + *length <= size); return; } #endif assert(limit <= ZOPFLI_MAX_MATCH); assert(limit >= ZOPFLI_MIN_MATCH); assert(pos < size); if (size - pos < ZOPFLI_MIN_MATCH) { /* The rest of the code assumes there are at least ZOPFLI_MIN_MATCH bytes to try. */ *length = 0; *distance = 0; return; } if (pos + limit > size) { limit = size - pos; } arrayend = &array[pos] + limit; arrayend_safe = arrayend - 8; assert(hval < 65536); pp = hhead[hval]; /* During the whole loop, p == hprev[pp]. */ p = hprev[pp]; assert(pp == hpos); dist = p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp); /* Go through all distances. */ while (dist < ZOPFLI_WINDOW_SIZE) { unsigned short currentlength = 0; assert(p < ZOPFLI_WINDOW_SIZE); assert(p == hprev[pp]); assert(hhashval[p] == hval); if (dist > 0) { assert(pos < size); assert(dist <= pos); scan = &array[pos]; match = &array[pos - dist]; /* Testing the byte at position bestlength first, goes slightly faster. */ if (pos + bestlength >= size || *(scan + bestlength) == *(match + bestlength)) { #ifdef ZOPFLI_HASH_SAME unsigned short same0 = h->same[pos & ZOPFLI_WINDOW_MASK]; if (same0 > 2 && *scan == *match) { unsigned short same1 = h->same[(pos - dist) & ZOPFLI_WINDOW_MASK]; unsigned short same = same0 < same1 ? same0 : same1; if (same > limit) same = limit; scan += same; match += same; } #endif scan = GetMatch(scan, match, arrayend, arrayend_safe); currentlength = scan - &array[pos]; /* The found length. */ } if (currentlength > bestlength) { if (sublen) { unsigned short j; for (j = bestlength + 1; j <= currentlength; j++) { sublen[j] = dist; } } bestdist = dist; bestlength = currentlength; if (currentlength >= limit) break; } } #ifdef ZOPFLI_HASH_SAME_HASH /* Switch to the other hash once this will be more efficient. */ if (hhead != h->head2 && bestlength >= h->same[hpos] && h->val2 == h->hashval2[p]) { /* Now use the hash that encodes the length and first byte. */ hhead = h->head2; hprev = h->prev2; hhashval = h->hashval2; hval = h->val2; } #endif pp = p; p = hprev[p]; if (p == pp) break; /* Uninited prev value. */ dist += p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp); #if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE chain_counter--; if (chain_counter <= 0) break; #endif } #ifdef ZOPFLI_LONGEST_MATCH_CACHE StoreInLongestMatchCache(s, pos, limit, sublen, bestdist, bestlength); #endif assert(bestlength <= limit); *distance = bestdist; *length = bestlength; assert(pos + *length <= size); }
void pgForeignKey::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) { if (!expandedKids) { expandedKids = true; wxStringTokenizer c1l(GetConkey(), wxT(",")); wxStringTokenizer c2l(GetConfkey(), wxT(",")); wxString c1, c2; // resolve column names while (c1l.HasMoreTokens()) { c1 = c1l.GetNextToken(); c2 = c2l.GetNextToken(); pgSet *set = ExecuteSet( wxT("SELECT a1.attname as conattname, a2.attname as confattname\n") wxT(" FROM pg_attribute a1, pg_attribute a2\n") wxT(" WHERE a1.attrelid=") + GetTableOidStr() + wxT(" AND a1.attnum=") + c1 + wxT("\n") wxT(" AND a2.attrelid=") + GetRelTableOidStr() + wxT(" AND a2.attnum=") + c2); if (set) { if (!fkColumns.IsNull()) { fkColumns += wxT(", "); refColumns += wxT(", "); quotedFkColumns += wxT(", "); quotedRefColumns += wxT(", "); } fkColumns += set->GetVal(0); refColumns += set->GetVal(1); quotedFkColumns += qtIdent(set->GetVal(0)); quotedRefColumns += qtIdent(set->GetVal(1)); delete set; } } wxTreeItemId item = browser->GetItemParent(GetId()); while (item) { pgTable *table = (pgTable *)browser->GetObject(item); if (table->IsCreatedBy(tableFactory)) { coveringIndex = table->GetCoveringIndex(browser, fkColumns); break; } item = browser->GetItemParent(item); } } if (properties) { CreateListColumns(properties); properties->AppendItem(_("Name"), GetName()); properties->AppendItem(_("OID"), NumToStr(GetOid())); properties->AppendItem(_("Child columns"), GetFkColumns()); properties->AppendItem(_("References"), GetReferences() + wxT("(") + GetRefColumns() + wxT(")")); properties->AppendItem(_("Covering index"), GetCoveringIndex()); properties->AppendItem(_("Match type"), GetMatch()); properties->AppendItem(_("On update"), GetOnUpdate()); properties->AppendItem(_("On delete"), GetOnDelete()); properties->AppendItem(_("Deferrable?"), BoolToYesNo(GetDeferrable())); if (GetDeferrable()) properties->AppendItem(_("Initially?"), GetDeferred() ? wxT("DEFERRED") : wxT("IMMEDIATE")); if (GetDatabase()->BackendMinimumVersion(9, 1)) properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); properties->AppendItem(_("System foreign key?"), BoolToYesNo(GetSystemObject())); properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); } }