private (object Value, string Error) ReadResponse() { var line = m_pClient.ReadLine(); switch (line[0]) { case '*': // multi-bulk reply int count = int.Parse(line.Substring(1)); if (count <= 0) { return(null, null); } var list = new object[count]; for (int i = 0; i < count; i++) { var record = ReadResponse(); if (record.Error != null) { return(null, record.Error); } list[i] = record.Value; } return(list, null); case '$': // bulk reply int size = int.Parse(line.Substring(1)); if (size <= 0) { if (size == 0) { return(new byte[0], null); } return(null, null); } var buffer = new byte[size]; using (var toStream = new MemoryStream()) { FixedCountReader.Read(m_pClient.TcpStream, toStream, size); buffer = toStream.ToArray(); } m_pClient.ReadLine(); // remove end crlf. return(buffer, null); case '+': // status reply return(line.Substring(1), null); case ':': // integer reply return(int.Parse(line.Substring(1)), null); case '-': // error reply return(null, line.Split(' ', 2)[1]); default: // unknown reply return(null, $"unknown response: {line}"); } }
private MemcachedCacheItem[] ExecGetCommand(string cmd, string[] keys) { ThrowIfObjectDisposed(); ThrowIfNotConnected(); try { m_pClient.WriteLine($"{cmd} {string.Join(" ", keys)}"); var list = new List <MemcachedCacheItem>(); while (true) { string line = m_pClient.ReadLine(); if (line == string.Empty) { line = m_pClient.ReadLine(); } if (line.Equals(END, StringComparison.InvariantCultureIgnoreCase)) { break; } if (line.Equals(ERROR, StringComparison.InvariantCultureIgnoreCase)) // not happended yet. { throw new Exception($"Error."); } if (line.StartsWith(CLIENT_ERROR, StringComparison.InvariantCultureIgnoreCase)) { throw new Exception($"Client error: {line.Split(' ', 2)[1]}"); } if (line.StartsWith(SERVER_ERROR, StringComparison.InvariantCultureIgnoreCase)) { throw new Exception($"Server error: {line.Split(' ', 2)[1]}"); } if (!line.StartsWith(VALUE, StringComparison.InvariantCultureIgnoreCase)) { throw new NotSupportedException($"Unsupported response: {line}"); } var items = line.Split(' ', 5, StringSplitOptions.RemoveEmptyEntries); var kvItem = new MemcachedCacheItem(); kvItem.Key = items[1]; kvItem.Flags = int.Parse(items[2]); kvItem.Length = int.Parse(items[3]); kvItem.Revision = items.Length > 4 ? int.Parse(items[4]) : 0; using (var toStream = new MemoryStream()) { FixedCountReader.Read(m_pClient.TcpStream, toStream, kvItem.Length); kvItem.ValueBytes = toStream.ToArray(); } m_pClient.ReadLine(); // remove end crlf. list.Add(kvItem); } return(list.ToArray()); } catch (SocketException ex) { m_pClient.Dispose(); throw ex; } catch (IOException ex) { m_pClient.Dispose(); throw ex; } }