ExtendEntityManager.cxx revision 7c478bd95313f5f23a4c958a745db2134aa03244
// Copyright (c) 1994, 1995, 1996 James Clark
// See the file COPYING for copying permission.
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __GNUG__
#pragma implementation
#endif
#include "splib.h"
#include "ExtendEntityManager.h"
#include "Message.h"
#include "MessageArg.h"
#include "OffsetOrderedList.h"
#include "rtti.h"
#include "StorageManager.h"
#include "Vector.h"
#include "NCVector.h"
#include "Owner.h"
#include "constant.h"
#include "EntityManagerMessages.h"
#include "StorageObjectPosition.h"
#include "Owner.h"
#include "CodingSystem.h"
#include "CodingSystemKit.h"
#include "InputSource.h"
#include "Mutex.h"
#include "macros.h"
#include "EntityCatalog.h"
#include "CharMap.h"
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#ifdef DECLARE_MEMMOVE
extern "C" {
}
#endif
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
class ExternalInputSource;
class EntityManagerImpl : public ExtendEntityManager {
public:
const InputCodingSystem *defaultCodingSystem,
const ConstPtr<InputCodingSystemKit> &,
void registerStorageManager(StorageManager *);
const CharsetInfo &,
unsigned flags,
Messenger &);
const CharsetInfo &charset() const;
Boolean internalCharsetIsDocCharset() const;
const CharsetInfo &charset,
const Location &,
const CharsetInfo &,
const StringC *,
Messenger &,
StringC &);
const CharsetInfo &,
StringC &) const;
StorageManager *lookupStorageType(const char *) const;
const CharsetInfo &,
const char *&) const;
const CharsetInfo &idCharset,
const Location &defLocation,
ParsedSystemId &parsedSysid) const;
const CharsetInfo &idCharset,
const StorageObjectLocation *def,
ParsedSystemId &parsedSysid) const;
return docCharset;
else
return charset();
}
private:
void operator=(const EntityManagerImpl &); // undefined
const CharsetInfo &internalCharset);
friend class FSIParser;
};
class ExternalInfoImpl : public ExternalInfo {
public:
const ParsedSystemId &parsedSystemId() const;
void noteStorageObjectEnd(Offset);
void noteInsertedRSs();
private:
// list of inserted RSs
};
class ExternalInputSource : public InputSource {
public:
const CharsetInfo &internalCharset,
const CharsetInfo &docCharset,
unsigned flags);
private:
void willNotRewind();
void willNotSetDocCharset();
void init();
void noteRS();
void insertChar(Char);
const CharsetInfo &docCharset);
const char *leftOver_;
enum RecordType {
crlf,
lf,
cr,
};
};
class FSIParser {
public:
const StorageObjectLocation *defLoc,
const EntityManagerImpl *em,
struct RecordType {
const char *name;
};
private:
void unget();
const EntityManagerImpl *em_;
const StorageObjectSpec *defSpec_;
const CharsetInfo &idCharset_;
static RecordType recordTypeTable[];
};
{
}
const InputCodingSystem *cs,
{
}
{
if (!info)
return false;
if (!p)
return false;
}
const ParsedSystemId *
{
if (!info)
return 0;
if (!p)
return 0;
return &p->parsedSystemId();
}
const InputCodingSystem *defaultCodingSystem,
{
}
{
return internalCharsetIsDocCharset_;
}
{
return codingSystemKit_->systemCharset();
}
const CharsetInfo &docCharset,
unsigned flags,
{
0, mgr, parsedSysid)
return 0;
return new ExternalInputSource(parsedSysid,
charset(),
}
const CharsetInfo &docCharset,
{
}
const CharsetInfo &docCharset,
{
if (mapCatalogDocument) {
}
if (!parseSystemId(sysids[i],
0,
0,
mgr,
return 0;
return 1;
}
const CharsetInfo &docCharset,
const StringC *mapCatalogPublic,
{
const StorageObjectLocation *defSoLocP;
else
defSoLocP = 0;
return 0;
if (mapCatalogPublic) {
}
return 1;
}
const CharsetInfo &docCharset,
const StorageObjectLocation *defLoc,
ParsedSystemId &parsedSysid) const
{
}
const CharsetInfo &internalCharset) const
{
return storageManagers_[i].pointer();
return defaultStorageManager_.pointer();
return 0;
}
const CharsetInfo &internalCharset) const
{
return 0;
return defaultStorageManager_.pointer();
return storageManagers_[i].pointer();
return 0;
}
{
return defaultStorageManager_.pointer();
return storageManagers_[i].pointer();
return 0;
}
const InputCodingSystem *
const CharsetInfo &internalCharset,
const char *&name) const
{
}
const char *s,
const CharsetInfo &internalCharset)
{
return false;
return false;
return true;
}
{
}
{
}
{
const ExternalInfo *info;
for (;;) {
if (!origin)
return 0;
if (inputSourceOrigin) {
if (info)
break;
return 0;
}
else {
}
}
}
class UnbufferingStorageObject : public StorageObject {
public:
~UnbufferingStorageObject() { delete [] buf_; }
if (!*unbuffer_)
if (buf_ == 0)
return 0;
}
nread = 1;
return 1;
}
}
private:
char *buf_;
};
class MappingDecoder : public Decoder {
public:
private:
};
{
}
{
for (size_t i = 0; i < n; i++) {
if (d & (unsigned(1) << 31))
else
to[i] += d;
}
return n;
}
{
}
const CharsetInfo &systemCharset,
const CharsetInfo &docCharset,
unsigned flags)
: InputSource(origin, 0, 0),
// hack
{
if (parsedSysid[i].codingSystemType
break;
}
}
sov_[i] = 0;
init();
}
const CharsetInfo &systemCharset)
{
}
{
maySetDocCharset_ = 0;
}
const CharsetInfo &docCharset)
{
// FIXME How should invalidChar be chosen when internalCharsetIsDocCharset_?
else
}
const CharsetInfo &toCharset)
{
for (;;) {
break;
break;
do {
if (count > totalCount)
count = totalCount;
else
}
totalCount -= count;
} while (totalCount > 0);
}
}
void ExternalInputSource::init()
{
so_ = 0;
buf_ = 0;
bufSize_ = 0;
bufLim_ = 0;
bufLimOffset_ = 0;
insertRS_ = true;
soIndex_ = 0;
leftOver_ = 0;
nLeftOver_ = 0;
}
{
if (buf_)
delete [] buf_;
}
{
reset(0, 0);
if (buf_)
delete [] buf_;
// reset makes a new EntityOrigin
so_ = 0;
return 0;
}
init();
return 1;
}
void ExternalInputSource::willNotRewind()
{
if (sov_[i])
sov_[i]->willNotRewind();
mayRewind_ = 0;
}
// Round up N so that it is a power of TO.
// TO must be a power of 2.
inline
{
}
inline
{
}
inline
void ExternalInputSource::noteRS()
{
}
{
// need more data
while (so_ == 0) {
return eE;
if (soIndex_ > 0)
if (mayNotExist_) {
}
else
}
if (so_) {
: StorageObjectSpec::encoding)) {
if (maySetDocCharset_) {
}
}
case StorageObjectSpec::asis:
recordType_ = asis;
insertRS_ = false;
break;
case StorageObjectSpec::cr:
recordType_ = cr;
break;
case StorageObjectSpec::lf:
recordType_ = lf;
break;
case StorageObjectSpec::crlf:
recordType_ = crlf;
break;
case StorageObjectSpec::find:
break;
default:
}
soIndex_++;
nLeftOver_ = 0;
break;
}
else
soIndex_++;
}
// compute neededSize and readSize
// In this case we want to do decoding in place.
// FIXME It might be a win on some systems (Irix?) to arrange that the
// read buffer is on a page boundary.
abort(); // FIXME throw an exception
// Now size_t(-1)/sizeof(Char) - (align - 1) - insertRS_ - keepSize > 0
if (readSizeChars
abort();
}
else {
// Needs to be room for everything before decoding.
// Also must be room for everything after decoding.
// all the converted characters
// enough Chars to contain left over bytes
/ sizeof(Char)));
if (neededSize2 > neededSize)
abort();
startOffset = 0;
}
if (bufSize_ < neededSize)
if (nread > 0) {
&leftOver_);
if (nChars > 0) {
if (insertRS_) {
noteRS();
insertRS_ = false;
bufLim_ += 1;
bufLimOffset_ += 1;
}
bufLimOffset_ += nChars;
break;
}
}
}
else
so_ = 0;
}
if (insertRS_) {
noteRS();
insertChar(RS);
insertRS_ = false;
bufLimOffset_ += 1;
}
switch (recordType_) {
case unknown:
{
if (e) {
if (*e == '\n') {
recordType_ = lf;
info_->noteInsertedRSs();
advanceEnd(e + 1);
insertRS_ = true;
}
else {
if (e + 1 < bufLim_) {
if (e[1] == '\n') {
recordType_ = crlf;
advanceEnd(e + 1);
if (e + 2 == bufLim_) {
bufLim_--;
insertRS_ = true;
}
}
else {
advanceEnd(e + 1);
recordType_ = cr;
info_->noteInsertedRSs();
insertRS_ = true;
}
}
else {
advanceEnd(e + 1);
}
}
}
else
}
break;
case crUnknown:
{
if (*cur() == '\n') {
noteRS();
recordType_ = crlf;
}
else {
insertRS_ = true;
recordType_ = cr;
info_->noteInsertedRSs();
}
}
break;
case lf:
{
if (e) {
advanceEnd(e + 1);
*e = RE;
insertRS_ = true;
}
else
}
break;
case cr:
{
if (e) {
advanceEnd(e + 1);
insertRS_ = true;
}
else
}
break;
case crlf:
{
for (;;) {
e = findNextLf(e, bufLim_);
if (!e) {
break;
}
// Need to delete final RS if not followed by anything.
if (e + 1 == bufLim_) {
bufLim_--;
advanceEnd(e);
insertRS_ = true;
break;
}
noteRSAt(e);
e++;
}
}
break;
case asis:
break;
default:
}
return nextChar();
}
{
if (*start == '\r')
return start;
return 0;
}
{
if (*start == '\n')
return start;
return 0;
}
{
return start;
return 0;
}
{
insertChar(ch);
}
{
moveLeft();
}
else {
// must have start == buf
== bufLim_) {
abort(); // FIXME throw an exception
}
leftOver_ = s;
}
bufLim_ += 1;
}
}
{
if (nLeftOver_ > 0) {
memmove(s,
leftOver_ = s;
}
delete [] buf_;
}
{
if (parsedSysid_.size() > 0)
}
{
}
{
}
{
}
void ExternalInfoImpl::noteInsertedRSs()
{
}
{
// We do the locking in OffsetOrderedList.
if (!notrack_)
if (offset
}
{
// The last endOffset_ must be -1.
}
}
StorageObjectLocation &ret) const
{
return false;
// the last endOffset_ is Offset(-1), so this will
// terminate
int i;
;
if (i == 0)
return false;
if (parsedSysid_[i].notrack
if (position_[i].insertedRSs)
}
return true;
}
else {
// line1RS is now the number of RSs that are before or on the current line.
size_t j;
if (position_[i].insertedRSs)
j++;
colStart++;
}
else {
j = 0;
colStart = 0;
}
// j is now the number of RSs that are before or on the current line
// colStart is the offset of the first column
// the offset of the first column
if (colStart < startOffset)
// the RS that starts a line will be in column 0;
// the first real character of a line will be column 1
}
return true;
}
{
return parsedSysid_[i];
}
{
return parsedSysid_.size();
}
{
return parsedSysid_;
}
{
}
{
}
const CharsetInfo &idCharset,
const StorageObjectLocation *defLoc,
const EntityManagerImpl *em,
strIndex_(0),
{
}
{
else
return -1;
}
{
if (strIndex_ > 0)
strIndex_ -= 1;
}
{
return false;
return false;
return true;
}
{
}
{
return (matchChar(c, ' ')
|| matchChar(c, '\r')
|| matchChar(c, '\n')
|| matchChar(c, ' '));
}
{
static const char digits[] = "0123456789";
for (int i = 0; digits[i] != '\0'; i++)
weight = i;
return 1;
}
return 0;
}
{
for (;;) {
if (c == -1)
break;
}
unget();
if (!setCatalogAttributes(parsedSysid))
return 0;
return parse(parsedSysid);
}
if (!sm)
for (;;) {
return 0;
sm = 0;
for (;;) {
if (c == -1)
break;
if (matchChar(c, '<')) {
hadData = 1;
for (;;) {
c = get();
if (c == -1) {
break;
}
unget();
if (!sm) {
}
break;
}
key += c;
}
if (sm)
break;
}
hadData = 1;
id += c;
}
}
return 0;
if (neutral) {
return 0;
}
if (!sm)
break;
}
return 1;
}
{
if (!sos.storageManager) {
else
}
return 0;
return 1;
}
{
neutral = 1;
return defSpec_->storageManager;
else
}
else {
if (sm)
neutral = 0;
return sm;
}
}
{
for (;;) {
return 0;
}
break;
if (hadPublic)
else if (gotValue) {
}
else
hadPublic = 1;
}
else
}
return 1;
}
{
// Do just enough to ensure it can be reparsed.
else if (matchChar(c, ' ')) {
to += c;
}
else
to += c;
}
}
// FIXME This should be table driven.
{
Boolean hadEncoding = 0;
Boolean hadTracking = 0;
smcrd = -1;
fold = 1;
Boolean hadRecords = 0;
for (;;) {
return 0;
}
break;
else if (hadBctf)
else if (hadEncoding)
else if (gotValue) {
const char *codingSystemName;
const InputCodingSystem *codingSystem
if (codingSystem) {
}
if (!isNdata_) {
if (defSpec_) {
}
else {
sos.codingSystemName = 0;
}
}
}
else
}
else
hadBctf = 1;
}
else if (hadEncoding)
else if (hadBctf)
else if (gotValue) {
const char *codingSystemName;
const InputCodingSystem *codingSystem
if (codingSystem) {
}
if (!isNdata_) {
if (defSpec_) {
}
else {
sos.codingSystemName = 0;
}
}
}
else
}
else
hadEncoding = 1;
}
if (hadTracking)
else if (gotValue) {
}
else
hadTracking = 1;
}
else if (hadZapeof)
else if (gotValue) {
else
}
else
hadZapeof = 1;
}
else if (hadZapeof)
else if (gotValue)
else
hadZapeof = 1;
}
if (hadSearch)
else if (gotValue) {
else
}
else
hadSearch = 1;
}
if (hadSearch)
else if (gotValue)
else
hadSearch = 1;
}
if (!neutral)
else if (hadFold)
else if (gotValue) {
fold = 1;
fold = 0;
else
}
else
fold = 1;
hadFold = 1;
}
if (!neutral)
else if (hadFold)
else if (gotValue)
else
fold = 0;
hadFold = 1;
}
if (hadSmcrd)
else if (gotValue) {
smcrd = -1;
else
}
else
hadSmcrd = 1;
}
else if (hadRecords)
else if (gotValue) {
}
else
hadRecords = 1;
}
if (hadBase)
else if (gotValue)
else {
}
hadBase = 1;
}
else if (hadRecords)
else if (!gotValue)
else
hadRecords = 1;
}
if (hadTracking)
else if (!gotValue)
else
hadTracking = 1;
}
if (hadTracking)
else if (gotValue)
hadTracking = 1;
}
else
}
if (neutral) {
}
}
return 1;
}
};
{
return recordTypeTable[i].name;
return 0;
}
{
return 1;
}
return 0;
}
{
else if (isNdata_
if (defId_)
else {
0);
}
}
if (sos.codingSystem) {
}
else {
if (isNdata_) {
}
else if (defSpec_) {
}
}
}
{
while (isS(c))
c = get();
if (c == -1) {
return 0;
}
if (matchChar(c, '>'))
return 1;
return 0;
for (;;) {
token += c;
c = get();
if (c == -1)
return 0;
if (isS(c))
break;
break;
}
while (isS(c))
c = get();
if (c == -1)
return 0;
if (!matchChar(c, '=')) {
unget();
gotValue = 0;
return 1;
}
gotValue = 1;
c = get();
while (isS(c))
c = get();
return 0;
for (;;) {
if (c == lit)
break;
if (c == -1)
return 0;
if (matchChar(c, '\n'))
;
else
value += c;
}
}
else {
for (;;) {
value += c;
c = get();
if (c == -1)
return 0;
if (isS(c))
break;
unget();
break;
}
}
}
return 1;
}
{
size_t j = 0;
size_t i = 0;
int digit;
i += 3;
i++;
}
i++;
}
else
}
}
const StorageManager *sm)
{
size_t i = 0;
int digit;
i += 2;
i++;
}
i++;
}
else if (smCharset) {
return 0;
;
return 0; // FIXME give error
else
}
else
}
return 1;
}
{
}
static
const CharsetInfo *idCharset,
const CharsetInfo &resultCharset,
{
size_t i;
}
}
for (i = 0; i < len; i++) {
const StorageObjectSpec &sos = (*this)[i];
}
? " BCTF="
: " ENCODING=");
}
}
tem,
if (needSmcrd)
}
}
const CharsetInfo *idCharset,
const CharsetInfo &resultCharset,
{
if (!idCharset) {
char buf[32];
}
return;
}
|| univ >= 127
|| univ < 32
#ifndef MSDOS_FILENAMES
#endif
needSmcrd = 1;
char buf[32];
}
else {
switch (univ) {
case 34: // double quote
case 35: // #
case 39: // apostrophe
case 60: // <
{
char buf[32];
}
break;
default:
break;
}
}
}
}
#ifdef SP_NAMESPACE
}
#endif