File: ArrayDescMarshaler.cs

package info (click to toggle)
mono 1.2.2.1-1etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 142,720 kB
  • ctags: 256,408
  • sloc: cs: 1,495,736; ansic: 249,442; sh: 18,327; xml: 12,463; makefile: 5,046; perl: 1,248; asm: 635; yacc: 285; sql: 7
file content (120 lines) | stat: -rw-r--r-- 3,103 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 *	Firebird ADO.NET Data provider for .NET and Mono 
 * 
 *	   The contents of this file are subject to the Initial 
 *	   Developer's Public License Version 1.0 (the "License"); 
 *	   you may not use this file except in compliance with the 
 *	   License. You may obtain a copy of the License at 
 *	   http://www.firebirdsql.org/index.php?op=doc&id=idpl
 *
 *	   Software distributed under the License is distributed on 
 *	   an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
 *	   express or implied. See the License for the specific 
 *	   language governing rights and limitations under the License.
 * 
 *	Copyright (c) 2002, 2005 Carlos Guzman Alvarez
 *	All Rights Reserved.
 */

using System;
using System.Runtime.InteropServices;

using FirebirdSql.Data.Common;

namespace FirebirdSql.Data.Embedded
{
	internal class ArrayDescMarshaler
	{
		#region Static Fields

		private static ArrayDescMarshaler instance;

		#endregion

		#region Constructors

		private ArrayDescMarshaler()
		{
		}

		#endregion

		#region Methods

		public static ArrayDescMarshaler GetInstance()
		{
			if (ArrayDescMarshaler.instance == null)
			{
				ArrayDescMarshaler.instance = new ArrayDescMarshaler();
			}

			return ArrayDescMarshaler.instance;
		}

		public void CleanUpNativeData(ref IntPtr pNativeData)
		{
			if (pNativeData != IntPtr.Zero)
			{
				// Destroy ArrayDescMarshal	structure
				Marshal.DestroyStructure(pNativeData, typeof(ArrayDescMarshal));

				// Destroy ArrayBound structures
				for (int i = 0; i < 16; i++)
				{
					Marshal.DestroyStructure(
						(IntPtr)(pNativeData.ToInt32() + ArrayDescMarshal.ComputeLength(i)),
						typeof(ArrayBoundMarshal));
				}

				// Free	pointer	memory
				Marshal.FreeHGlobal(pNativeData);

				pNativeData = IntPtr.Zero;
			}
		}

		public IntPtr MarshalManagedToNative(ArrayDesc descriptor)
		{
			ArrayDescMarshal arrayDesc = new ArrayDescMarshal();

			arrayDesc.DataType		= descriptor.DataType;
			arrayDesc.Scale			= (byte)descriptor.Scale;
			arrayDesc.Length		= descriptor.Length;
			arrayDesc.FieldName		= descriptor.FieldName;
			arrayDesc.RelationName	= descriptor.RelationName;
			arrayDesc.Dimensions	= descriptor.Dimensions;
			arrayDesc.Flags			= descriptor.Flags;

			ArrayBoundMarshal[] arrayBounds = new ArrayBoundMarshal[descriptor.Bounds.Length];

			for (int i = 0; i < descriptor.Dimensions; i++)
			{
				arrayBounds[i].LowerBound = (short)descriptor.Bounds[i].LowerBound;
				arrayBounds[i].UpperBound = (short)descriptor.Bounds[i].UpperBound;
			}

			return this.MarshalManagedToNative(arrayDesc, arrayBounds);
		}

		public IntPtr MarshalManagedToNative(
			ArrayDescMarshal arrayDesc,
			ArrayBoundMarshal[] arrayBounds)
		{
			int		size = ArrayDescMarshal.ComputeLength(arrayBounds.Length);
			IntPtr	ptr	 = Marshal.AllocHGlobal(size);

			Marshal.StructureToPtr(arrayDesc, ptr, true);
			for (int i = 0; i < arrayBounds.Length; i++)
			{
				Marshal.StructureToPtr(
					arrayBounds[i],
					(IntPtr)(ptr.ToInt32() + ArrayDescMarshal.ComputeLength(i)),
					true);
			}

			return ptr;
		}

		#endregion
	}
}