@@ -138,9 +138,8 @@ public static ParsedCount parseRepeatCount(String template, int position) {
138
138
// Empty brackets - treat as count 0
139
139
result .count = 0 ;
140
140
} else {
141
- // Template-based count - for now, use 1 as fallback
142
- result .count = 1 ;
143
- // TODO: Implement proper template size calculation
141
+ // Template-based count - calculate the size of the template
142
+ result .count = calculateTemplateSize (countStr );
144
143
}
145
144
146
145
result .endPosition = j ;
@@ -329,6 +328,58 @@ private static int countValuesNeeded(String template) {
329
328
return Math .max (count , 10 ); // Ensure we have at least 10 values
330
329
}
331
330
331
+ /**
332
+ * Calculates the total size in bytes of a template string.
333
+ * For use with x[template] and X[template] formats.
334
+ *
335
+ * This method uses the actual Pack.pack method to pack dummy data
336
+ * and measure the resulting size, which handles all complex cases
337
+ * including groups, modifiers, and nested templates correctly.
338
+ *
339
+ * @param template the template string
340
+ * @return the total size in bytes
341
+ */
342
+ private static int calculateTemplateSize (String template ) {
343
+ // Use the actual pack method to calculate the size by packing dummy data
344
+ // This handles all complex cases including groups, modifiers, etc.
345
+ try {
346
+ // Create a RuntimeList with the template and dummy values
347
+ org .perlonjava .runtime .RuntimeList args = new org .perlonjava .runtime .RuntimeList ();
348
+ args .add (new org .perlonjava .runtime .RuntimeScalar (template ));
349
+
350
+ // Count how many values the template needs and add dummy values
351
+ int valueCount = countValuesNeeded (template );
352
+ for (int j = 0 ; j < valueCount ; j ++) {
353
+ // Add dummy values - use 0 for numeric formats
354
+ args .add (new org .perlonjava .runtime .RuntimeScalar (0 ));
355
+ }
356
+
357
+ // Pack with the template and measure the result
358
+ org .perlonjava .runtime .RuntimeScalar result = org .perlonjava .operators .Pack .pack (args );
359
+ return result .toString ().length ();
360
+ } catch (Exception e ) {
361
+ // If packing fails for any reason, fall back to simple calculation
362
+ // This might happen for templates with special requirements
363
+ return calculateTemplateSizeSimple (template );
364
+ }
365
+ }
366
+
367
+ /**
368
+ * Simple fallback calculation for template size.
369
+ * This is used when the pack method fails for some reason.
370
+ */
371
+ private static int calculateTemplateSizeSimple (String template ) {
372
+ // For simple fallback, just count format characters and use default sizes
373
+ int size = 0 ;
374
+ for (int i = 0 ; i < template .length (); i ++) {
375
+ char c = template .charAt (i );
376
+ if (Character .isLetter (c ) && c != 'X' ) { // X is backward, doesn't add size
377
+ size += getFormatSize (c , false );
378
+ }
379
+ }
380
+ return Math .max (size , 1 ); // Return at least 1
381
+ }
382
+
332
383
/**
333
384
* Returns the size in bytes for a given format character.
334
385
*
0 commit comments