cdesktopenv/cde/lib/DtMmdb/schema/object_dict.C

543 lines
12 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $XConsortium: object_dict.C /main/7 1996/09/13 20:48:20 cde-hal $
*
* Copyright (c) 1993 HAL Computer Systems International, Ltd.
* All rights reserved. Unpublished -- rights reserved under
* the Copyright Laws of the United States. USE OF A COPYRIGHT
* NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE.
*
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
* SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE,
* DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
* PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
* INTERNATIONAL, LTD.
*
* RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject
* to the restrictions as set forth in subparagraph (c)(l)(ii)
* of the Rights in Technical Data and Computer Software clause
* at DFARS 252.227-7013.
*
* HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
* 1315 Dell Avenue
* Campbell, CA 95008
*
*/
#include "schema/object_dict.h"
#include "utility/randomize.h"
#include "utility/db_version.h"
#include "misc/unique_id.h"
desc* desc_ptr = 0;
desc* last_desc_ptr = 0;
char replace_string[PATHSIZ];
int replace_string_len;
//extern int yyparse();
//extern int yyrestart(FILE*);
//extern FILE *yyin;
extern int schemaparse();
extern void schemarestart(FILE*);
extern FILE *schemain;
object_dict::object_dict() :
v_dict(desc_name_eq, desc_name_ls), v_desc_ptr(0), v_last_desc_ptr(NULL)
{
v_db_path[0] = 0;
}
object_dict::~object_dict()
{
quit_a_base(v_desc_ptr, 0, true);
}
void object_dict::quit_a_base(desc* b, desc* e, Boolean sync)
{
_quit_stored_objects(b, e);
_quit_stores(b, e, sync);
_quit_descs(b, e);
}
void object_dict::_quit_descs(desc* begin_ptr, desc* end_ptr)
{
desc *ptr = begin_ptr;
desc *x_ptr = 0;
while ( ptr != end_ptr ) {
x_ptr = ptr;
ptr = ptr -> next_desc;
delete x_ptr;
}
}
extern int g_mode_8_3;
desc* object_dict::init_a_base(char* db_path, char* db_name)
{
//MESSAGE(cerr, "object_dict::init_a_base()");
//debug(cerr, db_path);
int len = MIN(strlen(db_path), PATHSIZ - 1);
*((char *) memcpy(v_db_path, db_path, len) + len) = '\0';
desc* x = 0;
char* schema_path = 0;
if ( g_mode_8_3 )
schema_path = form("%s/%s.%s", v_db_path, db_name, SCHEMA_FILE_SUFFIX);
else
schema_path = form("%s/%s", v_db_path, SCHEMA_FILE);
fstream in(schema_path, ios::in);
if ( !in )
throw(streamException(in.rdstate()));
char schema_header[LBUFSIZ];
if ( !in.getline(schema_header, LBUFSIZ) ) {
throw(streamException(in.rdstate()));
}
if ( strncmp(schema_header+1, "MMDB", 4) != 0 ) {
in.close();
x = parse(schema_path);
} else {
unsigned int sz = bytes(schema_path) - strlen(schema_header) - 1;
char* buf = new char[sz];
if ( !in.read(buf, sz) )
throw(streamException(in.rdstate()));
in.close();
buffer orig(0);
orig.set_chunk(buf, sz);
orig.set_content_sz(sz);
randomize rd(233);
rd.restore(orig);
//fprintf(stderr, "buf=%s\n", buf);
//debug(cerr, buf);
////////////////
// do the parse
////////////////
x = parse(orig);
delete [] buf;
}
_init(x);
return x;
}
desc* object_dict::init_a_base(char* define_desc_path, char* db_path,
char* db_name)
{
//MESSAGE(cerr, "object_dict::init a base (define case)");
//debug(cerr, define_desc_path);
//debug(cerr, db_path);
//debug(cerr, db_name);
int len;
len = MIN(strlen(db_path), PATHSIZ - 1);
*((char *) memcpy(v_db_path, db_path, len) + len) = '\0';
if ( db_name ) {
len = MIN(strlen(db_name), PATHSIZ - 1);
*((char *) memcpy(replace_string, db_name, len) + len) = '\0';
replace_string_len = strlen(replace_string);
} else {
replace_string[0] = 0;
replace_string_len = 0;
}
fstream in_test(define_desc_path, ios::in);
if ( ! in_test ) {
throw(stringException(form("%s does not exist.", define_desc_path)));
}
unsigned long llen = bytes(define_desc_path)*4;
in_test.close();
if ( disk_space(v_db_path) < llen ) {
throw(stringException(form("no enough space on %s", v_db_path)));
}
///////////////////////////////////
// define and init the dictionary
///////////////////////////////////
desc* x = parse(define_desc_path);
_init(x);
////////////////////////////
// randomize the schema.mmdb
////////////////////////////
fstream in(define_desc_path, ios::in);
if ( !in) {
debug(cerr, define_desc_path);
throw(streamException(in.rdstate()));
}
unsigned int sz = bytes(define_desc_path);
in.close();
char* schema_buf = new char[sz*3];
ostringstream* string_out = new ostringstream(schema_buf);
if ( !(*string_out) ) {
throw(streamException(string_out -> rdstate()));
}
x -> asciiOutList(*string_out);
len = MIN((unsigned int) string_out->str().size(), sz*3 - 1);
*((char *) memcpy(schema_buf, string_out->str().c_str(), len) + len) = '\0';
delete string_out;
sz = strlen(schema_buf);
buffer orig(0);
orig.set_chunk(schema_buf, sz);
orig.set_content_sz(sz);
randomize rd(233);
rd.scramble(orig);
/////////////////////////////
// save the output to db_path
/////////////////////////////
fstream out(form("%s/%s.%s", db_path, db_name, SCHEMA_FILE_SUFFIX), ios::out);
// fstream out(form("%s/%s.%s", db_path, db_name, SCHEMA_FILE_SUFFIX), ios::out, open_file_prot());
if ( !out ) {
MESSAGE(cerr, form("bad file name: %s", db_path));
throw(streamException(out.rdstate()));
}
char* desc_header = form("#MMDB\t%d\t%d\n", MAJOR, MINOR);
if ( !out.write(desc_header, strlen(desc_header)) ) {
MESSAGE(cerr, form("write descirption head in %s failed", db_path));
throw(streamException(out.rdstate()));
}
if ( !out.write(schema_buf, strlen(schema_buf)) ) {
MESSAGE(cerr, form("write descirption in %s failed", db_path));
throw(streamException(out.rdstate()));
}
out.close();
delete [] schema_buf;
return x;
}
desc* object_dict::parse(buffer& desc_buf)
{
char unique_nm[PATHSIZ];
Boolean ok = writeToTmpFile (
unique_nm,
desc_buf.get_base(),
desc_buf.content_sz()
);
//debug(cerr, desc_buf.get_base());
//fprintf(stderr, "get_base=%s\n", desc_buf.get_base());
//fprintf(stderr, "sz=%d\n", desc_buf.content_sz());
//fprintf(stderr, "tmpnm=%s\n", unique_nm);
if ( ok == false ) {
//fprintf(stderr, "write to temp failed\n");
throw(stringException("can't prepare the object dictionary."));
}
desc* x = 0;
mtry {
x = parse(unique_nm);
}
mcatch (mmdbException &,e) {
del_file(unique_nm);
rethrow;
} end_try;
del_file(unique_nm);
return x;
}
desc* object_dict::parse(char* define_desc_path)
{
schemain = fopen(define_desc_path, "r");
if ( schemain == NULL )
throw(stringException("open desc file failed"));
static int ct = 0;
if ( ct > 0 )
schemarestart(schemain);
else
ct = 1;
mtry {
if ( schemaparse() != 0 ) {
fclose(schemain);
throw(stringException("Parsing input failed"));
}
}
mcatch (mmdbException &,e) {
fclose(schemain);
rethrow;
} end_try;
fclose(schemain);
return desc_ptr;
}
void object_dict::_init(desc* x)
{
desc *ptr = x;
mtry { // init all stores
while ( ptr ) {
ptr -> init_store(this -> v_db_path);
ptr = ptr -> next_desc;
}
}
mcatch (mmdbException &,e) {
_quit_stores(x, ptr);
_quit_descs(x, ptr);
rethrow;
} end_try;
ptr = x;
while ( ptr ) { // add to the dict
if ( ptr -> get_store() )
v_dict.insert(ptr);
ptr = ptr -> next_desc;
}
//////////////////////////////
// init stored objects
//////////////////////////////
//MESSAGE(cerr, "init stored obj:");
ptr = x;
while ( ptr ) {
ptr -> init_handler(*this);
v_dict.insert(ptr);
ptr = ptr -> next_desc;
}
if ( v_desc_ptr == 0 ) {
v_desc_ptr = x;
} else {
v_last_desc_ptr -> next_desc = x;
}
v_last_desc_ptr = last_desc_ptr;
}
void object_dict::_quit_stores(desc* start_ptr, desc* end_ptr, Boolean sync)
{
desc *ptr = start_ptr;
if ( sync == true ) {
while ( ptr != end_ptr ) {
mtry {
ptr -> sync_store();
}
mcatch (mmdbException &,e)
{
#ifdef DEBUG
fprintf(stderr, "mmdbException caught @ %s line:%d.\n",
__FILE__, __LINE__);
rethrow;
#endif
}
end_try;
ptr = ptr -> next_desc;
}
}
ptr = start_ptr;
while ( ptr != end_ptr ) {
mtry {
ptr -> quit_store();
}
mcatch (mmdbException &,e)
{
#ifdef DEBUG
fprintf(stderr, "mmdbException caught @ %s line:%d.\n",
__FILE__, __LINE__);
rethrow;
#endif
}
end_try;
ptr = ptr -> next_desc;
}
}
void object_dict::_quit_stored_objects(desc* start_ptr, desc* end_ptr)
{
desc *ptr = start_ptr;
while ( ptr != end_ptr ) {
mtry {
ptr -> quit_handler();
//debug(cerr, *ptr);
}
mcatch (mmdbException &,e)
{
#ifdef DEBUG
fprintf(stderr, "mmdbException caught @ %s line:%d.\n",
__FILE__, __LINE__);
rethrow;
#endif
}
end_try;
ptr = ptr -> next_desc;
}
}
handler* object_dict::get_handler(const char* obj_name)
{
stored_object_desc key((char*)obj_name);
stored_object_desc* x = (stored_object_desc*)v_dict.member(&key);
if ( x ) {
return x -> get_handler();
} else {
throw(stringException(form("handler %s not in dict", obj_name)));
return 0;
}
}
abs_storage* object_dict::get_store(const char* obj_name)
{
store_desc key((char*)obj_name);
store_desc* x = (store_desc*)v_dict.member(&key);
if ( x ) {
return x -> get_store();
} else {
throw(stringException(form("store %s not in dict", obj_name)));
return 0;
}
}
void schemaerror( char* errorstr )
{
extern int linecount;
extern char schematext[];
if ( strlen( schematext ) > 0 )
throw(stringException(form("line %d %s at or before \"%s\"",
linecount, errorstr, schematext
)
));
else
throw(stringException(form("line %d %s illegal-symbol",
linecount, errorstr
)
));
return;
}
//void yyerror( char* errorstr )
//{
// extern int linecount;
// extern char yytext[];
//
// if ( strlen( yytext ) > 0 )
// MESSAGE(cerr, form("line %d %s at or before \"%s\"",
// linecount, errorstr, yytext
// )
// );
//
// else
// MESSAGE(cerr, form("line %d %s illegal-symbol",
// linecount, errorstr
// )
// );
//
// return;
//}
//
//int yywrap()
//{
// extern int linecount;
// extern char *pname;
//
//#ifdef DEBUG
// MESSAGE(cerr, form("Number of input lines %6d", linecount));
//#endif
//
//cerr << "Calling yywrap()\n";
// //return( 1 );
// return( 0 );
//}