// Warning: return's Length is not valid data length, but preallocation buffer. public override byte[] GetValue(byte[] key, out int valuelength) { object ovalue; if (UseStringKeys) { ovalue = table[Encoding.ASCII.GetString(key)]; } else { ovalue = table[key]; } if (null == ovalue) { valuelength = -1; return(null); } if (AppendBufferingEnabled) { AppendBuffer abvalue = (AppendBuffer)ovalue; return(abvalue.Get(out valuelength)); } else { byte[] value = (byte[])ovalue; valuelength = value.Length; return(value); } }
protected override void ProcessCommand(NetworkStream nstm, char tag) { //string s; int len; switch (tag) { case 'N': // Next in enumeration.. { int ienumid = nstm.ReadByte(); if (ienumid >= 0) { byte enumid = (byte)ienumid; if (enumid >= this.enums.Length) { nstm.WriteByte((byte)'-'); } else { if (null == this.enums[enumid]) { this.enums[enumid] = table.GetEnumerator(); } if (this.enums[enumid].MoveNext()) { nstm.WriteByte((byte)'+'); System.Collections.DictionaryEntry de = this.enums[enumid].Entry; XContent.SendXContent(nstm, (byte[])de.Key); if (AppendBufferingEnabled) { AppendBuffer abvalue = (AppendBuffer)de.Value; byte[] result = abvalue.Get(out len); XContent.SendXContent(nstm, result, len); } else { XContent.SendXContent(nstm, (byte[])de.Value); } } else { nstm.WriteByte((byte)'-'); } } } } break; case 'n': // Reset next in enumeration.. { int ienumid = nstm.ReadByte(); if (ienumid >= 0) { byte enumid = (byte)ienumid; if (XLog.logging) { XLog.log("Starting enumeration (enumid:" + enumid.ToString() + ")"); } if (enumid < this.enums.Length && null != this.enums[enumid]) { //this.enums[enumid].Reset(); this.enums[enumid] = null; } } } break; case 'b': // Enable AppendBuffer XContent.ReceiveXBytes(nstm, out len, buf); appendbuffersize = BytesToInt(buf); if (appendbuffersize < 0 || appendbuffersize >= 16777216) { throw new Exception("Invalid AppendBuffer preallocation size (appendbuffersize): " + appendbuffersize.ToString()); } if (XLog.logging) { XLog.log("Enabled AppendBuffer with initial value sizes of " + appendbuffersize.ToString()); } break; case 'L': // Set length.. { // Key.. byte[] putkey = XContent.ReceiveXBytes(nstm, out len, buf); putkey = GetSliceCopy(putkey, len); // ! // New length.. byte[] putlength = XContent.ReceiveXBytes(nstm, out len, buf); int newlength = BytesToInt(putlength); if (AppendBufferingEnabled) { object ovalue; if (UseStringKeys) { ovalue = table[Encoding.ASCII.GetString(putkey)]; } else { ovalue = table[putkey]; } if (null == ovalue) { int setbufsize = newlength; if (setbufsize < appendbuffersize) { setbufsize = appendbuffersize; // ? } if (UseStringKeys) { table[Encoding.ASCII.GetString(putkey)] = new AppendBuffer(setbufsize); } else { table[putkey] = new AppendBuffer(setbufsize); } } else { AppendBuffer abvalue = (AppendBuffer)ovalue; abvalue.SetLength(newlength); } } else { byte[] oldvalue = GetValue(putkey, out len); if (newlength < len) { CopyAndSetValue(putkey, oldvalue, newlength); } } } break; case 'G': // Get.. { //Thread.Sleep(15000); buf = XContent.ReceiveXBytes(nstm, out len, buf); byte[] getkey = GetSliceCopy(buf, len); byte[] result = GetValue(getkey, out len); if (null == result) { nstm.WriteByte((byte)'-'); // Key doesn't exist! } else { nstm.WriteByte((byte)'+'); // It exists! XContent.SendXContent(nstm, result, len); } } break; case 'l': // Get length.. { byte[] getkey = XContent.ReceiveXBytes(nstm, out len, buf); getkey = GetSliceCopy(getkey, len); byte[] value = GetValue(getkey, out len); if (null == value) { nstm.WriteByte((byte)'-'); // Key doesn't exist! } else { nstm.WriteByte((byte)'+'); // It exists! XContent.SendXContent(nstm, ToBytes(len)); } } break; case 'P': // Put.. { // Key.. buf = XContent.ReceiveXBytes(nstm, out len, buf); byte[] putkey = GetSliceCopy(buf, len); // Value.. buf = XContent.ReceiveXBytes(nstm, out len, buf); CopyAndSetValue(putkey, buf, len); } break; case 'a': // Math add.. { // Key.. buf = XContent.ReceiveXBytes(nstm, out len, buf); byte[] putkey = GetSliceCopy(buf, len); // ! // Operand.. buf = XContent.ReceiveXBytes(nstm, out len, buf); if (buf.Length >= 4) { int operand = BytesToInt(buf); // Do add... byte[] val = GetValue(putkey, out len); if (null == val || val.Length < 4) // Key doesn't exist, or too small, so assume it was 0. { ToBytes(operand, buf, 0); CopyAndSetValue(putkey, buf, 4); } else { int existingint = BytesToInt(val); int result = existingint + operand; //XLog.log("blarg", "adding " + existingint.ToString() + " and " + operand.ToString() + ", got result " + result.ToString()); ToBytes(result, buf, 0); CopyAndSetValue(putkey, buf, 4); } } } break; case 'A': // Append.. { // Key.. buf = XContent.ReceiveXBytes(nstm, out len, buf); byte[] putkey = GetSliceCopy(buf, len); // Value.. buf = XContent.ReceiveXBytes(nstm, out len, buf); AppendValue(putkey, buf, len); } break; default: base.ProcessCommand(nstm, tag); break; } }