private void InitializeBytes() { if (_bytes != null) { return; } uint fetched = 0; _bytes = new byte[0]; IDebugMemoryContext2 memAddr; if (GetMemoryContext(out memAddr) != VSConstants.S_OK) { // no address in the expression value, try casting to a char* VariableInformation v = new VariableInformation("(char*)(" + _variableInformation.FullName() + ")", (VariableInformation)_variableInformation); v.SyncEval(); if (v.Error) { return; } AD7Property p = new AD7Property(_engine, v); uint pLen; if (p.GetStringCharLength(out pLen) == VSConstants.S_OK) { _bytes = new byte[pLen]; p.GetStringRawBytes(pLen, _bytes, out fetched); } return; } IDebugMemoryBytes2 memContent; if (((AD7MemoryAddress)memAddr).Engine.GetMemoryBytes(out memContent) != VSConstants.S_OK) { return; } fetched = 0; bool eos = false; byte[] bytes = new byte[s_maxChars + 1]; byte[] chunk = new byte[2048]; while (!eos) { // fetched is count of bytes in string so far // eos == false => fetch < s_maxChars // eos == true => string is terminated, that is bytes[fetched-1] == 0 uint bytesRead; uint bytesUnreadable = 0; // get next chunk if (memContent.ReadAt(memAddr, (uint)chunk.Length, chunk, out bytesRead, ref bytesUnreadable) != VSConstants.S_OK) { break; } // copy chunk to bytes for (uint i = 0; i < bytesRead; ++i) { bytes[fetched++] = chunk[i]; if (bytes[fetched - 1] == 0) { eos = true; // end of string break; } if (fetched == s_maxChars) // buffer is full { bytes[fetched++] = 0; // end the string eos = true; break; } } if (bytesRead != chunk.Length) { // read to end of available memory break; } // advance to next chunk memAddr.Add(bytesRead, out memAddr); } if (!eos) { Debug.Assert(fetched < bytes.Length); bytes[fetched++] = 0; } if (fetched < bytes.Length) { _bytes = new byte[fetched]; Array.Copy(bytes, _bytes, (int)fetched); } else { _bytes = bytes; } }