Elimina i falsi "componenti mancanti" dal rilevamento delle family table
Il record "model_name" veniva preso per l'identita' del file, ma sui file reali nomina quasi sempre un altro modello - tipicamente uno dei membri del file stesso. Il parser esatto rifiutava percio' file perfettamente leggibili, il chiamante ripiegava sull'euristica testuale e quella estraeva codici inesistenti, riportati poi come componenti non trovati nell'indice. Il segnale ora richiede la conferma del nome proprio del modello (objname): scatta solo se il file dichiara davvero se stesso come istanza. Verificato contro le BOM esportate da Creo per 7 assiemi reali: 6 vengono riprodotte byte per byte (3 di queste prima non si generavano affatto), e la settima differisce per una sola parte, presente nella revisione di un sotto-assieme che Creo ha caricato ma assente in quella piu' recente. La verifica di completezza passa su tutti e 7 (prima 3 risultavano incompleti), e tutti i 351 .asm di una cartella raw/ reale si leggono col parser esatto, senza mai ricadere sull'euristica. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b136e7f49b
commit
0ae2a5e7cf
3 files changed
+100
-76
No files matched your search
@@ -37,6 +37,17 @@ public class AsmRecordReaderTests
|
||||
private static byte[] ConfigName(string istanza, int idMembro) =>
|
||||
Bytes(0xe3, "ConfigName", 0, 0xe2, (byte)'3', istanza, 0, idMembro, 0x82, 0x7b);
|
||||
|
||||
// \0objname\0 \xe2 \xe0\x01 object_type\0 <int> \xe0\x0a name\0 <nome>\0 - il nome proprio
|
||||
// del modello (quello che la BOM intesta), vedi docs/formato-asm-record.md §5
|
||||
private static byte[] ObjName(string nome) =>
|
||||
Bytes(0, "objname", 0, 0xe2, 0xe0, 0x01, "object_type", 0, 2, 0xe0, 0x0a, "name", 0, nome, 0);
|
||||
|
||||
// identita' dichiarata dal file: \xe0\x01 model_t_type\0 <int> \xe0\x0a model_name\0 <nome>\0
|
||||
// \xe0\x0a generic_name\0 \0 (vuoto)
|
||||
private static byte[] ModelName(string nome) =>
|
||||
Bytes(0xe0, 0x01, "model_t_type", 0, 2, 0xe0, 0x0a, "model_name", 0, nome, 0,
|
||||
0xe0, 0x0a, "generic_name", 0, 0);
|
||||
|
||||
private static byte[] Asm(int conteggioDichiarato, byte[] membri, byte[]? extra = null) =>
|
||||
Bytes("header ", extra ?? Array.Empty<byte>(), "\0members\0", 0xf1, 0xf8, conteggioDichiarato, membri, "#MdlStatus");
|
||||
|
||||
@@ -131,18 +142,44 @@ public class AsmRecordReaderTests
|
||||
[Fact]
|
||||
public void Assieme_family_table_con_generic_name_lancia_eccezione()
|
||||
{
|
||||
// Regressione: 2546220101.asm (docs/formato-asm-record.md §7) e' esso stesso
|
||||
// un'istanza di family table (model_name "2546220101_C01" + generic_name vuoto); il
|
||||
// suo "members" descrive solo questa rappresentazione, non le 4 istanze reali della
|
||||
// BOM Creo. Va segnalato invece di restituire silenziosamente il contenuto sbagliato.
|
||||
// Regressione: un file che e' esso stesso un'istanza di family table (il suo nome
|
||||
// proprio "2546220101" piu' il suffisso "_C01" in model_name) descrive in "members"
|
||||
// solo quella rappresentazione, non le istanze sorelle. Va segnalato invece di
|
||||
// restituire silenziosamente il contenuto sbagliato (docs/formato-asm-record.md §7).
|
||||
byte[] dati = Asm(1, Membro(1, 2, "9244206098"),
|
||||
extra: Bytes(0xe0, 0x01, "model_t_type", 0, 2,
|
||||
0xe0, 0x0a, "model_name", 0, "2546220101_C01", 0,
|
||||
0xe0, 0x0a, "generic_name", 0, 0));
|
||||
extra: Bytes(ObjName("2546220101"), ModelName("2546220101_C01")));
|
||||
|
||||
Assert.Throws<InvalidDataException>(() => AsmRecordReader.LeggiMembri(dati));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Model_name_di_un_altro_modello_non_lancia_eccezione()
|
||||
{
|
||||
// Regressione: sui file reali della share il record "model_name" nomina spesso un
|
||||
// modello diverso dal file (tipicamente un suo membro), non l'identita' del file. Il
|
||||
// nome proprio (objname) non conferma, quindi non e' il sintomo della family table:
|
||||
// "members" e' corretto e va usato. Verificato contro BOM Creo reali - senza questo
|
||||
// controllo il file cadeva sull'euristica testuale, che produceva codici inesistenti
|
||||
// segnalati poi come "componenti mancanti".
|
||||
byte[] dati = Asm(1, Membro(1, 2, "9044207999A_C01"),
|
||||
extra: Bytes(ObjName("9244207999A"), ModelName("9044207999A_C01")));
|
||||
|
||||
var membri = AsmRecordReader.LeggiMembri(dati);
|
||||
|
||||
Assert.Equal("9044207999A_C01", membri.Single().Nome);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Model_name_senza_nome_proprio_non_lancia_eccezione()
|
||||
{
|
||||
// Stesso caso del test sopra ma senza record "objname" (formato osservato su tutti i
|
||||
// file reali che facevano scattare il falso positivo): senza conferma del nome proprio
|
||||
// il record non e' un'identita', quindi "members" va letto normalmente.
|
||||
byte[] dati = Asm(1, Membro(1, 2, "9244206098"), extra: ModelName("2546220101_C01"));
|
||||
|
||||
Assert.Single(AsmRecordReader.LeggiMembri(dati));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Generic_name_senza_suffisso_istanza_non_lancia_eccezione()
|
||||
{
|
||||
@@ -152,9 +189,7 @@ public class AsmRecordReaderTests
|
||||
// correlato al nome del file). In quei casi "members" e' letto correttamente e va
|
||||
// usato normalmente, non bloccato per un falso positivo.
|
||||
byte[] dati = Asm(1, Membro(1, 2, "9244206098"),
|
||||
extra: Bytes(0xe0, 0x01, "model_t_type", 0, 2,
|
||||
0xe0, 0x0a, "model_name", 0, "9244230117", 0,
|
||||
0xe0, 0x0a, "generic_name", 0, 0));
|
||||
extra: Bytes(ObjName("9244230117"), ModelName("9244230117")));
|
||||
|
||||
var membri = AsmRecordReader.LeggiMembri(dati);
|
||||
|
||||
|
||||
Reference in new issue
Block a user