Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
330
cde/programs/dtinfo/DtMmdb/storage/unixf_storage.C
Normal file
330
cde/programs/dtinfo/DtMmdb/storage/unixf_storage.C
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* $TOG: unixf_storage.C /main/8 1998/04/17 11:50:39 mgreess $
|
||||
*
|
||||
* 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 "storage/unixf_storage.h"
|
||||
|
||||
#ifdef _IBMR2 /* connolly 2/21/95 from the AIX fsync() manpage */
|
||||
extern "C" int fsync(int fd);
|
||||
#endif
|
||||
|
||||
/***********************************************************/
|
||||
// Constructor
|
||||
/***********************************************************/
|
||||
unixf_storage::
|
||||
unixf_storage( char* file_path, char* file_name,
|
||||
rep_policy* rep_p, int m
|
||||
) :
|
||||
abs_storage( file_path, file_name, UNIX_STORAGE_CODE, rep_p ),
|
||||
mode(m), fstream(),
|
||||
total_bytes(-1), v_file_exist(exist_file(file_name, file_path))
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// Destructor
|
||||
/***********************************************************/
|
||||
unixf_storage::~unixf_storage()
|
||||
{
|
||||
/*
|
||||
MESSAGE(cerr, "~unixf storeage ()");
|
||||
debug(cerr, my_path());
|
||||
debug(cerr, my_name());
|
||||
*/
|
||||
if ( policy )
|
||||
policy -> remove(*this);
|
||||
|
||||
#ifdef REPORT_IO_COUNT
|
||||
#endif
|
||||
}
|
||||
|
||||
void unixf_storage::remove()
|
||||
{
|
||||
int fd = rdbuf() -> fd();
|
||||
fsync(fd);
|
||||
::close(fd);
|
||||
del_file(my_name(), my_path());
|
||||
/*
|
||||
int md = mode;
|
||||
_open(ios::trunc);
|
||||
mode = md;
|
||||
_open(mode);
|
||||
*/
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// Open the physical file associated with this store
|
||||
/***********************************************************/
|
||||
int unixf_storage::_open(int new_mode)
|
||||
{
|
||||
char *fmt = NULL;
|
||||
|
||||
if ( ! ( *this ) ) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fstream is in bad status @ %s:%d\n",
|
||||
__FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
rep_cell* replaced = 0;
|
||||
|
||||
if ( policy != 0 ) {
|
||||
|
||||
policy -> promote(*this, replaced);
|
||||
|
||||
if ( replaced ) {
|
||||
unixf_storage* us = ((unixf_storage*)replaced);
|
||||
us -> fstream::close();
|
||||
if ( us -> fstream::fail() ) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Can't close db file %s/%s @ %s:%d\n",
|
||||
us->my_path(), us->my_name(), __FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(us -> fstream::rdstate()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( v_file_exist == false ) {
|
||||
SET_BIT(new_mode, ios::out);
|
||||
v_file_exist = true;
|
||||
}
|
||||
|
||||
//MESSAGE(cerr, "_open");
|
||||
//debug(cerr, total_bytes);
|
||||
|
||||
if ( !BIT_TEST(mode, new_mode) ) {
|
||||
|
||||
if ( fstream::rdbuf() -> is_open() ) {
|
||||
fstream::close();
|
||||
|
||||
if ( fstream::fail() ) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Can't close db file %s/%s @ %s:%d\n",
|
||||
path, name, __FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
}
|
||||
|
||||
SET_BIT(mode, new_mode);
|
||||
|
||||
fmt = ::form("%s/%s", path, name);
|
||||
fstream::open((const char *) fmt, mode, open_file_prot());
|
||||
|
||||
} else {
|
||||
|
||||
if ( ! fstream::rdbuf() -> is_open() ) {
|
||||
fmt = ::form("%s/%s", path, name);
|
||||
fstream::open((const char *) fmt, mode, open_file_prot());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( (!(*this)) || !fstream::rdbuf() -> is_open() ) {
|
||||
MESSAGE(cerr, "_open failed");
|
||||
debug(cerr, new_mode);
|
||||
debug(cerr, mode);
|
||||
debug(cerr, my_path());
|
||||
debug(cerr, my_name());
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Can't close db file %s/%s @ %s:%d\n",
|
||||
path, name, __FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// Read a string from the store. Use internal buffer.
|
||||
/***********************************************************/
|
||||
int
|
||||
unixf_storage::readString(mmdb_pos_t loc, char* base, int len, int str_off)
|
||||
{
|
||||
_open(ios::in);
|
||||
|
||||
int offset = int(loc) + str_off;
|
||||
|
||||
if ( seekg( offset, ios::beg ) == 0 ) {
|
||||
MESSAGE(cerr, "seekg failed");
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
if ( read( base, len ) == 0 || len != fstream::gcount() ) {
|
||||
MESSAGE(cerr, "read() failed");
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// Write a string to the store. Use external buffer.
|
||||
/***********************************************************/
|
||||
int unixf_storage::updateString(mmdb_pos_t loc, const char* base, int len, int string_ofst, Boolean flush_opt)
|
||||
{
|
||||
/*
|
||||
debug(cerr, len);
|
||||
debug(cerr, loc);
|
||||
debug(cerr, int(base));
|
||||
debug(cerr, string_ofst);
|
||||
debug(cerr, int(flush_opt));
|
||||
*/
|
||||
|
||||
/*
|
||||
fprintf(stderr, "updateString():");
|
||||
fprintf(stderr, "len=%d, ", len);
|
||||
fprintf(stderr, "loc=%d, ", loc);
|
||||
fprintf(stderr, "string_ofst=%d, ", string_ofst);
|
||||
fprintf(stderr, "flush option=%d\n", flush_opt);
|
||||
*/
|
||||
|
||||
_open(ios::out);
|
||||
|
||||
#ifdef C_API
|
||||
if ( ! seekg(loc+string_ofst, ios::beg) ) {
|
||||
MESSAGE(cerr, form("seek() failed on %s", my_name()));
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
#else
|
||||
if ( ! seekp(loc+string_ofst, ios::beg) ) {
|
||||
MESSAGE(cerr, form("seek() failed on %s", my_name()));
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( ! write( base, len ) ) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "write() failed on %s @ %s:%d\n",
|
||||
my_name(), __FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
if ( flush_opt == true )
|
||||
flush();
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "%d bytes have been written at offset %d in %s/%s @ %s:%d\n", len, loc+string_ofst, path, name, __FILE__, __LINE__);
|
||||
#ifndef C_API
|
||||
{
|
||||
char fname[64];
|
||||
sprintf(fname, "%s.%d-%d", name, loc+string_ofst, len);
|
||||
ofstream output(fname);
|
||||
output.write(base, len);
|
||||
output.flush();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( !(*this) ) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "write() failed on %s @ %s:%d\n",
|
||||
my_name(), __FILE__, __LINE__);
|
||||
#endif
|
||||
throw(streamException(fstream::rdstate()));
|
||||
}
|
||||
|
||||
total_bytes = MAX(total_bytes, int(loc)+len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// insert a string.
|
||||
/***********************************************************/
|
||||
int unixf_storage::appendString(mmdb_pos_t, const char* base, int len, Boolean flush_opt)
|
||||
{
|
||||
mmdb_pos_t loc = bytes();
|
||||
updateString(loc, base, len, 0, flush_opt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
// Return the number of bytes in the store.
|
||||
/***********************************************************/
|
||||
int unixf_storage::bytes()
|
||||
{
|
||||
if ( total_bytes == -1 ) {
|
||||
|
||||
_open(ios::in);
|
||||
|
||||
|
||||
if ( !good() )
|
||||
clear();
|
||||
|
||||
|
||||
total_bytes = ::bytes(rdbuf() -> fd());
|
||||
}
|
||||
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
Boolean unixf_storage::io_mode(int test_mode)
|
||||
{
|
||||
Boolean opened = false;
|
||||
|
||||
if ( fstream::rdbuf() -> is_open() ) {
|
||||
opened = true ;
|
||||
fstream::close();
|
||||
}
|
||||
|
||||
fstream::open(name, test_mode, open_file_prot());
|
||||
|
||||
if ( ! fstream::rdbuf() -> is_open() )
|
||||
return false;
|
||||
else {
|
||||
fstream::close();
|
||||
|
||||
if ( opened == true )
|
||||
fstream::open(name, mode, open_file_prot());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int unixf_storage::truncate(int target_length_in_bytes)
|
||||
{
|
||||
char *fmt = NULL;
|
||||
|
||||
_open(ios::out);
|
||||
|
||||
if ( total_bytes > target_length_in_bytes ) {
|
||||
fmt = ::form("%s/%s", path, name);
|
||||
if ( ::truncate((const char *) fmt, target_length_in_bytes) != 0 ) {
|
||||
throw(systemException(errno));
|
||||
}
|
||||
|
||||
total_bytes = target_length_in_bytes;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user