Solution insertion and reading of the type fields multidimensional array (Error 
insertion of the array type fields solved)
--------------------------------------------------------------------------------------------------------------------------

                 Key: DNET-331
                 URL: http://tracker.firebirdsql.org/browse/DNET-331
             Project: .NET Data provider
          Issue Type: Improvement
          Components: ADO.NET Provider
    Affects Versions: 2.5.2, 2.5.1
         Environment: windows and GNU/Linux amd64
            Reporter: luis olascoaga
            Assignee: Jiri Cincura


Regards.
Here I present the solution to store and read array type fields and arrays
different dimensions (including char and varchar), independent of the ranges of 
indices
used by the field. The problem is solved by making the changes described below 
in the archives
Class ArrayBase.cs and GdsArray.cs, to slope the comments in the code:

In the method protected int GetSliceLength(bool read) ArrayBase.cs file should 
look like this:


protected int GetSliceLength(bool read) {

 int length = 0;

 int elements = 1;//Start at 1 and not 0

 for (int i = 0; i < this.descriptor.Dimensions; i++){
   ArrayBound bound = this.descriptor.Bounds[i];

  //Increase by multiplication, not addition

  elements*=(bound.UpperBound-bound.LowerBound+1);

 }



 length = elements * this.descriptor.Length;

 switch (this.descriptor.DataType){

  case IscCodes.blr_varying:

  case IscCodes.blr_varying2:

        length += elements * 2;

        break;

  }

  return length;

}


En el archivo GdsArray.cs:

Para el metodo protected override System.Array DecodeSlice(byte[] slice)

//Add this method to explore the structure vector indices

private void NextIndex(int []Low,int []Len,int []Indexs){

 int r,d,i=Len.Length-1;

 do{

  Indexs[i] = Indexs[i] - Low[i] + 1;

  r = Indexs[i] % Len[i];

  d = Indexs[i] / Len[i]; 

  Indexs[i] = r + Low[i];

  i--;  

 }while(i>=0 && r==0 && d==1);  

}

                

protected override System.Array DecodeSlice(byte[] slice){

 DbDataType     dbType          = DbDataType.Array;

 Array          sliceData       = null;

 //TemData is no longer necessary

 //Array                tempData        = null;

 Type           systemType      = this.GetSystemType();

 int[]          lengths         = new int[this.Descriptor.Dimensions];

 int[]          lowerBounds = new int[this.Descriptor.Dimensions];

 int[]       posindexs   = new int[this.Descriptor.Dimensions];//Indices for 
array of n dimensions

 int                    type            = 0;

 int                    index           = 0;



 // Get upper and lower bounds of each dimension

 for (int i = 0; i < this.Descriptor.Dimensions; i++){

  lowerBounds[i]        = this.Descriptor.Bounds[i].LowerBound;

  posindexs[i]    = lowerBounds[i];//Indices begin at the lowest values

  //The number of elements of dimension i is computed as follows:

  lengths[i]            = this.Descriptor.Bounds[i].UpperBound - lowerBounds[i] 
+ 1;

  /* 

   This is no longer necessary conditional   

   if (lowerBounds[i] == 0){
    lengths[i]++;

  }

 */
}



// Create arrays

#if     (NET_CF)

 /*

   For this case should be posindexs = lowerBounds= {0,0,0,..0},

   could be as?:
   lowerBounds = new int[this.Descriptor.Dimensions];

   posindexs   = new int[this.Descriptor.Dimensions];
*/

 sliceData = Array.CreateInstance(systemType, lengths);

#else

 sliceData = Array.CreateInstance(systemType, lengths, lowerBounds);

#endif

            

 //A decrease in the last index smaller

 posindexs[posindexs.Length-1]--;



 // Infer Firebird and Db datatypes

 type   = TypeHelper.GetFbType(this.Descriptor.DataType);

 dbType = TypeHelper.GetDbDataType(this.Descriptor.DataType, 0, 
this.Descriptor.Scale);

 // Decode slice        data

 XdrStream xdr = new XdrStream(slice, this.database.Charset);

 while (xdr.Position < xdr.Length){   

  //Search the following indices in the vector structure

  NextIndex(lowerBounds,lengths,posindexs);

  switch (dbType){

   /*

    In each case the switch is changed tempData.SetValue(xdr.?(),index)

    and sliceData.SetValue(xdr.?(), posindexs);

  */ 

  case DbDataType.Char:

   sliceData.SetValue(xdr.ReadString(this.Descriptor.Length), posindexs);

   break;



  case DbDataType.VarChar:

   sliceData.SetValue(xdr.ReadString(), posindexs);

   break;

  case DbDataType.SmallInt:

   sliceData.SetValue(xdr.ReadInt16(), posindexs);

   break;

  case DbDataType.Integer:

   sliceData.SetValue(xdr.ReadInt32(), posindexs);

   break;

  case DbDataType.BigInt:

   sliceData.SetValue(xdr.ReadInt64(), posindexs);

   break;

  case DbDataType.Numeric:

  case DbDataType.Decimal:

   sliceData.SetValue(xdr.ReadDecimal(type, this.Descriptor.Scale), posindexs);

   break;

  case DbDataType.Float:

   sliceData.SetValue(xdr.ReadSingle(), posindexs);

   break;

  case DbDataType.Double:

   sliceData.SetValue(xdr.ReadDouble(), posindexs);

   break;

  case DbDataType.Date:

   sliceData.SetValue(xdr.ReadDate(), posindexs);

   break;

 case DbDataType.Time:

  sliceData.SetValue(xdr.ReadTime(), posindexs);

  break;

 case DbDataType.TimeStamp:

  sliceData.SetValue(xdr.ReadDateTime(), posindexs);

  break;

 }

 index++;

}


/*

 This is no longer necessary conditional


 if (systemType.IsPrimitive) {

  // For primitive types we can use System.Buffer       to copy generated data 
to destination array

  Buffer.BlockCopy(tempData, 0, sliceData, 0, Buffer.ByteLength(tempData));

 }

 else {

  sliceData = tempData;

 }

*/


 // Close XDR stream

 xdr.Close();

 return sliceData;

}

Finally in the method private byte[] ReceiveSliceResponse(ArrayDesc desc)


private byte[] ReceiveSliceResponse(ArrayDesc desc){

 try{

  int operation = this.database.ReadOperation();

  if (operation == IscCodes.op_slice){

   // Read      slice length

   bool isVariying = false;

   int          elements = 0;

   int          length = this.database.ReadInt32();

   length = this.database.ReadInt32();

   switch (desc.DataType){

    case IscCodes.blr_text:

    case IscCodes.blr_text2:

    case IscCodes.blr_cstring:

    case IscCodes.blr_cstring2:

     elements = length / desc.Length;

     length += elements * ((4 - desc.Length) & 3);

     break;

   case IscCodes.blr_varying:

   case IscCodes.blr_varying2:

    /*

      The operation elements = length/desc.Length must be elements = 
length/(desc.Length+2) 
      be the inverse of the following case GetSliceLength method of the class 
ArrayBase:
          
       length = elements * this.descriptor.Length;

       switch (this.descriptor.DataType){

        case IscCodes.blr_varying: 

        case IscCodes.blr_varying2:

                                  length += elements * 2;

                                  break;

       }

   */

    elements = length/(desc.Length+2);

    isVariying = true;

    break;

  case IscCodes.blr_short: 

... the rest is equal ...

}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://tracker.firebirdsql.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Firebird-net-provider mailing list
Firebird-net-provider@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider

Reply via email to