Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution insertion and reading of the type fields multidimensional array (Error insertion of the array type fields solved) [DNET331] #342

Open
firebird-automations opened this issue Jul 14, 2010 · 0 comments

Comments

@firebird-automations
Copy link

Submitted by: luis olascoaga (olasur)

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 ...

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants