1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <VideoEditorClasses.h>
18#include <VideoEditorJava.h>
19#include <VideoEditorLogging.h>
20#include <VideoEditorOsal.h>
21
22extern "C" {
23#include <M4OSA_CharStar.h>
24};
25
26
27void
28videoEditJava_checkAndThrowIllegalArgumentExceptionFunc(
29                bool*                               pResult,
30                JNIEnv*                             pEnv,
31                bool                                condition,
32                const char*                         pMessage,
33                const char*                         pFile,
34                int                                 lineNo)
35{
36    // Check if the previous action succeeded.
37    if (*pResult)
38    {
39        // Check if the condition is true.
40        if (condition)
41        {
42            // Log the exception.
43            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",\
44                    "videoEditJava_checkAndThrowIllegalArgumentException, %s (%s:%d)",
45                    pMessage, pFile, lineNo);
46
47            // Reset the result flag.
48            (*pResult) = false;
49
50            // Throw an exception.
51            jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage);
52        }
53    }
54}
55
56void
57videoEditJava_checkAndThrowRuntimeExceptionFunc(
58                bool*                               pResult,
59                JNIEnv*                             pEnv,
60                bool                                condition,
61                M4OSA_ERR                           result,
62                const char*                         pFile,
63                int                                 lineNo
64                )
65{
66    const char* pMessage = NULL;
67
68    // Check if the previous action succeeded.
69    if (*pResult)
70    {
71        // Check if the condition is true.
72        if (condition)
73        {
74            // Get the error string.
75            pMessage = videoEditJava_getErrorName(result);
76
77            // Log the exception.
78            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
79                    "videoEditJava_checkAndThrowRuntimeException, %s (%s:%d)",
80                    pMessage, pFile, lineNo);
81
82            // Reset the result flag.
83            (*pResult) = false;
84
85            // Throw an exception.
86            jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
87        }
88    }
89}
90
91void
92videoEditJava_checkAndThrowIllegalStateExceptionFunc(
93                bool*                               pResult,
94                JNIEnv*                             pEnv,
95                bool                                condition,
96                const char*                         pMessage,
97                const char*                         pFile,
98                int                                 lineNo
99                )
100{
101    // Check if the previous action succeeded.
102    if (*pResult)
103    {
104        // Check if the condition is true.
105        if (condition)
106        {
107            // Log the exception.
108            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
109                    "videoEditJava_checkAndThrowIllegalStateException, %s (%s:%d)",
110                    pMessage, pFile, lineNo);
111
112            // Reset the result flag.
113            (*pResult) = false;
114
115            // Throw an exception.
116            jniThrowException(pEnv, "java/lang/IllegalStateException", pMessage);
117        }
118    }
119}
120
121void
122videoEditJava_getClass(
123                bool*                               pResult,
124                JNIEnv*                             pEnv,
125                const char*                         pName,
126                jclass*                             pClazz)
127{
128    // Only look for the class if locating the previous action succeeded.
129    if (*pResult)
130    {
131        // Log the function call.
132        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
133                "videoEditJava_getClass(%s)", pName);
134
135        // Look up the class.
136        jclass clazz = pEnv->FindClass(pName);
137
138        // Clear any resulting exceptions.
139        pEnv->ExceptionClear();
140
141        // Check if the class could be located.
142        if (NULL != clazz)
143        {
144            // Return the class.
145            (*pClazz) = clazz;
146        }
147        else
148        {
149            // Reset the result flag.
150            (*pResult) = false;
151
152            // Log the error.
153            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
154                    "videoEditJava_getClass, error: unable to locate class %s", pName);
155
156            // Throw an exception.
157            jniThrowException(pEnv, "java/lang/ClassNotFoundException",
158                    "unable to locate class");
159        }
160    }
161}
162
163void
164videoEditJava_getMethodId(
165                bool*                               pResult,
166                JNIEnv*                             pEnv,
167                jclass                              clazz,
168                const char*                         pName,
169                const char*                         pType,
170                jmethodID*                          pMethodId)
171{
172    // Only look for the class if locating the previous action succeeded.
173    if (*pResult)
174    {
175        // Log the function call.
176        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
177                "videoEditJava_getMethodId(%s,%s)", pName, pType);
178
179        // Look up the method id.
180        jmethodID methodId = pEnv->GetMethodID(clazz, pName, pType);
181
182        // Clear any resulting exceptions.
183        pEnv->ExceptionClear();
184
185        // Check if the method could be located.
186        if (NULL != methodId)
187        {
188            // Return the method id.
189            (*pMethodId) = methodId;
190        }
191        else
192        {
193            // Reset the result flag.
194            (*pResult) = false;
195
196            // Log the error.
197            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
198                    "videoEditJava_getMethodId, error: unable to locate method %s with type %s",
199                    pName, pType);
200
201            // Throw an exception.
202            jniThrowException(pEnv, "java/lang/NoSuchMethodException", "unable to locate method");
203        }
204    }
205}
206
207void
208videoEditJava_getFieldId(
209                bool*                               pResult,
210                JNIEnv*                             pEnv,
211                jclass                              clazz,
212                const char*                         pName,
213                const char*                         pType,
214                jfieldID*                           pFieldId)
215{
216    // Only look for the class if locating the previous action succeeded.
217    if (*pResult)
218    {
219        // Log the function call.
220        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
221                "videoEditJava_getFieldId(%s,%s)", pName, pType);
222
223        // Look up the field id.
224        jfieldID fieldId = pEnv->GetFieldID(clazz, pName, pType);
225
226        // Clear any resulting exceptions.
227        pEnv->ExceptionClear();
228
229        // Check if the field could be located.
230        if (NULL != fieldId)
231        {
232            // Return the field id.
233            (*pFieldId) = fieldId;
234        }
235        else
236        {
237            // Reset the result flag.
238            (*pResult) = false;
239
240            // Log the error.
241            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
242                    "videoEditJava_getFieldId, error: unable to locate field %s with type %s",
243                    pName, pType);
244
245            // Throw an exception.
246            jniThrowException(pEnv, "java/lang/NoSuchFieldException", "unable to locate field");
247        }
248    }
249}
250
251void
252videoEditJava_getObject(
253                bool*                               pResult,
254                JNIEnv*                             pEnv,
255                jobject                             object,
256                jfieldID                            objectFieldId,
257                jobject*                            pObject)
258{
259    // Only retrieve the array object and size if the previous action succeeded.
260    if (*pResult)
261    {
262        // Log the function call.
263        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
264            "videoEditJava_getObject()");
265
266        // Retrieve the object.
267        (*pObject) = pEnv->GetObjectField(object, objectFieldId);
268
269        // Clear any resulting exceptions.
270        pEnv->ExceptionClear();
271    }
272}
273
274void
275videoEditJava_getArray(
276                bool*                               pResult,
277                JNIEnv*                             pEnv,
278                jobject                             object,
279                jfieldID                            arrayFieldId,
280                jobjectArray*                       pArray,
281                jsize*                              pArraySize)
282{
283    // Only retrieve the array object and size if the previous action succeeded.
284    if (*pResult)
285    {
286        // Log the function call.
287        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getArray()");
288
289        // Retrieve the array object.
290        jobjectArray array     = (jobjectArray)pEnv->GetObjectField(object, arrayFieldId);
291        jsize        arraySize = 0;
292
293        // Clear any resulting exceptions.
294        pEnv->ExceptionClear();
295
296        // Check if the array could be retrieved.
297        if (NULL != array)
298        {
299            // Retrieve the array size.
300            arraySize = pEnv->GetArrayLength(array);
301        }
302
303        // Return the array and its size.
304        (*pArray)     = array;
305        (*pArraySize) = arraySize;
306    }
307}
308
309void*
310videoEditJava_getString(
311                bool*                               pResult,
312                JNIEnv*                             pEnv,
313                jobject                             object,
314                jfieldID                            stringFieldId,
315                M4OSA_UInt32*                       pLength)
316{
317    void*        pString = M4OSA_NULL;
318    jstring      string  = NULL;
319    M4OSA_UInt32 length  = 0;
320    M4OSA_Char*  pLocal  = M4OSA_NULL;
321    M4OSA_ERR    result  = M4NO_ERROR;
322
323    // Check if the previous action succeeded.
324    if (*pResult)
325    {
326        // Log the function call.
327        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getString()");
328
329        // Check if an object containing a string was specified.
330        if (NULL != stringFieldId)
331        {
332            // Retrieve the string object.
333            string = (jstring)pEnv->GetObjectField(object, stringFieldId);
334
335            // Clear any resulting exceptions.
336            pEnv->ExceptionClear();
337        }
338        else
339        {
340            // The string itself was specified.
341            string = (jstring)object;
342        }
343
344        // Check if the string could be retrieved.
345        if (NULL != string)
346        {
347            // Get a local copy of the string.
348            pLocal = (M4OSA_Char*)pEnv->GetStringUTFChars(string, M4OSA_NULL);
349            if (M4OSA_NULL != pLocal)
350            {
351                // Determine the length of the path
352                // (add one extra character for the zero terminator).
353                length = strlen((const char *)pLocal) + 1;
354
355                // Allocate memory for the string.
356                pString = videoEditOsal_alloc(pResult, pEnv, length, "String");
357                if (*pResult)
358                {
359                    // Copy the string.
360                    result = M4OSA_chrNCopy((M4OSA_Char*)pString, pLocal, length);
361
362                    // Check if the copy succeeded.
363                    videoEditJava_checkAndThrowRuntimeException(pResult, pEnv,
364                     (M4NO_ERROR != result), result);
365
366                    // Check if the string could not be copied.
367                    if (!(*pResult))
368                    {
369                        // Free the allocated memory.
370                        videoEditOsal_free(pString);
371                        pString = M4OSA_NULL;
372                    }
373                }
374
375                // Release the local copy of the string.
376                pEnv->ReleaseStringUTFChars(string, (const char *)pLocal);
377            }
378        }
379
380        // Check if the string was empty or could be copied.
381        if (*pResult)
382        {
383            // Check if the length was requested.
384            if (M4OSA_NULL != pLength)
385            {
386                // Return the length.
387                (*pLength) = length;
388            }
389        }
390
391        // Delete local references to avoid memory leaks
392        pEnv->DeleteLocalRef(string);
393    }
394
395    // Return the string.
396    return(pString);
397}
398
399void
400videoEditJava_getStaticIntField(
401                bool*                               pResult,
402                JNIEnv*                             pEnv,
403                jclass                              clazz,
404                const char*                         pName,
405                int*                                pValue)
406{
407    // Only look for the class if locating the previous action succeeded.
408    if (*pResult)
409    {
410        // Log the function call.
411        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
412                "videoEditJava_getStaticIntField(%s)", pName);
413
414        // Look up the field id.
415        jfieldID fieldId = pEnv->GetStaticFieldID(clazz, pName, "I");
416
417        // Clear any resulting exceptions.
418        pEnv->ExceptionClear();
419
420        // Check if the field could be located.
421        if (NULL != fieldId)
422        {
423            // Retrieve the field value.
424            (*pValue) = pEnv->GetStaticIntField(clazz, fieldId);
425
426            // Log the value.
427            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
428                    "videoEditJava_getStaticIntField, %s = %d", pName, (*pValue));
429        }
430        else
431        {
432            // Reset the result flag.
433            (*pResult) = false;
434
435            // Log the error.
436            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
437                    "videoEditJava_getStaticIntField, error: unable to locate field %s", pName);
438
439            // Throw an exception.
440            jniThrowException(pEnv, "java/lang/NoSuchFieldException",
441                    "unable to locate static field");
442        }
443    }
444}
445
446void
447videoEditJava_initConstantClass(
448                bool*                               pResult,
449                JNIEnv*                             pEnv,
450                VideoEditJava_ConstantsClass*               pClass)
451{
452    bool   gotten = true;
453    jclass clazz  = NULL;
454    int    index  = 0;
455
456    // Check if the previous action succeeded.
457    if (*pResult)
458    {
459        // Log the function call.
460        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
461                "videoEditJava_initConstantClass(%s)", pClass->pName);
462
463        // Only initialize the class once.
464        if (!pClass->initialized)
465        {
466            // Look up the class.
467            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
468
469            // Loop over the constants.
470            for (index = 0; index < pClass->count; index++)
471            {
472                // Look up the constant.
473                videoEditJava_getStaticIntField(pResult, pEnv, clazz,
474                                        pClass->pConstants[index].pName,
475                                        &pClass->pConstants[index].java);
476            }
477
478            // Check if all constants could be located.
479            if (*pResult)
480            {
481                // Set the initialized flag.
482                pClass->initialized = true;
483            }
484        }
485    }
486}
487
488const char*
489videoEditJava_getConstantClassName(
490                const VideoEditJava_ConstantsClass*         pClass,
491                int                                 value,
492                VideoEditJava_UnknownConstant               unknown)
493{
494    const char* pName = M4OSA_NULL;
495    int         index = 0;
496
497    // Loop over the list with constants.
498    for (index = 0;
499         ((M4OSA_NULL == pName) && (index < pClass->count));
500         index++)
501    {
502        // Check if the specified value matches the c value of the constant.
503        if (value == pClass->pConstants[index].c)
504        {
505            // Set the name.
506            pName = pClass->pConstants[index].pName;
507        }
508    }
509
510    // Check if no constant was found.
511    if (M4OSA_NULL == pName)
512    {
513        // Check if a function was specified to handle this case.
514        if (M4OSA_NULL != unknown)
515        {
516            // Pass the constant to the specified unknown function.
517            pName = unknown(value);
518        }
519        else
520        {
521            // Set the description to a default value.
522            pName = "<unknown>";
523        }
524    }
525
526    // Return the result.
527    return(pName);
528}
529
530const char*
531videoEditJava_getConstantClassString(
532                const VideoEditJava_ConstantsClass*         pClass,
533                int                                 value,
534                VideoEditJava_UnknownConstant               unknown)
535{
536    const char* pString = M4OSA_NULL;
537    int         index   = 0;
538
539    // Loop over the list with constants.
540    for (index = 0;
541         ((M4OSA_NULL == pString) && (index < pClass->count));
542         index++)
543    {
544        // Check if the specified value matches the c value of the constant.
545        if (value == pClass->pConstants[index].c)
546        {
547            // Set the description.
548            pString = pClass->pConstants[index].pDescription;
549        }
550    }
551
552    // Check if no constant was found.
553    if (M4OSA_NULL == pString)
554    {
555        // Check if a function was specified to handle this case.
556        if (M4OSA_NULL != unknown)
557        {
558            // Pass the constant to the specified unknown function.
559            pString = unknown(value);
560        }
561        else
562        {
563            // Set the description to a default value.
564            pString = "<unknown>";
565        }
566    }
567
568    // Return the result.
569    return(pString);
570}
571
572int
573videoEditJava_getConstantClassJavaToC(
574                bool*                               pResult,
575                const VideoEditJava_ConstantsClass*         pClass,
576                int                                 value)
577{
578    bool gotten = false;
579    int  index  = 0;
580
581    // Check if the previous action succeeded.
582    if (*pResult)
583    {
584        // Loop over the list with constants.
585        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
586        {
587            // Check if the specified value matches the java value of the constant.
588            if (value == pClass->pConstants[index].java)
589            {
590                // Set the value to the c value.
591                value = pClass->pConstants[index].c;
592
593                // Set the gotten flag.
594                gotten = true;
595            }
596        }
597
598        // Check if the value was not found.
599        if (!gotten)
600        {
601            (*pResult) = false;
602        }
603    }
604
605    // Return the translated value.
606    return(value);
607}
608
609int
610videoEditJava_getConstantClassJavaToC(
611                bool*                               pResult,
612                const VideoEditJava_ConstantsClass*         pClass,
613                int                                 value,
614                int                                 unknown)
615{
616    bool gotten = false;
617    int  index  = 0;
618
619    // Check if the previous action succeeded.
620    if (*pResult)
621    {
622        // Loop over the list with constants.
623        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
624        {
625            // Check if the specified value matches the java value of the constant.
626            if (value == pClass->pConstants[index].java)
627            {
628                // Set the value to the c value.
629                value = pClass->pConstants[index].c;
630
631                // Set the gotten flag.
632                gotten = true;
633            }
634        }
635
636        // If the constant was not found, look for the specified unknown.
637        if (!gotten)
638        {
639            // Set the value to the c value.
640            value = unknown;
641        }
642    }
643
644    // Return the translated value.
645    return(value);
646}
647
648int
649videoEditJava_getConstantClassCToJava(
650                const VideoEditJava_ConstantsClass*         pClass,
651                int                                 value)
652{
653    bool gotten = false;
654    int  index  = 0;
655
656    // Loop over the list with constants.
657    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
658    {
659        // Check if the specified value matches the c value of the constant.
660        if (value == pClass->pConstants[index].c)
661        {
662            // Set the value to the java value.
663            value = pClass->pConstants[index].java;
664
665            // Set the gotten flag.
666            gotten = true;
667        }
668    }
669
670    // Return the translated value.
671    return(value);
672}
673
674int
675videoEditJava_getConstantClassCToJava(
676                const VideoEditJava_ConstantsClass*         pClass,
677                int                                 value,
678                int                                 unknown)
679{
680    bool gotten = false;
681    int  index  = 0;
682
683    // Loop over the list with constants.
684    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
685    {
686        // Check if the specified value matches the c value of the constant.
687        if (value == pClass->pConstants[index].c)
688        {
689            // Set the value to the java value.
690            value = pClass->pConstants[index].java;
691
692            // Set the gotten flag.
693            gotten = true;
694        }
695    }
696
697    // If the constant was not found, look for the specified unknown.
698    if (!gotten)
699    {
700        // Loop over the list with constants.
701        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
702        {
703            // Check if the specified value matches the java value of the constant.
704            if (unknown == pClass->pConstants[index].c)
705            {
706                // Set the value to the c value.
707                value = pClass->pConstants[index].java;
708
709                // Set the gotten flag.
710                gotten = true;
711            }
712        }
713    }
714
715    // Return the translated value.
716    return(value);
717}
718
719void
720videoEditJava_initFieldClass(
721                bool*                               pResult,
722                JNIEnv*                             pEnv,
723                VideoEditJava_FieldsClass*                  pClass)
724{
725    bool   gotten = true;
726    jclass clazz  = NULL;
727    int    index  = 0;
728
729    // Check if the previous action succeeded.
730    if (*pResult)
731    {
732        // Log the function call.
733        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
734                "videoEditJava_initFieldClass(%s)", pClass->pName);
735
736        // Only initialize the class once.
737        if (!pClass->initialized)
738        {
739            // Look up the class.
740            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
741
742            // Loop over the fields.
743            for (index = 0; index < pClass->count; index++)
744            {
745                // Look up the field id.
746                videoEditJava_getFieldId(
747                        pResult,
748                        pEnv,
749                        clazz,
750                        pClass->pFields[index].pName,
751                        pClass->pFields[index].pType,
752                        &pClass->pFields[index].fieldId);
753            }
754
755            // Check if all fields could be located.
756            if (*pResult)
757            {
758                // Set the initialized flag.
759                pClass->initialized = true;
760            }
761        }
762    }
763}
764
765void
766videoEditJava_fieldClassClass(
767                bool*                               pResult,
768                JNIEnv*                             pEnv,
769                const VideoEditJava_FieldsClass*            pClass,
770                jclass*                             pClazz)
771{
772    // Check if the previous action succeeded.
773    if (*pResult)
774    {
775        // Check if the class is initialized.
776        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
777                "field class not initialized");
778
779        // Get the class.
780        videoEditJava_getClass(pResult, pEnv, pClass->pName, pClazz);
781    }
782}
783
784void
785videoEditJava_fieldClassFieldIds(
786                bool*                               pResult,
787                JNIEnv*                             pEnv,
788                const VideoEditJava_FieldsClass*            pClass,
789                int                                 count,
790                VideoEditJava_FieldIds*                     pIds)
791{
792    int index = 0;
793
794    // Check if the previous action succeeded.
795    if (*pResult)
796    {
797        // Check if the class is initialized.
798        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
799                "field class not initialized");
800
801        // Check if the number of fields matches.
802        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
803                (pClass->count != count),
804                "field class type mismatch");
805
806        // Check if the class and object are valid.
807        if (*pResult)
808        {
809            // Loop over the class fields.
810            for (index = 0; index < count; index++)
811            {
812                // Copy the field ids.
813                pIds->fieldIds[index] = pClass->pFields[index].fieldId;
814            }
815        }
816    }
817}
818
819void
820videoEditJava_initMethodClass(
821                bool*                               pResult,
822                JNIEnv*                             pEnv,
823                VideoEditJava_MethodsClass*                 pClass)
824{
825    bool   gotten = true;
826    jclass clazz  = NULL;
827    int    index  = 0;
828
829    // Check if the previous action succeeded.
830    if (*pResult)
831    {
832        // Log the function call.
833        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
834                "videoEditJava_initMethodClass(%s)", pClass->pName);
835
836        // Only initialize the class once.
837        if (!pClass->initialized)
838        {
839            // Look up the class.
840            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
841
842            // Loop over the methods.
843            for (index = 0; index < pClass->count; index++)
844            {
845                // Look up the method id.
846                videoEditJava_getMethodId(
847                        pResult,
848                        pEnv,
849                        clazz,
850                        pClass->pMethods[index].pName,
851                        pClass->pMethods[index].pType,
852                        &pClass->pMethods[index].methodId);
853            }
854
855            // Check if all methods could be located.
856            if (*pResult)
857            {
858                // Set the initialized flag.
859                pClass->initialized = true;
860            }
861        }
862    }
863}
864
865void
866videoEditJava_methodClassMethodIds(
867                bool*                               pResult,
868                JNIEnv*                             pEnv,
869                const VideoEditJava_MethodsClass*   pClass,
870                int                                 count,
871                VideoEditJava_MethodIds*            pIds)
872{
873    int index = 0;
874
875    // Check if the previous action succeeded.
876    if (*pResult)
877    {
878        // Check if the class is initialized.
879        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
880                    "method class not initialized");
881
882        // Check if the number of methods matches.
883        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,\
884                    (pClass->count != count),
885                    "method class type mismatch");
886
887        // Check if the class and object are valid.
888        if (*pResult)
889        {
890            // Loop over the class methods.
891            for (index = 0; index < count; index++)
892            {
893                // Copy the method ids.
894                pIds->methodIds[index] = pClass->pMethods[index].methodId;
895            }
896        }
897    }
898}
899
900