using System;
using System.Globalization;
using System.Xml;
+using System.Text;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Runtime.Serialization;
namespace System.Data.SqlTypes
{
[SerializableAttribute]
- [XmlSchemaProvider ("GetSchema")]
+ [XmlSchemaProvider ("GetXsdType")]
public sealed class SqlChars : INullable, IXmlSerializable, ISerializable
{
#region Fields
public SqlChars (SqlString value)
{
- if (value == null) {
+ if (value.IsNull) {
notNull = false;
buffer = null;
} else {
#region Properties
- public char [] Buffer {
- get { return buffer; }
- }
+ public char [] Buffer {
+ get { return buffer; }
+ }
- public bool IsNull {
- get { return !notNull; }
- }
+ public bool IsNull {
+ get { return !notNull; }
+ }
- public char this [long offset] {
- set {
+ public char this [long offset] {
+ set {
if (notNull && offset >= 0 && offset < buffer.Length)
buffer [offset] = value;
}
- get {
+ get {
if (buffer == null)
throw new SqlNullValueException ("Data is Null");
if (offset < 0 || offset >= buffer.Length)
throw new ArgumentOutOfRangeException ("Parameter name: offset");
return buffer [offset];
}
- }
+ }
- public long Length {
- get {
+ public long Length {
+ get {
if (!notNull || buffer == null)
throw new SqlNullValueException ("Data is Null");
if (buffer.Length < 0)
return -1;
return buffer.Length;
}
- }
+ }
- public long MaxLength {
- get {
+ public long MaxLength {
+ get {
if (!notNull || buffer == null || storage == StorageState.Stream)
return -1;
return buffer.Length;
}
- }
+ }
- public static SqlChars Null {
- get {
+ public static SqlChars Null {
+ get {
return new SqlChars ();
}
- }
+ }
- public StorageState Storage {
- get {
+ public StorageState Storage {
+ get {
if (storage == StorageState.UnmanagedBuffer)
throw new SqlNullValueException ("Data is Null");
return storage;
}
- }
+ }
- public char [] Value {
- get {
+ public char [] Value {
+ get {
if (buffer == null)
return buffer;
return (char []) buffer.Clone ();
}
- }
+ }
#endregion
throw new ArgumentOutOfRangeException ("Specified argument was out of the range of valid values.");
Array.Resize (ref buffer, (int) value);
}
-
+
public void SetNull ()
{
buffer = null;
notNull = false;
}
-
- [MonoTODO]
+
+ public static explicit operator SqlString (SqlChars value)
+ {
+ if (value.IsNull)
+ return SqlString.Null;
+ else {
+ return new SqlString (new String (value.Value));
+ }
+ }
+
+ public static explicit operator SqlChars (SqlString value)
+ {
+ if (value.IsNull)
+ return Null;
+ else
+ return new SqlChars (value.Value);
+ }
+
+ public SqlString ToSqlString ()
+ {
+ if (buffer == null) {
+ return SqlString.Null;
+ } else {
+ return new SqlString (buffer.ToString ());
+ }
+ }
+
public long Read (long offset, char [] buffer, int offsetInBuffer, int count)
{
- throw new NotImplementedException ();
+ if (buffer == null)
+ throw new ArgumentNullException ("buffer");
+
+ if (IsNull)
+ throw new SqlNullValueException ("There is no buffer. Read or write operation failed");
+
+ if (count > MaxLength || count > buffer.Length ||
+ count < 0 || ((offsetInBuffer + count) > buffer.Length))
+ throw new ArgumentOutOfRangeException ("count");
+
+ if (offset < 0 || offset > MaxLength)
+ throw new ArgumentOutOfRangeException ("offset");
+
+ if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length)
+ throw new ArgumentOutOfRangeException ("offsetInBuffer");
+
+ /* LAMESPEC: If count specifies more characters than what is available from
+ offset to the Length of the SqlChars instance, only the available
+ characters are copied
+ */
+
+ /* Final count of what will be copied */
+ long actualCount = count;
+ if (count + offset > Length)
+ actualCount = Length - offset;
+
+ Array.Copy (this.buffer, offset, buffer, offsetInBuffer, actualCount);
+
+ return actualCount;
}
- [MonoTODO]
+ public void Write (long offset, char [] buffer, int offsetInBuffer, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException ("buffer");
+
+ if (IsNull)
+ throw new SqlTypeException ("There is no buffer. Read or write operation failed.");
+
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException ("offset");
+
+ if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length
+ || offsetInBuffer > Length
+ || offsetInBuffer + count > Length
+ || offsetInBuffer + count > buffer.Length)
+ throw new ArgumentOutOfRangeException ("offsetInBuffer");
+
+ if (count < 0 || count > MaxLength)
+ throw new ArgumentOutOfRangeException ("count");
+
+ if (offset > MaxLength || offset+count > MaxLength)
+ throw new SqlTypeException ("The buffer is insufficient. Read or write operation failed.");
+
+ if (count + offset > Length &&
+ count + offset <= MaxLength)
+ SetLength (count);
+
+ Array.Copy (buffer, offsetInBuffer, this.buffer, offset, count);
+ }
+
+ public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
+ {
+ if (schemaSet != null && schemaSet.Count == 0) {
+ XmlSchema xs = new XmlSchema ();
+ XmlSchemaComplexType ct = new XmlSchemaComplexType ();
+ ct.Name = "string";
+ xs.Items.Add (ct);
+ schemaSet.Add (xs);
+ }
+ return new XmlQualifiedName ("string", "http://www.w3.org/2001/XMLSchema");
+ }
+
XmlSchema IXmlSerializable.GetSchema ()
{
- throw new NotImplementedException ();
+ return null;
}
- [MonoTODO]
void IXmlSerializable.ReadXml (XmlReader reader)
{
- throw new NotImplementedException ();
+ if (reader == null)
+ return;
+
+ switch (reader.ReadState) {
+ case ReadState.EndOfFile:
+ case ReadState.Error:
+ case ReadState.Closed:
+ return;
+ }
+ // Skip XML declaration and prolog
+ // or do I need to validate for the <string> tag?
+ reader.MoveToContent ();
+ if (reader.EOF)
+ return;
+
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.EndElement)
+ return;
+
+ if (reader.Value.Length > 0) {
+ if (String.Compare ("Null", reader.Value) == 0) {
+ // means a null reference/invalid value
+ notNull = false;
+ return;
+ }
+ // FIXME: Validate the value for expected format
+ this.buffer = reader.Value.ToCharArray ();
+ this.notNull = true;
+ this.storage = StorageState.Buffer;
+ }
}
- [MonoTODO]
void IXmlSerializable.WriteXml (XmlWriter writer)
{
- throw new NotImplementedException ();
+ writer.WriteString (this.buffer.ToString ());
}
[MonoTODO]
{
throw new NotImplementedException ();
}
-
+
#endregion
}
}