in SqliteVisualizer/SqliteVisualizer/SqliteFuncEvalQuery.cs [344:447]
private bool TryGetRow(out string[] row)
{
// Move to the next row
bool moreRows = false;
var exprs = new List<DkmLanguageExpression>();
try
{
const int SQLITE_ROW = 100;
SqliteVisualizerException ex = null;
DkmWorkList workList = DkmWorkList.Create(null);
DkmLanguageExpression expr = this.AddFuncEval(
workList,
$"sqlite3_step(*(sqlite3_stmt **){this.procMemForQuery})",
(r) =>
{
DkmSuccessEvaluationResult suc;
if (!this.VerifySuccess(r, out suc))
{
ex = new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
return;
}
moreRows = SQLITE_ROW == (int)suc.Address.Value;
});
exprs.Add(expr);
workList.Execute();
if (ex != null)
{
throw ex;
}
}
finally
{
foreach (var e in exprs)
{
e.Close();
}
exprs.Clear();
}
if (!moreRows)
{
row = new string[0];
return false;
}
// Read each column in the row
var rowLocal = new string[ColumnNames.Count()];
try
{
SqliteVisualizerException ex = null;
DkmProcess process = this.inspectionContext.Thread.Process;
DkmWorkList workList = DkmWorkList.Create(null);
for (int i = 0; i < rowLocal.Length; i++)
{
var i_local = i;
var e = this.AddFuncEval(
workList,
$"sqlite3_column_text(*(sqlite3_stmt **){this.procMemForQuery}, {i})",
(r) =>
{
DkmSuccessEvaluationResult suc;
if (!this.VerifySuccess(r, out suc))
{
ex = ex ?? new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
return;
}
ulong address = suc.Address.Value;
byte[] stringMaybe = process.ReadMemoryString(address, DkmReadMemoryFlags.None, 1, 1024);
int len = stringMaybe.Length;
if (len > 0)
{
// The debugger null terminates all strings, but encoding doesn't strip null when creating a string
len--;
rowLocal[i_local] = Encoding.UTF8.GetString(stringMaybe, 0, len);
}
});
exprs.Add(e);
}
workList.Execute();
if (ex != null)
{
throw ex;
}
}
finally
{
foreach (var e in exprs)
{
e.Close();
}
}
row = rowLocal;
return true;
}