File: PsychCellGlue.c

package info (click to toggle)
psychtoolbox-3 3.0.14.20170103%2Bgit6-g605ff5c.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 103,044 kB
  • ctags: 69,483
  • sloc: ansic: 167,371; cpp: 11,232; objc: 4,708; sh: 1,875; python: 383; php: 344; makefile: 207; java: 113
file content (218 lines) | stat: -rw-r--r-- 7,619 bytes parent folder | download | duplicates (3)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
  PsychToolbox2/Source/Common/PsychCellGlue.c		
  
  Allen.Ingling@nyu.edu				awi
  mario.kleiner@tuebingen.mpg.de	mk
  
  PLATFORMS: All
  
  PROJECTS: All
  
  HISTORY:
    11/17/03  awi		wrote it.  
    03/28/11   mk		Make 64-bit clean.

*/

#include "Psych.h"


/* 
    PsychAllocInCellVector() 


*/
psych_bool PsychAllocInNativeCellVector(int position, PsychArgRequirementType isRequired, const PsychGenericScriptType **cellVector)
{
	PsychError matchError;
	psych_bool acceptArg;

    PsychSetReceivedArgDescriptor(position, FALSE, PsychArgIn);
    PsychSetSpecifiedArgDescriptor(position, PsychArgIn, PsychArgType_cellArray, isRequired, 1, kPsychUnboundedArraySize,1, kPsychUnboundedArraySize,0, 1);
	matchError=PsychMatchDescriptors();
	acceptArg=PsychAcceptInputArgumentDecider(isRequired, matchError);
	if(acceptArg)
		*cellVector= PsychGetInArgMxPtr(position);
	return(acceptArg);
}


/*
    PsychAllocInNativeString()

    
*/
psych_bool PsychAllocInNativeString(int position, PsychArgRequirementType isRequired, const PsychGenericScriptType **nativeString)
{
	PsychError matchError;
	psych_bool acceptArg;
    
    PsychSetReceivedArgDescriptor(position, FALSE, PsychArgIn);
    PsychSetSpecifiedArgDescriptor(position, PsychArgIn, PsychArgType_char, isRequired, 1, kPsychUnboundedArraySize,1, kPsychUnboundedArraySize,0, 1);
 	matchError=PsychMatchDescriptors();
	acceptArg=PsychAcceptInputArgumentDecider(isRequired, matchError);
	if(acceptArg)
            *nativeString= PsychGetInArgMxPtr(position);
    return(acceptArg);
}


/*
    PsychAllocOutCellArray()
    
    -If argument is optional we allocate the structure even if the argument is not present.  If this behavior bothers you, 
    then check within your code for the presense of a return argument before creating the struct array.  We
    allocate space regardeless of whether the argument is present because this is consistant with other "PsychAllocOut*" 
    functions which behave this way because in some situations subfunctions might derive returned results from values
    stored in an optional argument.
    
    -If position is -1 then don't attempt to return the created structure to the calling environment.  Instead just 
    allocate the structure and return it in pStruct.  This is how to create a structure which is embeded within another 
    structure using PsychSetStructArrayStructArray().  Note that we use -1 as the flag and not NULL because NULL is 0 and
    0 is reserved for future use as a reference to the subfunction name, of if none then the function name. 
    

*/
psych_bool PsychAllocOutCellVector(	int position, 
									PsychArgRequirementType isRequired, 
									int numElements,  
									PsychGenericScriptType **pCell)
{
    mxArray **mxArrayOut;
    mwSize cellArrayNumDims=2;
    mwSize cellArrayDims[2];
	PsychError matchError;
	psych_bool putOut;

    
    cellArrayDims[0]=1;
    cellArrayDims[1]=numElements;
    
    if(position != kPsychNoArgReturn){  //Return the result to both the C caller and the scripting environment.
        PsychSetReceivedArgDescriptor(position, FALSE, PsychArgOut);
        PsychSetSpecifiedArgDescriptor(position, PsychArgOut, PsychArgType_cellArray, isRequired, 1,1,numElements,numElements,0,0);
        *pCell = mxCreateCellArray(cellArrayNumDims, cellArrayDims);
        mxArrayOut = PsychGetOutArgMxPtr(position);
		matchError=PsychMatchDescriptors();
		putOut=PsychAcceptOutputArgumentDecider(isRequired, matchError);
		if(putOut)
            *mxArrayOut=*pCell;
        return(putOut);
    }else{ //Return the result only to the C caller, not to the calling environment.  Ignore "required".    
        *pCell = mxCreateCellArray(cellArrayNumDims, cellArrayDims);
        return(TRUE);
    }
            
}


