Compare commits
14 Commits
regalloc_c
...
RDF_XPCOM_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b2424f7ca | ||
|
|
75bfddcd5c | ||
|
|
d67638c1e0 | ||
|
|
021dfd7c81 | ||
|
|
272deb6ee9 | ||
|
|
f81f4440bd | ||
|
|
914f82571b | ||
|
|
0f1dfe3d0d | ||
|
|
05693f5648 | ||
|
|
26c6838a88 | ||
|
|
90406a1af2 | ||
|
|
41eefd7f6c | ||
|
|
ab25b9b291 | ||
|
|
a151d7380d |
@@ -1,134 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextOne(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(0)) {
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(0)) {
|
||||
index = 0;
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextZero(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(~0)) {
|
||||
for (; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(~0)) {
|
||||
for (index = 0; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
// Print the set.
|
||||
//
|
||||
void BitSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
|
||||
|
||||
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
|
||||
Int32 currentBit = i;
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
|
||||
|
||||
Int32 nextBit = nextOne(currentBit);
|
||||
if (nextBit != currentBit + 1) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
|
||||
currentBit = nextBit;
|
||||
nextBit = nextOne(nextBit);
|
||||
}
|
||||
|
||||
if (currentBit > (i+1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
|
||||
|
||||
i = currentBit;
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
@@ -1,195 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BITSET_H_
|
||||
#define _BITSET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// BitSet -
|
||||
|
||||
class BitSet
|
||||
{
|
||||
private:
|
||||
|
||||
#if (PR_BITS_PER_WORD == 64)
|
||||
typedef Uint64 Word;
|
||||
#elif (PR_BITS_PER_WORD == 32)
|
||||
typedef Uint32 Word;
|
||||
#endif
|
||||
|
||||
static const nBitsInWord = PR_BITS_PER_WORD;
|
||||
static const nBytesInWord = PR_BYTES_PER_WORD;
|
||||
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
|
||||
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
|
||||
|
||||
// Return the number of Word need to store the universe.
|
||||
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
|
||||
// Return the given element offset in its containing Word.
|
||||
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
|
||||
// Return the Word offset for the given element int the universe.
|
||||
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
|
||||
// Return the mask for the given bit index.
|
||||
static Word getMask(Uint8 index) {return Word(1) << index;}
|
||||
|
||||
private:
|
||||
|
||||
Uint32 universeSize; // Size of the universe
|
||||
Word* word; // universe memory.
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
BitSet(const BitSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
// Create a bitset of universeSize bits.
|
||||
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
|
||||
|
||||
// Return the size of this bitset.
|
||||
Uint32 getSize() const {return universeSize;}
|
||||
|
||||
// Clear the bitset.
|
||||
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Clear the bit at index.
|
||||
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
|
||||
// Set the bitset.
|
||||
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Set the bit at index.
|
||||
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
|
||||
// Return true if the bit at index is set.
|
||||
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
|
||||
// Union with the given bitset.
|
||||
inline void or(const BitSet& set);
|
||||
// Intersection with the given bitset.
|
||||
inline void and(const BitSet& set);
|
||||
// Difference with the given bitset.
|
||||
inline void difference(const BitSet& set);
|
||||
// Copy set.
|
||||
inline BitSet& operator = (const BitSet& set);
|
||||
// Return true if the bitset are identical.
|
||||
friend bool operator == (const BitSet& set1, const BitSet& set2);
|
||||
// Return true if the bitset are different.
|
||||
friend bool operator != (const BitSet& set1, const BitSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
|
||||
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
|
||||
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
|
||||
|
||||
// Return the first bit at set to true or -1 if none.
|
||||
Int32 firstOne() const {return nextOne(-1);}
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
Int32 nextOne(Int32 pos) const;
|
||||
// Return the first bit at set to false or -1 if none.
|
||||
Int32 firstZero() const {return nextZero(-1);}
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
Int32 nextZero(Int32 pos) const;
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return true if the walk is ordered.
|
||||
static bool isOrdered() {return true;}
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return firstOne();}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return nextOne(pos);}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == -1;}
|
||||
// Return the element corresponding to the given iterator.
|
||||
Uint32 get(iterator pos) const {return pos;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// Union with the given bitset.
|
||||
//
|
||||
inline void BitSet::or(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ |= *src++;
|
||||
}
|
||||
|
||||
// Intersection with the given bitset.
|
||||
//
|
||||
inline void BitSet::and(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= *src++;
|
||||
}
|
||||
|
||||
// Difference with the given bitset.
|
||||
//
|
||||
inline void BitSet::difference(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= ~*src++;
|
||||
}
|
||||
|
||||
// Copy the given set into this set.
|
||||
//
|
||||
inline BitSet& BitSet::operator = (const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
if (this != &set)
|
||||
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return true if the given set is identical to this set.
|
||||
inline bool operator == (const BitSet& set1, const BitSet& set2)
|
||||
{
|
||||
set1.checkUniverseCompatibility(set2);
|
||||
|
||||
if (&set1 == &set2)
|
||||
return true;
|
||||
|
||||
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
|
||||
|
||||
#endif // _BITSET_H
|
||||
@@ -1,159 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _COALESCING_H_
|
||||
#define _COALESCING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
#if 1
|
||||
// Performing an ultra conservative coalescing meens that when we look at
|
||||
// candidates (source,destination) for coalescing we need to make sure
|
||||
// that the combined interference of the source and destination register
|
||||
// will not exceed the total number of register available for the register
|
||||
// class.
|
||||
#define ULTRA_CONSERVATIVE_COALESCING
|
||||
#else
|
||||
// If we are not doing an ultra conservative coalescing we have to make sure
|
||||
// that the total number of neighbor whose degree is greater than the total
|
||||
// number of register is not greater than the total number of register.
|
||||
#undef ULTRA_CONSERVATIVE_COALESCING
|
||||
#endif
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Coalescing
|
||||
{
|
||||
static bool coalesce(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
|
||||
// Initialize the lookup table
|
||||
//
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* newRange = new RegisterName[2 * rangeCount];
|
||||
RegisterName* coalescedRange = &newRange[rangeCount];
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
init(coalescedRange, rangeCount);
|
||||
|
||||
SparseSet interferences(pool, rangeCount);
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
bool removedInstructions = false;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.lndList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
|
||||
// Walk the nodes in the loop nesting depth list.
|
||||
for (Int32 n = nNodes - 1; n >= 0; n--) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
InstructionList::iterator it = instructions.begin();
|
||||
while (!instructions.done(it)) {
|
||||
Instruction& instruction = instructions.get(it);
|
||||
it = instructions.advance(it);
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
|
||||
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
|
||||
|
||||
if (source == destination) {
|
||||
instruction.remove();
|
||||
} else if (!iGraph.interfere(source, destination)) {
|
||||
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
|
||||
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
|
||||
|
||||
#ifdef ULTRA_CONSERVATIVE_COALESCING
|
||||
interferences.clear();
|
||||
|
||||
InterferenceVector* vector;
|
||||
for (vector = sourceVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
for (vector = destinationVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
|
||||
Uint32 count = interferences.getSize();
|
||||
#else // ULTRA_CONSERVATIVE_COALESCING
|
||||
trespass("not implemented");
|
||||
Uint32 count = 0;
|
||||
#endif // ULTRA_CONSERVATIVE_COALESCING
|
||||
|
||||
if (count < 6 /* FIX: should get the number from the class */) {
|
||||
// Update the interferences vector.
|
||||
if (sourceVector == NULL) {
|
||||
iGraph.setInterferenceVector(source, destinationVector);
|
||||
sourceVector = destinationVector;
|
||||
} else if (destinationVector == NULL)
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
else {
|
||||
InterferenceVector* last = NULL;
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
|
||||
last = v;
|
||||
assert(last);
|
||||
last->next = destinationVector;
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
}
|
||||
// Update the interference matrix.
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
|
||||
RegisterName* neighbors = v->neighbors;
|
||||
for (Uint32 i = 0; i < v->count; i++) {
|
||||
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
|
||||
iGraph.setInterference(neighbor, source);
|
||||
iGraph.setInterference(neighbor, destination);
|
||||
}
|
||||
}
|
||||
|
||||
instruction.remove();
|
||||
coalescedRange[source] = destination;
|
||||
removedInstructions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
|
||||
delete newRange;
|
||||
|
||||
return removedInstructions;
|
||||
}
|
||||
|
||||
#endif // _COALESCING_H_
|
||||
@@ -1,283 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
|
||||
#include "Coloring.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "FastBitSet.h"
|
||||
#include "FastBitMatrix.h"
|
||||
#include "CpuInfo.h"
|
||||
|
||||
bool Coloring::
|
||||
assignRegisters(FastBitMatrix& interferenceMatrix)
|
||||
{
|
||||
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
|
||||
|
||||
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
|
||||
}
|
||||
|
||||
PRInt32 Coloring::
|
||||
getLowestSpillCostRegister(FastBitSet& bitset)
|
||||
{
|
||||
PRInt32 lowest = bitset.firstOne();
|
||||
if (lowest != -1)
|
||||
{
|
||||
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
|
||||
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
|
||||
{
|
||||
cost = vReg.spillInfo.spillCost;
|
||||
lowest = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
PRUint32* Coloring::
|
||||
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
|
||||
{
|
||||
// first we construct the sets low and high. low contains all nodes of degree
|
||||
// inferior to the number of register available on the processor. All the
|
||||
// nodes with an high degree and a finite spill cost are placed in high.
|
||||
// Nodes of high degree and infinite spill cost are not included in either sets.
|
||||
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet low(pool, nRegisters);
|
||||
FastBitSet high(pool, nRegisters);
|
||||
FastBitSet stack(pool, nRegisters);
|
||||
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
{
|
||||
stack.set(i);
|
||||
vReg.colorRegister(nRegisters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
|
||||
low.set(i);
|
||||
else // if (!vReg.spillInfo.infiniteSpillCost)
|
||||
high.set(i);
|
||||
|
||||
// Set coloring info.
|
||||
vReg.spillInfo.willSpill = false;
|
||||
|
||||
switch(vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
vReg.colorRegister(LAST_GREGISTER + 1);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
vReg.colorRegister(LAST_FPREGISTER + 1);
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false); // Cannot happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the stack registers
|
||||
PRInt32 j;
|
||||
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
|
||||
*stackPtr++ = j;
|
||||
|
||||
// simplify
|
||||
while (true)
|
||||
{
|
||||
PRInt32 r;
|
||||
while ((r = getLowestSpillCostRegister(low)) != -1)
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
/* update low and high */
|
||||
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
|
||||
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
|
||||
{
|
||||
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
|
||||
// if the new interference degree of one of his neighbor becomes
|
||||
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
|
||||
|
||||
PRUint32 maxInterference = 0;
|
||||
switch (neighbor.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
maxInterference = NUMBER_OF_GREGISTERS;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
maxInterference = NUMBER_OF_FPREGISTERS;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
|
||||
{
|
||||
high.clear(j);
|
||||
low.set(j);
|
||||
}
|
||||
vReg.colorInfo.interferenceDegree--;
|
||||
interferenceMatrix.clear(r, j);
|
||||
interferenceMatrix.clear(j, r);
|
||||
}
|
||||
low.clear(r);
|
||||
|
||||
// Push this register.
|
||||
*stackPtr++ = r;
|
||||
}
|
||||
if ((r = getLowestSpillCostRegister(high)) != -1)
|
||||
{
|
||||
high.clear(r);
|
||||
low.set(r);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return stackPtr;
|
||||
}
|
||||
|
||||
bool Coloring::
|
||||
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
|
||||
{
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
|
||||
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
|
||||
FastBitSet usedStack(nRegisters + 1);
|
||||
bool success = true;
|
||||
Int32 lastUsedSSR = -1;
|
||||
|
||||
// select
|
||||
while (stackPtr != stackBase)
|
||||
{
|
||||
// Pop one register.
|
||||
PRUint32 r = *--stackPtr;
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
// Stack slots coloring.
|
||||
{
|
||||
usedStack.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
|
||||
|
||||
Int32 color = usedStack.firstZero();
|
||||
vReg.colorRegister(color);
|
||||
if (color > lastUsedSSR)
|
||||
lastUsedSSR = color;
|
||||
}
|
||||
else
|
||||
// Integer & Floating point register coloring.
|
||||
{
|
||||
usedRegisters.clear();
|
||||
preColoredRegisters.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
{
|
||||
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
|
||||
usedRegisters.set(nvReg.getColor());
|
||||
if (nvReg.isPreColored())
|
||||
preColoredRegisters.set(nvReg.getPreColor());
|
||||
}
|
||||
if (vReg.hasSpecialInterference)
|
||||
usedRegisters |= vReg.specialInterference;
|
||||
|
||||
PRInt8 c = -1;
|
||||
PRInt8 maxColor = 0;
|
||||
PRInt8 firstColor = 0;
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
firstColor = FIRST_GREGISTER;
|
||||
maxColor = LAST_GREGISTER;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
firstColor = FIRST_FPREGISTER;
|
||||
maxColor = LAST_FPREGISTER;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
|
||||
if (vReg.isPreColored())
|
||||
{
|
||||
c = vReg.getPreColor();
|
||||
if (usedRegisters.test(c))
|
||||
c = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
|
||||
c = usedRegisters.nextZero(c)) {}
|
||||
}
|
||||
|
||||
if ((c >= 0) && (c <= maxColor))
|
||||
{
|
||||
vReg.colorRegister(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
|
||||
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
|
||||
vReg.spillInfo.willSpill = true;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (success)
|
||||
{
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (vReg.getColor() > LAST_GREGISTER)
|
||||
PR_ASSERT(false);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
#if NUMBER_OF_FPREGISTERS != 0
|
||||
if (vReg.getColor() > LAST_FPREGISTER)
|
||||
PR_ASSERT(false);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
|
||||
return success;
|
||||
}
|
||||
#endif // NEW_LAURENTM_CODE
|
||||
@@ -1,284 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "SparseSet.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Coloring
|
||||
{
|
||||
private:
|
||||
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
|
||||
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
|
||||
|
||||
public:
|
||||
static bool color(RegisterAllocator& registerAllocator);
|
||||
static void finalColoring(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* color = registerAllocator.color;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = usePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
usePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = definePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
definePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* color = new RegisterName[rangeCount];
|
||||
registerAllocator.color = color;
|
||||
|
||||
for (Uint32 r = 1; r < rangeCount; r++)
|
||||
color[r] = RegisterName(6); // FIX;
|
||||
|
||||
// Color the preColored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID) {
|
||||
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
|
||||
}
|
||||
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
|
||||
registerAllocator.willSpill = &spill;
|
||||
SparseSet neighborColors(pool, 6); // FIX
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
bool coloringFailed = false;
|
||||
while (coloringStackPtr > coloringStack) {
|
||||
RegisterName range = *--coloringStackPtr;
|
||||
|
||||
if (!cost[range].infinite && cost[range].cost < 0) {
|
||||
coloringFailed = true;
|
||||
spill.set(range);
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
|
||||
} else {
|
||||
neighborColors.clear();
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >= 0; --i) {
|
||||
RegisterName neighborColor = color[vector->neighbors[i]];
|
||||
if (neighborColor < 6) // FIX
|
||||
neighborColors.set(neighborColor);
|
||||
}
|
||||
|
||||
if (neighborColors.getSize() == 6) { // FIX
|
||||
coloringFailed = true;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
|
||||
|
||||
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
|
||||
spill.set(range);
|
||||
} else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
|
||||
} else {
|
||||
for (Uint32 i = 0; i < 6; i++) // FIX
|
||||
if (!neighborColors.test(i)) {
|
||||
fprintf(stdout, "\twill color %d as %d\n", range, i);
|
||||
color[range] = RegisterName(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
if (coloringFailed) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
|
||||
spill.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
} else {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
return !coloringFailed;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
|
||||
{
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
SpillCost* spillCost = registerAllocator.spillCost;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
|
||||
Uint32* degree = new Uint32[rangeCount];
|
||||
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
|
||||
InterferenceVector* vector = iGraph.getInterferenceVector(i);
|
||||
degree[i] = (vector != NULL) ? vector->count : 0;
|
||||
}
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet low(pool, rangeCount);
|
||||
SparseSet high(pool, rangeCount);
|
||||
SparseSet highInfinite(pool, rangeCount);
|
||||
SparseSet preColored(pool, rangeCount);
|
||||
|
||||
// Get the precolored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID)
|
||||
preColored.set(name2range[getName(machinePtr->id)]);
|
||||
|
||||
// Insert the live ranges in the sets.
|
||||
//
|
||||
for (Uint32 range = 1; range < rangeCount; range++)
|
||||
if (!preColored.test(range))
|
||||
if (degree[range] < 6) // FIX
|
||||
low.set(range);
|
||||
else if (!spillCost[range].infinite)
|
||||
high.set(range);
|
||||
else
|
||||
highInfinite.set(range);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
|
||||
low.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
|
||||
high.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
|
||||
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
|
||||
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
RegisterName* coloringStackPtr = coloringStack;
|
||||
|
||||
while (low.getSize() != 0 || high.getSize() != 0) {
|
||||
while (low.getSize() != 0) {
|
||||
RegisterName range = RegisterName(low.getOne());
|
||||
low.clear(range);
|
||||
*coloringStackPtr++ = range;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = (vector->count - 1); i >= 0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
degree[neighbor]--;
|
||||
|
||||
if (degree[neighbor] < 6) // FIX
|
||||
if (high.test(neighbor)) {
|
||||
high.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
} else if (highInfinite.test(neighbor)) {
|
||||
highInfinite.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (high.getSize() != 0) {
|
||||
RegisterName best = RegisterName(high.getOne());
|
||||
double bestCost = spillCost[best].cost;
|
||||
double bestDegree = degree[best];
|
||||
|
||||
// Choose the next best candidate.
|
||||
//
|
||||
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
|
||||
RegisterName range = RegisterName(high.get(i));
|
||||
double thisCost = spillCost[range].cost;
|
||||
double thisDegree = degree[range];
|
||||
|
||||
if (thisCost * bestDegree < bestCost * thisDegree) {
|
||||
best = range;
|
||||
bestCost = thisCost;
|
||||
bestDegree = thisDegree;
|
||||
}
|
||||
}
|
||||
|
||||
high.clear(best);
|
||||
low.set(best);
|
||||
}
|
||||
}
|
||||
assert(highInfinite.getSize() == 0);
|
||||
|
||||
delete degree;
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
|
||||
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
return coloringStackPtr;
|
||||
}
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
|
||||
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
|
||||
#include "DominatorGraph.h"
|
||||
|
||||
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
|
||||
{
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
GtoV = new Uint32[nNodes + 1];
|
||||
VtoG = new Uint32[nNodes + 1];
|
||||
|
||||
Uint32 v = 1;
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
VtoG[v] = n;
|
||||
GtoV[n] = v++;
|
||||
}
|
||||
|
||||
// Initialize all the 1-based arrays.
|
||||
//
|
||||
parent = new Uint32[v];
|
||||
semi = new Uint32[v];
|
||||
vertex = new Uint32[v];
|
||||
label = new Uint32[v];
|
||||
size = new Uint32[v];
|
||||
ancestor = new Uint32[v];
|
||||
child = new Uint32[v];
|
||||
dom = new Uint32[v];
|
||||
bucket = new DGLinkedList*[v];
|
||||
|
||||
memset(semi, '\0', v * sizeof(Uint32));
|
||||
memset(bucket, '\0', v * sizeof(DGLinkedList*));
|
||||
|
||||
vCount = v;
|
||||
|
||||
build();
|
||||
|
||||
delete parent;
|
||||
delete semi;
|
||||
delete vertex;
|
||||
delete label;
|
||||
delete size;
|
||||
delete ancestor;
|
||||
delete child;
|
||||
delete dom;
|
||||
delete bucket;
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
|
||||
{
|
||||
semi[vx] = ++n;
|
||||
vertex[n] = label[vx] = vx;
|
||||
ancestor[vx] = child[vx] = 0;
|
||||
size[vx] = 1;
|
||||
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
|
||||
ControlEdge* successorEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
|
||||
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
|
||||
if (semi[w] == 0) {
|
||||
parent[w] = vx;
|
||||
n = DFS(w, n);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
|
||||
{
|
||||
Uint32 s = w;
|
||||
|
||||
while (semi[label[w]] < semi[label[child[s]]]) {
|
||||
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
|
||||
ancestor[child[s]] = s;
|
||||
child[s] = child[child[s]];
|
||||
} else {
|
||||
size[child[s]] = size[s];
|
||||
s = ancestor[s] = child[s];
|
||||
}
|
||||
}
|
||||
label[s] = label[w];
|
||||
size[vx] += size[w];
|
||||
if(size[vx] < (size[w] << 1)) {
|
||||
Uint32 t = s;
|
||||
s = child[vx];
|
||||
child[vx] = t;
|
||||
}
|
||||
while( s != 0 ) {
|
||||
ancestor[s] = vx;
|
||||
s = child[s];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DominatorGraph::COMPRESS(Uint32 vx)
|
||||
{
|
||||
if(ancestor[ancestor[vx]] != 0) {
|
||||
COMPRESS(ancestor[vx]);
|
||||
if(semi[label[ancestor[vx]]] < semi[label[vx]])
|
||||
label[vx] = label[ancestor[vx]];
|
||||
ancestor[vx] = ancestor[ancestor[vx]];
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::EVAL(Uint32 vx)
|
||||
{
|
||||
if(ancestor[vx] == 0)
|
||||
return label[vx];
|
||||
COMPRESS(vx);
|
||||
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
|
||||
}
|
||||
|
||||
void DominatorGraph::build()
|
||||
{
|
||||
Uint32 n = DFS(GtoV[0], 0);
|
||||
size[0] = label[0] = semi[0];
|
||||
|
||||
for (Uint32 i = n; i >= 2; i--) {
|
||||
Uint32 w = vertex[i];
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
|
||||
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
|
||||
Uint32 u = EVAL(vx);
|
||||
|
||||
if(semi[u] < semi[w])
|
||||
semi[w] = semi[u];
|
||||
}
|
||||
|
||||
DGLinkedList* elem = new DGLinkedList();
|
||||
elem->next = bucket[vertex[semi[w]]];
|
||||
elem->index = w;
|
||||
bucket[vertex[semi[w]]] = elem;
|
||||
|
||||
LINK(parent[w], w);
|
||||
|
||||
elem = bucket[parent[w]];
|
||||
while(elem != NULL) {
|
||||
Uint32 vx = elem->index;
|
||||
Uint32 u = EVAL(vx);
|
||||
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
|
||||
memset(size, '\0', n * sizeof(Uint32));
|
||||
Pool& pool = controlGraph.pool;
|
||||
nodes = new(pool) DGNode[n];
|
||||
|
||||
for(Uint32 j = 2; j <= n; j++) {
|
||||
Uint32 w = vertex[j];
|
||||
Uint32 d = dom[w];
|
||||
if(d != vertex[semi[w]]) {
|
||||
d = dom[d];
|
||||
dom[w] = d;
|
||||
}
|
||||
size[d]++;
|
||||
}
|
||||
dom[GtoV[0]] = 0;
|
||||
|
||||
for (Uint32 k = 1; k <= n; k++) {
|
||||
DGNode& node = nodes[VtoG[k]];
|
||||
Uint32 count = size[k];
|
||||
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
|
||||
}
|
||||
|
||||
for (Uint32 l = 2; l <= n; l++)
|
||||
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void DominatorGraph::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
for (Uint32 i = 0; i < nNodes; i++) {
|
||||
DGNode& node = nodes[i];
|
||||
if (node.successorsBegin != node.successorsEnd) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
|
||||
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DOMINATOR_GRAPH_H_
|
||||
#define _DOMINATOR_GRAPH_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
|
||||
class ControlGraph;
|
||||
|
||||
struct DGNode
|
||||
{
|
||||
Uint32* successorsBegin;
|
||||
Uint32* successorsEnd;
|
||||
};
|
||||
|
||||
struct DGLinkedList
|
||||
{
|
||||
DGLinkedList* next;
|
||||
Uint32 index;
|
||||
};
|
||||
|
||||
class DominatorGraph
|
||||
{
|
||||
private:
|
||||
|
||||
ControlGraph& controlGraph;
|
||||
|
||||
Uint32 vCount;
|
||||
|
||||
Uint32* VtoG;
|
||||
Uint32* GtoV;
|
||||
Uint32* parent;
|
||||
Uint32* semi;
|
||||
Uint32* vertex;
|
||||
Uint32* label;
|
||||
Uint32* size;
|
||||
Uint32* ancestor;
|
||||
Uint32* child;
|
||||
Uint32* dom;
|
||||
DGLinkedList** bucket;
|
||||
DGNode* nodes;
|
||||
|
||||
private:
|
||||
|
||||
void build();
|
||||
|
||||
Uint32 DFS(Uint32 vx, Uint32 n);
|
||||
void LINK(Uint32 vx, Uint32 w);
|
||||
void COMPRESS(Uint32 vx);
|
||||
Uint32 EVAL(Uint32 vx);
|
||||
|
||||
public:
|
||||
|
||||
DominatorGraph(ControlGraph& controlGraph);
|
||||
|
||||
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
|
||||
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
#endif // _DOMINATOR_GRAPH_H_
|
||||
@@ -1,97 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _HASH_SET_H_
|
||||
#define _HASH_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
struct HashSetElement
|
||||
{
|
||||
Uint32 index;
|
||||
HashSetElement* next;
|
||||
};
|
||||
|
||||
class HashSet
|
||||
{
|
||||
private:
|
||||
|
||||
static const hashSize = 64;
|
||||
|
||||
// Return the hash code for the given element index.
|
||||
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
|
||||
|
||||
private:
|
||||
|
||||
Pool& allocationPool;
|
||||
HashSetElement** bucket;
|
||||
HashSetElement* free;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
HashSet(const HashSet&);
|
||||
// No copy operator.
|
||||
void operator = (const HashSet&);
|
||||
|
||||
public:
|
||||
|
||||
// Create a new HashSet.
|
||||
inline HashSet(Pool& pool, Uint32 universeSize);
|
||||
|
||||
// Clear the hashset.
|
||||
void clear();
|
||||
// Clear the element for the given index.
|
||||
void clear(Uint32 index);
|
||||
// Set the element for the given index.
|
||||
void set(Uint32 index);
|
||||
// Return true if the element at index is a member.
|
||||
bool test(Uint32 index) const;
|
||||
// Union with the given hashset.
|
||||
inline void or(const HashSet& set);
|
||||
// Intersection with the given hashset.
|
||||
inline void and(const HashSet& set);
|
||||
// Difference with the given hashset.
|
||||
inline void difference(const HashSet& set);
|
||||
|
||||
// Logical operators.
|
||||
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
|
||||
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
|
||||
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef HashSetElement* iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const;
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const;
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == NULL;}
|
||||
};
|
||||
|
||||
|
||||
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
|
||||
: allocationPool(pool), free(NULL)
|
||||
{
|
||||
bucket = new(pool) HashSetElement*[hashSize];
|
||||
memset(bucket, '\0', sizeof(HashSetElement*));
|
||||
}
|
||||
|
||||
#endif // _HASH_SET_H_
|
||||
@@ -1,213 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INDEXED_POOL_H_
|
||||
#define _INDEXED_POOL_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
|
||||
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
|
||||
// IndexedObject.
|
||||
//
|
||||
// When the indexed pool is ask to allocate and initialize a new object (using
|
||||
// the operator new(anIndexedPool) it will zero the memory used to store the
|
||||
// object and initialize the field 'index' of this object to its position in
|
||||
// the pool.
|
||||
//
|
||||
// An object allocated by the indexed pool can be freed by calling the method
|
||||
// IndexedPool::release(IndexedElement& objectIndex).
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// IndexedPool<IndexedElement> elementPool;
|
||||
//
|
||||
// IndexedElement& element1 = *new(elementPool) IndexedElement();
|
||||
// IndexedElement& element2 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// indexedPool.release(element1);
|
||||
// IndexedElement& element3 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// At this point element1 is no longer a valid object, element2 is at
|
||||
// index 2 and element3 is at index 1.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedObject -
|
||||
//
|
||||
|
||||
template<class Object>
|
||||
struct IndexedObject
|
||||
{
|
||||
Uint32 index; // Index in the pool.
|
||||
Object* next; // Used to link IndexedObject together.
|
||||
|
||||
Uint32 getIndex() {return index;}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObject> -
|
||||
//
|
||||
|
||||
template <class IndexedObject>
|
||||
class IndexedPool
|
||||
{
|
||||
private:
|
||||
|
||||
static const blockSize = 4; // Size of one block.
|
||||
|
||||
Uint32 nBlocks; // Number of blocks in the pool.
|
||||
IndexedObject** block; // Array of block pointers.
|
||||
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
|
||||
Uint32 nextIndex; // Index of the next free object in the last block.
|
||||
|
||||
private:
|
||||
|
||||
void allocateAnotherBlock();
|
||||
IndexedObject& newObject();
|
||||
|
||||
public:
|
||||
|
||||
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
|
||||
~IndexedPool();
|
||||
|
||||
IndexedObject& get(Uint32 index) const;
|
||||
void release(IndexedObject& object);
|
||||
|
||||
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
|
||||
|
||||
// Return the universe size.
|
||||
Uint32 getSize() {return nextIndex;}
|
||||
|
||||
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
|
||||
};
|
||||
|
||||
// Free all the memory allocated for this object.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedPool<IndexedObject>::~IndexedPool()
|
||||
{
|
||||
for (Uint32 n = 0; n < nBlocks; n++)
|
||||
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
|
||||
}
|
||||
|
||||
// Release the given. This object will be iserted in the chained
|
||||
// list of free IndexedObjects. To minimize the fragmentation the chained list
|
||||
// is ordered by ascending indexes.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::release(IndexedObject& object)
|
||||
{
|
||||
Uint32 index = object.index;
|
||||
IndexedObject* list = freeObjects;
|
||||
|
||||
assert(&object == &get(index)); // Make sure that object is owned by this pool.
|
||||
|
||||
if (list == NULL) { // The list is empty.
|
||||
freeObjects = &object;
|
||||
object.next = NULL;
|
||||
} else { // The list contains at least 1 element.
|
||||
if (index < list->index) { // insert as first element.
|
||||
freeObjects = &object;
|
||||
object.next = list;
|
||||
} else { // Find this object's place.
|
||||
while ((list->next) != NULL && (list->next->index < index))
|
||||
list = list->next;
|
||||
|
||||
object.next = list->next;
|
||||
list->next = &object;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Sanity check to be sure that the list is correctly ordered.
|
||||
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
|
||||
if (obj->next != NULL)
|
||||
assert(obj->index < obj->next->index);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create a new block of IndexedObjects. We will allocate the memory to
|
||||
// store IndexedPool::blockSize IndexedObject and the new Array of block
|
||||
// pointers.
|
||||
// The newly created IndexedObjects will not be initialized.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::allocateAnotherBlock()
|
||||
{
|
||||
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
|
||||
|
||||
memcpy(memory, block, nBlocks * sizeof(Uint32));
|
||||
|
||||
block = (IndexedObject **) memory;
|
||||
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
|
||||
|
||||
block[nBlocks] = &objects[-(nBlocks * blockSize)];
|
||||
nBlocks++;
|
||||
}
|
||||
|
||||
// Return the IndexedObject at the position 'index' in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
|
||||
{
|
||||
Uint32 blockIndex = index / blockSize;
|
||||
assert(blockIndex < nBlocks);
|
||||
|
||||
return block[blockIndex][index];
|
||||
}
|
||||
|
||||
// Return the reference of an unused object in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::newObject()
|
||||
{
|
||||
if (freeObjects != NULL) {
|
||||
IndexedObject& newObject = *freeObjects;
|
||||
freeObjects = newObject.next;
|
||||
return newObject;
|
||||
}
|
||||
|
||||
Uint32 nextIndex = this->nextIndex++;
|
||||
Uint32 blockIndex = nextIndex / blockSize;
|
||||
|
||||
while (blockIndex >= nBlocks)
|
||||
allocateAnotherBlock();
|
||||
|
||||
IndexedObject& newObject = block[blockIndex][nextIndex];
|
||||
newObject.index = nextIndex;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
// Return the address of the next unsused object in the given
|
||||
// indexed pool. The field index of the newly allocated object
|
||||
// will be initialized to the corresponding index of this object
|
||||
// in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
|
||||
{
|
||||
assert(size == sizeof(IndexedObject));
|
||||
return (void *) &pool.newObject();
|
||||
}
|
||||
|
||||
#endif // _INDEXED_POOL_H_
|
||||
@@ -1,258 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INTERFERENCE_GRAPH_H_
|
||||
#define _INTERFERENCE_GRAPH_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
struct InterferenceVector
|
||||
{
|
||||
Uint32 count;
|
||||
InterferenceVector* next;
|
||||
RegisterName* neighbors;
|
||||
|
||||
InterferenceVector() : count(0), next(NULL) {}
|
||||
};
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class InterferenceGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* interferences;
|
||||
InterferenceVector** vector;
|
||||
Uint32* offset;
|
||||
Uint32 rangeCount;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
InterferenceGraph(const InterferenceGraph&);
|
||||
// No copy operator.
|
||||
void operator = (const InterferenceGraph&);
|
||||
|
||||
// Check if reg is a member of the universe.
|
||||
void checkMember(RegisterName name) {assert(name < rangeCount);}
|
||||
// Return the edge index for the interference between name1 and name2.
|
||||
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
|
||||
|
||||
public:
|
||||
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
// Calculate the interferences.
|
||||
void build();
|
||||
// Return true if reg1 and reg2 interfere.
|
||||
bool interfere(RegisterName name1, RegisterName name2);
|
||||
// Return the interference vector for the given register or NULL if there is none.
|
||||
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
|
||||
// Set the interference between name1 and name2.
|
||||
void setInterference(RegisterName name1, RegisterName name2);
|
||||
// Set the interference vector for the given register.
|
||||
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
|
||||
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the interferences.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
// Initialize the structures.
|
||||
//
|
||||
offset = new(pool) Uint32[rangeCount + 1];
|
||||
vector = new(pool) InterferenceVector*[rangeCount];
|
||||
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
|
||||
|
||||
Uint32 o = 0;
|
||||
offset[0] = 0;
|
||||
for (Uint32 i = 1; i <= rangeCount; ++i) {
|
||||
offset[i] = o;
|
||||
o += i;
|
||||
}
|
||||
|
||||
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
|
||||
registerAllocator.liveness = liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
// Create the interferences.
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
|
||||
RegisterName live = RegisterName(currentLive.get(e));
|
||||
|
||||
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
|
||||
|
||||
if (vector[define] == NULL)
|
||||
vector[define] = new(pool) InterferenceVector();
|
||||
vector[define]->count++;
|
||||
|
||||
if (vector[live] == NULL)
|
||||
vector[live] = new(pool) InterferenceVector();
|
||||
vector[live]->count++;
|
||||
|
||||
setInterference(live, define);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the liveness.
|
||||
//
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the memory to store the interferences.
|
||||
//
|
||||
for (Uint32 e = 0; e < rangeCount; e++)
|
||||
if (vector[e] != NULL) {
|
||||
InterferenceVector& v = *vector[e];
|
||||
v.neighbors = new(pool) RegisterName[v.count];
|
||||
v.count = 0;
|
||||
}
|
||||
|
||||
// Initialize the edges.
|
||||
//
|
||||
if (RegisterPressure::Set::isOrdered()) {
|
||||
RegisterName name1 = RegisterName(0);
|
||||
|
||||
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
|
||||
Uint32 interferenceIndex = interferences->get(i);
|
||||
|
||||
while(interferenceIndex >= offset[name1 + 1])
|
||||
name1 = RegisterName(name1 + 1);
|
||||
|
||||
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
|
||||
|
||||
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
|
||||
|
||||
assert(interfere(name1, name2));
|
||||
|
||||
InterferenceVector& vector1 = *vector[name1];
|
||||
vector1.neighbors[vector1.count++] = name2;
|
||||
|
||||
InterferenceVector& vector2 = *vector[name2];
|
||||
vector2.neighbors[vector2.count++] = name1;
|
||||
}
|
||||
} else {
|
||||
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
checkMember(name1); checkMember(name2);
|
||||
assert(name1 != name2); // This is not possible.
|
||||
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
interferences->set(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
return interferences->test(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
if (vector[i] != NULL) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
|
||||
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
|
||||
for (Uint32 j = 0; j < v->count; j++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
|
||||
if (v->next != NULL || j != (v->count - 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
|
||||
}
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _INTERFERENCE_GRAPH_H_
|
||||
@@ -1,87 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_H_
|
||||
#define _LIVE_RANGE_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LiveRange
|
||||
{
|
||||
static void build(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
// Intialize the lookup table.
|
||||
//
|
||||
Uint32 nameCount = registerAllocator.nameCount;
|
||||
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
|
||||
RegisterName* rangeName = &nameTable[nameCount];
|
||||
|
||||
init(rangeName, nameCount);
|
||||
|
||||
// Walk the graph.
|
||||
//
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
SparseSet destination(registerAllocator.pool, nameCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
|
||||
destination.clear();
|
||||
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
Instruction& phiNode = phiNodes.get(i);
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
|
||||
}
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
RegisterName destinationRoot = findRoot(destinationName, rangeName);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName sourceName = usePtr->getRegisterName();
|
||||
RegisterName sourceRoot = findRoot(sourceName, rangeName);
|
||||
|
||||
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
|
||||
rangeName[sourceRoot] = destinationRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
|
||||
}
|
||||
|
||||
#endif // _LIVE_RANGE_H_
|
||||
@@ -1,163 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_GRAPH_
|
||||
#define _LIVE_RANGE_GRAPH_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class LiveRangeGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* edges;
|
||||
Uint32 rangeCount;
|
||||
|
||||
public:
|
||||
//
|
||||
//
|
||||
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
//
|
||||
//
|
||||
void build();
|
||||
|
||||
//
|
||||
//
|
||||
void addEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
//
|
||||
//
|
||||
bool haveEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (define != live && registerAllocator.canInterfere(define, live))
|
||||
addEdge(define, live);
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName use = name2range[usePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (use != live && registerAllocator.canInterfere(use, live))
|
||||
addEdge(use, live);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
edges->set(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
return edges->test(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVE_RANGE_GRAPH_
|
||||
@@ -1,301 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVENESS_H_
|
||||
#define _LIVENESS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LivenessInfo -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LivenessInfo
|
||||
{
|
||||
RegisterPressure::Set* liveIn;
|
||||
RegisterPressure::Set* liveOut;
|
||||
DEBUG_LOG_ONLY(Uint32 size);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Liveness
|
||||
//
|
||||
// The liveness is defined by the following data-flow equations:
|
||||
//
|
||||
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
|
||||
// LiveOut(n) = U LiveIn(s) (s a successor of n).
|
||||
//
|
||||
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
|
||||
// is the set of defined registers in the block n, LiveIn(n) is the set of
|
||||
// live registers at the begining of the block n and LiveOut(n) is the set
|
||||
// of live registers at the end of the block n.
|
||||
//
|
||||
//
|
||||
// We will compute the liveness analysis in two stages:
|
||||
//
|
||||
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
|
||||
// for each block n.
|
||||
// 2- Perform a backward data-flow analysis to propagate the liveness information
|
||||
// through the entire control-flow graph.
|
||||
//
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Liveness
|
||||
{
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = name2range[usePtr->getRegisterName()];
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, rangeCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* usedByPhiNodes = NULL;
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
|
||||
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
|
||||
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
|
||||
currentKilled.set(define.getRegisterName());
|
||||
|
||||
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
|
||||
const ControlEdgeList& predecessors = node.getPredecessors();
|
||||
ControlEdgeList::iterator p = predecessors.begin();
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
|
||||
if (usePtr->isRegister())
|
||||
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
|
||||
}
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = usePtr->getRegisterName();
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, nameCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// Insert the phiNodes contribution.
|
||||
if (usedByPhiNodes != NULL)
|
||||
temp |= usedByPhiNodes[n];
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
for (Uint32 n = 0; n < size; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
|
||||
liveIn[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
|
||||
liveOut[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVENESS_H_
|
||||
@@ -1,40 +0,0 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
MODULE_NAME = RegisterAllocator
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(DEPTH)/Utilities/General \
|
||||
-I$(DEPTH)/Utilities/zlib \
|
||||
-I$(DEPTH)/Runtime/ClassReader \
|
||||
-I$(DEPTH)/Runtime/NativeMethods \
|
||||
-I$(DEPTH)/Runtime/System \
|
||||
-I$(DEPTH)/Runtime/ClassInfo \
|
||||
-I$(DEPTH)/Runtime/FileReader \
|
||||
-I$(DEPTH)/Compiler/PrimitiveGraph \
|
||||
-I$(DEPTH)/Compiler/FrontEnd \
|
||||
-I$(DEPTH)/Compiler/Optimizer \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
|
||||
-I$(DEPTH)/Compiler/RegisterAllocator \
|
||||
-I$(DEPTH)/Driver/StandAloneJava \
|
||||
-I$(DEPTH)/Debugger \
|
||||
$(NULL)
|
||||
|
||||
CXXSRCS = \
|
||||
RegisterAllocator.cpp \
|
||||
RegisterAllocatorTools.cpp \
|
||||
DominatorGraph.cpp \
|
||||
VirtualRegister.cpp \
|
||||
BitSet.cpp \
|
||||
SparseSet.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
libs:: $(MODULE)
|
||||
@@ -1,392 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _PHI_NODE_REMOVER_H_
|
||||
#define _PHI_NODE_REMOVER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "DominatorGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "Liveness.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterNameNode -
|
||||
|
||||
struct RegisterNameNode
|
||||
{
|
||||
RegisterNameNode* next;
|
||||
RegisterName newName;
|
||||
Uint32 nextPushed;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CopyData -
|
||||
|
||||
struct CopyData
|
||||
{
|
||||
RegisterName source;
|
||||
RegisterClassKind classKind;
|
||||
Uint32 useCount;
|
||||
bool isLiveOut;
|
||||
RegisterName sourceNameToUse;
|
||||
RegisterName temporaryName;
|
||||
RegisterNameNode* newName;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PhiNodeRemover<RegisterPressure> -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct PhiNodeRemover
|
||||
{
|
||||
// Replace the phi nodes by copy instructions.
|
||||
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
// Split some of the critical edges and return true if there are still some
|
||||
// in the graph after that.
|
||||
//
|
||||
static bool splitCriticalEdges(ControlGraph& /*cg*/)
|
||||
{
|
||||
// FIX: not implemented.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
|
||||
{
|
||||
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
|
||||
|
||||
if (pushed.test(oldName))
|
||||
(*stack)->newName = newName;
|
||||
else {
|
||||
newNode.newName = newName;
|
||||
newNode.nextPushed = *nodeListPointer;
|
||||
*nodeListPointer = oldName;
|
||||
newNode.next = *stack;
|
||||
*stack = &newNode;
|
||||
pushed.set(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Initialize the local variables.
|
||||
//
|
||||
|
||||
// When we insert the copies we will also need to create new VirtualRegisters for
|
||||
// the insertion of temporaries. The maximum number of temporary register will not
|
||||
// exceed the number of phiNodes in the primitive graph.
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
Uint32 maxNameCount = nameCount;
|
||||
for (Uint32 n = 0; n < nNodes; n++)
|
||||
maxNameCount += nodes[n]->getPhiNodes().length();
|
||||
|
||||
// If the CFG contains some critical edges (backward edge which source has more than one
|
||||
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
|
||||
// information to be able to insert temporary copies.
|
||||
RegisterPressure::Set* liveOut = NULL;
|
||||
if (splitCriticalEdges(controlGraph))
|
||||
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
|
||||
|
||||
DominatorGraph dGraph(controlGraph);
|
||||
|
||||
SparseSet pushed(pool, maxNameCount);
|
||||
SparseSet destinationList(pool, maxNameCount);
|
||||
SparseSet workList(pool, maxNameCount);
|
||||
|
||||
CopyData* copyStats = new(pool) CopyData[maxNameCount];
|
||||
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
|
||||
|
||||
struct NodeStack {
|
||||
Uint32* next;
|
||||
Uint32* limit;
|
||||
Uint32 pushedList;
|
||||
};
|
||||
|
||||
// Allocate the node stack and initialize the node stack pointer.
|
||||
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
|
||||
NodeStack* nodeStackPtr = nodeStack;
|
||||
|
||||
// We start by the begin node.
|
||||
Uint32 startNode = 0;
|
||||
Uint32* next = &startNode;
|
||||
Uint32* limit = &startNode + 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (next == limit) {
|
||||
// If there are no more node in the sibling, we have to pop the current
|
||||
// frame from the stack and update the copyStats of the pushed nodes.
|
||||
//
|
||||
if (nodeStackPtr == nodeStack)
|
||||
// We are at the bottom of the stack and there are no more nodes
|
||||
// to look at. We are done !
|
||||
break;
|
||||
|
||||
--nodeStackPtr;
|
||||
// We are done with all the children of this node in the dominator tree.
|
||||
// We need to update the copy information of all the new names pushed
|
||||
// during the walk over this node.
|
||||
Uint32 pushedList = nodeStackPtr->pushedList;
|
||||
while (pushedList != 0) {
|
||||
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
|
||||
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
|
||||
pushedList = nextName;
|
||||
}
|
||||
|
||||
// restore the previous frame.
|
||||
next = nodeStackPtr->next;
|
||||
limit = nodeStackPtr->limit;
|
||||
} else {
|
||||
Uint32 currentNode = *next++;
|
||||
Uint32 pushedList = 0;
|
||||
|
||||
|
||||
// Initialize the sets.
|
||||
pushed.clear();
|
||||
destinationList.clear();
|
||||
|
||||
// STEP1:
|
||||
// Walk the instruction list and to replace all the instruction uses with their new name.
|
||||
// If the instruction is a phi node and its defined register is alive at the end of this
|
||||
// block then we push the defined register into the stack.
|
||||
//
|
||||
ControlNode& node = *nodes[currentNode];
|
||||
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
|
||||
if (currentLiveOut != NULL) {
|
||||
// This is a phi node and we have to push its defined name if it is live
|
||||
// at the end of the node. We only need to do this if the CFG has critical edges.
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
|
||||
if (currentLiveOut->test(name))
|
||||
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
}
|
||||
|
||||
// STEP2:
|
||||
// Look at this node's successors' phiNodes. We keep track of the number of time
|
||||
// a VR will be used by another copy instruction and insert each definition into the
|
||||
// destinationList. This is the only pass over this node's successors as we will
|
||||
// get all the information we need in the CopyData structures.
|
||||
//
|
||||
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
|
||||
Uint32 useIndex = successorEdgePtr->getIndex();
|
||||
ControlNode& successor = successorEdgePtr->getTarget();
|
||||
|
||||
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
|
||||
// as soon as we find an instruction which is not a phi node
|
||||
InstructionList& phiNodes = successor.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
|
||||
|
||||
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
|
||||
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
|
||||
|
||||
assert(source.isRegister() && destination.isRegister());
|
||||
|
||||
RegisterName sourceName = source.getRegisterName();
|
||||
RegisterName destinationName = destination.getRegisterName();
|
||||
|
||||
// Get the correct name for the source.
|
||||
if (copyStats[sourceName].newName != NULL)
|
||||
sourceName = copyStats[sourceName].newName->newName;
|
||||
|
||||
// Update the CopyData structures.
|
||||
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
|
||||
copyStats[destinationName].source = sourceName;
|
||||
copyStats[destinationName].classKind = destination.getRegisterClass();
|
||||
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
|
||||
copyStats[destinationName].sourceNameToUse = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = sourceName;
|
||||
copyStats[sourceName].useCount++;
|
||||
destinationList.set(destinationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STEP3:
|
||||
// Insert into the worklist only the destination registers that will be not used in
|
||||
// another copy instruction in this block.
|
||||
//
|
||||
assert(workList.getSize() == 0);
|
||||
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
|
||||
Uint32 dest = destinationList.get(d);
|
||||
if (copyStats[dest].useCount == 0)
|
||||
workList.set(dest);
|
||||
}
|
||||
|
||||
// STEP4:
|
||||
// Insert the copy instructions.
|
||||
//
|
||||
Uint32 destinationListSize = destinationList.getSize();
|
||||
InstructionList::iterator endOfTheNode = instructions.end();
|
||||
|
||||
// Find the right place to insert the copy instructions.
|
||||
if (destinationListSize != 0)
|
||||
while (instructions.get(endOfTheNode).getFlags() & ifControl)
|
||||
endOfTheNode = instructions.retreat(endOfTheNode);
|
||||
|
||||
while (destinationListSize != 0) {
|
||||
while(workList.getSize()) {
|
||||
RegisterName destinationName = RegisterName(workList.getOne());
|
||||
RegisterName sourceName = copyStats[destinationName].source;
|
||||
|
||||
workList.clear(destinationName);
|
||||
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
|
||||
// Lost copy problem.
|
||||
copyStats[destinationName].isLiveOut = false;
|
||||
|
||||
RegisterName sourceName = destinationName;
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].useCount = 0;
|
||||
|
||||
// We need to insert a copy to a temporary register to keep the
|
||||
// source register valid at the end of the node defining it.
|
||||
// This copy will be inserted right after the phi node defining it.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
|
||||
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
|
||||
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
}
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterClassKind classKind = copyStats[destinationName].classKind;
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
|
||||
if (destinationList.test(sourceName))
|
||||
workList.set(sourceName);
|
||||
destinationList.clear(destinationName);
|
||||
}
|
||||
|
||||
destinationListSize = destinationList.getSize();
|
||||
if (destinationListSize != 0) {
|
||||
RegisterName sourceName = RegisterName(destinationList.getOne());
|
||||
RegisterName destinationName;
|
||||
|
||||
if (!copyStats[sourceName].temporaryName) {
|
||||
// Cycle problem.
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
} else
|
||||
destinationName = copyStats[sourceName].temporaryName;
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
|
||||
workList.set(sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
nodeStackPtr->pushedList = pushedList;
|
||||
nodeStackPtr->next = next;
|
||||
nodeStackPtr->limit = limit;
|
||||
++nodeStackPtr;
|
||||
next = dGraph.getSuccessorsBegin(currentNode);
|
||||
limit = dGraph.getSuccessorsEnd(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _PHI_NODE_REMOVER_H_
|
||||
@@ -1,155 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "PhiNodeRemover.h"
|
||||
#include "LiveRange.h"
|
||||
#include "Liveness.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
#include "Coalescing.h"
|
||||
#include "Spilling.h"
|
||||
#include "Coloring.h"
|
||||
#include "Splits.h"
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
class InstructionEmitter;
|
||||
|
||||
UT_DEFINE_LOG_MODULE(RegAlloc);
|
||||
|
||||
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
|
||||
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
|
||||
// some special code for the high word annotation.
|
||||
//
|
||||
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
|
||||
|
||||
// Perform some tests on the instruction graph.
|
||||
//
|
||||
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
|
||||
|
||||
// Replace the phi node instructions by their equivalent copy instructions.
|
||||
//
|
||||
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
|
||||
|
||||
// Do the register allocation.
|
||||
//
|
||||
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
|
||||
registerAllocator.doGraphColoring();
|
||||
}
|
||||
|
||||
void RegisterAllocator::doGraphColoring()
|
||||
{
|
||||
// Initialize the liverange map.
|
||||
//
|
||||
initLiveRanges();
|
||||
|
||||
// Build the live ranges. We do this to compress the number of RegisterNames
|
||||
// used in the insterference graph.
|
||||
//
|
||||
LiveRange<LowRegisterPressure>::build(*this);
|
||||
|
||||
// Remove unnecessary copies.
|
||||
//
|
||||
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
|
||||
|
||||
for (Uint8 loop = 0; loop < 10; loop++) {
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
|
||||
|
||||
while(true) {
|
||||
// Build the interference graph.
|
||||
//
|
||||
iGraph.build();
|
||||
|
||||
// Coalesce the copy instructions.
|
||||
//
|
||||
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the interference graph.
|
||||
//
|
||||
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Calculate the spill costs.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
|
||||
|
||||
// Calculate the split costs.
|
||||
//
|
||||
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
|
||||
|
||||
// Build the live range graph.
|
||||
//
|
||||
lGraph.build();
|
||||
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Color the graph. If it succeeds then we're done with the
|
||||
// register allocation.
|
||||
//
|
||||
if (Coloring<LowRegisterPressure>::color(*this)) {
|
||||
// Write the final colors in the instruction graph.
|
||||
//
|
||||
Coloring<LowRegisterPressure>::finalColoring(*this);
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to spill some registers.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::insertSpillCode(*this);
|
||||
|
||||
// Insert the split instructions.
|
||||
//
|
||||
Splits<LowRegisterPressure>::insertSplitCode(*this);
|
||||
|
||||
// Update the live ranges.
|
||||
//
|
||||
// FIX
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
RegisterAllocatorTools::updateInstructionGraph(*this);
|
||||
RegisterAllocatorTools::printInstructions(*this);
|
||||
#endif
|
||||
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void RegisterAllocator::initLiveRanges()
|
||||
{
|
||||
Uint32 count = this->nameCount;
|
||||
RegisterName* name2range = new(pool) RegisterName[nameCount];
|
||||
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
|
||||
name2range[r] = r;
|
||||
this->name2range = name2range;
|
||||
rangeCount = count;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_H_
|
||||
#define _REGISTER_ALLOCATOR_H_
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
struct SpillCost;
|
||||
struct SplitCost;
|
||||
|
||||
#include "Liveness.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h" // This should included by Backend.cpp
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
|
||||
//template <class RegisterPressure>
|
||||
class RegisterAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
Pool& pool; //
|
||||
ControlGraph& controlGraph; //
|
||||
VirtualRegisterManager& vrManager; //
|
||||
InstructionEmitter& emitter; //
|
||||
|
||||
RegisterName* name2range; //
|
||||
RegisterName* color; //
|
||||
SpillCost* spillCost; //
|
||||
SparseSet* willSpill; //
|
||||
SplitCost* splitCost; //
|
||||
NameLinkedList** splitAround; //
|
||||
InterferenceGraph<LowRegisterPressure> iGraph; //
|
||||
LiveRangeGraph<LowRegisterPressure> lGraph; //
|
||||
LivenessInfo<LowRegisterPressure> liveness; //
|
||||
Uint32 nameCount; //
|
||||
Uint32 rangeCount; //
|
||||
bool splitFound; //
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
//
|
||||
void doGraphColoring();
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
|
||||
|
||||
//
|
||||
//
|
||||
void initLiveRanges();
|
||||
|
||||
//
|
||||
//
|
||||
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_H_
|
||||
|
||||
@@ -1,355 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
#ifdef DEBUG
|
||||
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
|
||||
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
|
||||
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
BitSet registerSeen(controlGraph.pool, nameCount);
|
||||
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
bool renameRegisters = false;
|
||||
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
|
||||
renameRegisters = true;
|
||||
fprintf(stderr,
|
||||
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
|
||||
" is never used nor defined by any instruction in the instruction graph\n"
|
||||
" PLEASE FIX \n",
|
||||
i);
|
||||
}
|
||||
if (renameRegisters) {
|
||||
Instruction** definingInstruction = new Instruction*[nameCount];
|
||||
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
|
||||
RegisterName* newName = new RegisterName[nameCount];
|
||||
memset(newName, '\0', nameCount * sizeof(RegisterName));
|
||||
RegisterName nextName = RegisterName(1);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vrManager.setSize(nextName);
|
||||
|
||||
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
|
||||
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
|
||||
for (Uint32 i = 1; i < nameCount; i++)
|
||||
if (newName[i] != 0)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
|
||||
else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
|
||||
|
||||
|
||||
delete newName;
|
||||
delete definingInstruction;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.advance(i);
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
|
||||
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
|
||||
|
||||
if (source == destination)
|
||||
instruction.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
|
||||
// Set the index of the incoming edges.
|
||||
Uint32 index = 0;
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
|
||||
predecessors.get(p).setIndex(index++);
|
||||
|
||||
// Insert the phi node instruction in the instruction list.
|
||||
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
PhiNode& phiNode = phiNodes.get(i);
|
||||
ValueKind kind = phiNode.getKind();
|
||||
|
||||
if (!isStorableKind(kind))
|
||||
continue;
|
||||
|
||||
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
|
||||
Uint32 nInputs = phiNode.nInputs();
|
||||
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
|
||||
if (isDoublewordKind(kind)) {
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
|
||||
if (cost[i].infinite)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SplitCost* cost = registerAllocator.splitCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
|
||||
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
|
||||
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
phiNodes.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
if (!instructions.empty())
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
|
||||
}
|
||||
|
||||
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
instructions.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
@@ -1,117 +0,0 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
#define _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
#include "RegisterTypes.h"
|
||||
#include <string.h>
|
||||
|
||||
class RegisterAllocator;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
struct RegisterAllocatorTools
|
||||
{
|
||||
//
|
||||
//
|
||||
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
//
|
||||
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
static void printInstructions(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSpillCosts(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSplitCosts(RegisterAllocator& registerAllocator);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
//
|
||||
// FIX: this should go in a class (LookupTable ?)
|
||||
//
|
||||
|
||||
inline RegisterName findRoot(RegisterName name, RegisterName* table)
|
||||
{
|
||||
RegisterName* stack = table;
|
||||
RegisterName* stackPtr = stack;
|
||||
|
||||
RegisterName newName;
|
||||
while((newName = table[name]) != name) {
|
||||
*--stackPtr = name;
|
||||
name = newName;
|
||||
}
|
||||
|
||||
while (stackPtr != stack)
|
||||
table[*stackPtr++] = name;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void init(RegisterName* table, Uint32 nameCount)
|
||||
{
|
||||
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
|
||||
table[r] = r;
|
||||
}
|
||||
|
||||
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
|
||||
{
|
||||
RegisterName* liveRange = new RegisterName[tableSize];
|
||||
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
|
||||
|
||||
// Update the lookup table.
|
||||
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
|
||||
findRoot(r, table);
|
||||
|
||||
// Count the liveranges.
|
||||
Uint32 liveRangeCount = 1;
|
||||
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
|
||||
if (table[s] == s)
|
||||
liveRange[s] = RegisterName(liveRangeCount++);
|
||||
|
||||
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
|
||||
name2range[t] = liveRange[table[name2range[t]]];
|
||||
|
||||
return liveRangeCount;
|
||||
}
|
||||
|
||||
inline double doLog10(Uint32 power)
|
||||
{
|
||||
double log = 1.0;
|
||||
while (power--)
|
||||
log *= 10.0;
|
||||
return log;
|
||||
}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
@@ -1,104 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_TYPES_H_
|
||||
#define _REGISTER_TYPES_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterName -
|
||||
//
|
||||
|
||||
enum RegisterName {
|
||||
rnInvalid = 0,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterClassKind -
|
||||
//
|
||||
|
||||
enum RegisterClassKind {
|
||||
rckInvalid = 0,
|
||||
rckGeneral,
|
||||
rckStackSlot,
|
||||
|
||||
nRegisterClassKind
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterID -
|
||||
//
|
||||
|
||||
enum RegisterID {
|
||||
invalidID = 0
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterKind -
|
||||
//
|
||||
|
||||
enum RegisterKind {
|
||||
rkCallerSave = 0,
|
||||
rkCalleeSave,
|
||||
};
|
||||
|
||||
struct NameLinkedList {
|
||||
RegisterName name;
|
||||
NameLinkedList* next;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
const registerNameMask = 0x03ffffff;
|
||||
const coloredRegisterMask = 0x04000000;
|
||||
const machineRegisterMask = 0x08000000;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const coloredRegisterShift = 26;
|
||||
const machineRegisterShift = 27;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
const registerNameMask = 0x0fffffff;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
|
||||
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
|
||||
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
|
||||
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
|
||||
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
|
||||
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
|
||||
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // _REGISTER_TYPES_H_
|
||||
@@ -1,32 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SSATools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
if (!controlGraph.hasBackEdges)
|
||||
return;
|
||||
|
||||
Liveness liveness(controlGraph.pool);
|
||||
liveness.buildLivenessAnalysis(controlGraph, vrManager);
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _SPARSE_SET_H_
|
||||
#define _SPARSE_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "LogModule.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
class SparseSet
|
||||
{
|
||||
private:
|
||||
|
||||
struct Node {
|
||||
Uint32 element;
|
||||
Uint32 stackIndex;
|
||||
};
|
||||
|
||||
Node* node;
|
||||
Uint32 count;
|
||||
Uint32 universeSize;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
SparseSet(const SparseSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
|
||||
|
||||
// Clear the sparse set.
|
||||
void clear() {count = 0;}
|
||||
// Clear the element at index.
|
||||
inline void clear(Uint32 index);
|
||||
// Set the element at index.
|
||||
inline void set(Uint32 index);
|
||||
// Return true if the element at index is set.
|
||||
inline bool test(Uint32 index) const;
|
||||
// Union with the given sparse set.
|
||||
inline void or(const SparseSet& set);
|
||||
// Intersection with the given sparse set.
|
||||
inline void and(const SparseSet& set);
|
||||
// Difference with the given sparse set.
|
||||
inline void difference(const SparseSet& set);
|
||||
// Copy set.
|
||||
inline SparseSet& operator = (const SparseSet& set);
|
||||
inline SparseSet& operator = (const BitSet& set);
|
||||
// Return true if the sparse sets are identical.
|
||||
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
|
||||
// Return true if the sparse sets are different.
|
||||
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
|
||||
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
|
||||
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return count - 1;}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return --pos;}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos < 0;}
|
||||
// Return the element for the given iterator;
|
||||
Uint32 get(iterator pos) const {return node[pos].element;}
|
||||
// Return one element of this set.
|
||||
Uint32 getOne() const {assert(count > 0); return node[0].element;}
|
||||
// Return the size of this set.
|
||||
Uint32 getSize() const {return count;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
inline void SparseSet::clear(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex < count) && (node[stackIndex].element == element)) {
|
||||
Uint32 stackTop = node[count - 1].element;
|
||||
|
||||
node[stackIndex].element = stackTop;
|
||||
node[stackTop].stackIndex = stackIndex;
|
||||
this->count = count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SparseSet::set(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
|
||||
node[count].element = element;
|
||||
node[element].stackIndex = count;
|
||||
this->count = count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SparseSet::test(Uint32 element) const
|
||||
{
|
||||
checkMember(element);
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
return ((stackIndex < count) && (node[stackIndex].element == element));
|
||||
}
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const SparseSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Uint32 sourceCount = set.getSize();
|
||||
Node* node = this->node;
|
||||
|
||||
memcpy(node, set.node, sourceCount * sizeof(Node));
|
||||
|
||||
for (Uint32 i = 0; i < sourceCount; i++) {
|
||||
Uint32 element = node[i].element;
|
||||
node[element].stackIndex = i;
|
||||
}
|
||||
|
||||
count = sourceCount;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const BitSet& set)
|
||||
{
|
||||
// FIX: there's room for optimization here.
|
||||
assert(universeSize == set.getSize());
|
||||
|
||||
clear();
|
||||
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
|
||||
this->set(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // _SPARSE_SET_H_
|
||||
@@ -1,270 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
#define INCLUDE_EMITTER
|
||||
#include "CpuInfo.h"
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Spilling.h"
|
||||
|
||||
|
||||
void Spilling::
|
||||
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
|
||||
{
|
||||
PRUint32 nVirtualRegisters = vRegManager.count();
|
||||
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
|
||||
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
|
||||
RegisterFifo grNeedLoad(nVirtualRegisters);
|
||||
RegisterFifo fpNeedLoad(nVirtualRegisters);
|
||||
|
||||
for (PRInt32 n = nNodes - 1; n >= 0; n--)
|
||||
{
|
||||
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
|
||||
ControlNode& node = *dfsList[n];
|
||||
|
||||
currentLive = node.liveAtEnd;
|
||||
|
||||
PRUint32 nGeneralAlive = 0;
|
||||
PRUint32 nFloatingPointAlive = 0;
|
||||
|
||||
// Get the number of registers alive at the end of this node.
|
||||
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
|
||||
if (vReg.spillInfo.willSpill)
|
||||
{
|
||||
currentLive.clear(j);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
|
||||
{
|
||||
Instruction& instruction = instructions.get(i);
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* defPtr;
|
||||
|
||||
// if(node.dfsNum == 8) { printf("\n");
|
||||
// instruction.printPretty(stdout);
|
||||
// printf("\n"); }
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
currentLive.clear(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive--;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deaths
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
if (!currentLive.test(vReg.getRegisterIndex()))
|
||||
// This is the last use of this register.
|
||||
{
|
||||
currentLive.set(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = grNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nGeneralAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = fpNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nFloatingPointAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle uses
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
PRUint32 registerIndex = vReg.getRegisterIndex();
|
||||
|
||||
if (vReg.spillInfo.willSpill) {
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (!grNeedLoad.test(registerIndex))
|
||||
{
|
||||
grNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/* if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
if (!fpNeedLoad.test(registerIndex))
|
||||
{
|
||||
fpNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/*if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
usedInThisInstruction.set(registerIndex);
|
||||
vReg.spillInfo.lastUsingInstruction = &instruction;
|
||||
}
|
||||
currentLive.clear(registerIndex);
|
||||
} else { // will not spill
|
||||
currentLive.set(registerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
|
||||
if (vReg.spillInfo.willSpill)
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
|
||||
// this virtualRegister was used in this instruction and is also defined. We need to move
|
||||
// this virtual register to its alias first and then save it to memory.
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
|
||||
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg, *vReg.equivalentRegister[vrcStackSlot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = grNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
while (!fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = fpNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,269 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPILLING_H_
|
||||
#define _SPILLING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Spilling
|
||||
{
|
||||
private:
|
||||
static void insertStoreAfter(Instruction& instruction, RegisterName name);
|
||||
static void insertLoadBefore(Instruction& instruction, RegisterName name);
|
||||
|
||||
public:
|
||||
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
|
||||
static void insertSpillCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SpillCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
double copies;
|
||||
double cost;
|
||||
bool infinite;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
SparseSet& willSpill = *registerAllocator.willSpill;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
needLoad.clear();
|
||||
currentLive = liveOut[n];
|
||||
mustSpill = currentLive;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.retreat(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
bool foundLiveDefine = false;
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
if (defineBegin != defineEnd && !foundLiveDefine) {
|
||||
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
|
||||
instruction.remove();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
#ifdef DEBUG
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
|
||||
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
|
||||
abort();
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (willSpill.test(range))
|
||||
insertStoreAfter(instruction, range);
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!currentLive.test(range))
|
||||
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
|
||||
RegisterName load = RegisterName(needLoad.get(r));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instruction, load);
|
||||
mustSpill.set(load);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
currentLive.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
RegisterName load = RegisterName(needLoad.get(l));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instructions.first(), load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert load for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert store for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet live(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
|
||||
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
|
||||
|
||||
SpillCost* cost = new SpillCost[rangeCount];
|
||||
memset(cost, '\0', rangeCount * sizeof(SpillCost));
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
needLoad.clear();
|
||||
live = liveOut[n];
|
||||
mustSpill = live;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range))
|
||||
cost[range].infinite = true;
|
||||
|
||||
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
|
||||
cost[range].stores += weight;
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
if (!live.test(name2range[usePtr->getRegisterName()])) {
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
Uint32 range = needLoad.get(l);
|
||||
cost[range].loads += weight;
|
||||
mustSpill.set(range);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
|
||||
live.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[useBegin[0].getRegisterName()];
|
||||
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
|
||||
|
||||
cost[source].copies += weight;
|
||||
cost[destination].copies += weight;
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
|
||||
cost[needLoad.get(s)].loads += weight;
|
||||
}
|
||||
|
||||
for (Uint32 r = 0; r < rangeCount; r++) {
|
||||
SpillCost& c = cost[r];
|
||||
c.cost = 2 * (c.loads + c.stores) - c.copies;
|
||||
}
|
||||
|
||||
registerAllocator.spillCost = cost;
|
||||
}
|
||||
|
||||
#endif // _SPILLING_H_
|
||||
@@ -1,239 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPLITS_H_
|
||||
#define _SPLITS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Splits
|
||||
{
|
||||
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
|
||||
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
|
||||
static void insertSplitCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SplitCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
|
||||
{
|
||||
// FIX
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
|
||||
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
|
||||
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >=0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
RegisterName c = color[neighbor];
|
||||
|
||||
if (c < 6) { // FIX
|
||||
NameLinkedList* node = new(pool) NameLinkedList();
|
||||
node->name = neighbor;
|
||||
node->next = neighborsWithColor[c];
|
||||
neighborsWithColor[c] = node;
|
||||
}
|
||||
}
|
||||
|
||||
bool splitAroundName = true;
|
||||
|
||||
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
|
||||
RegisterName bestColor = RegisterName(6); // FIX
|
||||
double bestCost = registerAllocator.spillCost[range].cost;
|
||||
SplitCost* splitCost = registerAllocator.splitCost;
|
||||
|
||||
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
|
||||
|
||||
double splitAroundNameCost = 0.0;
|
||||
bool canSplitAroundName = true;
|
||||
|
||||
SplitCost& sCost = splitCost[range];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(neighbor, range)) {
|
||||
canSplitAroundName = false;
|
||||
break;
|
||||
} else
|
||||
splitAroundNameCost += addedCost;
|
||||
}
|
||||
if (canSplitAroundName && splitAroundNameCost < bestCost) {
|
||||
bestCost = splitAroundNameCost;
|
||||
bestColor = i;
|
||||
splitAroundName = true;
|
||||
}
|
||||
|
||||
double splitAroundColorCost = 0.0;
|
||||
bool canSplitAroundColor = true;
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(range, neighbor)) {
|
||||
canSplitAroundColor = false;
|
||||
break;
|
||||
} else {
|
||||
SplitCost& sCost = splitCost[neighbor];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
splitAroundColorCost += addedCost;
|
||||
}
|
||||
}
|
||||
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
|
||||
bestCost = splitAroundColorCost;
|
||||
bestColor = i;
|
||||
splitAroundName = false;
|
||||
}
|
||||
}
|
||||
if (bestColor < RegisterName(6)) {
|
||||
color[range] = bestColor;
|
||||
registerAllocator.splitFound = true;
|
||||
|
||||
NameLinkedList** splitAround = registerAllocator.splitAround;
|
||||
|
||||
if (splitAroundName)
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
newNode->name = node->name;
|
||||
newNode->next = splitAround[range];
|
||||
splitAround[range] = newNode;
|
||||
}
|
||||
else
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
RegisterName neighbor = node->name;
|
||||
newNode->name = range;
|
||||
newNode->next = splitAround[neighbor];
|
||||
splitAround[neighbor] = newNode;
|
||||
}
|
||||
|
||||
trespass("Found a split");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
|
||||
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
|
||||
|
||||
SparseSet live(pool, rangeCount);
|
||||
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
live = liveOut[n];
|
||||
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
|
||||
ControlNode& successor = successorsPtr->getTarget();
|
||||
|
||||
if (successor.getControlKind() != ckEnd) {
|
||||
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
|
||||
|
||||
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
|
||||
RegisterName name = RegisterName(live.get(i));
|
||||
if (!successorLiveIn.test(name))
|
||||
splitCost[name].loads += doLog10(successor.loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!live.test(range)) {
|
||||
if (&instruction != &instructions.last())
|
||||
splitCost[range].loads += weight;
|
||||
else {
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
|
||||
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
live.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
|
||||
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
|
||||
registerAllocator.splitAround = splitAround;
|
||||
|
||||
registerAllocator.splitCost = splitCost;
|
||||
registerAllocator.splitFound = false;
|
||||
}
|
||||
|
||||
#endif // _SPLITS_H_
|
||||
@@ -1,186 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "Timer.h"
|
||||
#include "Pool.h"
|
||||
|
||||
static Pool pool; // Pool for the Timer class.
|
||||
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
|
||||
|
||||
const nTimersInABlock = 128; // Number of timers in a block.
|
||||
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
|
||||
static Uint8 nextTimer = 0; // nextAvailableTimer.
|
||||
|
||||
//
|
||||
// Calibrate the call to PR_Now().
|
||||
//
|
||||
static PRTime calibrate()
|
||||
{
|
||||
PRTime t = PR_Now();
|
||||
PRTime& a = *new(pool) PRTime();
|
||||
|
||||
// Call 10 times the PR_Now() function.
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
t = (PR_Now() - t + 9) / 10;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static PRTime adjust = calibrate();
|
||||
|
||||
//
|
||||
// Return the named timer..
|
||||
//
|
||||
TimerEntry& Timer::getTimerEntry(const char* name)
|
||||
{
|
||||
if (!timerEntries.exists(name)) {
|
||||
TimerEntry* newEntry = new(pool) TimerEntry();
|
||||
newEntry->accumulator = 0;
|
||||
newEntry->running = false;
|
||||
timerEntries.add(name, newEntry);
|
||||
}
|
||||
|
||||
return *timerEntries[name];
|
||||
}
|
||||
|
||||
//
|
||||
// Return a reference to a new timer.
|
||||
//
|
||||
PRTime& Timer::getNewTimer()
|
||||
{
|
||||
if (nextTimer >= nTimersInABlock) {
|
||||
timers = new(pool) PRTime[nTimersInABlock];
|
||||
nextTimer = 0;
|
||||
}
|
||||
return timers[nextTimer++];
|
||||
}
|
||||
|
||||
static Uint32 timersAreFrozen = 0;
|
||||
|
||||
//
|
||||
// Start the named timer.
|
||||
//
|
||||
void Timer::start(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(!timer.running);
|
||||
|
||||
timer.accumulator = 0;
|
||||
timer.running = true;
|
||||
timer.done = false;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Stop the named timer.
|
||||
//
|
||||
void Timer::stop(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(timer.running);
|
||||
timer.running = false;
|
||||
timer.done = true;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Freeze all the running timers.
|
||||
//
|
||||
void Timer::freezeTimers()
|
||||
{
|
||||
PRTime when = PR_Now() - adjust;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry*> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.accumulator += (when - *entry.startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
timersAreFrozen++;
|
||||
}
|
||||
|
||||
//
|
||||
// Unfreeze all the running timers.
|
||||
//
|
||||
void Timer::unfreezeTimers()
|
||||
{
|
||||
PR_ASSERT(timersAreFrozen != 0);
|
||||
timersAreFrozen--;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry *> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
PRTime& newStart = getNewTimer();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.startTime = &newStart;
|
||||
}
|
||||
}
|
||||
|
||||
newStart = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print the named timer in the file f.
|
||||
//
|
||||
void Timer::print(FILE* f, const char *name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
|
||||
PR_ASSERT(timer.done);
|
||||
PRTime elapsed = timer.accumulator;
|
||||
|
||||
if (elapsed >> 32) {
|
||||
fprintf(f, "[timer %s out of range]\n", name);
|
||||
} else {
|
||||
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "prtime.h"
|
||||
|
||||
//
|
||||
// Naming convention:
|
||||
// As the class Timer contains only static methods, the timer's name should start with the
|
||||
// module name. Otherwise starting 2 timers with the same name will assert.
|
||||
//
|
||||
|
||||
#ifndef NO_TIMER
|
||||
|
||||
struct TimerEntry
|
||||
{
|
||||
PRTime *startTime; // Current time when we start the timer.
|
||||
PRTime accumulator; // Time spent in this timer.
|
||||
bool running; // True if the timer is running.
|
||||
bool done; // True if the timer was running and was stopped.
|
||||
};
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
|
||||
// Return the named timer.
|
||||
static TimerEntry& getTimerEntry(const char* name);
|
||||
// Return a reference to a new Timer.
|
||||
static PRTime& getNewTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Start the timer.
|
||||
static void start(const char* name);
|
||||
// Stop the timer.
|
||||
static void stop(const char* name);
|
||||
// Freeze all the running timers.
|
||||
static void freezeTimers();
|
||||
// Unfreeze all the running timers.
|
||||
static void unfreezeTimers();
|
||||
// Print the timer.
|
||||
static void print(FILE* f, const char *name);
|
||||
};
|
||||
|
||||
inline void startTimer(const char* name) {Timer::start(name);}
|
||||
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
|
||||
#define START_TIMER_SAFE Timer::freezeTimers();
|
||||
#define END_TIMER_SAFE Timer::unfreezeTimers();
|
||||
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
|
||||
|
||||
#else /* NO_TIMER */
|
||||
|
||||
inline void startTimer(const char* /*name*/) {}
|
||||
inline void stopTimer(const char* /*name*/) {}
|
||||
#define START_TIMER_SAFE
|
||||
#define END_TIMER_SAFE
|
||||
#define TIMER_SAFE(x) x;
|
||||
|
||||
#endif /* NO_TIMER */
|
||||
#endif /* _TIMER_H_ */
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Instruction.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister -
|
||||
|
||||
#ifdef MANUAL_TEMPLATES
|
||||
template class IndexedPool<VirtualRegister>;
|
||||
#endif
|
||||
|
||||
// Set the defining instruction.
|
||||
//
|
||||
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||
{
|
||||
if (definingInstruction != NULL) {
|
||||
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||
return;
|
||||
}
|
||||
definingInstruction = &instruction;
|
||||
}
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTUAL_REGISTER_H_
|
||||
#define _VIRTUAL_REGISTER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "IndexedPool.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "RegisterTypes.h"
|
||||
#include "RegisterClass.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister - 24b
|
||||
|
||||
class Instruction;
|
||||
|
||||
class VirtualRegister : public IndexedObject<VirtualRegister>
|
||||
{
|
||||
public:
|
||||
|
||||
Instruction* definingInstruction; // Instruction defining this VR.
|
||||
|
||||
// Initialize a VR of the given classKind.
|
||||
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
|
||||
|
||||
// Return the defining instruction for this VR.
|
||||
Instruction* getDefiningInstruction() const {return definingInstruction;}
|
||||
// Set the defining instruction.
|
||||
void setDefiningInstruction(Instruction& insn);
|
||||
};
|
||||
|
||||
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
|
||||
// they have the same index. If they have the same index then they are at the same
|
||||
// address in the indexed pool.
|
||||
//
|
||||
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return ®A == ®B;}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegisterManager -
|
||||
|
||||
struct PreColoredRegister
|
||||
{
|
||||
RegisterID id;
|
||||
RegisterName color;
|
||||
};
|
||||
|
||||
class VirtualRegisterManager
|
||||
{
|
||||
private:
|
||||
|
||||
IndexedPool<VirtualRegister> registerPool;
|
||||
PreColoredRegister machineRegister[6];
|
||||
|
||||
public:
|
||||
VirtualRegisterManager()
|
||||
{
|
||||
for (Uint32 i = 0; i < 6; i++)
|
||||
machineRegister[i].id = invalidID;
|
||||
}
|
||||
|
||||
// Return the VirtualRegister at the given index.
|
||||
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
|
||||
|
||||
// Return a new VirtualRegister.
|
||||
RegisterID newVirtualRegister(RegisterClassKind classKind)
|
||||
{
|
||||
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
|
||||
RegisterID rid;
|
||||
|
||||
setName(rid, RegisterName(vReg.getIndex()));
|
||||
setClass(rid, classKind);
|
||||
return rid;
|
||||
}
|
||||
|
||||
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
|
||||
{
|
||||
RegisterID rid = machineRegister[name].id;
|
||||
|
||||
if (rid == invalidID) {
|
||||
rid = newVirtualRegister(classKind);
|
||||
DEBUG_ONLY(setMachineRegister(rid));
|
||||
machineRegister[name].id = rid;
|
||||
machineRegister[name].color = name;
|
||||
}
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
|
||||
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
|
||||
|
||||
// Return the VirtualRegister universe size.
|
||||
Uint32 getSize() {return registerPool.getSize();}
|
||||
|
||||
void setSize(Uint32 size) {registerPool.setSize(size);}
|
||||
};
|
||||
|
||||
#endif // _VIRTUAL_REGISTER_H_
|
||||
9
mozilla/modules/rdf/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
DIRS = include src
|
||||
|
||||
INCLUDE = $(INCLUDE) -I$(DEPTH)/modules/libimg/public
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
14
mozilla/modules/rdf/Makefile.in
Normal file
@@ -0,0 +1,14 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = include src
|
||||
|
||||
INCLUDE += -I$(topsrcdir)/modules/libimg/public
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
BIN
mozilla/modules/rdf/images/channels.gif
Normal file
|
After Width: | Height: | Size: 269 B |
BIN
mozilla/modules/rdf/images/file.gif
Normal file
|
After Width: | Height: | Size: 126 B |
BIN
mozilla/modules/rdf/images/guide.gif
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
mozilla/modules/rdf/images/history.gif
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
mozilla/modules/rdf/images/ldap.gif
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
mozilla/modules/rdf/images/personal.gif
Normal file
|
After Width: | Height: | Size: 126 B |
BIN
mozilla/modules/rdf/images/search.gif
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
mozilla/modules/rdf/images/sitemap.gif
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
8
mozilla/modules/rdf/include/MANIFEST
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
rdf.h
|
||||
vocab.h
|
||||
htrdf.h
|
||||
jsec2rdf.h
|
||||
26
mozilla/modules/rdf/include/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
MODULE = rdf
|
||||
DEPTH = ../../..
|
||||
EXPORTS = rdf.h htrdf.h vocab.h jsec2rdf.h
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
33
mozilla/modules/rdf/include/Makefile.in
Normal file
@@ -0,0 +1,33 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
MODULE = rdf
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
EXPORTS = rdf.h htrdf.h vocab.h jsec2rdf.h
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
8
mozilla/modules/rdf/include/export.mac
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
rdf.h
|
||||
vocab.h
|
||||
htrdf.h
|
||||
jsec2rdf.h
|
||||
580
mozilla/modules/rdf/include/htrdf.h
Normal file
@@ -0,0 +1,580 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef htrdf_h___
|
||||
#define htrdf_h___
|
||||
|
||||
/* the RDF HT API */
|
||||
|
||||
#include "rdf.h"
|
||||
|
||||
#ifdef XPCOM_XXX
|
||||
#include "ntypes.h"
|
||||
#include "structs.h"
|
||||
#include "pa_parse.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hyper Tree Api
|
||||
*
|
||||
* Hyper tree is the tree view of the rdf store. This is for use by the FE in
|
||||
* implementing the nav center.
|
||||
*
|
||||
* The RDF structure could be a gnarly graph whose nodes are RDF_Resource.
|
||||
* There can be multiple tree views (HT_View) into this graph. Corresponding
|
||||
* to each view, there is a hyper tree whose nodes are HT_Resource.
|
||||
* Each HT_Resource belongs to exactly one HT_View.
|
||||
* The FE iterate over the hypertree to draw it. It can start the iteration
|
||||
* either at the top or at some interior node. When some state change occurs
|
||||
* in the hypertree, the FE will get notified about the node on which the
|
||||
* change took place. At that point, it can either redraw the whole thing
|
||||
* or do a partial redraw. The FE does this by iterating over the relevant
|
||||
* portions of the hypertree. Since the hypertree is a strict tree, the FE
|
||||
* can also iterate upwards.
|
||||
*
|
||||
*
|
||||
* Possible state changes to the hypertree of an HT_View include :
|
||||
* (i) addition/deletion of nodes
|
||||
* (ii) containers closing/opening
|
||||
* (iii) selection changes
|
||||
* These changes could occur either because of
|
||||
* (i) User clicking around the tree
|
||||
* (ii) Network activity
|
||||
* (iii) scripts running
|
||||
* The FE can recieve notifications about these activities.
|
||||
* If the FE does not want to be notified about something, it can set
|
||||
* the notification mask to block certain notifications.
|
||||
*/
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
/* Opaque data structures */
|
||||
typedef struct _HT_ViewStruct* HT_View;
|
||||
|
||||
typedef struct _HT_PaneStruct* HT_Pane;
|
||||
|
||||
typedef struct _HT_CursorStruct* HT_Cursor;
|
||||
|
||||
typedef struct _HT_ResourceStruct* HT_Resource;
|
||||
|
||||
/* for use with HT_GetTemplate */
|
||||
enum TemplateType {
|
||||
ht_template_chrome,
|
||||
ht_template_management,
|
||||
ht_template_navigation
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the Notification structure that gets passed to the HT layer on
|
||||
* creation of the view. This should be allocated/static memory. HT layer
|
||||
* will store a pointer to this structure. On CloseView, a View Closed
|
||||
* event will be generated and the notification function will be called.
|
||||
* At this point, the module using HT can free the memory associated with
|
||||
* the HT_Notification struct.
|
||||
*/
|
||||
|
||||
|
||||
typedef uint32 HT_NotificationMask;
|
||||
typedef uint32 HT_Event;
|
||||
typedef uint32 HT_Error;
|
||||
|
||||
#define HT_NoErr 0
|
||||
#define HT_Err 1
|
||||
|
||||
struct _HT_NotificationStruct;
|
||||
|
||||
typedef void (*HT_NotificationProc)(struct _HT_NotificationStruct*,
|
||||
HT_Resource node, HT_Event whatHappened, void *param, uint32 tokenType);
|
||||
typedef struct _HT_NotificationStruct {
|
||||
HT_NotificationProc notifyProc;
|
||||
void *data;
|
||||
} HT_NotificationStruct;
|
||||
|
||||
|
||||
/*
|
||||
* HT_Notification events and masks
|
||||
*/
|
||||
|
||||
|
||||
typedef HT_NotificationStruct* HT_Notification;
|
||||
|
||||
#define HT_EVENT_NODE_ADDED 0x00000001UL
|
||||
#define HT_EVENT_NODE_DELETED_DATA 0x00000002UL
|
||||
#define HT_EVENT_NODE_DELETED_NODATA 0x00000004UL
|
||||
#define HT_EVENT_NODE_VPROP_CHANGED 0x00000008UL
|
||||
#define HT_EVENT_NODE_SELECTION_CHANGED 0x00000010UL
|
||||
#define HT_EVENT_NODE_OPENCLOSE_CHANGED 0x00000020UL
|
||||
#define HT_EVENT_VIEW_CLOSED 0x00000040UL /* same as HT_EVENT_VIEW_DELETED */
|
||||
#define HT_EVENT_VIEW_DELETED 0x00000040UL /* same as HT_EVENT_VIEW_CLOSED */
|
||||
#define HT_EVENT_VIEW_SELECTED 0x00000080UL
|
||||
#define HT_EVENT_VIEW_ADDED 0x00000100UL
|
||||
#define HT_EVENT_NODE_OPENCLOSE_CHANGING 0x00000200UL
|
||||
#define HT_EVENT_VIEW_SORTING_CHANGED 0x00000400UL
|
||||
#define HT_EVENT_VIEW_REFRESH 0x00000800UL
|
||||
#define HT_EVENT_VIEW_WORKSPACE_REFRESH 0x00001000UL
|
||||
#define HT_EVENT_NODE_EDIT 0x00002000UL
|
||||
#define HT_EVENT_WORKSPACE_EDIT 0x00004000UL
|
||||
#define HT_EVENT_VIEW_HTML_ADD 0x00008000UL
|
||||
#define HT_EVENT_VIEW_HTML_REMOVE 0x00010000UL
|
||||
#define HT_EVENT_NODE_ENABLE 0x00020000UL
|
||||
#define HT_EVENT_NODE_DISABLE 0x00040000UL
|
||||
#define HT_EVENT_NODE_SCROLLTO 0x00080000UL
|
||||
#define HT_EVENT_COLUMN_ADD 0x00100000UL
|
||||
#define HT_EVENT_COLUMN_DELETE 0x00200000UL
|
||||
#define HT_EVENT_COLUMN_SIZETO 0x00400000UL
|
||||
#define HT_EVENT_COLUMN_REORDER 0x00800000UL
|
||||
#define HT_EVENT_COLUMN_SHOW 0x01000000UL
|
||||
#define HT_EVENT_COLUMN_HIDE 0x02000000UL
|
||||
#define HT_EVENT_VIEW_MODECHANGED 0x04000000UL
|
||||
#define HT_EVENT_VIEW_WINDOWTYPE_CHANGED 0x04000000UL
|
||||
|
||||
#define HT_EVENT_NO_NOTIFICATION_MASK 0x00000000UL
|
||||
#define HT_EVENT_DEFAULT_NOTIFICATION_MASK 0xFFFFFFFFUL
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* View/Pane Creation / Destruction / Management */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/* Window Types for Panes */
|
||||
#define HT_POPUP_WINDOW 0
|
||||
#define HT_DOCKED_WINDOW 1
|
||||
#define HT_STANDALONE_WINDOW 2
|
||||
#define HT_EMBEDDED_WINDOW 3
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_PaneFromResource(RDF_Resource r, HT_Notification n, PRBool autoFlush, PRBool autoOpen, PRBool useColumns);
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_PaneFromURL(void* context, char* url, char* templateType,
|
||||
HT_Notification n, PRBool autoFlush, int32 param_count,
|
||||
char** param_names, char** param_values);
|
||||
|
||||
/* NewQuickFilePane
|
||||
* Creates a pane consisting of one view. This view has the RDF resource
|
||||
* corresponding to the Quickfile folder as its root.
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_NewQuickFilePane (HT_Notification notify);
|
||||
|
||||
/* NewToolbarPane
|
||||
* Added by Dave
|
||||
* Create a pane consisting of multiple views. Each view corresponds to a single toolbar.
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Pane) HT_NewToolbarPane (HT_Notification notify);
|
||||
|
||||
/* NewPersonalToolbarPane
|
||||
* Creates a pane consisting of one view. This view has the RDF resource
|
||||
* corresponding to the Personal Toolbar folder as its root.
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_NewPersonalToolbarPane (HT_Notification notify);
|
||||
|
||||
/* HT_NewBreadcrumbPane
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_NewBreadcrumbPane (HT_Notification notify);
|
||||
|
||||
PR_PUBLIC_API(void) HT_AddToContainer (HT_Resource container, char *url, char *optionalTitle);
|
||||
PR_PUBLIC_API(void) HT_AddBookmark (char *url, char *optionalTitle);
|
||||
|
||||
/* CreateView
|
||||
* Takes an rdf node as the root of the view tree and creates a XP view.
|
||||
* HT_Notification would be to the notifier when there is a state change.
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_NewPane (HT_Notification notify);
|
||||
|
||||
/* DeleteView
|
||||
* Destroy a valid view created via CreateView
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Error) HT_DeleteView (HT_View view);
|
||||
PR_PUBLIC_API(HT_Error) HT_DeletePane (HT_Pane pane);
|
||||
|
||||
/* HT_TopNode
|
||||
* Obtain the top node associated with a view tree
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Resource) HT_TopNode (HT_View view);
|
||||
|
||||
PR_PUBLIC_API(void*) HT_GetViewFEData (HT_View node);
|
||||
PR_PUBLIC_API(void) HT_SetViewFEData (HT_View node, void* data);
|
||||
PR_PUBLIC_API(void*) HT_GetPaneFEData (HT_Pane pane);
|
||||
PR_PUBLIC_API(void) HT_SetPaneFEData (HT_Pane pane, void* data);
|
||||
|
||||
PR_PUBLIC_API(HT_View) HT_GetSelectedView (HT_Pane pane);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetSelectedView (HT_Pane pane, HT_View view);
|
||||
|
||||
#ifdef XPCOM_XXX
|
||||
PR_PUBLIC_API(void) HT_LayoutComplete(MWContext *context, TagList *metaTags, char *url);
|
||||
#endif
|
||||
|
||||
enum _HT_ViewType {
|
||||
HT_VIEW_BOOKMARK=0, HT_VIEW_HISTORY, HT_VIEW_SITEMAP, HT_VIEW_FILES, HT_VIEW_SEARCH
|
||||
} ;
|
||||
typedef enum _HT_ViewType HT_ViewType;
|
||||
|
||||
/*
|
||||
* HT_GetViewType: find a particular view type (returns NULL if not found or unknown)
|
||||
*/
|
||||
PR_PUBLIC_API(HT_View) HT_GetViewType (HT_Pane pane, HT_ViewType viewType);
|
||||
|
||||
|
||||
/*
|
||||
* HT_GetView
|
||||
* Obtain the view tree associated with a node
|
||||
*/
|
||||
PR_PUBLIC_API(HT_View) HT_GetView (HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Pane) HT_GetPane (HT_View view);
|
||||
|
||||
/*
|
||||
* HT_GetViewData / HT_SetViewData
|
||||
* get/set FE specific data to be associated with a view
|
||||
*/
|
||||
PR_PUBLIC_API(void*) HT_GetNodeFEData (HT_Resource node);
|
||||
PR_PUBLIC_API(void) HT_SetNodeFEData (HT_Resource node, void* data);
|
||||
|
||||
/*
|
||||
* HT_GetNotificationMask / HT_SetNotificationMask
|
||||
* get/set the notification mask associated with a view
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Error) HT_GetNotificationMask (HT_Pane node, HT_NotificationMask *mask);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetNotificationMask (HT_Pane node, HT_NotificationMask mask);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* View Traversal */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
PR_PUBLIC_API(char *) HT_GetViewName(HT_View view);
|
||||
|
||||
/*
|
||||
* HT_GetNthView
|
||||
*/
|
||||
PR_PUBLIC_API(HT_View) HT_GetNthView (HT_Pane pane, uint32 theIndex);
|
||||
PR_PUBLIC_API(uint32) HT_GetViewIndex(HT_View view);
|
||||
PR_PUBLIC_API(uint32) HT_GetViewListCount(HT_Pane pane);
|
||||
|
||||
/*
|
||||
* HT_GetNthItem / HT_GetNodeIndex
|
||||
* get the nth resource in a view (or NULL if not in view),
|
||||
* or find a resource's index in a view
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Resource) HT_GetNthItem (HT_View view, uint32 theIndex);
|
||||
PR_PUBLIC_API(uint32) HT_GetNodeIndex(HT_View view, HT_Resource node);
|
||||
PR_PUBLIC_API(uint32) HT_GetItemListCount(HT_View view);
|
||||
PR_PUBLIC_API(uint16) HT_GetItemIndentation(HT_Resource r);
|
||||
/*
|
||||
* HT_GetParent
|
||||
* obtain the parent of a node
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Resource) HT_GetParent (HT_Resource node);
|
||||
|
||||
/*
|
||||
* HT_NodeDisplayString/HT_ViewDisplayString (obsolete)
|
||||
* obtain the name of a node
|
||||
*/
|
||||
PR_PUBLIC_API(HT_Error) HT_NodeDisplayString (HT_Resource node, char *buffer, int bufferLen); /* obsolete! */
|
||||
PR_PUBLIC_API(HT_Error) HT_ViewDisplayString (HT_View view, char *buffer, int bufferLen); /* obsolete! */
|
||||
|
||||
/* an API for external access to the templates. It takes a specifier
|
||||
defined by enum TemplateType, in this file. HT_GetTemplate() returns
|
||||
the basic HT_Pane corresponding to the requested type. */
|
||||
PR_PUBLIC_API(HT_Pane) HT_GetTemplate(int templateType);
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_GetTemplateData(HT_Resource node, void* token, uint32 tokenType, void **nodeData);
|
||||
PR_PUBLIC_API(PRBool) HT_GetNodeData (HT_Resource node, void *token,
|
||||
uint32 tokenType, void **data);
|
||||
PR_PUBLIC_API(PRBool) HT_IsNodeDataEditable(HT_Resource node,
|
||||
void *token, uint32 tokenType);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetNodeData (HT_Resource node, void *token,
|
||||
uint32 tokenType, void *data);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetNodeName (HT_Resource node, void *data);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetTreeStateForButton(HT_Resource node, int state);
|
||||
PR_PUBLIC_API(int) HT_GetTreeStateForButton(HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetWindowType(HT_Pane pane, int windowType);
|
||||
PR_PUBLIC_API(int) HT_GetWindowType(HT_Pane pane);
|
||||
|
||||
/*
|
||||
* HT_GetLargeIconURL / HT_GetSmallIconURL
|
||||
* obtain the large/small icon URLs for a node if available, otherwise return NULL
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(char *) HT_GetWorkspaceLargeIconURL (HT_View view);
|
||||
PR_PUBLIC_API(char *) HT_GetWorkspaceSmallIconURL (HT_View view);
|
||||
PR_PUBLIC_API(char *) HT_GetNodeLargeIconURL (HT_Resource r);
|
||||
PR_PUBLIC_API(char *) HT_GetNodeSmallIconURL (HT_Resource r);
|
||||
PR_PUBLIC_API(char *) HT_GetIconURL(HT_Resource r, PRBool isToolbarIcon, PRBool isWorkspace, int buttonState);
|
||||
|
||||
PR_PUBLIC_API(char *) HT_GetLargeIconURL (HT_Resource r); /* obsolete! */
|
||||
PR_PUBLIC_API(char *) HT_GetSmallIconURL (HT_Resource r); /* obsolete! */
|
||||
|
||||
/*
|
||||
* HT_NewColumnCursor / HT_GetNextColumn / HT_DeleteColumnCursor
|
||||
* obtain column information
|
||||
*/
|
||||
|
||||
enum _HT_ColumnType {
|
||||
HT_COLUMN_UNKNOWN=0, HT_COLUMN_STRING, HT_COLUMN_DATE_STRING,
|
||||
HT_COLUMN_DATE_INT, HT_COLUMN_INT, HT_COLUMN_RESOURCE
|
||||
} ;
|
||||
typedef enum _HT_ColumnType HT_ColumnType;
|
||||
|
||||
PR_PUBLIC_API(HT_Cursor) HT_NewColumnCursor (HT_View view);
|
||||
PR_PUBLIC_API(PRBool) HT_GetNextColumn(HT_Cursor cursor, char **colName,
|
||||
uint32 *colWidth, void **token, uint32 *tokenType);
|
||||
PR_PUBLIC_API(void) HT_DeleteColumnCursor(HT_Cursor cursor);
|
||||
PR_PUBLIC_API(void) HT_SetColumnOrder(HT_View view, void *srcColToken,
|
||||
void *destColToken,
|
||||
PRBool afterDestFlag);
|
||||
PR_PUBLIC_API(void) HT_SetSortColumn(HT_View view, void *token,
|
||||
uint32 tokenType, PRBool descendingFlag);
|
||||
PR_PUBLIC_API(void) HT_SetColumnWidth(HT_View view, void *token,
|
||||
uint32 tokenType, uint32 width);
|
||||
PR_PUBLIC_API(uint32) HT_GetColumnWidth(HT_View view, void *token, uint32 tokenType);
|
||||
PR_PUBLIC_API(void) HT_SetColumnVisibility(HT_View view, void *token, uint32 tokenType, PRBool isHiddenFlag);
|
||||
PR_PUBLIC_API(PRBool) HT_GetColumnVisibility(HT_View view, void *token, uint32 tokenType);
|
||||
PR_PUBLIC_API(void) HT_ShowColumn(HT_View view, void *token, uint32 tokenType);
|
||||
PR_PUBLIC_API(void) HT_HideColumn(HT_View view, void *token, uint32 tokenType);
|
||||
PR_PUBLIC_API(PRBool) HT_ContainerSupportsNaturalOrderSort(HT_Resource container);
|
||||
PR_PUBLIC_API(void) HT_SetColumnFEData(HT_View view, void *token, void *data);
|
||||
PR_PUBLIC_API(void *) HT_GetColumnFEData (HT_View view, void *token);
|
||||
|
||||
PR_PUBLIC_API(void) HT_SetTopVisibleNodeIndex(HT_View view, uint32 topNodeIndex);
|
||||
PR_PUBLIC_API(uint32) HT_GetTopVisibleNodeIndex(HT_View view);
|
||||
|
||||
|
||||
/*
|
||||
* HT Menu Commands
|
||||
*/
|
||||
|
||||
enum _HT_MenuCmd {
|
||||
HT_CMD_SEPARATOR=0, HT_CMD_OPEN, HT_CMD_OPEN_FILE, HT_CMD_PRINT_FILE,
|
||||
HT_CMD_OPEN_NEW_WIN, HT_CMD_OPEN_COMPOSER, HT_CMD_OPEN_AS_WORKSPACE,
|
||||
HT_CMD_NEW_BOOKMARK, HT_CMD_NEW_FOLDER, HT_CMD_NEW_SEPARATOR,
|
||||
HT_CMD_MAKE_ALIAS, HT_CMD_ADD_TO_BOOKMARKS, HT_CMD_SAVE_AS,
|
||||
HT_CMD_CREATE_SHORTCUT, HT_CMD_SET_TOOLBAR_FOLDER,
|
||||
HT_CMD_SET_BOOKMARK_MENU, HT_CMD_SET_BOOKMARK_FOLDER, HT_CMD_CUT,
|
||||
HT_CMD_COPY, HT_CMD_PASTE, HT_CMD_DELETE_FILE, HT_CMD_DELETE_FOLDER,
|
||||
HT_CMD_REVEAL_FILEFOLDER, HT_CMD_PROPERTIES, HT_CMD_RENAME_WORKSPACE,
|
||||
HT_CMD_DELETE_WORKSPACE, HT_CMD_MOVE_WORKSPACE_UP, HT_CMD_MOVE_WORKSPACE_DOWN,
|
||||
HT_CMD_REFRESH, HT_CMD_EXPORT, HT_CMD_REMOVE_BOOKMARK_MENU,
|
||||
HT_CMD_REMOVE_BOOKMARK_FOLDER, HT_CMD_SET_PASSWORD, HT_CMD_REMOVE_PASSWORD,
|
||||
HT_CMD_EXPORTALL, HT_CMD_UNDO, HT_CMD_NEW_WORKSPACE, HT_CMD_RENAME, HT_CMD_FIND,
|
||||
HT_CMD_GET_NEW_MAIL
|
||||
};
|
||||
|
||||
typedef enum _HT_MenuCmd HT_MenuCmd;
|
||||
|
||||
PR_PUBLIC_API(HT_Cursor) HT_NewContextMenuCursor(HT_Resource r);
|
||||
PR_PUBLIC_API(HT_Cursor) HT_NewContextualMenuCursor (HT_View view,
|
||||
PRBool workspaceMenuCmds,
|
||||
PRBool backgroundMenuCmds);
|
||||
PR_PUBLIC_API(PRBool) HT_NextContextMenuItem(HT_Cursor c, HT_MenuCmd *menuCmd);
|
||||
PR_PUBLIC_API(void) HT_DeleteContextMenuCursor(HT_Cursor c);
|
||||
PR_PUBLIC_API(char *) HT_GetMenuCmdName(HT_MenuCmd menuCmd);
|
||||
PR_PUBLIC_API(HT_Error) HT_DoMenuCmd(HT_Pane pane, HT_MenuCmd menuCmd);
|
||||
PR_PUBLIC_API(PRBool) HT_IsMenuCmdEnabled(HT_Pane pane, HT_MenuCmd menuCmd);
|
||||
|
||||
/*
|
||||
* HT_Find
|
||||
* show HTML find dialog (hint is the default string to look for and can be NULL)
|
||||
*/
|
||||
PR_PUBLIC_API(void) HT_Find(char *hint);
|
||||
|
||||
/*
|
||||
* HT_Properties
|
||||
* show HTML dialog of node's properties
|
||||
*/
|
||||
PR_PUBLIC_API(void) HT_Properties (HT_Resource r);
|
||||
|
||||
|
||||
/*
|
||||
* HT_GetRDFResource
|
||||
* obtain the RDF_Resource associated with a HT node
|
||||
*/
|
||||
PR_PUBLIC_API(RDF_Resource) HT_GetRDFResource (HT_Resource node);
|
||||
|
||||
/*
|
||||
* Access the node's name and URL
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(char *) HT_GetNodeURL(HT_Resource node);
|
||||
PR_PUBLIC_API(char *) HT_GetNodeDisplayURL(HT_Resource node);
|
||||
PR_PUBLIC_API(char *) HT_GetNodeName(HT_Resource node);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Accessor and Mutators */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* HT_IsURLBar
|
||||
* determine whether node is a URL bar
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_IsURLBar (HT_Resource node);
|
||||
|
||||
/*
|
||||
* HT_IsSeparator
|
||||
* determine whether node is a separator
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_IsSeparator (HT_Resource node);
|
||||
|
||||
/*
|
||||
* HT_IsContainer
|
||||
* determine whether node is a container
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_IsContainer (HT_Resource node);
|
||||
PR_PUBLIC_API(uint32) HT_GetCountVisibleChildren(HT_Resource node);
|
||||
PR_PUBLIC_API(uint32) HT_GetCountDirectChildren(HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Resource) HT_GetContainerItem(HT_Resource parent, uint32 childNum);
|
||||
|
||||
/*
|
||||
* HT_DataSource : obtain the origin of the data
|
||||
* HT_IsLocalData : is the data local?
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_IsLocalData (HT_Resource node) ;
|
||||
PR_PUBLIC_API(char *) HT_DataSource (HT_Resource node) ;
|
||||
|
||||
|
||||
PR_PUBLIC_API(HT_Pane) HT_GetHTPaneList ();
|
||||
PR_PUBLIC_API(HT_Pane) HT_GetNextHTPane (HT_Pane pane);
|
||||
/*
|
||||
* HT_IsSelected / HT_GetSelectedState / HT_SetSelectedState
|
||||
* manage selection state of a node; get/set operations will generate
|
||||
* a HT_EVENT_NODE_SELECTION_CHANGED notification unless masked out
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_IsSelected (HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Error) HT_GetSelectedState (HT_Resource node, PRBool *selectedState);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetSelectedState (HT_Resource node, PRBool isSelected);
|
||||
|
||||
PR_PUBLIC_API(HT_Error) HT_SetSelection (HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetSelectionAll (HT_View view, PRBool selectedState);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetSelectionRange (HT_Resource node1, HT_Resource node2);
|
||||
|
||||
PR_PUBLIC_API(HT_Resource) HT_GetNextSelection(HT_View view, HT_Resource startingNode);
|
||||
PR_PUBLIC_API(void) HT_ToggleSelection(HT_Resource node);
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_IsEnabled (HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Error) HT_GetEnabledState (HT_Resource node, PRBool *enabledState);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetEnabledState(HT_Resource node, PRBool isEnabled);
|
||||
|
||||
#ifdef XPCOM_XXX /* mwcontext dependency */
|
||||
PR_PUBLIC_API(PRBool) HT_Launch(HT_Resource node, MWContext *context);
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_LaunchURL(HT_Pane pane, char *url, MWContext *context);
|
||||
#endif
|
||||
|
||||
PR_PUBLIC_API(void) HT_TypeTo(HT_Pane pane, char *typed);
|
||||
|
||||
/*
|
||||
* HT_NewCursor, HT_GetNextItem, HT_DeleteCursor
|
||||
* Used to iterate over a container's children. Until the container has been
|
||||
* opened at least once, you won't see any of the children.
|
||||
*/
|
||||
|
||||
PR_PUBLIC_API(HT_Cursor) HT_NewCursor (HT_Resource node) ;
|
||||
PR_PUBLIC_API(HT_Error) HT_DeleteCursor (HT_Cursor cursor) ;
|
||||
PR_PUBLIC_API(HT_Resource) HT_GetNextItem (HT_Cursor cursor) ;
|
||||
|
||||
/*
|
||||
* HT_IsContainerOpen / HT_GetOpenState / HT_SetOpenState
|
||||
* manage open state of a node; get/set operations will generate
|
||||
* a HT_EVENT_NODE_OPENCLOSE_CHANGED notification unless masked out
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_IsContainerOpen (HT_Resource node);
|
||||
PR_PUBLIC_API(HT_Error) HT_GetOpenState (HT_Resource containerNode, PRBool *openState);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetOpenState (HT_Resource containerNode, PRBool isOpen);
|
||||
PR_PUBLIC_API(HT_Error) HT_SetAutoFlushOpenState (HT_Resource containerNode, PRBool isOpen);
|
||||
|
||||
|
||||
/*
|
||||
* HT_ItemHasForwardSibling / HT_ItemHasBackwardSibling
|
||||
* determine if a given node has a following/previous sibling node
|
||||
*/
|
||||
PR_PUBLIC_API(PRBool) HT_ItemHasForwardSibling(HT_Resource r);
|
||||
PR_PUBLIC_API(PRBool) HT_ItemHasBackwardSibling(HT_Resource r);
|
||||
|
||||
PR_PUBLIC_API(void) HT_NewWorkspace(HT_Pane pane, char *id, char *optionalTitle);
|
||||
PR_PUBLIC_API(void) HT_SetWorkspaceOrder(HT_View src, HT_View dest, PRBool afterDestFlag);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Creating new containers */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
PR_PUBLIC_API(HT_Resource) HT_MakeNewContainer(HT_Resource parent, char* name);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Drag and Drop */
|
||||
/* drop actions should be made an enum */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
typedef uint8 HT_DropAction;
|
||||
|
||||
|
||||
#define DROP_NOT_ALLOWED 0
|
||||
#define COPY_MOVE_CONTENT 1
|
||||
#define UPLOAD_RDF 2
|
||||
#define COPY_MOVE_LINK 3
|
||||
#define UPLOAD_LFS 4
|
||||
#define DROP_ABORTED 5
|
||||
|
||||
PR_PUBLIC_API(HT_DropAction) HT_CanDropHTROn(HT_Resource dropTarget, HT_Resource obj);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_CanDropURLOn(HT_Resource dropTarget, char* url);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropHTROn(HT_Resource dropTarget, HT_Resource obj);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropURLOn(HT_Resource dropTarget, char* url);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropURLAndTitleOn(HT_Resource dropTarget,
|
||||
char* url, char *title);
|
||||
|
||||
PR_PUBLIC_API(HT_DropAction) HT_CanDropHTRAtPos(HT_Resource dropTarget, HT_Resource obj,
|
||||
PRBool before);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_CanDropURLAtPos(HT_Resource dropTarget, char* url,
|
||||
PRBool before);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropHTRAtPos(HT_Resource dropTarget, HT_Resource obj,
|
||||
PRBool before);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropURLAtPos(HT_Resource dropTarget, char* url,
|
||||
PRBool before);
|
||||
PR_PUBLIC_API(HT_DropAction) HT_DropURLAndTitleAtPos(HT_Resource dropTarget,
|
||||
char* url, char *title, PRBool before);
|
||||
PR_PUBLIC_API(PRBool) HT_IsDropTarget(HT_Resource dropTarget);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Editing */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_RemoveChild (HT_Resource parent, HT_Resource child);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Other */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
PR_PUBLIC_API(RDF) RDF_GetNavCenterDB();
|
||||
PR_PUBLIC_API(void) HT_InformRDFOfNewDocument(char* address);
|
||||
|
||||
PR_PUBLIC_API(PRBool) HT_HasHTMLPane(HT_View htView);
|
||||
PR_PUBLIC_API(char *) HT_HTMLPaneHeight(HT_View htView);
|
||||
|
||||
PR_PUBLIC_API(void) HT_AddSitemapFor(HT_Pane htPane, char *pUrl, char *pSitemapUrl, char* name);
|
||||
PR_PUBLIC_API(void) HT_AddRelatedLinksFor(HT_Pane htPane, char *pUrl);
|
||||
PR_PUBLIC_API(void) HT_ExitPage(HT_Pane htPane, char *pUrl);
|
||||
PR_PUBLIC_API(void)
|
||||
RDF_AddCookieResource(char* name, char* path, char* host, char* expires, char* value,
|
||||
PRBool isDomain, PRBool secure) ;
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif /* htrdf_h___ */
|
||||
75
mozilla/modules/rdf/include/jsec2rdf.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _JSEC_2_RDF_H_
|
||||
#define _JSEC_2_RDF_H_
|
||||
|
||||
#include "rdf.h"
|
||||
|
||||
typedef int16 JSec_Error;
|
||||
|
||||
#define JSec_OK ((JSec_Error)0x0000)
|
||||
#define JSec_NullObject ((JSec_Error)0x0001)
|
||||
|
||||
typedef RDF_Resource JSec_Principal;
|
||||
typedef RDF_Resource JSec_PrincipalUse;
|
||||
typedef RDF_Resource JSec_Target;
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
PR_EXTERN(char*) RDFJSec_GetPrincipalURLString(char *principalID);
|
||||
PR_EXTERN(const char*) RDFJSec_PrincipalUseID(JSec_PrincipalUse prUse);
|
||||
|
||||
PR_EXTERN(JSec_Error) RDFJSec_InitPrivilegeDB(); /* just use gNCDB */
|
||||
PR_EXTERN(JSec_Error) RDFJSec_SavePrivilegeDB();
|
||||
PR_EXTERN(JSec_Error) RDFJSec_ClosePrivilegeDB();
|
||||
|
||||
PR_EXTERN(RDF_Cursor) RDFJSec_ListAllPrincipals();
|
||||
PR_EXTERN(JSec_Principal) RDFJSec_NextPrincipal(RDF_Cursor c);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_ReleaseCursor(RDF_Cursor c);
|
||||
|
||||
PR_EXTERN(JSec_Principal) RDFJSec_NewPrincipal(char* principalID);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_AddPrincipal(JSec_Principal pr);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_DeletePrincipal(JSec_Principal pr);
|
||||
PR_EXTERN(char*) RDFJSec_PrincipalID(JSec_Principal pr);
|
||||
PR_EXTERN(void*) RDFJSec_AttributeOfPrincipal(JSec_Principal pr, char* attributeType);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_SetPrincipalAttribute(JSec_Principal pr, char* attributeType, void* attValue);
|
||||
|
||||
PR_EXTERN(RDF_Cursor) RDFJSec_ListAllPrincipalUses(JSec_Principal pr);
|
||||
PR_EXTERN(JSec_PrincipalUse) RDFJSec_NextPrincipalUse(RDF_Cursor c);
|
||||
|
||||
PR_EXTERN(JSec_PrincipalUse) RDFJSec_NewPrincipalUse(JSec_Principal pr, JSec_Target tr, char* priv);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_AddPrincipalUse(JSec_Principal pr, JSec_PrincipalUse prUse);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_DeletePrincipalUse (JSec_Principal pr, JSec_PrincipalUse prUse);
|
||||
|
||||
PR_EXTERN(JSec_Error) RDFJSec_AddPrincipalUsePrivilege (JSec_PrincipalUse prUse, char* priv);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_DeletePrincipalUsePrivilege (JSec_PrincipalUse prUse, char* priv);
|
||||
PR_EXTERN(char*) RDFJSec_PrivilegeOfPrincipalUse (JSec_PrincipalUse p);
|
||||
|
||||
PR_EXTERN(JSec_Error) RDFJSec_AddTargetToPrincipalUse(JSec_PrincipalUse prUse, JSec_Target tr);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_DeleteTargetToPrincipalUse(JSec_PrincipalUse prUse, JSec_Target tr);
|
||||
PR_EXTERN(JSec_Target) RDFJSec_TargetOfPrincipalUse (JSec_PrincipalUse p);
|
||||
|
||||
PR_EXTERN(JSec_Target) RDFJSec_NewTarget(char* targetName, JSec_Principal pr);
|
||||
PR_EXTERN(char*) RDFJSec_GetTargetName(JSec_Target tr);
|
||||
PR_EXTERN(char*) RDFJSec_AttributeOfTarget(JSec_Target tr, char* attributeType);
|
||||
PR_EXTERN(JSec_Error) RDFJSec_SetTargetAttribute(JSec_Target tr, char* attributeType, char* attValue);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif /* _JSEC_2_RDF_H_ */
|
||||
37
mozilla/modules/rdf/include/makefile.win
Normal file
@@ -0,0 +1,37 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
|
||||
MODULE = rdf
|
||||
|
||||
DEPTH = ..\..\..
|
||||
|
||||
EXPORTS = rdf.h \
|
||||
rdfc.h \
|
||||
nsIRDFService.h \
|
||||
nsIRDFDataSource.h \
|
||||
nsIRDFDataBase.h \
|
||||
nsIRDFObserver.h \
|
||||
nsIRDFCursor.h \
|
||||
htrdf.h \
|
||||
vocab.h \
|
||||
jsec2rdf.h \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -16,23 +16,38 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ASSIGNER_H_
|
||||
#define _REGISTER_ASSIGNER_H_
|
||||
#ifndef nsIRDFCursor_h__
|
||||
#define nsIRDFCursor_h__
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
/*
|
||||
|
||||
class FastBitMatrix;
|
||||
nsIRDFCursor:
|
||||
|
||||
class RegisterAssigner
|
||||
{
|
||||
protected:
|
||||
VirtualRegisterManager& vRegManager;
|
||||
|
||||
An iterator for RDF data sources.
|
||||
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "rdf.h"
|
||||
|
||||
|
||||
// 1c2abdb0-4cef-11d2-bc16-00805f912fe7
|
||||
#define NS_IRDFCURSOR_IID \
|
||||
{ \
|
||||
0x1c2abdb0, \
|
||||
0x4cef, \
|
||||
0x11d2, \
|
||||
{ 0xbc, 0x16, 0x00, 0x80, 0x5f, 0x91, 0x2f, 0xe7 } \
|
||||
}
|
||||
|
||||
|
||||
class nsIRDFCursor : public nsISupports {
|
||||
public:
|
||||
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||
|
||||
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||
|
||||
NS_IMETHOD HasElements(PRBool& hasElements) = 0;
|
||||
|
||||
NS_IMETHOD Next(RDF_NodeStruct& next /* in/out */) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||
#endif /* nsIRDFCursor_h__ */
|
||||
74
mozilla/modules/rdf/include/nsIRDFDataBase.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIRDFDataBase_h__
|
||||
#define nsIRDFDataBase_h__
|
||||
|
||||
/*
|
||||
This file contains the interface definition for an RDF database.
|
||||
|
||||
RDF databases aggregate RDF data sources (see nsIRDFDataSource.h)
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIRDFDataSource.h"
|
||||
#include "rdf.h"
|
||||
|
||||
|
||||
// 96343820-307c-11d2-bc15-00805f912fe7
|
||||
#define NS_IRDFDATABASE_IID \
|
||||
{ \
|
||||
0x96343820, \
|
||||
0x307c, \
|
||||
0x11d2, \
|
||||
{ 0xb, 0xc15, 0x00, 0x80, 0x5f, 0x91, 0x2f, 0xe7 } \
|
||||
}
|
||||
|
||||
|
||||
class nsIRDFDataBase : public nsIRDFDataSource {
|
||||
public:
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
NS_IMETHOD Initialize(nsIRDFResourceManager* r) = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
/*
|
||||
Add a data source for the specified URL to the database.
|
||||
|
||||
Parameters:
|
||||
dataSource -- a ptr to the data source to add
|
||||
|
||||
Returns:
|
||||
*/
|
||||
NS_IMETHOD AddDataSource(nsIRDFDataSource* dataSource) = 0;
|
||||
|
||||
NS_IMETHOD RemoveDataSource(nsIRDFDataSource* dataSource) = 0;
|
||||
|
||||
NS_IMETHOD GetDataSource(RDF_String url,
|
||||
nsIRDFDataSource **source /* out */ ) = 0;
|
||||
#endif
|
||||
|
||||
// XXX move these to datasource?
|
||||
NS_IMETHOD DeleteAllArcs(RDF_Resource resource) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsIRDFDataBase_h__ */
|
||||
223
mozilla/modules/rdf/include/nsIRDFDataSource.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIRDFDataSource_h__
|
||||
#define nsIRDFDataSource_h__
|
||||
|
||||
/*
|
||||
This file contains the interface definition for an RDF data source.
|
||||
|
||||
Classes which implement this interface for a particular type of URL
|
||||
are registered with the RDF singleton via nsIRDF::RegisterHandler(...)
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "rdf.h"
|
||||
|
||||
// 852666b0-2cce-11d2-bc14-00805f912fe7
|
||||
#define NS_IRDFDATASOURCE_IID \
|
||||
{ \
|
||||
0x852666b0, \
|
||||
0x2cce, \
|
||||
0x11d2, \
|
||||
{ 0xb, 0xc14,0x00, 0x80, 0x5f, 0x91 0x2f, 0xe7 } \
|
||||
}
|
||||
|
||||
class nsIRDFCursor;
|
||||
class nsIRDFObserver;
|
||||
class nsIRDFDataBase;
|
||||
|
||||
class nsIRDFDataSource : public nsISupports {
|
||||
public:
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
/**
|
||||
* Initialize this data source
|
||||
*/
|
||||
NS_IMETHOD Initialize(RDF_String url,
|
||||
nsIRDFResourceManager* m);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the name of this data source.
|
||||
*
|
||||
* For regular data sources, this will be the URL of the source.
|
||||
*
|
||||
* For aggregated sources, it generally will not be a valid RDF URL.
|
||||
*/
|
||||
NS_IMETHOD GetName(const RDF_String* name /* out */ ) = 0;
|
||||
|
||||
/**
|
||||
* Find an RDF resource that points to a given node over the
|
||||
* specified arc & truth value (defaults to "PR_TRUE").
|
||||
*/
|
||||
NS_IMETHOD GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Resource *source /* out */) = 0;
|
||||
|
||||
NS_IMETHOD GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_Resource *source /* out */) = 0;
|
||||
|
||||
/**
|
||||
* Find all RDF resources that point to a given node over the
|
||||
* specified arc & truth value (defaults to "PR_TRUE").
|
||||
*/
|
||||
NS_IMETHOD GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
nsIRDFCursor **sources /* out */) = 0;
|
||||
|
||||
NS_IMETHOD GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
nsIRDFCursor **sources /* out */) = 0;
|
||||
|
||||
/**
|
||||
* Find a child of that is related to the source by the given arc
|
||||
* arc and truth value (defaults to PR_TRUE).
|
||||
*/
|
||||
NS_IMETHOD GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
RDF_NodeStruct& target /* in/out */) = 0;
|
||||
|
||||
NS_IMETHOD GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
PRBool tv,
|
||||
RDF_NodeStruct& target /* in/out */) = 0;
|
||||
|
||||
/**
|
||||
* Find all children of that are related to the source by the given arc
|
||||
* arc and truth value (defaults to PR_TRUE).
|
||||
*/
|
||||
NS_IMETHOD GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */) = 0;
|
||||
|
||||
NS_IMETHOD GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */) = 0;
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
/**
|
||||
* Find all parents that point to a node over a given arc label,
|
||||
* regardless of truth value.
|
||||
*/
|
||||
NS_IMETHOD GetAllSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
nsIRDFCursor2 **sources /* out */) = 0;
|
||||
|
||||
/**
|
||||
* Find all children of a resource that are related by the
|
||||
* given arc label, regardless of the truth value.
|
||||
*/
|
||||
NS_IMETHOD GetAllTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor2 **targets /* out */);
|
||||
#endif /* RDF_NOT_IMPLEMENTED */
|
||||
|
||||
|
||||
/**
|
||||
* Add an assertion to the graph.
|
||||
*/
|
||||
NS_IMETHOD Assert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool tv = PR_TRUE) = 0;
|
||||
|
||||
/**
|
||||
* Remove an assertion from the graph.
|
||||
*/
|
||||
NS_IMETHOD Unassert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target) = 0;
|
||||
|
||||
/**
|
||||
* Query whether an assertion exists in this graph.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD HasAssertion(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool truthValue,
|
||||
PRBool* hasAssertion /* out */) = 0;
|
||||
|
||||
/**
|
||||
* Add an observer to this data source.
|
||||
*/
|
||||
NS_IMETHOD AddObserver(nsIRDFObserver *n,
|
||||
RDF_EventMask type = RDF_ANY_NOTIFY) = 0;
|
||||
|
||||
/**
|
||||
* Remove an observer from this data source
|
||||
*/
|
||||
NS_IMETHOD RemoveObserver(nsIRDFObserver *n,
|
||||
RDF_EventMask = RDF_ANY_NOTIFY) = 0;
|
||||
|
||||
/**
|
||||
* Get a cursor to iterate over all the arcs that point into a node.
|
||||
*/
|
||||
NS_IMETHOD ArcLabelsIn(RDF_Node node,
|
||||
nsIRDFCursor **labels /* out */) = 0;
|
||||
|
||||
/**
|
||||
* Get a cursor to iterate over all the arcs that originate in
|
||||
* a resource.
|
||||
*/
|
||||
NS_IMETHOD ArcLabelsOut(RDF_Resource source,
|
||||
nsIRDFCursor **labels /* out */) = 0;
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
/**
|
||||
* Notify this data source that it is a child of a database.
|
||||
*
|
||||
* The datasource must send notifications to the parent when
|
||||
* changes to it's graph are made, in case the parent has observers
|
||||
* interested in the events generated.
|
||||
*/
|
||||
NS_IMETHOD AddParent(nsIRDFDataBase* parent) = 0;
|
||||
|
||||
/**
|
||||
* Notify this data source that it has been disconnected from a
|
||||
* parent.
|
||||
*/
|
||||
NS_IMETHOD RemoveParent(nsIRDFDataBase* parent) = 0;
|
||||
|
||||
/**
|
||||
* Request that a data source obtain updates if applicable.
|
||||
*/
|
||||
// XXX move this to an nsIRDFRemoteDataStore interface?
|
||||
NS_IMETHOD Update(RDF_Resource hint) = 0;
|
||||
#endif /* RDF_NOT_IMPLEMENTED */
|
||||
|
||||
/**
|
||||
* Request that a data source write it's contents out to
|
||||
* permanent storage if applicable.
|
||||
*/
|
||||
NS_IMETHOD Flush() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsIRDFDataSource_h__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
@@ -16,22 +16,36 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_PRESSURE_H_
|
||||
#define _REGISTER_PRESSURE_H_
|
||||
#ifndef nsIRDFObserver_h__
|
||||
#define nsIRDFObserver_h__
|
||||
|
||||
#include "BitSet.h"
|
||||
#include "HashSet.h"
|
||||
/*
|
||||
This file defines the interface for RDF observers.
|
||||
*/
|
||||
|
||||
struct LowRegisterPressure
|
||||
#include "nsISupports.h"
|
||||
#include "rdf.h"
|
||||
|
||||
|
||||
// 3cc75360-484a-11d2-bc16-00805f912fe7
|
||||
#define NS_IRDFOBSERVER_IID \
|
||||
{ \
|
||||
0x3cc75360, \
|
||||
0x484a, \
|
||||
0x11d2, \
|
||||
{ 0xbc, 0x16, 0x00, 0x80, 0x5f, 0x91, 0x2f, 0xe7 } \
|
||||
}
|
||||
|
||||
class nsIRDFDataSource;
|
||||
|
||||
class nsIRDFObserver : public nsISupports
|
||||
{
|
||||
typedef BitSet Set;
|
||||
static const bool setIsOrdered = true;
|
||||
public:
|
||||
|
||||
NS_IMETHOD HandleEvent(nsIRDFDataSource *source,
|
||||
RDF_Event event) = 0;
|
||||
|
||||
};
|
||||
|
||||
struct HighRegisterPressure
|
||||
{
|
||||
typedef HashSet Set;
|
||||
static const bool setIsOrdered = false;
|
||||
};
|
||||
|
||||
#endif // _REGISTER_PRESSURE_H_
|
||||
#endif /* nsIRDFObserver_h__ */
|
||||
68
mozilla/modules/rdf/include/nsIRDFService.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsIRDFService_h__
|
||||
#define nsIRDFService_h__
|
||||
|
||||
/*
|
||||
This file defines the interface for the RDF singleton,
|
||||
which maintains various pieces of pieces of information global
|
||||
to all RDF data sources.
|
||||
|
||||
In particular, it provides the interface for mapping rdf URL types
|
||||
to nsIRDFDataSource implementors for that type of content.
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h" /* nsCID typedef, for consistency */
|
||||
#include "rdf.h"
|
||||
|
||||
class nsIRDFDataSource;
|
||||
class nsIRDFDataBase;
|
||||
|
||||
// 6edf3660-32f0-11d2-9abe-00600866748f
|
||||
#define NS_IRDFSERVICE_IID \
|
||||
{ \
|
||||
0x6edf3660, \
|
||||
0x32f0, \
|
||||
0x11d2, \
|
||||
{ 0x9a, 0xbe, 0x00, 0x60, 0x08, 0x66, 0x74, 0x8f } \
|
||||
}
|
||||
|
||||
|
||||
class nsIRDFService : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_IMETHOD Initialize();
|
||||
|
||||
#ifdef RDF_NOT_IMPLEMENTED
|
||||
NS_IMETHOD RegisterHandler(RDF_String url_selector, const nsCID& clsid) = 0;
|
||||
|
||||
NS_IMETHOD RemoveHandler(RDF_String url_selector, const nsCID& clsid) = 0;
|
||||
|
||||
NS_IMETHOD CreateDataSource(RDF_String url,
|
||||
nsIRDFDataSource **source /* out */) = 0;
|
||||
#endif /* RDF_NOT_IMPLEMENTED */
|
||||
|
||||
NS_IMETHOD CreateDatabase(const RDF_String* url_ary,
|
||||
nsIRDFDataBase **db /* out */) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsIRDFService_h__ */
|
||||
120
mozilla/modules/rdf/include/rdf.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef rdf_h___
|
||||
#define rdf_h___
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nsError.h"
|
||||
|
||||
typedef nsresult RDF_Error;
|
||||
|
||||
#define RDF_ERROR_ILLEGAL_ASSERT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_RDF,1)
|
||||
#define RDF_ERROR_ILLEGAL_KILL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_RDF,2)
|
||||
#define RDF_ERROR_UNABLE_TO_CREATE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_RDF,3)
|
||||
|
||||
#define RDF_ERROR_NO_MEMORY NS_ERROR_OUT_OF_MEMORY /* XXX remove this */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct RDF_ResourceStruct* RDF_Resource;
|
||||
typedef struct RDF_CursorStruct* RDF_Cursor;
|
||||
typedef struct RDF_DBStruct* RDF;
|
||||
typedef struct RDF_TranslatorStruct *RDFT;
|
||||
|
||||
typedef char* RDF_String;
|
||||
|
||||
typedef enum {
|
||||
RDF_ANY_TYPE,
|
||||
RDF_RESOURCE_TYPE,
|
||||
RDF_INT_TYPE,
|
||||
RDF_STRING_TYPE,
|
||||
#ifdef RDF_BLOB
|
||||
RDF_BLOB_TYPE
|
||||
#endif
|
||||
} RDF_ValueType;
|
||||
|
||||
|
||||
#ifdef RDF_BLOB
|
||||
typedef struct RDF_BlobStruct {
|
||||
PRUint32 size;
|
||||
void* data;
|
||||
} *RDF_Blob;
|
||||
#endif
|
||||
|
||||
typedef struct RDF_NodeStruct {
|
||||
RDF_ValueType type;
|
||||
union {
|
||||
RDF_Resource r;
|
||||
RDF_String s;
|
||||
#ifdef RDF_BLOB
|
||||
RDF_Blob b;
|
||||
#endif
|
||||
} value;
|
||||
} *RDF_Node;
|
||||
|
||||
typedef PRUint32 RDF_EventType;
|
||||
#define RDF_ASSERT_NOTIFY ((RDF_EventType)0x00000001)
|
||||
#define RDF_DELETE_NOTIFY ((RDF_EventType)0x00000002)
|
||||
#define RDF_KILL_NOTIFY ((RDF_EventType)0x00000004)
|
||||
#define RDF_CREATE_NOTIFY ((RDF_EventType)0x00000008)
|
||||
#define RDF_RESOURCE_GC_NOTIFY ((RDF_EventType)0x00000010)
|
||||
#define RDF_INSERT_NOTIFY ((RDF_EventType)0x00000020)
|
||||
|
||||
typedef PRUint32 RDF_EventMask;
|
||||
#define RDF_ANY_NOTIFY ((RDF_EventMask)0xFFFFFFFF)
|
||||
|
||||
typedef struct RDF_AssertEventStruct {
|
||||
RDF_Resource u;
|
||||
RDF_Resource s;
|
||||
void* v;
|
||||
RDF_ValueType type;
|
||||
PRBool tv;
|
||||
char* dataSource;
|
||||
} *RDF_AssertEvent;
|
||||
|
||||
|
||||
typedef struct RDF_UnassertEventStruct {
|
||||
RDF_Resource u;
|
||||
RDF_Resource s;
|
||||
void* v;
|
||||
RDF_ValueType type;
|
||||
char* dataSource;
|
||||
} *RDF_UnassertEvent;
|
||||
|
||||
typedef struct RDF_KillEventStruct {
|
||||
RDF_Resource u;
|
||||
} *RDF_KillEvent;
|
||||
|
||||
|
||||
typedef struct RDF_EventStruct {
|
||||
RDF_EventType eventType;
|
||||
union ev {
|
||||
struct RDF_AssertEventStruct assert;
|
||||
struct RDF_UnassertEventStruct unassert;
|
||||
struct RDF_KillEventStruct kill;
|
||||
} event;
|
||||
} *RDF_Event;
|
||||
|
||||
#include "vocab.h"
|
||||
#include "rdfc.h"
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif /* rdf_h___ */
|
||||
106
mozilla/modules/rdf/include/rdf2.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef rdf_h___
|
||||
#define rdf_h___
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nsError.h"
|
||||
|
||||
typedef nsresult RDF_Error;
|
||||
|
||||
#define RDF_ERROR_ILLEGAL_ASSERT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_RDF,1)
|
||||
#define RDF_ERROR_ILLEGAL_KILL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_RDF,2)
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct RDF_ResourceStruct* RDF_Resource;
|
||||
typedef struct RDF_CursorStruct* RDF_Cursor;
|
||||
typedef struct RDF_DBStruct* RDF;
|
||||
typedef struct RDF_TranslatorStruct *RDFT;
|
||||
|
||||
typedef enum {
|
||||
RDF_ANY_TYPE,
|
||||
RDF_RESOURCE_TYPE,
|
||||
RDF_INT_TYPE,
|
||||
RDF_STRING_TYPE.
|
||||
#ifdef RDF_BLOB
|
||||
RDF_BLOB_TYPE
|
||||
#endif
|
||||
} RDF_ValueType;
|
||||
|
||||
|
||||
#ifdef RDF_BLOB
|
||||
typedef struct RDF_BlobStruct {
|
||||
PRUint32 size;
|
||||
void* data;
|
||||
} *RDF_Blob;
|
||||
#endif
|
||||
|
||||
typedef struct RDF_NodeStruct {
|
||||
RDF_ValueType type;
|
||||
union {
|
||||
RDF_Resource r;
|
||||
RDF_String s;
|
||||
#ifdef RDF_BLOB
|
||||
RDF_Blob b;
|
||||
#endif
|
||||
} value;
|
||||
} *RDF_Node;
|
||||
|
||||
typedef PRUint32 RDF_EventType;
|
||||
#define RDF_ASSERT_NOTIFY ((RDF_EventType)0x00000001)
|
||||
#define RDF_DELETE_NOTIFY ((RDF_EventType)0x00000002)
|
||||
|
||||
typedef PRUint32 RDF_EventMask;
|
||||
#define RDF_ANY_NOTIFY ((RDF_EventMask)0xFFFFFFFF)
|
||||
|
||||
typedef struct RDF_AssertEventStruct {
|
||||
RDF_Resource u;
|
||||
RDF_Resource s;
|
||||
struct RDF_NodeStruct v;
|
||||
PRBool tv;
|
||||
char* dataSource;
|
||||
} *RDF_AssertEvent;
|
||||
|
||||
typedef struct RDF_UnassertEventStruct {
|
||||
RDF_Resource u;
|
||||
RDF_Resource s;
|
||||
struct RDF_NodeStruct v;
|
||||
char* dataSource;
|
||||
} *RDF_UnassertEvent;
|
||||
|
||||
typedef struct RDF_KillEventStruct {
|
||||
RDF_Resource u;
|
||||
} *RDF_KillEvent;
|
||||
|
||||
typedef struct RDF_EventStruct {
|
||||
RDF_EventType eventType;
|
||||
union ev {
|
||||
struct RDF_AssertEventStruct assert;
|
||||
struct RDF_UnassertEventStruct unassert;
|
||||
struct RDF_KillEventStruct kill;
|
||||
} event;
|
||||
} *RDF_Event;
|
||||
|
||||
#include "vocab.h"
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif /* rdf_h___ */
|
||||
128
mozilla/modules/rdf/include/rdfc.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef rdfc_h__
|
||||
#define rdfc_h__
|
||||
|
||||
#include "rdf.h"
|
||||
#include "nspr.h"
|
||||
|
||||
/* core rdf apis */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct _RDF_InitParamsStruct {
|
||||
char *profileURL;
|
||||
char *bookmarksURL;
|
||||
char *globalHistoryURL;
|
||||
} RDF_InitParamsStruct;
|
||||
|
||||
typedef struct _RDF_InitParamsStruct* RDF_InitParams;
|
||||
|
||||
struct RDF_NotificationStruct;
|
||||
typedef struct RDF_NotificationStruct* RDF_Notification;
|
||||
|
||||
typedef void (*RDF_NotificationProc)(RDF_Event theEvent, void* pdata);
|
||||
|
||||
PR_PUBLIC_API(RDF) RDF_GetDB(const RDF_String* dbs);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_ReleaseDB(RDF rdf);
|
||||
PR_PUBLIC_API(RDFT) RDF_AddDataSource(RDF rdf, char* dataSource);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_ReleaseDataSource(RDF rdf, RDFT dataSource);
|
||||
PR_PUBLIC_API(RDF_Resource) RDF_GetResource(RDF db, char* id, PRBool createp);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_ReleaseResource(RDF db, RDF_Resource resource);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_DeleteAllArcs(RDF rdfDB, RDF_Resource source);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_Update(RDF rdfDB, RDF_Resource u);
|
||||
|
||||
PR_PUBLIC_API(RDF_Notification) RDF_AddNotifiable (RDF rdfDB, RDF_NotificationProc callBack, RDF_Event ev, void* pdata);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_DeleteNotifiable (RDF_Notification ns);
|
||||
|
||||
|
||||
PR_PUBLIC_API(PRBool) RDF_Assert(RDF rdfDB, RDF_Resource source, RDF_Resource arcLabel,
|
||||
void* target, RDF_ValueType targetType);
|
||||
PR_PUBLIC_API(PRBool) RDF_AssertFalse(RDF rdfDB, RDF_Resource source, RDF_Resource arcLabel,
|
||||
void* target, RDF_ValueType targetType);
|
||||
PR_PUBLIC_API(PRBool) RDF_Unassert(RDF rdfDB, RDF_Resource source, RDF_Resource arcLabel,
|
||||
void* target, RDF_ValueType targetType);
|
||||
|
||||
|
||||
PR_PUBLIC_API(PRBool) RDF_CanAssert(RDF rdfDB, RDF_Resource u, RDF_Resource arcLabel, void* v, RDF_ValueType targetType);
|
||||
PR_PUBLIC_API(PRBool) RDF_CanAssertFalse(RDF rdfDB, RDF_Resource u, RDF_Resource arcLabel, void* v, RDF_ValueType targetType);
|
||||
PR_PUBLIC_API(PRBool) RDF_CanUnassert(RDF rdfDB, RDF_Resource u, RDF_Resource arcLabel, void* v, RDF_ValueType targetType);
|
||||
|
||||
|
||||
PR_PUBLIC_API(PRBool) RDF_HasAssertion (RDF rdfDB, RDF_Resource source, RDF_Resource arcLabel,
|
||||
void* target, RDF_ValueType targetType, PRBool tv);
|
||||
PR_PUBLIC_API(void*) RDF_GetSlotValue (RDF rdfDB, RDF_Resource u, RDF_Resource s, RDF_ValueType targetType,
|
||||
PRBool inversep, PRBool tv);
|
||||
PR_PUBLIC_API(RDF_Cursor) RDF_GetTargets (RDF rdfDB, RDF_Resource source, RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType, PRBool tv);
|
||||
PR_PUBLIC_API(RDF_Cursor) RDF_GetSources (RDF rdfDB, RDF_Resource target, RDF_Resource arcLabel,
|
||||
RDF_ValueType sourceType, PRBool tv);
|
||||
PR_PUBLIC_API(RDF_Cursor) RDF_ArcLabelsOut (RDF rdfDB, RDF_Resource u);
|
||||
PR_PUBLIC_API(RDF_Cursor) RDF_ArcLabelsIn (RDF rdfDB, RDF_Resource u);
|
||||
PR_PUBLIC_API(void*) RDF_NextValue(RDF_Cursor c);
|
||||
PR_PUBLIC_API(char*) RDF_ValueDataSource(RDF_Cursor c);
|
||||
PR_PUBLIC_API(RDF_ValueType) RDF_CursorValueType(RDF_Cursor c);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_DisposeCursor (RDF_Cursor c);
|
||||
|
||||
|
||||
|
||||
/*** Guha needs to get his act together and figure out how to do this.
|
||||
PR_PUBLIC_API(RDF_Error) RDF_Undo(RDF rdf);
|
||||
***/
|
||||
|
||||
/* These two should be removed soon. They are here because Nav Center
|
||||
depends on them. */
|
||||
|
||||
/* PR_PUBLIC_API(RDF_Error) RDF_Init(char *profileDirURL); */
|
||||
PR_PUBLIC_API(RDF_Error) RDF_Init(RDF_InitParams params);
|
||||
PR_PUBLIC_API(RDF_Error) RDF_Shutdown(void);
|
||||
|
||||
/* the stuff in vocab.h will supercede whats below. I am leaving this here
|
||||
only for the very near future */
|
||||
|
||||
|
||||
/** utilities : move out of here!!! **/
|
||||
/* well known resources */
|
||||
|
||||
|
||||
PR_PUBLIC_API(char*) RDF_GetResourceName(RDF rdfDB, RDF_Resource node);
|
||||
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetFirstInstance (RDF_Resource type, char* defaultURL);
|
||||
PR_PUBLIC_API(void) RDFUtil_SetFirstInstance (RDF_Resource type, RDF_Resource item);
|
||||
|
||||
typedef void (*printProc)(void* data, char* str);
|
||||
PR_PUBLIC_API(void) outputMCFTree (RDF db, printProc printer, void* data, RDF_Resource node);
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetBreadcrumb();
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetQuickFileFolder();
|
||||
PR_PUBLIC_API(void) RDFUtil_SetQuickFileFolder(RDF_Resource container);
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetPTFolder();
|
||||
PR_PUBLIC_API(void) RDFUtil_SetPTFolder(RDF_Resource container);
|
||||
PR_PUBLIC_API(RDF_Cursor) RDF_Find (RDF_Resource s, RDF_Resource match, void* v, RDF_ValueType type);
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetNewBookmarkFolder();
|
||||
PR_PUBLIC_API(void) RDFUtil_SetNewBookmarkFolder(RDF_Resource container);
|
||||
PR_PUBLIC_API(RDF_Resource) RDFUtil_GetDefaultSelectedView();
|
||||
PR_PUBLIC_API(void) RDFUtil_SetDefaultSelectedView(RDF_Resource container);
|
||||
|
||||
/** end utilities **/
|
||||
|
||||
/* this stuff is stuck in here for netlib */
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif /* rdfc_h__ */
|
||||
229
mozilla/modules/rdf/include/vocab.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_VOCAB_H_
|
||||
#define _RDF_VOCAB_H_
|
||||
|
||||
typedef struct _RDF_CoreVocabStruct {
|
||||
RDF_Resource RDF_parent;
|
||||
RDF_Resource RDF_name;
|
||||
RDF_Resource RDF_instanceOf;
|
||||
RDF_Resource RDF_subClassOf;
|
||||
RDF_Resource RDF_PropertyType;
|
||||
RDF_Resource RDF_Class;
|
||||
RDF_Resource RDF_slotsHere;
|
||||
RDF_Resource RDF_slotsIn;
|
||||
RDF_Resource RDF_domain;
|
||||
RDF_Resource RDF_range;
|
||||
RDF_Resource RDF_StringType;
|
||||
RDF_Resource RDF_IntType;
|
||||
RDF_Resource RDF_equals;
|
||||
RDF_Resource RDF_lessThan;
|
||||
RDF_Resource RDF_greaterThan;
|
||||
RDF_Resource RDF_lessThanOrEqual;
|
||||
RDF_Resource RDF_greaterThanOrEqual;
|
||||
RDF_Resource RDF_stringEquals;
|
||||
RDF_Resource RDF_stringNotEquals;
|
||||
RDF_Resource RDF_substring;
|
||||
RDF_Resource RDF_stringStartsWith;
|
||||
RDF_Resource RDF_stringEndsWith;
|
||||
RDF_Resource RDF_child;
|
||||
RDF_Resource RDF_comment;
|
||||
RDF_Resource RDF_content;
|
||||
RDF_Resource RDF_summary;
|
||||
} RDF_CoreVocabStruct;
|
||||
|
||||
typedef RDF_CoreVocabStruct* RDF_CoreVocab;
|
||||
|
||||
typedef struct _RDF_NCVocabStruct {
|
||||
RDF_Resource RDF_overview;
|
||||
RDF_Resource RDF_Trash;
|
||||
RDF_Resource RDF_Clipboard;
|
||||
RDF_Resource RDF_Top;
|
||||
RDF_Resource RDF_Search;
|
||||
RDF_Resource RDF_Sitemaps;
|
||||
RDF_Resource RDF_BreadCrumbCategory;
|
||||
RDF_Resource RDF_BookmarkFolderCategory;
|
||||
RDF_Resource RDF_NewBookmarkFolderCategory;
|
||||
RDF_Resource RDF_History;
|
||||
RDF_Resource RDF_HistoryBySite;
|
||||
RDF_Resource RDF_HistoryByDate;
|
||||
RDF_Resource RDF_HistoryMostVisited;
|
||||
|
||||
/* IE items */
|
||||
RDF_Resource RDF_IEBookmarkFolderCategory;
|
||||
RDF_Resource RDF_IEHistory;
|
||||
|
||||
RDF_Resource RDF_bookmarkAddDate;
|
||||
RDF_Resource RDF_PersonalToolbarFolderCategory;
|
||||
RDF_Resource RDF_Column;
|
||||
RDF_Resource RDF_ColumnResource;
|
||||
RDF_Resource RDF_ColumnWidth;
|
||||
RDF_Resource RDF_ColumnIconURL;
|
||||
RDF_Resource RDF_ColumnDataType;
|
||||
RDF_Resource RDF_smallIcon; /* Small normal icon. */
|
||||
RDF_Resource RDF_largeIcon; /* Large normal icon. */
|
||||
RDF_Resource RDF_Guide;
|
||||
RDF_Resource RDF_HTMLURL;
|
||||
RDF_Resource RDF_HTMLHeight;
|
||||
RDF_Resource RDF_LocalFiles;
|
||||
RDF_Resource RDF_FTP;
|
||||
RDF_Resource RDF_Appletalk;
|
||||
RDF_Resource RDF_Mail;
|
||||
RDF_Resource RDF_Password;
|
||||
RDF_Resource RDF_SBProviders;
|
||||
RDF_Resource RDF_WorkspacePos;
|
||||
RDF_Resource RDF_ItemPos;
|
||||
RDF_Resource RDF_Locks;
|
||||
RDF_Resource RDF_AddLock;
|
||||
RDF_Resource RDF_DeleteLock;
|
||||
RDF_Resource RDF_IconLock;
|
||||
RDF_Resource RDF_NameLock;
|
||||
RDF_Resource RDF_CopyLock;
|
||||
RDF_Resource RDF_MoveLock;
|
||||
RDF_Resource RDF_WorkspacePosLock;
|
||||
RDF_Resource RDF_DefaultSelectedView;
|
||||
RDF_Resource RDF_AutoOpen;
|
||||
RDF_Resource RDF_resultType;
|
||||
RDF_Resource RDF_methodType;
|
||||
RDF_Resource RDF_prompt;
|
||||
RDF_Resource RDF_HTMLType;
|
||||
RDF_Resource RDF_URLShortcut;
|
||||
RDF_Resource RDF_Poll;
|
||||
RDF_Resource RDF_PollInterval;
|
||||
RDF_Resource RDF_PollURL;
|
||||
|
||||
RDF_Resource RDF_Cookies;
|
||||
#ifdef TRANSACTION_RECEIPTS
|
||||
RDF_Resource RDF_Receipts;
|
||||
#endif
|
||||
RDF_Resource RDF_Toolbar;
|
||||
RDF_Resource RDF_JSec;
|
||||
RDF_Resource RDF_JSecPrincipal;
|
||||
RDF_Resource RDF_JSecTarget;
|
||||
RDF_Resource RDF_JSecAccess;
|
||||
|
||||
/* Commands */
|
||||
|
||||
RDF_Resource RDF_Command;
|
||||
RDF_Resource RDF_Command_Launch;
|
||||
RDF_Resource RDF_Command_Refresh;
|
||||
RDF_Resource RDF_Command_Reveal;
|
||||
RDF_Resource RDF_Command_Atalk_FlatHierarchy;
|
||||
RDF_Resource RDF_Command_Atalk_Hierarchy;
|
||||
|
||||
/* NavCenter appearance styles */
|
||||
|
||||
RDF_Resource viewFGColor;
|
||||
RDF_Resource viewBGColor;
|
||||
RDF_Resource viewBGURL;
|
||||
RDF_Resource showTreeConnections;
|
||||
RDF_Resource treeConnectionFGColor;
|
||||
RDF_Resource treeOpenTriggerIconURL;
|
||||
RDF_Resource treeClosedTriggerIconURL;
|
||||
RDF_Resource selectionFGColor;
|
||||
RDF_Resource selectionBGColor;
|
||||
RDF_Resource columnHeaderFGColor;
|
||||
RDF_Resource columnHeaderBGColor;
|
||||
RDF_Resource columnHeaderBGURL;
|
||||
RDF_Resource showColumnHeaders;
|
||||
RDF_Resource showColumnHeaderDividers;
|
||||
RDF_Resource showTitleBar; /* Whether or not to show the title bar at all */
|
||||
RDF_Resource showControlStrip; /* Whether or not to show the control strip at all. */
|
||||
|
||||
RDF_Resource sortColumnFGColor;
|
||||
RDF_Resource sortColumnBGColor;
|
||||
RDF_Resource titleBarFGColor;
|
||||
RDF_Resource titleBarBGColor;
|
||||
RDF_Resource titleBarBGURL;
|
||||
RDF_Resource titleBarShowText;
|
||||
RDF_Resource dividerColor;
|
||||
RDF_Resource showDivider;
|
||||
RDF_Resource selectedColumnHeaderFGColor;
|
||||
RDF_Resource selectedColumnHeaderBGColor;
|
||||
RDF_Resource showColumnHilite;
|
||||
RDF_Resource triggerPlacement;
|
||||
|
||||
/* NavCenter behavior flags */
|
||||
|
||||
RDF_Resource useInlineEditing;
|
||||
RDF_Resource useSingleClick;
|
||||
RDF_Resource loadOpenState;
|
||||
RDF_Resource saveOpenState;
|
||||
|
||||
/* Toolbar Appearance Styles */
|
||||
RDF_Resource toolbarBitmapPosition; /* Bitmap's position ("side"/"top") */
|
||||
RDF_Resource toolbarDisplayMode;
|
||||
RDF_Resource toolbarCollapsed;
|
||||
RDF_Resource toolbarVisible;
|
||||
RDF_Resource toolbarRolloverIcon; /* The icon to display on rollover. */
|
||||
RDF_Resource toolbarPressedIcon; /* The icon to display on a press. */
|
||||
RDF_Resource toolbarDisabledIcon; /* The icon to display when disabled. */
|
||||
RDF_Resource toolbarEnabledIcon; /* THe icon to display when enabled. */
|
||||
|
||||
/* Cookie Stuff */
|
||||
RDF_Resource cookieDomain;
|
||||
RDF_Resource cookieValue;
|
||||
RDF_Resource cookieHost;
|
||||
RDF_Resource cookiePath;
|
||||
RDF_Resource cookieSecure;
|
||||
RDF_Resource cookieExpires;
|
||||
|
||||
RDF_Resource toolbarButtonsFixedSize; /* Whether or not the buttons must be the same size ("yes"/"no") */
|
||||
RDF_Resource viewRolloverColor; /* What to display when an item is rolled over in a view.*/
|
||||
RDF_Resource viewPressedColor; /* What to display when an item is pressed in a view. */
|
||||
RDF_Resource viewDisabledColor; /* Color to use when item is disabled in a view. */
|
||||
RDF_Resource urlBar; /* Whether or not the button is a URL bar. */
|
||||
RDF_Resource urlBarWidth; /* The width of the URL bar. */
|
||||
|
||||
RDF_Resource buttonTreeState; /* The tree state (docked, popup) for a button. */
|
||||
RDF_Resource buttonTooltipText; /* The tooltip text for a button. */
|
||||
RDF_Resource buttonStatusbarText; /* The status bar text for a button. */
|
||||
RDF_Resource buttonBorderStyle; /* What type of border the button should have. */
|
||||
|
||||
RDF_Resource controlStripFGColor; /* The tree's control strip foreground */
|
||||
RDF_Resource controlStripBGColor; /* The tree's control strip background */
|
||||
RDF_Resource controlStripBGURL; /* The tree's control strip BG URL */
|
||||
RDF_Resource controlStripCloseText; /* The text displayed for the close function in the control strip. */
|
||||
|
||||
RDF_Resource pos;
|
||||
RDF_Resource from;
|
||||
RDF_Resource to;
|
||||
RDF_Resource subject;
|
||||
RDF_Resource date;
|
||||
RDF_Resource displayURL;
|
||||
} RDF_NCVocabStruct;
|
||||
|
||||
typedef RDF_NCVocabStruct* RDF_NCVocab;
|
||||
|
||||
typedef struct _RDF_WDVocabStruct {
|
||||
RDF_Resource RDF_URL;
|
||||
RDF_Resource RDF_description;
|
||||
RDF_Resource RDF_keyword;
|
||||
RDF_Resource RDF_Container;
|
||||
RDF_Resource RDF_firstVisitDate;
|
||||
RDF_Resource RDF_lastVisitDate;
|
||||
RDF_Resource RDF_numAccesses;
|
||||
RDF_Resource RDF_creationDate;
|
||||
RDF_Resource RDF_lastModifiedDate;
|
||||
RDF_Resource RDF_size;
|
||||
} RDF_WDVocabStruct;
|
||||
|
||||
typedef RDF_WDVocabStruct* RDF_WDVocab;
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -15,11 +15,13 @@
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
//
|
||||
// RDFDebug.Prefix
|
||||
//
|
||||
// Global prefix file for the debug RDF project.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _REGISTER_CLASS_H_
|
||||
#define _REGISTER_CLASS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#endif // _REGISTER_CLASS_H_
|
||||
#include "MacPrefix_debug.h"
|
||||
#include "RDFConfig.h"
|
||||
193
mozilla/modules/rdf/macbuild/RDF.exp
Normal file
@@ -0,0 +1,193 @@
|
||||
###
|
||||
### Symbols you may have to hand annotate with #{code} or #{data}...
|
||||
###
|
||||
|
||||
HT_CanDropHTROn
|
||||
HT_CanDropURLOn
|
||||
HT_DeleteCursor
|
||||
HT_DeleteView
|
||||
HT_DropHTROn
|
||||
HT_DropURLOn
|
||||
HT_GetNextItem
|
||||
HT_GetNotificationMask
|
||||
HT_GetNthItem
|
||||
HT_GetNthItemInt
|
||||
HT_GetOpenState
|
||||
HT_GetParent
|
||||
HT_GetRDFResource
|
||||
HT_GetSelectedState
|
||||
HT_GetView
|
||||
HT_GetViewData
|
||||
HT_IsContainer
|
||||
HT_IsContainerOpen
|
||||
HT_IsSelected
|
||||
HT_KillResource
|
||||
HT_MakeNewContainer
|
||||
HT_NewCursor
|
||||
HT_NewView
|
||||
HT_NodeDisplayString
|
||||
HT_RemoveChild
|
||||
HT_SetNotificationMask
|
||||
HT_SetOpenState
|
||||
HT_SetSelectedState
|
||||
HT_SetViewData
|
||||
HT_TopNode
|
||||
HT_WriteOutAsBookmarks
|
||||
RDF_AddNotifiable
|
||||
RDF_Assert
|
||||
RDF_CanAssert
|
||||
RDF_CanUnassert
|
||||
RDF_Create
|
||||
RDF_DeleteNotifiable
|
||||
RDF_DisposeCursor
|
||||
RDF_GetSlotValue
|
||||
RDF_GetSlotValues
|
||||
RDF_HasAssertion
|
||||
RDF_Init
|
||||
RDF_InitLocalStores
|
||||
RDF_Kill
|
||||
RDF_NextValue
|
||||
RDF_SaveState
|
||||
RDF_SetResourceLock
|
||||
RDF_Shutdown
|
||||
RDF_StdVocab
|
||||
RDF_Unassert
|
||||
RDF_AddCookieResource
|
||||
# RDFglueExit
|
||||
# RDFglueInitialize
|
||||
# __initialize
|
||||
# __ptmf_null
|
||||
# __terminate
|
||||
# abortRDFParse
|
||||
# addChildAfter
|
||||
# addChildBefore
|
||||
# addDescription
|
||||
# addNotifiable
|
||||
# addSlotValue
|
||||
# addToAssertionList
|
||||
# addToResourceList
|
||||
# append2Strings
|
||||
# asEqual
|
||||
# asTv
|
||||
# asType
|
||||
# assert
|
||||
# assignHeaderSlot
|
||||
# assignSlot
|
||||
# beginReadingRDFFile
|
||||
# bkStateTransition
|
||||
# bookmarkSlotp
|
||||
# charSearch
|
||||
# containerIDp
|
||||
# containerp
|
||||
# copyString
|
||||
# createBootstrapResources
|
||||
# createContainer
|
||||
# createSeparator
|
||||
# deleteNotifiable
|
||||
# derelativizeURL
|
||||
# destroyViewInt
|
||||
# disposeCursor
|
||||
# endsWith
|
||||
# exitRDF
|
||||
# fillContainer
|
||||
# finishRDFParse
|
||||
# freeAssertion
|
||||
# freeMem
|
||||
# gBookmarkURL
|
||||
# gLocalStoreURL
|
||||
# gRDFDB
|
||||
# gcRDFFile
|
||||
# getElfProp
|
||||
# getFirstToken
|
||||
# getHash
|
||||
# getMem
|
||||
# getRDFDB
|
||||
# getRelURL
|
||||
# getSlotValue
|
||||
# getSlotValues
|
||||
# globals
|
||||
# hasAssertion
|
||||
# hashIndex
|
||||
# ht_fprintf
|
||||
# htrdfNotifFunc
|
||||
# idenEqual
|
||||
# idenHash
|
||||
# initDataSources
|
||||
# initLocalStore
|
||||
# inverseTV
|
||||
# isContainer
|
||||
# isLeaf
|
||||
# isSeparator
|
||||
# isTypeOf
|
||||
# killResource
|
||||
# localStoreAdd
|
||||
# localStoreAssert
|
||||
# localStoreDisposeCursor
|
||||
# localStoreGetSlotValue
|
||||
# localStoreGetSlotValues
|
||||
# localStoreHasAssertion
|
||||
# localStoreNextValue
|
||||
# localStoreRemove
|
||||
# localStoreUnassert
|
||||
# lockedp
|
||||
# longjmp
|
||||
# makeNewAssertion
|
||||
# makeNewID
|
||||
# makeNewRDFDB
|
||||
# makeRDFFile
|
||||
# newFolderBkItem
|
||||
# newHTEntry
|
||||
# newHashtable
|
||||
# newLeafBkItem
|
||||
# nextValue
|
||||
# outputRDFTree
|
||||
# outputRDFTreeInt
|
||||
# parseNextBkBlob
|
||||
# parseNextBkToken
|
||||
# parseNextMCFBlob
|
||||
# parseNextRDFBlob
|
||||
# parseNextRDFLine
|
||||
# parseNextRDFToken
|
||||
# parseNextRDFXMLBlob
|
||||
# parseRDFElement
|
||||
# parseSlotValue
|
||||
# possiblyGCResource
|
||||
# putHash
|
||||
# rdfDB
|
||||
# rdfDBInited
|
||||
# readRDFFile
|
||||
# remHash
|
||||
# remoteAssert
|
||||
# remoteStoreAdd
|
||||
# remoteStoreDisposeCursor
|
||||
# remoteStoreGetSlotValue
|
||||
# remoteStoreGetSlotValues
|
||||
# remoteStoreHasAssertion
|
||||
# remoteStoreNextValue
|
||||
# remoteStoreRemove
|
||||
# remoteUnassert
|
||||
# resolveGenlPosReference
|
||||
# resolveReference
|
||||
# resourceDescription
|
||||
# resourceFromID
|
||||
# resourceLastModifiedDate
|
||||
# resourceLastVisitDate
|
||||
# resourceName
|
||||
# resourceTransition
|
||||
# revCharSearch
|
||||
# saveLocalStore
|
||||
# sendNotification
|
||||
# sendNotifications
|
||||
# separatorCounter
|
||||
# setAsTv
|
||||
# setAsType
|
||||
# setContainerp
|
||||
# setHiddenState
|
||||
# setLockedp
|
||||
# startsWith
|
||||
# stringAppend
|
||||
# stringEquals
|
||||
# translators
|
||||
# unassert
|
||||
# urlEquals
|
||||
# writeResource
|
||||
BIN
mozilla/modules/rdf/macbuild/RDF.mcp
Normal file
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -15,6 +15,4 @@
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashSet.h"
|
||||
#define CGLUESUPPORTED 0 // turn off C glue support to avoid conflict on create() in RDF
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -16,6 +16,12 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Liveness.h"
|
||||
//
|
||||
// RDFDebug.Prefix
|
||||
//
|
||||
// Global prefix file for the debug RDF project.
|
||||
//
|
||||
//
|
||||
|
||||
#include "MacPrefix_debug.h"
|
||||
#include "RDFConfig.h"
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
@@ -16,14 +16,14 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SSA_TOOLS_H_
|
||||
#define _SSA_TOOLS_H_
|
||||
//
|
||||
// RDFDebug.Prefix
|
||||
//
|
||||
// Global prefix file for the debug RDF project.
|
||||
//
|
||||
//
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
|
||||
#endif // _SSA_TOOLS_H_
|
||||
#define MOZ_LITE 1
|
||||
#define DEVELOPER_DEBUG 1
|
||||
#include "RDFConfig.h"
|
||||
#include <OpenTransport.h>
|
||||
30
mozilla/modules/rdf/macbuild/RDFNoLDAPDebug.Prefix
Normal file
@@ -0,0 +1,30 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
//
|
||||
// RDFDebug.Prefix
|
||||
//
|
||||
// Global prefix file for the debug RDF project.
|
||||
//
|
||||
//
|
||||
|
||||
#define MOZ_LITE 1
|
||||
#define DEBUG 1
|
||||
#define DEVELOPER_DEBUG 1
|
||||
#include "RDFConfig.h"
|
||||
#include <OpenTransport.h>
|
||||
9
mozilla/modules/rdf/makefile.win
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
DIRS=\
|
||||
include \
|
||||
src \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
46
mozilla/modules/rdf/src/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
MODULE = rdf
|
||||
LIBRARY_NAME = $(LITE_PREFIX)rdf
|
||||
LIBXP = $(DIST)/lib/libxp.$(LIB_SUFFIX)
|
||||
|
||||
REQUIRES = nspr
|
||||
|
||||
JNI_GEN = netscape.rdf.core.NativeRDF netscape.rdf.core.NativeRDFEnumeration
|
||||
|
||||
CSRCS = \
|
||||
vocab.c \
|
||||
mcf.c \
|
||||
remstore.c \
|
||||
utils.c \
|
||||
rdfparse.c \
|
||||
bmk2mcf.c \
|
||||
rdfht.c \
|
||||
columns.c \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = -I$(PUBLIC)/rdf
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
$(LIBRARY): $(OBJS)
|
||||
87
mozilla/modules/rdf/src/Makefile.in
Normal file
@@ -0,0 +1,87 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
MODULE = rdf
|
||||
LIBRARY_NAME = $(LITE_PREFIX)rdf
|
||||
LIBXP = $(DIST)/lib/libxp.$(LIB_SUFFIX)
|
||||
|
||||
REQUIRES = nspr dbm java js htmldlgs util img layer pref ldap network parse
|
||||
|
||||
JNI_GEN = netscape.rdf.core.NativeRDF netscape.rdf.core.NativeRDFEnumeration
|
||||
|
||||
CSRCS = \
|
||||
vocab.c \
|
||||
mcf.c \
|
||||
remstore.c \
|
||||
utils.c \
|
||||
rdfparse.c \
|
||||
mcff2mcf.c \
|
||||
bmk2mcf.c \
|
||||
ldap2rdf.c \
|
||||
glue.c \
|
||||
rdfht.c \
|
||||
jsec2rdf.c \
|
||||
$(NULL)
|
||||
|
||||
ifndef RDF_STANDALONE
|
||||
CSRCS += \
|
||||
nlcstore.c \
|
||||
find2rdf.c \
|
||||
fs2rdf.c \
|
||||
hist2rdf.c \
|
||||
pm2rdf.c \
|
||||
es2mcf.c \
|
||||
columns.c \
|
||||
ht.c \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
SPF_OBJS = $(OBJDIR)/spf2ldif.o \
|
||||
$(OBJDIR)/hashtable.o
|
||||
|
||||
LOCAL_INCLUDES = -I$(PUBLIC)/rdf
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef RDF_STANDALONE
|
||||
DEFINES := $(filter-out -DMOZILLA_CLIENT, $(DEFINES))
|
||||
endif
|
||||
|
||||
$(LIBRARY): $(OBJS)
|
||||
|
||||
test: $(OBJDIR)/test
|
||||
spf2ldif: $(OBJDIR)/spf2ldif
|
||||
|
||||
.PHONY: test spf2ldif
|
||||
|
||||
$(OBJDIR)/test: $(OBJDIR)/test.o $(LIBRARY)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $(OBJDIR)/test.o $(LIBRARY) $(LIBNSPR) $(LIBXP) $(LDFLAGS) $(OS_LIBS)
|
||||
|
||||
$(OBJDIR)/spf2ldif: $(SPF_OBJS) $(LIBRARY)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $(SPF_OBJS) $(LIBRARY) $(LIBNSPR) $(LIBXP) $(LDFLAGS) $(OS_LIBS)
|
||||
1235
mozilla/modules/rdf/src/atalk.c
Normal file
87
mozilla/modules/rdf/src/atalk.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_ATALK_H_
|
||||
#define _RDF_ATALK_H_
|
||||
|
||||
#ifdef XP_MAC
|
||||
|
||||
#include <Appletalk.h>
|
||||
#include <Devices.h>
|
||||
#include <Gestalt.h>
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "mcf.h"
|
||||
#include "vocab.h"
|
||||
#include "utils.h"
|
||||
#include "prefapi.h"
|
||||
|
||||
|
||||
/* atalk.c data structures and defines */
|
||||
|
||||
extern int RDF_APPLETALK_TOP_NAME, RDF_AFP_CLIENT_37_STR, RDF_AFP_AUTH_FAILED_STR;
|
||||
extern int RDF_AFP_PW_EXPIRED_STR, RDF_AFP_ALREADY_MOUNTED_STR, RDF_AFP_MAX_SERVERS_STR;
|
||||
extern int RDF_AFP_NOT_RESPONDING_STR, RDF_AFP_SAME_NODE_STR, RDF_AFP_ERROR_NUM_STR;
|
||||
extern int RDF_VOLUME_DESC_STR, RDF_DIRECTORY_DESC_STR, RDF_FILE_DESC_STR;
|
||||
|
||||
#define ATALK_NOHIERARCHY_PREF "browser.navcenter.appletalk.zone.nohierarchy"
|
||||
|
||||
#define ATALK_CMD_PREFIX "Command:at:"
|
||||
|
||||
#define kAppleShareVerGestalt 'afps'
|
||||
#define kAppleShareVer_3_7 0x00000006
|
||||
#define AFPX_PROT_VERSION 0
|
||||
#define BASE_AFPX_OFFSET 30
|
||||
#define BASE_AFP_OFFSET 24
|
||||
|
||||
typedef struct _ourNBPUserDataStruct
|
||||
{
|
||||
RDFT rdf;
|
||||
char *parentID;
|
||||
} ourNBPUserDataStruct;
|
||||
typedef ourNBPUserDataStruct *ourNBPUserDataPtr;
|
||||
|
||||
|
||||
/* atalk.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
#ifdef XP_MAC
|
||||
PRBool isAFPVolume(short ioVRefNum);
|
||||
#endif
|
||||
|
||||
void getZones(RDFT rdf);
|
||||
void processZones(RDFT rdf, char *zones, uint16 numZones, XP_Bool noHierarchyFlag);
|
||||
void checkServerLookup (MPPParamBlock *nbp);
|
||||
void getServers(RDFT rdf, RDF_Resource parent);
|
||||
void AtalkPossible(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
RDF_Error AtalkDestroy (RDFT r);
|
||||
PRBool AtalkHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void *v, RDF_ValueType type, PRBool tv);
|
||||
PRBool AtalkAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void *v, RDF_ValueType type, PRBool tv);
|
||||
char * convertAFPtoUnescapedFile(char *id);
|
||||
void * AtalkGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor AtalkGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * AtalkNextValue (RDFT rdf, RDF_Cursor c);
|
||||
RDF_Resource CreateAFPFSUnit (char *nname, PRBool isDirectoryFlag);
|
||||
RDFT MakeAtalkStore (char* url);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
602
mozilla/modules/rdf/src/bmk2mcf.c
Normal file
@@ -0,0 +1,602 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* Reading bookmarks.htm into rdf.
|
||||
tags in the bookmark file.
|
||||
<TITLE>
|
||||
<H1>
|
||||
<H3>
|
||||
<DL></DL>
|
||||
<DT>
|
||||
<P>
|
||||
|
||||
<DT> indicates that an item is coming.
|
||||
If the next item is an <a then we have a url
|
||||
If the next item is a h3, we have a folder.
|
||||
<DL> indicates that the previous item (which should have been a folder)
|
||||
is the parent of the next set.
|
||||
</DL> indicates pop out a level
|
||||
<P> ignore this on reading, but write out one after each <DL>
|
||||
<DD> the description for the previous <DT>
|
||||
|
||||
Category urls. Make it up out of the add dates. */
|
||||
|
||||
|
||||
/*
|
||||
This file translates netscape bookmarks into the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
|
||||
#include "bmk2mcf.h"
|
||||
#include "utils.h"
|
||||
#include "time.h"
|
||||
#ifdef MOZILLA_CLIENT
|
||||
|
||||
/* extern declarations */
|
||||
PR_PUBLIC_API(void) HT_WriteOutAsBookmarks (RDF r, PRFileDesc *fp, RDF_Resource u); /* XXX this should be elsewhere */
|
||||
extern char *gBookmarkURL;
|
||||
extern RDF gNCDB;
|
||||
|
||||
/* globals */
|
||||
uint16 separatorCounter = 0;
|
||||
static char* gBkFolderDate;
|
||||
static RDFT gBMKStore = 0;
|
||||
extern int RDF_PERSONAL_TOOLBAR_NAME;
|
||||
|
||||
RDF_Resource
|
||||
createSeparator(void)
|
||||
{
|
||||
char url[50];
|
||||
RDF_Resource sep;
|
||||
PR_snprintf(url, 50, "separator%i", separatorCounter++);
|
||||
sep = RDF_GetResource(NULL, url, 1);
|
||||
return sep;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
RDF_Resource
|
||||
createContainer (char* id)
|
||||
{
|
||||
RDF_Resource r = RDF_GetResource(NULL, id, true);
|
||||
setContainerp(r, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef MOZILLA_CLIENT
|
||||
|
||||
char *
|
||||
resourceDescription (RDF rdf, RDF_Resource r)
|
||||
{
|
||||
return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_description, RDF_STRING_TYPE, false, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
resourceLastVisitDate (RDF rdf, RDF_Resource r)
|
||||
{
|
||||
return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_lastVisitDate, RDF_STRING_TYPE, false, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
resourceLastModifiedDate (RDF rdf, RDF_Resource r)
|
||||
{
|
||||
return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_lastModifiedDate, RDF_STRING_TYPE, false, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
parseNextBkBlob (RDFFile f, char* blob, int32 size)
|
||||
{
|
||||
int32 n, last, m;
|
||||
PRBool somethingseenp = false;
|
||||
n = last = 0;
|
||||
|
||||
while (n < size) {
|
||||
char c = blob[n];
|
||||
m = 0;
|
||||
somethingseenp = false;
|
||||
memset(f->line, '\0', f->lineSize);
|
||||
if (f->holdOver[0] != '\0') {
|
||||
memcpy(f->line, f->holdOver, RDF_STRLEN(f->holdOver));
|
||||
m = RDF_STRLEN(f->holdOver);
|
||||
somethingseenp = true;
|
||||
memset(f->holdOver, '\0', RDF_BUF_SIZE);
|
||||
}
|
||||
while ((m < 300) && (c != '<') && (c != '>') && (n < size)) {
|
||||
f->line[m] = c;
|
||||
m++;
|
||||
somethingseenp = (somethingseenp || ((c != ' ') && (c != '\r') && (c != '\n')));
|
||||
n++;
|
||||
c = blob[n];
|
||||
}
|
||||
if (c == '>') f->line[m] = c;
|
||||
n++;
|
||||
if (m > 0) {
|
||||
if ((c == '<') || (c == '>')) {
|
||||
last = n;
|
||||
if (c == '<') f->holdOver[0] = '<';
|
||||
if (somethingseenp == true) parseNextBkToken(f, f->line);
|
||||
} else if (size > last) {
|
||||
memcpy(f->holdOver, f->line, m);
|
||||
}
|
||||
} else if (c == '<') f->holdOver[0] = '<';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
parseNextBkToken (RDFFile f, char* token)
|
||||
{
|
||||
/* printf(token); */
|
||||
if (token[0] == '<') {
|
||||
bkStateTransition(f, token);
|
||||
} else {
|
||||
/* ok, we have a piece of content.
|
||||
can be the title, or a description or */
|
||||
if ((f->status == IN_TITLE) || (f->status == IN_H3) ||
|
||||
(f->status == IN_ITEM_TITLE)) {
|
||||
if (IN_H3 && gBkFolderDate) {
|
||||
char *url;
|
||||
RDF_Resource newFolder;
|
||||
url = PR_smprintf("%s%s.rdf", gBkFolderDate, token);
|
||||
newFolder = createContainer(url);
|
||||
free(url);
|
||||
addSlotValue(f,newFolder, gCoreVocab->RDF_parent, f->stack[f->depth-1],
|
||||
RDF_RESOURCE_TYPE, NULL);
|
||||
freeMem(gBkFolderDate);
|
||||
gBkFolderDate = NULL;
|
||||
f->lastItem = newFolder;
|
||||
}
|
||||
if ((f->db == gLocalStore) || (f->status != IN_TITLE))
|
||||
{
|
||||
addSlotValue(f, f->lastItem, gCoreVocab->RDF_name,
|
||||
copyString(token), RDF_STRING_TYPE, NULL);
|
||||
}
|
||||
|
||||
if (startsWith("Personal Toolbar", token) && (containerp(f->lastItem)))
|
||||
addSlotValue(f, f->lastItem, gCoreVocab->RDF_instanceOf,
|
||||
gNavCenter->RDF_PersonalToolbarFolderCategory,
|
||||
RDF_RESOURCE_TYPE, "true");
|
||||
|
||||
} else if (f->status == IN_ITEM_DESCRIPTION) {
|
||||
addDescription(f, f->lastItem, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
addDescription (RDFFile f, RDF_Resource r, char* token)
|
||||
{
|
||||
char* desc = (char*) remoteStoreGetSlotValue(gLocalStore, r, gWebData->RDF_description,
|
||||
RDF_STRING_TYPE, false, true);
|
||||
if (desc == NULL) {
|
||||
addSlotValue(f, f->lastItem, gWebData->RDF_description,
|
||||
copyString(token),
|
||||
RDF_STRING_TYPE, NULL);
|
||||
} else {
|
||||
addSlotValue(f, f->lastItem, gWebData->RDF_description,
|
||||
append2Strings(desc, token), RDF_STRING_TYPE, NULL);
|
||||
remoteUnassert(gLocalStore, f->lastItem, gWebData->RDF_description, desc, RDF_STRING_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
bkStateTransition (RDFFile f, char* token)
|
||||
{
|
||||
if (startsWith("<A", token)) {
|
||||
newLeafBkItem(f, token);
|
||||
f->status = IN_ITEM_TITLE;
|
||||
} else if (startsWith(OPEN_H3_STRING, token)) {
|
||||
newFolderBkItem(f, token);
|
||||
f->status = IN_H3;
|
||||
} else if (startsWith(OPEN_TITLE_STRING, token)) {
|
||||
f->status = IN_TITLE;
|
||||
} else if (startsWith(OPEN_H3_STRING, token)) {
|
||||
f->status = IN_H3;
|
||||
} else if (startsWith(DD_STRING, token)) {
|
||||
if (remoteStoreGetSlotValue(gLocalStore, f->lastItem, gWebData->RDF_description,
|
||||
RDF_STRING_TYPE, false, true)
|
||||
== NULL) f->status = IN_ITEM_DESCRIPTION;
|
||||
} else if (startsWith(OPEN_DL_STRING, token)) {
|
||||
f->stack[f->depth++] = f->lastItem;
|
||||
} else if (startsWith(CLOSE_DL_STRING, token)) {
|
||||
f->depth--;
|
||||
} else if (startsWith("<HR>", token)) {
|
||||
addSlotValue(f, createSeparator(), gCoreVocab->RDF_parent, f->stack[f->depth-1],
|
||||
RDF_RESOURCE_TYPE, NULL);
|
||||
f->status = 0;
|
||||
} else if ((f->status == IN_ITEM_DESCRIPTION) && (startsWith("<BR>", token))) {
|
||||
addDescription(f, f->lastItem, token);
|
||||
} else f->status = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
newFolderBkItem(RDFFile f, char* token)
|
||||
{
|
||||
int16 start, end;
|
||||
start = charSearch('"', token);
|
||||
end = revCharSearch('"', token);
|
||||
token[end] = '\0';
|
||||
gBkFolderDate = copyString(&token[start+1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
newLeafBkItem (RDFFile f, char* token)
|
||||
{
|
||||
char buffer[128];
|
||||
struct tm *time;
|
||||
uint32 dateVal;
|
||||
char* url = NULL;
|
||||
char* addDate = NULL;
|
||||
char* lastVisit = NULL;
|
||||
char* lastModified = NULL;
|
||||
uint8 current = 0;
|
||||
int32 len = RDF_STRLEN(token);
|
||||
int32 n = 0;
|
||||
char c = token[n++];
|
||||
PRBool inString = false;
|
||||
RDF_Resource newR;
|
||||
|
||||
while (n < len) {
|
||||
if (c == '"') {
|
||||
if (inString) {
|
||||
token[n-1] = '\0';
|
||||
inString = false;
|
||||
} else {
|
||||
inString = true;
|
||||
if (current == 0) {
|
||||
url = &token[n];
|
||||
} else if (current == 1) {
|
||||
addDate = &token[n];
|
||||
} else if (current == 2) {
|
||||
lastVisit = &token[n];
|
||||
} else if (current == 3) {
|
||||
lastModified = &token[n];
|
||||
}
|
||||
current++;
|
||||
}
|
||||
}
|
||||
c = token[n++];
|
||||
}
|
||||
if (url == NULL) return;
|
||||
newR = RDF_GetResource(NULL, url, true);
|
||||
addSlotValue(f, newR, gCoreVocab->RDF_parent, f->stack[f->depth-1],
|
||||
RDF_RESOURCE_TYPE, NULL);
|
||||
/* addSlotValue(f, newR, gWebData->RDF_URL, (void*)copyString(url),
|
||||
RDF_STRING_TYPE, true); */
|
||||
if (addDate != NULL)
|
||||
{
|
||||
dateVal = atol(addDate);
|
||||
if ((time = localtime((time_t *) &dateVal)) != NULL)
|
||||
{
|
||||
/* xxx
|
||||
#ifdef XP_MAC
|
||||
time->tm_year += 4;
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#elif XP_UNIX
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#else
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
|
||||
#endif
|
||||
|
||||
addSlotValue(f, newR, gNavCenter->RDF_bookmarkAddDate,
|
||||
(void*)copyString(buffer), RDF_STRING_TYPE, NULL);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (lastVisit != NULL)
|
||||
{
|
||||
dateVal = atol(lastVisit);
|
||||
if ((time = localtime((time_t *) &dateVal)) != NULL)
|
||||
{
|
||||
/* xxx
|
||||
#ifdef XP_MAC
|
||||
time->tm_year += 4;
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#elif XP_UNIX
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#else
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
|
||||
#endif
|
||||
addSlotValue(f, newR, gWebData->RDF_lastVisitDate,
|
||||
(void*)copyString(buffer), RDF_STRING_TYPE, NULL);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (lastModified != NULL)
|
||||
{
|
||||
dateVal = atol(lastModified);
|
||||
if ((time = localtime((time_t *) &dateVal)) != NULL)
|
||||
{
|
||||
/* xxx
|
||||
#ifdef XP_MAC
|
||||
time->tm_year += 4;
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#elif XP_UNIX
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#else
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
|
||||
#endif
|
||||
addSlotValue(f, newR, gWebData->RDF_lastModifiedDate,
|
||||
(void*)copyString(buffer), RDF_STRING_TYPE, NULL);
|
||||
*/
|
||||
}
|
||||
}
|
||||
f->lastItem = newR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
numericDate(char *url)
|
||||
{
|
||||
char *date = NULL;
|
||||
int len=0;
|
||||
|
||||
if (!url) return NULL;
|
||||
while (url[len])
|
||||
{
|
||||
if (!isdigit(url[len])) break;
|
||||
++len;
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
if ((date = getMem(len+1)) != NULL)
|
||||
{
|
||||
strncpy(date, url, len);
|
||||
}
|
||||
}
|
||||
return(date);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
bookmarkSlotp (RDF_Resource s)
|
||||
{
|
||||
return ((s == gCoreVocab->RDF_parent) || (s == gWebData->RDF_lastVisitDate) || (s == gWebData->RDF_description) ||
|
||||
(s == gNavCenter->RDF_bookmarkAddDate) || (s == gWebData->RDF_lastModifiedDate) ||
|
||||
(s == gCoreVocab->RDF_name));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HT_WriteOutAsBookmarks1 (RDF rdf, PRFileDesc *fp, RDF_Resource u, RDF_Resource top, int indent)
|
||||
{
|
||||
RDF_Cursor c = RDF_GetSources(rdf, u, gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, true);
|
||||
RDF_Resource next;
|
||||
char *date, *name, *url;
|
||||
int loop;
|
||||
|
||||
if (c == NULL) return;
|
||||
if (u == top) {
|
||||
name = RDF_GetResourceName(rdf, u);
|
||||
ht_rjcprintf(fp, "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n", NULL);
|
||||
ht_rjcprintf(fp, "<!-- This is an automatically generated file.\n", NULL);
|
||||
ht_rjcprintf(fp, "It will be read and overwritten.\n", NULL);
|
||||
ht_rjcprintf(fp, "Do Not Edit! -->\n", NULL);
|
||||
|
||||
ht_rjcprintf(fp, "<TITLE>%s</TITLE>\n", (name) ? name:"");
|
||||
ht_rjcprintf(fp, "<H1>%s</H1>\n<DL><p>\n", (name) ? name:"");
|
||||
}
|
||||
while ((next = RDF_NextValue(c)) != NULL) {
|
||||
|
||||
url = resourceID(next);
|
||||
if (containerp(next) && (!startsWith("ftp:",url)) && (!startsWith("file:",url))
|
||||
&& (!startsWith("IMAP:", url)) && (!startsWith("nes:", url))
|
||||
&& (!startsWith("mail:", url)) && (!startsWith("cache:", url))
|
||||
&& (!startsWith("ldap:", url))) {
|
||||
for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
|
||||
|
||||
date = numericDate(resourceID(next));
|
||||
ht_rjcprintf(fp, "<DT><H3 ADD_DATE=\"%s\">", (date) ? date:"");
|
||||
if (date) freeMem(date);
|
||||
name = RDF_GetResourceName(rdf, next);
|
||||
ht_rjcprintf(fp, "%s</H3>\n", name);
|
||||
|
||||
for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
|
||||
ht_rjcprintf(fp, "<DL><p>\n", NULL);
|
||||
HT_WriteOutAsBookmarks1(rdf, fp, next, top, indent+1);
|
||||
|
||||
for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
|
||||
|
||||
ht_rjcprintf(fp, "</DL><p>\n", NULL);
|
||||
}
|
||||
else if (isSeparator(next)) {
|
||||
for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
|
||||
ht_rjcprintf(fp, "<HR>\n", NULL);
|
||||
}
|
||||
else {
|
||||
char* bkAddDate = (char*)RDF_GetSlotValue(rdf, next,
|
||||
gNavCenter->RDF_bookmarkAddDate,
|
||||
RDF_STRING_TYPE, false, true);
|
||||
|
||||
for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
|
||||
|
||||
ht_rjcprintf(fp, "<DT><A HREF=\"%s\" ", resourceID(next));
|
||||
date = numericDate(bkAddDate);
|
||||
ht_rjcprintf(fp, "ADD_DATE=\"%s\" ", (date) ? date: "");
|
||||
if (date) freeMem(date);
|
||||
ht_rjcprintf(fp, "LAST_VISIT=\"%s\" ", resourceLastVisitDate(rdf, next));
|
||||
ht_rjcprintf(fp, "LAST_MODIFIED=\"%s\">", resourceLastModifiedDate(rdf, next));
|
||||
ht_rjcprintf(fp, "%s</A>\n", RDF_GetResourceName(rdf, next));
|
||||
|
||||
if (resourceDescription(rdf, next) != NULL) {
|
||||
ht_rjcprintf(fp, "<DD>%s\n", resourceDescription(rdf, next));
|
||||
}
|
||||
}
|
||||
}
|
||||
RDF_DisposeCursor(c);
|
||||
if (u == top) {
|
||||
ht_rjcprintf(fp, "</DL>\n", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PR_PUBLIC_API(void)
|
||||
HT_WriteOutAsBookmarks (RDF r, PRFileDesc *fp, RDF_Resource u)
|
||||
{
|
||||
HT_WriteOutAsBookmarks1 (r, fp, u, u, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
flushBookmarks()
|
||||
{
|
||||
PRFileDesc *bkfp;
|
||||
|
||||
if (gBookmarkURL != NULL)
|
||||
{
|
||||
/*
|
||||
delete bookmark.htm as PROpen() with PR_TRUNCATE appears broken (at least on Mac)
|
||||
*/
|
||||
CallPRDeleteFileUsingFileURL(gBookmarkURL);
|
||||
|
||||
if ((bkfp = CallPROpenUsingFileURL(gBookmarkURL, (PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE),
|
||||
0644)) != NULL)
|
||||
{
|
||||
HT_WriteOutAsBookmarks(gNCDB, bkfp, gNavCenter->RDF_BookmarkFolderCategory);
|
||||
PR_Close(bkfp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
ResourceBelongsToBookmarksp (RDF_Resource r, int32 depth) {
|
||||
if (depth > 20) {
|
||||
return false;
|
||||
} else if (r == gNavCenter->RDF_BookmarkFolderCategory) {
|
||||
return 1;
|
||||
} else if (containerp(r)) {
|
||||
Assertion as = r->rarg1;
|
||||
while (as) {
|
||||
if ((as->db == gBMKStore) &&
|
||||
(as->s == gCoreVocab->RDF_parent) &&
|
||||
(as->tv == 1) &&
|
||||
(ResourceBelongsToBookmarksp((RDF_Resource)as->value, depth+1))) return 1;
|
||||
as = as->next;
|
||||
}
|
||||
return 0;
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool remoteAssert3 (RDFFile fi, RDFT mcf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv);
|
||||
PRBool remoteUnassert3 (RDFFile fi, RDFT mcf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type);
|
||||
|
||||
|
||||
PRBool
|
||||
bmkUnassert (RDFT mcf, RDF_Resource u, RDF_Resource s,
|
||||
void* v, RDF_ValueType type) {
|
||||
if (ResourceBelongsToBookmarksp(u, 0)) {
|
||||
return (remoteStoreRemove(mcf, u, s, v, type) != NULL);
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
bmkAssert (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv) {
|
||||
if (ResourceBelongsToBookmarksp(u, 0)) {
|
||||
return (remoteStoreAdd(mcf, u, s, v, type, tv) != NULL);
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
extern RDF_Resource gPTFolder;
|
||||
void
|
||||
readInBookmarks()
|
||||
{
|
||||
/* RDF_Resource ptFolder; */
|
||||
RDF_Resource bmk = RDF_GetResource(NULL, "NC:Bookmarks", true);
|
||||
RDFFile f = makeRDFFile(gBookmarkURL, bmk, true);
|
||||
PRFileDesc *fp;
|
||||
int32 len;
|
||||
char buf[512];
|
||||
f->fileType = RDF_BOOKMARKS;
|
||||
f->db = gBMKStore;
|
||||
f->assert = remoteAssert3;
|
||||
|
||||
fp = CallPROpenUsingFileURL(f->url, PR_RDONLY|PR_CREATE_FILE, 0644);
|
||||
if (fp == NULL) return;
|
||||
while((len=PR_Read(fp, buf, sizeof(buf))) >0) {
|
||||
parseNextBkBlob(f, buf, len);
|
||||
}
|
||||
|
||||
gPTFolder = remoteStoreGetSlotValue(f->db,
|
||||
gNavCenter->RDF_PersonalToolbarFolderCategory,
|
||||
gCoreVocab->RDF_instanceOf, RDF_RESOURCE_TYPE, true, true);
|
||||
|
||||
if (gPTFolder == NULL) {
|
||||
if ((gPTFolder = createContainer("personaltoolbar.rdf")) != NULL) {
|
||||
addSlotValue(f, gPTFolder, gCoreVocab->RDF_instanceOf,
|
||||
gNavCenter->RDF_PersonalToolbarFolderCategory,
|
||||
RDF_RESOURCE_TYPE, "true");
|
||||
addSlotValue(f, gPTFolder, gCoreVocab->RDF_name,
|
||||
copyString("Personal Toolbar"),
|
||||
RDF_STRING_TYPE, "true");
|
||||
RDFUtil_SetPTFolder(gPTFolder);
|
||||
}
|
||||
}
|
||||
|
||||
PR_Close(fp);
|
||||
freeMem(f->line);
|
||||
freeMem(f->currentSlot);
|
||||
freeMem(f->holdOver);
|
||||
}
|
||||
|
||||
|
||||
RDFT
|
||||
MakeBMKStore (char* url)
|
||||
{
|
||||
if (startsWith("rdf:bookmarks", url)) {
|
||||
if (gBMKStore == 0) {
|
||||
RDFT ntr = gBMKStore = NewRemoteStore(url);
|
||||
ntr->assert = bmkAssert;
|
||||
ntr->unassert = bmkUnassert;
|
||||
readInBookmarks();
|
||||
return ntr;
|
||||
} else return gBMKStore;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
72
mozilla/modules/rdf/src/bmk2mcf.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_BMK2MCF_H_
|
||||
#define _RDF_BMK2MCF_H_
|
||||
|
||||
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "vocab.h"
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
|
||||
|
||||
/* bmk2mcf.c data structures and defines */
|
||||
|
||||
#define OPEN_TITLE_STRING "<TITLE>"
|
||||
#define CLOSE_TITLE_STRING "</TITLE>"
|
||||
#define OPEN_H1_STRING "<H1>"
|
||||
#define CLOSE_H1_STRING "</H1>"
|
||||
#define OPEN_H3_STRING "<H3"
|
||||
#define CLOSE_H3_STRING "</H3>"
|
||||
#define OPEN_DL_STRING "<DL>"
|
||||
#define CLOSE_DL_STRING "</DL>"
|
||||
#define DT_STRING "<DT>"
|
||||
#define PAR_STRING "<P>"
|
||||
#define DD_STRING "<DD>"
|
||||
|
||||
#define IN_TITLE 1
|
||||
#define IN_H3 5
|
||||
#define IN_ITEM_TITLE 7
|
||||
#define IN_ITEM_DESCRIPTION 9
|
||||
|
||||
|
||||
|
||||
/* bmk2mcf.c function prototypes */
|
||||
|
||||
|
||||
|
||||
RDF_Resource createSeparator(void);
|
||||
RDF_Resource createContainer (char* id);
|
||||
char * resourceDescription (RDF rdf, RDF_Resource r);
|
||||
char * resourceLastVisitDate (RDF rdf, RDF_Resource r);
|
||||
char * resourceLastModifiedDate (RDF rdf, RDF_Resource r);
|
||||
void parseNextBkBlob (RDFFile f, char* blob, int32 size);
|
||||
void parseNextBkToken (RDFFile f, char* token);
|
||||
void addDescription (RDFFile f, RDF_Resource r, char* token);
|
||||
void bkStateTransition (RDFFile f, char* token);
|
||||
void newFolderBkItem(RDFFile f, char* token);
|
||||
void newLeafBkItem (RDFFile f, char* token);
|
||||
char * numericDate(char *url);
|
||||
void HT_WriteOutAsBookmarks1 (RDF rdf, PRFileDesc *fp, RDF_Resource u, RDF_Resource top, int indent);
|
||||
void flushBookmarks();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
114
mozilla/modules/rdf/src/che2rdf.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "rdf-int.h"
|
||||
|
||||
/* We need to define a new class of urls for cache objects.
|
||||
e.g., cache:<something here>
|
||||
|
||||
The url for the rdf datastore corresponding to the cache
|
||||
is rdf:cache.
|
||||
|
||||
The Cache Schema.
|
||||
The cache consists of a hierarchy of objects. The standard
|
||||
hierarchy relation (RDF_parent). In addition, each object
|
||||
may have the following properties.
|
||||
lastAccess
|
||||
lastModified
|
||||
|
||||
container cache objects start with cache:container ...
|
||||
|
||||
*/
|
||||
|
||||
|
||||
RDFT gCacheStore = NULL;
|
||||
|
||||
RDFT MakeCacheStore (char* url) {
|
||||
if (startsWith("rdf:cache", url)) {
|
||||
if (gCacheStore != NULL) {
|
||||
return gCacheStore;
|
||||
} else {
|
||||
RDF_Translator ntr = (RDF_Translator)getMem(sizeof(RDF_TranslatorStruct));
|
||||
ntr->assert = NULL;
|
||||
ntr->unassert = NULL;
|
||||
ntr->getSlotValue = cacheGetSlotValue;
|
||||
ntr->getSlotValues = cacheGetSlotValues;
|
||||
ntr->hasAssertion = cacheHasAssertion;
|
||||
ntr->nextValue = cacheNextValue;
|
||||
ntr->disposeCursor = cacheDisposeCursor;
|
||||
gCacheStore = ntr;
|
||||
return ntr;
|
||||
}
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
cacheHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv) {
|
||||
if ((resourceType(u) == CACHE_RT) && tv) {
|
||||
/*e.g., u->id = cache:http://www.netscape.com/
|
||||
s = gWebData->RDF_size
|
||||
v = 1000
|
||||
type = RDF_INT_TYPE
|
||||
return true if the cache object corresponding to u has a size of 1000
|
||||
e.g., u->id = cache:http://www.netscape.com/
|
||||
s = gCoreVocab->RDF_parent
|
||||
type = RDF_RESOURCE_TYPE
|
||||
v-> = "cache:container:MemoryCache"
|
||||
*/
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RDF_Cursor cacheGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv) {
|
||||
if ((resourceType(u) == CACHE_RT) && tv && (s == gCoreVocab->RDF_parent) && inversep) {
|
||||
RDF_Cursor c;
|
||||
c = (RDF_Cursor) getMem(sizeof(RDF_CursorStruc));
|
||||
c->u = u;
|
||||
c->count = 0;
|
||||
c->pdata = NULL;
|
||||
c->type = type;
|
||||
return c;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
void* cacheNextValue (RDFT rdf, RDF_Cursor c) {
|
||||
"return the next value, update count, return NUll when there are no more.
|
||||
the children are nodes. to create a new node, call RDF_Create(url, 1);
|
||||
If something is a container, after getting the object, do setContainerp(r, 1);"
|
||||
}
|
||||
|
||||
RDF_Error cacheDisposeCursor (RDFT rdf, RDF_Cursor c) {
|
||||
"dispose it. c could be NULL"
|
||||
}
|
||||
|
||||
|
||||
void* cacheGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,
|
||||
PRBool inversep, PRBool tv) {
|
||||
if ("willing to answer this") {
|
||||
return the value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
284
mozilla/modules/rdf/src/columns.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file synthesizes default columns for a given node.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "columns.h"
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
ColumnsGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
RDF_Cursor c;
|
||||
|
||||
if (!containerp(u) || (s != gNavCenter->RDF_Column) || (inversep) ||
|
||||
(!tv) || (type != RDF_RESOURCE_TYPE))
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
if ((c = (RDF_Cursor)getMem(sizeof(struct RDF_CursorStruct))) != NULL)
|
||||
{
|
||||
c->u = u;
|
||||
c->value = NULL;
|
||||
c->count = 0;
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
ColumnsGetSlotValue(RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,
|
||||
PRBool inversep, PRBool tv)
|
||||
{
|
||||
void *val = NULL;
|
||||
|
||||
if (u == NULL) return(NULL);
|
||||
|
||||
if ((s == gCoreVocab->RDF_name) && (type == RDF_STRING_TYPE)
|
||||
&& (!inversep) && (tv))
|
||||
{
|
||||
#ifdef XXX
|
||||
if (u == gCoreVocab->RDF_name) val = copyString(XP_GetString(RDF_NAME_STR));
|
||||
else if (u == gNavCenter->RDF_URLShortcut) val = copyString(XP_GetString(RDF_SHORTCUT_STR));
|
||||
else if (u == gWebData->RDF_URL) val = copyString(XP_GetString(RDF_URL_STR));
|
||||
else if (u == gWebData->RDF_description) val = copyString(XP_GetString(RDF_DESCRIPTION_STR));
|
||||
else if (u == gWebData->RDF_firstVisitDate) val = copyString(XP_GetString(RDF_FIRST_VISIT_STR));
|
||||
else if (u == gWebData->RDF_lastVisitDate) val = copyString(XP_GetString(RDF_LAST_VISIT_STR));
|
||||
else if (u == gWebData->RDF_numAccesses) val = copyString(XP_GetString(RDF_NUM_ACCESSES_STR));
|
||||
else if (u == gWebData->RDF_creationDate) val = copyString(XP_GetString(RDF_CREATED_ON_STR));
|
||||
else if (u == gWebData->RDF_lastModifiedDate) val = copyString(XP_GetString(RDF_LAST_MOD_STR));
|
||||
else if (u == gWebData->RDF_size) val = copyString(XP_GetString(RDF_SIZE_STR));
|
||||
else if (u == gNavCenter->RDF_bookmarkAddDate) val = copyString(XP_GetString(RDF_ADDED_ON_STR));
|
||||
#endif
|
||||
}
|
||||
else if ((s == gNavCenter->RDF_ColumnDataType) &&
|
||||
(type == RDF_INT_TYPE) && (!inversep) && (tv))
|
||||
{
|
||||
if (u == gNavCenter->RDF_bookmarkAddDate ||
|
||||
u == gWebData->RDF_firstVisitDate ||
|
||||
u == gWebData->RDF_lastVisitDate ||
|
||||
u == gWebData->RDF_lastModifiedDate ||
|
||||
u == gWebData->RDF_creationDate)
|
||||
{
|
||||
val = (void *)HT_COLUMN_STRING;
|
||||
}
|
||||
else if (u == gWebData->RDF_size ||
|
||||
u == gWebData->RDF_numAccesses ||
|
||||
u == gNavCenter->cookieDomain ||
|
||||
u == gNavCenter->cookieSecure)
|
||||
{
|
||||
val = (void *)HT_COLUMN_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default to string... XXX wrong thing to do? */
|
||||
val = (void *)HT_COLUMN_STRING;
|
||||
}
|
||||
}
|
||||
else if ((s == gNavCenter->RDF_ColumnWidth) &&
|
||||
(type == RDF_INT_TYPE) && (!inversep) && (tv))
|
||||
{
|
||||
if (u == gCoreVocab->RDF_name) val = (void *)128L;
|
||||
else if (u == gWebData->RDF_URL) val = (void *)200L;
|
||||
else val = (void *)80;
|
||||
}
|
||||
return(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
ColumnsNextValue (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
void *arc = NULL;
|
||||
|
||||
PR_ASSERT(c != NULL);
|
||||
if (c == NULL) return(NULL);
|
||||
|
||||
switch( resourceType(c->u) )
|
||||
{
|
||||
case RDF_RT:
|
||||
if ((c->u == gNavCenter->RDF_Sitemaps) || (c->u == gNavCenter->RDF_Mail))
|
||||
{
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gWebData->RDF_URL; break;
|
||||
}
|
||||
}
|
||||
else do
|
||||
{
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1:
|
||||
if ((idenEqual(c->u, gNavCenter->RDF_BookmarkFolderCategory)) ||
|
||||
((!startsWith("http://", resourceID(c->u))) && endsWith(".rdf", resourceID(c->u))))
|
||||
{
|
||||
arc = gNavCenter->RDF_URLShortcut;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* disallow shortcuts from external RDF graphs, so skip to next column */
|
||||
arc = NULL;
|
||||
++(c->count);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: arc = gWebData->RDF_URL; break;
|
||||
case 3: arc = gWebData->RDF_description; break;
|
||||
case 4: arc = gWebData->RDF_keyword; break;
|
||||
case 5: arc = gNavCenter->RDF_bookmarkAddDate; break;
|
||||
case 6: arc = gWebData->RDF_lastVisitDate; break;
|
||||
case 7: arc = gWebData->RDF_lastModifiedDate; break;
|
||||
case 8: arc = gNavCenter->pos; break;
|
||||
}
|
||||
} while ((c->count <= 6) && (arc == NULL));
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case HISTORY_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gWebData->RDF_URL; break;
|
||||
case 2: arc = gWebData->RDF_firstVisitDate; break;
|
||||
case 3: arc = gWebData->RDF_lastVisitDate; break;
|
||||
case 4: arc = NULL; break;
|
||||
case 5: arc = gWebData->RDF_numAccesses; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case COOKIE_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gNavCenter->cookieHost; break;
|
||||
case 2: arc = gNavCenter->cookiePath; break;
|
||||
case 3: arc = gNavCenter->cookieValue; break;
|
||||
case 4: arc = gNavCenter->cookieExpires; break;
|
||||
case 5: arc = gNavCenter->cookieDomain; break;
|
||||
case 6: arc = gNavCenter->cookieSecure; break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FTP_RT:
|
||||
case ES_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gWebData->RDF_URL; break;
|
||||
case 2: arc = gWebData->RDF_description; break;
|
||||
case 3: arc = gWebData->RDF_size; break;
|
||||
case 4: arc = gWebData->RDF_lastModifiedDate; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LFS_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gWebData->RDF_URL; break;
|
||||
case 2: arc = gWebData->RDF_description; break;
|
||||
case 3: arc = gWebData->RDF_size; break;
|
||||
case 4: arc = gWebData->RDF_lastModifiedDate; break;
|
||||
case 5: arc = gWebData->RDF_creationDate; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PM_RT:
|
||||
case IM_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gWebData->RDF_URL; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEARCH_RT:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
case 1: arc = gNavCenter->RDF_URLShortcut; break;
|
||||
case 2: arc = gWebData->RDF_URL; break;
|
||||
case 3: arc = gWebData->RDF_description; break;
|
||||
case 4: arc = gWebData->RDF_keyword; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
switch(c->count)
|
||||
{
|
||||
case 0: arc = gCoreVocab->RDF_name; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++(c->count);
|
||||
return(arc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
ColumnsDisposeCursor (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
if (c != NULL)
|
||||
{
|
||||
freeMem(c);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakeColumnStore (char* url)
|
||||
{
|
||||
RDFT ntr = NULL;
|
||||
|
||||
if (strstr(url, "rdf:columns"))
|
||||
{
|
||||
if ((ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct))) != NULL)
|
||||
{
|
||||
ntr->getSlotValues = ColumnsGetSlotValues;
|
||||
ntr->getSlotValue = ColumnsGetSlotValue;
|
||||
ntr->nextValue = ColumnsNextValue;
|
||||
ntr->disposeCursor = ColumnsDisposeCursor;
|
||||
ntr->url = copyString(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(ntr);
|
||||
}
|
||||
48
mozilla/modules/rdf/src/columns.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_COLUMNS_H_
|
||||
#define _RDF_COLUMNS_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "htrdf.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
|
||||
/* columns.c data structures */
|
||||
|
||||
extern int RDF_NAME_STR, RDF_SHORTCUT_STR, RDF_URL_STR, RDF_DESCRIPTION_STR;
|
||||
extern int RDF_FIRST_VISIT_STR, RDF_LAST_VISIT_STR, RDF_NUM_ACCESSES_STR;
|
||||
extern int RDF_CREATED_ON_STR, RDF_LAST_MOD_STR, RDF_SIZE_STR, RDF_ADDED_ON_STR;
|
||||
|
||||
|
||||
/* columns.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
RDF_Cursor ColumnsGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * ColumnsGetSlotValue(RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * ColumnsNextValue (RDFT rdf, RDF_Cursor c);
|
||||
RDF_Error ColumnsDisposeCursor (RDFT rdf, RDF_Cursor c);
|
||||
RDFT MakeColumnStore (char* url);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
574
mozilla/modules/rdf/src/comwrap.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "rdf.h"
|
||||
#include "nsIRDFDataSource.h"
|
||||
#include "nsIRDFDataBase.h"
|
||||
#include "nsIRDFObserver.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIRDFCursor.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include "plhash.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
PR_PUBLIC_API(void) _comwrap_NotificationCB(RDF_Event event, void* pdata);
|
||||
PR_END_EXTERN_C
|
||||
|
||||
class rdfDataBaseWrapper;
|
||||
class rdfCursorWrapper;
|
||||
class rdfServiceWrapper;
|
||||
class rdfServiceFactory;
|
||||
|
||||
class rdfDatabaseWrapper : public nsIRDFDataBase {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
rdfDatabaseWrapper(RDF r);
|
||||
virtual ~rdfDatabaseWrapper();
|
||||
|
||||
/* nsIRDFDataSource methods: */
|
||||
|
||||
NS_METHOD GetName(const RDF_String* name /* out */ );
|
||||
|
||||
NS_METHOD GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Resource *source /* out */);
|
||||
|
||||
NS_METHOD GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_Resource *source /* out */);
|
||||
|
||||
NS_METHOD GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
nsIRDFCursor **sources /* out */);
|
||||
|
||||
NS_METHOD GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
nsIRDFCursor **sources /* out */);
|
||||
|
||||
NS_METHOD GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
RDF_NodeStruct& target /* in/out */);
|
||||
|
||||
NS_METHOD GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
PRBool tv,
|
||||
RDF_NodeStruct& target /* in/out */);
|
||||
|
||||
NS_METHOD GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */);
|
||||
|
||||
NS_METHOD GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */);
|
||||
|
||||
NS_METHOD Assert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool tv = PR_TRUE);
|
||||
|
||||
NS_METHOD Unassert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target);
|
||||
|
||||
NS_METHOD HasAssertion(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool tv,
|
||||
PRBool* hasAssertion /* out */);
|
||||
|
||||
NS_METHOD AddObserver(nsIRDFObserver *n,
|
||||
RDF_EventMask type = RDF_ANY_NOTIFY);
|
||||
|
||||
NS_METHOD RemoveObserver(nsIRDFObserver *n,
|
||||
RDF_EventMask = RDF_ANY_NOTIFY);
|
||||
|
||||
NS_METHOD ArcLabelsIn(RDF_Node node,
|
||||
nsIRDFCursor **labels /* out */);
|
||||
|
||||
NS_METHOD ArcLabelsOut(RDF_Resource source,
|
||||
nsIRDFCursor **labels /* out */);
|
||||
|
||||
NS_METHOD Flush();
|
||||
|
||||
/* nsIRDFDataBase methods: */
|
||||
NS_METHOD AddDataSource(nsIRDFDataSource* dataSource);
|
||||
|
||||
NS_METHOD RemoveDataSource(nsIRDFDataSource* dataSource);
|
||||
|
||||
NS_METHOD GetDataSource(RDF_String url,
|
||||
nsIRDFDataSource **source /* out */ );
|
||||
|
||||
NS_METHOD DeleteAllArcs(RDF_Resource resource);
|
||||
|
||||
private:
|
||||
RDF mRDF;
|
||||
|
||||
PLHashTable* mpObserverMap;
|
||||
};
|
||||
|
||||
class rdfCursorWrapper : public nsIRDFCursor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
rdfCursorWrapper(RDF_Cursor c);
|
||||
virtual ~rdfCursorWrapper();
|
||||
|
||||
NS_METHOD HasElements(PRBool& hasElements);
|
||||
|
||||
NS_METHOD Next(RDF_NodeStruct& n);
|
||||
|
||||
private:
|
||||
RDF_Cursor mCursor;
|
||||
};
|
||||
|
||||
class rdfServiceWrapper : public nsIRDFService {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_METHOD CreateDatabase(const RDF_String* url,
|
||||
nsIRDFDataBase** db);
|
||||
|
||||
};
|
||||
|
||||
class rdfServiceFactory : public nsIFactory {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
rdfServiceFactory();
|
||||
virtual ~rdfServiceFactory();
|
||||
|
||||
NS_METHOD CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID anIID,
|
||||
void **aResult);
|
||||
|
||||
NS_METHOD LockFactory(PRBool aLock);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
rdfDataBaseWrapper:
|
||||
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS( rdfDatabaseWrapper, NS_IRDFDATABASE_IID )
|
||||
|
||||
rdfDatabaseWrapper::rdfDatabaseWrapper(RDF r) : mRDF(r)
|
||||
{
|
||||
mpObserverMap = PL_NewHashTable( 100,
|
||||
NULL, // XXX isn't there are hash fn for pointers???
|
||||
PL_CompareValues,
|
||||
PL_CompareValues,
|
||||
0,
|
||||
0 );
|
||||
|
||||
PR_ASSERT( mpObserverMap );
|
||||
#ifdef XXX
|
||||
if( !mpObserverMap ) // XXX just like 'new' failing on this object?
|
||||
throw bad_alloc("rdf: unable to allocate observer map" );
|
||||
#endif
|
||||
}
|
||||
|
||||
rdfDatabaseWrapper::~rdfDatabaseWrapper()
|
||||
{
|
||||
PL_HashTableDestroy( mpObserverMap );
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetName(const RDF_String* name /* out */ )
|
||||
{
|
||||
PR_ASSERT( PR_FALSE );
|
||||
return NS_ERROR_NOT_IMPLEMENTED; // XXX
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Resource *source /* out */)
|
||||
{
|
||||
PR_ASSERT( target && source );
|
||||
*source = (RDF_Resource) RDF_GetSlotValue( mRDF,
|
||||
target->value.r,
|
||||
arcLabel,
|
||||
RDF_RESOURCE_TYPE, // anything else makes no sense
|
||||
PR_TRUE,
|
||||
PR_TRUE );
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetSource(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_Resource *source /* out */)
|
||||
{
|
||||
*source = (RDF_Resource) RDF_GetSlotValue( mRDF,
|
||||
target->value.r,
|
||||
arcLabel,
|
||||
RDF_RESOURCE_TYPE, // anything else makes no sense
|
||||
PR_TRUE,
|
||||
tv );
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
nsIRDFCursor **sources /* out */)
|
||||
{
|
||||
return GetSources(target,arcLabel,PR_TRUE,sources);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetSources(RDF_Node target,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
nsIRDFCursor **sources /* out */)
|
||||
{
|
||||
PR_ASSERT( sources );
|
||||
if( 0 == sources )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*sources = 0;
|
||||
|
||||
RDF_Cursor c = RDF_GetSources( mRDF,
|
||||
target->value.r,
|
||||
arcLabel,
|
||||
RDF_RESOURCE_TYPE, // anything else makes no sense
|
||||
tv );
|
||||
|
||||
if( c ) {
|
||||
*sources = new rdfCursorWrapper( c );
|
||||
(*sources)->AddRef();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
RDF_NodeStruct& target /* in/out */)
|
||||
{
|
||||
return GetTarget(source,arcLabel,targetType,PR_TRUE,target);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetTarget(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
PRBool tv,
|
||||
RDF_NodeStruct& target /* in/out */)
|
||||
{
|
||||
PR_ASSERT( targetType != RDF_ANY_TYPE ); // not ready to support this yet
|
||||
|
||||
void* value = RDF_GetSlotValue( mRDF,
|
||||
target.value.r,
|
||||
arcLabel,
|
||||
targetType, // anything else makes no sense
|
||||
PR_FALSE,
|
||||
tv );
|
||||
|
||||
target.type = targetType;
|
||||
target.value.r = (RDF_Resource) value; // reasonable? XXX
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */)
|
||||
{
|
||||
return GetTargets(source,arcLabel,PR_TRUE,targetType,targets);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::GetTargets(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
PRBool tv,
|
||||
RDF_ValueType targetType,
|
||||
nsIRDFCursor **targets /* out */)
|
||||
{
|
||||
PR_ASSERT( targets );
|
||||
if( 0 == targets )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*targets = 0;
|
||||
|
||||
RDF_Cursor c = RDF_GetTargets( mRDF,
|
||||
source,
|
||||
arcLabel,
|
||||
targetType,
|
||||
tv );
|
||||
|
||||
if( c ) {
|
||||
*targets = new rdfCursorWrapper( c );
|
||||
(*targets)->AddRef();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::Assert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool tv)
|
||||
{
|
||||
PRBool b = tv ? RDF_Assert( mRDF, source, arcLabel, (void*)target->value.r, target->type ) :
|
||||
RDF_AssertFalse( mRDF, source, arcLabel, (void*)target->value.r, target->type );
|
||||
|
||||
// XXX
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::Unassert(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target)
|
||||
{
|
||||
PRBool b = RDF_Unassert( mRDF,
|
||||
source,
|
||||
arcLabel,
|
||||
target->value.r,
|
||||
target->type ); // XXX
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::HasAssertion(RDF_Resource source,
|
||||
RDF_Resource arcLabel,
|
||||
RDF_Node target,
|
||||
PRBool truthValue,
|
||||
PRBool* hasAssertion /* out */)
|
||||
{
|
||||
*hasAssertion = RDF_HasAssertion( mRDF,
|
||||
source,
|
||||
arcLabel,
|
||||
target->value.r,
|
||||
target->type,
|
||||
truthValue );
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
_comwrap_NotificationCB(RDF_Event event, void* pdata)
|
||||
{
|
||||
nsIRDFObserver* observer = (nsIRDFObserver*) pdata;
|
||||
// XXX QueryInterface & release??
|
||||
observer->HandleEvent( (nsIRDFDataSource*)pdata, event );
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::AddObserver(nsIRDFObserver *observer,
|
||||
RDF_EventMask type)
|
||||
{
|
||||
// XXX event masking does not currently work
|
||||
|
||||
RDF_Notification notification = (RDF_Notification) PL_HashTableLookup( mpObserverMap, observer );
|
||||
if( !notification ) {
|
||||
observer->AddRef();
|
||||
notification = RDF_AddNotifiable( mRDF,
|
||||
_comwrap_NotificationCB,
|
||||
NULL, // XXX
|
||||
observer );
|
||||
PL_HashTableAdd( mpObserverMap,
|
||||
observer,
|
||||
notification );
|
||||
}
|
||||
|
||||
return NS_OK; // XXX
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::RemoveObserver(nsIRDFObserver *observer,
|
||||
RDF_EventMask type)
|
||||
{
|
||||
|
||||
RDF_Notification notification = (RDF_Notification) PL_HashTableLookup( mpObserverMap, observer );
|
||||
if( !notification )
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
RDF_Error err = RDF_DeleteNotifiable( notification );
|
||||
PR_ASSERT( !err ); // the current implementation never fails!
|
||||
PL_HashTableRemove( mpObserverMap, observer );
|
||||
observer->Release();
|
||||
|
||||
return NS_OK; // XXX
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::ArcLabelsIn(RDF_Node node,
|
||||
nsIRDFCursor **labels /* out */)
|
||||
{
|
||||
PR_ASSERT( labels );
|
||||
if( 0 == labels )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*labels = 0;
|
||||
|
||||
RDF_Cursor c = RDF_ArcLabelsIn( mRDF, node->value.r );
|
||||
|
||||
if( c ) {
|
||||
*labels = new rdfCursorWrapper( c );
|
||||
(*labels)->AddRef();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::ArcLabelsOut(RDF_Resource source,
|
||||
nsIRDFCursor **labels /* out */)
|
||||
{
|
||||
PR_ASSERT( labels );
|
||||
if( 0 == labels )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*labels = 0;
|
||||
|
||||
RDF_Cursor c = RDF_ArcLabelsOut( mRDF, source );
|
||||
|
||||
if( c ) {
|
||||
*labels = new rdfCursorWrapper( c );
|
||||
(*labels)->AddRef();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::Flush()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED; // XXX
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD
|
||||
rdfDatabaseWrapper::DeleteAllArcs(RDF_Resource resource)
|
||||
{
|
||||
return RDF_DeleteAllArcs( mRDF, resource );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
rdfServiceWrapper: the RDF service singleton
|
||||
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS( rdfServiceWrapper, NS_IRDFSERVICE_IID )
|
||||
|
||||
NS_METHOD
|
||||
rdfServiceWrapper::CreateDatabase(const RDF_String* url_ary,
|
||||
nsIRDFDataBase **db)
|
||||
{
|
||||
PR_ASSERT( 0 != db );
|
||||
if( 0 == db )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*db = 0;
|
||||
|
||||
nsresult result = NS_OK;
|
||||
RDF rdf = RDF_GetDB(url_ary);
|
||||
|
||||
if( 0 == rdf ) {
|
||||
result = RDF_ERROR_UNABLE_TO_CREATE; // XXX this is too wishy-washy
|
||||
} else {
|
||||
*db = new rdfDatabaseWrapper(rdf); // XXX
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
rdfCursorWrapper
|
||||
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS( rdfCursorWrapper, NS_IRDFCURSOR_IID )
|
||||
|
||||
rdfCursorWrapper::rdfCursorWrapper(RDF_Cursor c) : mCursor(c)
|
||||
{
|
||||
}
|
||||
|
||||
rdfCursorWrapper::~rdfCursorWrapper()
|
||||
{
|
||||
RDF_DisposeCursor( mCursor );
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfCursorWrapper::Next(RDF_NodeStruct& next)
|
||||
{
|
||||
next.type = RDF_CursorValueType( mCursor );
|
||||
next.value.r = (RDF_Resource) RDF_NextValue( mCursor );
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
rdfServiceFactory
|
||||
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS( rdfServiceFactory, NS_IFACTORY_IID )
|
||||
|
||||
NS_METHOD
|
||||
rdfServiceFactory::CreateInstance( nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult )
|
||||
{
|
||||
PR_ASSERT( aResult );
|
||||
if( 0 == aResult )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*aResult = 0;
|
||||
|
||||
nsISupports* instance = new rdfServiceWrapper();
|
||||
|
||||
nsresult result = instance->QueryInterface( aIID, aResult );
|
||||
PR_ASSERT( result = NS_OK );
|
||||
|
||||
if( result != NS_OK )
|
||||
delete instance; // wrong interface!
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfServiceFactory::LockFactory(PRBool lock)
|
||||
{
|
||||
PR_ASSERT( PR_FALSE );
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
490
mozilla/modules/rdf/src/es2mcf.c
Normal file
@@ -0,0 +1,490 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements FTP support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "es2mcf.h"
|
||||
#include "glue.h"
|
||||
#include "ht.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/* externs */
|
||||
extern RDF gNCDB;
|
||||
#define ESFTPRT(x) ((resourceType((RDF_Resource)x) == ES_RT) || (resourceType((RDF_Resource)x) == FTP_RT))
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakeESFTPStore (char* url)
|
||||
{
|
||||
RDFT ntr = NewRemoteStore(url);
|
||||
ntr->assert = ESAssert;
|
||||
ntr->unassert = ESUnassert;
|
||||
ntr->possiblyAccessFile = ESFTPPossiblyAccessFile;
|
||||
return ntr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ESFTPPossiblyAccessFile (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
if (((resourceType(u) == ES_RT) || (resourceType(u) == FTP_RT)) &&
|
||||
(s == gCoreVocab->RDF_parent) && (containerp(u))) {
|
||||
char* id = resourceID(u);
|
||||
readRDFFile((resourceType(u) == ES_RT ? &id[4] : id), u, false, rdf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ESAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
PRBool retVal;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char*) v)));
|
||||
|
||||
if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE) &&
|
||||
(ESFTPRT((RDF_Resource)v)) &&
|
||||
(tv) && (containerp((RDF_Resource)v))) {
|
||||
ESAddChild((RDF_Resource)v, u);
|
||||
retVal = PR_TRUE;
|
||||
} else {
|
||||
retVal = PR_FALSE;
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ESUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type)
|
||||
{
|
||||
PRBool retVal;
|
||||
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char*) v)));
|
||||
if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE) &&
|
||||
(ESFTPRT((RDF_Resource)v)) &&
|
||||
(containerp((RDF_Resource)v))) {
|
||||
ESRemoveChild((RDF_Resource)v, u);
|
||||
retVal = PR_TRUE;
|
||||
} else {
|
||||
retVal = PR_FALSE;
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
es_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx)
|
||||
{
|
||||
RDF_Resource parent = NULL, child = NULL, r;
|
||||
_esFEData *feData;
|
||||
char *newURL, *p;
|
||||
|
||||
feData = (_esFEData *)urls->fe_data;
|
||||
if ((status >= 0) && (feData != NULL))
|
||||
{
|
||||
parent = RDF_GetResource(gNCDB, feData->parent, false);
|
||||
child = RDF_GetResource(gNCDB, feData->child, false);
|
||||
if ((parent != NULL) && (child != NULL))
|
||||
{
|
||||
switch(feData->method)
|
||||
{
|
||||
case URL_POST_METHOD:
|
||||
if (((p = RDF_STRRCHR(resourceID(child), '/')) != NULL) && (*++p != '\0'))
|
||||
{
|
||||
if ((newURL = append2Strings(resourceID(parent), p)) != NULL)
|
||||
{
|
||||
if ((r = RDF_GetResource(gNCDB, newURL, 1)) != NULL)
|
||||
{
|
||||
setContainerp(r, containerp(child));
|
||||
setResourceType(r, resourceType(child));
|
||||
|
||||
remoteStoreAdd(gRemoteStore, r,
|
||||
gCoreVocab->RDF_parent, parent,
|
||||
RDF_RESOURCE_TYPE, 1);
|
||||
}
|
||||
freeMem(newURL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case URL_DELETE_METHOD:
|
||||
remoteStoreRemove(gRemoteStore, child,
|
||||
gCoreVocab->RDF_parent, parent,
|
||||
RDF_RESOURCE_TYPE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (status < 0)
|
||||
{
|
||||
if ((cx != NULL) && (urls != NULL) && (urls->error_msg != NULL))
|
||||
{
|
||||
FE_Alert(cx, urls->error_msg);
|
||||
}
|
||||
}
|
||||
if (feData != NULL)
|
||||
{
|
||||
esFreeFEData(feData);
|
||||
}
|
||||
NET_FreeURLStruct (urls);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
nativeFilename(char *filename)
|
||||
{
|
||||
char *newName = NULL, *temp;
|
||||
int x = 0;
|
||||
|
||||
if (filename == NULL) return(NULL);
|
||||
if ((newName = unescapeURL(filename)) != NULL)
|
||||
{
|
||||
if ((temp = convertFileURLToNSPRCopaceticPath(newName)) != NULL)
|
||||
{
|
||||
temp = copyString(temp);
|
||||
}
|
||||
freeMem(newName);
|
||||
newName = temp;
|
||||
#ifdef XP_WIN
|
||||
if (newName != NULL)
|
||||
{
|
||||
while (newName[x] != '\0')
|
||||
{
|
||||
if (newName[x] == '/')
|
||||
{
|
||||
newName[x] = '\\';
|
||||
}
|
||||
++x;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return(newName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_esFEData *
|
||||
esMakeFEData(RDF_Resource parent, RDF_Resource child, int method)
|
||||
{
|
||||
_esFEData *feData;
|
||||
|
||||
if ((feData = (_esFEData *)XP_ALLOC(3*sizeof(char *))) != NULL)
|
||||
{
|
||||
feData->parent = copyString(resourceID(parent));
|
||||
feData->child = copyString(resourceID(child));
|
||||
feData->method = method;
|
||||
}
|
||||
return(feData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
esFreeFEData(_esFEData *feData)
|
||||
{
|
||||
if (feData != NULL)
|
||||
{
|
||||
if (feData->parent) freeMem(feData->parent);
|
||||
if (feData->child) freeMem(feData->child);
|
||||
freeMem(feData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** go tell the directory that child got added to parent **/
|
||||
void
|
||||
ESAddChild (RDF_Resource parent, RDF_Resource child)
|
||||
{
|
||||
URL_Struct *urls;
|
||||
void *feData, **files_to_post = NULL;
|
||||
|
||||
if ((urls = NET_CreateURLStruct(resourceID(parent), NET_SUPER_RELOAD)) != NULL)
|
||||
{
|
||||
feData = (void *)esMakeFEData(parent, child, URL_POST_METHOD);
|
||||
if ((files_to_post = (char **)XP_ALLOC(2*sizeof(char *))) != NULL)
|
||||
{
|
||||
files_to_post[0] = nativeFilename(resourceID(child));
|
||||
files_to_post[1] = NULL;
|
||||
}
|
||||
if ((feData != NULL) && (files_to_post != NULL))
|
||||
{
|
||||
urls->files_to_post = (void *)files_to_post;
|
||||
urls->post_to = NULL;
|
||||
urls->method = URL_POST_METHOD;
|
||||
urls->fe_data = (void *)feData;
|
||||
NET_GetURL(urls, FO_PRESENT,
|
||||
(MWContext *)gRDFMWContext(NULL),
|
||||
es_GetUrlExitFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (feData != NULL)
|
||||
{
|
||||
esFreeFEData(feData);
|
||||
}
|
||||
if (files_to_post != NULL)
|
||||
{
|
||||
if (files_to_post[0] != NULL) freeMem(files_to_post[0]);
|
||||
XP_FREE(files_to_post);
|
||||
}
|
||||
NET_FreeURLStruct(urls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** remove the child from the directory **/
|
||||
void
|
||||
ESRemoveChild (RDF_Resource parent, RDF_Resource child)
|
||||
{
|
||||
URL_Struct *urls;
|
||||
void *feData;
|
||||
|
||||
if ((urls = NET_CreateURLStruct(resourceID(child), NET_SUPER_RELOAD)) != NULL)
|
||||
{
|
||||
feData = (void *)esMakeFEData(parent, child, URL_DELETE_METHOD);
|
||||
if (feData != NULL)
|
||||
{
|
||||
urls->method = URL_DELETE_METHOD;
|
||||
urls->fe_data = (void *)feData;
|
||||
NET_GetURL(urls, FO_PRESENT,
|
||||
(MWContext *)gRDFMWContext(NULL),
|
||||
es_GetUrlExitFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_FreeURLStruct(urls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
parseNextESFTPLine (RDFFile f, char* line)
|
||||
{
|
||||
PRBool directoryp;
|
||||
RDF_Resource ru;
|
||||
char *token, *url;
|
||||
int16 loop, tokenNum = 0;
|
||||
int32 val;
|
||||
|
||||
if (f->fileType != FTP_RT && f->fileType != ES_RT) return;
|
||||
|
||||
/* work around bug where linefeeds are actually encoded as %0A */
|
||||
if (endsWith("%0A", line)) line[RDF_STRLEN(line)-3] = '\0';
|
||||
|
||||
if ((token = strtok(line, " ")) != NULL)
|
||||
{
|
||||
/* skip 1st token (the numeric command) */
|
||||
token = strtok(NULL, " \t");
|
||||
}
|
||||
|
||||
if (startsWith("200:", line))
|
||||
{
|
||||
while (token != NULL)
|
||||
{
|
||||
while ((token != NULL) && (tokenNum < RDF_MAX_NUM_FILE_TOKENS))
|
||||
{
|
||||
if (!RDF_STRCMP(token, "Filename"))
|
||||
{
|
||||
f->tokens[f->numFileTokens].token = gCoreVocab->RDF_name;
|
||||
f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;
|
||||
f->tokens[f->numFileTokens].tokenNum = tokenNum;
|
||||
++(f->numFileTokens);
|
||||
}
|
||||
else if (!RDF_STRCMP(token, "Content-Length"))
|
||||
{
|
||||
f->tokens[f->numFileTokens].token = gWebData->RDF_size;
|
||||
f->tokens[f->numFileTokens].type = RDF_INT_TYPE;
|
||||
f->tokens[f->numFileTokens].tokenNum = tokenNum;
|
||||
++(f->numFileTokens);
|
||||
}
|
||||
else if (!RDF_STRCMP(token, "File-type"))
|
||||
{
|
||||
f->tokens[f->numFileTokens].token = gWebData->RDF_description;
|
||||
f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;
|
||||
f->tokens[f->numFileTokens].tokenNum = tokenNum;
|
||||
++(f->numFileTokens);
|
||||
}
|
||||
else if (!RDF_STRCMP(token, "Last-Modified"))
|
||||
{
|
||||
f->tokens[f->numFileTokens].token = gWebData->RDF_lastModifiedDate;
|
||||
f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;
|
||||
f->tokens[f->numFileTokens].tokenNum = tokenNum;
|
||||
++(f->numFileTokens);
|
||||
}
|
||||
/*
|
||||
else if (!RDF_STRCMP(token, "Permissions"))
|
||||
{
|
||||
f->tokens[f->numFileTokens].token = NULL;
|
||||
f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;
|
||||
f->tokens[f->numFileTokens].tokenNum = tokenNum;
|
||||
++(f->numFileTokens);
|
||||
}
|
||||
*/
|
||||
++tokenNum;
|
||||
token = strtok(NULL, " \t");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (startsWith("201:", line))
|
||||
{
|
||||
directoryp = false;
|
||||
while (token != NULL)
|
||||
{
|
||||
for (loop=0; loop<f->numFileTokens; loop++)
|
||||
{
|
||||
if (tokenNum == f->tokens[loop].tokenNum)
|
||||
{
|
||||
f->tokens[loop].data = strdup(token);
|
||||
if (f->tokens[loop].token == gWebData->RDF_description)
|
||||
{
|
||||
if (startsWith("Directory", token) ||
|
||||
startsWith("Sym-Directory", token))
|
||||
{
|
||||
directoryp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++tokenNum;
|
||||
token = strtok(NULL, " \t");
|
||||
}
|
||||
|
||||
ru = NULL;
|
||||
for (loop=0; loop<f->numFileTokens; loop++)
|
||||
{
|
||||
/* find name, create resource from it */
|
||||
|
||||
if (f->tokens[loop].token == gCoreVocab->RDF_name)
|
||||
{
|
||||
if (resourceType(f->top) == ES_RT)
|
||||
{
|
||||
url = PR_smprintf("nes:%s%s%s", f->url, f->tokens[loop].data, (directoryp) ? "/":"");
|
||||
}
|
||||
else
|
||||
{
|
||||
url = PR_smprintf("%s%s%s", f->url, f->tokens[loop].data, (directoryp) ? "/":"");
|
||||
}
|
||||
if (url != NULL)
|
||||
{
|
||||
if ((ru = RDF_GetResource(NULL, url, 1)) != NULL)
|
||||
{
|
||||
setResourceType(ru, resourceType(f->top));
|
||||
if (directoryp == true)
|
||||
{
|
||||
setContainerp(ru, 1);
|
||||
}
|
||||
XP_FREE(url);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ru != NULL)
|
||||
{
|
||||
for (loop=0; loop<f->numFileTokens; loop++)
|
||||
{
|
||||
if (f->tokens[loop].data != NULL)
|
||||
{
|
||||
switch(f->tokens[loop].type)
|
||||
{
|
||||
case RDF_STRING_TYPE:
|
||||
addSlotValue(f, ru, f->tokens[loop].token,
|
||||
unescapeURL(f->tokens[loop].data),
|
||||
f->tokens[loop].type, NULL);
|
||||
break;
|
||||
|
||||
case RDF_INT_TYPE:
|
||||
if (directoryp == false)
|
||||
{
|
||||
sscanf(f->tokens[loop].data, "%lu", &val);
|
||||
if (val != 0)
|
||||
{
|
||||
addSlotValue(f, ru, f->tokens[loop].token,
|
||||
(void *)val, f->tokens[loop].type, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
addSlotValue(f, ru, gCoreVocab->RDF_parent, f->top, RDF_RESOURCE_TYPE, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
parseNextESFTPBlob(NET_StreamClass *stream, char* blob, int32 size)
|
||||
{
|
||||
RDFFile f;
|
||||
int32 n, last, m;
|
||||
n = last = 0;
|
||||
|
||||
f = (RDFFile)stream->data_object;
|
||||
if (f == NULL || size < 0) {
|
||||
return MK_INTERRUPTED;
|
||||
}
|
||||
|
||||
while (n < size) {
|
||||
char c = blob[n];
|
||||
m = 0;
|
||||
memset(f->line, '\0', f->lineSize);
|
||||
if (f->holdOver[0] != '\0') {
|
||||
memcpy(f->line, f->holdOver, RDF_STRLEN(f->holdOver));
|
||||
m = RDF_STRLEN(f->holdOver);
|
||||
memset(f->holdOver, '\0', RDF_BUF_SIZE);
|
||||
}
|
||||
while ((m < f->lineSize) && (c != '\r') && (c != '\n') && (n < size)) {
|
||||
f->line[m] = c;
|
||||
m++;
|
||||
n++;
|
||||
c = blob[n];
|
||||
}
|
||||
n++;
|
||||
if (m > 0) {
|
||||
if ((c == '\n') || (c == '\r')) {
|
||||
last = n;
|
||||
parseNextESFTPLine(f, f->line);
|
||||
} else if (size > last) {
|
||||
memcpy(f->holdOver, f->line, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
67
mozilla/modules/rdf/src/es2mcf.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_ES2MCF_H_
|
||||
#define _RDF_ES2MCF_H_
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "net.h"
|
||||
|
||||
|
||||
|
||||
/* es2mcf.c data structures and defines */
|
||||
|
||||
typedef struct {
|
||||
char *parent;
|
||||
char *child;
|
||||
int method;
|
||||
} _esFEData;
|
||||
|
||||
|
||||
|
||||
/* es2mcf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
RDFT MakeESFTPStore (char* url);
|
||||
_esFEData * esMakeFEData(RDF_Resource parent, RDF_Resource child, int method);
|
||||
void esFreeFEData(_esFEData *feData);
|
||||
void ESFTPPossiblyAccessFile (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep) ;
|
||||
RDF_Error ESInit (RDFT ntr);
|
||||
PRBool ESFTPRT (RDF_Resource u);
|
||||
PRBool ESAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool ESUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ESDBAdd (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ESDBRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ESHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
void * ESGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor ESGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * ESNextValue (RDFT mcf, RDF_Cursor c);
|
||||
RDF_Error ESDisposeCursor (RDFT mcf, RDF_Cursor c);
|
||||
void es_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx);
|
||||
char * nativeFilename(char *filename);
|
||||
void ESAddChild (RDF_Resource parent, RDF_Resource child);
|
||||
void ESRemoveChild (RDF_Resource parent, RDF_Resource child);
|
||||
void possiblyAccessES(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
void parseNextESFTPLine (RDFFile f, char* line);
|
||||
int parseNextESFTPBlob(NET_StreamClass *stream, char* blob, int32 size);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
372
mozilla/modules/rdf/src/find2rdf.c
Normal file
@@ -0,0 +1,372 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements Find support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "find2rdf.h"
|
||||
|
||||
/* globals */
|
||||
static RDFT gRDFFindDB = NULL;
|
||||
|
||||
|
||||
|
||||
void
|
||||
parseResourceIntoFindTokens(RDF_Resource u, findTokenStruct *tokens)
|
||||
{
|
||||
char *id, *token, *value;
|
||||
int loop;
|
||||
|
||||
if ((id = copyString(resourceID(u) + RDF_STRLEN("find:"))) != NULL)
|
||||
{
|
||||
/* parse ID, build up token list */
|
||||
if ((token = strtok(id, "&")) != NULL)
|
||||
{
|
||||
while (token != NULL)
|
||||
{
|
||||
if ((value = strstr(token, "=")) != NULL)
|
||||
{
|
||||
*value++ = '\0';
|
||||
}
|
||||
for (loop=0; tokens[loop].token != NULL; loop++)
|
||||
{
|
||||
if (!RDF_STRCMP(token, tokens[loop].token))
|
||||
{
|
||||
tokens[loop].value = copyString(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, "&");
|
||||
}
|
||||
}
|
||||
freeMem(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
parseFindURL(RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
RDF_Resource searchOn = NULL, matchOn = NULL;
|
||||
int loop;
|
||||
findTokenStruct tokens[5];
|
||||
|
||||
/* build up a token list */
|
||||
tokens[0].token = "location"; tokens[0].value = NULL;
|
||||
tokens[1].token = "attribute"; tokens[1].value = NULL;
|
||||
tokens[2].token = "method"; tokens[2].value = NULL;
|
||||
tokens[3].token = "value"; tokens[3].value = NULL;
|
||||
tokens[4].token = NULL; tokens[4].value = NULL;
|
||||
|
||||
parseResourceIntoFindTokens(u, tokens);
|
||||
|
||||
if ((tokens[1].value != NULL) && (tokens[3].value != NULL))
|
||||
{
|
||||
if ((searchOn = RDF_GetResource(NULL, tokens[1].value, 0)) != NULL)
|
||||
{
|
||||
if ((matchOn = RDF_GetResource(NULL, tokens[2].value, 0)) == NULL)
|
||||
{
|
||||
matchOn = gCoreVocab->RDF_substring;
|
||||
}
|
||||
if ((c = getMem(sizeof(struct RDF_CursorStruct))) != NULL)
|
||||
{
|
||||
c->u = u;
|
||||
c->s = s;
|
||||
c->type = type;
|
||||
c->tv = tv;
|
||||
c->inversep = inversep;
|
||||
c->count = 0;
|
||||
/* Note: need to copy value string [its a local variable] */
|
||||
c->pdata = (void *)RDF_Find(searchOn, matchOn,
|
||||
copyString(tokens[3].value), RDF_STRING_TYPE);
|
||||
if (c->pdata == NULL)
|
||||
{
|
||||
freeMem(c);
|
||||
c = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free values in token list */
|
||||
for (loop=0; tokens[loop].token != NULL; loop++)
|
||||
{
|
||||
if (tokens[loop].value != NULL)
|
||||
{
|
||||
freeMem(tokens[loop].value);
|
||||
tokens[loop].value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
FindGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
PRBool passThru = PR_TRUE;
|
||||
|
||||
if ((((s == gCoreVocab->RDF_child) && (!inversep)) ||
|
||||
((s == gCoreVocab->RDF_parent) && (inversep))) &&
|
||||
(type == RDF_RESOURCE_TYPE) && (tv))
|
||||
{
|
||||
if (startsWith("find:", resourceID(u)))
|
||||
{
|
||||
passThru = PR_FALSE;
|
||||
c = parseFindURL(rdf, u, s, type, inversep, tv);
|
||||
}
|
||||
}
|
||||
|
||||
if (passThru == PR_TRUE)
|
||||
{
|
||||
c = remoteStoreGetSlotValues(rdf, u, s, type, inversep, tv);
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
findNextURL(RDF_Cursor c)
|
||||
{
|
||||
RDF_Resource r = NULL;
|
||||
PRBool valid = PR_FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
if ((r = (RDF_Resource)RDF_NextValue(c)) != NULL)
|
||||
{
|
||||
if (strstr(resourceID(r), ":"))
|
||||
{
|
||||
if ((!startsWith("find:", resourceID(r))) &&
|
||||
(!startsWith("NC:", resourceID(r))) &&
|
||||
(!startsWith("Command:", resourceID(r))))
|
||||
{
|
||||
valid = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while((r != NULL) && (valid == PR_FALSE));
|
||||
return((void *)r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
FindNextValue(RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
PRBool passThru = PR_TRUE;
|
||||
void *retVal = NULL;
|
||||
|
||||
PR_ASSERT(c != NULL);
|
||||
if (c == NULL) return(NULL);
|
||||
|
||||
if ((c->u != NULL) && (((c->s == gCoreVocab->RDF_child) && (!(c->inversep))) ||
|
||||
((c->s == gCoreVocab->RDF_parent) && (c->inversep))) &&
|
||||
(c->type == RDF_RESOURCE_TYPE) && (c->tv))
|
||||
{
|
||||
if (startsWith("find:", resourceID(c->u)))
|
||||
{
|
||||
if (c->pdata != NULL)
|
||||
{
|
||||
passThru = PR_FALSE;
|
||||
retVal = findNextURL((RDF_Cursor)(c->pdata));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (passThru == PR_TRUE)
|
||||
{
|
||||
retVal = remoteStoreNextValue(rdf, c);
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
FindGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
void *retVal = NULL;
|
||||
PRBool passThru = PR_TRUE;
|
||||
|
||||
if ((startsWith("find:", resourceID(u))) && (s == gCoreVocab->RDF_name))
|
||||
{
|
||||
/* DebugStr("\p FindGetSlotValue on name"); */
|
||||
}
|
||||
|
||||
if (passThru == PR_TRUE)
|
||||
{
|
||||
retVal = remoteStoreGetSlotValue(rdf, u, s, type, inversep, tv);
|
||||
}
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char*) retVal)));
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
FindPossible(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
RDF_Cursor c;
|
||||
RDF_Resource r;
|
||||
|
||||
if ((startsWith("find:", resourceID(u))) && (containerp(u) &&
|
||||
(((s == gCoreVocab->RDF_parent) && (inversep)) ||
|
||||
((s == gCoreVocab->RDF_child) && (!inversep))) ))
|
||||
{
|
||||
if ((c = FindGetSlotValues (rdf, u, s, RDF_RESOURCE_TYPE, inversep, PR_TRUE)) != NULL)
|
||||
{
|
||||
while((r = (RDF_Resource)FindNextValue(rdf, c)) != NULL)
|
||||
{
|
||||
if (!remoteStoreHasAssertion (rdf, r, gCoreVocab->RDF_parent,
|
||||
u, RDF_RESOURCE_TYPE, PR_TRUE))
|
||||
{
|
||||
remoteStoreAdd(rdf, r, gCoreVocab->RDF_parent,
|
||||
u, RDF_RESOURCE_TYPE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
RDF_DisposeCursor(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
FindDisposeCursor(RDFT mcf, RDF_Cursor c)
|
||||
{
|
||||
RDF_Error err = noRDFErr;
|
||||
char *value;
|
||||
|
||||
if (c != NULL)
|
||||
{
|
||||
if ((((c->s == gCoreVocab->RDF_child) && (!(c->inversep))) ||
|
||||
((c->s == gCoreVocab->RDF_parent) && (c->inversep))) &&
|
||||
(c->type == RDF_RESOURCE_TYPE) && (c->tv))
|
||||
{
|
||||
if (startsWith("find:", resourceID(c->u)))
|
||||
{
|
||||
if (c->pdata != NULL)
|
||||
{
|
||||
/* Note: at creation, we had to copy "v",
|
||||
so free it here */
|
||||
if ((value = ((RDF_Cursor)(c->pdata))->value) != NULL)
|
||||
{
|
||||
freeMem(value);
|
||||
((RDF_Cursor)(c->pdata))->value = NULL;
|
||||
}
|
||||
RDF_DisposeCursor((RDF_Cursor)(c->pdata));
|
||||
c->pdata = NULL;
|
||||
}
|
||||
}
|
||||
freeMem(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = remoteStoreDisposeCursor (mcf, c);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
findPossiblyAddName(RDFT rdf, RDF_Resource u)
|
||||
{
|
||||
findTokenStruct tokens[5];
|
||||
char *name;
|
||||
|
||||
if ((name = (char *)remoteStoreGetSlotValue(rdf, u, gCoreVocab->RDF_name,
|
||||
RDF_STRING_TYPE, PR_FALSE, PR_TRUE)) == NULL)
|
||||
{
|
||||
/* build up a token list */
|
||||
tokens[0].token = "location"; tokens[0].value = NULL;
|
||||
tokens[1].token = "attribute"; tokens[1].value = NULL;
|
||||
tokens[2].token = "method"; tokens[2].value = NULL;
|
||||
tokens[3].token = "value"; tokens[3].value = NULL;
|
||||
tokens[4].token = NULL; tokens[4].value = NULL;
|
||||
|
||||
parseResourceIntoFindTokens(u, tokens);
|
||||
|
||||
if ((name = PR_smprintf(XP_GetString(RDF_FIND_FULLNAME_STR),
|
||||
((tokens[1].value != NULL) ? tokens[1].value : ""),
|
||||
((tokens[2].value != NULL) ? tokens[2].value : ""),
|
||||
((tokens[3].value != NULL) ? tokens[3].value : ""))) != NULL)
|
||||
{
|
||||
remoteStoreAdd(rdf, u, gCoreVocab->RDF_name, name,
|
||||
RDF_STRING_TYPE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
FindAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
/* don't handle the assert, but simply add a name if it doesn't already have one */
|
||||
|
||||
if (startsWith("find:", resourceID(u)))
|
||||
{
|
||||
findPossiblyAddName(rdf, u);
|
||||
}
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakeFindStore (char *url)
|
||||
{
|
||||
RDFT ntr = NULL;
|
||||
|
||||
if (gRDFFindDB != NULL) return(gRDFFindDB);
|
||||
|
||||
if (strstr(url, "rdf:find"))
|
||||
{
|
||||
if ((ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct))) != NULL)
|
||||
{
|
||||
ntr->assert = FindAssert;
|
||||
ntr->unassert = NULL;
|
||||
ntr->hasAssertion = remoteStoreHasAssertion;
|
||||
ntr->getSlotValue = FindGetSlotValue;
|
||||
ntr->getSlotValues = FindGetSlotValues;
|
||||
ntr->nextValue = FindNextValue;
|
||||
ntr->disposeCursor = FindDisposeCursor;
|
||||
ntr->possiblyAccessFile = FindPossible;
|
||||
ntr->destroy = NULL;
|
||||
ntr->url = copyString(url);
|
||||
gRDFFindDB = ntr;
|
||||
}
|
||||
}
|
||||
return(ntr);
|
||||
}
|
||||
52
mozilla/modules/rdf/src/find2rdf.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_FIND_H_
|
||||
#define _RDF_FIND_H_
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/* find.c data structures and defines */
|
||||
|
||||
typedef struct _findTokenStruct {
|
||||
char *token;
|
||||
char *value;
|
||||
} findTokenStruct;
|
||||
|
||||
|
||||
/* find.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
void parseResourceIntoFindTokens(RDF_Resource u, findTokenStruct *tokens);
|
||||
RDF_Cursor parseFindURL(RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor FindGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * findNextURL(RDF_Cursor c);
|
||||
void * FindNextValue(RDFT rdf, RDF_Cursor c);
|
||||
void * FindGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void FindPossible(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
RDF_Error FindDisposeCursor(RDFT mcf, RDF_Cursor c);
|
||||
void findPossiblyAddName(RDFT rdf, RDF_Resource u);
|
||||
PRBool FindAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
RDFT MakeFindStore (char* url);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
1143
mozilla/modules/rdf/src/fs2rdf.c
Normal file
84
mozilla/modules/rdf/src/fs2rdf.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_FS2RDF_H_
|
||||
#define _RDF_FS2RDF_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "xp_mem.h"
|
||||
#include "client.h"
|
||||
#include "prio.h"
|
||||
#include "prlong.h"
|
||||
#include "nlcstore.h"
|
||||
#include "remstore.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Appletalk.h>
|
||||
#include <Devices.h>
|
||||
#include <Files.h>
|
||||
#include <FinderRegistry.h>
|
||||
#include <Folders.h>
|
||||
#include <Processes.h>
|
||||
|
||||
#include "FullPath.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* fs2rdf.c data structures and defines */
|
||||
|
||||
extern int RDF_VOLUME_DESC_STR, RDF_DIRECTORY_DESC_STR, RDF_FILE_DESC_STR;
|
||||
|
||||
#define fsUnitp(u) (resourceType(u) == LFS_RT)
|
||||
|
||||
#define XP_DIRECTORY_SEPARATOR '/'
|
||||
|
||||
|
||||
|
||||
|
||||
/* fs2rdf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
#ifdef XP_MAC
|
||||
OSErr nativeMacPathname(char *fileURL, FSSpec *fss);
|
||||
OSErr getPSNbyTypeSig(ProcessSerialNumber *thePSN, OSType pType, OSType pSignature);
|
||||
#endif
|
||||
|
||||
void importForProfile (char *dir, const char *uname);
|
||||
void GuessIEBookmarks(void);
|
||||
char * getVolume(int16 volNum, PRBool afpVols);
|
||||
PRDir * OpenDir(char *name);
|
||||
RDFT MakeLFSStore (char* url);
|
||||
PRBool fsAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool fsRemoveFile(char *filePathname, PRBool justCheckWriteAccess);
|
||||
PRBool fsRemoveDir(char *filePathname, PRBool justCheckWriteAccess);
|
||||
PRBool fsUnassert (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool fsHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
void * fsGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
PRBool fileDirectoryp(RDF_Resource u);
|
||||
RDF_Cursor fsGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * fsNextValue (RDFT rdf, RDF_Cursor c);
|
||||
PRBool isFileVisible(char *fileURL);
|
||||
RDF_Error fsDisposeCursor (RDFT rdf, RDF_Cursor c);
|
||||
RDF_Resource CreateFSUnit (char* nname, PRBool isDirectoryFlag);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
469
mozilla/modules/rdf/src/glue.c
Normal file
@@ -0,0 +1,469 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the glue code that links the RDF module with
|
||||
* ugly navigator stuff including Netlib for getURL, preferences for
|
||||
* finding out where bookmarks.htm and lclstore.mcf are located. By
|
||||
* changing this glue file, one should be able to use the rest of the
|
||||
* RDF library with something else (like the server).
|
||||
|
||||
* For more information on this file, contact rjc or guha
|
||||
* For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "glue.h"
|
||||
#include "remstore.h"
|
||||
#include "rdfparse.h"
|
||||
#include "es2mcf.h"
|
||||
#include "mcff2mcf.h"
|
||||
#include "nlcstore.h"
|
||||
#include "autoupdt.h"
|
||||
#include "ht.h"
|
||||
#ifdef NU_CACHE
|
||||
#include "CacheStubs.h"
|
||||
#endif
|
||||
|
||||
/* external routines */
|
||||
extern MWContext *FE_GetRDFContext(void);
|
||||
extern char *gDefaultNavcntr;
|
||||
extern RDF gNCDB;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned int
|
||||
rdf_write_ready(NET_StreamClass *stream)
|
||||
{
|
||||
return MAX_WRITE_READY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
rdf_complete(NET_StreamClass *stream)
|
||||
{
|
||||
RDFFile f = (RDFFile)stream->data_object;
|
||||
if (RDF_STRCMP(f->url, gNavCntrUrl) == 0) {
|
||||
if (f->resourceCount == 0) {
|
||||
parseNextRDFXMLBlob(stream, gDefaultNavcntr, RDF_STRLEN(gDefaultNavcntr));
|
||||
} else {
|
||||
RDF_Resource browser = RDF_GetResource(NULL, "netscape:browser", 1);
|
||||
RDF_Resource updateFrom = RDF_GetResource(NULL, "updateURL", 1);
|
||||
char* uf = RDF_GetSlotValue(gNCDB, browser, updateFrom,
|
||||
RDF_STRING_TYPE, false, true);
|
||||
RDF_Resource fileSize = RDF_GetResource(NULL, "fileSize", 1);
|
||||
char* fs = RDF_GetSlotValue(gNCDB, browser, fileSize,
|
||||
RDF_STRING_TYPE, false, true);
|
||||
uint32 fSize;
|
||||
if (fs == NULL) {
|
||||
fSize = 3000;
|
||||
} else {
|
||||
sscanf("%lu", fs, &fSize);
|
||||
freeMem(fs);
|
||||
}
|
||||
if (uf != NULL) {
|
||||
#ifdef MOZ_SMARTUPDATE
|
||||
checkForAutoUpdate((void *)FE_GetRDFContext(), uf, fSize);
|
||||
#endif /* MOZ_SMARTUPDATE */
|
||||
freeMem(uf);
|
||||
}
|
||||
|
||||
/* A temporary hack to demo AutoUpdate on windows */
|
||||
#ifndef MOZ_SMARTUPDATE
|
||||
#ifdef XP_WIN
|
||||
checkForAutoUpdate((void *)FE_GetRDFContext(), "http://warp/u/raman/gromit/softupdt.exe", 45328);
|
||||
#endif /* XP_WIN */
|
||||
#endif /* MOZ_SMARTUPDATE */
|
||||
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
freeMem(f->line);
|
||||
freeMem(f->currentSlot);
|
||||
freeMem(f->holdOver);
|
||||
freeNamespaces(f) ;
|
||||
f->line = NULL;
|
||||
f->currentSlot = NULL;
|
||||
f->holdOver = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
rdf_abort(NET_StreamClass *stream, int status)
|
||||
{
|
||||
RDFFile f = (RDFFile)stream->data_object;
|
||||
if (RDF_STRCMP(f->url, gNavCntrUrl) == 0) {
|
||||
parseNextRDFXMLBlob(stream, gDefaultNavcntr, RDF_STRLEN(gDefaultNavcntr));
|
||||
}
|
||||
|
||||
if (f) {
|
||||
f->locked = false;
|
||||
gcRDFFile (f);
|
||||
freeMem(f->line);
|
||||
freeMem(f->currentSlot);
|
||||
freeMem(f->holdOver);
|
||||
freeNamespaces(f) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef MOZILLA_CLIENT
|
||||
|
||||
#ifdef XP_MAC
|
||||
PR_PUBLIC_API(NET_StreamClass *)
|
||||
#else
|
||||
PUBLIC NET_StreamClass *
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
parseNextRDFXMLBlob (NET_StreamClass *stream, char* blob, int32 size)
|
||||
{
|
||||
RDFFile f;
|
||||
|
||||
f = (RDFFile)stream->data_object;
|
||||
if ((f == NULL) || (size < 0)) {
|
||||
return MK_INTERRUPTED;
|
||||
}
|
||||
return parseNextRDFXMLBlobInt(f, blob, size);
|
||||
}
|
||||
|
||||
rdf_Converter(FO_Present_Types format_out, void *client_data,
|
||||
URL_Struct *urls, MWContext *cx)
|
||||
{
|
||||
RDFFile rdfFile;
|
||||
MKStreamWriteFunc writeFunc = NULL;
|
||||
|
||||
if ((urls == NULL) || (urls->fe_data == NULL))
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* determine appropriate write function to use */
|
||||
rdfFile = urls->fe_data;
|
||||
switch(rdfFile->fileType)
|
||||
{
|
||||
/* case ES_RT:
|
||||
case FTP_RT:
|
||||
writeFunc = (MKStreamWriteFunc)parseNextESFTPBlob;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
writeFunc = (MKStreamWriteFunc)parseNextRDFXMLBlob;
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate stream data block */
|
||||
return NET_NewStream("RDF", writeFunc,
|
||||
(MKStreamCompleteFunc)rdf_complete,
|
||||
(MKStreamAbortFunc)rdf_abort,
|
||||
(MKStreamWriteReadyFunc)rdf_write_ready,
|
||||
urls->fe_data, cx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
rdf_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx)
|
||||
{
|
||||
RDFFile f;
|
||||
char *navCenterURL = NULL;
|
||||
|
||||
if ((status < 0) && (urls != NULL))
|
||||
{
|
||||
if ((cx != NULL) && (urls->error_msg != NULL))
|
||||
{
|
||||
FE_Alert(cx, urls->error_msg);
|
||||
}
|
||||
|
||||
/* if unable to read in navcntr.rdf file, create some default views */
|
||||
if ((f = (RDFFile) urls->fe_data) != NULL)
|
||||
{
|
||||
if (RDF_STRCMP(f->url, gNavCntrUrl) == 0)
|
||||
{
|
||||
parseNextRDFXMLBlobInt(f, gDefaultNavcntr,
|
||||
RDF_STRLEN(gDefaultNavcntr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (urls != NULL)
|
||||
{
|
||||
if ((f = (RDFFile) urls->fe_data) != NULL)
|
||||
{
|
||||
htLoadComplete(f->url, status);
|
||||
}
|
||||
}
|
||||
|
||||
NET_FreeURLStruct (urls);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int
|
||||
rdfRetrievalType (RDFFile f)
|
||||
{
|
||||
URL_Struct *urls;
|
||||
char *url;
|
||||
int type;
|
||||
|
||||
url = f->url;
|
||||
if (f->localp)
|
||||
{
|
||||
urls = NET_CreateURLStruct(url, NET_CACHE_ONLY_RELOAD);
|
||||
if ((urls != NULL) && (NET_IsURLInDiskCache(urls) || NET_IsURLInMemCache(urls)))
|
||||
{
|
||||
type = NET_DONT_RELOAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = NET_NORMAL_RELOAD;
|
||||
}
|
||||
if (urls != NULL) NET_FreeURLStruct(urls);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = NET_NORMAL_RELOAD;
|
||||
}
|
||||
return(type);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
rdf_GetURL (MWContext *cx, int method, Net_GetUrlExitFunc *exit_routine, RDFFile rdfFile)
|
||||
{
|
||||
URL_Struct *urls = NULL;
|
||||
char* url ;
|
||||
#ifdef DEBUG_gagan
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (cx == NULL) return 0;
|
||||
if (rdfFile->refreshingp && rdfFile->updateURL) {
|
||||
url = rdfFile->updateURL;
|
||||
} else {
|
||||
url = rdfFile->url;
|
||||
}
|
||||
if (RDF_STRCMP(url, gNavCntrUrl) == 0) {
|
||||
urls = NET_CreateURLStruct(url, NET_CACHE_ONLY_RELOAD);
|
||||
#ifdef NU_CACHE
|
||||
if (!CacheManager_Contains(url)) {
|
||||
#else
|
||||
if (NET_IsURLInDiskCache(urls) || NET_IsURLInMemCache(urls)) {
|
||||
} else {
|
||||
#endif
|
||||
NET_FreeURLStruct(urls);
|
||||
urls = NULL;
|
||||
}
|
||||
}
|
||||
if (!urls)
|
||||
urls = NET_CreateURLStruct(url, (rdfFile->refreshingp ?
|
||||
NET_SUPER_RELOAD : NET_NORMAL_RELOAD));
|
||||
if (urls == NULL) return 0;
|
||||
urls->fe_data = rdfFile;
|
||||
if (method) urls->method = method;
|
||||
NET_GetURL(urls, FO_CACHE_AND_RDF, cx, rdf_GetUrlExitFunc);
|
||||
return 1;
|
||||
}
|
||||
#endif /* MOZILLA_CLIENT */
|
||||
|
||||
|
||||
|
||||
void
|
||||
possiblyRereadRDFFiles (void* data)
|
||||
{
|
||||
possiblyRefreshRDFFiles();
|
||||
/* timerID = FE_SetTimeout(possiblyRereadRDFFiles, NULL, 1000 * 60 * 10);
|
||||
once every 10 minutes
|
||||
diabled for legal reasons.*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RDFglueInitialize()
|
||||
{
|
||||
#ifdef MOZILLA_CLIENT
|
||||
|
||||
timerID = FE_SetTimeout(possiblyRereadRDFFiles, NULL, 1000 * 60 * 10); /* once every 10 minutes */
|
||||
if (gRLForbiddenDomains != NULL)
|
||||
{
|
||||
freeMem(gRLForbiddenDomains);
|
||||
gRLForbiddenDomains = NULL;
|
||||
}
|
||||
if (PREF_CopyCharPref("browser.relatedLinksDisabledForDomains", &gRLForbiddenDomains) != PREF_OK)
|
||||
{
|
||||
gRLForbiddenDomains = NULL;
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_CLIENT */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RDFglueExit (void)
|
||||
{
|
||||
#ifdef MOZILLA_CLIENT
|
||||
|
||||
if (timerID != NULL)
|
||||
{
|
||||
/* commented out as the timer's window has already been destroyed */
|
||||
|
||||
/* FE_ClearTimeout(timerID); */
|
||||
timerID = NULL;
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_CLIENT */
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
gRDFMWContext(RDFT db)
|
||||
{
|
||||
#ifndef MOZILLA_CLIENT
|
||||
return NULL;
|
||||
#else
|
||||
void *cx;
|
||||
RDFL rdf = NULL;
|
||||
|
||||
if (db) rdf = db->rdf;
|
||||
|
||||
while (rdf) {
|
||||
if (rdf->rdf->context) return (rdf->rdf->context);
|
||||
rdf = rdf->next;
|
||||
}
|
||||
|
||||
cx = (void *)FE_GetRDFContext();
|
||||
return(cx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* beginReadingRDFFile is called whenever we need to read something of
|
||||
* the net (or local drive). The url of the file to be read is at
|
||||
* file->url. As the bits are read in (and it can take the bits in
|
||||
* any sized chunks) it should call parseNextRDFBlob(file, nextBlock,
|
||||
* blobSize) when its done, it should call void finishRDFParse
|
||||
* (RDFFile f) to abort, it should call void abortRDFParse (RDFFile f)
|
||||
* [which will undo all that has been read from that file]
|
||||
*/
|
||||
|
||||
void
|
||||
beginReadingRDFFile (RDFFile file)
|
||||
{
|
||||
char *url;
|
||||
int method = 0;
|
||||
|
||||
#ifndef MOZILLA_CLIENT
|
||||
|
||||
/* If standalone, we just use to open the file */
|
||||
NET_StreamClass stream;
|
||||
PRFileDesc *fd;
|
||||
PRFileInfo fi;
|
||||
PRBool bSuccess = FALSE;
|
||||
|
||||
url = file->url;
|
||||
fd = CallPROpenUsingFileURL(url, PR_RDONLY, 0);
|
||||
if(fd)
|
||||
{
|
||||
if(PR_GetOpenFileInfo(fd, &fi) == PR_SUCCESS)
|
||||
{
|
||||
char* buf = malloc(fi.size);
|
||||
if(PR_Read(fd, buf, fi.size))
|
||||
{
|
||||
stream.data_object = file;
|
||||
if(parseNextRDFXMLBlob (&stream, buf, fi.size))
|
||||
bSuccess = TRUE;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
PR_Close(fd);
|
||||
}
|
||||
if(bSuccess == TRUE)
|
||||
rdf_complete(&stream);
|
||||
#else
|
||||
|
||||
/*
|
||||
XXX this is the pre-raptor world
|
||||
|
||||
url = file->url;
|
||||
if (file->fileType == ES_RT) method = URL_INDEX_METHOD;
|
||||
rdf_GetURL (gRDFMWContext(file->db), method, NULL, file);
|
||||
*/
|
||||
|
||||
rdfStreamListener* pListener = new rdfStreamListener;
|
||||
pListener->AddRef(); // XXX is this evil? Can't see any reason to use factories but...
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef MOZILLA_CLIENT
|
||||
DB *
|
||||
CallDBOpenUsingFileURL(char *fileURL, int flags,int mode, DBTYPE type, const void *openinfo)
|
||||
{
|
||||
DB *result;
|
||||
char *path;
|
||||
char *escapedPath;
|
||||
|
||||
if (fileURL == NULL) return NULL;
|
||||
|
||||
escapedPath = unescapeURL(fileURL);
|
||||
|
||||
#ifdef XP_MAC
|
||||
path = WH_FilePlatformName(convertFileURLToNSPRCopaceticPath(fileURL));
|
||||
PR_ASSERT(path != NULL);
|
||||
#else
|
||||
|
||||
path = convertFileURLToNSPRCopaceticPath(escapedPath);
|
||||
#endif
|
||||
result = dbopen(path, flags, mode, type, openinfo);
|
||||
#ifdef XP_MAC
|
||||
XP_FREE(path);
|
||||
#endif
|
||||
|
||||
if (escapedPath != NULL) freeMem(escapedPath);
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
#if defined(XP_WIN) && defined(DEBUG)
|
||||
/* Some XP functions that are implemented in winfe
|
||||
* in the client.
|
||||
*/
|
||||
void XP_AssertAtLine( char *pFileName, int iLine )
|
||||
{
|
||||
fprintf(stderr, "assert: line %d, file %s%c\n", __LINE__, pFileName, 7);
|
||||
}
|
||||
|
||||
char* NOT_NULL(const char* x)
|
||||
{
|
||||
return (char*)x;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
90
mozilla/modules/rdf/src/glue.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_GLUE_H_
|
||||
#define _RDF_GLUE_H_
|
||||
|
||||
|
||||
#include "xp.h"
|
||||
#include "xp_mem.h"
|
||||
#include "net.h"
|
||||
#include "ntypes.h"
|
||||
#include "fe_proto.h"
|
||||
|
||||
#include "prinit.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/fcntl.h>
|
||||
#elif defined(XP_MAC)
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "ht.h"
|
||||
|
||||
|
||||
|
||||
#define APPLICATION_RDF "application/x-rdf" /* XXX what should these be? */
|
||||
#define EXTENSION_RDF ".rdf"
|
||||
#define EXTENSION_MCF ".mcf"
|
||||
|
||||
|
||||
|
||||
/* external globals */
|
||||
extern char* gLocalStoreURL;
|
||||
extern char* gBookmarkURL;
|
||||
|
||||
|
||||
|
||||
/* glue.c prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
void ht_fprintf(PRFileDesc *file, const char *fmt, ...);
|
||||
|
||||
unsigned int rdf_write_ready(NET_StreamClass *stream);
|
||||
void rdf_complete(NET_StreamClass *stream);
|
||||
void rdf_abort(NET_StreamClass *stream, int status);
|
||||
NET_StreamClass * rdf_Converter(FO_Present_Types format_out,
|
||||
void *client_data, URL_Struct *urls, MWContext *cx);
|
||||
void rdf_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx);
|
||||
int rdfRetrievalType (RDFFile f);
|
||||
int rdf_GetURL (MWContext *cx, int method,
|
||||
Net_GetUrlExitFunc *exit_routine, RDFFile rdfFile);
|
||||
void possiblyRereadRDFFiles (void* data);
|
||||
void RDFglueInitialize (void);
|
||||
void RDFglueExit (void);
|
||||
void *gRDFMWContext(RDFT db);
|
||||
void beginReadingRDFFile (RDFFile file);
|
||||
void readLocalFile (RDFFile file);
|
||||
|
||||
char *unescapeURL(char *inURL);
|
||||
char *convertFileURLToNSPRCopaceticPath(char* inURL);
|
||||
PRFileDesc *CallPROpenUsingFileURL(char *fileURL, PRIntn flags, PRIntn mode);
|
||||
PRDir *CallPROpenDirUsingFileURL(char *fileURL);
|
||||
int32 CallPRWriteAccessFileUsingFileURL(char *fileURL);
|
||||
int32 CallPRDeleteFileUsingFileURL(char *fileURL);
|
||||
int CallPR_RmDirUsingFileURL(char *dirURL);
|
||||
int32 CallPRMkDirUsingFileURL(char *dirURL, int mode);
|
||||
DB *CallDBOpenUsingFileURL(char *fileURL, int flags,int mode,
|
||||
DBTYPE type, const void *openinfo);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
675
mozilla/modules/rdf/src/hist2rdf.c
Normal file
@@ -0,0 +1,675 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements History support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "hist2rdf.h"
|
||||
#include "remstore.h"
|
||||
#include "utils.h"
|
||||
|
||||
static PRBool histInFlatFilep = 0;
|
||||
|
||||
/* extern declarations */
|
||||
void GH_DeleteHistoryItem (char * url);
|
||||
PR_PUBLIC_API(void) updateNewHistItem (DBT *key, DBT *data); /* XXX this should be elsewhere */
|
||||
|
||||
|
||||
/* externs */
|
||||
extern char *profileDirURL;
|
||||
extern char *gGlobalHistoryURL;
|
||||
|
||||
|
||||
/* external string references in allxpstr */
|
||||
extern int RDF_WEEKOF, RDF_WITHINLASTHOUR, RDF_TODAY, RDF_DAY_0;
|
||||
extern int RDF_RELATEDLINKSNAME;
|
||||
|
||||
|
||||
/* globals */
|
||||
PLHashTable *hostHash = 0;
|
||||
RDFT grdf = NULL;
|
||||
RDFT gHistoryStore = 0;
|
||||
PRBool ByDateOpened = 0;
|
||||
PRBool historyInitialized = 0;
|
||||
static int saveCount = 0;
|
||||
|
||||
|
||||
char *prefixList[] = {
|
||||
"about:", "javascript:", "livescript:", "mailbox:", "mailto:",
|
||||
"mocha:", "news:", "pop3", "snews:", "view-source", "wysiwyg:", NULL
|
||||
};
|
||||
|
||||
char *suffixList[] = {
|
||||
".gif", ".jpg", ".jpeg", ".xbm", ".pfr", ".class", ".tmp", ".js", ".rdf",
|
||||
".mcf", ".mco", NULL
|
||||
};
|
||||
|
||||
char *intermediateList[] = {
|
||||
".gif", ".GIF", NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
void
|
||||
collateHistory (RDFT r, RDF_Resource u, PRBool byDateFlag)
|
||||
{
|
||||
HASHINFO hash = { 4*1024, 0, 0, 0, 0, 0};
|
||||
DBT key, data;
|
||||
time_t last,first;
|
||||
uint32 numaccess;
|
||||
PRBool firstOne = 0;
|
||||
DB* db = CallDBOpenUsingFileURL(gGlobalHistoryURL, O_RDONLY ,0600,
|
||||
DB_HASH, &hash);
|
||||
grdf = r;
|
||||
if (db != NULL) {
|
||||
while (0 == (*db->seq)(db, &key, &data, (firstOne ? R_NEXT : R_FIRST))) {
|
||||
char* title = ((char*)data.data + 16); /* title */
|
||||
char* url = (char*)key.data; /* url */
|
||||
/* int32 flag = (int32)*((char*)data.data + 3*sizeof(int32)); */
|
||||
int32 flag;
|
||||
HIST_COPY_INT32(&flag, (int8 *)data.data + 3 * sizeof(int32));
|
||||
firstOne = 1;
|
||||
#ifdef XP_UNIX
|
||||
if ((/*1 == flag &&*/ displayHistoryItem((char*)key.data))) {
|
||||
#else
|
||||
if (1 == flag && displayHistoryItem((char*)key.data)) {
|
||||
#endif
|
||||
HIST_COPY_INT32(&last, (time_t *)((int8 *)data.data));
|
||||
HIST_COPY_INT32(&first, (time_t *)((int8 *)data.data + sizeof(int32)));
|
||||
HIST_COPY_INT32(&numaccess, (time_t *)((int8 *)data.data + 2*sizeof(int32)));
|
||||
|
||||
collateOneHist(r, u,url,title, last, first, numaccess, byDateFlag);
|
||||
}
|
||||
}
|
||||
(*db->close)(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
collateOneHist (RDFT r, RDF_Resource u, char* url, char* title, time_t lastAccessDate,
|
||||
time_t firstAccessDate, uint32 numAccesses, PRBool byDateFlag)
|
||||
{
|
||||
char buffer[128];
|
||||
struct tm *time;
|
||||
RDF_Resource hostUnit, urlUnit;
|
||||
char* existingName = NULL;
|
||||
uint32 oldNumAccess = 0;
|
||||
if (startsWith("404", title)) return;
|
||||
urlUnit = HistCreate(url, 1);
|
||||
existingName = remoteStoreGetSlotValue(gLocalStore, urlUnit, gCoreVocab->RDF_name, RDF_STRING_TYPE, 0, 1);
|
||||
|
||||
PR_ASSERT( IsUTF8String((const char* )existingName));
|
||||
|
||||
if (existingName == NULL) {
|
||||
if (title[0] != '\0') remoteAddName(urlUnit, title);
|
||||
} else freeMem(existingName);
|
||||
if (byDateFlag) {
|
||||
hostUnit = hostUnitOfDate(r, u, lastAccessDate);
|
||||
} else {
|
||||
hostUnit = hostUnitOfURL(r, u, urlUnit, title);
|
||||
}
|
||||
|
||||
if (hostUnit == NULL) return;
|
||||
|
||||
|
||||
if (hostUnit != urlUnit) remoteAddParent(urlUnit, hostUnit);
|
||||
|
||||
if ((time = localtime((time_t *) &lastAccessDate)) != NULL)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
time->tm_year += 4;
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#elif XP_UNIX
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#else
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
|
||||
#endif
|
||||
PR_ASSERT( IsUTF8String((const char* )buffer));
|
||||
remoteStoreAdd(gRemoteStore, urlUnit, gWebData->RDF_lastVisitDate,
|
||||
(void *)copyString(buffer), RDF_STRING_TYPE, 1);
|
||||
}
|
||||
if ((time = localtime((time_t *) &firstAccessDate)) != NULL)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
time->tm_year += 4;
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#elif XP_UNIX
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
|
||||
#else
|
||||
strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
|
||||
#endif
|
||||
PR_ASSERT( IsUTF8String((const char* )buffer));
|
||||
remoteStoreAdd(gRemoteStore, urlUnit, gWebData->RDF_firstVisitDate,
|
||||
(void *)copyString(buffer), RDF_STRING_TYPE, 1);
|
||||
}
|
||||
/* oldNumAccess = remoteStoreGetSlotValue(gHistoryStore, urlUnit, gWebData->RDF_numAccesses,
|
||||
RDF_INT_TYPE, 0, 1);
|
||||
if (oldNumAccess) remoteStoreRemove(gHistoryStore, urlUnit, gWebData->RDF_numAccesses, oldNumAccess,
|
||||
RDF_INT_TYPE);
|
||||
if (numAccesses==0) ++numAccesses;
|
||||
remoteStoreAdd(gHistoryStore, urlUnit, gWebData->RDF_numAccesses,
|
||||
(void *)numAccesses, RDF_INT_TYPE, 1); */
|
||||
if (numAccesses > 5) histAddParent(urlUnit, gNavCenter->RDF_HistoryMostVisited);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
hostUnitOfURL (RDFT r, RDF_Resource top, RDF_Resource nu, char* title)
|
||||
{
|
||||
char host[100];
|
||||
char* url = resourceID(nu);
|
||||
int16 s1, s2, s3;
|
||||
RDF_Resource hostResource, existing;
|
||||
if (RDF_STRLEN(url) > 100) return NULL;
|
||||
if (startsWith("file", url)) {
|
||||
return RDF_GetResource(NULL, "Local Files", 1);
|
||||
} else {
|
||||
memset(host, '\0', 100);
|
||||
s1 = charSearch(':', url)+3;
|
||||
s2 = charSearch('/', &url[s1]);
|
||||
s3 = charSearch(':', &url[s1]);
|
||||
if (s2 == -1) s2 = RDF_STRLEN(url)-s1;
|
||||
if ((s3 != -1) && (s2 > s3)) s2 = s3;
|
||||
if (startsWith("www", &url[s1])) {s1 = s1+4; s2 = s2-4;}
|
||||
if (s2<1) return(NULL);
|
||||
memcpy((char*)host, &url[s1], s2);
|
||||
host[0] = toupper(host[0]);
|
||||
hostResource = RDF_GetResource(NULL, host, 1);
|
||||
setContainerp(hostResource, 1);
|
||||
setResourceType(hostResource, HISTORY_RT);
|
||||
existing = PL_HashTableLookup(hostHash, hostResource);
|
||||
if (existing != NULL) {
|
||||
if (existing == nu) {
|
||||
return existing;
|
||||
} else if (existing == top) {
|
||||
return hostResource;
|
||||
} else {
|
||||
remoteStoreRemove(gHistoryStore, existing, gCoreVocab->RDF_parent, top, RDF_RESOURCE_TYPE);
|
||||
histAddParent(existing, hostResource);
|
||||
histAddParent(hostResource, top);
|
||||
PL_HashTableAdd(hostHash, hostResource, top);
|
||||
return hostResource;
|
||||
}
|
||||
} else {
|
||||
PL_HashTableAdd(hostHash, hostResource, nu);
|
||||
histAddParent(nu, top);
|
||||
return nu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
hourRange(char *buffer, struct tm *theTm)
|
||||
{
|
||||
char *startHourStr="AM",*endHourStr="AM";
|
||||
|
||||
if (theTm->tm_hour > 0 && theTm->tm_hour < 12) {
|
||||
sprintf(buffer, "AM");
|
||||
} else {
|
||||
sprintf(buffer, "PM");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
hostUnitOfDate (RDFT r, RDF_Resource u, time_t lastAccessDate)
|
||||
{
|
||||
RDF_Resource node = NULL, parentNode;
|
||||
/*
|
||||
RDF_Resources std;
|
||||
*/
|
||||
time_t now, tempTime;
|
||||
struct tm *T,nowStruct, dateStruct;
|
||||
char hourBuffer[128], dayBuffer[128], weekBuffer[128];
|
||||
char bigBuffer[1024];
|
||||
int numDays;
|
||||
|
||||
/* NOTE: localtime uses a single static buffer, so MUST copy contents out */
|
||||
|
||||
time((time_t *)&now);
|
||||
if ((T = localtime(&now)) == NULL) return(NULL);
|
||||
nowStruct = *T;
|
||||
|
||||
if ((T = localtime(&lastAccessDate)) == NULL) return(NULL);
|
||||
dateStruct = *T;
|
||||
|
||||
bigBuffer[0] = hourBuffer[0] = dayBuffer[0] = weekBuffer[0] = 0;
|
||||
|
||||
if (now < (lastAccessDate + SECS_IN_HOUR)) /* within the last hour */
|
||||
{
|
||||
strcpy(hourBuffer, XP_GetString(RDF_WITHINLASTHOUR));
|
||||
}
|
||||
else if ((nowStruct.tm_year == dateStruct.tm_year) && /* some time today */
|
||||
(nowStruct.tm_yday == dateStruct.tm_yday))
|
||||
{
|
||||
strcpy(dayBuffer, XP_GetString(RDF_TODAY));
|
||||
hourRange(hourBuffer, &dateStruct);
|
||||
}
|
||||
else /* check if within last week */
|
||||
{
|
||||
numDays = 7;
|
||||
do
|
||||
{
|
||||
now -= SECS_IN_DAY;
|
||||
if ((T = localtime(&now)) == NULL) return(NULL);
|
||||
nowStruct = *T;
|
||||
if ((nowStruct.tm_year == dateStruct.tm_year) &&
|
||||
(nowStruct.tm_yday == dateStruct.tm_yday))
|
||||
{
|
||||
sprintf(dayBuffer, "%d/%d - %s",
|
||||
(uint) dateStruct.tm_mon + 1, (uint)dateStruct.tm_mday,
|
||||
XP_GetString(RDF_DAY_0 + nowStruct.tm_wday));
|
||||
hourRange(hourBuffer, &dateStruct);
|
||||
break;
|
||||
}
|
||||
} while (numDays-- > 0);
|
||||
|
||||
if (dayBuffer[0] == '\0') /* older than a week */
|
||||
{
|
||||
tempTime = lastAccessDate;
|
||||
numDays = dateStruct.tm_wday;
|
||||
while (numDays-- > 0)
|
||||
{
|
||||
tempTime -= SECS_IN_DAY;
|
||||
}
|
||||
if ((T = localtime(&tempTime)) == NULL) return(NULL);
|
||||
dateStruct = *T;
|
||||
#ifdef XP_MAC
|
||||
/* Mac epoch according to localtime is 1904 */
|
||||
PR_snprintf(weekBuffer, sizeof(weekBuffer)-1, XP_GetString(RDF_WEEKOF), (uint)dateStruct.tm_mon + 1,
|
||||
(int)dateStruct.tm_mday, (uint)dateStruct.tm_year + 1904);
|
||||
#else
|
||||
PR_snprintf(weekBuffer, sizeof(weekBuffer)-1, XP_GetString(RDF_WEEKOF), (uint)dateStruct.tm_mon + 1,
|
||||
(int)dateStruct.tm_mday, (uint)dateStruct.tm_year + 1900);
|
||||
#endif
|
||||
|
||||
if ((T = localtime(&lastAccessDate)) == NULL) return(NULL);
|
||||
dateStruct = *T;
|
||||
|
||||
#ifdef XP_MAC
|
||||
/* Mac epoch according to localtime is 1904 */
|
||||
sprintf(dayBuffer, "%s - %d/%d/%d",
|
||||
XP_GetString(RDF_DAY_0 + dateStruct.tm_wday), (uint) dateStruct.tm_mon + 1,
|
||||
(uint)dateStruct.tm_mday, (uint)dateStruct.tm_year + 1904);
|
||||
#else
|
||||
sprintf(dayBuffer, "%s - %d/%d/%d",
|
||||
XP_GetString(RDF_DAY_0 + dateStruct.tm_wday), (uint) dateStruct.tm_mon + 1,
|
||||
(uint)dateStruct.tm_mday, (uint)dateStruct.tm_year + 1900);
|
||||
#endif
|
||||
hourRange(hourBuffer, &dateStruct);
|
||||
}
|
||||
}
|
||||
parentNode = u;
|
||||
|
||||
if (weekBuffer[0] != '\0')
|
||||
{
|
||||
if ((node = RDF_GetResource(NULL, weekBuffer, false)) == NULL)
|
||||
{
|
||||
if ((node = RDF_GetResource(NULL, weekBuffer, true)) == NULL) return(NULL);
|
||||
}
|
||||
setContainerp(node, 1);
|
||||
setResourceType(node, HISTORY_RT);
|
||||
remoteStoreAdd(gHistoryStore, node, gCoreVocab->RDF_parent,
|
||||
parentNode, RDF_RESOURCE_TYPE, 1);
|
||||
PR_ASSERT( IsUTF8String((const char* )weekBuffer));
|
||||
remoteStoreAdd(gHistoryStore, node, gCoreVocab->RDF_name,
|
||||
copyString(weekBuffer), RDF_STRING_TYPE, 1);
|
||||
parentNode = node;
|
||||
}
|
||||
if (dayBuffer[0] != '\0')
|
||||
{
|
||||
sprintf(bigBuffer, "%d/%d", (uint) dateStruct.tm_mon + 1,
|
||||
(uint)dateStruct.tm_mday);
|
||||
|
||||
|
||||
if ((node = RDF_GetResource(NULL, bigBuffer, false)) == NULL)
|
||||
{
|
||||
if ((node = RDF_GetResource(NULL, bigBuffer, true)) == NULL) return(NULL);
|
||||
}
|
||||
setContainerp(node, 1);
|
||||
setResourceType(node, HISTORY_RT);
|
||||
histAddParent(node, parentNode);
|
||||
sprintf(bigBuffer,"%s - %s",weekBuffer,dayBuffer);
|
||||
PR_ASSERT( IsUTF8String((const char* )dayBuffer));
|
||||
remoteStoreAdd(gHistoryStore, node, gCoreVocab->RDF_name,
|
||||
copyString(dayBuffer), RDF_STRING_TYPE, 1);
|
||||
parentNode = node;
|
||||
}
|
||||
if (hourBuffer[0] == 'W')
|
||||
{
|
||||
sprintf(bigBuffer, "%s", hourBuffer);
|
||||
|
||||
if ((node = RDF_GetResource(NULL, bigBuffer, false)) == NULL)
|
||||
{
|
||||
if ((node = RDF_GetResource(NULL, bigBuffer, true)) == NULL) return(NULL);
|
||||
}
|
||||
setContainerp(node, 1);
|
||||
setResourceType(node, HISTORY_RT);
|
||||
remoteStoreAdd(gHistoryStore, node, gCoreVocab->RDF_parent,
|
||||
parentNode, RDF_RESOURCE_TYPE, 1);
|
||||
PR_ASSERT( IsUTF8String((const char* )hourBuffer));
|
||||
remoteStoreAdd(gHistoryStore, node, gCoreVocab->RDF_name,
|
||||
copyString(hourBuffer), RDF_STRING_TYPE, 1);
|
||||
parentNode = node;
|
||||
}
|
||||
return (node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
saveHistory ()
|
||||
{
|
||||
char* escapedPath = unescapeURL(gGlobalHistoryURL);
|
||||
char* path = WH_FilePlatformName(convertFileURLToNSPRCopaceticPath(escapedPath));
|
||||
PRFileDesc* file = PR_Open(path, PR_WRONLY | PR_CREATE_FILE, 00200);
|
||||
char* hist;
|
||||
if (file != NULL) {
|
||||
hist = RDF_SerializeRDFStore(gHistoryStore) ;
|
||||
if (hist != NULL) {
|
||||
PR_Write(file, hist, RDF_STRLEN(hist));
|
||||
}
|
||||
}
|
||||
freeMem(path);
|
||||
freeMem(escapedPath);
|
||||
PR_Close(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PR_PUBLIC_API(void)
|
||||
updateNewHistItem (DBT *key, DBT *data)
|
||||
{
|
||||
time_t last,first,numaccess;
|
||||
int32 flg = (int32)*((char*)data->data + 3*sizeof(int32));
|
||||
if (!displayHistoryItem((char*)key->data)) return;
|
||||
if (historyInitialized && (gHistoryStore != NULL)) {
|
||||
HIST_COPY_INT32(&last, (time_t *)((char *)data->data));
|
||||
HIST_COPY_INT32(&first, (time_t *)((char *)data->data + sizeof(int32)));
|
||||
HIST_COPY_INT32(&numaccess, (time_t *)((char *)data->data + 2*sizeof(int32)));
|
||||
|
||||
if (hostHash) collateOneHist(grdf, gNavCenter->RDF_HistoryBySite,
|
||||
(char*)key->data, /* url */
|
||||
((char*)data->data + 4*sizeof(int32)), /* title */
|
||||
last, first, numaccess, 0);
|
||||
if (ByDateOpened) collateOneHist(grdf, gNavCenter->RDF_HistoryByDate,
|
||||
(char*)key->data, /* url */
|
||||
((char*)data->data + 4*sizeof(int32)), /* title */
|
||||
last, first, numaccess, 1);
|
||||
saveCount++;
|
||||
if (saveCount > 5) {
|
||||
if (histInFlatFilep) saveHistory();
|
||||
saveCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** History clustering utils **/
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
displayHistoryItem (char* url)
|
||||
{
|
||||
int x;
|
||||
x=0;
|
||||
while (prefixList[x]) {
|
||||
if (startsWith(prefixList[x++], url)) return 0;
|
||||
}
|
||||
x=0;
|
||||
while (suffixList[x]) {
|
||||
if (endsWith(suffixList[x++], url)) return 0;
|
||||
}
|
||||
x=0;
|
||||
while (intermediateList[x]) {
|
||||
if (strstr(url, intermediateList[x++])) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
HistCreate (char* url, PRBool createp)
|
||||
{
|
||||
size_t size = RDF_STRLEN(url);
|
||||
char* nurl = getMem(size+8);
|
||||
RDF_Resource ans;
|
||||
if (charSearch(':', url) == -1) {
|
||||
if (url[size-1] == '/') {
|
||||
sprintf(nurl, "http://%s", url);
|
||||
nurl[RDF_STRLEN(nurl)-1] = '\0';
|
||||
} else {
|
||||
sprintf(nurl, "http://%s/", url);
|
||||
}
|
||||
} else {
|
||||
if (url[size-1] == '/') {
|
||||
memcpy(nurl, url, size-1);
|
||||
} else {
|
||||
sprintf(nurl, "%s/", url);
|
||||
}
|
||||
}
|
||||
ans = RDF_GetResource(NULL, nurl, 0);
|
||||
if (ans != NULL) {
|
||||
freeMem(nurl);
|
||||
return ans;
|
||||
}
|
||||
freeMem(nurl);
|
||||
ans = RDF_GetResource(NULL, url, createp);
|
||||
|
||||
if (ans != NULL) {
|
||||
return ans;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool bySite = 0;
|
||||
|
||||
Assertion
|
||||
histAddParent (RDF_Resource child, RDF_Resource parent)
|
||||
{
|
||||
Assertion nextAs, prevAs, newAs;
|
||||
RDF_Resource s = gCoreVocab->RDF_parent;
|
||||
RDF_ValueType type = RDF_RESOURCE_TYPE;
|
||||
nextAs = prevAs = child->rarg1;
|
||||
while (nextAs != null) {
|
||||
if (asEqual(gHistoryStore, nextAs, child, s, parent, type)) return null;
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
newAs = makeNewAssertion(gHistoryStore, child, s, parent, type, 1);
|
||||
if (prevAs == null) {
|
||||
child->rarg1 = newAs;
|
||||
} else {
|
||||
prevAs->next = newAs;
|
||||
}
|
||||
nextAs = prevAs = parent->rarg2;
|
||||
if (nextAs == NULL) {
|
||||
parent->rarg2 = newAs;
|
||||
} else {
|
||||
PRBool added = 0;
|
||||
if (bySite) {
|
||||
while (nextAs && !isSeparator(nextAs->u)) {
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
}
|
||||
if (nextAs) {
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
}
|
||||
}
|
||||
while (nextAs != null) {
|
||||
char* nid = resourceID(nextAs->u);
|
||||
if (RDF_STRCMP(resourceID(child), resourceID(nextAs->u)) > 0) {
|
||||
if (prevAs == nextAs) {
|
||||
newAs->invNext = prevAs;
|
||||
parent->rarg2 = newAs;
|
||||
added = 1;
|
||||
break;
|
||||
} else {
|
||||
newAs->invNext = nextAs;
|
||||
prevAs->invNext = newAs;
|
||||
added = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
}
|
||||
if (!added) prevAs->invNext = newAs;
|
||||
}
|
||||
sendNotifications2(gHistoryStore, RDF_ASSERT_NOTIFY, child, s, parent, type, 1);
|
||||
/* XXX have to mark the entire subtree XXX */
|
||||
/* sendNotifications(gHistoryStore->rdf, RDF_ASSERT_NOTIFY, child, s, parent, type, 1); */
|
||||
return(newAs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
historyUnassert (RDFT hst, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type)
|
||||
{
|
||||
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if ((type == RDF_RESOURCE_TYPE) && (resourceType((RDF_Resource)v) == HISTORY_RT) &&
|
||||
(s == gCoreVocab->RDF_parent)) {
|
||||
RDF_Resource parents[5];
|
||||
int8 n = 0;
|
||||
Assertion as = u->rarg1;
|
||||
memset(parents, '\0', 5 * sizeof(RDF_Resource));
|
||||
while (as) {
|
||||
if ((as->type == RDF_RESOURCE_TYPE) && (as->s == gCoreVocab->RDF_parent) &&
|
||||
(resourceType((RDF_Resource)as->value) == HISTORY_RT) && (n < 5)) {
|
||||
parents[n++] = (RDF_Resource)as->value;
|
||||
}
|
||||
as = as->next;
|
||||
}
|
||||
if (containerp(u)) {
|
||||
Assertion as = u->rarg2;
|
||||
while (as) {
|
||||
if ((as->db == gHistoryStore) && (as->s == gCoreVocab->RDF_parent)) {
|
||||
GH_DeleteHistoryItem (resourceID(as->u));
|
||||
}
|
||||
as = as->invNext;
|
||||
}
|
||||
} else {
|
||||
GH_DeleteHistoryItem (resourceID(u));
|
||||
}
|
||||
|
||||
while (n > 0) {
|
||||
n = n - 1;
|
||||
if (parents[n]) {
|
||||
Assertion nas = remoteStoreRemove (gHistoryStore, u, gCoreVocab->RDF_parent,
|
||||
parents[n], RDF_RESOURCE_TYPE);
|
||||
freeMem(nas);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
HistPossiblyAccessFile (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
if ((s == gCoreVocab->RDF_parent) && inversep && (rdf == gHistoryStore) &&
|
||||
((u == gNavCenter->RDF_HistoryByDate) || (u == gNavCenter->RDF_HistoryBySite))) {
|
||||
if (histInFlatFilep) {
|
||||
readRDFFile(gGlobalHistoryURL, NULL, 0, gHistoryStore);
|
||||
historyInitialized = 1;
|
||||
} else {
|
||||
collateHistory(rdf, u, (u == gNavCenter->RDF_HistoryByDate));
|
||||
historyInitialized = 1;
|
||||
}
|
||||
} else if ((s == gCoreVocab->RDF_parent) && inversep && (rdf == gHistoryStore) &&
|
||||
(u == gNavCenter->RDF_HistoryMostVisited)) {
|
||||
collateHistory(rdf, gNavCenter->RDF_HistoryBySite, 0);
|
||||
historyInitialized = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RDFT
|
||||
MakeHistoryStore (char* url)
|
||||
{
|
||||
if (startsWith("rdf:history", url)) {
|
||||
if (gHistoryStore == 0) {
|
||||
RDFT ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct));
|
||||
RDF_Resource sep = createSeparator();
|
||||
ntr->assert = NULL;
|
||||
ntr->unassert = historyUnassert;
|
||||
ntr->getSlotValue = remoteStoreGetSlotValue;
|
||||
ntr->getSlotValues = remoteStoreGetSlotValues;
|
||||
ntr->hasAssertion = remoteStoreHasAssertion;
|
||||
ntr->nextValue = remoteStoreNextValue;
|
||||
ntr->disposeCursor = remoteStoreDisposeCursor;
|
||||
ntr->possiblyAccessFile = HistPossiblyAccessFile;
|
||||
gHistoryStore = ntr;
|
||||
histInFlatFilep = endsWith(".rdf", gGlobalHistoryURL);
|
||||
ntr->url = copyString(url);
|
||||
hostHash = PL_NewHashTable(500, idenHash, PL_CompareValues, PL_CompareValues, null, null);
|
||||
ByDateOpened = 1;
|
||||
return ntr;
|
||||
} else return gHistoryStore;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void
|
||||
dumpHist ()
|
||||
{
|
||||
FILE *fp = fopen("history.txt", "w");
|
||||
HASHINFO hash = { 4*1024, 0, 0, 0, 0, 0};
|
||||
DBT key, data;
|
||||
PRBool firstOne = 0;
|
||||
DB* db = CallDBOpenUsingFileURL(gGlobalHistoryURL, O_RDONLY ,0600,
|
||||
DB_HASH, &hash);
|
||||
|
||||
if (db != NULL) {
|
||||
while (0 == (*db->seq)(db, &key, &data, (firstOne ? R_NEXT : R_FIRST))) {
|
||||
firstOne = 1;
|
||||
if ((1 == (int32)*((char*)data.data + 3*sizeof(uint32)) &&
|
||||
displayHistoryItem((char*)key.data))) {
|
||||
fprintf(fp, "%s\n", (char*)key.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
(*db->close)(db);
|
||||
}
|
||||
|
||||
*/
|
||||
84
mozilla/modules/rdf/src/hist2rdf.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_HIST2RDF_H_
|
||||
#define _RDF_HIST2RDF_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prtypes.h" /* for IS_LITTLE_ENDIAN / IS_BIG_ENDIAN */
|
||||
|
||||
|
||||
|
||||
#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN)
|
||||
#error Must have a byte order
|
||||
#endif
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define HIST_COPY_INT32(_a,_b) XP_MEMCPY(_a, _b, sizeof(int32));
|
||||
#else
|
||||
#define HIST_COPY_INT32(_a,_b) \
|
||||
do { \
|
||||
((char *)(_a))[0] = ((char *)(_b))[3]; \
|
||||
((char *)(_a))[1] = ((char *)(_b))[2]; \
|
||||
((char *)(_a))[2] = ((char *)(_b))[1]; \
|
||||
((char *)(_a))[3] = ((char *)(_b))[0]; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* hist2rdf.c data structures and defines */
|
||||
|
||||
#define remoteAddParent(child, parent) histAddParent(child, parent);
|
||||
#define remoteAddName(u, name) remoteStoreAdd(gRemoteStore, u, gCoreVocab->RDF_name, copyString(name), RDF_STRING_TYPE, 1);
|
||||
|
||||
#define SECS_IN_HOUR (60L * 60L)
|
||||
#define SECS_IN_DAY (SECS_IN_HOUR * 24L)
|
||||
|
||||
extern int RDF_HTML_WINDATE, RDF_HTML_MACDATE;
|
||||
|
||||
|
||||
/* hist2rdf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
void collateHistory (RDFT r, RDF_Resource u, PRBool byDateFlag);
|
||||
void collateOneHist (RDFT r, RDF_Resource u, char* url, char* title, time_t lastAccessDate, time_t firstAccessDate, uint32 numAccesses, PRBool byDateFlag);
|
||||
RDF_Resource hostUnitOfURL (RDFT r, RDF_Resource top, RDF_Resource nu, char* title);
|
||||
void hourRange(char *buffer, struct tm *theTm);
|
||||
RDF_Resource hostUnitOfDate (RDFT r, RDF_Resource u, time_t lastAccessDate);
|
||||
void saveHistory();
|
||||
void deleteCurrentSitemaps (char *address);
|
||||
void addRelatedLinks (char* address);
|
||||
PRBool displayHistoryItem (char* url);
|
||||
RDF_Resource HistCreate (char* url, PRBool createp);
|
||||
Assertion histAddParent (RDF_Resource child, RDF_Resource parent);
|
||||
PRBool historyUnassert (RDFT hst, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
void HistPossiblyAccessFile (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
RDF_Cursor historyStoreGetSlotValuesInt (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
PRBool historyStoreHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
RDFT MakeHistoryStore (char* url);
|
||||
void dumpHist ();
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
10391
mozilla/modules/rdf/src/ht.c
Normal file
398
mozilla/modules/rdf/src/ht.h
Normal file
@@ -0,0 +1,398 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_HT_H_
|
||||
#define _RDF_HT_H_
|
||||
|
||||
|
||||
#ifndef HT_RAPTOR
|
||||
#include "xpassert.h"
|
||||
#include "xp_qsort.h"
|
||||
#include "xp_time.h"
|
||||
#include "client.h"
|
||||
#include "net.h"
|
||||
#include "xpgetstr.h"
|
||||
#include "xp_str.h"
|
||||
#include "htmldlgs.h"
|
||||
#include "xp_ncent.h"
|
||||
#include "xpassert.h"
|
||||
#include "nspr.h"
|
||||
#include "prefapi.h"
|
||||
#include "fe_proto.h"
|
||||
#include "intl_csi.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "stdlib.h"
|
||||
#include <Aliases.h>
|
||||
#endif
|
||||
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "math.h"
|
||||
#include "htrdf.h"
|
||||
|
||||
#ifdef SMART_MAIL
|
||||
#include "pm2rdf.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "prprf.h"
|
||||
#include "plhash.h"
|
||||
#include "xp_core.h"
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "mcf.h"
|
||||
#include "htrdf.h"
|
||||
#include "vocab.h"
|
||||
|
||||
#ifndef XP_ASSERT
|
||||
#define XP_ASSERT(x)
|
||||
#endif
|
||||
|
||||
#ifndef XP_FREE
|
||||
#define XP_FREE(x) PR_Free((x))
|
||||
#endif
|
||||
|
||||
#ifndef XP_STRCASECMP
|
||||
#define XP_STRCASECMP(x,y) strcmp((x),(y))
|
||||
#endif
|
||||
|
||||
#define MWContext void
|
||||
#endif
|
||||
|
||||
|
||||
/* HT data structures and defines */
|
||||
|
||||
#define ITEM_LIST_SIZE 500 /* XXX ITEM_LIST_SIZE should be dynamic */
|
||||
#define ITEM_LIST_ELEMENT_SIZE 20
|
||||
|
||||
#define NUM_MENU_CMDS 40
|
||||
|
||||
#define RDF_SITEMAP 1
|
||||
#define RDF_RELATED_LINKS 2
|
||||
#define FROM_PAGE 1
|
||||
#define GUESS_FROM_PREVIOUS_PAGE 2
|
||||
|
||||
#define HTDEL remoteStoreRemove
|
||||
|
||||
#ifndef HT_RAPTOR
|
||||
/* external string references in allxpstr */
|
||||
extern int RDF_HTML_STR, RDF_HTML_STR_1, RDF_HTML_STR_2, RDF_HTML_STR_3;
|
||||
extern int RDF_HTML_STR_4, RDF_HTML_STR_5, RDF_HTML_STR_NUMBER;
|
||||
extern int RDF_HTML_WINDATE, RDF_HTML_MACDATE, RDF_CMD_0, RDF_DATA_1, RDF_DATA_2;
|
||||
extern int RDF_DELETEFILE, RDF_UNABLETODELETEFILE, RDF_DELETEFOLDER;
|
||||
extern int RDF_UNABLETODELETEFOLDER, RDF_SITEMAPNAME;
|
||||
extern int RDF_RELATEDLINKSNAME, RDF_DEFAULTCOLUMNNAME;
|
||||
extern int RDF_NEWWORKSPACEPROMPT, RDF_DELETEWORKSPACE;
|
||||
extern int RDF_ADDITIONS_ALLOWED, RDF_DELETION_ALLOWED;
|
||||
extern int RDF_ICON_URL_LOCKED, RDF_NAME_LOCKED, RDF_COPY_ALLOWED;
|
||||
extern int RDF_MOVE_ALLOWED, RDF_WORKSPACE_POS_LOCKED;
|
||||
extern int RDF_MAIN_TITLE, RDF_COLOR_TITLE, RDF_HTML_INFOHEADER_STR;
|
||||
extern int RDF_MISSION_CONTROL_TITLE, RDF_TREE_COLORS_TITLE, RDF_SELECTION_COLORS_TITLE;
|
||||
extern int RDF_COLUMN_COLORS_TITLE, RDF_TITLEBAR_COLORS_TITLE, RDF_HTML_MAININFOHEADER_STR;
|
||||
extern int RDF_HTML_EMPTYHEADER_STR, RDF_HTML_COLOR_STR, RDF_SETCOLOR_JS, RDF_DEFAULTCOLOR_JS;
|
||||
extern int RDF_COLOR_LAYER, RDF_HTMLCOLOR_STR;
|
||||
extern int RDF_SELECT_START, RDF_SELECT_END, RDF_SELECT_OPTION;
|
||||
extern int RDF_FIND_STR1, RDF_FIND_STR2, RDF_FIND_INPUT_STR;
|
||||
extern int RDF_LOCAL_LOCATION_STR, RDF_REMOTE_LOCATION_STR, RDF_ALL_LOCATION_STR;
|
||||
extern int RDF_CONTAINS_STR, RDF_IS_STR, RDF_IS_NOT_STR, RDF_STARTS_WITH_STR, RDF_ENDS_WITH_STR;
|
||||
extern int RDF_FIND_TITLE, RDF_FIND_FULLNAME_STR, RDF_SHORTCUT_CONFLICT_STR, RDF_FTP_NAME_STR;
|
||||
|
||||
#ifdef HT_PASSWORD_RTNS
|
||||
extern int RDF_NEWPASSWORD, RDF_CONFIRMPASSWORD;
|
||||
extern int RDF_MISMATCHPASSWORD, RDF_ENTERPASSWORD;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define MISSION_CONTROL_RDF_PREF "browser.navcenter.admin"
|
||||
#define NETSCAPE_RDF_FILENAME "netscape.rdf"
|
||||
|
||||
typedef struct _SBProviderStruct {
|
||||
struct _SBProviderStruct *next;
|
||||
char *url;
|
||||
char *name;
|
||||
PRBool containerp;
|
||||
PRBool openp;
|
||||
} SBProviderStruct;
|
||||
typedef SBProviderStruct* SBProvider;
|
||||
|
||||
typedef struct _HT_PaneStruct {
|
||||
struct _HT_PaneStruct *next;
|
||||
void *pdata;
|
||||
HT_Notification ns;
|
||||
PLHashTable *hash;
|
||||
HT_NotificationMask mask;
|
||||
RDF db;
|
||||
RDF_Notification rns;
|
||||
struct _HT_ViewStruct *viewList;
|
||||
struct _HT_ViewStruct *selectedView;
|
||||
struct _HT_URLSiteMapAssoc *smp;
|
||||
struct _HT_URLSiteMapAssoc *sbp;
|
||||
uint32 viewListCount;
|
||||
PRBool autoFlushFlag;
|
||||
SBProvider smartBrowsingProviders;
|
||||
PRBool dirty;
|
||||
PRBool personaltoolbar;
|
||||
PRBool toolbar;
|
||||
PRBool bookmarkmenu;
|
||||
PRBool special;
|
||||
int windowType;
|
||||
char *windowURL;
|
||||
char *templateType;
|
||||
struct _HT_PaneStruct *templatePane;
|
||||
char *htdburl;
|
||||
RDFT htdb;
|
||||
} HT_PaneStruct;
|
||||
|
||||
typedef struct HT_ColumnStruct {
|
||||
struct HT_ColumnStruct *next;
|
||||
char *name;
|
||||
uint32 width;
|
||||
uint32 tokenType;
|
||||
void *token;
|
||||
void *feData;
|
||||
PRBool isHiddenFlag;
|
||||
} HT_ColumnStruct, *HT_Column;
|
||||
|
||||
typedef struct _HT_ViewStruct {
|
||||
struct _HT_ViewStruct *next;
|
||||
HT_Pane pane;
|
||||
HT_Resource top;
|
||||
void *pdata;
|
||||
HT_Column columns;
|
||||
uint32 workspacePos;
|
||||
struct _HT_ResourceStruct ***itemList;
|
||||
uint32 itemListSize;
|
||||
uint32 itemListCount;
|
||||
uint32 topNodeIndex;
|
||||
uint32 selectedNodeHint;
|
||||
uint32 sortTokenType;
|
||||
void *sortToken;
|
||||
PRBool descendingFlag;
|
||||
PRBool refreshingItemListp;
|
||||
PRBool inited;
|
||||
RDF_Resource treeRel;
|
||||
} HT_ViewStruct;
|
||||
|
||||
typedef struct _HT_ValueStruct {
|
||||
struct _HT_ValueStruct *next;
|
||||
uint32 tokenType;
|
||||
RDF_Resource token;
|
||||
void *data;
|
||||
} HT_ValueStruct, *HT_Value;
|
||||
|
||||
#define HT_CONTAINER_FLAG 0x0001
|
||||
#define HT_OPEN_FLAG 0x0002
|
||||
#define HT_AUTOFLUSH_OPEN_FLAG 0x0004
|
||||
#define HT_HIDDEN_FLAG 0x0008
|
||||
#define HT_SELECTED_FLAG 0x0010
|
||||
#define HT_VOLATILE_URL_FLAG 0x0020
|
||||
#define HT_FREEICON_URL_FLAG 0x0040
|
||||
#define HT_PASSWORDOK_FLAG 0x0080
|
||||
#define HT_INITED_FLAG 0x0100
|
||||
#define HT_DIRTY_FLAG 0x0200
|
||||
#define HT_ENABLED_FLAG 0x0400
|
||||
|
||||
typedef struct _HT_ResourceStruct {
|
||||
struct _HT_ResourceStruct *nextItem;
|
||||
HT_View view;
|
||||
HT_Resource parent;
|
||||
RDF_Resource node;
|
||||
void *feData;
|
||||
char *dataSource;
|
||||
char *url[5];
|
||||
HT_Value values;
|
||||
HT_Resource child;
|
||||
HT_Resource *children; /* used by sorting */
|
||||
uint32 unsortedIndex; /* used by sorting */
|
||||
uint32 itemListIndex;
|
||||
uint32 numChildren, numChildrenTotal;
|
||||
uint16 flags;
|
||||
uint16 depth;
|
||||
HT_Resource next;
|
||||
/* a pane or view might have multiple occurances of a RDF_Resource.
|
||||
The hash table just points to the first of them. This allows us to
|
||||
make a linked list of it */
|
||||
} HT_ResourceStruct;
|
||||
|
||||
typedef struct _HT_MenuCommandStruct {
|
||||
struct _HT_MenuCommandStruct *next;
|
||||
HT_MenuCmd menuCmd;
|
||||
char *name;
|
||||
RDF_Resource graphCommand;
|
||||
} _HT_MenuCommandStruct, *HT_MenuCommand;
|
||||
|
||||
typedef struct _HT_CursorStruct {
|
||||
HT_Resource container;
|
||||
HT_Resource node;
|
||||
RDF_Cursor cursor;
|
||||
uint32 numElements;
|
||||
HT_Column columns;
|
||||
uint16 contextMenuIndex;
|
||||
PRBool foundValidMenuItem;
|
||||
PRBool isWorkspaceFlag;
|
||||
PRBool isBackgroundFlag;
|
||||
PRBool commandExtensions;
|
||||
PRBool commandListBuild;
|
||||
HT_MenuCmd menuCmd;
|
||||
HT_MenuCommand menuCommandList;
|
||||
} HT_CursorStruct;
|
||||
|
||||
typedef struct _HT_Icon {
|
||||
struct _HT_Icon *next;
|
||||
char *name;
|
||||
} _HT_Icon, *HT_Icon;
|
||||
|
||||
typedef struct _htmlElement {
|
||||
struct _htmlElement *next;
|
||||
HT_Resource node;
|
||||
RDF_Resource token;
|
||||
uint32 tokenType;
|
||||
} _htmlElement, *_htmlElementPtr;
|
||||
|
||||
typedef struct _HT_URLSiteMapAssoc {
|
||||
uint8 siteToolType;
|
||||
uint8 origin;
|
||||
uint8 onDisplayp;
|
||||
char *url;
|
||||
RDF_Resource sitemap;
|
||||
char* name;
|
||||
char* sitemapUrl;
|
||||
RDFT db;
|
||||
struct _HT_URLSiteMapAssoc *next;
|
||||
} HT_URLSiteMapAssoc;
|
||||
|
||||
|
||||
|
||||
/* HT function prototypes */
|
||||
|
||||
XP_BEGIN_PROTOS
|
||||
|
||||
void HT_Startup();
|
||||
void HT_Shutdown();
|
||||
void htLoadComplete(char *url, int status);
|
||||
void htTimerRoutine(void *timerID);
|
||||
PRBool possiblyUpdateView(HT_View view);
|
||||
void updateViewItem(HT_Resource node);
|
||||
HT_Resource newHTEntry (HT_View view, RDF_Resource node);
|
||||
void addWorkspace(HT_Pane pane, RDF_Resource r, void *feData);
|
||||
void deleteWorkspace(HT_Pane pane, RDF_Resource r);
|
||||
void htrdfNotifFunc (RDF_Event ns, void* pdata);
|
||||
void bmkNotifFunc (RDF_Event ns, void* pdata);
|
||||
void refreshItemListInt (HT_View view, HT_Resource node);
|
||||
PRBool relatedLinksContainerp (HT_Resource node);
|
||||
int nodeCompareRtn(HT_Resource *node1, HT_Resource *node2);
|
||||
void sortNodes(HT_View view, HT_Resource parent, HT_Resource *children, uint32 numChildren);
|
||||
uint32 refreshItemList1(HT_View view, HT_Resource node);
|
||||
void refreshItemList (HT_Resource node, HT_Event whatHappened);
|
||||
void refreshPanes();
|
||||
PRBool initToolbars (HT_Pane pane);
|
||||
HT_Pane paneFromResource(RDF db, RDF_Resource resource, HT_Notification notify, PRBool autoFlushFlag, PRBool autoOpenFlag, PRBool useColumns);
|
||||
void htSetBookmarkAddDateToNow(RDF_Resource r);
|
||||
RDF newHTPaneDB();
|
||||
RDF HTRDF_GetDB();
|
||||
PRBool initViews (HT_Pane pane);
|
||||
void htNewWorkspace(HT_Pane pane, char *id, char *optionalTitle, uint32 workspacePos);
|
||||
HT_PaneStruct * HT_GetHTPaneList ();
|
||||
HT_PaneStruct * HT_GetNextHTPane (HT_PaneStruct* pane);
|
||||
void htSetWorkspaceOrder(RDF_Resource src, RDF_Resource dest, PRBool afterDestFlag);
|
||||
HT_View HT_NewView (RDF_Resource topNode, HT_Pane pane, PRBool useColumns, void *feData, PRBool autoOpen);
|
||||
void sendNotification (HT_Resource node, HT_Event whatHappened, RDF_Resource s, HT_ColumnType type);
|
||||
void deleteHTNode(HT_Resource node);
|
||||
void destroyViewInt (HT_Resource r, PRBool saveOpenState);
|
||||
void htDeletePane(HT_Pane pane, PRBool saveWorkspaceOrder);
|
||||
void saveWorkspaceOrder(HT_Pane pane);
|
||||
void resynchItem (HT_Resource node, void *token, void *data, PRBool assertAction);
|
||||
void resynchContainer (HT_Resource container);
|
||||
HT_Resource addContainerItem (HT_Resource container, RDF_Resource item);
|
||||
void refreshContainerIndexes(HT_Resource container);
|
||||
void removeHTFromHash (HT_Pane pane, HT_Resource item);
|
||||
void deleteHTSubtree (HT_Resource subtree);
|
||||
void deleteContainerItem (HT_Resource container, RDF_Resource item);
|
||||
uint32 fillContainer (HT_Resource node);
|
||||
void sendColumnNotification (HT_View view, void *token, uint32 tokenType, HT_Event whatHappened);
|
||||
PRBool htIsMenuCmdEnabled(HT_Pane pane, HT_MenuCmd menuCmd, PRBool isWorkspaceFlag, PRBool isBackgroundFlag);
|
||||
void freeMenuCommandList();
|
||||
void exportCallbackWrite(PRFileDesc *fp, char *str);
|
||||
void exportCallback(MWContext *context, char *filename, RDF_Resource node);
|
||||
void htEmptyClipboard(RDF_Resource parent);
|
||||
void htCopyReference(RDF_Resource original, RDF_Resource newParent, PRBool empty);
|
||||
PRBool htVerifyUniqueToken(HT_Resource node, void *token, uint32 tokenType, char *data);
|
||||
PRBool ht_isURLReal(HT_Resource node);
|
||||
char * buildInternalIconURL(HT_Resource node, PRBool *volatileURLFlag, PRBool largeIconFlag, PRBool workspaceFlag);
|
||||
char * getIconURL( HT_Resource node, PRBool toolbarFlag, PRBool workspaceFlag, int state);
|
||||
PRBool htIsPropertyInMoreOptions(RDF_Resource r);
|
||||
void addHtmlElement(HT_Resource node, RDF_Resource token, uint32 tokenType);
|
||||
void freeHtmlElementList();
|
||||
_htmlElementPtr findHtmlElement(void *token);
|
||||
void freeHtmlElement(void *token);
|
||||
char * constructHTMLTagData(char *dynStr, int strID, char *data);
|
||||
char * constructHTML(char *dynStr, HT_Resource node, void *token, uint32 tokenType);
|
||||
char * constructHTMLPermission(char *dynStr, HT_Resource node, RDF_Resource token, char *permText);
|
||||
PRBool htIsOpLocked(HT_Resource node, RDF_Resource token);
|
||||
char * constructBasicHTML(char *dynStr, int strID, char *data1, char *data2);
|
||||
void setHiddenState (HT_Resource node);
|
||||
void htSetFindResourceName(RDF db, RDF_Resource r);
|
||||
void htOpenTo(HT_View view, RDF_Resource u, PRBool selectView);
|
||||
PRBool mutableContainerp (RDF_Resource node);
|
||||
char * possiblyCleanUpTitle (char* title);
|
||||
PRBool htRemoveChild(HT_Resource parent, HT_Resource child, PRBool moveToTrash);
|
||||
void ht_SetPassword(HT_Resource node, char *password);
|
||||
PRBool ht_hasPassword(HT_Resource node);
|
||||
PRBool ht_checkPassword(HT_Resource node, PRBool alwaysCheck);
|
||||
HT_DropAction htLaunchSmartNode(HT_Resource dropTarget, char *fullURL);
|
||||
HT_DropAction dropOnSmartNode(HT_Resource dropTarget, HT_Resource dropObject, PRBool justAction);
|
||||
HT_DropAction dropOnSmartURL(HT_Resource dropTarget, char *objTitle, PRBool justAction);
|
||||
HT_DropAction dropOn (HT_Resource dropTarget, HT_Resource dropObject, PRBool justAction);
|
||||
void Win32FileCopyMove(HT_Resource dropTarget, HT_Resource dropObject);
|
||||
HT_DropAction copyMoveRDFLink (HT_Resource dropTarget, HT_Resource dropObject);
|
||||
HT_DropAction copyMoveRDFLinkAtPos (HT_Resource dropx, HT_Resource dropObject, PRBool before);
|
||||
HT_DropAction uploadLFS (HT_Resource dropTarget, HT_Resource dropObject);
|
||||
HT_DropAction uploadRDFFile (HT_Resource dropTarget, HT_Resource dropObject);
|
||||
HT_DropAction esfsCopyMoveContent (HT_Resource dropTarget, HT_Resource dropObject);
|
||||
RDF_BT urlResourceType (char* url);
|
||||
HT_DropAction dropURLOn (HT_Resource dropTarget, char* objURL, char *objTitle, PRBool justAction);
|
||||
void replacePipeWithColon(char* url);
|
||||
HT_DropAction copyRDFLinkURL (HT_Resource dropTarget, char* objURL, char *objTitle);
|
||||
HT_DropAction copyRDFLinkURLAt (HT_Resource dropx, char* objURL, char *objTitle, PRBool before);
|
||||
HT_DropAction uploadLFSURL (HT_Resource dropTarget, char* objURL);
|
||||
HT_DropAction uploadRDFFileURL (HT_Resource dropTarget, char* objURL);
|
||||
HT_DropAction esfsCopyMoveContentURL (HT_Resource dropTarget, char* objURL);
|
||||
RDFT HTADD(HT_Pane pane, RDF_Resource u, RDF_Resource s, void* v);
|
||||
HT_URLSiteMapAssoc * makeNewSMP (HT_Pane htPane, char* pUrl, char* sitemapurl);
|
||||
void RetainOldSitemaps (HT_Pane htPane, char *pUrl);
|
||||
void populateSBProviders (HT_Pane htPane);
|
||||
SBProvider SBProviderOfNode (HT_Resource node);
|
||||
PRBool implicitDomainURL (char* url);
|
||||
PRBool domainMatches (char *dom, char *url);
|
||||
void nextDomain (char* dom, size_t *n);
|
||||
PRBool relatedLinksEnabledURL (char* url);
|
||||
void cleanupInt (HT_Pane htPane, HT_URLSiteMapAssoc *nsmp, RDF_Resource parent);
|
||||
HT_Pane newTemplatePane(char* templateName);
|
||||
void PaneDeleteSBPCleanup (HT_Pane htPane);
|
||||
|
||||
#ifndef HT_RAPTOR
|
||||
PRBool rdfFindDialogHandler(XPDialogState *dlgstate, char **argv, int argc, unsigned int button);
|
||||
#endif
|
||||
|
||||
XP_END_PROTOS
|
||||
|
||||
#endif
|
||||
|
||||
404
mozilla/modules/rdf/src/jsec2rdf.c
Normal file
@@ -0,0 +1,404 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "jsec2rdf.h"
|
||||
#include "fs2rdf.h"
|
||||
#include "utils.h"
|
||||
#include "nlcstore.h"
|
||||
#include "vocabint.h"
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
extern RDF gNCDB;
|
||||
RDF gJSecDB = NULL;
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_InitPrivilegeDB()
|
||||
{
|
||||
if (gJSecDB == 0) {
|
||||
gJSecDB = gNCDB;
|
||||
}
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_SavePrivilegeDB()
|
||||
{
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_ClosePrivilegeDB()
|
||||
{
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
#define JSEC_PRINCIPAL_URL "jsecprin:"
|
||||
|
||||
char *
|
||||
RDFJSec_GetPrincipalURLString(char *principalID)
|
||||
{
|
||||
size_t size = RDF_STRLEN(principalID);
|
||||
char* url = getMem(size+RDF_STRLEN(JSEC_PRINCIPAL_URL)+1);
|
||||
if (url == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sprintf(url, "%s%s", JSEC_PRINCIPAL_URL, principalID);
|
||||
strcpy(url, principalID);
|
||||
return url;
|
||||
}
|
||||
|
||||
RDF_Cursor
|
||||
RDFJSec_ListAllPrincipals()
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
if (gNavCenter != NULL) {
|
||||
c = RDF_GetSources(gJSecDB, gNavCenter->RDF_JSec,
|
||||
gNavCenter->RDF_JSecPrincipal,
|
||||
RDF_RESOURCE_TYPE, TRUE);
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
JSec_Principal
|
||||
RDFJSec_NextPrincipal(RDF_Cursor c)
|
||||
{
|
||||
if (c != NULL) {
|
||||
return RDF_NextValue(c);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RDF_Error
|
||||
RDFJSec_ReleaseCursor(RDF_Cursor c)
|
||||
{
|
||||
RDF_Error err = 0;
|
||||
if (c != NULL) {
|
||||
err = RDF_DisposeCursor(c);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
JSec_Principal
|
||||
RDFJSec_NewPrincipal(char* principalID)
|
||||
{
|
||||
RDF_Resource principalUnit;
|
||||
char *url = RDFJSec_GetPrincipalURLString(principalID);
|
||||
if (url == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
principalUnit = RDF_GetResource(NULL, url, FALSE);
|
||||
if (!principalUnit) {
|
||||
principalUnit = RDF_GetResource(NULL, url, TRUE);
|
||||
}
|
||||
freeMem(url);
|
||||
return (JSec_Principal)principalUnit;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_AddPrincipal(JSec_Principal pr)
|
||||
{
|
||||
if ((pr == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
if (RDF_HasAssertion(gJSecDB, pr, gNavCenter->RDF_JSecPrincipal, gNavCenter->RDF_JSec,
|
||||
RDF_RESOURCE_TYPE, PR_FALSE)) {
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
setContainerp(pr, PR_TRUE);
|
||||
setResourceType(pr, JSEC_RT);
|
||||
RDF_Assert(gJSecDB, pr, gNavCenter->RDF_JSecPrincipal, gNavCenter->RDF_JSec, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_DeletePrincipal(JSec_Principal pr)
|
||||
{
|
||||
RDF_Cursor c;
|
||||
if ((pr == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
/* Before deleting the principal, delete all the PrincipalUses for this principal.
|
||||
*/
|
||||
c = RDFJSec_ListAllPrincipalUses(pr);
|
||||
if (c != NULL) {
|
||||
JSec_PrincipalUse prUse;
|
||||
while ((prUse = RDFJSec_NextPrincipalUse(c)) != NULL) {
|
||||
RDFJSec_DeletePrincipalUse(pr, prUse);
|
||||
}
|
||||
}
|
||||
RDF_Unassert(gJSecDB, pr, gNavCenter->RDF_JSecPrincipal, gNavCenter->RDF_JSec, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
char *
|
||||
RDFJSec_PrincipalID(JSec_Principal pr)
|
||||
{
|
||||
char *url = resourceID(pr);
|
||||
char *ans = getMem(RDF_STRLEN(url)+1);
|
||||
int n;
|
||||
if (ans == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
n = charSearch(':', url);
|
||||
if (n == -1) {
|
||||
strcpy(ans, url);
|
||||
} else {
|
||||
strcpy(ans, url+n+1);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void *
|
||||
RDFJSec_AttributeOfPrincipal(JSec_Principal pr, char* attributeType)
|
||||
{
|
||||
RDF_Resource attributeResource = RDF_GetResource(NULL, attributeType, TRUE);
|
||||
void *attValue;
|
||||
RDF_Cursor c = NULL;
|
||||
c = RDF_GetTargets(gJSecDB, pr, attributeResource, RDF_STRING_TYPE, TRUE);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
attValue = RDF_NextValue(c);
|
||||
RDF_DisposeCursor(c);
|
||||
return attValue;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_SetPrincipalAttribute(JSec_Principal pr, char* attributeType, void* attValue)
|
||||
{
|
||||
RDF_Resource attributeResource = RDF_GetResource(NULL, attributeType, TRUE);
|
||||
RDF_Assert(gJSecDB, pr, attributeResource, attValue, RDF_STRING_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
RDFJSec_ListAllPrincipalUses(JSec_Principal pr)
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
c = RDF_GetSources(gJSecDB, (RDF_Resource)pr, gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, true);
|
||||
return(c);
|
||||
}
|
||||
|
||||
JSec_PrincipalUse
|
||||
RDFJSec_NextPrincipalUse(RDF_Cursor c)
|
||||
{
|
||||
if (c != NULL) {
|
||||
return RDF_NextValue(c);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSec_PrincipalUse
|
||||
RDFJSec_NewPrincipalUse(JSec_Principal pr, JSec_Target tr, char* priv)
|
||||
{
|
||||
RDF_Resource principalUseUnit;
|
||||
char *targetID = resourceID(tr);
|
||||
char *principalID = resourceID(pr);
|
||||
char *principalUseID = getMem(RDF_STRLEN(principalID) + strlen(targetID) + 2);
|
||||
if (principalUseID == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sprintf(principalUseID, "%s!%s", principalID, targetID);
|
||||
principalUseUnit = RDF_GetResource(NULL, principalUseID, FALSE);
|
||||
if (!principalUseUnit) {
|
||||
principalUseUnit = RDF_GetResource(NULL, principalUseID, TRUE);
|
||||
RDFJSec_AddTargetToPrincipalUse(principalUseUnit, tr);
|
||||
RDFJSec_AddPrincipalUsePrivilege(principalUseUnit, priv);
|
||||
}
|
||||
return principalUseUnit;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_AddPrincipalUse(JSec_Principal pr, JSec_PrincipalUse prUse)
|
||||
{
|
||||
if ((pr == NULL) || (prUse == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
setContainerp(prUse, PR_TRUE);
|
||||
setResourceType(prUse, JSEC_RT);
|
||||
RDF_Assert(gJSecDB, prUse, gCoreVocab->RDF_parent, pr, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_DeletePrincipalUse (JSec_Principal pr, JSec_PrincipalUse prUse)
|
||||
{
|
||||
JSec_Target tr;
|
||||
char *priv;
|
||||
if ((pr == NULL) || (prUse == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
/* Before deleting the principal, delete all the PrincipalUses for this principal.
|
||||
*/
|
||||
tr = RDFJSec_TargetOfPrincipalUse(prUse);
|
||||
RDFJSec_DeleteTargetToPrincipalUse(prUse, tr);
|
||||
priv = RDFJSec_PrivilegeOfPrincipalUse(prUse);
|
||||
RDFJSec_DeletePrincipalUsePrivilege(prUse, priv);
|
||||
RDF_Unassert(gJSecDB, prUse, gCoreVocab->RDF_parent, pr, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
RDFJSec_PrincipalUseID(JSec_PrincipalUse prUse)
|
||||
{
|
||||
return resourceID(prUse);
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_AddPrincipalUsePrivilege (JSec_PrincipalUse prUse, char* priv)
|
||||
{
|
||||
char *oldPriv;
|
||||
if ((prUse == NULL) || (priv == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
/* Each PrincipalUse can only have one Privilege. Thus delete the old privilege*/
|
||||
oldPriv = RDFJSec_PrivilegeOfPrincipalUse(prUse);
|
||||
RDFJSec_DeletePrincipalUsePrivilege(prUse, oldPriv);
|
||||
RDF_Assert(gJSecDB, prUse, gNavCenter->RDF_JSecAccess, priv, RDF_STRING_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_DeletePrincipalUsePrivilege (JSec_PrincipalUse prUse, char* priv)
|
||||
{
|
||||
if ((prUse == NULL) || (priv == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
RDF_Unassert(gJSecDB, prUse, gNavCenter->RDF_JSecAccess, priv, RDF_STRING_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
char *
|
||||
RDFJSec_PrivilegeOfPrincipalUse (JSec_PrincipalUse prUse)
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
char *privilege;
|
||||
if (gNavCenter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
c = RDF_GetTargets(gJSecDB, (RDF_Resource)prUse, gNavCenter->RDF_JSecAccess, RDF_STRING_TYPE, TRUE);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
privilege = RDF_NextValue(c);
|
||||
RDF_DisposeCursor(c);
|
||||
return privilege;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_AddTargetToPrincipalUse(JSec_PrincipalUse prUse, JSec_Target tr)
|
||||
{
|
||||
JSec_Target oldTarget;
|
||||
if ((prUse == NULL) || (tr == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
/* Each PrincipalUse can only have one Target. Thus delete the old target */
|
||||
oldTarget = RDFJSec_TargetOfPrincipalUse(prUse);
|
||||
RDFJSec_DeleteTargetToPrincipalUse(prUse, oldTarget);
|
||||
RDF_Assert(gJSecDB, prUse, gNavCenter->RDF_JSecTarget, tr, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_DeleteTargetToPrincipalUse(JSec_PrincipalUse prUse, JSec_Target tr)
|
||||
{
|
||||
if ((prUse == NULL) || (tr == NULL) || (gNavCenter == NULL)) {
|
||||
return JSec_NullObject;
|
||||
}
|
||||
RDF_Unassert(gJSecDB, prUse, gNavCenter->RDF_JSecTarget, tr, RDF_RESOURCE_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
JSec_Target
|
||||
RDFJSec_TargetOfPrincipalUse (JSec_PrincipalUse prUse)
|
||||
{
|
||||
RDF_Cursor c = NULL;
|
||||
JSec_Target tr;
|
||||
if ((prUse == NULL) || (gNavCenter == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
c = RDF_GetTargets(gJSecDB, (RDF_Resource)prUse, gNavCenter->RDF_JSecTarget, RDF_RESOURCE_TYPE, true);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tr = RDF_NextValue(c);
|
||||
RDF_DisposeCursor(c);
|
||||
return tr;
|
||||
}
|
||||
|
||||
JSec_Target
|
||||
RDFJSec_NewTarget(char* targetName, JSec_Principal pr)
|
||||
{
|
||||
RDF_Resource tr;
|
||||
/* RDF_Resource prResource; */
|
||||
char *principalID = RDFJSec_PrincipalID(pr);
|
||||
char *targetID = getMem(RDF_STRLEN(targetName) + strlen(principalID) + 2);
|
||||
if (targetID == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gNavCenter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprintf(targetID, "%s!%s", targetName, principalID);
|
||||
tr = RDF_GetResource(NULL, targetID, FALSE);
|
||||
if (!tr) {
|
||||
tr = RDF_GetResource(NULL, targetID, TRUE);
|
||||
if (tr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
RDFJSec_SetTargetAttribute(tr, "targetName", targetName);
|
||||
RDF_Assert(gJSecDB, tr, gNavCenter->RDF_JSecPrincipal, pr, RDF_RESOURCE_TYPE);
|
||||
}
|
||||
return tr;
|
||||
}
|
||||
|
||||
char *
|
||||
RDFJSec_GetTargetName(JSec_Target tr)
|
||||
{
|
||||
return RDFJSec_AttributeOfTarget(tr, "targetName");
|
||||
}
|
||||
|
||||
char *
|
||||
RDFJSec_AttributeOfTarget(JSec_Target tr, char* attributeType)
|
||||
{
|
||||
RDF_Resource attributeResource = RDF_GetResource(NULL, attributeType, TRUE);
|
||||
char *attValue;
|
||||
RDF_Cursor c = NULL;
|
||||
c = RDF_GetTargets(gJSecDB, tr, attributeResource, RDF_STRING_TYPE, TRUE);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
attValue = RDF_NextValue(c);
|
||||
RDF_DisposeCursor(c);
|
||||
return attValue;
|
||||
}
|
||||
|
||||
JSec_Error
|
||||
RDFJSec_SetTargetAttribute(JSec_Target tr, char* attributeType, char* attValue)
|
||||
{
|
||||
RDF_Resource attributeResource = RDF_GetResource(NULL, attributeType, TRUE);
|
||||
RDF_Assert(gJSecDB, tr, attributeResource, attValue, RDF_STRING_TYPE);
|
||||
return JSec_OK;
|
||||
}
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
562
mozilla/modules/rdf/src/ldap2rdf.c
Normal file
@@ -0,0 +1,562 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements LDAP support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
/*
|
||||
XXX Someone needs to get this up to speed again
|
||||
*/
|
||||
#if 0
|
||||
#ifdef MOZ_LDAP
|
||||
|
||||
#include "ldap2rdf.h"
|
||||
#include "utils.h"
|
||||
|
||||
/* statics */
|
||||
static PRHashTable *ldap2rdfHash;
|
||||
static PRHashTable *invldap2rdfHash;
|
||||
static RDFT gRDFDB;
|
||||
static PRBool ldap2rdfInitedp = 0;
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakeLdapStore (char* url)
|
||||
{
|
||||
RDFT ntr = (RDFT)getMem(sizeof(RDF_TranslatorStruct));
|
||||
ntr->assert = ldapAssert;
|
||||
ntr->unassert = ldapUnassert;
|
||||
ntr->getSlotValue = ldapGetSlotValue;
|
||||
ntr->getSlotValues = ldapGetSlotValues;
|
||||
ntr->hasAssertion = ldapHasAssertion;
|
||||
ntr->nextValue = ldapNextValue;
|
||||
ntr->disposeCursor = ldapDisposeCursor;
|
||||
ldap2rdfInit(ntr);
|
||||
return ntr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
LdapInit (RDFT ntr)
|
||||
{
|
||||
ntr->assert = ldapAssert;
|
||||
ntr->unassert = ldapUnassert;
|
||||
ntr->getSlotValue = ldapGetSlotValue;
|
||||
ntr->getSlotValues = ldapGetSlotValues;
|
||||
ntr->hasAssertion = ldapHasAssertion;
|
||||
ntr->nextValue = ldapNextValue;
|
||||
ntr->disposeCursor = ldapDisposeCursor;
|
||||
ldap2rdfInit(ntr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ldap2rdfInit (RDFT rdf)
|
||||
{
|
||||
if (!ldap2rdfInitedp) {
|
||||
ldap2rdfHash = PR_NewHashTable(500, idenHash, idenEqual, idenEqual, null, null);
|
||||
invldap2rdfHash = PR_NewHashTable(500, idenHash, idenEqual, idenEqual, null, null);
|
||||
gRDFDB = rdf;
|
||||
ldap2rdfInitedp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Assertion
|
||||
ldaparg1 (RDF_Resource u)
|
||||
{
|
||||
return (Assertion) PR_HashTableLookup(ldap2rdfHash, u);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Assertion
|
||||
setldaparg1 (RDF_Resource u, Assertion as)
|
||||
{
|
||||
return (Assertion) PR_HashTableAdd(ldap2rdfHash, u, as);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Assertion
|
||||
ldaparg2 (RDF_Resource u)
|
||||
{
|
||||
return (Assertion) PR_HashTableLookup(invldap2rdfHash, u);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Assertion
|
||||
setldaparg2 (RDF_Resource u, Assertion as)
|
||||
{
|
||||
return (Assertion) PR_HashTableAdd(invldap2rdfHash, u, as);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v));
|
||||
if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
|
||||
if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE) &&
|
||||
(tv) && (ldapContainerp(v))) {
|
||||
return (ldapAddChild(rdf, (RDF_Resource)v, u));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type)
|
||||
{
|
||||
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
|
||||
if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE) &&
|
||||
(ldapContainerp(v))) {
|
||||
return (ldapRemoveChild(rdf, (RDF_Resource)v, u));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapDBAdd (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type)
|
||||
{
|
||||
Assertion nextAs, prevAs, newAs;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if ((s == gCoreVocab->RDF_instanceOf) && (v == gWebData->RDF_Container)) {
|
||||
setContainerp(u, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nextAs = prevAs = ldaparg1(u);
|
||||
while (nextAs != null) {
|
||||
if (asEqual(nextAs, u, s, v, type)) return 1;
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
newAs = makeNewAssertion(u, s, v, type, 1);
|
||||
if (prevAs == null) {
|
||||
setldaparg1(u, newAs);
|
||||
} else {
|
||||
prevAs->next = newAs;
|
||||
}
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
nextAs = prevAs = ldaparg2((RDF_Resource)v);
|
||||
while (nextAs != null) {
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
}
|
||||
if (prevAs == null) {
|
||||
setldaparg2((RDF_Resource)v, newAs);
|
||||
} else {
|
||||
prevAs->invNext = newAs;
|
||||
}
|
||||
}
|
||||
sendNotifications2(rdf, RDF_ASSERT_NOTIFY, u, s, v, type, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapDBRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type)
|
||||
{
|
||||
Assertion nextAs, prevAs, ans;
|
||||
PRBool found = false;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
nextAs = prevAs = ldaparg1(u);
|
||||
while (nextAs != null) {
|
||||
if (asEqual(nextAs, u, s, v, type)) {
|
||||
if (prevAs == null) {
|
||||
setldaparg1(u, nextAs->next);
|
||||
} else {
|
||||
prevAs->next = nextAs->next;
|
||||
}
|
||||
found = true;
|
||||
ans = nextAs;
|
||||
break;
|
||||
}
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
if (found == false) return false;
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
nextAs = prevAs = ldaparg2((RDF_Resource)v);
|
||||
while (nextAs != null) {
|
||||
if (nextAs == ans) {
|
||||
if (prevAs == nextAs) {
|
||||
setldaparg2((RDF_Resource)v, nextAs->invNext);
|
||||
} else {
|
||||
prevAs->invNext = nextAs->invNext;
|
||||
}
|
||||
}
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
}
|
||||
}
|
||||
sendNotifications2(rdf, RDF_DELETE_NOTIFY, u, s, v, type, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
Assertion nextAs;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
|
||||
|
||||
nextAs = ldaparg1(u);
|
||||
while (nextAs != null) {
|
||||
if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
|
||||
possiblyAccessldap(rdf, u, s, false);
|
||||
|
||||
nextAs = ldaparg1(u);
|
||||
while (nextAs != null) {
|
||||
if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
ldapGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
Assertion nextAs;
|
||||
if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
|
||||
|
||||
nextAs = (inversep ? ldaparg2(u) : ldaparg1(u));
|
||||
while (nextAs != null) {
|
||||
if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
|
||||
void * retVal = (inversep ? nextAs->u : nextAs->value);
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )retVal)));
|
||||
return retVal
|
||||
}
|
||||
nextAs = (inversep ? nextAs->invNext : nextAs->next);
|
||||
}
|
||||
|
||||
possiblyAccessldap(rdf, u, s, inversep);
|
||||
|
||||
nextAs = (inversep ? ldaparg2(u) : ldaparg1(u));
|
||||
while (nextAs != null) {
|
||||
if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
|
||||
void * retVal = (inversep ? nextAs->u : nextAs->value);
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )retVal)));
|
||||
return retVal
|
||||
}
|
||||
nextAs = (inversep ? nextAs->invNext : nextAs->next);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
ldapGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
Assertion as;
|
||||
RDF_Cursor c;
|
||||
if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
|
||||
as = (inversep ? ldaparg2(u) : ldaparg1(u));
|
||||
if (as == null) {
|
||||
possiblyAccessldap(rdf, u, s, inversep);
|
||||
as = (inversep ? ldaparg2(u) : ldaparg1(u));
|
||||
if (as == null)
|
||||
return null;
|
||||
}
|
||||
c = (RDF_CursorStruc*)getMem(sizeof(RDF_CursorStruc));
|
||||
c->u = u;
|
||||
c->s = s;
|
||||
c->type = type;
|
||||
c->inversep = inversep;
|
||||
c->tv = tv;
|
||||
c->count = 0;
|
||||
c->pdata = as;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
ldapNextValue (RDFT mcf, RDF_Cursor c)
|
||||
{
|
||||
while (c->pdata != null) {
|
||||
Assertion as = (Assertion) c->pdata;
|
||||
if ((as->s == c->s) && (as->tv == c->tv) && (c->type == as->type)) {
|
||||
c->value = (c->inversep ? as->u : as->value);
|
||||
c->pdata = (c->inversep ? as->invNext : as->next);
|
||||
return c->value;
|
||||
}
|
||||
c->pdata = (c->inversep ? as->invNext : as->next);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
ldapDisposeCursor (RDFT mcf, RDF_Cursor c)
|
||||
{
|
||||
freeMem(c);
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
ldapNewContainer(char *id)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
ldapModifyEntry (RDFT rdf, RDF_Resource parent, RDF_Resource child, PRBool addFlag)
|
||||
{
|
||||
RDF_Cursor c;
|
||||
RDF_Resource newParent, r;
|
||||
char *urivals[2];
|
||||
LDAP *ld;
|
||||
LDAPMod urimod, *mods[2];
|
||||
LDAPURLDesc *ldURL=NULL;
|
||||
int err;
|
||||
char *errStr, *parentID;
|
||||
|
||||
parentID = resourceID(parent);
|
||||
|
||||
if (containerp(child))
|
||||
{
|
||||
if (newParent = ldapNewContainer(parentID))
|
||||
{
|
||||
if ((c = RDF_GetSources(rdf->rdf->rdf, child,
|
||||
gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, 1)) != NULL)
|
||||
{
|
||||
while ((r = RDF_NextValue(c)) != NULL)
|
||||
{
|
||||
err = ldapModifyEntry(rdf, newParent, r, addFlag);
|
||||
if (err)
|
||||
{
|
||||
/* XXX MAJOR rollback issues!
|
||||
Punt for now! */
|
||||
|
||||
return(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
ldap_url_parse(parentID, &ldURL);
|
||||
if (ldURL == NULL) return(-1);
|
||||
ld = ldap_init (ldURL->lud_host, ldURL->lud_port);
|
||||
if (ld == NULL)
|
||||
{
|
||||
ldap_free_urldesc(ldURL);
|
||||
return(-1);
|
||||
}
|
||||
if ((err = ldap_simple_bind_s(ld, ADMIN_ID, ADMIN_PW)) /* XXX */
|
||||
!= LDAP_SUCCESS)
|
||||
{
|
||||
if ((errStr = ldap_err2string(err)) != NULL)
|
||||
{
|
||||
/* We need to change XP_MakeHTMLAlert to use UTF8 */
|
||||
XP_MakeHTMLAlert(NULL, errStr);
|
||||
}
|
||||
|
||||
ldap_unbind(ld);
|
||||
ldap_free_urldesc(ldURL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
urivals[0] = resourceID(child);
|
||||
urivals[1] = NULL;
|
||||
|
||||
urimod.mod_op = ((addFlag == true) ? LDAP_MOD_ADD : LDAP_MOD_DELETE);
|
||||
urimod.mod_type = "labeledURI";
|
||||
urimod.mod_values = urivals;
|
||||
|
||||
mods[0] = &urimod;
|
||||
mods[1] = NULL;
|
||||
|
||||
err = ldap_modify_s(ld, ldURL->lud_dn, mods);
|
||||
if (err != LDAP_SUCCESS)
|
||||
{
|
||||
if ((errStr = ldap_err2string(err)) != NULL)
|
||||
{
|
||||
/* We need to change XP_MakeHTMLAlert to use UTF8 */
|
||||
XP_MakeHTMLAlert(NULL, errStr);
|
||||
}
|
||||
}
|
||||
|
||||
ldap_unbind(ld);
|
||||
ldap_free_urldesc(ldURL);
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapAddChild (RDFT rdf, RDF_Resource parent, RDF_Resource child)
|
||||
{
|
||||
return (ldapModifyEntry(rdf, parent, child, true) != LDAP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapRemoveChild (RDFT rdf, RDF_Resource parent, RDF_Resource child)
|
||||
{
|
||||
return (ldapModifyEntry(rdf, parent, child, false) != LDAP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
possiblyAccessldap(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
/** try to get the values of u.s from the directory **/
|
||||
|
||||
LDAP *ld;
|
||||
LDAPMessage *result=NULL, *entry;
|
||||
LDAPURLDesc *ldURL=NULL;
|
||||
RDF_Resource node;
|
||||
char *attrs[2], **vals;
|
||||
int err, i;
|
||||
char *title = NULL;
|
||||
|
||||
/*
|
||||
Note: a labeledURI is a url followed by an optional [space title-string]
|
||||
*/
|
||||
|
||||
if (!stringEquals(resourceID(s), resourceID(gCoreVocab->RDF_parent)) || (!inversep) || (!ldap_is_ldap_url(resourceID(u)))) return;
|
||||
|
||||
ldap_url_parse(resourceID(u), &ldURL);
|
||||
if (ldURL == NULL) return;
|
||||
ld = ldap_init (ldURL->lud_host, ldURL->lud_port);
|
||||
if (ld == NULL)
|
||||
{
|
||||
ldap_free_urldesc(ldURL);
|
||||
return;
|
||||
}
|
||||
if ((err = ldap_simple_bind_s(ld, NULL, NULL)) != LDAP_SUCCESS)
|
||||
{
|
||||
ldap_unbind(ld);
|
||||
ldap_free_urldesc(ldURL);
|
||||
return;
|
||||
}
|
||||
|
||||
attrs[0] = "labeledURI";
|
||||
attrs[1] = NULL;
|
||||
|
||||
err = ldap_search_s(ld, ldURL->lud_dn, LDAP_SCOPE_BASE, ldURL->lud_filter, attrs, 0, &result);
|
||||
if (err == LDAP_SUCCESS)
|
||||
{
|
||||
for (entry=ldap_first_entry(ld, result); entry!=NULL; entry=ldap_next_entry(ld, entry))
|
||||
{
|
||||
if ((vals = ldap_get_values(ld, entry, attrs[0])) != NULL)
|
||||
{
|
||||
for (i=0; vals[i] != NULL; i++)
|
||||
{
|
||||
/* vals[i] has a URL... add into RDF graph */
|
||||
|
||||
/*
|
||||
if (((title = strstr(vals[i], " ")) != NULL)
|
||||
&& (*(title+1) != '\0'))
|
||||
{
|
||||
*(++title) = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
title = NULL;
|
||||
}
|
||||
*/
|
||||
if ((node = RDF_Create(vals[i], true)) != NULL)
|
||||
{
|
||||
setResourceType(node, LDAP_RT);
|
||||
if (ldapContainerp(node) == true)
|
||||
{
|
||||
setContainerp(node, 1);
|
||||
}
|
||||
|
||||
ldapDBAdd(rdf, node, gCoreVocab->RDF_parent,
|
||||
u, RDF_RESOURCE_TYPE);
|
||||
|
||||
if (title != NULL)
|
||||
{
|
||||
ldapDBAdd(rdf, node, gCoreVocab->RDF_name,
|
||||
title, RDF_STRING_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
ldap_value_free(vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != NULL)
|
||||
{
|
||||
ldap_msgfree(result);
|
||||
}
|
||||
ldap_unbind(ld);
|
||||
ldap_free_urldesc(ldURL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
ldapContainerp (RDF_Resource u)
|
||||
{
|
||||
return(ldap_is_ldap_url(resourceID(u))); /* XXX ??? */
|
||||
}
|
||||
|
||||
|
||||
#endif /* MOZ_LDAP */
|
||||
#endif
|
||||
|
||||
69
mozilla/modules/rdf/src/ldap2rdf.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_LDAP2RDF_H_
|
||||
#define _RDF_LDAP2RDF_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
|
||||
#ifdef MOZ_LDAP
|
||||
#include "ldap.h"
|
||||
#include "xpgetstr.h"
|
||||
#include "htmldlgs.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* ldap2rdf.c data structures and defines */
|
||||
|
||||
#define ADMIN_ID "uid=rjc, ou=People, o=airius.com"
|
||||
#define ADMIN_PW "netscape"
|
||||
|
||||
|
||||
|
||||
/* ldap2rdf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
RDFT MakeLdapStore (char* url);
|
||||
RDF_Error LdapInit (RDFT ntr);
|
||||
void ldap2rdfInit (RDFT rdf);
|
||||
Assertion ldaparg1 (RDF_Resource u);
|
||||
Assertion setldaparg1 (RDF_Resource u, Assertion as);
|
||||
Assertion ldaparg2 (RDF_Resource u);
|
||||
Assertion setldaparg2 (RDF_Resource u, Assertion as);
|
||||
PRBool ldapAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool ldapUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ldapDBAdd (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ldapDBRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
PRBool ldapHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
void * ldapGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor ldapGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * ldapNextValue (RDFT mcf, RDF_Cursor c);
|
||||
RDF_Error ldapDisposeCursor (RDFT mcf, RDF_Cursor c);
|
||||
RDF_Resource ldapNewContainer(char *id);
|
||||
int ldapModifyEntry (RDFT rdf, RDF_Resource parent, RDF_Resource child, PRBool addFlag);
|
||||
PRBool ldapAddChild (RDFT rdf, RDF_Resource parent, RDF_Resource child);
|
||||
PRBool ldapRemoveChild (RDFT rdf, RDF_Resource parent, RDF_Resource child);
|
||||
void possiblyAccessldap(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
PRBool ldapContainerp (RDF_Resource u);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
52
mozilla/modules/rdf/src/makefile.win
Normal file
@@ -0,0 +1,52 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
DEPTH = ..\..\..
|
||||
LIBRARY_SUFFIX=$(MOZ_BITS)
|
||||
MAKE_OBJ_TYPE=DLL
|
||||
MODULE=rdf
|
||||
LIBRARY_NAME=rdf
|
||||
REQUIRES=nspr
|
||||
|
||||
C_OBJS=.\$(OBJDIR)\vocab.obj \
|
||||
.\$(OBJDIR)\mcf.obj \
|
||||
.\$(OBJDIR)\remstore.obj \
|
||||
.\$(OBJDIR)\utils.obj \
|
||||
.\$(OBJDIR)\rdfparse.obj \
|
||||
.\$(OBJDIR)\bmk2mcf.obj \
|
||||
.\$(OBJDIR)\columns.obj \
|
||||
.\$(OBJDIR)\rdfht.obj \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS=\
|
||||
.\$(OBJDIR)\comwrap.obj \
|
||||
.\$(OBJDIR)\netglue.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS=-I$(XPDIST)\public\xpcom
|
||||
LINCS=$(LINCS) -I$(PUBLIC)\rdf
|
||||
LINCS=$(LINCS) -I$(PUBLIC)\netlib -I$(PUBLIC)\raptor
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
|
||||
|
||||
|
||||
1125
mozilla/modules/rdf/src/mcf.c
Normal file
93
mozilla/modules/rdf/src/mcf.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_MCF_H_
|
||||
#define _RDF_MCF_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "prprf.h"
|
||||
#include "prtime.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* mcf.c data structures and defines */
|
||||
|
||||
struct RDF_NotificationStruct {
|
||||
RDF_Event theEvent;
|
||||
void* pdata;
|
||||
RDF_NotificationProc notifFunction;
|
||||
RDF rdf;
|
||||
struct RDF_NotificationStruct* next;
|
||||
};
|
||||
|
||||
|
||||
#define ntr(r, n) (*((RDFT*)r->translators + n))
|
||||
#define ntrn(r, n) (*((RDFT*)r->translators + n) == NULL)
|
||||
#define callAssert(n, r, u, s, v,type,tv) (ntrn(r, n) || (ntr(r, n)->assert == NULL) ? 0 : (*(ntr(r, n)->assert))(ntr(r, n), u, s, v, type, tv))
|
||||
#define callUnassert(n, r, u, s, v,type) (ntrn(r, n) || (ntr(r, n)->unassert == NULL) ? 0 : (*(ntr(r, n)->unassert))(ntr(r, n), u, s, v, type))
|
||||
#define callGetSlotValue(n, r, u, s, type, invp, tv) (ntrn(r, n) || (ntr(r, n)->getSlotValue == NULL) ? 0 : (*(ntr(r, n)->getSlotValue))(ntr(r, n), u, s, type, invp, tv))
|
||||
#define callGetSlotValues(n, r, u, s, type,invp, tv) (ntrn(r, n) || (ntr(r, n)->getSlotValues == NULL) ? 0 : (*(ntr(r, n)->getSlotValues))(ntr(r, n), u, s, type,invp, tv))
|
||||
#define callHasAssertions(n, r, u, s, v,type,tv) (ntrn(r, n) || (ntr(r, n)->hasAssertion == NULL) ? 0 : (*(ntr(r, n)->hasAssertion))(ntr(r, n), u, s, v, type, tv))
|
||||
#define callArcLabelsOut(n, r, u) (ntrn(r, n) || (ntr(r, n)->arcLabelsOut == NULL) ? 0 : (*(ntr(r, n)->arcLabelsOut))(ntr(r, n), u))
|
||||
#define callArcLabelsIn(n, r, u) (ntrn(r, n) || (ntr(r, n)->arcLabelsIn == NULL) ? 0 : (*(ntr(r, n)->arcLabelsIn))(ntr(r, n), u))
|
||||
#define callDisposeResource(n, r, u) (ntrn(r, n) || (ntr(r, n)->disposeResource == NULL) ? 1 : (*(ntr(r, n)->disposeResource))(ntr(r, n), u))
|
||||
#define callExitRoutine(n, r) (ntrn(r, n) || (ntr(r, n)->destroy == NULL) ? 0 : (*(ntr(r, n)->destroy))(ntr(r, n)))
|
||||
#define callUpdateRoutine(n, r, u) (ntrn(r, n) || (ntr(r, n)->update == NULL) ? 0 : (*(ntr(r, n)->update))(ntr(r, n), u))
|
||||
|
||||
#define ID_BUF_SIZE 20
|
||||
|
||||
|
||||
|
||||
/* mcf.c function prototypes */
|
||||
|
||||
|
||||
|
||||
RDFT getTranslator (char* url);
|
||||
RDFL deleteFromRDFList (RDFL xrl, RDF db);
|
||||
RDF_Error exitRDF (RDF rdf);
|
||||
RDF_Resource addDep (RDF db, RDF_Resource u);
|
||||
PRBool rdfassert(RDF rdf, RDF_Resource u, RDF_Resource s, void* value, RDF_ValueType type, PRBool tv);
|
||||
PRBool containerIDp(char* id);
|
||||
char * makeNewID ();
|
||||
PRBool iscontainerp (RDF_Resource u);
|
||||
RDF_BT resourceTypeFromID (char* id);
|
||||
RDF_Resource specialUrlResource (char* id);
|
||||
RDF_Resource NewRDFResource (char* id);
|
||||
RDF_Resource QuickGetResource (char* id);
|
||||
RDF_Cursor getSlotValues (RDF rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void disposeResourceInt (RDF rdf, RDF_Resource u);
|
||||
void possiblyGCResource (RDF_Resource u);
|
||||
RDF_Resource NewRDFResource (char* id);
|
||||
RDF_Resource QuickGetResource (char* id);
|
||||
void assertNotify (RDF rdf, RDF_Notification not, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv, char* ds);
|
||||
void insertNotify (RDF rdf, RDF_Notification not, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv, char* ds);
|
||||
void unassertNotify (RDF_Notification not, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, char* ds);
|
||||
void sendNotifications1 (RDFL rl, RDF_EventType opType, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
void sendNotifications (RDF rdf, RDF_EventType opType, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv, char* ds);
|
||||
RDF_Resource nextFindValue (RDF_Cursor c);
|
||||
PRBool matchStrings(RDF_Resource match, char *str1, char *str2);
|
||||
PRBool itemMatchesFind (RDF r, RDF_Resource u, RDF_Resource s, void* v, RDF_Resource match, RDF_ValueType type);
|
||||
PR_PUBLIC_API(RDF_Cursor)RDF_Find (RDF_Resource s, RDF_Resource match, void* v, RDF_ValueType type);
|
||||
PRIntn findEnumerator (PLHashEntry *he, PRIntn i, void *arg);
|
||||
void disposeAllDBs ();
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
374
mozilla/modules/rdf/src/mcff2mcf.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "mcff2mcf.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
|
||||
int
|
||||
parseNextMCFBlob(NET_StreamClass *stream, char* blob, int32 size)
|
||||
{
|
||||
RDFFile f;
|
||||
int32 n, last, m;
|
||||
n = last = 0;
|
||||
|
||||
f = (RDFFile)stream->data_object;
|
||||
if ((f == NULL) || (size < 0)) {
|
||||
return MK_INTERRUPTED;
|
||||
}
|
||||
|
||||
while (n < size) {
|
||||
char c = blob[n];
|
||||
m = 0;
|
||||
memset(f->line, '\0', f->lineSize);
|
||||
if (f->holdOver[0] != '\0') {
|
||||
memcpy(f->line, f->holdOver, RDF_STRLEN(f->holdOver));
|
||||
m = RDF_STRLEN(f->holdOver);
|
||||
memset(f->holdOver, '\0', RDF_BUF_SIZE);
|
||||
}
|
||||
while ((m < f->lineSize) && (c != '\r') && (c != '\n') && (n < size)) {
|
||||
f->line[m] = c;
|
||||
m++;
|
||||
n++;
|
||||
c = blob[n];
|
||||
}
|
||||
n++;
|
||||
if (m > 0) {
|
||||
if ((c == '\n') || (c == '\r')) {
|
||||
last = n;
|
||||
parseNextMCFLine(f, f->line);
|
||||
} else if (size > last) {
|
||||
memcpy(f->holdOver, f->line, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
parseNextMCFLine (RDFFile f, char* line)
|
||||
{
|
||||
char* nextToken ;
|
||||
int16 offset = 0;
|
||||
RDF_Error err;
|
||||
|
||||
if ((nullp(line)) || (line[0] == '\0'))return;
|
||||
nextToken = getMem(MAX_URL_SIZE);
|
||||
err = getFirstToken(line, nextToken, &offset);
|
||||
|
||||
offset++;
|
||||
if ((err != noRDFErr) && (nextToken[0] == ';')) {
|
||||
freeMem(nextToken);
|
||||
return;
|
||||
}
|
||||
if (startsWith("begin-headers", nextToken)) {
|
||||
f->status = HEADERS;
|
||||
} else if (startsWith("end-headers", nextToken)) {
|
||||
f->status = BODY;
|
||||
} else if (startsWith("unit", nextToken)) {
|
||||
f->status = BODY;
|
||||
if (!(nullp(f->currentResource))) resourceTransition(f);
|
||||
getFirstToken(&line[offset], nextToken, &offset);
|
||||
f->currentResource = resolveReference(nextToken, f);
|
||||
} else if (nextToken[RDF_STRLEN(nextToken)-1] == ':') {
|
||||
memset(f->currentSlot, '\0', 100);
|
||||
memcpy(f->currentSlot, nextToken, RDF_STRLEN(nextToken)-1);
|
||||
while (getFirstToken(&line[offset], nextToken, &offset) == noRDFErr) {
|
||||
if (f->status == HEADERS) {
|
||||
assignHeaderSlot(f, f->currentSlot, nextToken);
|
||||
} else if (f->currentResource) {
|
||||
assignSlot(f->currentResource, f->currentSlot, nextToken, f);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
freeMem(nextToken);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
finishMCFParse (RDFFile f)
|
||||
{
|
||||
parseNextMCFLine(f, f->storeAway);
|
||||
resourceTransition(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
resourceTransition (RDFFile f)
|
||||
{
|
||||
if ((f->currentResource) && (!f->genlAdded))
|
||||
addSlotValue(f, f->currentResource, gCoreVocab->RDF_parent, f->rtop,
|
||||
RDF_RESOURCE_TYPE, NULL);
|
||||
f->genlAdded = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
assignHeaderSlot (RDFFile f, char* slot, char* value)
|
||||
{
|
||||
if (startsWith(slot, "expiresOn")) {
|
||||
if (f->expiryTime == NULL) f->expiryTime = (PRTime*)getMem(sizeof(PRTime));
|
||||
if (PR_ParseTimeString (value, 0, f->expiryTime) != PR_SUCCESS) {
|
||||
freeMem(f->expiryTime);
|
||||
f->expiryTime = NULL;
|
||||
}
|
||||
} else if (!(startsWith(slot, "RDFVersion"))) {
|
||||
assignSlot(f->top, slot, value, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
getFirstToken (char* line, char* nextToken, int16* l)
|
||||
{
|
||||
PRBool in_paren = 0;
|
||||
PRBool in_string = 0;
|
||||
PRBool in_bracket = 0;
|
||||
PRBool something_seen = 0;
|
||||
uint16 front_spaces = 0;
|
||||
uint16 index;
|
||||
RDF_Error ans = -1;
|
||||
|
||||
memset(nextToken, '\0', 200);
|
||||
|
||||
for (index = 0; index < RDF_STRLEN(line); index++) {
|
||||
char c = line[index];
|
||||
|
||||
if ((c == '\n') || (c == '\0') || (c == '\r')) {
|
||||
*l = index + *l ;
|
||||
return ans;
|
||||
}
|
||||
|
||||
if ((c == ':') && ((index == 0) || (line[index-1] == ' ')) &&
|
||||
((line[index+1] == ' ') || (line[index+1] == '\0'))) c = ' ';
|
||||
|
||||
if (c != ' ') something_seen = 1;
|
||||
|
||||
if (in_paren) {
|
||||
if (c == ')') {
|
||||
nextToken[index-front_spaces] = c;
|
||||
ans = noRDFErr;
|
||||
*l = index + *l ;
|
||||
return ans;
|
||||
} else {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
}
|
||||
} else if (in_string) {
|
||||
if (c == '"') {
|
||||
nextToken[index-front_spaces] = c;
|
||||
ans = noRDFErr;
|
||||
*l = index + *l ;
|
||||
return ans;
|
||||
} else {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
}
|
||||
} else if (in_bracket) {
|
||||
if (c == ']') {
|
||||
nextToken[index-front_spaces] = c;
|
||||
*l = index + *l ;
|
||||
ans = noRDFErr;
|
||||
return ans;
|
||||
} else {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
}
|
||||
} else if (c == '"') {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
in_string = 1;
|
||||
} else if (c == '[') {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
in_bracket = 1;
|
||||
} else if (c == '(') {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
in_paren = 1;
|
||||
} else if (c == ' '){
|
||||
if (something_seen) {
|
||||
*l = index + *l ;
|
||||
return ans;
|
||||
} else {
|
||||
front_spaces++;
|
||||
}
|
||||
} else {
|
||||
ans = noRDFErr;
|
||||
nextToken[index-front_spaces] = c;
|
||||
}
|
||||
}
|
||||
*l = index + *l ;
|
||||
return ans;
|
||||
}
|
||||
|
||||
void
|
||||
assignSlot (RDF_Resource u, char* slot, char* value, RDFFile f)
|
||||
{
|
||||
PRBool tv = true;
|
||||
char* tvstr;
|
||||
if (value[0] == '(') {
|
||||
tv = false;
|
||||
value = &value[1];
|
||||
value[RDF_STRLEN(value)-1] = '\0';
|
||||
}
|
||||
|
||||
if (tv) {
|
||||
tvstr = "true";
|
||||
} else tvstr = "false";
|
||||
|
||||
if (startsWith("default_genl", slot)) return;
|
||||
|
||||
if (startsWith("name", slot) || (startsWith("local-name", slot))) {
|
||||
value[RDF_STRLEN(value)-1] = '\0';
|
||||
addSlotValue(f, u, gCoreVocab->RDF_name, copyString(&value[1]), RDF_STRING_TYPE, tvstr);
|
||||
} else if (startsWith("specs", slot) || (startsWith("child", slot))) {
|
||||
RDF_Resource spec = resolveReference(value, f);
|
||||
if (!nullp(spec)) addSlotValue(f, spec, gCoreVocab->RDF_parent, u, RDF_RESOURCE_TYPE, tvstr);
|
||||
} else if (startsWith("genls_pos", slot)) {
|
||||
RDF_Resource genl = resolveGenlPosReference(value, f);
|
||||
if (!nullp(genl)) addSlotValue(f, u, gCoreVocab->RDF_parent, genl, RDF_RESOURCE_TYPE, tvstr);
|
||||
} else if ((startsWith("genls", slot)) || (startsWith("parent", slot))) {
|
||||
RDF_Resource genl = resolveReference(value, f);
|
||||
if (!nullp(genl)) addSlotValue(f, u, gCoreVocab->RDF_parent, genl, RDF_RESOURCE_TYPE, tvstr);
|
||||
} else {
|
||||
void* parsed_value;
|
||||
RDF_ValueType data_type;
|
||||
RDF_Resource s = RDF_GetResource(NULL, slot, true);
|
||||
RDF_Error err = parseSlotValue(f, s, value, &parsed_value, &data_type);
|
||||
if ((err == noRDFErr) && (!nullp(parsed_value)))
|
||||
addSlotValue(f, u, s, parsed_value, data_type, tvstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
parseSlotValue (RDFFile f, RDF_Resource s, char* value, void** parsed_value, RDF_ValueType* data_type)
|
||||
{
|
||||
if (value[0] == '"') {
|
||||
int32 size = RDF_STRLEN(value)-1;
|
||||
*parsed_value = getMem(size);
|
||||
value[size] = '\0';
|
||||
*parsed_value = &value[1];
|
||||
*data_type = RDF_STRING_TYPE;
|
||||
return noRDFErr;
|
||||
} else if (value[0] == '#') {
|
||||
if (value[1] == '"') {
|
||||
value[RDF_STRLEN(value)-1] = '\0';
|
||||
value = &value[2];
|
||||
} else {
|
||||
value = &value[1];
|
||||
}
|
||||
*parsed_value = resolveReference(value, f);
|
||||
return noRDFErr;
|
||||
} else if (charSearch('.', value) == -1) {
|
||||
int16 ans = 0;
|
||||
/* XXX sscanf(value, "%ld", &ans); */
|
||||
*data_type = RDF_INT_TYPE;
|
||||
return noRDFErr;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
derelativizeURL (char* tok, char* url, RDFFile f)
|
||||
{
|
||||
if ((tok[0] == '/') && (endsWith(".mco", tok))) {
|
||||
void stringAppendBase (char* dest, const char* addition) ;
|
||||
stringAppendBase(url, f->url);
|
||||
stringAppend(url, "#");
|
||||
stringAppend(url, tok);
|
||||
} else if ((endsWith(".mco", tok)) && (charSearch('#', tok) == -1)) {
|
||||
void stringAppendBase (char* dest, const char* addition) ;
|
||||
stringAppendBase(url, f->url);
|
||||
stringAppend(url, "#");
|
||||
stringAppend(url, tok);
|
||||
} else {
|
||||
memcpy(url, tok, RDF_STRLEN(tok));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
resolveReference (char *tok, RDFFile f)
|
||||
{
|
||||
RDF_Resource existing;
|
||||
char* url = getMem(MAX_URL_SIZE);
|
||||
if (tok[0] == '#') tok = &tok[1];
|
||||
if (tok[RDF_STRLEN(tok)-1] == '"') tok[strlen(tok)-1] = '\0';
|
||||
if (tok[0] == '"') tok = &tok[1];
|
||||
memset(url, '\0', 200);
|
||||
if (charSearch(':', tok) == -1) {
|
||||
derelativizeURL(tok, url, f);
|
||||
} else {
|
||||
memcpy(url, tok, RDF_STRLEN(tok));
|
||||
}
|
||||
if (RDF_STRCMP(url,"this") == 0) {
|
||||
existing = f->top;
|
||||
} else {
|
||||
existing = RDF_GetResource(NULL, url, false);
|
||||
}
|
||||
if (existing != null) return existing;
|
||||
existing = RDF_GetResource(NULL, url, true);
|
||||
addToResourceList(f, existing);
|
||||
freeMem(url);
|
||||
return existing;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
resolveGenlPosReference(char* tok, RDFFile f)
|
||||
{
|
||||
RDF_Resource ans;
|
||||
char* url = (char*)getMem(MAX_URL_SIZE);
|
||||
long i1, i2;
|
||||
i1 = charSearch('"', tok);
|
||||
i2 = revCharSearch('"', tok);
|
||||
memcpy(url, &tok[i1], i2-i1+1);
|
||||
ans = resolveReference(url, f);
|
||||
freeMem(url);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
getRelURL (RDF_Resource u, RDF_Resource top)
|
||||
{
|
||||
char* uID = resourceID(u);
|
||||
char* topID = resourceID(top);
|
||||
if (startsWith(topID, uID)) {
|
||||
int16 n = charSearch('#', uID);
|
||||
if (n == -1) return uID;
|
||||
return &(uID)[n+1];
|
||||
} else return uID;
|
||||
}
|
||||
61
mozilla/modules/rdf/src/mcff2mcf.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_MCFF2MCF_H_
|
||||
#define _RDF_MCFF2MCF_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
|
||||
|
||||
|
||||
/* mcff2mcf.c data structures and defines */
|
||||
|
||||
|
||||
|
||||
|
||||
/* mcff2mcf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
RDF_Resource getMCFFrtop (char* furl);
|
||||
RDFFile makeRDFFile (char* url, RDF_Resource top, PRBool localp);
|
||||
void initRDFFile (RDFFile ans);
|
||||
void finishRDFParse (RDFFile f);
|
||||
void abortRDFParse (RDFFile f);
|
||||
void addToResourceList (RDFFile f, RDF_Resource u);
|
||||
void addToAssertionList (RDFFile f, Assertion as);
|
||||
void parseNextRDFBlob (RDFFile f, char* blob, int32 size);
|
||||
int parseNextMCFBlob(NET_StreamClass *stream, char* blob, int32 size);
|
||||
void parseNextMCFLine (RDFFile f, char* line);
|
||||
void finishMCFParse (RDFFile f);
|
||||
void resourceTransition (RDFFile f);
|
||||
void assignHeaderSlot (RDFFile f, char* slot, char* value);
|
||||
RDF_Error getFirstToken (char* line, char* nextToken, int16* l);
|
||||
|
||||
void assignSlot (RDF_Resource u, char* slot, char* value, RDFFile f);
|
||||
RDF_Error parseSlotValue (RDFFile f, RDF_Resource s, char* value, void** parsed_value, RDF_ValueType* data_type);
|
||||
void derelativizeURL (char* tok, char* url, RDFFile f);
|
||||
RDF_Resource resolveReference (char *tok, RDFFile f);
|
||||
RDF_Resource resolveGenlPosReference(char* tok, RDFFile f);
|
||||
char * getRelURL (RDF_Resource u, RDF_Resource top);
|
||||
PRBool bookmarkSlotp (RDF_Resource s);
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
165
mozilla/modules/rdf/src/netglue.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsString.h"
|
||||
#include "rdf-int.h"
|
||||
|
||||
class rdfStreamListener : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
rdfStreamListener(RDFFile);
|
||||
~rdfStreamListener();
|
||||
|
||||
NS_METHOD GetBindInfo(nsIURL* aURL);
|
||||
|
||||
NS_METHOD OnProgress(nsIURL* aURL, PRInt32 Progress, PRInt32 ProgressMax);
|
||||
|
||||
NS_METHOD OnStatus(nsIURL* aURL, const nsString& aMsg);
|
||||
|
||||
NS_METHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
|
||||
|
||||
NS_METHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *pIStream, PRInt32 length);
|
||||
|
||||
NS_METHOD OnStopBinding(nsIURL* aURL, PRInt32 status, const nsString& aMsg);
|
||||
|
||||
protected:
|
||||
rdfStreamListener::rdfStreamListener();
|
||||
|
||||
private:
|
||||
RDFFile mFile;
|
||||
};
|
||||
|
||||
rdfStreamListener::rdfStreamListener(RDFFile f) : mFile(f)
|
||||
{
|
||||
}
|
||||
|
||||
rdfStreamListener::~rdfStreamListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::GetBindInfo(nsIURL* aURL)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::OnProgress(nsIURL* aURL,
|
||||
PRInt32 Progress,
|
||||
PRInt32 ProgressMax)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::OnStatus(nsIURL* aURL,
|
||||
const nsString& aMsg)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::OnStartBinding(nsIURL* aURL,
|
||||
const char *aContentType)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::OnDataAvailable(nsIURL* aURL,
|
||||
nsIInputStream *pIStream,
|
||||
PRInt32 length)
|
||||
{
|
||||
PRInt32 len;
|
||||
|
||||
// PRLOG(("\n+++ rdfStreamListener::OnDataAvailable: URL: %p, %d bytes available...\n", aURL, length));
|
||||
|
||||
do {
|
||||
const PRUint32 buffer_size = 80;
|
||||
char buffer[buffer_size];
|
||||
|
||||
nsresult err = pIStream->Read(buffer, 0, buffer_size, &len);
|
||||
if (err == NS_OK) {
|
||||
(void) parseNextRDFXMLBlobInt(mFile, buffer, len);
|
||||
} // else XXX ?
|
||||
} while (len > 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
rdfStreamListener::OnStopBinding(nsIURL* aURL,
|
||||
PRInt32 status,
|
||||
const nsString& aMsg)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
switch( status ) {
|
||||
|
||||
case NS_BINDING_SUCCEEDED:
|
||||
finishRDFParse( mFile );
|
||||
break;
|
||||
|
||||
case NS_BINDING_FAILED:
|
||||
case NS_BINDING_ABORTED:
|
||||
abortRDFParse( mFile );
|
||||
// XXX status code?
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_ASSERT(PR_FALSE);
|
||||
result = NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* beginReadingRDFFile is called whenever we need to read something of
|
||||
* the net (or local drive). The url of the file to be read is at
|
||||
* file->url. As the bits are read in (and it can take the bits in
|
||||
* any sized chunks) it should call parseNextRDFBlobInt(file, nextBlock,
|
||||
* blobSize) when its done, it should call void finishRDFParse
|
||||
* (RDFFile f) to abort, it should call void abortRDFParse (RDFFile f)
|
||||
* [which will undo all that has been read from that file]
|
||||
*/
|
||||
|
||||
void
|
||||
beginReadingRDFFile (RDFFile file)
|
||||
{
|
||||
rdfStreamListener* pListener = new rdfStreamListener(file);
|
||||
pListener->AddRef(); // XXX is this evil? Can't see any reason to use factories but...
|
||||
nsIURL* pURL = NULL;
|
||||
nsString url_address( file->url );
|
||||
nsresult r = NS_NewURL( &pURL, url_address );
|
||||
if( NS_OK != r ) {
|
||||
// XXX what to do?
|
||||
}
|
||||
|
||||
r = pURL->Open(pListener);
|
||||
if( NS_OK != r ) {
|
||||
// XXX what to do?
|
||||
}
|
||||
|
||||
}
|
||||
829
mozilla/modules/rdf/src/nlcstore.c
Normal file
@@ -0,0 +1,829 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements local store support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#include "nlcstore.h"
|
||||
#include "glue.h"
|
||||
#include "mcf.h"
|
||||
#include "xpassert.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/* globals */
|
||||
PRBool doingFirstTimeInitp = 0;
|
||||
RDFT gOPSStore = 0;
|
||||
|
||||
|
||||
|
||||
/* externs */
|
||||
extern char *profileDirURL;
|
||||
extern char *gBookmarkURL;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
To do : killing a unit
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
compareUnalignedUINT32Ptrs(void *v1, void *v2)
|
||||
{
|
||||
uint32 val1, val2;
|
||||
|
||||
memcpy(&val1,v1,sizeof(uint32));
|
||||
memcpy(&val2,v2,sizeof(uint32));
|
||||
return((val1==val2) ? PR_TRUE:PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
DBM_OpenDBMStore (DBMRDF store, char* directory)
|
||||
{
|
||||
HASHINFO hash_info = {128, 0, 0, 0, 0, 0};
|
||||
PRBool createp = 0;
|
||||
char* dbPathname;
|
||||
char* dirPathname;
|
||||
CHECK_VAR1(profileDirURL);
|
||||
dirPathname = makeDBURL(directory);
|
||||
CallPRMkDirUsingFileURL(dirPathname, 00700);
|
||||
freeMem(dirPathname);
|
||||
|
||||
dbPathname = makeRDFDBURL(directory, "names.db");
|
||||
CHECK_VAR1(dbPathname);
|
||||
store->nameDB = CallDBOpenUsingFileURL(dbPathname, O_RDWR, 0644, DB_HASH, &hash_info);
|
||||
if (store->nameDB == NULL) {
|
||||
createp = 1;
|
||||
store->nameDB = CallDBOpenUsingFileURL(dbPathname, O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
|
||||
}
|
||||
freeMem(dbPathname);
|
||||
CHECK_VAR1(store->nameDB);
|
||||
dbPathname = makeRDFDBURL(directory, "child.db");
|
||||
CHECK_VAR1(dbPathname);
|
||||
hash_info.bsize = 2056;
|
||||
store->childrenDB = CallDBOpenUsingFileURL(dbPathname,
|
||||
O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
|
||||
freeMem(dbPathname);
|
||||
CHECK_VAR1(store->childrenDB);
|
||||
|
||||
dbPathname = makeRDFDBURL(directory, "lstr.db");
|
||||
hash_info.bsize = 1024 ;
|
||||
store->propDB = CallDBOpenUsingFileURL(dbPathname,
|
||||
O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
|
||||
freeMem(dbPathname);
|
||||
CHECK_VAR1(store->propDB);
|
||||
|
||||
dbPathname = makeRDFDBURL(directory, "ilstr.db");
|
||||
CHECK_VAR1(dbPathname);
|
||||
hash_info.bsize = 1024*16;
|
||||
store->invPropDB = CallDBOpenUsingFileURL(dbPathname,
|
||||
O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
|
||||
freeMem(dbPathname);
|
||||
CHECK_VAR1(store->invPropDB);
|
||||
|
||||
if (RDF_STRCMP(directory, "NavCen") == 0) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
DBM_CloseRDFDBMStore (RDFT r)
|
||||
{
|
||||
|
||||
DBMRDF db = (DBMRDF)r->pdata;
|
||||
if (r->rdf) return 0;
|
||||
if (db->nameDB != NULL) (*db->nameDB->close)(db->nameDB);
|
||||
if (db->childrenDB != NULL) (*db->childrenDB->close)(db->childrenDB);
|
||||
if (db->propDB != NULL) (*db->propDB->close)(db->propDB);
|
||||
if (db->invPropDB != NULL) (*db->invPropDB->close)(db->invPropDB);
|
||||
freeMem(db);
|
||||
r->pdata = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
makeUSKey (RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size)
|
||||
{
|
||||
if ((s == gCoreVocab->RDF_name) || (inversep && (s == gCoreVocab->RDF_parent))) {
|
||||
*size = RDF_STRLEN(resourceID(u));
|
||||
return resourceID(u);
|
||||
} else {
|
||||
char* ans;
|
||||
*size = RDF_STRLEN(resourceID(u)) + strlen(resourceID(s));
|
||||
ans = getMem(*size);
|
||||
memcpy(ans, resourceID(u), RDF_STRLEN(resourceID(u)));
|
||||
memcpy(&ans[RDF_STRLEN(resourceID(u))], resourceID(s), strlen(resourceID(s)));
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
DB *
|
||||
getUSDB (RDFT r, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
DBMRDF db = (DBMRDF)r->pdata;
|
||||
if (inversep) {
|
||||
if (s == gCoreVocab->RDF_parent) {
|
||||
return db->childrenDB;
|
||||
} else {
|
||||
return db->invPropDB;
|
||||
}
|
||||
} else if (s == gCoreVocab->RDF_name) {
|
||||
return db->nameDB;
|
||||
} else return db->propDB;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
freeKey (char* keyData, RDF_Resource u, RDF_Resource s, PRBool inversep)
|
||||
{
|
||||
if ((s == gCoreVocab->RDF_name) || (inversep && (s == gCoreVocab->RDF_parent))) return;
|
||||
freeMem(keyData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DBMAs *
|
||||
DBM_GetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size)
|
||||
{
|
||||
size_t keySize;
|
||||
void* keyData = makeUSKey(u, s, inversep, &keySize);
|
||||
DBT key, data;
|
||||
DB *db;
|
||||
int status;
|
||||
CHECK_VAR(keyData, NULL);
|
||||
key.data = keyData;
|
||||
key.size = keySize;
|
||||
db = getUSDB(rdf, u, s, inversep);
|
||||
if (db == NULL) {
|
||||
*size = 0;
|
||||
freeKey(keyData, u, s, inversep);
|
||||
return NULL;
|
||||
}
|
||||
status = (*db->get)(db, &key, &data, 0);
|
||||
if (status != 0) {
|
||||
*size = 0;
|
||||
freeKey(keyData, u, s, inversep);
|
||||
return NULL;
|
||||
} else {
|
||||
void* ans = (char*)getMem(data.size);
|
||||
*size = data.size;
|
||||
memcpy(ans, data.data, *size);
|
||||
freeKey(keyData, u, s, inversep);
|
||||
return (DBMAs*) ans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DBM_PutSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, void* value, size_t size)
|
||||
{
|
||||
size_t keySize;
|
||||
void* keyData = makeUSKey(u, s, inversep, &keySize);
|
||||
DBT key, data;
|
||||
int status;
|
||||
DB* db;
|
||||
CHECK_VAR1(keyData);
|
||||
db = getUSDB(rdf, u, s, inversep);
|
||||
if (db == NULL) {
|
||||
freeKey(keyData, u, s, inversep);
|
||||
return ;
|
||||
}
|
||||
key.data = keyData;
|
||||
key.size = keySize;
|
||||
data.data = value;
|
||||
data.size = size;
|
||||
status = (*db->del)(db, &key, 0);
|
||||
if (value != NULL) {
|
||||
status = (*db->put)(db, &key, &data, 0);
|
||||
}
|
||||
if ((status == 0) && (!doingFirstTimeInitp)) (*db->sync)(db, 0);
|
||||
freeKey(keyData, u, s, inversep);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nlocalStoreHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs *data;
|
||||
uint16 n = 0;
|
||||
PRBool ans = 0;
|
||||
PRBool invp = (s == gCoreVocab->RDF_parent);
|
||||
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
data = (invp ? DBM_GetSlotValue(rdf, (RDF_Resource)v, s, 1, &size) :
|
||||
DBM_GetSlotValue(rdf, u, s, 0, &size));
|
||||
if (data == NULL) return 0;
|
||||
while (n < size) {
|
||||
DBMAs nas = nthdbmas(data, n);
|
||||
if (nas == NULL) break;
|
||||
if ((type == valueTypeOfAs(nas)) && (tvOfAs(nas) == tv) &&
|
||||
(invp ? valueEqual(type, dataOfDBMAs(nas), u) : valueEqual(type, dataOfDBMAs(nas), v))) {
|
||||
ans = 1;
|
||||
break;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
freeMem(data);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
nlocalStoreGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type, PRBool inversep, PRBool tv)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs *data;
|
||||
uint16 n = 0;
|
||||
void* ans;
|
||||
data = DBM_GetSlotValue(rdf, u, s, inversep, &size);
|
||||
if (data == NULL) return 0;
|
||||
while (n < size) {
|
||||
DBMAs nas = nthdbmas(data, n);
|
||||
if (nas == NULL) break;
|
||||
if (type == valueTypeOfAs(nas)) {
|
||||
if (type == RDF_STRING_TYPE) {
|
||||
ans = copyString((char *)dataOfDBMAs(nas));
|
||||
} else if (type == RDF_RESOURCE_TYPE) {
|
||||
ans = RDF_GetResource(NULL, (char *)dataOfDBMAs(nas), true);
|
||||
} else if (type == RDF_INT_TYPE) {
|
||||
/* ans = dataOfDBMAs(nas); */
|
||||
memcpy((char*)&ans, dataOfDBMAs(nas), sizeof(uint32));
|
||||
}
|
||||
freeMem(data);
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )ans)));
|
||||
return ans;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
freeMem((void*)data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
nlocalStoreGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s,
|
||||
RDF_ValueType type,
|
||||
PRBool inversep, PRBool tv)
|
||||
{
|
||||
RDF_Cursor c;
|
||||
void* val;
|
||||
size_t size;
|
||||
if (resourceType(u) == LFS_RT) return NULL;
|
||||
if (!tv && (s != gCoreVocab->RDF_parent)) return NULL;
|
||||
val = DBM_GetSlotValue(rdf, u, s, inversep, &size);
|
||||
if (val == NULL) return NULL;
|
||||
c = (RDF_Cursor) getMem(sizeof(struct RDF_CursorStruct));
|
||||
if (c == NULL) {
|
||||
freeMem(val);
|
||||
return NULL;
|
||||
}
|
||||
c->u = u;
|
||||
c->s = s;
|
||||
c->inversep = inversep;
|
||||
c->type = type;
|
||||
c->tv = tv;
|
||||
c->count = 0;
|
||||
c->pdata = val;
|
||||
c->size = size;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
nlocalStoreNextValue (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
void* ans;
|
||||
void* data;
|
||||
if ((c == NULL) || (c->pdata == NULL)) return NULL;
|
||||
if ((c->type == RDF_ARC_LABELS_IN_QUERY) || (c->type == RDF_ARC_LABELS_OUT_QUERY))
|
||||
return nlcStoreArcsInOutNextValue(rdf, c);
|
||||
data = c->pdata;
|
||||
while (c->count < c->size) {
|
||||
DBMAs nas = nthdbmas(data, c->count);
|
||||
if (nas == NULL) break;
|
||||
if ((c->tv == tvOfAs(nas)) && (c->type == valueTypeOfAs(nas))) {
|
||||
if (c->type == RDF_RESOURCE_TYPE) {
|
||||
RDF_Resource nu = RDF_GetResource(NULL, (char *)dataOfDBMAs(nas), 1);
|
||||
|
||||
if (nu && startsWith("http:", resourceID(nu)) && strstr(resourceID(nu), ".rdf")) {
|
||||
RDFL rl = rdf->rdf;
|
||||
char* dburl = getBaseURL(resourceID(nu));
|
||||
while (rl) {
|
||||
RDF_AddDataSource(rl->rdf, dburl);
|
||||
rl = rl->next;
|
||||
}
|
||||
freeMem(dburl);
|
||||
}
|
||||
|
||||
ans = nu;
|
||||
c->count = dbmasSize(nas) + c->count;
|
||||
return nu;
|
||||
} else {
|
||||
ans = dataOfDBMAs(nas);
|
||||
c->count = dbmasSize(nas) + c->count;
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
c->count = dbmasSize(nas) + c->count;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
nlocalStoreDisposeCursor (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
if (c != NULL) {
|
||||
if (c->pdata) freeMem(c->pdata);
|
||||
c->pdata = NULL;
|
||||
freeMem(c);
|
||||
}
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DBMAs
|
||||
makeAsBlock (void* v, RDF_ValueType type, PRBool tv, size_t *size)
|
||||
{
|
||||
size_t vsize=0;
|
||||
DBMAs ans;
|
||||
int rem = 0;
|
||||
/*
|
||||
ldiv_t cdiv ;
|
||||
*/
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if (type == RDF_STRING_TYPE) {
|
||||
vsize = RDF_STRLEN(v);
|
||||
} else if (type == RDF_RESOURCE_TYPE) {
|
||||
vsize = RDF_STRLEN( resourceID((RDF_Resource)v));
|
||||
} else if (type == RDF_INT_TYPE) {
|
||||
vsize = 4;
|
||||
}
|
||||
*size = 4 + vsize + 1;
|
||||
rem = *size % 4;
|
||||
if (rem) {
|
||||
*size += 4 - rem;
|
||||
}
|
||||
ans = (DBMAs) getMem(*size);
|
||||
if (ans == NULL) return NULL;
|
||||
ans->size[0] = (uint8)(((*size) & 0x00FF0000) >> 16);
|
||||
ans->size[1] = (uint8)(((*size) & 0x0000FF00) >> 8);
|
||||
ans->size[2] = (uint8)((*size) & 0x000000FF);
|
||||
*(((unsigned char *)ans)+3) = (tv ? 0x10 : 0) | (type & 0x0F);
|
||||
if (type == RDF_STRING_TYPE) {
|
||||
memcpy((char*)ans+4, (char*) v, vsize);
|
||||
} else if (type == RDF_RESOURCE_TYPE) {
|
||||
memcpy((char*)ans+4, resourceID((RDF_Resource)v), vsize);
|
||||
} else if (type == RDF_INT_TYPE) {
|
||||
memcpy((char*)ans+4, (char*)v, vsize);
|
||||
}
|
||||
/*
|
||||
cdiv = ldiv(*size, 256);
|
||||
ans->size[0] = (uint8)(cdiv.quot);
|
||||
ans->size[1] = (uint8)(cdiv.rem);
|
||||
ans->tag = (tv ? 0x10 : 0) | (type & 0x0F);
|
||||
if (type == RDF_STRING_TYPE) {
|
||||
memcpy((char*)ans+3, (char*) v, vsize);
|
||||
} else if (type == RDF_RESOURCE_TYPE) {
|
||||
memcpy((char*)ans+3, resourceID((RDF_Resource)v), vsize);
|
||||
} else if (type == RDF_INT_TYPE) {
|
||||
memcpy((char*)ans+3, (char*)v, vsize);
|
||||
}
|
||||
*/
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nlocalStoreAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs* data;
|
||||
char* ndata;
|
||||
DBMAs temp;
|
||||
uint16 n = 0;
|
||||
size_t tsize;
|
||||
PRBool ans = 0;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
|
||||
/* don't store RDF Commands in the local store */
|
||||
if (s == gNavCenter->RDF_Command) return 0;
|
||||
|
||||
data = DBM_GetSlotValue(rdf, u, s, 0, &size);
|
||||
if (((data == NULL) && (size != 0)) || ((size == 0) && (data != NULL))) return 0;
|
||||
while (n < size) {
|
||||
DBMAs nas = nthdbmas(data, n);
|
||||
if (nas == NULL) {freeMem(data); return 0;}
|
||||
if (type == valueTypeOfAs(nas) && (valueEqual(type, dataOfDBMAs(nas), v))) {
|
||||
ans = 1;
|
||||
break;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
if (ans) {
|
||||
freeMem(data);
|
||||
return 1;
|
||||
} else {
|
||||
temp = makeAsBlock(v, type, tv, &tsize);
|
||||
if (temp == NULL) {freeMem(data);return 0;}
|
||||
if (data == NULL) {
|
||||
DBM_PutSlotValue(rdf, u, s, 0, (void*)temp, tsize);
|
||||
/* addSlotsHere(rdf, u, s); */
|
||||
freeMem(temp);
|
||||
temp = NULL;
|
||||
} else {
|
||||
ndata = (char*)getMem(size + tsize);
|
||||
if (ndata == NULL) {freeMem(data); freeMem(temp);return 0;}
|
||||
memcpy(ndata, data, size);
|
||||
memcpy(&ndata[size], (char*)temp, tsize);
|
||||
DBM_PutSlotValue(rdf, u,s, 0, ndata, size+tsize);
|
||||
freeMem(data);
|
||||
freeMem(ndata);
|
||||
freeMem(temp);
|
||||
}
|
||||
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
temp = makeAsBlock(u, RDF_RESOURCE_TYPE, tv, &tsize);
|
||||
if (temp == NULL) return 0;
|
||||
data = DBM_GetSlotValue(rdf, (RDF_Resource)v, s, 1, &size);
|
||||
if (data == NULL) {
|
||||
DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, (void*) temp, tsize);
|
||||
freeMem(temp);
|
||||
/* addSlotsIn(rdf, (RDF_Resource)v, s);*/
|
||||
} else {
|
||||
ndata = (char*)getMem(size + tsize);
|
||||
if (ndata == NULL) {freeMem(data); freeMem(temp);return 0;}
|
||||
memcpy(ndata, data, size);
|
||||
memcpy(&ndata[size], (char*)temp, tsize);
|
||||
DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, ndata, size+tsize);
|
||||
freeMem(data);
|
||||
freeMem(ndata);
|
||||
freeMem(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
sendNotifications2(rdf, RDF_INSERT_NOTIFY, u, s, v, type, tv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nlocalStoreAssert1 (RDFFile f, RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
return nlocalStoreAssert(rdf, u, s, v, type, tv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nlocalStoreUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs* data;
|
||||
char* temp;
|
||||
uint16 n = 0;
|
||||
size_t tsize;
|
||||
PRBool ans = 0;
|
||||
DBMAs nas;
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
data = DBM_GetSlotValue(rdf, u, s, 0, &size);
|
||||
if (data == NULL) return 1;
|
||||
while (n < size) {
|
||||
nas = nthdbmas(data, n);
|
||||
if (type == valueTypeOfAs(nas) && (valueEqual(type, dataOfDBMAs(nas), v))) {
|
||||
ans = 1;
|
||||
break;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
if (!ans) {
|
||||
freeMem(data);
|
||||
return 1;
|
||||
} else {
|
||||
if (size == dbmasSize(nas)) {
|
||||
DBM_PutSlotValue(rdf, u, s, 0, NULL, 0);
|
||||
/*deleteSlotsHere(rdf, u, s);*/
|
||||
} else {
|
||||
tsize = size - dbmasSize(nas);
|
||||
temp = (char*)getMem(tsize);
|
||||
if (temp == NULL) {
|
||||
freeMem(data);
|
||||
return 0;
|
||||
}
|
||||
if (n != 0) memcpy(temp, data, n);
|
||||
memcpy(((char*)temp+n), ((char*)data + n + dbmasSize(nas)), tsize-n);
|
||||
DBM_PutSlotValue(rdf, u, s, 0, temp, tsize);
|
||||
freeMem(temp);
|
||||
}
|
||||
freeMem(data);
|
||||
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
data = DBM_GetSlotValue(rdf, ((RDF_Resource)v), s, 1, &size);
|
||||
ans = n = 0;
|
||||
if (data == NULL) {
|
||||
return 1;
|
||||
} else {
|
||||
while (n < size) {
|
||||
nas = nthdbmas(data, n);
|
||||
if (valueEqual(RDF_RESOURCE_TYPE, dataOfDBMAs(nas), u)){
|
||||
ans = 1;
|
||||
break;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
if (!ans) {
|
||||
return 1;
|
||||
} else {
|
||||
if (size == dbmasSize(nas)) {
|
||||
DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, NULL, 0);
|
||||
/* deleteSlotsIn(rdf, (RDF_Resource)v, s); */
|
||||
} else {
|
||||
tsize = size - dbmasSize(nas);
|
||||
temp = (char*)getMem(tsize);
|
||||
if (temp == NULL) {
|
||||
freeMem(data);
|
||||
return 0;
|
||||
}
|
||||
if (n) memcpy(temp, data, n);
|
||||
memcpy(((char*)temp+n), ((char*)data + n + dbmasSize(nas)), tsize-n);
|
||||
DBM_PutSlotValue(rdf, ((RDF_Resource)v), s, 1, temp, tsize);
|
||||
freeMem(temp);
|
||||
}
|
||||
freeMem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sendNotifications2(rdf, RDF_DELETE_NOTIFY, u, s, v, type, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
addSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s)
|
||||
{
|
||||
if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) &&
|
||||
(s != gCoreVocab->RDF_slotsHere) && (s != gCoreVocab->RDF_slotsIn)) {
|
||||
nlocalStoreAssert (rdf, u, gCoreVocab->RDF_slotsHere, s, RDF_RESOURCE_TYPE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
deleteSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s)
|
||||
{
|
||||
if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) &&
|
||||
(s != gCoreVocab->RDF_slotsHere) && (s != gCoreVocab->RDF_slotsIn)) {
|
||||
nlocalStoreUnassert (rdf, u, gCoreVocab->RDF_slotsHere, s, RDF_RESOURCE_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
addSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s)
|
||||
{
|
||||
if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) &&
|
||||
(s != gCoreVocab->RDF_slotsHere) && (s != gCoreVocab->RDF_slotsIn)) {
|
||||
nlocalStoreAssert (rdf, u, gCoreVocab->RDF_slotsIn, s, RDF_RESOURCE_TYPE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
deleteSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s)
|
||||
{
|
||||
if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) &&
|
||||
(s != gCoreVocab->RDF_slotsHere) && (s != gCoreVocab->RDF_slotsIn)) {
|
||||
nlocalStoreUnassert (rdf, u, gCoreVocab->RDF_slotsIn, s, RDF_RESOURCE_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
nlclStoreKill (RDFT rdf, RDF_Resource u)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs* data;
|
||||
uint16 n = 0;
|
||||
data = DBM_GetSlotValue(rdf, u, gCoreVocab->RDF_slotsHere, 0, &size);
|
||||
while (n < size) {
|
||||
DBMAs nas = nthdbmas(data, n);
|
||||
RDF_Resource s;
|
||||
s = RDF_GetResource(NULL, (char*)dataOfDBMAs(nas), 1);
|
||||
DBM_PutSlotValue(rdf, u, s, 0, NULL, 0);
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_name, 0, NULL, 0) ;
|
||||
DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_parent, 1, NULL, 0) ;
|
||||
DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_parent, 0, NULL, 0) ;
|
||||
data = DBM_GetSlotValue(rdf, u, gCoreVocab->RDF_slotsIn, 0, &size);
|
||||
while (n < size) {
|
||||
DBMAs nas = nthdbmas(data, n);
|
||||
RDF_Resource s;
|
||||
s = RDF_GetResource(NULL, (char*)dataOfDBMAs(nas), 1);
|
||||
DBM_PutSlotValue(rdf, u, s, 1, NULL, 0);
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
nlocalStoreAddChildAt(RDFT rdf, RDF_Resource parent, RDF_Resource ref,
|
||||
RDF_Resource new, PRBool beforep)
|
||||
{
|
||||
size_t size ;
|
||||
DBMAs* data;
|
||||
char* ndata;
|
||||
RDF_Resource s = gCoreVocab->RDF_parent;
|
||||
DBMAs temp;
|
||||
uint16 n = 0;
|
||||
size_t tsize;
|
||||
PRBool ans = 0;
|
||||
DBMAs nas;
|
||||
data = DBM_GetSlotValue(rdf, parent, s, 1, &size);
|
||||
if (!data) return 0;
|
||||
while (n < size) {
|
||||
nas = nthdbmas(data, n);
|
||||
if (valueEqual(RDF_RESOURCE_TYPE, dataOfDBMAs(nas), ref)) {
|
||||
ans = 1;
|
||||
if (!beforep) {
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
break;
|
||||
}
|
||||
n = dbmasSize(nas) + n;
|
||||
}
|
||||
if (!ans) {
|
||||
freeMem(data);
|
||||
return 0;
|
||||
} else {
|
||||
char* dx = (char*)data;
|
||||
|
||||
temp = makeAsBlock(new, RDF_RESOURCE_TYPE, 1, &tsize);
|
||||
ndata = (char*)getMem(size + tsize);
|
||||
if ((temp == NULL) || (ndata == NULL)) {freeMem(data);freeMem(temp);freeMem(ndata);return 1;}
|
||||
memcpy(ndata, dx, n);
|
||||
memcpy(&ndata[n], (char*)temp, tsize);
|
||||
memcpy(&ndata[n+tsize], &dx[n], size-n);
|
||||
DBM_PutSlotValue(rdf, parent, s, 1, ndata, size+tsize);
|
||||
freeMem(data);
|
||||
freeMem(ndata);
|
||||
freeMem(temp);
|
||||
}
|
||||
|
||||
temp = makeAsBlock(parent, RDF_RESOURCE_TYPE, 1, &tsize);
|
||||
if (temp == NULL) return 0;
|
||||
data = DBM_GetSlotValue(rdf, new, s, 0, &size);
|
||||
if (data == NULL) {
|
||||
DBM_PutSlotValue(rdf, new, s, 0, (void*) temp, tsize);
|
||||
} else {
|
||||
ndata = (char*)getMem(size + tsize);
|
||||
if (ndata == NULL) {freeMem(data);freeMem(temp);return 0;}
|
||||
memcpy(ndata, data, size);
|
||||
memcpy(&ndata[size], (char*)temp, tsize);
|
||||
DBM_PutSlotValue(rdf, (RDF_Resource)new, s, 0, ndata, size+tsize);
|
||||
freeMem(data);
|
||||
freeMem(ndata);
|
||||
freeMem(temp);
|
||||
}
|
||||
sendNotifications2(rdf, RDF_INSERT_NOTIFY, new, s, parent, RDF_RESOURCE_TYPE, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
nlcStoreArcsIn (RDFT rdf, RDF_Resource u)
|
||||
{
|
||||
RDF_Cursor c = (RDF_Cursor) getMem(sizeof(struct RDF_CursorStruct));
|
||||
c->u = u;
|
||||
c->queryType = RDF_ARC_LABELS_IN_QUERY;
|
||||
c->inversep = 1;
|
||||
c->count = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
nlcStoreArcsOut (RDFT rdf, RDF_Resource u)
|
||||
{
|
||||
RDF_Cursor c = (RDF_Cursor) getMem(sizeof(struct RDF_CursorStruct));
|
||||
c->u = u;
|
||||
c->queryType = RDF_ARC_LABELS_OUT_QUERY;
|
||||
c->count = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Resource
|
||||
nlcStoreArcsInOutNextValue (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
while (c->count < (int16) gCoreVocabSize) {
|
||||
RDF_Resource s = *(gAllVocab + c->count);
|
||||
size_t size;
|
||||
void* data = DBM_GetSlotValue(rdf, c->u, s, c->inversep, &size);
|
||||
c->count++;
|
||||
if (data) {
|
||||
freeMem(data);
|
||||
return s;
|
||||
} else {
|
||||
freeMem(data);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
RDFT
|
||||
MakeLocalStore (char* url)
|
||||
{
|
||||
if (startsWith(url, "rdf:localStore") && (gLocalStore)) {
|
||||
return gLocalStore;
|
||||
} else if (startsWith(url, "rdf:ops") && (gOPSStore)) {
|
||||
return gOPSStore;
|
||||
} else if (startsWith(url, "rdf:ops") || startsWith(url, "rdf:localStore")) {
|
||||
RDFT ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct));
|
||||
DBMRDF db = (DBMRDF)getMem(sizeof(struct _DBMRDFStruct));
|
||||
CHECK_VAR(ntr, NULL);
|
||||
CHECK_VAR(db, NULL);
|
||||
if (startsWith(url, "rdf:localStore")) {
|
||||
gLocalStore = ntr;
|
||||
} else {
|
||||
gOPSStore = ntr;
|
||||
}
|
||||
ntr->url = copyString(url);
|
||||
ntr->assert = nlocalStoreAssert;
|
||||
ntr->unassert = nlocalStoreUnassert;
|
||||
ntr->getSlotValue = nlocalStoreGetSlotValue;
|
||||
ntr->getSlotValues = nlocalStoreGetSlotValues;
|
||||
ntr->hasAssertion = nlocalStoreHasAssertion;
|
||||
ntr->nextValue = nlocalStoreNextValue;
|
||||
ntr->disposeCursor = nlocalStoreDisposeCursor;
|
||||
ntr->destroy = DBM_CloseRDFDBMStore;
|
||||
ntr->arcLabelsIn = nlcStoreArcsIn;
|
||||
ntr->arcLabelsOut = nlcStoreArcsOut;
|
||||
ntr->pdata = db;
|
||||
DBM_OpenDBMStore(db, (startsWith(url, "rdf:localStore") ? "NavCen" : &url[4]));
|
||||
nlocalStoreAssert(ntr, gNavCenter->RDF_BookmarkFolderCategory, gCoreVocab->RDF_name,
|
||||
copyString("Bookmarks"), RDF_STRING_TYPE, 1);
|
||||
return ntr;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
} */
|
||||
122
mozilla/modules/rdf/src/nlcstore.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_NLCSTORE_H_
|
||||
#define _RDF_NLCSTORE_H_
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
#include "rdf.h"
|
||||
#include "mcom_ndbm.h"
|
||||
|
||||
|
||||
#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN)
|
||||
#error Must have a byte order
|
||||
#endif
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define COPY_INT16(_a,_b) XP_MEMCPY(_a, _b, sizeof(uint16));
|
||||
#else
|
||||
#define COPY_INT16(_a,_b) \
|
||||
do { \
|
||||
((char *)(_a))[0] = ((char *)(_b))[1]; \
|
||||
((char *)(_a))[1] = ((char *)(_b))[0]; \
|
||||
} while(0)
|
||||
#endif
|
||||
#if !defined(XP_MAC) && !defined(COPY_INT16)
|
||||
#define COPY_INT16(_a,_b) XP_MEMCPY(_a, _b, sizeof(int16));
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* nlcstore.c data structures and defines */
|
||||
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma options align=packed
|
||||
#endif
|
||||
|
||||
typedef struct _DBMAsStruct {
|
||||
uint8 size[3];
|
||||
uint8 tag;
|
||||
uint8 data[1]; /* me & the compiler man, we're like _this_ */
|
||||
} DBMAsStruct;
|
||||
typedef DBMAsStruct* DBMAs;
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
typedef struct _DBMRDFStruct {
|
||||
DB *propDB;
|
||||
DB *invPropDB;
|
||||
DB *nameDB;
|
||||
DB *childrenDB;
|
||||
} *DBMRDF;
|
||||
|
||||
|
||||
#define dataOfDBMAs(dbmas) (((char *)dbmas) + 4)
|
||||
#define dbmasSize(dbmas) ((size_t)(((1 << 16) * dbmas->size[0]) + ((1 << 8) * dbmas->size[1]) + dbmas->size[2]))
|
||||
#define nthdbmas(data, n) ((DBMAs)(((char *)data) + n))
|
||||
#define valueTypeOfAs(nas) (RDF_ValueType) ((*(((uint8 *)(nas)) + 3)) & 0x0F)
|
||||
#define tvOfAs(nas) ((PRBool)(((*((uint8 *)(nas) + 3)) & 0x10) != 0))
|
||||
#define valueEqual(type, v1, v2) (((type == RDF_RESOURCE_TYPE) && stringEquals((char*)v1, resourceID((RDF_Resource)v2))) || \
|
||||
((type == RDF_INT_TYPE) && (compareUnalignedUINT32Ptrs(v1,v2))) || \
|
||||
((type == RDF_STRING_TYPE) && stringEquals((char*)v1, (char*)v2)))
|
||||
|
||||
|
||||
|
||||
/* nlcstore.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
PRBool compareUnalignedUINT32Ptrs(void *v1, void *v2);
|
||||
char * makeRDFDBURL(char* directory, char* name);
|
||||
void readInBookmarksOnInit(RDFFile f);
|
||||
void DBM_OpenDBMStore (DBMRDF store, char* directory);
|
||||
RDF_Error DBM_CloseRDFDBMStore (RDFT r);
|
||||
char * makeUSKey (RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size);
|
||||
DB * getUSDB (RDFT r, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
void freeKey (char* keyData, RDF_Resource u, RDF_Resource s, PRBool inversep);
|
||||
DBMAs * DBM_GetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size);
|
||||
void DBM_PutSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, void* value, size_t size);
|
||||
PRBool nlocalStoreHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
void * nlocalStoreGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor nlocalStoreGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * nlocalStoreNextValue (RDFT rdf, RDF_Cursor c);
|
||||
RDF_Error nlocalStoreDisposeCursor (RDFT rdf, RDF_Cursor c);
|
||||
DBMAs makeAsBlock (void* v, RDF_ValueType type, PRBool tv, size_t *size);
|
||||
PRBool nlocalStoreAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool nlocalStoreAssert1 (RDFFile f, RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool nlocalStoreUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
void addSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s);
|
||||
void deleteSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s);
|
||||
void addSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s);
|
||||
void deleteSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s);
|
||||
void nlclStoreKill (RDFT rdf, RDF_Resource u);
|
||||
PRBool nlocalStoreAddChildAt(RDFT rdf, RDF_Resource parent, RDF_Resource ref, RDF_Resource new, PRBool beforep);
|
||||
RDF_Cursor nlcStoreArcsIn (RDFT rdf, RDF_Resource u);
|
||||
RDF_Cursor nlcStoreArcsOut (RDFT rdf, RDF_Resource u);
|
||||
RDF_Resource nlcStoreArcsInOutNextValue (RDFT rdf, RDF_Cursor c);
|
||||
RDFT MakeLocalStore (char* url);
|
||||
RDF_Resource nlcStoreArcsInOutNextValue (RDFT rdf, RDF_Cursor c) ;
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
563
mozilla/modules/rdf/src/pm2rdf.c
Normal file
@@ -0,0 +1,563 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements mail support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#ifdef SMART_MAIL
|
||||
#include "pm2rdf.h"
|
||||
|
||||
extern char *profileDirURL;
|
||||
|
||||
|
||||
|
||||
void
|
||||
Pop_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
GetPopToRDF (RDFT rdf)
|
||||
{
|
||||
MF folder = (MF) rdf->pdata;
|
||||
if (endsWith("/inbox", rdf->url)) {
|
||||
char* popurl = getMem(100);
|
||||
int n = 10;
|
||||
int l = RDF_STRLEN(rdf->url);
|
||||
URL_Struct *urls ;
|
||||
memcpy(popurl, "pop3://", 7);
|
||||
while (n < l) {
|
||||
if (rdf->url[n] == '/') break;
|
||||
popurl[n-3] = rdf->url[n];
|
||||
n++;
|
||||
}
|
||||
|
||||
urls = NET_CreateURLStruct(popurl, NET_DONT_RELOAD);
|
||||
if (urls != NULL) {
|
||||
urls->fe_data = rdf;
|
||||
|
||||
NET_GetURL(urls, FO_PRESENT, gRDFMWContext(rdf), Pop_GetUrlExitFunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
PopGetNewMail (RDF_Resource r)
|
||||
{
|
||||
if (containerp(r) && (resourceType(r) == PM_RT)) {
|
||||
MF folder = (MF) r->pdata;
|
||||
GetPopToRDF(folder->rdf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
stripCopy (char* str)
|
||||
{
|
||||
return copyString(XP_StripLine(str));
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
msgDeletedp (MM msg)
|
||||
{
|
||||
return (msg && (msg->flags) && (msg->flags[4] == '8'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE *
|
||||
openPMFile (char* path)
|
||||
{
|
||||
FILE* ans = fopen(path, "r+");
|
||||
if (!ans) {
|
||||
ans = fopen(path, "w");
|
||||
if (ans) fclose(ans);
|
||||
ans = fopen(path, "r+");
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
addMsgToFolder (MF folder, MM msg)
|
||||
{
|
||||
if (!folder->tail) {
|
||||
folder->msg = folder->tail = msg;
|
||||
} else {
|
||||
folder->tail->next = msg;
|
||||
folder->tail = msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RDF_StartMessageDelivery (RDFT rdf)
|
||||
{
|
||||
MF folder = (MF) rdf->pdata;
|
||||
MM msg = (MM) getMem(sizeof(struct MailMessage));
|
||||
char* nurl = getMem(100);
|
||||
fseek(folder->mfile, 0L, SEEK_END);
|
||||
fprintf(folder->mfile, "From - \n");
|
||||
msg->offset = ftell(folder->mfile);
|
||||
sprintf(nurl, "%s?%i", rdf->url, msg->offset);
|
||||
msg->r = RDF_GetResource(NULL, nurl, 1);
|
||||
msg->r->pdata = msg;
|
||||
msg->flags = getMem(4);
|
||||
folder->add = msg;
|
||||
setResourceType(msg->r, PM_RT);
|
||||
fseek(folder->mfile, 0L, SEEK_END);
|
||||
fputs("X-Mozilla-Status: 0000\n", folder->mfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
MIW1 (const char* block, int32 len)
|
||||
{
|
||||
char* blk = XP_ALLOC(len +1);
|
||||
int32 n = 0;
|
||||
int32 m = 0;
|
||||
PRBool seenp = 0;
|
||||
PRBool wsendp = 0;
|
||||
memset(blk, '\0', len);
|
||||
while (n++ < len) {
|
||||
char c = block[n];
|
||||
if ((c == '\r') || (c == '\n')) break;
|
||||
if (!seenp) {
|
||||
seenp = (c == ':');
|
||||
} else {
|
||||
if (c != ' ') wsendp = 1;
|
||||
if (wsendp) {
|
||||
blk[m++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RDF_AddMessageLine (RDFT rdf, char* block, int32 length)
|
||||
{
|
||||
MF folder = (MF) rdf->pdata;
|
||||
MM msg = folder->add;
|
||||
char* temp = getMem(length+1);
|
||||
memcpy(temp, block, length);
|
||||
if (!msg->from && (startsWith("From:", block))) {
|
||||
msg->from = MIW1(block, length);
|
||||
} else if (!msg->subject && (startsWith("Subject:", block))) {
|
||||
msg->subject = MIW1(block, length);
|
||||
} else if (!msg->date && (startsWith("Date:", block))) {
|
||||
msg->date = MIW1(block, length);
|
||||
}
|
||||
fseek(folder->mfile, 0L, SEEK_END);
|
||||
fputs(temp, folder->mfile);
|
||||
freeMem(temp);
|
||||
}
|
||||
|
||||
|
||||
#define TON(s) ((s == NULL) ? "" : s)
|
||||
void writeMsgSum (MF folder, MM msg) {
|
||||
if (!msg->flags) msg->flags = copyString("0000");
|
||||
if (msg->summOffset == -1) {
|
||||
fseek(folder->sfile, 0L, SEEK_END);
|
||||
msg->summOffset = ftell(folder->sfile);
|
||||
} else {
|
||||
fseek(folder->sfile, msg->summOffset, SEEK_SET);
|
||||
}
|
||||
fprintf(folder->sfile, "Status: %s\nSOffset: %d\nFrom: %s\nSubject: %s\nDate: %s\nMOffset: %d\n",
|
||||
msg->flags, ftell(folder->sfile),
|
||||
TON(msg->from), TON(msg->subject), TON(msg->date), msg->offset );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RDF_FinishMessageDelivery (RDFT rdf)
|
||||
{
|
||||
MF folder = (MF) rdf->pdata;
|
||||
MM msg = folder->add;
|
||||
folder->add = NULL;
|
||||
addMsgToFolder(folder, msg);
|
||||
setResourceType(msg->r, PM_RT);
|
||||
fseek(folder->sfile, 0L, SEEK_END);
|
||||
msg->summOffset = ftell(folder->sfile);
|
||||
writeMsgSum(folder, msg);
|
||||
fseek(folder->mfile, 0L, SEEK_END);
|
||||
fputs("\n", folder->mfile);
|
||||
sendNotifications2(rdf, RDF_ASSERT_NOTIFY, msg->r, gCoreVocab->RDF_parent, folder->top,
|
||||
RDF_RESOURCE_TYPE, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
setMessageFlag (RDFT rdf, RDF_Resource r, char* newFlag)
|
||||
{
|
||||
MF folder = (MF) rdf->pdata;
|
||||
MM msg = (MM)r->pdata;
|
||||
fseek(folder->sfile, msg->summOffset+8, SEEK_SET);
|
||||
fputs(newFlag, folder->sfile);
|
||||
freeMem(msg->flags);
|
||||
msg->flags = copyString(newFlag);
|
||||
/* need to mark the flag in the message file */
|
||||
fflush(folder->sfile);
|
||||
}
|
||||
|
||||
#define BUFF_SIZE 50000
|
||||
|
||||
|
||||
RDFT
|
||||
getBFTranslator (char* url) {
|
||||
if (startsWith("mailbox://folder/", url)) {
|
||||
char* temp = getMem(RDF_STRLEN(url));
|
||||
RDFT ans = NULL;
|
||||
sprintf(temp, "mailbox://%s", &url[17]);
|
||||
ans = getTranslator(temp);
|
||||
freeMem(temp);
|
||||
return ans;
|
||||
} else return getTranslator(url);
|
||||
}
|
||||
|
||||
PRBool
|
||||
MoveMessage (char* to, char* from, MM message) {
|
||||
RDFT todb = getBFTranslator(to);
|
||||
RDFT fromdb = getBFTranslator(from);
|
||||
MF tom = todb->pdata;
|
||||
MF fom = fromdb->pdata;
|
||||
RDF_Resource r;
|
||||
MM newMsg = (MM)getMem(sizeof(struct MailMessage));
|
||||
char* buffer = getMem(BUFF_SIZE);
|
||||
if (!buffer) return 0;
|
||||
setMessageFlag(fromdb, message->r, "0008");
|
||||
fseek(tom->mfile, 0L, SEEK_END);
|
||||
fseek(fom->mfile, message->offset, SEEK_SET);
|
||||
fputs("From -\n", tom->mfile);
|
||||
sprintf(buffer, "mailbox://%s?%d", &to[17], ftell(tom->mfile));
|
||||
r = RDF_GetResource(NULL, buffer, 1);
|
||||
newMsg->subject = copyString(message->subject);
|
||||
newMsg->from = copyString(message->from);
|
||||
newMsg->date = copyString(message->date);
|
||||
newMsg->r = r;
|
||||
r->pdata = newMsg;
|
||||
setResourceType(r, PM_RT);
|
||||
newMsg->summOffset = -1;
|
||||
newMsg->offset = ftell(tom->mfile);
|
||||
writeMsgSum(tom, newMsg);
|
||||
addMsgToFolder (tom, newMsg) ;
|
||||
fflush(tom->sfile);
|
||||
while (fgets(buffer, BUFF_SIZE, fom->mfile) && strncmp("From ", buffer, 5)) {
|
||||
fputs(buffer, tom->mfile);
|
||||
}
|
||||
sendNotifications2(todb, RDF_ASSERT_NOTIFY, r, gCoreVocab->RDF_parent, tom->top,
|
||||
RDF_RESOURCE_TYPE, 1);
|
||||
sendNotifications2(fromdb, RDF_DELETE_NOTIFY, message->r, gCoreVocab->RDF_parent, fom->top,
|
||||
RDF_RESOURCE_TYPE, 1);
|
||||
freeMem(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
readSummaryFile (RDFT rdf)
|
||||
{
|
||||
if (startsWith("mailbox://", rdf->url)) {
|
||||
char* url = rdf->url;
|
||||
char* folderURL = &url[10];
|
||||
int32 flen = RDF_STRLEN(profileDirURL) + strlen(folderURL) + 4;
|
||||
char* fileurl = getMem(flen);
|
||||
char* nurl = getMem(RDF_STRLEN(url) + 20);
|
||||
FILE *f;
|
||||
char* buff = getMem(BUFF_SIZE);
|
||||
MF folder = (MF) getMem(sizeof(struct MailFolder));
|
||||
MM msg = NULL;
|
||||
FILE *mf;
|
||||
char* aclen;
|
||||
|
||||
rdf->pdata = folder;
|
||||
sprintf(fileurl, "%s%s.ssf", profileDirURL, folderURL);
|
||||
fileurl = MCDepFileURL(fileurl);
|
||||
f = openPMFile(fileurl);
|
||||
sprintf(fileurl, "%s%s", profileDirURL, folderURL);
|
||||
fileurl = MCDepFileURL(fileurl);
|
||||
mf = openPMFile(fileurl);
|
||||
folder->top = RDF_GetResource(NULL, rdf->url, 1);
|
||||
setResourceType(folder->top, PM_RT);
|
||||
setContainerp(folder->top, 1);
|
||||
folder->top->pdata = folder;
|
||||
folder->rdf = rdf;
|
||||
folder->sfile = f;
|
||||
folder->mfile = mf;
|
||||
|
||||
while (f && fgets(buff, BUFF_SIZE, f)) {
|
||||
if (startsWith("Status:", buff)) {
|
||||
msg = (MM) getMem(sizeof(struct MailMessage));
|
||||
msg->flags = stripCopy(&buff[8]);
|
||||
fgets(buff, BUFF_SIZE, f);
|
||||
sscanf(&buff[9], "%d", &msg->summOffset);
|
||||
fgets(buff, BUFF_SIZE, f);
|
||||
msg->from = stripCopy(&buff[6]);
|
||||
fgets(buff, BUFF_SIZE, f);
|
||||
msg->subject = stripCopy(&buff[8]);
|
||||
fgets(buff, BUFF_SIZE, f);
|
||||
msg->date = stripCopy(&buff[6]);
|
||||
fgets(buff, BUFF_SIZE, f);
|
||||
sscanf(&buff[9], "%d", &msg->offset);
|
||||
sprintf(nurl, "%s?%d", url, msg->offset);
|
||||
msg->r = RDF_GetResource(NULL, nurl, 1);
|
||||
msg->r->pdata = msg;
|
||||
addMsgToFolder (folder, msg) ;
|
||||
setResourceType(msg->r, PM_RT);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg == NULL) {
|
||||
/* either a new mailbox or need to read BMF to recreate */
|
||||
while (mf && fgets(buff, BUFF_SIZE, mf)) {
|
||||
if (strncmp("From ", buff, 5) ==0) {
|
||||
if (msg) writeMsgSum(folder, msg);
|
||||
msg = (MM) getMem(sizeof(struct MailMessage));
|
||||
msg->offset = ftell(mf);
|
||||
msg->summOffset = -1;
|
||||
sprintf(nurl, "%s?%i", url, msg->offset);
|
||||
msg->r = RDF_GetResource(NULL, nurl, 1);
|
||||
msg->r->pdata = msg;
|
||||
setResourceType(msg->r, PM_RT);
|
||||
addMsgToFolder (folder, msg) ;
|
||||
}
|
||||
if ((!msg->from) && (startsWith("From:", buff))) {
|
||||
msg->from = stripCopy(&buff[6]);
|
||||
} else if ((!msg->date) && (startsWith("Date:", buff))) {
|
||||
msg->date = stripCopy(&buff[6]);
|
||||
} else if ((!msg->subject) && (startsWith("Subject:", buff))) {
|
||||
msg->subject = stripCopy(&buff[8]);
|
||||
} else if ((!msg->flags) && (startsWith("X-Mozilla-Status:", buff))) {
|
||||
msg->flags = stripCopy(&buff[17]);
|
||||
}
|
||||
}
|
||||
if (msg) writeMsgSum(folder, msg);
|
||||
if (folder->sfile) fflush(folder->sfile);
|
||||
}
|
||||
memset(fileurl, '\0', flen);
|
||||
memcpy(fileurl, rdf->url, RDF_STRLEN(rdf->url));
|
||||
aclen = RDF_STRCHR(&fileurl[10], '/');
|
||||
fileurl[aclen-fileurl] = '\0';
|
||||
RDF_STRCAT(fileurl, "/trash");
|
||||
folder->trash = fileurl;
|
||||
freeMem(buff);
|
||||
freeMem(nurl);
|
||||
/* GetPopToRDF(rdf); */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
pmGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,
|
||||
PRBool inversep, PRBool tv)
|
||||
{
|
||||
if ((resourceType(u) == PM_RT) && tv && (!inversep) && (type == RDF_STRING_TYPE) && (u->pdata)) {
|
||||
MM msg = (MM) u->pdata;
|
||||
if (s == gNavCenter->from) {
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )msg->from)));
|
||||
return copyString(msg->from);
|
||||
} else if (s == gNavCenter->subject) {
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )msg->subject)));
|
||||
return copyString(msg->subject);
|
||||
} else if (s == gNavCenter->date) {
|
||||
return copyString(msg->date);
|
||||
} else return NULL;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Cursor
|
||||
pmGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,
|
||||
PRBool inversep, PRBool tv)
|
||||
{
|
||||
if ((resourceType(u) == PM_RT) && tv && (inversep) && (type == RDF_RESOURCE_TYPE)
|
||||
&& (s == gCoreVocab->RDF_parent)) {
|
||||
MF folder = (MF)rdf->pdata;
|
||||
if (folder->top == u) {
|
||||
RDF_Cursor c = (RDF_Cursor)getMem(sizeof(struct RDF_CursorStruct));
|
||||
c->u = u;
|
||||
c->s = s;
|
||||
c->type = type;
|
||||
c->inversep = inversep;
|
||||
c->tv = tv;
|
||||
c->count = 0;
|
||||
c->pdata = folder->msg;
|
||||
return c;
|
||||
} else return NULL;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
pmNextValue (RDFT rdf, RDF_Cursor c)
|
||||
{
|
||||
MM msg = (MM) c->pdata;
|
||||
RDF_Resource ans = NULL;
|
||||
while (msg && msgDeletedp(msg)) {
|
||||
msg = msg->next;
|
||||
}
|
||||
if (msg) {
|
||||
ans = msg->r;
|
||||
c->pdata = msg->next;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDF_Error
|
||||
pmDisposeCursor (RDFT mcf, RDF_Cursor c)
|
||||
{
|
||||
freeMem(c);
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE *
|
||||
getPopMBox (RDFT db)
|
||||
{
|
||||
MF folder = (MF)db->pdata;
|
||||
return folder->mfile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
pmHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
|
||||
{
|
||||
/*this is clearly wrong, but doesn't break anything now ...*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
pmRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type)
|
||||
{
|
||||
PR_ASSERT( (RDF_STRING_TYPE != type) || ( IsUTF8String((const char* )v)));
|
||||
if ((startsWith("mailbox://", rdf->url)) && (resourceType(u) == PM_RT) && (s == gCoreVocab->RDF_parent)
|
||||
&& (type == RDF_RESOURCE_TYPE)) {
|
||||
RDF_Resource mbox = (RDF_Resource) v;
|
||||
if (!(containerp(mbox) && (resourceType(mbox) == PM_RT))) {
|
||||
return false;
|
||||
} else {
|
||||
MF folder = (MF)mbox->pdata;
|
||||
sendNotifications2(rdf, RDF_DELETE_NOTIFY, u, s, v, type, 1);
|
||||
MoveMessage(folder->trash, resourceID(mbox), (MM)u->pdata);
|
||||
return 1;
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakePopDB (char* url)
|
||||
{
|
||||
if (startsWith("mailbox://", url)) {
|
||||
RDFT ntr;
|
||||
if ((ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct))) != NULL) {
|
||||
char* fileurl = getMem(100);
|
||||
PRDir* dir ;
|
||||
char* aclen;
|
||||
sprintf(fileurl, "%s%s", profileDirURL, &url[10]);
|
||||
aclen = RDF_STRCHR(&fileurl[RDF_STRLEN(profileDirURL)+1], '/');
|
||||
fileurl[aclen-fileurl] = '\0';
|
||||
dir = OpenDir(fileurl);
|
||||
if (dir == NULL) {
|
||||
if ( CallPRMkDirUsingFileURL(fileurl, 00700) > -1) dir = OpenDir(fileurl);
|
||||
}
|
||||
freeMem(fileurl);
|
||||
if (dir) {
|
||||
PR_CloseDir(dir);
|
||||
ntr->assert = NULL;
|
||||
ntr->unassert = pmRemove;
|
||||
ntr->getSlotValue = pmGetSlotValue;
|
||||
ntr->getSlotValues = pmGetSlotValues;
|
||||
ntr->hasAssertion = pmHasAssertion;
|
||||
ntr->nextValue = pmNextValue;
|
||||
ntr->disposeCursor = pmDisposeCursor;
|
||||
ntr->url = copyString(url);
|
||||
readSummaryFile(ntr);
|
||||
return ntr;
|
||||
} else {
|
||||
freeMem(ntr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else return NULL;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RDFT
|
||||
MakeMailAccountDB (char* url)
|
||||
{
|
||||
if (startsWith("mailaccount://", url)) {
|
||||
RDFT ntr = NewRemoteStore(url);
|
||||
char* fileurl = getMem(100);
|
||||
int32 n = PR_SKIP_BOTH;
|
||||
PRDirEntry *de;
|
||||
PRDir* dir ;
|
||||
RDF_Resource top = RDF_GetResource(NULL, url, 1);
|
||||
sprintf(fileurl, "%s%s", profileDirURL, &url[14]);
|
||||
dir = OpenDir(fileurl);
|
||||
if (dir == NULL) {
|
||||
if ( CallPRMkDirUsingFileURL(fileurl, 00700) > -1) dir = OpenDir(fileurl);
|
||||
}
|
||||
while ((dir != NULL) && ((de = PR_ReadDir(dir, (PRDirFlags)(n++))) != NULL)) {
|
||||
if ((!endsWith(".ssf", de->name)) && (!endsWith(".dat", de->name)) &&
|
||||
(!endsWith(".snm", de->name)) && (!endsWith("~", de->name))) {
|
||||
RDF_Resource r;
|
||||
sprintf(fileurl, "mailbox://folder/%s/%s", &url[14], de->name);
|
||||
r = RDF_GetResource(NULL, fileurl, 1);
|
||||
setResourceType(r, PMF_RT);
|
||||
remoteStoreAdd(ntr, r, gCoreVocab->RDF_parent, top, RDF_RESOURCE_TYPE, 1);
|
||||
remoteStoreAdd(ntr, r, gCoreVocab->RDF_name, copyString(de->name), RDF_STRING_TYPE, 1);
|
||||
}
|
||||
}
|
||||
freeMem(fileurl);
|
||||
if (dir) PR_CloseDir(dir);
|
||||
return ntr;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
101
mozilla/modules/rdf/src/pm2rdf.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RDF_PM2RDF_H_
|
||||
#define _RDF_PM2RDF_H_
|
||||
|
||||
#include "net.h"
|
||||
#include "rdf.h"
|
||||
#include "rdf-int.h"
|
||||
#include "prio.h"
|
||||
#include "glue.h"
|
||||
#include "utils.h"
|
||||
#include "xp_str.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* pm2rdf.c data structures and defines */
|
||||
|
||||
#define TON(s) ((s == NULL) ? "" : s)
|
||||
|
||||
#define pmUnitp(u) ((resourceType(u) == PM_RT) || (resourceType(u) == IM_RT))
|
||||
|
||||
struct MailFolder {
|
||||
FILE *sfile;
|
||||
FILE *mfile;
|
||||
struct MailMessage* msg;
|
||||
struct MailMessage* tail;
|
||||
struct MailMessage* add;
|
||||
RDF_Resource top;
|
||||
int32 status;
|
||||
RDFT rdf;
|
||||
char* trash;
|
||||
};
|
||||
|
||||
typedef struct MailFolder* MF;
|
||||
|
||||
struct MailMessage {
|
||||
char* subject;
|
||||
char* from;
|
||||
char* date;
|
||||
int32 offset;
|
||||
char* flags;
|
||||
int32 summOffset;
|
||||
RDF_Resource r;
|
||||
struct MailMessage *next;
|
||||
};
|
||||
|
||||
typedef struct MailMessage* MM;
|
||||
|
||||
|
||||
/* pm2rdf.c function prototypes */
|
||||
|
||||
NSPR_BEGIN_EXTERN_C
|
||||
|
||||
void Pop_GetUrlExitFunc (URL_Struct *urls, int status, MWContext *cx);
|
||||
void GetPopToRDF (RDFT rdf);
|
||||
void PopGetNewMail (RDF_Resource r);
|
||||
char * stripCopy (char* str);
|
||||
PRBool msgDeletedp (MM msg);
|
||||
FILE * openPMFile (char* path);
|
||||
void addMsgToFolder (MF folder, MM msg);
|
||||
void RDF_StartMessageDelivery (RDFT rdf);
|
||||
char * MIW1 (const char* block, int32 len);
|
||||
void RDF_AddMessageLine (RDFT rdf, char* block, int32 length);
|
||||
void writeMsgSum (MF folder, MM msg);
|
||||
void RDF_FinishMessageDelivery (RDFT rdf);
|
||||
void setMessageFlag (RDFT rdf, RDF_Resource r, char* newFlag);
|
||||
PRBool MoveMessage (char* to, char* from, MM message);
|
||||
void readSummaryFile (RDFT rdf);
|
||||
void * pmGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
RDF_Cursor pmGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep, PRBool tv);
|
||||
void * pmNextValue (RDFT rdf, RDF_Cursor c);
|
||||
RDF_Error pmDisposeCursor (RDFT mcf, RDF_Cursor c);
|
||||
FILE * getPopMBox (RDFT db);
|
||||
PRBool pmHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv);
|
||||
PRBool pmRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type);
|
||||
RDFT MakePopDB (char* url);
|
||||
RDFT MakeMailAccountDB (char* url);
|
||||
|
||||
|
||||
|
||||
|
||||
NSPR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
432
mozilla/modules/rdf/src/qryparse.c
Normal file
@@ -0,0 +1,432 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* qryparse.c
|
||||
|
||||
A parser for queries expressed in RDF syntax.
|
||||
|
||||
There is a query tag (RDF:Query) which encloses one or more literal tags.
|
||||
It has an id (which is currently ignored).
|
||||
Literal tags (RDF:Literal) are like assertions, except they may contain variables.
|
||||
Variables are specified as hrefs, the first character of which is $.
|
||||
|
||||
The format of a literal whose range is a resource type is:
|
||||
|
||||
<RDF:Literal href=domain>
|
||||
<property href=range>
|
||||
</RDF:Literal>
|
||||
|
||||
a literal whose range is a string or int is expressed as:
|
||||
|
||||
<RDF:Literal href=domain>
|
||||
<property>string-or-int-value</property>
|
||||
</RDF:Literal>
|
||||
|
||||
Note: in order for the query engine to correctly retrieve property values
|
||||
which are strings or ints, you must add assertions about the
|
||||
property's range (otherwise it is assumed to be a resource).
|
||||
The range property may be the resource named "String", "Int", or any
|
||||
other resource.
|
||||
|
||||
For example:
|
||||
<RDF:Resource id="motto">
|
||||
<domain href="State.mcf"/>
|
||||
<range href="String"/>
|
||||
</RDF:Resource>
|
||||
|
||||
Here is an example of a query:
|
||||
|
||||
<RDF:Query id="query1">
|
||||
<result href="$result"/>
|
||||
<RDF:Literal href="$var1">
|
||||
<typeof href="Country.mcf"/>
|
||||
</RDF:Literal>
|
||||
<RDF:Literal href="$var1">
|
||||
<state href="$var2"/>
|
||||
</RDF:Literal>
|
||||
<RDF:Literal href="$var2">
|
||||
<capitalCity href="$result"/>
|
||||
</RDF:Literal>
|
||||
</RDF:Query>
|
||||
|
||||
In the Prolog-like syntax this looks like:
|
||||
typeof($var1, Country) & state($var1, $var2) & capitalCity($var2, $result)
|
||||
*/
|
||||
|
||||
#include "query.h"
|
||||
#include "rdf-int.h"
|
||||
|
||||
#define QUERY_TAG "RDF:Query"
|
||||
#define LITERAL_TAG "RDF:Literal"
|
||||
#define RESULT_TAG "RDF:result"
|
||||
#define SEQ_TAG "RDF:seq"
|
||||
#define SEQ_END_TAG "</RDF:seq>"
|
||||
#define LI_TAG "RDF:li"
|
||||
#define RDF_OBJECT 10 /* status */
|
||||
#define RDF_PROPERTY 11 /* status */
|
||||
#define RDF_SEQ 12
|
||||
#define RDF_LI 13
|
||||
#define RDF_PARSE_ERROR 5 /* this should go in rdf.h */
|
||||
|
||||
/* analogous to RDFFile */
|
||||
typedef struct _QueryParseStruct {
|
||||
uint16 status; /* whether we're parsing an object or property */
|
||||
PRBool tv; /* truth value of current literal */
|
||||
uint16 depth;
|
||||
RDF rdf;
|
||||
RDF_Query query;
|
||||
RDFElement elf;
|
||||
TermStruc stack[16];
|
||||
TermStruc* value;
|
||||
uint8 valueCount;
|
||||
uint8 valueSize;
|
||||
} QueryParseStruct;
|
||||
|
||||
extern void parseRDFElement(RDFElement elf, char* token);
|
||||
extern char* getElfProp(char* prop, RDFElement elf);
|
||||
extern PRBool variableTermp(TermStruc term);
|
||||
extern PRBool resourceTermp(TermStruc term);
|
||||
extern PRBool constantTermp(TermStruc term);
|
||||
|
||||
/* prototypes */
|
||||
PRBool variablep(char* elf);
|
||||
RDF_ValueType rangeType(RDF rdf, RDF_Resource prop);
|
||||
RDF_Error parseNextQueryToken (QueryParseStruct *q, char* token);
|
||||
RDF_Query parseQuery(RDF rdf, char* blob, int32 size);
|
||||
RDF_Error parsePropertyValue(QueryParseStruct *q, char* token);
|
||||
RDF_Error parseEndTag(QueryParseStruct *q, char* token);
|
||||
RDF_Error parseTag (QueryParseStruct *q, char* token);
|
||||
RDF_Error addValueToList(QueryParseStruct *q, void* value, RDF_TermType type);
|
||||
TermStruc* copyTermList(TermStruc* list, uint8 count);
|
||||
|
||||
PRBool variablep(char* elf) {
|
||||
return elf[0] == '$';
|
||||
}
|
||||
|
||||
/* Returns the ValueType of the range of the property specified */
|
||||
RDF_ValueType rangeType(RDF rdf, RDF_Resource prop) {
|
||||
RDF_Resource rangeType;
|
||||
if (prop == gCoreVocab->RDF_substring) return RDF_STRING_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_notSubstring) return RDF_STRING_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_stringEquals) return RDF_STRING_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_notStringEquals) return RDF_STRING_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_lessThan) return RDF_INT_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_greaterThan) return RDF_INT_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_lessThanOrEqual) return RDF_INT_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_greaterThanOrEqual) return RDF_INT_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_equals) return RDF_INT_TYPE;
|
||||
else if (prop == gCoreVocab->RDF_notEquals) return RDF_INT_TYPE;
|
||||
/* fix me - add RDF_stringEquals */
|
||||
rangeType = RDF_GetSlotValue(rdf, prop, gCoreVocab->RDF_range, RDF_RESOURCE_TYPE, false, true);
|
||||
if (rangeType == NULL) return RDF_RESOURCE_TYPE; /* don't know so assume resource */
|
||||
else if (rangeType == gCoreVocab->RDF_StringType) return RDF_STRING_TYPE;
|
||||
else if (rangeType == gCoreVocab->RDF_IntType) return RDF_INT_TYPE;
|
||||
else return RDF_RESOURCE_TYPE; /* not string or int so must be a resource */
|
||||
}
|
||||
|
||||
/* Returns query parsed from blob, NULL if there was a parsing error.
|
||||
This is adapted from parseNextRDFXMLBlob, the main differences being that
|
||||
a file structure is not maintained. blob must contain the entire query.
|
||||
*/
|
||||
RDF_Query parseQuery(RDF rdf, char* blob, int32 size) {
|
||||
RDF_Error err = noRDFErr;
|
||||
QueryParseStruct q;
|
||||
char line[LINE_SIZE];
|
||||
char holdOver[LINE_SIZE];
|
||||
int32 n, last, m;
|
||||
PRBool somethingseenp = false;
|
||||
n = last = 0;
|
||||
q.depth = 0;
|
||||
q.elf = (RDFElement)getMem(sizeof(RDFElementStruct));
|
||||
q.rdf = rdf;
|
||||
q.query = RDF_CreateQuery(rdf);
|
||||
q.tv = true;
|
||||
q.value = NULL;
|
||||
q.valueCount = 0;
|
||||
q.valueSize = 0;
|
||||
|
||||
memset(holdOver, '\0', LINE_SIZE);
|
||||
while (n < size) {
|
||||
char c = blob[n];
|
||||
m = 0;
|
||||
somethingseenp = false;
|
||||
memset(line, '\0', LINE_SIZE);
|
||||
if (holdOver[0] != '\0') {
|
||||
memcpy(line, holdOver, RDF_STRLEN(holdOver));
|
||||
m = RDF_STRLEN(holdOver);
|
||||
somethingseenp = true;
|
||||
memset(holdOver, '\0', LINE_SIZE);
|
||||
}
|
||||
while ((m < 300) && (c != '<') && (c != '>')) {
|
||||
line[m] = c;
|
||||
m++;
|
||||
somethingseenp = (somethingseenp || ((c != ' ') && (c != '\r') && (c != '\n')));
|
||||
n++;
|
||||
if (n < size) c = blob[n];
|
||||
else break;
|
||||
}
|
||||
if (c == '>') line[m] = c;
|
||||
n++;
|
||||
if (m > 0) {
|
||||
if ((c == '<') || (c == '>')) {
|
||||
last = n;
|
||||
if (c == '<') holdOver[0] = '<';
|
||||
if (somethingseenp == true) {
|
||||
err = parseNextQueryToken(&q, line);
|
||||
if (err != noRDFErr) {
|
||||
if (q.query != NULL) RDF_DestroyQuery(q.query);
|
||||
q.query = NULL;
|
||||
break; /* while (n < size) */
|
||||
}
|
||||
}
|
||||
} else if (size > last) {
|
||||
memcpy(holdOver, line, m);
|
||||
}
|
||||
} else if (c == '<') holdOver[0] = '<';
|
||||
}
|
||||
if (q.elf != NULL) freeMem(q.elf);
|
||||
return q.query;
|
||||
}
|
||||
|
||||
RDF_Error addValueToList(QueryParseStruct *q, void* value, RDF_TermType type) {
|
||||
RDF_Error err = noRDFErr;
|
||||
int increment = 5;
|
||||
if (q->valueSize == q->valueCount) {
|
||||
TermStruc* old = q->value;
|
||||
TermStruc* newTermList = (TermStruc*)getMem((q->valueSize + increment) * sizeof(TermStruc));
|
||||
if (newTermList == NULL) return RDF_NO_MEMORY;
|
||||
memcpy((char*)newTermList, (char*)q->value, (q->valueSize)* sizeof(TermStruc));
|
||||
q->value = newTermList;
|
||||
q->valueSize = q->valueSize + increment;
|
||||
freeMem(old);
|
||||
}
|
||||
(q->value + q->valueCount)->value = value;
|
||||
(q->value + q->valueCount)->type = type;
|
||||
q->valueCount++;
|
||||
return err;
|
||||
}
|
||||
|
||||
TermStruc* copyTermList(TermStruc* list, uint8 count) {
|
||||
TermStruc* newList = (TermStruc*)getMem(count * sizeof(TermStruc));
|
||||
if (newList == NULL) return NULL;
|
||||
memcpy((char*)newList, (char*)list, count * sizeof(TermStruc));
|
||||
return newList;
|
||||
}
|
||||
|
||||
RDF_Error parsePropertyValue(QueryParseStruct *q, char* token) {
|
||||
RDF_Error err = noRDFErr;
|
||||
if ((q->depth == 3) && (q->status == RDF_PROPERTY)) {
|
||||
/* parse the property value */
|
||||
RDF_Resource slot = (RDF_Resource)q->stack[q->depth-1].value;
|
||||
RDF_ValueType type = rangeType(q->rdf, slot);
|
||||
TermStruc unitTerm = q->stack[q->depth-2];
|
||||
switch (type) { /* switch on value type of property */
|
||||
int i;
|
||||
case RDF_RESOURCE_TYPE:
|
||||
err = RDF_PARSE_ERROR;
|
||||
break;
|
||||
case RDF_STRING_TYPE:
|
||||
if (variablep(token)) {
|
||||
RDF_Variable rangeVar = RDF_GetVariable(q->query, token);
|
||||
if (variableTermp(unitTerm))
|
||||
err = RDF_AddConjunctVRV(q->query, (RDF_Variable)unitTerm.value, slot, rangeVar, type);
|
||||
else err = RDF_AddConjunctRRV(q->query, (RDF_Resource)unitTerm.value, slot, rangeVar, type);
|
||||
} else if (variableTermp(unitTerm)) {
|
||||
err = RDF_AddConjunctVRO(q->query, (RDF_Variable)unitTerm.value, slot, (void*)token, type);
|
||||
} else err = RDF_AddConjunctRRO(q->query, (RDF_Resource)unitTerm.value, slot, (void*)token, type);
|
||||
break;
|
||||
case RDF_INT_TYPE:
|
||||
if (variablep(token)) {
|
||||
RDF_Variable rangeVar = RDF_GetVariable(q->query, token);
|
||||
if (variableTermp(unitTerm))
|
||||
err = RDF_AddConjunctVRV(q->query, (RDF_Variable)unitTerm.value, slot, rangeVar, type);
|
||||
else err = RDF_AddConjunctRRV(q->query, (RDF_Resource)unitTerm.value, slot, rangeVar, type);
|
||||
} else if (sscanf(token, "%d", &i) == 1) { /* fix me */
|
||||
if (variableTermp(unitTerm)) {
|
||||
err = RDF_AddConjunctVRO(q->query, (RDF_Variable)unitTerm.value, slot, (void*)i, type);
|
||||
} else err = RDF_AddConjunctRRO(q->query, (RDF_Resource)unitTerm.value, slot, (void*)i, type);
|
||||
} else err = RDF_PARSE_ERROR;
|
||||
break;
|
||||
default:
|
||||
err = RDF_PARSE_ERROR; /* should never get here */
|
||||
break;
|
||||
}
|
||||
} else if (q->status == RDF_LI) {
|
||||
RDF_Resource slot = (RDF_Resource)q->stack[q->depth-3].value;
|
||||
RDF_ValueType type = rangeType(q->rdf, slot);
|
||||
switch (type) {
|
||||
int i;
|
||||
case RDF_RESOURCE_TYPE:
|
||||
err = RDF_PARSE_ERROR;
|
||||
break;
|
||||
case RDF_STRING_TYPE:
|
||||
if (variablep(token))
|
||||
err = addValueToList(q, RDF_GetVariable(q->query, token), RDF_VARIABLE_TERM_TYPE);
|
||||
else err = addValueToList(q, copyString(token), RDF_CONSTANT_TERM_TYPE);
|
||||
break;
|
||||
case RDF_INT_TYPE:
|
||||
if (variablep(token)) {
|
||||
err = addValueToList(q, RDF_GetVariable(q->query, token), RDF_VARIABLE_TERM_TYPE);
|
||||
} else if (sscanf(token, "%d", &i) == 1) { /* fix me */
|
||||
err = addValueToList(q, (void*)i, RDF_CONSTANT_TERM_TYPE);
|
||||
} else err = RDF_PARSE_ERROR;
|
||||
break;
|
||||
default:
|
||||
err = RDF_PARSE_ERROR; /* should never get here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
RDF_Error parseTag (QueryParseStruct *q, char* token) {
|
||||
RDF_Error err = noRDFErr;
|
||||
RDFElement elf = q->elf;
|
||||
memset((char*)elf, '\0', sizeof(RDFElementStruct));
|
||||
parseRDFElement(elf, token);
|
||||
|
||||
/* the block can start with Query, Literal or a property name */
|
||||
|
||||
if (startsWith(QUERY_TAG, elf->tagName)) {
|
||||
char* url = getElfProp("id", elf);
|
||||
/* don't have anything to do with id right now */
|
||||
q->stack[q->depth++].value = (void*)NULL;
|
||||
q->status = RDF_OBJECT;
|
||||
} else if (startsWith(LITERAL_TAG, elf->tagName)) {
|
||||
char* domain = getElfProp("href", elf);
|
||||
if (variablep(domain)) {
|
||||
q->stack[q->depth].value = RDF_GetVariable(q->query, domain);
|
||||
q->stack[q->depth].type = RDF_VARIABLE_TERM_TYPE;
|
||||
q->depth++;
|
||||
} else {
|
||||
q->stack[q->depth].value = resourceFromID(domain, true);
|
||||
q->stack[q->depth].type = RDF_RESOURCE_TERM_TYPE;
|
||||
q->depth++;
|
||||
}
|
||||
q->status = RDF_OBJECT;
|
||||
/*
|
||||
if (stringEquals(LITERAL_NEGATION_TAG, elf->tagName))
|
||||
q->tv = false;
|
||||
else q->tv = true;
|
||||
*/
|
||||
} else if (stringEquals(elf->tagName, RESULT_TAG) && (q->depth == 1)) {
|
||||
/* set a result variable */
|
||||
char* range = getElfProp("href", elf);
|
||||
RDF_Variable resultVar = RDF_GetVariable(q->query, range);
|
||||
RDF_SetResultVariable(resultVar, true);
|
||||
q->status = RDF_OBJECT;
|
||||
} else if (stringEquals(elf->tagName, SEQ_TAG) && (q->depth == 3)) {
|
||||
/* ignore stack value */
|
||||
q->depth++;
|
||||
q->status = RDF_SEQ;
|
||||
q->valueSize = 10;
|
||||
q->valueCount = 0;
|
||||
q->value = (TermStruc*)getMem(q->valueSize * sizeof(TermStruc));
|
||||
if (q->value == NULL) err = RDF_PARSE_ERROR;
|
||||
} else if (stringEquals(elf->tagName, LI_TAG) && (q->depth == 4)) {
|
||||
/* ignore stack value */
|
||||
if (elf->emptyTagp) { /* <RDF:li href="$var"/> */
|
||||
char* range = getElfProp("href", elf);
|
||||
RDF_Resource slot = (RDF_Resource)q->stack[q->depth-2].value;
|
||||
RDF_ValueType type = rangeType(q->rdf, slot);
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
if (variablep(range)) {
|
||||
err = addValueToList(q, RDF_GetVariable(q->query, range), RDF_VARIABLE_TERM_TYPE);
|
||||
} else err = addValueToList(q, resourceFromID(range, true), RDF_RESOURCE_TERM_TYPE);
|
||||
} else err = RDF_PARSE_ERROR;
|
||||
} else { /* <RDF:li> */
|
||||
q->depth++;
|
||||
q->status = RDF_LI;
|
||||
}
|
||||
} else if (q->depth != 1) { /* property */
|
||||
char* pname = elf->tagName;
|
||||
RDF_Resource slot = resourceFromID(pname, true);
|
||||
if (elf->emptyTagp) {
|
||||
char* range = getElfProp("href", elf);
|
||||
RDF_ValueType type = rangeType(q->rdf, slot);
|
||||
TermStruc unitTerm = q->stack[q->depth-1];
|
||||
switch (type) { /* switch on value type of property */
|
||||
case RDF_RESOURCE_TYPE:
|
||||
if (variablep(range)) {
|
||||
RDF_Variable rangeVar = RDF_GetVariable(q->query, range);
|
||||
if (variableTermp(unitTerm)) {
|
||||
err = RDF_AddConjunctVRV(q->query, (RDF_Variable)unitTerm.value, slot, rangeVar, type);
|
||||
} else {
|
||||
err = RDF_AddConjunctRRV(q->query, (RDF_Resource)unitTerm.value, slot, rangeVar, type);
|
||||
}
|
||||
} else {
|
||||
RDF_Resource rangeRsrc = resourceFromID(range, true);
|
||||
if (variableTermp(unitTerm)) {
|
||||
/* RDF_AddConjunctVRR */
|
||||
err = RDF_AddConjunctVRR(q->query, (RDF_Variable)unitTerm.value, slot, rangeRsrc);
|
||||
} else err = RDF_PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = RDF_PARSE_ERROR; /* strings and ints cannot be inside href */
|
||||
break;
|
||||
}
|
||||
q->status = RDF_OBJECT;
|
||||
} else {
|
||||
/* this isn't really a term, its just a property but we access it in the same way as a term */
|
||||
q->stack[q->depth].value = slot;
|
||||
q->stack[q->depth].type = RDF_RESOURCE_TERM_TYPE;
|
||||
q->depth++;
|
||||
q->status = RDF_PROPERTY;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
RDF_Error parseEndTag(QueryParseStruct *q, char* token) {
|
||||
RDF_Error err = noRDFErr;
|
||||
if (stringEquals(SEQ_END_TAG, token)) {
|
||||
RDF_Resource slot = (RDF_Resource)q->stack[q->depth-2].value;
|
||||
RDF_ValueType type = rangeType(q->rdf, slot);
|
||||
TermStruc unitTerm = q->stack[q->depth-3];
|
||||
/* copy the value list, add the conjunct, and destroy the list - the engine destroys the copy. */
|
||||
TermStruc* copy = copyTermList(q->value, q->valueCount);
|
||||
if (copy == NULL) return RDF_NO_MEMORY;
|
||||
err = RDF_AddConjunctVRL(q->query, (RDF_Variable)unitTerm.value, slot, (RDF_Term)copy, type, q->valueCount);
|
||||
q->valueCount = q->valueSize = 0;
|
||||
freeMem(q->value);
|
||||
}
|
||||
if (q->depth == 0) return RDF_PARSE_ERROR;
|
||||
q->depth--;
|
||||
if (q->status == RDF_OBJECT)
|
||||
q->status = RDF_PROPERTY;
|
||||
else if (q->status == RDF_LI)
|
||||
q->status = RDF_SEQ;
|
||||
else if (q->status == RDF_SEQ)
|
||||
q->status = RDF_OBJECT; /* also terminates the property */
|
||||
return err;
|
||||
}
|
||||
|
||||
/* this is adapted from parseNextRDFToken, the difference being in the actions. */
|
||||
RDF_Error parseNextQueryToken (QueryParseStruct *q, char* token) {
|
||||
RDF_Error err = noRDFErr;
|
||||
if (token[0] == '\n' || token[0] == '\r') return err;
|
||||
if (token[0] != '<') {
|
||||
err = parsePropertyValue(q, token);
|
||||
} else if (token[1] == '/') {
|
||||
err = parseEndTag(q, token);
|
||||
} else {
|
||||
err = parseTag(q, token);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
651
mozilla/modules/rdf/src/query.c
Normal file
@@ -0,0 +1,651 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements query support for the rdf data model.
|
||||
For more information on this file, contact rjc or guha
|
||||
For more information on RDF, look at the RDF section of www.mozilla.org
|
||||
*/
|
||||
|
||||
#ifdef XP_PC
|
||||
#define strcasecomp RDF_STRCMP
|
||||
#endif
|
||||
|
||||
#include "query.h"
|
||||
#include "rdf-int.h"
|
||||
|
||||
/* prototypes */
|
||||
PRBool variableTermp(TermStruc term);
|
||||
PRBool resourceTermp(TermStruc term);
|
||||
PRBool constantTermp(TermStruc term);
|
||||
RDF_Error addVariableToList(RDF_Variable variable, RDF_VariableList *list);
|
||||
void destroyVariableList(RDF_VariableList list, PRBool destroyVariables);
|
||||
void destroyLiteralList(RDF_LiteralList list, PRBool destroyLiterals);
|
||||
PRBool comparisonp(RDF_Resource r);
|
||||
PRBool specialResourcePredicate(RDF_Resource r);
|
||||
PRBool findLiteral(RDF_Literal target, RDF_LiteralList list);
|
||||
RDF_Literal getNthLiteral(RDF_Query q, uint16 index);
|
||||
PRBool constantp(TermStruc term, RDF_VariableList knownVars);
|
||||
RDF_Literal oneUnknownAs(RDF_Query q, RDF_LiteralList orderedLiterals, RDF_VariableList knownVars);
|
||||
RDF_Literal noUnknownAs(RDF_Query q, RDF_LiteralList orderedLiterals, RDF_VariableList knownVars);
|
||||
PRBool orderConjuncts(RDF_Query q);
|
||||
PRBool processNextLiteral(RDF_Query q, RDF_Literal literal);
|
||||
void addLiteral(RDF_Query q, RDF_Literal literal);
|
||||
|
||||
/* Variable API */
|
||||
PR_PUBLIC_API(PRBool) RDF_IsResultVariable(RDF_Variable var) {
|
||||
return var->isResult;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(void) RDF_SetResultVariable(RDF_Variable var, PRBool isResult) {
|
||||
var->isResult = isResult;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(void*) RDF_GetVariableValue(RDF_Variable var) {
|
||||
if (var->query->queryRunning)
|
||||
return var->value;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(void) RDF_SetVariableValue(RDF_Variable var, void* value, RDF_ValueType type) {
|
||||
if (!var->query->queryRunning) var->query->conjunctsOrdered = false;
|
||||
var->value = value;
|
||||
var->type = type;
|
||||
}
|
||||
|
||||
PRBool variableTermp(TermStruc term) {
|
||||
return term.type == RDF_VARIABLE_TERM_TYPE;
|
||||
}
|
||||
|
||||
PRBool resourceTermp(TermStruc term) {
|
||||
return term.type == RDF_RESOURCE_TERM_TYPE;
|
||||
}
|
||||
|
||||
PRBool constantTermp(TermStruc term) {
|
||||
return term.type == RDF_CONSTANT_TERM_TYPE;
|
||||
}
|
||||
|
||||
/* Adds the variable to the variable list if it isn't already on the list. */
|
||||
RDF_Error addVariableToList(RDF_Variable variable, RDF_VariableList *list) {
|
||||
PRBool found = false;
|
||||
RDF_VariableList current = *list;
|
||||
while (current != NULL) {
|
||||
if (current->element == variable) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
if (!found) {
|
||||
RDF_VariableList newlist = (RDF_VariableList)getMem(sizeof(RDF_VariableListStruc));
|
||||
if (newlist == NULL) return RDF_NO_MEMORY;
|
||||
newlist->element = variable;
|
||||
newlist->next = *list;
|
||||
*list = newlist;
|
||||
}
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
void destroyVariableList(RDF_VariableList list, PRBool destroyVariables) {
|
||||
if (list != NULL) {
|
||||
destroyVariableList(list->next, destroyVariables);
|
||||
if (destroyVariables) freeMem(list->element); /* free the variable */
|
||||
freeMem(list); /* free the list structure */
|
||||
}
|
||||
}
|
||||
|
||||
void destroyLiteralList(RDF_LiteralList list, PRBool destroyLiterals) {
|
||||
if (list != NULL) {
|
||||
destroyLiteralList(list->next, destroyLiterals);
|
||||
if (destroyLiterals) {
|
||||
RDF_Literal literal = list->element;
|
||||
if (literal->c != NULL) RDF_DisposeCursor(literal->c);
|
||||
if (literal->valueType == RDF_STRING_TYPE) {
|
||||
int i;
|
||||
for (i = 0; i < literal->valueCount; i++) {
|
||||
TermStruc term = *(literal->v + i);
|
||||
if (constantTermp(term)) freeMem(term.value);
|
||||
}
|
||||
}
|
||||
freeMem(literal->v);
|
||||
freeMem(list->element); /* free the literal */
|
||||
}
|
||||
freeMem(list); /* free the list structure */
|
||||
}
|
||||
}
|
||||
|
||||
PRBool comparisonp(RDF_Resource r) {
|
||||
return (r == gCoreVocab->RDF_substring ||
|
||||
r == gCoreVocab->RDF_notSubstring ||
|
||||
r == gCoreVocab->RDF_lessThan ||
|
||||
r == gCoreVocab->RDF_greaterThan ||
|
||||
r == gCoreVocab->RDF_lessThanOrEqual ||
|
||||
r == gCoreVocab->RDF_greaterThanOrEqual ||
|
||||
r == gCoreVocab->RDF_equals ||
|
||||
r == gCoreVocab->RDF_notEquals ||
|
||||
r == gCoreVocab->RDF_stringEquals ||
|
||||
r == gCoreVocab->RDF_notStringEquals);
|
||||
}
|
||||
|
||||
PRBool specialResourcePredicate(RDF_Resource r) {
|
||||
return (r == gCoreVocab->RDF_notInstanceOf || r == gCoreVocab->RDF_notParent);
|
||||
}
|
||||
|
||||
/* Creates and initializes a query. Returns NULL if not enough memory. */
|
||||
PR_PUBLIC_API(RDF_Query) RDF_CreateQuery(RDF rdf) {
|
||||
RDF_Query q = (RDF_Query)getMem(sizeof(RDF_QueryStruc));
|
||||
if (q == NULL) return q;
|
||||
q->variables = NULL;
|
||||
q->literals = NULL;
|
||||
q->numLiterals = 0;
|
||||
q->index = 0;
|
||||
q->conjunctsOrdered = false;
|
||||
q->queryRunning = false;
|
||||
q->rdf = rdf;
|
||||
return q;
|
||||
}
|
||||
|
||||
/* Destroys a query. */
|
||||
PR_PUBLIC_API(void) RDF_DestroyQuery(RDF_Query q) {
|
||||
destroyLiteralList(q->literals, true); /* free the literals */
|
||||
q->literals = NULL;
|
||||
destroyVariableList(q->variables, true); /* free the variables */
|
||||
q->variables = NULL;
|
||||
freeMem(q); /* free the query */
|
||||
q = NULL;
|
||||
}
|
||||
|
||||
/* Returns the variable with the given name in the query.
|
||||
If not found:
|
||||
if the query is running, return NULL
|
||||
otherwise create a new variable with the given name.
|
||||
if there isn't enough memory, return NULL.
|
||||
*/
|
||||
PR_PUBLIC_API(RDF_Variable) RDF_GetVariable(RDF_Query q, char* name) {
|
||||
RDF_Variable newvar;
|
||||
RDF_VariableList newlist;
|
||||
RDF_VariableList current = q->variables;
|
||||
while (current != NULL) {
|
||||
if (stringEquals(current->element->id, name)) return current->element;
|
||||
if (current->next == NULL) break;
|
||||
else current = current->next;
|
||||
}
|
||||
if (q->queryRunning) return NULL;
|
||||
newvar = (RDF_Variable)getMem(sizeof(RDF_VariableStruc));
|
||||
if (newvar == NULL) return NULL;
|
||||
newvar->id = copyString(name);
|
||||
newvar->query = q;
|
||||
/* create a list containing the variable and append it to the front of the variable list */
|
||||
newlist = (RDF_VariableList)getMem(sizeof(RDF_VariableListStruc));
|
||||
if (newlist == NULL) {
|
||||
freeMem(newvar);
|
||||
return NULL;
|
||||
}
|
||||
newlist->element = newvar;
|
||||
newlist->next = q->variables;
|
||||
q->variables = newlist;
|
||||
return newvar;
|
||||
}
|
||||
|
||||
/* Returns the number of variables in the query. */
|
||||
PR_PUBLIC_API(uint16) RDF_GetVariableListCount(RDF_Query q) {
|
||||
RDF_VariableList current = q->variables;
|
||||
uint16 count = 0;
|
||||
while (current != NULL) {
|
||||
current = current->next;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Returns the variables belonging to the query at the given index. */
|
||||
PR_PUBLIC_API(RDF_Variable) RDF_GetNthVariable(RDF_Query q, uint16 index) {
|
||||
RDF_VariableList current = q->variables;
|
||||
uint16 count = 0;
|
||||
while (current != NULL) {
|
||||
if (count == index)
|
||||
return current->element;
|
||||
else {
|
||||
current = current->next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns true if target is found in literal */
|
||||
PRBool findLiteral(RDF_Literal target, RDF_LiteralList list) {
|
||||
while (list != NULL) {
|
||||
if (list->element == target) return true;
|
||||
else list = list->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns the literal belonging to the query at the given index. */
|
||||
RDF_Literal getNthLiteral(RDF_Query q, uint16 index) {
|
||||
RDF_LiteralList current = q->literals;
|
||||
uint16 count = 0;
|
||||
while (current != NULL) {
|
||||
if (count == index)
|
||||
return current->element;
|
||||
else {
|
||||
current = current->next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A term is constant if it is not a variable, if it is a variable with
|
||||
a non-null value, or if it is a known variable.
|
||||
*/
|
||||
PRBool constantp(TermStruc term, RDF_VariableList knownVars) {
|
||||
if (term.type != RDF_VARIABLE_TERM_TYPE) return true;
|
||||
else {
|
||||
RDF_Variable var = (RDF_Variable)term.value;
|
||||
if (var->value != NULL) return true;
|
||||
else {
|
||||
while (knownVars != NULL) {
|
||||
if (knownVars->element == var) return true;
|
||||
knownVars = knownVars->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a literal with a constant term which has not been ordered yet. */
|
||||
RDF_Literal oneUnknownAs(RDF_Query q, RDF_LiteralList orderedLiterals, RDF_VariableList knownVars) {
|
||||
RDF_LiteralList list = q->literals;
|
||||
RDF_Literal answer = NULL;
|
||||
while (list != NULL) {
|
||||
RDF_Literal current = list->element;
|
||||
if (!findLiteral(current, orderedLiterals)) {
|
||||
if (((constantp(current->u, knownVars)) || (constantp(*current->v, knownVars))) &&
|
||||
current->valueCount == 1 && /* no disjunctions */
|
||||
!comparisonp(current->s) && /* comparisons must have constant terms */
|
||||
!specialResourcePredicate(current->s) /* notTypeOf and notParent must have constant terms */
|
||||
/* && current->tv == true */) {
|
||||
if (answer == NULL) {
|
||||
answer = current;
|
||||
} else {
|
||||
/* fix me - deal with branching factor */
|
||||
answer = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/* Returns a literal with both terms constant which has not been ordered yet. */
|
||||
RDF_Literal noUnknownAs(RDF_Query q, RDF_LiteralList orderedLiterals, RDF_VariableList knownVars) {
|
||||
RDF_LiteralList list = q->literals;
|
||||
while (list != NULL) {
|
||||
RDF_Literal current = list->element;
|
||||
if (!findLiteral(current, orderedLiterals) &&
|
||||
constantp(current->u, knownVars)) {
|
||||
int i;
|
||||
PRBool foundNonConstant = false;
|
||||
for (i = 0; i < current->valueCount; i++) { /* all values constant? */
|
||||
TermStruc term = *(current->v + i);
|
||||
if (!constantp(term, knownVars)) foundNonConstant = true;
|
||||
}
|
||||
if (foundNonConstant) list = list->next;
|
||||
else return current;
|
||||
}
|
||||
else list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns true if the conjuncts were ordered succesfully.
|
||||
*/
|
||||
PRBool orderConjuncts(RDF_Query q) {
|
||||
uint16 numOrdered = 0;
|
||||
RDF_Error err = noRDFErr;
|
||||
RDF_LiteralList orderedLiterals = NULL;
|
||||
RDF_LiteralList orderedLiteralsTail = orderedLiterals;
|
||||
RDF_VariableList knownVars = NULL;
|
||||
|
||||
if (q->conjunctsOrdered) return true;
|
||||
|
||||
while (numOrdered < q->numLiterals) {
|
||||
RDF_Literal lit1 = noUnknownAs(q, orderedLiterals, knownVars);
|
||||
if (lit1 != NULL) {
|
||||
/* add literal to ordered list */
|
||||
RDF_LiteralList newlist = (RDF_LiteralList)getMem(sizeof(RDF_LiteralListStruc));
|
||||
if (newlist == NULL) break;
|
||||
newlist->element = lit1;
|
||||
newlist->next = NULL;
|
||||
if (orderedLiterals == NULL)
|
||||
orderedLiterals = orderedLiteralsTail = newlist;
|
||||
else {
|
||||
orderedLiteralsTail->next = newlist;
|
||||
orderedLiteralsTail = orderedLiteralsTail->next;
|
||||
}
|
||||
numOrdered++;
|
||||
} else {
|
||||
RDF_Literal lit2 = oneUnknownAs(q, orderedLiterals, knownVars);
|
||||
if (lit2 != NULL) {
|
||||
RDF_LiteralList newlist = (RDF_LiteralList)getMem(sizeof(RDF_LiteralListStruc));
|
||||
if (newlist == NULL) break;
|
||||
/* add unit and value as known variables */
|
||||
lit2->variable = (RDF_Variable) (constantp(lit2->u, knownVars) ? lit2->v->value : lit2->u.value);
|
||||
if (variableTermp(lit2->u)) {
|
||||
err = addVariableToList((RDF_Variable)lit2->u.value, &knownVars);
|
||||
if (err != noRDFErr) break;
|
||||
}
|
||||
if (variableTermp(*lit2->v)) {
|
||||
err = addVariableToList((RDF_Variable)lit2->v->value, &knownVars);
|
||||
if (err != noRDFErr) break;
|
||||
}
|
||||
/* add literal to ordered list */
|
||||
newlist->element = lit2;
|
||||
newlist->next = NULL;
|
||||
if (orderedLiterals == NULL)
|
||||
orderedLiterals = orderedLiteralsTail = newlist;
|
||||
else {
|
||||
orderedLiteralsTail->next = newlist;
|
||||
orderedLiteralsTail = orderedLiteralsTail->next;
|
||||
}
|
||||
numOrdered++;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
if (numOrdered == q->numLiterals) { /* ordered all succesfully so replace literals */
|
||||
RDF_LiteralList old = q->literals;
|
||||
q->literals = orderedLiterals;
|
||||
destroyLiteralList(old, false);
|
||||
q->conjunctsOrdered = true;
|
||||
} else { /* unsuccessful so destroy ordered list structure */
|
||||
destroyLiteralList(orderedLiterals, false);
|
||||
q->conjunctsOrdered = false;
|
||||
}
|
||||
destroyVariableList(knownVars, false); /* free the knownVars list structure */
|
||||
return q->conjunctsOrdered;
|
||||
}
|
||||
|
||||
PRBool processNextLiteral(RDF_Query q, RDF_Literal literal) {
|
||||
if (literal->c != NULL) {
|
||||
RDF_SetVariableValue(literal->variable, RDF_NextValue(literal->c), literal->valueType);
|
||||
return (RDF_GetVariableValue(literal->variable) != NULL);
|
||||
} else {
|
||||
RDF_Resource u; /* unit is a resource except for the comparison case so don't set it yet. */
|
||||
RDF_Resource s = literal->s;
|
||||
void* v;
|
||||
if (literal->variable == NULL) {
|
||||
PRBool result = false;
|
||||
PRBool ans = false;
|
||||
int i;
|
||||
if (literal->bt) return false;
|
||||
/* find a value that satisfies predicate */
|
||||
for (i = 0; i < literal->valueCount; i++) {
|
||||
TermStruc valueTerm = *(literal->v + i);
|
||||
if (comparisonp(s)) {
|
||||
/* unit is a variable in all comparisons.
|
||||
value may be a variable or a constant.
|
||||
*/
|
||||
switch (literal->valueType) {
|
||||
char *str, *pattern;
|
||||
int i, j;
|
||||
case RDF_STRING_TYPE:
|
||||
if (literal->u.type != RDF_VARIABLE_TERM_TYPE) return false; /* error */
|
||||
if (((RDF_Variable)literal->u.value)->type != RDF_STRING_TYPE) return false;
|
||||
str = (char*)RDF_GetVariableValue((RDF_Variable)literal->u.value);
|
||||
switch (valueTerm.type) {
|
||||
case RDF_VARIABLE_TERM_TYPE:
|
||||
pattern = (char*)RDF_GetVariableValue((RDF_Variable)valueTerm.value);
|
||||
break;
|
||||
case RDF_CONSTANT_TERM_TYPE:
|
||||
pattern = (char*)valueTerm.value;
|
||||
break;
|
||||
default:
|
||||
/* should blow up */
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
if (s == gCoreVocab->RDF_stringEquals) {
|
||||
ans = stringEquals(pattern, str);
|
||||
} else if (s == gCoreVocab->RDF_substring) {
|
||||
ans = substring(pattern, str);
|
||||
} else if (s == gCoreVocab->RDF_notStringEquals) {
|
||||
ans = !stringEquals(pattern, str);
|
||||
} else if (s == gCoreVocab->RDF_notSubstring) {
|
||||
ans = !substring(pattern, str);
|
||||
} else return false; /* error */
|
||||
break;
|
||||
case RDF_INT_TYPE:
|
||||
if (literal->u.type != RDF_VARIABLE_TERM_TYPE) return false; /* error */
|
||||
if (((RDF_Variable)literal->u.value)->type != RDF_INT_TYPE) return false;
|
||||
i = (int)RDF_GetVariableValue((RDF_Variable)literal->u.value);
|
||||
switch (valueTerm.type) {
|
||||
case RDF_VARIABLE_TERM_TYPE:
|
||||
j = (int)RDF_GetVariableValue((RDF_Variable)valueTerm.value);
|
||||
break;
|
||||
case RDF_CONSTANT_TERM_TYPE:
|
||||
j = (int)valueTerm.value;
|
||||
break;
|
||||
default:
|
||||
/* should blow up */
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
if (s == gCoreVocab->RDF_equals) {
|
||||
ans = (i == j);
|
||||
} else if (s == gCoreVocab->RDF_notEquals) {
|
||||
ans = (i != j);
|
||||
} else if (s == gCoreVocab->RDF_lessThan) {
|
||||
ans = (i < j);
|
||||
} else if (s == gCoreVocab->RDF_greaterThan) {
|
||||
ans = (i > j);
|
||||
} else if (s == gCoreVocab->RDF_lessThanOrEqual) {
|
||||
ans = (i <= j);
|
||||
} else if (s == gCoreVocab->RDF_greaterThanOrEqual) {
|
||||
ans = (i >= j);
|
||||
} else return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
u = (RDF_Resource)((variableTermp(literal->u)) ? ((RDF_Variable)literal->u.value)->value : literal->u.value);
|
||||
/* special predicates */
|
||||
if (s == gCoreVocab->RDF_notInstanceOf) {
|
||||
ans = !RDF_HasAssertion(q->rdf, u, gCoreVocab->RDF_instanceOf, valueTerm.value, literal->valueType, true);
|
||||
} else if (s == gCoreVocab->RDF_notParent) {
|
||||
ans = !RDF_HasAssertion(q->rdf, u, gCoreVocab->RDF_parent, valueTerm.value, literal->valueType, true);
|
||||
} else ans = RDF_HasAssertion(q->rdf, u, s, valueTerm.value, literal->valueType, true);
|
||||
}
|
||||
literal->bt = true;
|
||||
/* result = ((literal->tv == true) ? ans : !ans); */
|
||||
result = ans;
|
||||
if (result) return result; /* otherwise try next value */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
u = (RDF_Resource)((variableTermp(literal->u)) ? ((RDF_Variable)literal->u.value)->value : literal->u.value);
|
||||
v = (variableTermp(*literal->v)) ? ((RDF_Variable)literal->v->value)->value : literal->v->value;
|
||||
if ((u == NULL) && variableTermp(literal->u) && resourceTermp(*literal->v)) {
|
||||
literal->c = RDF_GetSources(q->rdf, (RDF_Resource)v, s, literal->valueType, true);
|
||||
if (literal->c == NULL) return false;
|
||||
RDF_SetVariableValue(literal->variable, RDF_NextValue(literal->c), literal->valueType);
|
||||
return (RDF_GetVariableValue(literal->variable) != NULL);
|
||||
} else if ((v == NULL) && variableTermp(*literal->v) && (u != NULL)) {
|
||||
literal->c = RDF_GetTargets(q->rdf, u, s, literal->valueType, true); /* note arg order differs from java implementation */
|
||||
if (literal->c == NULL) return false;
|
||||
RDF_SetVariableValue(literal->variable, RDF_NextValue(literal->c), literal->valueType);
|
||||
return (RDF_GetVariableValue(literal->variable) != NULL);
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(PRBool) RDF_RunQuery (RDF_Query q) {
|
||||
q->queryRunning = true;
|
||||
orderConjuncts(q);
|
||||
if (q->conjunctsOrdered)
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(PRBool) RDF_GetNextElement(RDF_Query q) {
|
||||
if (!q->queryRunning) RDF_RunQuery(q);
|
||||
if (q->index == q->numLiterals) q->index--;
|
||||
while (q->index < q->numLiterals) {
|
||||
RDF_Literal lit = getNthLiteral(q, q->index); /* we know it's it range so don't have to check for NULL */
|
||||
if (!processNextLiteral(q, lit)) {
|
||||
if (q->index == 0) return false;
|
||||
lit->c = NULL;
|
||||
if (lit->variable != NULL) RDF_SetVariableValue(lit->variable, (void*)NULL, RDF_RESOURCE_TYPE);
|
||||
lit->bt = false;
|
||||
q->index--;
|
||||
} else {
|
||||
q->index++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(void) RDF_EndQuery (RDF_Query q) {
|
||||
q->queryRunning = false;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_VariableList) RDF_GetVariableList(RDF_Query q) {
|
||||
return q->variables;
|
||||
}
|
||||
|
||||
/* Note: should put a test for overflow of numLiterals */
|
||||
|
||||
/* Adds a literal to the query. */
|
||||
void addLiteral(RDF_Query q, RDF_Literal literal) {
|
||||
RDF_LiteralList newlist = (RDF_LiteralList)getMem(sizeof(RDF_LiteralListStruc));
|
||||
if (newlist == NULL) return;
|
||||
newlist->element = literal;
|
||||
newlist->next = q->literals;
|
||||
q->literals = newlist;
|
||||
q->numLiterals++;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctVRV(RDF_Query q, RDF_Variable arg1, RDF_Resource s, RDF_Variable arg2, RDF_ValueType type) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = (void*)arg1;
|
||||
literal->u.type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->u.value)->type = RDF_RESOURCE_TYPE;
|
||||
literal->s = s;
|
||||
literal->valueCount = 1;
|
||||
literal->v = (TermStruc*)getMem(sizeof(TermStruc));
|
||||
literal->v->value = (void*)arg2;
|
||||
literal->v->type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->v->value)->type = literal->valueType = type;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctVRO(RDF_Query q, RDF_Variable arg1, RDF_Resource s, void* arg2, RDF_ValueType type) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = (void*)arg1;
|
||||
literal->u.type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->u.value)->type = type;
|
||||
literal->s = s;
|
||||
literal->valueCount = 1;
|
||||
literal->v = (TermStruc*)getMem(sizeof(TermStruc));
|
||||
literal->v->value = (type == RDF_STRING_TYPE) ? (void*)copyString((char*)arg2) : (void*)arg2;
|
||||
literal->v->type = RDF_CONSTANT_TERM_TYPE;
|
||||
literal->valueType = type;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctRRO(RDF_Query q, RDF_Resource arg1, RDF_Resource s, void* arg2, RDF_ValueType type) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = (void*)arg1;
|
||||
literal->u.type = RDF_RESOURCE_TERM_TYPE;
|
||||
literal->s = s;
|
||||
literal->valueCount = 1;
|
||||
literal->v = (TermStruc*)getMem(sizeof(TermStruc));
|
||||
literal->v->value = (type == RDF_STRING_TYPE) ? (void*)copyString((char*)arg2) : (void*)arg2;
|
||||
literal->v->type = RDF_CONSTANT_TERM_TYPE;
|
||||
literal->valueType = type;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctVRR(RDF_Query q, RDF_Variable arg1, RDF_Resource s, RDF_Resource arg2) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = (void*)arg1;
|
||||
literal->u.type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->u.value)->type = RDF_RESOURCE_TYPE;
|
||||
literal->s = s;
|
||||
literal->valueCount = 1;
|
||||
literal->v = (TermStruc*)getMem(sizeof(TermStruc));
|
||||
literal->v->value = (void*)arg2;
|
||||
literal->v->type = RDF_RESOURCE_TERM_TYPE;
|
||||
literal->valueType = RDF_RESOURCE_TYPE;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctRRV(RDF_Query q, RDF_Resource arg1, RDF_Resource s, RDF_Variable arg2, RDF_ValueType type) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = arg1;
|
||||
literal->u.type = RDF_RESOURCE_TERM_TYPE;
|
||||
literal->s = s;
|
||||
literal->valueCount = 1;
|
||||
literal->v = (TermStruc*)getMem(sizeof(TermStruc));
|
||||
literal->v->value = (void*)arg2;
|
||||
literal->v->type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->v->value)->type = literal->valueType = type;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||
|
||||
PR_PUBLIC_API(RDF_Error) RDF_AddConjunctVRL(RDF_Query q, RDF_Variable arg1, RDF_Resource s, RDF_Term arg2, RDF_ValueType type, uint8 count) {
|
||||
RDF_Literal literal = (RDF_Literal)getMem(sizeof(LiteralStruc));
|
||||
if (literal == NULL) return RDF_NO_MEMORY;
|
||||
literal->u.value = (void*)arg1;
|
||||
literal->u.type = RDF_VARIABLE_TERM_TYPE;
|
||||
((RDF_Variable)literal->u.value)->type = type;
|
||||
literal->s = s;
|
||||
literal->valueCount = count;
|
||||
literal->v = (void*)arg2;
|
||||
/* value and type of each term already assigned */
|
||||
literal->valueType = type;
|
||||
literal->tv = true;
|
||||
addLiteral(q, literal);
|
||||
q->conjunctsOrdered = false;
|
||||
return noRDFErr;
|
||||
}
|
||||