00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <QDir>
00030
00031 #include "Archivero.hpp"
00032
00033
00034 extern QDir dir_datos;
00035
00036
00038 Archivero::Archivero () : ccache (TAM_CCACHE * 1024), rcache (TAM_RCACHE * 1024)
00039 {
00040 }
00041
00043 Archivero::~Archivero ()
00044 {
00045 qDebug ("Destructor de Archivero");
00046 }
00047
00064 QString Archivero::BuscaPropiedad (const QString &nom_ent,
00065 const QString &nom_prop)
00066 {
00067 QStringList lista_ents;
00068
00069 QDomDocument documento ("entidad");
00070 QDomNode nodo;
00071 QDomElement elemento;
00072 QDomAttr atributo;
00073
00074
00075 lista_ents += nom_ent;
00076
00077 for (QStringList::Iterator iter = lista_ents.begin();
00078 iter != lista_ents.end(); ++iter)
00079 {
00080 if (!CargaDocumento (documento, *iter))
00081 return (QString::null);
00082
00083
00084
00085 elemento = documento.documentElement();
00086 nodo = elemento.firstChild();
00087 while (!nodo.isNull())
00088 {
00089 elemento = nodo.toElement();
00090 if (!elemento.isNull())
00091 {
00092 if (elemento.tagName() != "herencia")
00093 {
00094 atributo = elemento.attributeNode ("nombre");
00095
00096 if ((atributo.value().length() == nom_prop.length()) &&
00097 (atributo.value().startsWith (nom_prop, Qt::CaseInsensitive)))
00098 {
00099
00100 return (*iter);
00101 }
00102 }
00103 else
00104 {
00105 atributo = elemento.attributeNode ("entidad");
00106
00107
00108
00109 if (!lista_ents.contains (atributo.value(),
00110 Qt::CaseInsensitive))
00111 lista_ents += atributo.value();
00112 }
00113 }
00114 nodo = nodo.nextSibling();
00115 }
00116 }
00117
00118
00119 qWarning ("La entidad \"%s\" no dispone de la propiedad \"%s\"",
00120 nom_ent.toLatin1().constData(), nom_prop.toLatin1().constData());
00121
00122 return (QString::null);
00123 }
00124
00126
00134 bool Archivero::CargaDocumento (QDomDocument &documento, const QString &nom_ent)
00135 {
00136
00137
00138 QStringList lista (dir_datos.entryList (QDir::Files).filter (nom_ent + ".xml",
00139 Qt::CaseInsensitive));
00140
00141 QStringList::iterator iter (lista.begin());
00142
00143 for ( ; iter != lista.end(); ++iter)
00144 if ((*iter).length() == (nom_ent.length() + 4))
00145
00146 break;
00147
00148 if (iter == lista.end())
00149 {
00150 qWarning ("No se ha encontrado el fichero \"%s\"", dir_datos.filePath
00151 (nom_ent + ".xml").toLatin1().constData());
00152 return (false);
00153 }
00154
00155 QFile fichero (dir_datos.filePath (*iter));
00156
00157 if (!fichero.open (QIODevice::ReadOnly | QIODevice::Text))
00158 {
00159
00160 qWarning ("\"%s\": %s", fichero.fileName().toLatin1().constData(),
00161 fichero.errorString().toLatin1().constData());
00162 return (false);
00163 }
00164
00165 QString dsc_error;
00166 int lin_error, col_error;
00167
00168 if (!documento.setContent (&fichero, &dsc_error, &lin_error, &col_error))
00169 {
00170 fichero.close();
00171
00172 qWarning ("\"%s\" (%d, %d): %s", fichero.fileName().toLatin1().constData(),
00173 lin_error, col_error, dsc_error.toLatin1().constData());
00174
00175 return (false);
00176 }
00177
00178 fichero.close();
00179 return (true);
00180 }
00181
00183
00192 unsigned char Archivero::DaModoPropiedad (const QString &nom_ent,
00193 const QString &nom_prop)
00194 {
00195 const Propiedad *prop = ObtenPropiedad (nom_ent, nom_prop);
00196
00197 if (prop != NULL)
00198 return (prop->modo);
00199 else
00200 return ((unsigned char) -1);
00201 }
00202
00204
00213 unsigned char Archivero::DaTipoPropiedad (const QString &nom_ent,
00214 const QString &nom_prop)
00215 {
00216 const Propiedad *prop = ObtenPropiedad (nom_ent, nom_prop);
00217
00218 if (prop != NULL)
00219 return (prop->tipo);
00220 else
00221 return ((unsigned char) -1);
00222 }
00223
00225
00234 QString Archivero::DaPropiedad (const QString &nom_ent,
00235 const QString &nom_prop)
00236 {
00237 const Propiedad *prop = ObtenPropiedad (nom_ent, nom_prop);
00238
00239 if (prop != NULL)
00240 return (*(prop->contenido));
00241 else
00242 return (QString::null);
00243 }
00244
00246
00254 Archivero::Propiedad *Archivero::LeePropiedad (const QString &nom_ent,
00255 const QString &nom_prop)
00256 {
00257 Propiedad *propiedad = NULL;
00258
00259 QDomDocument documento ("entidad");
00260 QDomNode nodo;
00261 QDomElement elemento;
00262 QDomAttr atributo;
00263 QDomText texto;
00264
00265 if (!CargaDocumento (documento, nom_ent))
00266 return (NULL);
00267
00268 elemento = documento.documentElement();
00269 nodo = elemento.firstChild();
00270 while (!nodo.isNull())
00271 {
00272 elemento = nodo.toElement();
00273 if ((!elemento.isNull()) && (elemento.tagName() != "herencia"))
00274 {
00275 atributo = elemento.attributeNode ("nombre");
00276
00277 if ((atributo.value().length() == nom_prop.length()) &&
00278 (atributo.value().startsWith (nom_prop, Qt::CaseInsensitive)))
00279 {
00280
00281 propiedad = new Propiedad (nom_ent, nom_prop);
00282
00283 if (elemento.tagName() == "rutina")
00284 propiedad->modo = MODO_RUTINA;
00285 else
00286 propiedad->modo = MODO_VARIABLE;
00287
00288 atributo = elemento.attributeNode ("tipo");
00289 if (atributo.value() == "booleano")
00290 propiedad->tipo = TIPO_BOOLEANO;
00291 else if (atributo.value() == "entero")
00292 propiedad->tipo = TIPO_ENTERO;
00293 else if (atributo.value() == "cadena")
00294 propiedad->tipo = TIPO_CADENA;
00295 else
00296 propiedad->tipo = TIPO_NADA;
00297
00298 propiedad->contenido = new QString;
00299
00300 nodo = nodo.firstChild();
00301 while (!nodo.isNull())
00302 {
00303 texto = nodo.toText();
00304 if (!texto.isNull())
00305 propiedad->contenido->append (texto.data());
00306
00307 nodo = nodo.nextSibling();
00308 }
00309 break;
00310 }
00311 }
00312 nodo = nodo.nextSibling();
00313 }
00314
00315 if (propiedad == NULL)
00316 return (NULL);
00317
00318
00319 if (propiedad->modo == MODO_RUTINA)
00320 {
00321 *(propiedad->contenido) = FiltroLecturaRutina (*(propiedad->contenido));
00322 }
00323 else if (propiedad->tipo == TIPO_CADENA)
00324 {
00325 bool error;
00326
00327 *(propiedad->contenido) = FiltroLecturaCadena (*(propiedad->contenido),
00328 error);
00329
00330 if (error)
00331 qWarning ("\"%s\": Uso incorrecto de \"\\\" en la cadena \"%s\"",
00332 nom_ent.toLatin1().constData(),
00333 nom_prop.toLatin1().constData());
00334 }
00335 else if (propiedad->tipo == TIPO_ENTERO)
00336 {
00337 bool error;
00338
00339 *(propiedad->contenido) = FiltroLecturaEntero (*(propiedad->contenido),
00340 error);
00341
00342 if (error)
00343 qWarning ("\"%s\": Formato incorrecto del entero \"%s\"",
00344 nom_ent.toLatin1().constData(),
00345 nom_prop.toLatin1().constData());
00346 }
00347 else
00348 {
00349 bool error;
00350
00351 *(propiedad->contenido) = FiltroLecturaBooleano (*(propiedad->contenido),
00352 error);
00353
00354 if (error)
00355 qWarning ("\"%s\": Formato incorrecto del booleano \"%s\"",
00356 nom_ent.toLatin1().constData(),
00357 nom_prop.toLatin1().constData());
00358 }
00359
00360 propiedad->contenido->squeeze();
00361
00362 return (propiedad);
00363 }
00364
00366
00374 const Archivero::Propiedad *Archivero::ObtenPropiedad (const QString &nom_ent,
00375 const QString &nom_prop)
00376 {
00377
00378 QString clave (nom_ent + ">" + nom_prop);
00379
00380
00381 QString *ent_fisica = rcache.object (clave);
00382
00383 if (ent_fisica == 0)
00384 {
00385 ent_fisica = new QString (BuscaPropiedad (nom_ent, nom_prop));
00386 if (ent_fisica->isNull())
00387 {
00388 delete (ent_fisica);
00389 return (NULL);
00390 }
00391 rcache.insert (clave, ent_fisica, ent_fisica->length());
00392 }
00393
00394 if (*ent_fisica != nom_ent)
00395 clave = (*ent_fisica + ">" + nom_prop);
00396
00397
00398 Propiedad *propiedad = ccache.object (clave);
00399
00400 if (propiedad == 0)
00401 {
00402 propiedad = LeePropiedad (*ent_fisica, nom_prop);
00403 if (propiedad == NULL)
00404 {
00405
00406
00407 qDebug ("Archivero::ObtenPropiedad(): LeePropiedad() ha devuelto NULL");
00408 return (NULL);
00409 }
00410 ccache.insert (clave, propiedad, propiedad->contenido->length());
00411 }
00412
00413 return (propiedad);
00414 }
00415
00416
00417
00418
00420 Archivero::Propiedad::Propiedad (const QString &nom_ent,
00421 const QString &nom_prop) : entidad (nom_ent),
00422 nombre (nom_prop)
00423 {
00424 modificada = 0;
00425 }
00426
00428 Archivero::Propiedad::~Propiedad ()
00429 {
00430 qDebug ("Destructor de Archivero::Propiedad");
00431
00432 if (modificada)
00433 GuardaPropiedad();
00434
00435 delete (contenido);
00436 }
00437
00439 void Archivero::Propiedad::GuardaPropiedad ()
00440 {
00441 }
00442
00443
00444
00445
00447
00454 QString FiltroLecturaBooleano (const QString &original, bool &error)
00455 {
00456 QString filtrado ("F");
00457
00458 bool hay_booleano = false;
00459
00460 error = false;
00461
00462 const unsigned long longitud = original.length();
00463
00464 for (unsigned long i = 0; i < longitud; i++)
00465 {
00466 switch (original.at (i).toLatin1())
00467 {
00468 case ' ' :
00469 case '\n':
00470 case '\r':
00471 case '\t':
00472 break;
00473
00474 case 'V':
00475 if (hay_booleano || ((i + 8) > longitud) ||
00476 (original.at (i + 1) != 'E') ||
00477 (original.at (i + 2) != 'R') ||
00478 (original.at (i + 3) != 'D') ||
00479 (original.at (i + 4) != 'A') ||
00480 (original.at (i + 5) != 'D') ||
00481 (original.at (i + 6) != 'E') ||
00482 (original.at (i + 7) != 'R') ||
00483 (original.at (i + 8) != 'O'))
00484 error = true;
00485 else
00486 {
00487 hay_booleano = true;
00488 filtrado = "V";
00489 }
00490 break;
00491
00492 case 'F':
00493 if (hay_booleano || ((i + 5) > longitud) ||
00494 (original.at (i + 1) != 'A') ||
00495 (original.at (i + 2) != 'L') ||
00496 (original.at (i + 3) != 'S') ||
00497 (original.at (i + 4) != 'O'))
00498 error = true;
00499 else
00500 hay_booleano = true;
00501 break;
00502
00503 default:
00504 error = true;
00505 }
00506 if (error)
00507 break;
00508 }
00509
00510 return (filtrado);
00511 }
00512
00514
00521 QString FiltroLecturaCadena (const QString &original, bool &error)
00522 {
00523 QString filtrado;
00524
00525 bool hay_espacio = false;
00526 bool omitir_espacio = true;
00527
00528
00529 error = false;
00530
00531 const unsigned long longitud = original.length();
00532 const char *cadena = original.toLatin1().constData();
00533
00534 for (unsigned long i = 0; i < longitud; i++)
00535 {
00536 switch (cadena[i])
00537 {
00538 case ' ' :
00539 case '\n':
00540 case '\r':
00541 case '\t':
00542 hay_espacio = true;
00543 break;
00544
00545 case '\\':
00546 switch (cadena[i + 1])
00547 {
00548 case 'n':
00549 filtrado += '\n';
00550 omitir_espacio = true;
00551 break;
00552
00553 case 't':
00554 filtrado += '\t';
00555 omitir_espacio = true;
00556 break;
00557
00558 case ' ':
00559 filtrado += ' ';
00560 omitir_espacio = true;
00561 break;
00562
00563 case '\\':
00564 if ((!omitir_espacio) && (hay_espacio))
00565 {
00566 filtrado += ' ';
00567 }
00568 filtrado += '\\';
00569 hay_espacio = false;
00570 omitir_espacio = false;
00571 break;
00572
00573 case '0':
00574 case '1':
00575 if ((cadena[i + 2] < '0') || (cadena[i + 2] > '9') ||
00576 (cadena[i + 3] < '0') || (cadena[i + 3] > '9'))
00577 error = true;
00578 else
00579 {
00580 filtrado += ((cadena[i + 1] - '0') * 100) +
00581 ((cadena[i + 2] - '0') * 10) +
00582 (cadena[i + 3] - '0');
00583 hay_espacio = false;
00584 omitir_espacio = false;
00585 }
00586 i += 2;
00587 break;
00588
00589 case '2':
00590 if ((cadena[i + 2] < '0') || (cadena[i + 2] > '5') ||
00591 (cadena[i + 3] < '0') ||
00592 (cadena[i + 3] > ((cadena[i + 2] == '5') ? '5' : '9')))
00593 error = true;
00594 else
00595 {
00596 filtrado += 200 + ((cadena[i + 2] - '0') * 10) +
00597 (cadena[i + 3] - '0');
00598 hay_espacio = false;
00599 omitir_espacio = false;
00600 }
00601 i += 2;
00602 break;
00603
00604 default:
00605 error = true;
00606 }
00607 i += 1;
00608 break;
00609
00610 default:
00611 if ((!omitir_espacio) && (hay_espacio))
00612 filtrado += ' ';
00613 filtrado += cadena[i];
00614 hay_espacio = false;
00615 omitir_espacio = false;
00616 }
00617 }
00618
00619 return (filtrado);
00620 }
00621
00623
00630 QString FiltroLecturaEntero (const QString &original, bool &error)
00631 {
00632 QString filtrado = "0";
00633
00634 bool hay_numero = false;
00635 bool fin_numero = false;
00636 bool negativo = false;
00637 error = false;
00638
00639 const unsigned long longitud = original.length();
00640
00641 for (unsigned long i = 0; i < longitud; i++)
00642 {
00643 switch (original.at (i).toLatin1())
00644 {
00645 case ' ' :
00646 case '\n':
00647 case '\r':
00648 case '\t':
00649 if (hay_numero)
00650 fin_numero = true;
00651 break;
00652
00653 case '+':
00654 if (hay_numero)
00655 error = true;
00656 break;
00657
00658 case '-':
00659 if (hay_numero)
00660 error = true;
00661 else
00662 negativo = !negativo;
00663 break;
00664
00665 default:
00666 if (fin_numero || (original.at (i) < '0') || (original.at (i) > '9'))
00667 error = true;
00668 else if (hay_numero)
00669 filtrado += original.at (i);
00670 else if (original.at (i) != '0')
00671 {
00672 filtrado = original.at (i);
00673 if (negativo)
00674 filtrado.prepend ('-');
00675 hay_numero = true;
00676 }
00677 }
00678 if (error)
00679 break;
00680 }
00681
00682 return (filtrado);
00683 }
00684
00686
00691 QString FiltroLecturaRutina (const QString &original)
00692 {
00693 QString filtrado;
00694
00695 bool hay_espacio = false;
00696 bool omitir_espacio = true;
00697
00698
00699 const unsigned long longitud = original.length();
00700
00701 for (unsigned long i = 0; i < longitud; i++)
00702 {
00703 switch (original.at (i).toLatin1())
00704 {
00705 case ' ' :
00706 case '\t':
00707 hay_espacio = true;
00708 break;
00709
00710 case '\n':
00711 case '\r':
00712
00713 if (!omitir_espacio)
00714 {
00715 filtrado += '\n';
00716 omitir_espacio = true;
00717 }
00718 break;
00719
00720 default:
00721 if ((!omitir_espacio) && (hay_espacio))
00722 filtrado += ' ';
00723 filtrado += original.at (i);
00724 hay_espacio = false;
00725 omitir_espacio = false;
00726 }
00727 }
00728
00729 return (filtrado);
00730 }
00731
00733 QString FiltroEscrituraBooleano (const QString &original)
00734 {
00735 QString filtrado;
00736
00737 return (filtrado);
00738 }
00739
00741 QString FiltroEscrituraCadena (const QString &original)
00742 {
00743 QString filtrado;
00744
00745 return (filtrado);
00746 }
00747
00749 QString FiltroEscrituraEntero (const QString &original)
00750 {
00751 QString filtrado;
00752
00753 return (filtrado);
00754 }
00755
00757 QString FiltroEscrituraRutina (const QString &original)
00758 {
00759 QString filtrado;
00760
00761 return (filtrado);
00762 }