/*
    PsychSetCellVectorStringElement()
    
    The variable "index", the index of the element within the struct array, is zero-indexed.  
*/
void PsychSetCellVectorStringElement(  int index,
                                        const char *text,
                                        PsychGenericScriptType *cellVector)
{
    size_t numElements;
    psych_bool isCell;
    mxArray *mxFieldValue;
    
    //check for bogus arguments
    numElements = mxGetM(cellVector) * mxGetN(cellVector);
    if((size_t) index >= numElements)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a cell array field at an out-of-bounds index");

    isCell= mxIsCell(cellVector);
    if(!isCell)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a cell within a non-existent cell array.");
        
    //do stuff
    mxFieldValue=mxCreateString(text);
    mxSetCell(cellVector, (mwIndex) index, mxFieldValue);    
    if (PSYCH_LANGUAGE == PSYCH_OCTAVE) mxDestroyArray(mxFieldValue);
}


/*
    PsychSetCellArrayDoubleElement()
    
    Note: The variable "index" is zero-indexed.
*/                                    
void PsychSetCellVectorDoubleElement(	int index,
                                        double value,
                                        PsychGenericScriptType *cellVector)
{
    size_t numElements;
    psych_bool isCell;
    mxArray *mxFieldValue;

    //check for bogus arguments
    numElements = mxGetM(cellVector) * mxGetN(cellVector);
    if((size_t) index >= numElements)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a cell array field at an out-of-bounds index");

    isCell= mxIsCell(cellVector);
    if(!isCell)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a field within a non-existent cell array.");

    //do stuff
    mxFieldValue= mxCreateDoubleMatrix(1, 1, mxREAL);
    mxGetPr(mxFieldValue)[0]= value;
    mxSetCell(cellVector, (mwIndex) index, mxFieldValue); 
    if (PSYCH_LANGUAGE == PSYCH_OCTAVE) mxDestroyArray(mxFieldValue);
}


/*
    PsychSetStructArrayNativeElement()
    
    
*/
void PsychSetCellVectorNativeElement(	int index,
                                        PsychGenericScriptType *pNativeElement,
                                        PsychGenericScriptType *cellVector)
{
    size_t numElements;
    psych_bool isCell;
    
    //check for bogus arguments
    numElements = mxGetM(cellVector) * mxGetN(cellVector);
    if((size_t) index >= numElements)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a cell array field at an out-of-bounds index");

    isCell= mxIsCell(cellVector);
    if(!isCell)
        PsychErrorExitMsg(PsychError_internal, "Attempt to set a field within a non-existent structure.");
        
    //do stuff
    mxSetCell(cellVector, (mwIndex) index, pNativeElement);     
}


/*
    PsychConvertNativeCellArrayToNativeString()
    
    Accept a native cell array and convert it to a native string by using the  Psychtoolbox script 
    Psychtoolbox/PsychOneliners/CatStr.m
    
    PsychConvertNativeCellArrayToNativeString() is derived from parts of Denis Pelli's Rush.c from the OS 9 Psychtoolbox
    
*/
void PsychConvertNativeCellArrayToNativeString(const PsychGenericScriptType **nativeCellArray, PsychGenericScriptType **nativeString)
{
                          
    int								error, numOutputs, numInputs;
	PsychGenericScriptType			**inputs;
	PsychGenericScriptType			*outputs[1]; //, *inputs[1];
    
    numInputs=1; 
    numOutputs=1;
    outputs[0]=NULL;
    inputs = (PsychGenericScriptType**) nativeCellArray;
    error=mexCallMATLAB(numOutputs, outputs, numInputs, inputs, "CatStr"); 	// Psychtoolbox:PsychOneliners:CatStr.m
    if(error)
        PsychErrorExitMsg(PsychError_internal, "Failed to convert a cell array to string");
    *nativeString=outputs[0];    
}