a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
record.hpp
gehe zur Dokumentation dieser Datei
1 // record.hpp : Datensatz im Arbeitsspeicher
2 // 1995-08-19 Datensatz, Struktur und Manipulation im Arbeitsspeicher
3 // Copyright 2011 Universitätsbibliothek Braunschweig, more see bottom
4 
5 // (Lesen und Speichern siehe ABASEW.CPP)
6 // Klasse RECORD (c) UB Braunschweig 1995/2003
7 
8 // Setzt die Klasse KONFIG voraus
9 
10 // Ein Objekt RECORD wird gebraucht, um einen Datensatz darzustellen
11 // und zu manipulieren
12 // Einlesen aus und Speichern in einer Datenbank leistet Klasse ABASE
13 // Ein RECORD kann an ein Objekt EXET uebergeben werden zwecks Export
14 
15 // RECORD wird benoetigt von der Klasse EXET (und damit auch von den
16 // erweiterten Klassen INDEX und ABASE.
17 
18 
19 #ifndef __ALLEGRO
20 #include "allegro.hpp" // globale Konstanten und Variablen
21 #endif
22 
23 #ifndef __RECORD
24 #define __RECORD
25 #define WSPACE 64000 // max. Feldlaenge (vorher 32000)
26 // bezieht sich auf das Eingabefeld; wieviel ein Satz verkraften kann,
27 // steht auf einem anderen Blatt...
28 
29 // Ein Objekt der Klasse KONFIG wird gebraucht:
30 
31 #include "konfig.hpp"
32 
33 // ************* KLASSENBESCHREIBUNG
34 
35 class RECORD
36 {
37  //===========//
38 public: // Variablen // %% Hinweise auf die aelteren DOS-Variablen
39  //===========//
40 
41  CHAR *g ; // Basisadresse der Datenfelder [general data address]
42  CHAR **ga ; // Adressenarray f.d. Datenfelder, ga[0] = g [general array for data]
43  int *gi ; // Array der internen Nummern der Felder gemaess Konfiguration [general internal numbers of fields]
44  // z.B. #u1 hat hier die Nr. 0, #00 die 2
45  int cri ; // Position der 1. Kat. d. aktuellen Satzes in ga[] [current rec index in ga; pos. of 1st field]
46  // normal: 0, nur bei Untersaetzen waehrend Export >0
47  int gri ; // Anzahl Felder des Satzes
48  CHAR *gend ; // Endadresse der Daten in g (hinter letztem Byte) [ g end address]
49 
50  int mri ; // markiertes Feld; Adresse: ga[mri] [marked rec index]
51  // i.d.R. die #01, die mit Alt+m markiert wurde
52  // Fuer Editor-Zwecke. Bleibt auf dem gewaehlten
53  // Feld auch bei Verschiebungen per Ins/Del
54 
55  int Adn ; // logische Nr. der Datenbank (0,1,2,3) zu der der Satz gehoert %% Adb
56  // -1 wenn rec nicht zu einer Datenbank gehoert
57  // globale Variable ABASE Abase[Adn] ist Adresse des Db-Objekts
58  int rFi ; // Nr. der .ALD-Datei d. Satzes %% filenmb
59  long rOf ; // OffsetPosition innerhalb .ALD-Datei %% rad
60  long rNr ; // Satznummer, 0 = neu %% recn
61  int rLg ; // Satzlaenge in der Datei %% rlg
62  int rSt ; // Status %% rstat
63  // (0=neu,1=normal,2=reserviert,8=gesperrt,9=geloescht)
64 
65  KONFIG *kfg ; // pointer auf das zustaendige KONFIG-Objekt
66  char schema; // Konfig.Buchstabe, z.B. a
67 
68 // Nur fuer die Indexierung (wird z.B. in Reserve() gefuellt:
69  int rKx ; // Anzahl Schluessel %% okn
70  CHAR *rKy[1000]; // Adressenliste der Schluessel %% oldkeys[]
71  CHAR *rKbase; // Basisadresse fuer Schluessel
72  // Platzzuteilung erfolgt in index.cpp
73  char rKf[1000]; // flags: 0=key valid / 1=not valid %% okf
74  // bei 1 muss der Schl. geloescht werden
75  long rNa ; // additional, for #nra (nachgeladener Satz) $$981109
76  // Nur >0, wenn gerade einer nachgeladen wurde
77 
78  CHAR *Wsp2 ; // 2. Haelfte von Wspace, Hilfsvar f. UTF-Wandlung
79 
80  char editdate[48];// letztes Aenderungsdatum (z.B. f. a99 Reservespeicher) // $$20120118 48 statt 18
81 
82 /*
83  Am wichtigsten ist der Array ga[], der die Anfangsadressen der Datenfelder
84  im Arbeitsspeicher enthält. Es kann darin mehrere aufeinanderfolgende
85  Datensätze geben (z.B. bei Nachladungen). Ein weiterer (auch der erste)
86  beginnt jeweils mit der Zeichenfolge 29 01, diese Zeichen stehen also
87  i.d.R. unmittelbar vor der Zeichenfolge #00 des ersten Feldes. Ein
88  hierarchischer Untersatz beginnt dagegen mit 29 02, darauf folgt "#01",
89  bzw. mit 29 03, darauf folgt "#02", usw. Das jeweils erste Feld eines
90  Satzes oder Untersatzes beginnt also nicht mit '#', sondern mit Code 29
91  und dem Hierarchiebyte. Das ist beim Umgang mit ga[] sehr wichtig.
92  Der Array gi[] enthält die internen Nummern der Felder laut CFG, wobei
93  #u1 und #u2 die Nummern 1 und 2 haben, #00 dann die 3 usw. Dieser Array
94  dient der schnellen Suche nach einem Feld und der internen Sortierung (denn
95  die CFG-Reihenfolge muss keine numerisch aufsteigende sein!
96 */
97  //============//
98 public: // Methoden //
99  //============//
100 
101 // ************* Konstruktor:
102 
103  RECORD(KONFIG *cfg, unsigned int gsp=0, int gd=0, int wsp=0);
104 
105  // cfg = ein Objekt KONFIG, muss vorher angelegt werden
106  // Defaults fuer folgende Werte werden aus CFG uebernommen,
107  // wenn nicht angegeben oder 0 angegeben:
108  // gsp = max. Groesse des Speichers fuer Felder,
109  // gd = max. Zahl der Felder eines Satzes
110  // wsp = max. Groesse eines Feldes (default WSPACE)
111 
112  // Fehler: Aerror enthaelt eine Meldung, sonst Aerror == ""
113  // (Konstruktor kann kein "return xyz" machen)
114  // Beispiel: KONFIG *kfg = new KONFIG("A","C:\\ALLEGRO\\DEMO");
115  // RECORD *satz = new RECORD(kfg); // Standard!
116  // RECORD *rec = new RECORD(kfg,10000,0,2000);
117  // RECORD *dummy = new RECORD(kfg,100,10,300);
118  // Fuer Hilfszwecke kann es sinnvoll sein, kleine Werte zu nehmen, wenn
119  // mit dem Objekt nicht wirklich viel zu tun ist
120 
121 // Destruktor
122  ~RECORD();
123 
124 
125 // *****************
126 // Sonstige Methoden (weitere Hinweise siehe in record.cpp)
127 
128 // ------------------------------------------------------------
129 // Positionsnr. eines Feldes innerhalb des Array ga[] im RECORD bestimmen:
130 
131  int Pos(FLD *, int md=0); // %% kat_pos(CHAR *);
132  // return: interne Position der Kategorie im ga[]-Array
133  // -1 wenn nicht vorhanden
134 
135  // Beispiel: i=rec->Pos("#123");
136  // Ergebnis: rec->ga[i] ist die Adresse des Feldes
137  // und zwar des Zeichens '#'
138  // md == 1 : ganzen hierarchischen Satz durchsuchen, incl. Untersaetze
139  // 0 : nur aktuellen Satz ab Position cri, Untersaetze nicht
140 
141 // ------------------------------------------------------------
142 // absolute String-Adresse des Feldtextes bestimmen:
143 
144  CHAR *Adr(FLD *,int md=0); // %% kat_adr(CHAR *);
145  // return: Adresse des Feldtextes (erstes Textzeichen des Inhalts!)
146  // NULL wenn Feld nicht vorhanden
147 
148  // Beispiel: adr=rec->Adr("#123");
149  // Ergebnis: adr ist die Adresse des Feldtextes (!)
150  // also des Zeichens hinter #123
151  // adr-kfg->skt ist die Adresse von '#'
152  // md wie bei Pos()
153 
154 // ------------------------------------------------------------
155 // absolute String-Adresse eines Unterfeldtextes bestimmen:
156 // Adresse eines UnterFelds (z.B. AdrSf("#96a$u")
157 // und auf Wunsch kopieren (z.B. AdrSf("#98a$u",kopie,10) // 10 zeichen
158 // AdrSf("#98a$u",kopie) // ganzes Unterfeld
159 // Achtung: dann muss kopie lang genug sein!
160 
161  CHAR *AdrSf(CHAR *ufd,CHAR *kopie=0, int lgth=0);
162  // return: Adresse des ersten Zeichens des Unterfeldtextes von $u in #96a
163  // NULL wenn nicht vorhanden
164  // Beispiele: adr=AdrSf(#90$u) Text von $u in #90
165  // adr=AdrSf(#123$$); Text von #123 VOR allen Unterfeldern
166 
167 // ------------------------------------------------------------
168 // Ein Feld in den Datensatz einsortieren
169 
170  int Ins(FLD *); // %% kat_ins(CHAR *);
171  // return: Position, an der das Feld eingeordnet wurde
172  // -1 wenn Feld fehlerhaft, Fehlermeldung in Aerror
173  // z.B. unerlaubte Wiederholung, Feld nicht aenderbar
174  // d.h. der Felddeskriptor in der CFG wird verwendet
175  // Beispiel: rec->Ins("#123 Text");
176 
177 
178 // ------------------------------------------------------------
179 // Ein Feld aus dem Satz loeschen
180 
181  int Del(FLD *); // %% rdelete(i,i+1);
182  // return: Position, wo sich das Feld befand
183  // komplettes Feld steht dann in Aerror, falls man es braucht
184  // -1 wenn nicht gefunden (Aerror leer)
185  // Beispiel: rec->Del("#123");
186 
187 
188 // ------------------------------------------------------------
189 // PartDelete : Mehrere Felder aus dem Satz loeschen
190 
191  int PartDel(int i ,int j); // %% rdelete(i,j);
192  // loesche die Felder i bis j-1
193  // Bedingungen: i,j > 0, j>i, i,j<=rec->gri
194  // Special case : j==-1 : from i to end of rec (= gri)
195  // return: 0 if not possible, 1:done
196  // Beispiele: i=rec->Pos("#81");
197  // j=rec->Pos("#90");
198  // PartDel(i,j+1); // Felder #81 bis incl. #90 loeschen
199 
200 // ------------------------------------------------------------
201 // Search+Replace innerhalb eines Satzes:
202 
203  CHAR *SrRp(CHAR *a,CHAR *b,int ,int ,int ); // srch (+repl)
204  // suche a im Bereich b
205 
206 // field-specific srch&repl in current rec
207  CHAR *FSrRp(CHAR *a,int); // md=1: repl 0:not
208  // a="*#nn_abc_XYZ_" : Im Feld #nn die Sequenz abc durch XYZ ersetzen
209 
210 // Hierarchische Untersatze
211  int SubPos(CHAR *); // Position eines Untersatzes bestimmen
212  // und diesen zum aktuellen Satz machen
213 
214  int SubDel(CHAR *); // Untersatz loeschen ab angegebener Kategorie
215 
216  int SubDel(int ); // Untersatz loeschen ab einer Position
217 
218  int SubCopy(int, RECORD *, int, int md=0); // Untersatz kopieren
219 
220  int SubMove(int, RECORD *, int); // Untersatz verschieben
221 
222  int SubNxt(int); // naechsten Untersatz finden, ab Position int
223  // return -1 wenn keiner mehr kommt, nicht-zyklisch
224 
225  int SubPre(int); // vorigen Untersatz finden, ab Position int
226  // return -1 wenn es keinen Untersatz gibt,
227  // zyklisch: wenn (0), dann Pos. des letzten
228 
229 
230 // ========================================================================
231 
232  int Reserve(); // Satz zum Bearbeiten reservieren
233  // incl. blockieren und aktuelle Schluessel bestimmen
234 
235  int Release(); // wieder freigeben
236 
237  void Copy(RECORD *); // Inhalt aus anderem Satz kopieren
238 
239  void Empty(); // reset rec as if new
240 
241 // UTF-8 in intern wandeln, u-Befehle normalerweise in Indexparam.
242  void UTFcode(CHAR *ft, CHAR *gt); // ft (UTF) -> gt (Internal)
243 
244 // ========================================================================
245 
246 private:
247 
248  CHAR *Wspace; // Workspace, Eingabetext landet hier
249 
250 // Hilfsfunktion zum Einordnen von Wspace in den Satz
251  int ginst(int); // %% ginst(int);
252 // %% das ist die alte Funktion aus acore.c, fuer die String-Array-Operation
253 
254 // ========================================================================
255 
256 }; // end RECORD class
257 
258 #endif // zu #ifndef RECORD
259 
260 /*
261  Copyright 2011 Universitätsbibliothek Braunschweig
262 
263  Licensed under the Apache License, Version 2.0 (the "License");
264  you may not use this file except in compliance with the License.
265  You may obtain a copy of the License at
266 
267  http://www.apache.org/licenses/LICENSE-2.0
268 
269  Unless required by applicable law or agreed to in writing, software
270  distributed under the License is distributed on an "AS IS" BASIS,
271  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
272  See the License for the specific language governing permissions and
273  limitations under the License.
274 */
275