1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
12 #include "sjme/alloc.h"
13 #include "sjme/debug.h"
14 #include "sjme/nvm/descriptor.h"
15 #include "sjme/util.h"
16 #include "sjme/cleanup.h"
19 * Field type link, used for method type parsing.
23 typedef struct sjme_desc_fieldTypeLink sjme_desc_fieldTypeLink
;
25 struct sjme_desc_fieldTypeLink
27 /** The previous link. */
28 sjme_desc_fieldTypeLink
* prev
;
31 sjme_desc_fieldTypeLink
* next
;
33 /** Field information. */
34 sjme_desc_fieldType field
;
37 static sjme_errorCode
sjme_desc_interpretBinaryNameFixed(sjme_lpcstr inStr
,
38 sjme_jint inLen
, sjme_lpcstr finalEnd
, sjme_jint numSlash
,
39 sjme_desc_binaryName
* result
)
42 return sjme_error_notImplemented(0);
45 sjme_lpcstr at
, end
, base
, nextAt
;
46 sjme_jint c
, identLen
, identAt
;
47 sjme_desc_identifier
* ident
;
49 if (inStr
== NULL
|| finalEnd
== NULL
)
50 return SJME_ERROR_NULL_ARGUMENTS
;
52 /* If a result is actually cared about rather than a parse check. */
55 /* Fill in basic details. */
56 result
->whole
->pointer
= inStr
;
57 result
->whole
.length
= finalEnd
- inStr
;
58 result
->hash
= sjme_string_hashN(result
->whole
.pointer
,
59 result
->whole
.length
);
61 /* Initialize list. */
62 sjme_list_directInit(numSlash
+ 1, &result
->identifiers
,
63 sjme_desc_identifier
, 0);
66 /* Otherwise identifier is ignored. */
70 ident
= sjme_alloca(sizeof(*ident
));
72 return sjme_error_outOfMemory(NULL
, 0);
75 memset(ident
, 0, sizeof(*ident
));
78 /* Parse individual identifiers, if there are none then this */
79 /* will be skipped completely. */
82 for (at
= inStr
, base
= at
, end
= at
+ inLen
;
83 at
< end
&& identAt
< numSlash
; at
= nextAt
)
85 /* Decode character. */
86 c
= sjme_string_decodeChar(at
, &nextAt
);
88 return SJME_ERROR_INVALID_BINARY_NAME
;
90 /* Only split on slashes. */
94 /* If a slash it will then get split and an identifier parsed. */
97 return SJME_ERROR_INVALID_BINARY_NAME
;
99 /* Which identifier is filled? */
101 ident
= &result
->identifiers
.elements
[identAt
];
103 memset(ident
, 0, sizeof(*ident
));
105 /* Parse individual identifier fragment. */
106 if (sjme_error_is(error
= sjme_desc_interpretIdentifier(
107 ident
, base
, identLen
)))
108 return sjme_error_defaultOr(error
,
109 SJME_ERROR_INVALID_BINARY_NAME
);
111 /* Move identifier and next base up. */
116 /* The end fragment is not valid if empty. */
117 identLen
= finalEnd
- base
;
119 return SJME_ERROR_INVALID_BINARY_NAME
;
121 /* Which identifier is filled? */
123 ident
= &result
->identifiers
.elements
[identAt
];
125 memset(ident
, 0, sizeof(*ident
));
127 /* Parse final one. */
128 if (sjme_error_is(error
= sjme_desc_interpretIdentifier(
129 ident
, base
, identLen
)))
130 return sjme_error_defaultOr(error
,
131 SJME_ERROR_INVALID_BINARY_NAME
);
134 return SJME_ERROR_NONE
;
138 static sjme_errorCode
sjme_desc_interpretBinaryNameNumSlash(sjme_lpcstr inStr
,
139 sjme_jint inLen
, sjme_jint
* outNumSlash
, sjme_lpcstr
* finalEnd
)
142 return sjme_error_notImplemented(0);
144 sjme_jint c
, numSlash
;
147 if (inStr
== NULL
|| outNumSlash
== NULL
)
148 return SJME_ERROR_NULL_ARGUMENTS
;
150 /* Count the number of slashes. */
152 for (at
= inStr
, end
= at
+ inLen
; at
< end
;)
154 /* Decode character. */
155 c
= sjme_string_decodeChar(at
, &at
);
157 return SJME_ERROR_INVALID_BINARY_NAME
;
159 /* If a slash it will then get split. */
164 /* Store the end for faster final decode. */
165 if (finalEnd
!= NULL
)
169 *outNumSlash
= numSlash
;
170 return SJME_ERROR_NONE
;
174 static sjme_errorCode
sjme_desc_interpretFieldTypeAllocSize(sjme_lpcstr inStr
,
175 sjme_jint inLen
, sjme_jint
* outAllocLen
)
178 return sjme_error_notImplemented(0);
180 sjme_errorCode error
;
181 sjme_jint typeCode
, allocLen
, subLen
;
184 if (inStr
== NULL
|| outAllocLen
== NULL
)
185 return SJME_ERROR_NULL_ARGUMENTS
;
187 /* Decode the type code. */
189 typeCode
= sjme_string_decodeChar(next
, &next
);
191 return SJME_ERROR_INVALID_FIELD_TYPE
;
193 /* Base size with the single base component. */
194 allocLen
= sizeof(sjme_desc_fieldType
) +
195 sizeof(sjme_desc_fieldTypeComponent
);
197 /* If an array, count the number of dimensions... */
198 while (typeCode
== '[')
201 allocLen
+= sizeof(sjme_desc_fieldTypeComponent
);
203 /* Read in next code. */
204 typeCode
= sjme_string_decodeChar(next
, &next
);
206 return SJME_ERROR_INVALID_FIELD_TYPE
;
208 /* Stop if not an array. */
216 /* Determine the number of identifiers used. */
218 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameNumSlash(
219 next
, inLen
- (next
- inStr
) - 1, &subLen
,
220 NULL
)) || subLen
< 0)
221 return sjme_error_defaultOr(error
,
222 SJME_ERROR_INVALID_FIELD_TYPE
);
225 allocLen
+= SJME_SIZEOF_DESC_BINARY_NAME(subLen
+ 1) +
226 sizeof(sjme_desc_fieldTypeComponent
);
230 *outAllocLen
= allocLen
;
231 return SJME_ERROR_NONE
;
235 static sjme_errorCode
sjme_desc_interpretFieldTypeFixed(sjme_lpcstr inStr
,
236 sjme_jint inLen
, sjme_desc_fieldType
* result
, sjme_jboolean continueField
,
237 sjme_lpcstr
*fieldEnd
)
240 return sjme_error_notImplemented(0);
242 sjme_errorCode error
;
243 sjme_jint typeCode
, compAt
, numSlash
, strLen
, subAt
, c
;
244 sjme_jboolean isArray
, isObject
, isFinal
, arrayFragment
;
245 sjme_desc_fieldTypeComponent
* component
;
246 sjme_desc_fieldTypeComponent
* parent
;
247 sjme_lpcstr strAt
, strBase
, finalEnd
, lastAt
, rootStrBase
, seek
;
249 if (inStr
== NULL
|| result
== NULL
)
250 return SJME_ERROR_NULL_ARGUMENTS
;
252 /* Component parsing loop. */
253 isFinal
= SJME_JNI_FALSE
;
256 arrayFragment
= SJME_JNI_FALSE
;
257 for (compAt
= 0;; compAt
++)
259 /* Reading into where? */
260 component
= &result
->components
[compAt
];
262 /* Decode single character which determines the type this is. */
265 typeCode
= sjme_string_decodeChar(strAt
, &strAt
);
267 /* There are more characters that are valid? */
270 /* Last is at the base. */
273 /* Option to continue parsing fields? */
276 if (fieldEnd
!= NULL
)
283 return SJME_ERROR_INVALID_FIELD_TYPE
;
287 /* Handle based on the type code. */
288 isArray
= SJME_JNI_FALSE
;
289 isObject
= SJME_JNI_FALSE
;
292 /* Single type codes. */
294 component
->javaType
= SJME_JAVA_TYPE_ID_VOID
;
299 component
->javaType
= SJME_JAVA_TYPE_ID_BOOLEAN_OR_BYTE
;
304 component
->javaType
= SJME_JAVA_TYPE_ID_SHORT_OR_CHAR
;
308 component
->javaType
= SJME_JAVA_TYPE_ID_INTEGER
;
312 component
->javaType
= SJME_JAVA_TYPE_ID_LONG
;
316 component
->javaType
= SJME_JAVA_TYPE_ID_FLOAT
;
320 component
->javaType
= SJME_JAVA_TYPE_ID_DOUBLE
;
323 /* Longer type codes. */
325 isObject
= SJME_JNI_TRUE
;
328 component
->javaType
= SJME_JAVA_TYPE_ID_OBJECT
;
332 return SJME_ERROR_INVALID_FIELD_TYPE
;
335 /* Determine cell size. */
336 if (component
->javaType
== SJME_JAVA_TYPE_ID_VOID
)
337 component
->cells
= 0;
338 else if (component
->javaType
== SJME_JAVA_TYPE_ID_LONG
||
339 component
->javaType
== SJME_JAVA_TYPE_ID_DOUBLE
)
340 component
->cells
= 2;
342 component
->cells
= 1;
344 /* The fragment is the remaining string. */
345 component
->fragment
.pointer
= strBase
;
347 /* Is this an array? */
350 /* We parsed an array, so handle actual fragment length later. */
351 arrayFragment
= SJME_JNI_TRUE
;
354 component
->isArray
= SJME_JNI_TRUE
;
356 /* Increase dimension count. */
357 result
->numDims
+= 1;
359 /* Initialize just to base zero for now. */
360 component
->fragment
.length
= 0;
362 /* Binary name is unspecified. */
363 component
->binaryName
.pointer
= NULL
;
364 component
->binaryName
.length
= 0;
366 /* Go up and increase the array size of each component. */
367 for (subAt
= 0; subAt
<= compAt
; subAt
++)
368 result
->components
[subAt
].numDims
+= 1;
371 /* Is this an object? */
374 /* Do not parse anymore, would be an error. */
375 isFinal
= SJME_JNI_TRUE
;
377 /* Determine the string length fragment. */
379 for (seek
= strBase
; *seek
!= 0;)
382 c
= sjme_string_decodeChar(seek
, &seek
);
384 return SJME_ERROR_INVALID_FIELD_TYPE
;
386 /* Stop at semicolon. */
391 /* The string length is more well known now. */
392 strLen
= (seek
- strBase
) - 1;
395 /* Count the number of slashes. */
397 if (sjme_error_is(error
=
398 sjme_desc_interpretBinaryNameNumSlash(strAt
,
399 strLen
, &numSlash
, NULL
)) ||
401 return sjme_error_defaultOr(error
,
402 SJME_ERROR_INVALID_FIELD_TYPE
);
404 /* Interpret binary name, result is actually ignored. */
405 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameFixed(
406 strBase
, strLen
, finalEnd
, numSlash
,
408 return sjme_error_defaultOr(error
,
409 SJME_ERROR_INVALID_FIELD_TYPE
);
411 /* Fill in binary name fragment. */
412 component
->binaryName
.pointer
= strBase
;
413 component
->binaryName
.length
= strLen
;
415 /* Need ending semicolon. */
417 if (';' != sjme_string_decodeChar(strAt
, &strAt
))
418 return SJME_ERROR_INVALID_FIELD_TYPE
;
420 /* Fragment length is the base string component. */
421 component
->fragment
.length
= strAt
- rootStrBase
;
424 /* Primitive type. */
427 /* Do not parse any further. */
428 isFinal
= SJME_JNI_TRUE
;
430 /* Fragment length is only a single character. */
431 component
->fragment
.length
= 1;
433 /* Binary name is unspecified. */
434 component
->binaryName
.pointer
= NULL
;
435 component
->binaryName
.length
= 0;
439 /* Fixup array fragment length. */
441 for (compAt
= result
->numDims
; compAt
> 0; compAt
--)
443 /* Get base component. */
444 component
= &result
->components
[compAt
];
445 parent
= &result
->components
[compAt
- 1];
447 /* Calculate parent length, is always one higher as it contains */
448 /* the current component along with the array marker. */
449 parent
->fragment
.length
= component
->fragment
.length
+ 1;
452 /* Base initialize of field. */
453 result
->whole
.pointer
= inStr
;
454 result
->whole
.length
= lastAt
- inStr
;
455 result
->hash
= sjme_string_hashN(result
->whole
.pointer
,
456 result
->whole
.length
);
459 return SJME_ERROR_NONE
;
463 sjme_jint
sjme_desc_compareBinaryName(
464 sjme_attrInNullable
const sjme_desc_binaryName aName
,
465 sjme_attrInNullable
const sjme_desc_binaryName bName
)
468 return sjme_error_notImplemented(0);
471 if (aName
== NULL
|| bName
== NULL
)
472 return sjme_compare_null(aName
, bName
);
474 /* Normal compare. */
475 return sjme_string_compareN(
476 aName
->whole
.pointer
, aName
->whole
.length
,
477 bName
->whole
.pointer
, bName
->whole
.length
);
481 sjme_jint
sjme_desc_compareBinaryNameP(
482 sjme_attrInNullable sjme_pointerLen
* aPointerLen
,
483 sjme_attrInNullable sjme_desc_binaryName bName
)
486 return sjme_error_notImplemented(0);
491 aNull
= (aPointerLen
== NULL
|| aPointerLen
->pointer
== NULL
);
492 if (aNull
|| bName
== NULL
)
493 return sjme_compare_null((aNull
? NULL
: aPointerLen
), bName
);
495 /* Normal compare. */
496 return sjme_string_compareN(
497 aPointerLen
->pointer
, aPointerLen
->length
,
498 bName
->whole
.pointer
, bName
->whole
.length
);
502 sjme_jint
sjme_desc_compareBinaryNamePS(
503 sjme_attrInNullable sjme_pointerLen
* aPointerLen
,
504 sjme_attrInNullable sjme_lpcstr bString
)
507 return sjme_error_notImplemented(0);
512 aNull
= (aPointerLen
== NULL
|| aPointerLen
->pointer
== NULL
);
513 if (aNull
|| bString
== NULL
)
514 return sjme_compare_null((aNull
? NULL
: aPointerLen
), bString
);
516 /* Normal compare. */
517 return sjme_string_compareN(
518 aPointerLen
->pointer
, aPointerLen
->length
,
519 bString
, strlen(bString
));
523 sjme_jint
sjme_desc_compareBinaryNameS(
524 sjme_attrInNullable sjme_desc_binaryName aName
,
525 sjme_attrInNullable sjme_lpcstr bString
)
528 return sjme_error_notImplemented(0);
533 if (aName
== NULL
|| bString
== NULL
)
534 return sjme_compare_null(aName
, bString
);
536 /* Wrong string length? */
537 strLen
= strlen(bString
);
538 if (strLen
!= aName
->whole
.length
)
539 return SJME_JNI_FALSE
;
541 /* Compare actual values. */
542 return strncmp(aName
->whole
.pointer
, bString
, strLen
);
546 sjme_jint
sjme_desc_compareClass(
547 sjme_attrInNullable sjme_desc_className aClass
,
548 sjme_attrInNullable sjme_desc_className bClass
)
551 return sjme_error_notImplemented(0);
554 if (aClass
== NULL
|| bClass
== NULL
)
555 return sjme_compare_null(aClass
, bClass
);
557 /* Normal compare. */
558 return sjme_string_compareN(
559 aClass
->whole
.pointer
, aClass
->whole
.length
,
560 bClass
->whole
.pointer
, bClass
->whole
.length
);
564 sjme_jint
sjme_desc_compareClassS(
565 sjme_attrInNullable sjme_desc_className aClass
,
566 sjme_attrInNullable sjme_lpcstr bString
)
569 return sjme_error_notImplemented(0);
572 if (aClass
== NULL
|| bString
== NULL
)
573 return sjme_compare_null(aClass
, bString
);
575 /* Normal compare. */
576 return sjme_string_compareN(
577 aClass
->whole
.pointer
, aClass
->whole
.length
,
578 bString
, strlen(bString
));
582 sjme_jint
sjme_desc_compareField(
583 sjme_attrInNullable sjme_desc_fieldType aField
,
584 sjme_attrInNullable sjme_desc_fieldType bField
)
587 return sjme_error_notImplemented(0);
590 if (aField
== NULL
|| bField
== NULL
)
591 return sjme_compare_null(aField
, bField
);
593 /* Normal compare. */
594 return sjme_string_compareN(
595 aField
->whole
.pointer
, aField
->whole
.length
,
596 bField
->whole
.pointer
, bField
->whole
.length
);
600 sjme_jint
sjme_desc_compareFieldC(
601 sjme_attrInNullable sjme_desc_fieldTypeComponent aFieldComponent
,
602 sjme_attrInNullable sjme_desc_fieldType bField
)
605 return sjme_error_notImplemented(0);
608 if (aFieldComponent
== NULL
|| bField
== NULL
)
609 return sjme_compare_null(aFieldComponent
, bField
);
611 /* Normal compare. */
612 return sjme_string_compareN(
613 aFieldComponent
->fragment
.pointer
,
614 aFieldComponent
->fragment
.length
,
615 bField
->whole
.pointer
, bField
->whole
.length
);
619 sjme_jint
sjme_desc_compareFieldS(
620 sjme_attrInNullable sjme_desc_fieldType aField
,
621 sjme_attrInNullable sjme_lpcstr bString
)
624 return sjme_error_notImplemented(0);
627 if (aField
== NULL
|| bString
== NULL
)
628 return sjme_compare_null(aField
, bString
);
630 /* Normal compare. */
631 return sjme_string_compareN(
632 aField
->whole
.pointer
, aField
->whole
.length
,
633 bString
, strlen(bString
));
637 sjme_jint
sjme_desc_compareIdentifier(
638 sjme_attrInNullable sjme_desc_identifier aIdent
,
639 sjme_attrInNullable sjme_desc_identifier bIdent
)
642 return sjme_error_notImplemented(0);
645 if (aIdent
== NULL
|| bIdent
== NULL
)
646 return sjme_compare_null(aIdent
, bIdent
);
648 /* Normal compare. */
649 return sjme_string_compareN(
650 aIdent
->whole
.pointer
, aIdent
->whole
.length
,
651 bIdent
->whole
.pointer
, bIdent
->whole
.length
);
655 sjme_jint
sjme_desc_compareIdentifierS(
656 sjme_attrInNullable sjme_desc_identifier aIdent
,
657 sjme_attrInNullable sjme_lpcstr bString
)
660 return sjme_error_notImplemented(0);
665 if (aIdent
== NULL
|| bString
== NULL
)
666 return sjme_compare_null(aIdent
, bString
);
668 /* Compare by string. */
669 return sjme_string_compareN(
670 aIdent
->whole
.pointer
, aIdent
->whole
.length
,
671 bString
, strlen(bString
));
675 sjme_jint
sjme_desc_compareMethod(
676 sjme_attrInNullable sjme_desc_methodType aMethod
,
677 sjme_attrInNullable sjme_desc_methodType bMethod
)
680 return sjme_error_notImplemented(0);
683 if (aMethod
== NULL
|| bMethod
== NULL
)
684 return sjme_compare_null(aMethod
, bMethod
);
686 /* Normal compare. */
687 return sjme_string_compareN(
688 aMethod
->whole
.pointer
, aMethod
->whole
.length
,
689 bMethod
->whole
.pointer
, bMethod
->whole
.length
);
693 sjme_jint
sjme_desc_compareMethodS(
694 sjme_attrInNullable sjme_desc_methodType aMethod
,
695 sjme_attrInNullable sjme_lpcstr bString
)
698 return sjme_error_notImplemented(0);
701 if (aMethod
== NULL
|| bString
== NULL
)
702 return sjme_compare_null(aMethod
, bString
);
704 /* Normal compare. */
705 return sjme_string_compareN(
706 aMethod
->whole
.pointer
, aMethod
->whole
.length
,
707 bString
, strlen(bString
));
711 sjme_errorCode
sjme_desc_interpretBinaryName(
712 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
713 sjme_attrOutNotNull sjme_desc_binaryName
* outName
,
714 sjme_attrInNotNull sjme_lpcstr inStr
,
715 sjme_attrInPositive sjme_jint inLen
)
718 return sjme_error_notImplemented(0);
720 sjme_errorCode error
;
721 sjme_lpcstr finalEnd
;
722 sjme_desc_binaryName
* result
;
723 sjme_jint resultLen
, numSlash
;
725 if (inPool
== NULL
|| outName
== NULL
|| inStr
== NULL
)
726 return SJME_ERROR_NULL_ARGUMENTS
;
729 return SJME_ERROR_INVALID_ARGUMENT
;
731 return SJME_ERROR_INVALID_BINARY_NAME
;
733 /* Count the number of slashes. */
736 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameNumSlash(inStr
,
737 inLen
, &numSlash
, &finalEnd
)))
738 return sjme_error_default(error
);
741 resultLen
= SJME_SIZEOF_DESC_BINARY_NAME(numSlash
+ 1);
742 result
= sjme_alloca(resultLen
);
744 /* Check that it is valid. */
746 return sjme_error_outOfMemory(inPool
, resultLen
);
749 memset(result
, 0, resultLen
);
751 /* Parse fixed binary name. */
752 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameFixed(
753 inStr
, inLen
, finalEnd
, numSlash
, result
)))
754 return sjme_error_defaultOr(error
,
755 SJME_ERROR_INVALID_BINARY_NAME
);
758 return sjme_alloc_copyWeak(inPool
, resultLen
,
759 sjme_nvm_enqueueHandler
, SJME_NVM_ENQUEUE_IDENTITY
,
760 (void**)outName
, (void*)result
, NULL
);
764 sjme_errorCode
sjme_desc_interpretClassName(
765 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
766 sjme_attrOutNotNull sjme_desc_className
* outName
,
767 sjme_attrInNotNull sjme_lpcstr inStr
,
768 sjme_attrInPositive sjme_jint inLen
)
771 return sjme_error_notImplemented(0);
773 sjme_errorCode error
;
774 sjme_jint c
, numSlash
, allocLen
, strLen
;
775 sjme_desc_className
* result
;
776 sjme_lpcstr finalEnd
;
778 if (inPool
== NULL
|| outName
== NULL
|| inStr
== NULL
)
779 return SJME_ERROR_NULL_ARGUMENTS
;
782 return SJME_ERROR_INVALID_ARGUMENT
;
784 return SJME_ERROR_INVALID_CLASS_NAME
;
786 /* Get actual string length. */
787 strLen
= sjme_string_lengthN(inStr
, inLen
);
789 /* Is this an array? Interpret as field. */
790 c
= sjme_string_decodeChar(inStr
, NULL
);
793 /* Determine field size. */
795 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeAllocSize(
796 inStr
, strLen
, &allocLen
)) || allocLen
< 0)
797 return sjme_error_defaultOr(error
,
798 SJME_ERROR_INVALID_CLASS_NAME
);
801 /* Otherwise, interpret as binary name. */
804 /* Determine slashes for resultant size. */
807 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameNumSlash(
808 inStr
, strLen
, &numSlash
, &finalEnd
)) ||
810 return sjme_error_defaultOr(error
,
811 SJME_ERROR_INVALID_CLASS_NAME
);
813 /* Allocate this much. */
814 allocLen
= SJME_SIZEOF_DESC_BINARY_NAME(numSlash
+ 1);
817 /* Add class base. */
818 allocLen
+= sizeof(sjme_desc_className
);
821 result
= sjme_alloca(allocLen
);
823 return sjme_error_outOfMemory(inPool
, allocLen
);
826 memset(result
, 0, allocLen
);
828 /* Fill in basic details. */
829 result
->whole
.pointer
= inStr
;
830 result
->whole
.length
= strLen
;
831 result
->hash
= sjme_string_hashN(result
->whole
.pointer
,
832 result
->whole
.length
);
838 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeFixed(
839 inStr
, strLen
, &result
->descriptor
.field
,
840 SJME_JNI_FALSE
, NULL
)))
841 return sjme_error_defaultOr(error
,
842 SJME_ERROR_INVALID_CLASS_NAME
);
845 result
->isField
= SJME_JNI_TRUE
;
848 /* Parse binary name. */
852 if (sjme_error_is(error
= sjme_desc_interpretBinaryNameFixed(
853 inStr
, strLen
, finalEnd
, numSlash
,
854 &result
->descriptor
.binary
)))
855 return sjme_error_defaultOr(error
,
856 SJME_ERROR_INVALID_CLASS_NAME
);
860 return sjme_alloc_copyWeak(inPool
, allocLen
,
861 sjme_nvm_enqueueHandler
, SJME_NVM_ENQUEUE_IDENTITY
,
862 (void**)outName
, (void*)result
, NULL
);
866 sjme_errorCode
sjme_desc_interpretFieldType(
867 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
868 sjme_attrOutNotNull sjme_desc_fieldType
* outType
,
869 sjme_attrInNotNull sjme_lpcstr inStr
,
870 sjme_attrInPositive sjme_jint inLen
)
873 return sjme_error_notImplemented(0);
875 sjme_errorCode error
;
876 sjme_jint strLen
, typeCode
, allocLen
;
877 sjme_desc_fieldType
* result
;
879 if (inPool
== NULL
|| outType
== NULL
|| inStr
== NULL
)
880 return SJME_ERROR_NULL_ARGUMENTS
;
883 return SJME_ERROR_INVALID_ARGUMENT
;
885 return SJME_ERROR_INVALID_FIELD_TYPE
;
887 /* Need the length of string to determine what possible type this is. */
888 strLen
= sjme_string_lengthN(inStr
, inLen
);
890 return SJME_ERROR_INVALID_FIELD_TYPE
;
892 /* How many bytes are needed for allocation? */
894 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeAllocSize(inStr
,
895 inLen
, &allocLen
)) || allocLen
<= 0)
896 return sjme_error_defaultOr(error
,
897 SJME_ERROR_INVALID_FIELD_TYPE
);
899 /* Allocate result. */
900 result
= sjme_alloca(allocLen
);
902 return sjme_error_outOfMemory(inPool
, allocLen
);
905 memset(result
, 0, allocLen
);
907 /* Load field, recursively. */
908 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeFixed(
909 inStr
, inLen
, result
, SJME_JNI_FALSE
, NULL
)))
910 return sjme_error_defaultOr(error
,
911 SJME_ERROR_INVALID_FIELD_TYPE
);
913 /* Return copy of it. */
914 return sjme_alloc_copyWeak(inPool
, allocLen
,
915 sjme_nvm_enqueueHandler
, SJME_NVM_ENQUEUE_IDENTITY
,
916 (void**)outType
, (void*)result
, NULL
);
920 sjme_errorCode
sjme_desc_interpretIdentifier(
921 sjme_attrOutNotNull sjme_desc_identifier
* outIdent
,
922 sjme_attrInNotNull sjme_lpcstr inStr
,
923 sjme_attrInPositive sjme_jint inLen
)
926 return sjme_error_notImplemented(0);
931 if (outIdent
== NULL
|| inStr
== NULL
)
932 return SJME_ERROR_NULL_ARGUMENTS
;
935 return SJME_ERROR_INVALID_ARGUMENT
;
937 return SJME_ERROR_INVALID_IDENTIFIER
;
939 /* Check input for invalid characters. */
940 for (at
= inStr
, end
= at
+ inLen
; at
< end
;)
942 /* Decode character. */
943 c
= sjme_string_decodeChar(at
, &at
);
945 return SJME_ERROR_INVALID_IDENTIFIER
;
947 /* Is the character not valid? */
948 if (c
== '.' || c
== ';' || c
== '[' || c
== '/')
949 return SJME_ERROR_INVALID_IDENTIFIER
;
952 /* Cannot be blank. */
954 return SJME_ERROR_INVALID_IDENTIFIER
;
957 memset(outIdent
, 0, sizeof(*outIdent
));
958 outIdent
->hash
= sjme_string_hashN(inStr
, inLen
);
959 outIdent
->whole
.pointer
= (sjme_pointer
)inStr
;
960 outIdent
->whole
.length
= end
- inStr
;
963 return SJME_ERROR_NONE
;
967 sjme_errorCode
sjme_desc_interpretMethodType(
968 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
969 sjme_attrOutNotNull sjme_desc_methodType
* outType
,
970 sjme_attrInNotNull sjme_lpcstr inStr
,
971 sjme_attrInPositive sjme_jint inLen
)
974 return sjme_error_notImplemented(0);
976 sjme_errorCode error
;
977 sjme_jint c
, fragmentLen
, allocLen
, fieldCount
, fieldAt
;
978 sjme_lpcstr strAt
, strBase
;
979 sjme_desc_fieldTypeLink
* firstField
;
980 sjme_desc_fieldTypeLink
* lastField
;
981 sjme_desc_fieldTypeLink
* currentField
;
982 sjme_jboolean isReturn
, stopNow
;
983 sjme_desc_methodType
* result
;
984 sjme_desc_fieldTypeComponent
* target
;
985 sjme_desc_fieldType
* sourceField
;
986 sjme_desc_fieldTypeComponent
* source
;
988 if (inPool
== NULL
|| outType
== NULL
|| inStr
== NULL
)
989 return SJME_ERROR_NULL_ARGUMENTS
;
992 return SJME_ERROR_INVALID_ARGUMENT
;
994 return SJME_ERROR_INVALID_METHOD_TYPE
;
996 /* First character should be opening parenthesis. */
998 c
= sjme_string_decodeChar(strAt
, &strAt
);
1000 return SJME_ERROR_INVALID_METHOD_TYPE
;
1002 /* Parse each argument. */
1005 currentField
= NULL
;
1006 isReturn
= SJME_JNI_FALSE
;
1007 stopNow
= SJME_JNI_FALSE
;
1013 c
= sjme_string_decodeChar(strAt
, &strAt
);
1014 if ((!stopNow
&& c
< 0) || (stopNow
&& c
>= 0))
1015 return SJME_ERROR_INVALID_METHOD_TYPE
;
1017 /* Stop processing? */
1021 /* End of argument list? */
1024 /* Handle return value now. */
1025 isReturn
= SJME_JNI_TRUE
;
1027 /* Run loop again. */
1031 /* Maximum end of string. */
1032 fragmentLen
= inLen
- (strBase
- inStr
);
1034 /* Determine the allocation size. */
1036 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeAllocSize(
1037 strBase
, fragmentLen
, &allocLen
)) ||
1039 return sjme_error_defaultOr(error
,
1040 SJME_ERROR_INVALID_METHOD_TYPE
);
1043 currentField
= sjme_alloca(sizeof(*currentField
) + allocLen
);
1044 if (currentField
== NULL
)
1045 return sjme_error_outOfMemory(inPool
, allocLen
);
1048 memset(currentField
, 0, allocLen
);
1051 if (firstField
== NULL
)
1053 firstField
= currentField
;
1054 lastField
= currentField
;
1057 /* Link in otherwise. */
1060 lastField
->next
= currentField
;
1061 currentField
->prev
= lastField
;
1062 lastField
= currentField
;
1065 /* Parse single field */
1066 if (sjme_error_is(error
= sjme_desc_interpretFieldTypeFixed(
1067 strBase
, fragmentLen
, ¤tField
->field
,
1068 SJME_JNI_TRUE
, &strAt
)))
1069 return sjme_error_defaultOr(error
,
1070 SJME_ERROR_INVALID_METHOD_TYPE
);
1072 /* Was a parsed field, so count up. */
1075 /* If this was the return value, stop. */
1077 stopNow
= SJME_JNI_TRUE
;
1080 /* If there was never a return type, fail. */
1082 return SJME_ERROR_INVALID_METHOD_TYPE
;
1084 /* Allocate result. */
1085 allocLen
= SJME_SIZEOF_DESC_METHOD_TYPE(fieldCount
);
1086 result
= sjme_alloca(allocLen
);
1088 return sjme_error_outOfMemory(inPool
, allocLen
);
1091 memset(result
, 0, allocLen
);
1093 /* Initialize field list. */
1094 if (sjme_error_is(error
= sjme_list_directInit(fieldCount
,
1095 &result
->fields
, sjme_desc_fieldTypeComponent
, 0)))
1096 return sjme_error_default(error
);
1098 /* Fill in all the various details. */
1099 result
->whole
.pointer
= inStr
;
1100 result
->whole
.length
= strAt
- inStr
;
1101 result
->hash
= sjme_string_hashN(result
->whole
.pointer
,
1102 result
->whole
.length
);
1104 /* Set initial cell base. */
1105 result
->returnCells
= 0;
1106 result
->argCells
= 0;
1108 /* Go through and process each field. */
1109 currentField
= firstField
;
1110 for (fieldAt
= 0; fieldAt
< fieldCount
;
1111 fieldAt
++, currentField
= currentField
->next
)
1113 /* Source field to read from. */
1114 sourceField
= ¤tField
->field
;
1115 source
= &sourceField
->components
[0];
1117 /* Which field is being modified? */
1118 isReturn
= (fieldAt
== fieldCount
- 1);
1119 target
= &result
->fields
.elements
[(isReturn
? 0 : fieldAt
+ 1)];
1121 /* Everything can be copied over quickly. */
1122 memmove(target
, source
,
1123 sizeof(sjme_desc_fieldTypeComponent
));
1125 /* Increase base cells. */
1127 result
->returnCells
= source
->cells
;
1129 result
->argCells
+= source
->cells
;
1133 return sjme_alloc_copyWeak(inPool
, allocLen
,
1134 sjme_nvm_enqueueHandler
, SJME_NVM_ENQUEUE_IDENTITY
,
1135 (void**)outType
, (void*)result
, NULL
);