mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
10 KiB
677 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
buffer.cxx
|
|
|
|
Abstract:
|
|
|
|
MIDL Compiler Buffer Manager Definition
|
|
|
|
This class manages a collection of pre-allocated strings.
|
|
|
|
Author:
|
|
|
|
Donna Liu (donnali) 09-Nov-1990
|
|
|
|
Revision History:
|
|
|
|
26-Feb-1992 donnali
|
|
|
|
Moved toward NT coding style.
|
|
|
|
--*/
|
|
|
|
|
|
#include "nulldefs.h"
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
}
|
|
#include "buffer.hxx"
|
|
|
|
extern void midl_debug (char *);
|
|
|
|
_BufferElement::_BufferElement(
|
|
struct _BufferElement * pPrevElem,
|
|
struct _BufferElement * pNextElem,
|
|
char ** pNewBuf
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method constructs a buffer holding a fixed number of
|
|
pre-allocated strings.
|
|
|
|
Arguments:
|
|
|
|
pPrevElem - Supplies a pointer to the previous buffer.
|
|
|
|
pNextElem - Supplies a pointer to the next buffer.
|
|
|
|
pNewBuf - Supplies storage for pre-allocated strings to be
|
|
deposited later.
|
|
|
|
--*/
|
|
{
|
|
pPrev = pPrevElem;
|
|
pNext = pNextElem;
|
|
pBuffer = pNewBuf;
|
|
}
|
|
|
|
BufferManager::BufferManager(
|
|
unsigned short usBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method constructs a BufferManager object.
|
|
|
|
Arguments:
|
|
|
|
usBufferSize - Supplies the size of each managed buffer.
|
|
|
|
--*/
|
|
{
|
|
char ** pTemp = new (char *[usBufferSize]);
|
|
|
|
usBufSize = usBufferSize;
|
|
usTabSize = 0;
|
|
pszTable = (char **)0;
|
|
pHead = pTail = pSave = new BufferElement(
|
|
(BufferElement *)0,
|
|
(BufferElement *)0,
|
|
pTemp);
|
|
iHead = iTail = (usBufSize / 2);
|
|
}
|
|
|
|
BufferManager::BufferManager(
|
|
unsigned short usBufferSize,
|
|
unsigned short usTableSize,
|
|
char * aStringTable[]
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method constructs a BufferManager object.
|
|
|
|
Arguments:
|
|
|
|
usBufferSize - Supplies the size of each managed buffer.
|
|
|
|
usTableSize - Supplies the size of the table containing string
|
|
constants.
|
|
|
|
aStringTable - Supplies the table containing string constants.
|
|
|
|
--*/
|
|
{
|
|
char ** pTemp = new (char *[usBufferSize]);
|
|
|
|
usBufSize = usBufferSize;
|
|
usTabSize = usTableSize;
|
|
pszTable = aStringTable;
|
|
pHead = pTail = pSave = new BufferElement(
|
|
(BufferElement *)0,
|
|
(BufferElement *)0,
|
|
pTemp);
|
|
iHead = iTail = (usBufSize / 2);
|
|
}
|
|
|
|
|
|
struct _BufferElement * BufferElement::ExtendPrev(
|
|
char ** pNewBuf
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method allocates pPrev if necessary.
|
|
|
|
Arguments:
|
|
|
|
pNewBuf - Supplies storage for pre-allocated strings to be
|
|
deposited later.
|
|
|
|
Return Value:
|
|
|
|
The pointer to the previous buffer.
|
|
|
|
--*/
|
|
{
|
|
if (pPrev == (struct _BufferElement *)0)
|
|
{
|
|
return pPrev = new BufferElement((BufferElement *)0, this, pNewBuf);
|
|
}
|
|
else
|
|
{
|
|
return pPrev;
|
|
}
|
|
}
|
|
|
|
|
|
struct _BufferElement * BufferElement::ExtendNext(
|
|
char ** pNewBuf
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method allocates pNext if necessary.
|
|
|
|
Arguments:
|
|
|
|
pNewBuf - Supplies storage for pre-allocated strings to be
|
|
deposited later.
|
|
|
|
Return Value:
|
|
|
|
The pointer to the next buffer.
|
|
|
|
--*/
|
|
{
|
|
if (pNext == (struct _BufferElement *)0)
|
|
{
|
|
return pNext = new BufferElement(this, (BufferElement *)0, pNewBuf);
|
|
}
|
|
else
|
|
{
|
|
return pNext;
|
|
}
|
|
}
|
|
|
|
|
|
inline struct _BufferElement * BufferElement::GetPrev(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method returns pPrev.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The pointer to the previous buffer.
|
|
|
|
--*/
|
|
{
|
|
return pPrev;
|
|
}
|
|
|
|
|
|
inline struct _BufferElement * BufferElement::GetNext(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method returns pNext.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The pointer to the next buffer.
|
|
|
|
--*/
|
|
{
|
|
return pNext;
|
|
}
|
|
|
|
|
|
void BufferManager::Clear(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method clears the BufferManager so that it is oblivious of
|
|
all the strings formerly stored.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
pHead = pTail = pSave;
|
|
iHead = iTail = usBufSize / 2;
|
|
}
|
|
|
|
|
|
inline short
|
|
BufferManager::Empty(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method answers if a BufferManager object is empty of strings.
|
|
|
|
Return Value:
|
|
|
|
Zero if not empty.
|
|
Non-zero if empty.
|
|
|
|
--*/
|
|
{
|
|
return (pHead == pTail && iHead == iTail);
|
|
}
|
|
|
|
|
|
void BufferManager::Print(
|
|
FILE * pFile
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method prints all the strings managed by a BufferManager
|
|
to a file.
|
|
|
|
Arguments:
|
|
|
|
pFile - Supplies the output file handle.
|
|
|
|
--*/
|
|
{
|
|
unsigned short usCount;
|
|
BufferElement * pTemp;
|
|
|
|
if (pHead == pTail)
|
|
{
|
|
for (usCount = iHead ; usCount < iTail ; usCount++)
|
|
{
|
|
fprintf (pFile, "%s", pHead->pBuffer[usCount]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (usCount = iHead ; usCount < usBufSize ; usCount++)
|
|
{
|
|
fprintf (pFile, "%s", pHead->pBuffer[usCount]);
|
|
}
|
|
for (pTemp = pHead->GetNext() ;
|
|
pTemp != pTail ;
|
|
pTemp = pTemp->GetNext())
|
|
{
|
|
for (usCount = 0 ; usCount < usBufSize ; usCount++)
|
|
{
|
|
fprintf (pFile, "%s", pTemp->pBuffer[usCount]);
|
|
}
|
|
}
|
|
for (usCount = 0 ; usCount < iTail ; usCount++)
|
|
{
|
|
fprintf (pFile, "%s", pTail->pBuffer[usCount]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::Print(
|
|
char * pString
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method prints all the strings managed by a BufferManager
|
|
to a file.
|
|
|
|
Arguments:
|
|
|
|
pFile - Supplies the output file handle.
|
|
|
|
--*/
|
|
{
|
|
unsigned short usCount;
|
|
BufferElement * pTemp;
|
|
|
|
if (pHead == pTail)
|
|
{
|
|
for (usCount = iHead ; usCount < iTail ; usCount++)
|
|
{
|
|
sprintf (pString, "%s", pHead->pBuffer[usCount]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (usCount = iHead ; usCount < usBufSize ; usCount++)
|
|
{
|
|
sprintf (pString, "%s", pHead->pBuffer[usCount]);
|
|
}
|
|
for (pTemp = pHead->GetNext() ;
|
|
pTemp != pTail ;
|
|
pTemp = pTemp->GetNext())
|
|
{
|
|
for (usCount = 0 ; usCount < usBufSize ; usCount++)
|
|
{
|
|
sprintf (pString, "%s", pTemp->pBuffer[usCount]);
|
|
}
|
|
}
|
|
for (usCount = 0 ; usCount < iTail ; usCount++)
|
|
{
|
|
sprintf (pString, "%s", pTail->pBuffer[usCount]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BufferManager::Clone(
|
|
BufferManager * pBuffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method clones a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
pBuffer - Supplies the clone.
|
|
|
|
--*/
|
|
{
|
|
unsigned short usCount;
|
|
BufferElement * pTemp;
|
|
|
|
if (pHead == pTail)
|
|
{
|
|
for (usCount = iHead ; usCount < iTail ; usCount++)
|
|
{
|
|
pBuffer->ConcatTail(pHead->pBuffer[usCount]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (usCount = iHead ; usCount < usBufSize ; usCount++)
|
|
{
|
|
pBuffer->ConcatTail(pHead->pBuffer[usCount]);
|
|
}
|
|
for (pTemp = pHead->GetNext() ;
|
|
pTemp != pTail ;
|
|
pTemp = pTemp->GetNext())
|
|
{
|
|
for (usCount = 0 ; usCount < usBufSize ; usCount++)
|
|
{
|
|
pBuffer->ConcatTail(pTemp->pBuffer[usCount]);
|
|
}
|
|
}
|
|
for (usCount = 0 ; usCount < iTail ; usCount++)
|
|
{
|
|
pBuffer->ConcatTail(pTail->pBuffer[usCount]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::Merge(
|
|
BufferManager * pBuffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method merges the content of two BufferManager objects.
|
|
|
|
Arguments:
|
|
|
|
pBuffer - Supplies a BufferManager object whose content will be
|
|
removed and appended to that of this BufferManager object.
|
|
|
|
--*/
|
|
{
|
|
char * psz = (char *)0;
|
|
|
|
while (1)
|
|
{
|
|
pBuffer->RemoveHead(&psz);
|
|
if (psz != (char *)0)
|
|
{
|
|
ConcatTail(psz);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::ConcatHead(
|
|
char *psz
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method concatenates a string to the head of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
psz - Supplies the string to be concatenated.
|
|
|
|
--*/
|
|
{
|
|
BufferElement * pTemp;
|
|
|
|
if (iHead == 0)
|
|
{
|
|
char ** pNewBuf = (char **) new (char *[usBufSize]);
|
|
pTemp = pHead->ExtendPrev(pNewBuf);
|
|
if (pTemp == (BufferElement *)0)
|
|
{
|
|
midl_debug ("running out of memory\n");
|
|
}
|
|
else
|
|
{
|
|
midl_debug ("getting a new buffer head\n");
|
|
iHead = usBufSize-1;
|
|
pHead = pTemp;
|
|
pHead->pBuffer[iHead] = psz;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pHead->pBuffer[--iHead] = psz;
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::ConcatHead(
|
|
unsigned short iIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method concatenates a string to the head of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
iIndex - Supplies an index into the table of string constants.
|
|
|
|
--*/
|
|
{
|
|
if (iIndex >= usTabSize)
|
|
{
|
|
midl_debug ("table index out of range\n");
|
|
}
|
|
else
|
|
{
|
|
ConcatHead(pszTable[iIndex]);
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::ConcatTail(
|
|
char *psz
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method concatenates a string to the tail of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
psz - Supplies the string to be concatenated.
|
|
|
|
--*/
|
|
{
|
|
BufferElement * pTemp;
|
|
|
|
if (iTail == usBufSize)
|
|
{
|
|
pTemp = pTail->ExtendNext(new (char *[usBufSize]));
|
|
if (pTemp == (BufferElement *)0)
|
|
{
|
|
midl_debug ("running out of memory\n");
|
|
}
|
|
else
|
|
{
|
|
midl_debug ("getting a new buffer tail\n");
|
|
iTail = 0;
|
|
pTail = pTemp;
|
|
pTail->pBuffer[iTail++] = psz;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTail->pBuffer[iTail++] = psz;
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::ConcatTail(
|
|
unsigned short iIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method concatenates a string to the tail of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
iIndex - Supplies an index into the table of string constants.
|
|
|
|
--*/
|
|
{
|
|
if (iIndex >= usTabSize)
|
|
{
|
|
midl_debug ("table index out of range\n");
|
|
}
|
|
else
|
|
{
|
|
ConcatTail(pszTable[iIndex]);
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::RemoveHead(
|
|
char ** psz
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method removes a string from the head of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
psz - Returns the string just removed.
|
|
|
|
--*/
|
|
{
|
|
if (psz == (char **)0)
|
|
{
|
|
midl_debug ("empty output parameter\n");
|
|
}
|
|
else if (pHead == pTail && iHead == iTail)
|
|
{
|
|
midl_debug ("empty buffer\n");
|
|
* psz = (char *)0;
|
|
}
|
|
else
|
|
{
|
|
* psz = pHead->pBuffer[iHead++];
|
|
if (iHead == usBufSize)
|
|
{
|
|
if (pHead == pTail)
|
|
{
|
|
iHead = iTail = usBufSize / 2;
|
|
}
|
|
else
|
|
{
|
|
pHead = pHead->pNext; // may need some check here
|
|
iHead = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BufferManager::RemoveTail(
|
|
char ** psz
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method removes a string from the tail of the list of
|
|
strings managed by a BufferManager.
|
|
|
|
Arguments:
|
|
|
|
psz - Returns the string just removed.
|
|
|
|
--*/
|
|
{
|
|
if (psz == (char **)0)
|
|
{
|
|
midl_debug ("empty output parameter\n");
|
|
}
|
|
else if (pHead == pTail && iHead == iTail)
|
|
{
|
|
midl_debug ("empty buffer\n");
|
|
* psz = (char *)0;
|
|
}
|
|
else
|
|
{
|
|
* psz = pTail->pBuffer[--iTail];
|
|
if (iTail == 0)
|
|
{
|
|
if (pHead == pTail)
|
|
{
|
|
iHead = iTail = usBufSize / 2;
|
|
}
|
|
else
|
|
{
|
|
pTail = pTail->pPrev; // may need some check here
|
|
iTail = usBufSize;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|